diff --git a/CHANGELOG.md b/CHANGELOG.md index f92e080..b212e5d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,19 @@ *** +### v2.0.1 2016-02-28 + +#### Changes + +* build and test using Go 1.6 +* fix ```reflect+anonymous+unexported``` bug in ```gopacket```'s ```packet.go``` + * [gopacket issue](https://github.com/google/gopacket/issues/175) +* use godep to vendor dependencies + * as Elastic Beats continues to change rapidly + * fix for gopacket + +*** + ### v2.0.0 2016-02-18 #### Changes diff --git a/Godeps/Godeps.json b/Godeps/Godeps.json new file mode 100644 index 0000000..ce846f9 --- /dev/null +++ b/Godeps/Godeps.json @@ -0,0 +1,108 @@ +{ + "ImportPath": "github.com/cleesmith/unifiedbeat", + "GoVersion": "go1.6", + "Deps": [ + { + "ImportPath": "github.com/Shopify/sarama", + "Comment": "v1.8.0-17-g8aadb47", + "Rev": "8aadb476e66ca998f2f6bb3c993e9a2daa3666b9" + }, + { + "ImportPath": "github.com/cleesmith/go-unified2", + "Comment": "20140127-34-g833ecbd", + "Rev": "833ecbd754de334e591f3913bed0c9181188f0de" + }, + { + "ImportPath": "github.com/dustin/go-humanize", + "Rev": "8929fe90cee4b2cb9deb468b51fb34eba64d1bf0" + }, + { + "ImportPath": "github.com/eapache/go-resiliency/breaker", + "Comment": "v1.0.0-4-gb86b1ec", + "Rev": "b86b1ec0dd4209a588dc1285cdd471e73525c0b3" + }, + { + "ImportPath": "github.com/eapache/queue", + "Comment": "v1.0.2", + "Rev": "ded5959c0d4e360646dc9e9908cff48666781367" + }, + { + "ImportPath": "github.com/elastic/beats/libbeat/beat", + "Comment": "v1.1.1-503-g6daa4b7", + "Rev": "6daa4b795928756c19747eedbc76c14584c5a3f4" + }, + { + "ImportPath": "github.com/elastic/beats/libbeat/cfgfile", + "Comment": "v1.1.1-503-g6daa4b7", + "Rev": "6daa4b795928756c19747eedbc76c14584c5a3f4" + }, + { + "ImportPath": "github.com/elastic/beats/libbeat/common", + "Comment": "v1.1.1-503-g6daa4b7", + "Rev": "6daa4b795928756c19747eedbc76c14584c5a3f4" + }, + { + "ImportPath": "github.com/elastic/beats/libbeat/logp", + "Comment": "v1.1.1-503-g6daa4b7", + "Rev": "6daa4b795928756c19747eedbc76c14584c5a3f4" + }, + { + "ImportPath": "github.com/elastic/beats/libbeat/outputs", + "Comment": "v1.1.1-503-g6daa4b7", + "Rev": "6daa4b795928756c19747eedbc76c14584c5a3f4" + }, + { + "ImportPath": "github.com/elastic/beats/libbeat/publisher", + "Comment": "v1.1.1-503-g6daa4b7", + "Rev": "6daa4b795928756c19747eedbc76c14584c5a3f4" + }, + { + "ImportPath": "github.com/elastic/beats/libbeat/service", + "Comment": "v1.1.1-503-g6daa4b7", + "Rev": "6daa4b795928756c19747eedbc76c14584c5a3f4" + }, + { + "ImportPath": "github.com/garyburd/redigo/internal", + "Rev": "a47585eaae68b1d14b02940d2af1b9194f3caa9c" + }, + { + "ImportPath": "github.com/garyburd/redigo/redis", + "Rev": "a47585eaae68b1d14b02940d2af1b9194f3caa9c" + }, + { + "ImportPath": "github.com/golang/snappy", + "Rev": "723cc1e459b8eea2dea4583200fd60757d40097a" + }, + { + "ImportPath": "github.com/google/gopacket", + "Comment": "v1.1.11-79-g3b097a3", + "Rev": "3b097a3f06f4af581aed40162263ac34e636381e" + }, + { + "ImportPath": "github.com/klauspost/crc32", + "Rev": "19b0b332c9e4516a6370a0456e6182c3b5036720" + }, + { + "ImportPath": "github.com/nranchev/go-libGeoIP", + "Rev": "c78e8bd2dd3599feb21fd30886043979e82fe948" + }, + { + "ImportPath": "github.com/oschwald/geoip2-golang", + "Comment": "v0.1.0-23-gbf3c252", + "Rev": "bf3c2529e7f0619767568752f5155dd9c5125426" + }, + { + "ImportPath": "github.com/oschwald/maxminddb-golang", + "Comment": "v0.2.0-36-gb4a9635", + "Rev": "b4a963502ba01ab44940ee21d5539bd65c726924" + }, + { + "ImportPath": "github.com/satori/go.uuid", + "Rev": "e673fdd4dea8a7334adbbe7f57b7e4b00bdc5502" + }, + { + "ImportPath": "gopkg.in/yaml.v2", + "Rev": "7ad95dd0798a40da1ccdff6dff35fd177b5edf40" + } + ] +} diff --git a/Godeps/Readme b/Godeps/Readme new file mode 100644 index 0000000..4cdaa53 --- /dev/null +++ b/Godeps/Readme @@ -0,0 +1,5 @@ +This directory tree is generated automatically by godep. + +Please do not edit. + +See https://github.com/tools/godep for more information. diff --git a/README.md b/README.md index 8487797..2a1f86d 100644 --- a/README.md +++ b/README.md @@ -6,8 +6,6 @@ such as [Snort](https://www.snort.org/) and [Suricata](http://suricata-ids.org/) *** -### February 18, 2016 - #### Usage 1. build from source diff --git a/main.go b/main.go index 4a3a740..7e043a4 100644 --- a/main.go +++ b/main.go @@ -34,7 +34,7 @@ import ( ) var Name = "unifiedbeat" -var Version = "2.0.0" +var Version = "2.0.1" func main() { if err := beat.Run(Name, Version, unifiedbeat.New()); err != nil { diff --git a/vendor/github.com/Shopify/sarama/.gitignore b/vendor/github.com/Shopify/sarama/.gitignore new file mode 100644 index 0000000..3591f9f --- /dev/null +++ b/vendor/github.com/Shopify/sarama/.gitignore @@ -0,0 +1,24 @@ +# Compiled Object files, Static and Dynamic libs (Shared Objects) +*.o +*.a +*.so +*.test + +# Folders +_obj +_test +.vagrant + +# Architecture specific extensions/prefixes +*.[568vq] +[568vq].out + +*.cgo1.go +*.cgo2.c +_cgo_defun.c +_cgo_gotypes.go +_cgo_export.* + +_testmain.go + +*.exe diff --git a/vendor/github.com/Shopify/sarama/.travis.yml b/vendor/github.com/Shopify/sarama/.travis.yml new file mode 100644 index 0000000..f7c8855 --- /dev/null +++ b/vendor/github.com/Shopify/sarama/.travis.yml @@ -0,0 +1,33 @@ +language: go +go: +- 1.4.3 +- 1.5.3 +- 1.6 + +env: + global: + - KAFKA_PEERS=localhost:9091,localhost:9092,localhost:9093,localhost:9094,localhost:9095 + - TOXIPROXY_ADDR=http://localhost:8474 + - KAFKA_INSTALL_ROOT=/home/travis/kafka + - KAFKA_HOSTNAME=localhost + - DEBUG=true + matrix: + - KAFKA_VERSION=0.8.2.2 + - KAFKA_VERSION=0.9.0.1 + +before_install: +- export REPOSITORY_ROOT=${TRAVIS_BUILD_DIR} +- vagrant/install_cluster.sh +- vagrant/boot_cluster.sh +- vagrant/create_topics.sh + +install: +- make install_dependencies + +script: +- make test +- make vet +- make errcheck +- make fmt + +sudo: false diff --git a/vendor/github.com/Shopify/sarama/CHANGELOG.md b/vendor/github.com/Shopify/sarama/CHANGELOG.md new file mode 100644 index 0000000..f0dd96f --- /dev/null +++ b/vendor/github.com/Shopify/sarama/CHANGELOG.md @@ -0,0 +1,249 @@ +# Changelog + +#### Version 1.9.0 (trunk) + +New Features: + - Add support for custom offset manager retention durations + ([#602](https://github.com/Shopify/sarama/pull/602)). + - Publish low-level mocks to enable testing of third-party producer/consumer + implementations ([#570](https://github.com/Shopify/sarama/pull/570)). + - Declare support for Golang 1.6 + ([#611](https://github.com/Shopify/sarama/pull/611)). + +Improvements: + - Simplified broker locking scheme slightly + ([#604](https://github.com/Shopify/sarama/pull/604)). + +#### Version 1.8.0 (2016-02-01) + +New Features: + - Full support for Kafka 0.9: + - All protocol messages and fields + ([#586](https://github.com/Shopify/sarama/pull/586), + [#588](https://github.com/Shopify/sarama/pull/588), + [#590](https://github.com/Shopify/sarama/pull/590)). + - Verified that TLS support works + ([#581](https://github.com/Shopify/sarama/pull/581)). + - Fixed the OffsetManager compatibility + ([#585](https://github.com/Shopify/sarama/pull/585)). + +Improvements: + - Optimize for fewer system calls when reading from the network + ([#584](https://github.com/Shopify/sarama/pull/584)). + - Automatically retry `InvalidMessage` errors to match upstream behaviour + ([#589](https://github.com/Shopify/sarama/pull/589)). + +#### Version 1.7.0 (2015-12-11) + +New Features: + - Preliminary support for Kafka 0.9 + ([#572](https://github.com/Shopify/sarama/pull/572)). This comes with several + caveats: + - Protocol-layer support is mostly in place + ([#577](https://github.com/Shopify/sarama/pull/577)), however Kafka 0.9 + renamed some messages and fields, which we did not in order to preserve API + compatibility. + - The producer and consumer work against 0.9, but the offset manager does + not ([#573](https://github.com/Shopify/sarama/pull/573)). + - TLS support may or may not work + ([#581](https://github.com/Shopify/sarama/pull/581)). + +Improvements: + - Don't wait for request timeouts on dead brokers, greatly speeding recovery + when the TCP connection is left hanging + ([#548](https://github.com/Shopify/sarama/pull/548)). + - Refactored part of the producer. The new version provides a much more elegant + solution to [#449](https://github.com/Shopify/sarama/pull/449). It is also + slightly more efficient, and much more precise in calculating batch sizes + when compression is used + ([#549](https://github.com/Shopify/sarama/pull/549), + [#550](https://github.com/Shopify/sarama/pull/550), + [#551](https://github.com/Shopify/sarama/pull/551)). + +Bug Fixes: + - Fix race condition in consumer test mock + ([#553](https://github.com/Shopify/sarama/pull/553)). + +#### Version 1.6.1 (2015-09-25) + +Bug Fixes: + - Fix panic that could occur if a user-supplied message value failed to encode + ([#449](https://github.com/Shopify/sarama/pull/449)). + +#### Version 1.6.0 (2015-09-04) + +New Features: + - Implementation of a consumer offset manager using the APIs introduced in + Kafka 0.8.2. The API is designed mainly for integration into a future + high-level consumer, not for direct use, although it is *possible* to use it + directly. + ([#461](https://github.com/Shopify/sarama/pull/461)). + +Improvements: + - CRC32 calculation is much faster on machines with SSE4.2 instructions, + removing a major hotspot from most profiles + ([#255](https://github.com/Shopify/sarama/pull/255)). + +Bug Fixes: + - Make protocol decoding more robust against some malformed packets generated + by go-fuzz ([#523](https://github.com/Shopify/sarama/pull/523), + [#525](https://github.com/Shopify/sarama/pull/525)) or found in other ways + ([#528](https://github.com/Shopify/sarama/pull/528)). + - Fix a potential race condition panic in the consumer on shutdown + ([#529](https://github.com/Shopify/sarama/pull/529)). + +#### Version 1.5.0 (2015-08-17) + +New Features: + - TLS-encrypted network connections are now supported. This feature is subject + to change when Kafka releases built-in TLS support, but for now this is + enough to work with TLS-terminating proxies + ([#154](https://github.com/Shopify/sarama/pull/154)). + +Improvements: + - The consumer will not block if a single partition is not drained by the user; + all other partitions will continue to consume normally + ([#485](https://github.com/Shopify/sarama/pull/485)). + - Formatting of error strings has been much improved + ([#495](https://github.com/Shopify/sarama/pull/495)). + - Internal refactoring of the producer for code cleanliness and to enable + future work ([#300](https://github.com/Shopify/sarama/pull/300)). + +Bug Fixes: + - Fix a potential deadlock in the consumer on shutdown + ([#475](https://github.com/Shopify/sarama/pull/475)). + +#### Version 1.4.3 (2015-07-21) + +Bug Fixes: + - Don't include the partitioner in the producer's "fetch partitions" + circuit-breaker ([#466](https://github.com/Shopify/sarama/pull/466)). + - Don't retry messages until the broker is closed when abandoning a broker in + the producer ([#468](https://github.com/Shopify/sarama/pull/468)). + - Update the import path for snappy-go, it has moved again and the API has + changed slightly ([#486](https://github.com/Shopify/sarama/pull/486)). + +#### Version 1.4.2 (2015-05-27) + +Bug Fixes: + - Update the import path for snappy-go, it has moved from google code to github + ([#456](https://github.com/Shopify/sarama/pull/456)). + +#### Version 1.4.1 (2015-05-25) + +Improvements: + - Optimizations when decoding snappy messages, thanks to John Potocny + ([#446](https://github.com/Shopify/sarama/pull/446)). + +Bug Fixes: + - Fix hypothetical race conditions on producer shutdown + ([#450](https://github.com/Shopify/sarama/pull/450), + [#451](https://github.com/Shopify/sarama/pull/451)). + +#### Version 1.4.0 (2015-05-01) + +New Features: + - The consumer now implements `Topics()` and `Partitions()` methods to enable + users to dynamically choose what topics/partitions to consume without + instantiating a full client + ([#431](https://github.com/Shopify/sarama/pull/431)). + - The partition-consumer now exposes the high water mark offset value returned + by the broker via the `HighWaterMarkOffset()` method ([#339](https://github.com/Shopify/sarama/pull/339)). + - Added a `kafka-console-consumer` tool capable of handling multiple + partitions, and deprecated the now-obsolete `kafka-console-partitionConsumer` + ([#439](https://github.com/Shopify/sarama/pull/439), + [#442](https://github.com/Shopify/sarama/pull/442)). + +Improvements: + - The producer's logging during retry scenarios is more consistent, more + useful, and slightly less verbose + ([#429](https://github.com/Shopify/sarama/pull/429)). + - The client now shuffles its initial list of seed brokers in order to prevent + thundering herd on the first broker in the list + ([#441](https://github.com/Shopify/sarama/pull/441)). + +Bug Fixes: + - The producer now correctly manages its state if retries occur when it is + shutting down, fixing several instances of confusing behaviour and at least + one potential deadlock ([#419](https://github.com/Shopify/sarama/pull/419)). + - The consumer now handles messages for different partitions asynchronously, + making it much more resilient to specific user code ordering + ([#325](https://github.com/Shopify/sarama/pull/325)). + +#### Version 1.3.0 (2015-04-16) + +New Features: + - The client now tracks consumer group coordinators using + ConsumerMetadataRequests similar to how it tracks partition leadership using + regular MetadataRequests ([#411](https://github.com/Shopify/sarama/pull/411)). + This adds two methods to the client API: + - `Coordinator(consumerGroup string) (*Broker, error)` + - `RefreshCoordinator(consumerGroup string) error` + +Improvements: + - ConsumerMetadataResponses now automatically create a Broker object out of the + ID/address/port combination for the Coordinator; accessing the fields + individually has been deprecated + ([#413](https://github.com/Shopify/sarama/pull/413)). + - Much improved handling of `OffsetOutOfRange` errors in the consumer. + Consumers will fail to start if the provided offset is out of range + ([#418](https://github.com/Shopify/sarama/pull/418)) + and they will automatically shut down if the offset falls out of range + ([#424](https://github.com/Shopify/sarama/pull/424)). + - Small performance improvement in encoding and decoding protocol messages + ([#427](https://github.com/Shopify/sarama/pull/427)). + +Bug Fixes: + - Fix a rare race condition in the client's background metadata refresher if + it happens to be activated while the client is being closed + ([#422](https://github.com/Shopify/sarama/pull/422)). + +#### Version 1.2.0 (2015-04-07) + +Improvements: + - The producer's behaviour when `Flush.Frequency` is set is now more intuitive + ([#389](https://github.com/Shopify/sarama/pull/389)). + - The producer is now somewhat more memory-efficient during and after retrying + messages due to an improved queue implementation + ([#396](https://github.com/Shopify/sarama/pull/396)). + - The consumer produces much more useful logging output when leadership + changes ([#385](https://github.com/Shopify/sarama/pull/385)). + - The client's `GetOffset` method will now automatically refresh metadata and + retry once in the event of stale information or similar + ([#394](https://github.com/Shopify/sarama/pull/394)). + - Broker connections now have support for using TCP keepalives + ([#407](https://github.com/Shopify/sarama/issues/407)). + +Bug Fixes: + - The OffsetCommitRequest message now correctly implements all three possible + API versions ([#390](https://github.com/Shopify/sarama/pull/390), + [#400](https://github.com/Shopify/sarama/pull/400)). + +#### Version 1.1.0 (2015-03-20) + +Improvements: + - Wrap the producer's partitioner call in a circuit-breaker so that repeatedly + broken topics don't choke throughput + ([#373](https://github.com/Shopify/sarama/pull/373)). + +Bug Fixes: + - Fix the producer's internal reference counting in certain unusual scenarios + ([#367](https://github.com/Shopify/sarama/pull/367)). + - Fix the consumer's internal reference counting in certain unusual scenarios + ([#369](https://github.com/Shopify/sarama/pull/369)). + - Fix a condition where the producer's internal control messages could have + gotten stuck ([#368](https://github.com/Shopify/sarama/pull/368)). + - Fix an issue where invalid partition lists would be cached when asking for + metadata for a non-existant topic ([#372](https://github.com/Shopify/sarama/pull/372)). + + +#### Version 1.0.0 (2015-03-17) + +Version 1.0.0 is the first tagged version, and is almost a complete rewrite. The primary differences with previous untagged versions are: + +- The producer has been rewritten; there is now a `SyncProducer` with a blocking API, and an `AsyncProducer` that is non-blocking. +- The consumer has been rewritten to only open one connection per broker instead of one connection per partition. +- The main types of Sarama are now interfaces to make depedency injection easy; mock implementations for `Consumer`, `SyncProducer` and `AsyncProducer` are provided in the `github.com/Shopify/sarama/mocks` package. +- For most uses cases, it is no longer necessary to open a `Client`; this will be done for you. +- All the configuration values have been unified in the `Config` struct. +- Much improved test suite. diff --git a/vendor/github.com/Shopify/sarama/CONTRIBUTING.md b/vendor/github.com/Shopify/sarama/CONTRIBUTING.md new file mode 100644 index 0000000..b0f107c --- /dev/null +++ b/vendor/github.com/Shopify/sarama/CONTRIBUTING.md @@ -0,0 +1,31 @@ +# Contributing + +Contributions are always welcome, both reporting issues and submitting pull requests! + +### Reporting issues + +Please make sure to include any potentially useful information in the issue, so we can pinpoint the issue faster without going back and forth. + +- What SHA of Sarama are you running? If this is not the latest SHA on the master branch, please try if the problem persists with the latest version. +- You can set `sarama.Logger` to a [log.Logger](http://golang.org/pkg/log/#Logger) instance to capture debug output. Please include it in your issue description. +- Also look at the logs of the Kafka broker you are connected to. If you see anything out of the ordinary, please include it. + +Also, please include the following information about your environment, so we can help you faster: + +- What version of Kafka are you using? +- What version of Go are you using? +- What are the values of your Producer/Consumer/Client configuration? + + +### Submitting pull requests + +We will gladly accept bug fixes, or additions to this library. Please fork this library, commit & push your changes, and open a pull request. Because this library is in production use by many people and applications, we code review all additions. To make the review process go as smooth as possible, please consider the following. + +- If you plan to work on something major, please open an issue to discuss the design first. +- Don't break backwards compatibility. If you really have to, open an issue to discuss this first. +- Make sure to use the `go fmt` command to format your code according to the standards. Even better, set up your editor to do this for you when saving. +- Run [go vet](https://godoc.org/golang.org/x/tools/cmd/vet) to detect any suspicious constructs in your code that could be bugs. +- Explicitly handle all error return values. If you really want to ignore an error value, you can assign it to `_`.You can use [errcheck](https://github.com/kisielk/errcheck) to verify whether you have handled all errors. +- You may also want to run [golint](https://github.com/golang/lint) as well to detect style problems. +- Add tests that cover the changes you made. Make sure to run `go test` with the `-race` argument to test for race conditions. +- Make sure your code is supported by all the Go versions we support. You can rely on [Travis CI](https://travis-ci.org/Shopify/sarama) for testing older Go versions diff --git a/vendor/github.com/Shopify/sarama/MIT-LICENSE b/vendor/github.com/Shopify/sarama/MIT-LICENSE new file mode 100644 index 0000000..8121b63 --- /dev/null +++ b/vendor/github.com/Shopify/sarama/MIT-LICENSE @@ -0,0 +1,20 @@ +Copyright (c) 2013 Evan Huus + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/github.com/Shopify/sarama/Makefile b/vendor/github.com/Shopify/sarama/Makefile new file mode 100644 index 0000000..01c6d35 --- /dev/null +++ b/vendor/github.com/Shopify/sarama/Makefile @@ -0,0 +1,24 @@ +default: fmt vet errcheck test + +test: + go test -v -timeout 60s -race ./... + +vet: + go vet ./... + +errcheck: + @if go version | grep -q go1.5; then errcheck github.com/Shopify/sarama/...; fi + +fmt: + @if [ -n "$$(go fmt ./...)" ]; then echo 'Please run go fmt on your code.' && exit 1; fi + +install_dependencies: install_errcheck install_go_vet get + +install_errcheck: + @if go version | grep -q go1.5; then go get github.com/kisielk/errcheck; fi + +install_go_vet: + go get golang.org/x/tools/cmd/vet + +get: + go get -t diff --git a/vendor/github.com/Shopify/sarama/README.md b/vendor/github.com/Shopify/sarama/README.md new file mode 100644 index 0000000..417c9b5 --- /dev/null +++ b/vendor/github.com/Shopify/sarama/README.md @@ -0,0 +1,36 @@ +sarama +====== + +[![GoDoc](https://godoc.org/github.com/Shopify/sarama?status.png)](https://godoc.org/github.com/Shopify/sarama) +[![Build Status](https://travis-ci.org/Shopify/sarama.svg?branch=master)](https://travis-ci.org/Shopify/sarama) + +Sarama is an MIT-licensed Go client library for [Apache Kafka](https://kafka.apache.org/) version 0.8 (and later). + +### Getting started + +- API documentation and examples are available via [godoc](https://godoc.org/github.com/Shopify/sarama). +- Mocks for testing are available in the [mocks](./mocks) subpackage. +- The [examples](./examples) directory contains more elaborate example applications. +- The [tools](./tools) directory contains command line tools that can be useful for testing, diagnostics, and instrumentation. + +### Compatibility and API stability + +Sarama provides a "2 releases + 2 months" compatibility guarantee: we support +the two latest stable releases of Kafka and Go, and we provide a two month +grace period for older releases. This means we currently officially support +Go 1.6, 1.5 and 1.4, and Kafka 0.9.0 and 0.8.2, although older releases are still +likely to work. + +Sarama follows semantic versioning and provides API stability via the gopkg.in service. +You can import a version with a guaranteed stable API via http://gopkg.in/Shopify/sarama.v1. +A changelog is available [here](CHANGELOG.md). + +### Contributing + +* Get started by checking our [contribution guidelines](https://github.com/Shopify/sarama/blob/master/CONTRIBUTING.md). +* Read the [Sarama wiki](https://github.com/Shopify/sarama/wiki) for more + technical and design details. +* The [Kafka Protocol Specification](https://cwiki.apache.org/confluence/display/KAFKA/A+Guide+To+The+Kafka+Protocol) + contains a wealth of useful information. +* For more general issues, there is [a google group](https://groups.google.com/forum/#!forum/kafka-clients) for Kafka client developers. +* If you have any questions, just ask! diff --git a/vendor/github.com/Shopify/sarama/Vagrantfile b/vendor/github.com/Shopify/sarama/Vagrantfile new file mode 100644 index 0000000..4586d9a --- /dev/null +++ b/vendor/github.com/Shopify/sarama/Vagrantfile @@ -0,0 +1,19 @@ +# -*- mode: ruby -*- +# vi: set ft=ruby : + +# Vagrantfile API/syntax version. Don't touch unless you know what you're doing! +VAGRANTFILE_API_VERSION = "2" + +MEMORY = 3072 + +Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| + config.vm.box = "ubuntu/trusty64" + + config.vm.provision :shell, path: "vagrant/provision.sh" + + config.vm.network "private_network", ip: "192.168.100.67" + + config.vm.provider "virtualbox" do |v| + v.memory = MEMORY + end +end diff --git a/vendor/github.com/Shopify/sarama/async_producer.go b/vendor/github.com/Shopify/sarama/async_producer.go new file mode 100644 index 0000000..e7ae8c2 --- /dev/null +++ b/vendor/github.com/Shopify/sarama/async_producer.go @@ -0,0 +1,893 @@ +package sarama + +import ( + "fmt" + "sync" + "time" + + "github.com/eapache/go-resiliency/breaker" + "github.com/eapache/queue" +) + +// AsyncProducer publishes Kafka messages using a non-blocking API. It routes messages +// to the correct broker for the provided topic-partition, refreshing metadata as appropriate, +// and parses responses for errors. You must read from the Errors() channel or the +// producer will deadlock. You must call Close() or AsyncClose() on a producer to avoid +// leaks: it will not be garbage-collected automatically when it passes out of +// scope. +type AsyncProducer interface { + + // AsyncClose triggers a shutdown of the producer, flushing any messages it may + // have buffered. The shutdown has completed when both the Errors and Successes + // channels have been closed. When calling AsyncClose, you *must* continue to + // read from those channels in order to drain the results of any messages in + // flight. + AsyncClose() + + // Close shuts down the producer and flushes any messages it may have buffered. + // You must call this function before a producer object passes out of scope, as + // it may otherwise leak memory. You must call this before calling Close on the + // underlying client. + Close() error + + // Input is the input channel for the user to write messages to that they + // wish to send. + Input() chan<- *ProducerMessage + + // Successes is the success output channel back to the user when AckSuccesses is + // enabled. If Return.Successes is true, you MUST read from this channel or the + // Producer will deadlock. It is suggested that you send and read messages + // together in a single select statement. + Successes() <-chan *ProducerMessage + + // Errors is the error output channel back to the user. You MUST read from this + // channel or the Producer will deadlock when the channel is full. Alternatively, + // you can set Producer.Return.Errors in your config to false, which prevents + // errors to be returned. + Errors() <-chan *ProducerError +} + +type asyncProducer struct { + client Client + conf *Config + ownClient bool + + errors chan *ProducerError + input, successes, retries chan *ProducerMessage + inFlight sync.WaitGroup + + brokers map[*Broker]chan<- *ProducerMessage + brokerRefs map[chan<- *ProducerMessage]int + brokerLock sync.Mutex +} + +// NewAsyncProducer creates a new AsyncProducer using the given broker addresses and configuration. +func NewAsyncProducer(addrs []string, conf *Config) (AsyncProducer, error) { + client, err := NewClient(addrs, conf) + if err != nil { + return nil, err + } + + p, err := NewAsyncProducerFromClient(client) + if err != nil { + return nil, err + } + p.(*asyncProducer).ownClient = true + return p, nil +} + +// NewAsyncProducerFromClient creates a new Producer using the given client. It is still +// necessary to call Close() on the underlying client when shutting down this producer. +func NewAsyncProducerFromClient(client Client) (AsyncProducer, error) { + // Check that we are not dealing with a closed Client before processing any other arguments + if client.Closed() { + return nil, ErrClosedClient + } + + p := &asyncProducer{ + client: client, + conf: client.Config(), + errors: make(chan *ProducerError), + input: make(chan *ProducerMessage), + successes: make(chan *ProducerMessage), + retries: make(chan *ProducerMessage), + brokers: make(map[*Broker]chan<- *ProducerMessage), + brokerRefs: make(map[chan<- *ProducerMessage]int), + } + + // launch our singleton dispatchers + go withRecover(p.dispatcher) + go withRecover(p.retryHandler) + + return p, nil +} + +type flagSet int8 + +const ( + syn flagSet = 1 << iota // first message from partitionProducer to brokerProducer + fin // final message from partitionProducer to brokerProducer and back + shutdown // start the shutdown process +) + +// ProducerMessage is the collection of elements passed to the Producer in order to send a message. +type ProducerMessage struct { + Topic string // The Kafka topic for this message. + // The partitioning key for this message. Pre-existing Encoders include + // StringEncoder and ByteEncoder. + Key Encoder + // The actual message to store in Kafka. Pre-existing Encoders include + // StringEncoder and ByteEncoder. + Value Encoder + + // This field is used to hold arbitrary data you wish to include so it + // will be available when receiving on the Successes and Errors channels. + // Sarama completely ignores this field and is only to be used for + // pass-through data. + Metadata interface{} + + // Below this point are filled in by the producer as the message is processed + + // Offset is the offset of the message stored on the broker. This is only + // guaranteed to be defined if the message was successfully delivered and + // RequiredAcks is not NoResponse. + Offset int64 + // Partition is the partition that the message was sent to. This is only + // guaranteed to be defined if the message was successfully delivered. + Partition int32 + + retries int + flags flagSet +} + +const producerMessageOverhead = 26 // the metadata overhead of CRC, flags, etc. + +func (m *ProducerMessage) byteSize() int { + size := producerMessageOverhead + if m.Key != nil { + size += m.Key.Length() + } + if m.Value != nil { + size += m.Value.Length() + } + return size +} + +func (m *ProducerMessage) clear() { + m.flags = 0 + m.retries = 0 +} + +// ProducerError is the type of error generated when the producer fails to deliver a message. +// It contains the original ProducerMessage as well as the actual error value. +type ProducerError struct { + Msg *ProducerMessage + Err error +} + +func (pe ProducerError) Error() string { + return fmt.Sprintf("kafka: Failed to produce message to topic %s: %s", pe.Msg.Topic, pe.Err) +} + +// ProducerErrors is a type that wraps a batch of "ProducerError"s and implements the Error interface. +// It can be returned from the Producer's Close method to avoid the need to manually drain the Errors channel +// when closing a producer. +type ProducerErrors []*ProducerError + +func (pe ProducerErrors) Error() string { + return fmt.Sprintf("kafka: Failed to deliver %d messages.", len(pe)) +} + +func (p *asyncProducer) Errors() <-chan *ProducerError { + return p.errors +} + +func (p *asyncProducer) Successes() <-chan *ProducerMessage { + return p.successes +} + +func (p *asyncProducer) Input() chan<- *ProducerMessage { + return p.input +} + +func (p *asyncProducer) Close() error { + p.AsyncClose() + + if p.conf.Producer.Return.Successes { + go withRecover(func() { + for _ = range p.successes { + } + }) + } + + var errors ProducerErrors + if p.conf.Producer.Return.Errors { + for event := range p.errors { + errors = append(errors, event) + } + } + + if len(errors) > 0 { + return errors + } + return nil +} + +func (p *asyncProducer) AsyncClose() { + go withRecover(p.shutdown) +} + +// singleton +// dispatches messages by topic +func (p *asyncProducer) dispatcher() { + handlers := make(map[string]chan<- *ProducerMessage) + shuttingDown := false + + for msg := range p.input { + if msg == nil { + Logger.Println("Something tried to send a nil message, it was ignored.") + continue + } + + if msg.flags&shutdown != 0 { + shuttingDown = true + p.inFlight.Done() + continue + } else if msg.retries == 0 { + if shuttingDown { + // we can't just call returnError here because that decrements the wait group, + // which hasn't been incremented yet for this message, and shouldn't be + pErr := &ProducerError{Msg: msg, Err: ErrShuttingDown} + if p.conf.Producer.Return.Errors { + p.errors <- pErr + } else { + Logger.Println(pErr) + } + continue + } + p.inFlight.Add(1) + } + + if msg.byteSize() > p.conf.Producer.MaxMessageBytes { + p.returnError(msg, ErrMessageSizeTooLarge) + continue + } + + handler := handlers[msg.Topic] + if handler == nil { + handler = p.newTopicProducer(msg.Topic) + handlers[msg.Topic] = handler + } + + handler <- msg + } + + for _, handler := range handlers { + close(handler) + } +} + +// one per topic +// partitions messages, then dispatches them by partition +type topicProducer struct { + parent *asyncProducer + topic string + input <-chan *ProducerMessage + + breaker *breaker.Breaker + handlers map[int32]chan<- *ProducerMessage + partitioner Partitioner +} + +func (p *asyncProducer) newTopicProducer(topic string) chan<- *ProducerMessage { + input := make(chan *ProducerMessage, p.conf.ChannelBufferSize) + tp := &topicProducer{ + parent: p, + topic: topic, + input: input, + breaker: breaker.New(3, 1, 10*time.Second), + handlers: make(map[int32]chan<- *ProducerMessage), + partitioner: p.conf.Producer.Partitioner(topic), + } + go withRecover(tp.dispatch) + return input +} + +func (tp *topicProducer) dispatch() { + for msg := range tp.input { + if msg.retries == 0 { + if err := tp.partitionMessage(msg); err != nil { + tp.parent.returnError(msg, err) + continue + } + } + + handler := tp.handlers[msg.Partition] + if handler == nil { + handler = tp.parent.newPartitionProducer(msg.Topic, msg.Partition) + tp.handlers[msg.Partition] = handler + } + + handler <- msg + } + + for _, handler := range tp.handlers { + close(handler) + } +} + +func (tp *topicProducer) partitionMessage(msg *ProducerMessage) error { + var partitions []int32 + + err := tp.breaker.Run(func() (err error) { + if tp.partitioner.RequiresConsistency() { + partitions, err = tp.parent.client.Partitions(msg.Topic) + } else { + partitions, err = tp.parent.client.WritablePartitions(msg.Topic) + } + return + }) + + if err != nil { + return err + } + + numPartitions := int32(len(partitions)) + + if numPartitions == 0 { + return ErrLeaderNotAvailable + } + + choice, err := tp.partitioner.Partition(msg, numPartitions) + + if err != nil { + return err + } else if choice < 0 || choice >= numPartitions { + return ErrInvalidPartition + } + + msg.Partition = partitions[choice] + + return nil +} + +// one per partition per topic +// dispatches messages to the appropriate broker +// also responsible for maintaining message order during retries +type partitionProducer struct { + parent *asyncProducer + topic string + partition int32 + input <-chan *ProducerMessage + + leader *Broker + breaker *breaker.Breaker + output chan<- *ProducerMessage + + // highWatermark tracks the "current" retry level, which is the only one where we actually let messages through, + // all other messages get buffered in retryState[msg.retries].buf to preserve ordering + // retryState[msg.retries].expectChaser simply tracks whether we've seen a fin message for a given level (and + // therefore whether our buffer is complete and safe to flush) + highWatermark int + retryState []partitionRetryState +} + +type partitionRetryState struct { + buf []*ProducerMessage + expectChaser bool +} + +func (p *asyncProducer) newPartitionProducer(topic string, partition int32) chan<- *ProducerMessage { + input := make(chan *ProducerMessage, p.conf.ChannelBufferSize) + pp := &partitionProducer{ + parent: p, + topic: topic, + partition: partition, + input: input, + + breaker: breaker.New(3, 1, 10*time.Second), + retryState: make([]partitionRetryState, p.conf.Producer.Retry.Max+1), + } + go withRecover(pp.dispatch) + return input +} + +func (pp *partitionProducer) dispatch() { + // try to prefetch the leader; if this doesn't work, we'll do a proper call to `updateLeader` + // on the first message + pp.leader, _ = pp.parent.client.Leader(pp.topic, pp.partition) + if pp.leader != nil { + pp.output = pp.parent.getBrokerProducer(pp.leader) + pp.parent.inFlight.Add(1) // we're generating a syn message; track it so we don't shut down while it's still inflight + pp.output <- &ProducerMessage{Topic: pp.topic, Partition: pp.partition, flags: syn} + } + + for msg := range pp.input { + if msg.retries > pp.highWatermark { + // a new, higher, retry level; handle it and then back off + pp.newHighWatermark(msg.retries) + time.Sleep(pp.parent.conf.Producer.Retry.Backoff) + } else if pp.highWatermark > 0 { + // we are retrying something (else highWatermark would be 0) but this message is not a *new* retry level + if msg.retries < pp.highWatermark { + // in fact this message is not even the current retry level, so buffer it for now (unless it's a just a fin) + if msg.flags&fin == fin { + pp.retryState[msg.retries].expectChaser = false + pp.parent.inFlight.Done() // this fin is now handled and will be garbage collected + } else { + pp.retryState[msg.retries].buf = append(pp.retryState[msg.retries].buf, msg) + } + continue + } else if msg.flags&fin == fin { + // this message is of the current retry level (msg.retries == highWatermark) and the fin flag is set, + // meaning this retry level is done and we can go down (at least) one level and flush that + pp.retryState[pp.highWatermark].expectChaser = false + pp.flushRetryBuffers() + pp.parent.inFlight.Done() // this fin is now handled and will be garbage collected + continue + } + } + + // if we made it this far then the current msg contains real data, and can be sent to the next goroutine + // without breaking any of our ordering guarantees + + if pp.output == nil { + if err := pp.updateLeader(); err != nil { + pp.parent.returnError(msg, err) + time.Sleep(pp.parent.conf.Producer.Retry.Backoff) + continue + } + Logger.Printf("producer/leader/%s/%d selected broker %d\n", pp.topic, pp.partition, pp.leader.ID()) + } + + pp.output <- msg + } + + if pp.output != nil { + pp.parent.unrefBrokerProducer(pp.leader, pp.output) + } +} + +func (pp *partitionProducer) newHighWatermark(hwm int) { + Logger.Printf("producer/leader/%s/%d state change to [retrying-%d]\n", pp.topic, pp.partition, hwm) + pp.highWatermark = hwm + + // send off a fin so that we know when everything "in between" has made it + // back to us and we can safely flush the backlog (otherwise we risk re-ordering messages) + pp.retryState[pp.highWatermark].expectChaser = true + pp.parent.inFlight.Add(1) // we're generating a fin message; track it so we don't shut down while it's still inflight + pp.output <- &ProducerMessage{Topic: pp.topic, Partition: pp.partition, flags: fin, retries: pp.highWatermark - 1} + + // a new HWM means that our current broker selection is out of date + Logger.Printf("producer/leader/%s/%d abandoning broker %d\n", pp.topic, pp.partition, pp.leader.ID()) + pp.parent.unrefBrokerProducer(pp.leader, pp.output) + pp.output = nil +} + +func (pp *partitionProducer) flushRetryBuffers() { + Logger.Printf("producer/leader/%s/%d state change to [flushing-%d]\n", pp.topic, pp.partition, pp.highWatermark) + for { + pp.highWatermark-- + + if pp.output == nil { + if err := pp.updateLeader(); err != nil { + pp.parent.returnErrors(pp.retryState[pp.highWatermark].buf, err) + goto flushDone + } + Logger.Printf("producer/leader/%s/%d selected broker %d\n", pp.topic, pp.partition, pp.leader.ID()) + } + + for _, msg := range pp.retryState[pp.highWatermark].buf { + pp.output <- msg + } + + flushDone: + pp.retryState[pp.highWatermark].buf = nil + if pp.retryState[pp.highWatermark].expectChaser { + Logger.Printf("producer/leader/%s/%d state change to [retrying-%d]\n", pp.topic, pp.partition, pp.highWatermark) + break + } else if pp.highWatermark == 0 { + Logger.Printf("producer/leader/%s/%d state change to [normal]\n", pp.topic, pp.partition) + break + } + } +} + +func (pp *partitionProducer) updateLeader() error { + return pp.breaker.Run(func() (err error) { + if err = pp.parent.client.RefreshMetadata(pp.topic); err != nil { + return err + } + + if pp.leader, err = pp.parent.client.Leader(pp.topic, pp.partition); err != nil { + return err + } + + pp.output = pp.parent.getBrokerProducer(pp.leader) + pp.parent.inFlight.Add(1) // we're generating a syn message; track it so we don't shut down while it's still inflight + pp.output <- &ProducerMessage{Topic: pp.topic, Partition: pp.partition, flags: syn} + + return nil + }) +} + +// one per broker; also constructs an associated flusher +func (p *asyncProducer) newBrokerProducer(broker *Broker) chan<- *ProducerMessage { + var ( + input = make(chan *ProducerMessage) + bridge = make(chan *produceSet) + responses = make(chan *brokerProducerResponse) + ) + + bp := &brokerProducer{ + parent: p, + broker: broker, + input: input, + output: bridge, + responses: responses, + buffer: newProduceSet(p), + currentRetries: make(map[string]map[int32]error), + } + go withRecover(bp.run) + + // minimal bridge to make the network response `select`able + go withRecover(func() { + for set := range bridge { + request := set.buildRequest() + + response, err := broker.Produce(request) + + responses <- &brokerProducerResponse{ + set: set, + err: err, + res: response, + } + } + close(responses) + }) + + return input +} + +type brokerProducerResponse struct { + set *produceSet + err error + res *ProduceResponse +} + +// groups messages together into appropriately-sized batches for sending to the broker +// handles state related to retries etc +type brokerProducer struct { + parent *asyncProducer + broker *Broker + + input <-chan *ProducerMessage + output chan<- *produceSet + responses <-chan *brokerProducerResponse + + buffer *produceSet + timer <-chan time.Time + timerFired bool + + closing error + currentRetries map[string]map[int32]error +} + +func (bp *brokerProducer) run() { + var output chan<- *produceSet + Logger.Printf("producer/broker/%d starting up\n", bp.broker.ID()) + + for { + select { + case msg := <-bp.input: + if msg == nil { + bp.shutdown() + return + } + + if msg.flags&syn == syn { + Logger.Printf("producer/broker/%d state change to [open] on %s/%d\n", + bp.broker.ID(), msg.Topic, msg.Partition) + if bp.currentRetries[msg.Topic] == nil { + bp.currentRetries[msg.Topic] = make(map[int32]error) + } + bp.currentRetries[msg.Topic][msg.Partition] = nil + bp.parent.inFlight.Done() + continue + } + + if reason := bp.needsRetry(msg); reason != nil { + bp.parent.retryMessage(msg, reason) + + if bp.closing == nil && msg.flags&fin == fin { + // we were retrying this partition but we can start processing again + delete(bp.currentRetries[msg.Topic], msg.Partition) + Logger.Printf("producer/broker/%d state change to [closed] on %s/%d\n", + bp.broker.ID(), msg.Topic, msg.Partition) + } + + continue + } + + if bp.buffer.wouldOverflow(msg) { + if err := bp.waitForSpace(msg); err != nil { + bp.parent.retryMessage(msg, err) + continue + } + } + + if err := bp.buffer.add(msg); err != nil { + bp.parent.returnError(msg, err) + continue + } + + if bp.parent.conf.Producer.Flush.Frequency > 0 && bp.timer == nil { + bp.timer = time.After(bp.parent.conf.Producer.Flush.Frequency) + } + case <-bp.timer: + bp.timerFired = true + case output <- bp.buffer: + bp.rollOver() + case response := <-bp.responses: + bp.handleResponse(response) + } + + if bp.timerFired || bp.buffer.readyToFlush() { + output = bp.output + } else { + output = nil + } + } +} + +func (bp *brokerProducer) shutdown() { + for !bp.buffer.empty() { + select { + case response := <-bp.responses: + bp.handleResponse(response) + case bp.output <- bp.buffer: + bp.rollOver() + } + } + close(bp.output) + for response := range bp.responses { + bp.handleResponse(response) + } + + Logger.Printf("producer/broker/%d shut down\n", bp.broker.ID()) +} + +func (bp *brokerProducer) needsRetry(msg *ProducerMessage) error { + if bp.closing != nil { + return bp.closing + } + + return bp.currentRetries[msg.Topic][msg.Partition] +} + +func (bp *brokerProducer) waitForSpace(msg *ProducerMessage) error { + Logger.Printf("producer/broker/%d maximum request accumulated, waiting for space\n", bp.broker.ID()) + + for { + select { + case response := <-bp.responses: + bp.handleResponse(response) + // handling a response can change our state, so re-check some things + if reason := bp.needsRetry(msg); reason != nil { + return reason + } else if !bp.buffer.wouldOverflow(msg) { + return nil + } + case bp.output <- bp.buffer: + bp.rollOver() + return nil + } + } +} + +func (bp *brokerProducer) rollOver() { + bp.timer = nil + bp.timerFired = false + bp.buffer = newProduceSet(bp.parent) +} + +func (bp *brokerProducer) handleResponse(response *brokerProducerResponse) { + if response.err != nil { + bp.handleError(response.set, response.err) + } else { + bp.handleSuccess(response.set, response.res) + } + + if bp.buffer.empty() { + bp.rollOver() // this can happen if the response invalidated our buffer + } +} + +func (bp *brokerProducer) handleSuccess(sent *produceSet, response *ProduceResponse) { + // we iterate through the blocks in the request set, not the response, so that we notice + // if the response is missing a block completely + sent.eachPartition(func(topic string, partition int32, msgs []*ProducerMessage) { + if response == nil { + // this only happens when RequiredAcks is NoResponse, so we have to assume success + bp.parent.returnSuccesses(msgs) + return + } + + block := response.GetBlock(topic, partition) + if block == nil { + bp.parent.returnErrors(msgs, ErrIncompleteResponse) + return + } + + switch block.Err { + // Success + case ErrNoError: + for i, msg := range msgs { + msg.Offset = block.Offset + int64(i) + } + bp.parent.returnSuccesses(msgs) + // Retriable errors + case ErrInvalidMessage, ErrUnknownTopicOrPartition, ErrLeaderNotAvailable, ErrNotLeaderForPartition, + ErrRequestTimedOut, ErrNotEnoughReplicas, ErrNotEnoughReplicasAfterAppend: + Logger.Printf("producer/broker/%d state change to [retrying] on %s/%d because %v\n", + bp.broker.ID(), topic, partition, block.Err) + bp.currentRetries[topic][partition] = block.Err + bp.parent.retryMessages(msgs, block.Err) + bp.parent.retryMessages(bp.buffer.dropPartition(topic, partition), block.Err) + // Other non-retriable errors + default: + bp.parent.returnErrors(msgs, block.Err) + } + }) +} + +func (bp *brokerProducer) handleError(sent *produceSet, err error) { + switch err.(type) { + case PacketEncodingError: + sent.eachPartition(func(topic string, partition int32, msgs []*ProducerMessage) { + bp.parent.returnErrors(msgs, err) + }) + default: + Logger.Printf("producer/broker/%d state change to [closing] because %s\n", bp.broker.ID(), err) + bp.parent.abandonBrokerConnection(bp.broker) + _ = bp.broker.Close() + bp.closing = err + sent.eachPartition(func(topic string, partition int32, msgs []*ProducerMessage) { + bp.parent.retryMessages(msgs, err) + }) + bp.buffer.eachPartition(func(topic string, partition int32, msgs []*ProducerMessage) { + bp.parent.retryMessages(msgs, err) + }) + bp.rollOver() + } +} + +// singleton +// effectively a "bridge" between the flushers and the dispatcher in order to avoid deadlock +// based on https://godoc.org/github.com/eapache/channels#InfiniteChannel +func (p *asyncProducer) retryHandler() { + var msg *ProducerMessage + buf := queue.New() + + for { + if buf.Length() == 0 { + msg = <-p.retries + } else { + select { + case msg = <-p.retries: + case p.input <- buf.Peek().(*ProducerMessage): + buf.Remove() + continue + } + } + + if msg == nil { + return + } + + buf.Add(msg) + } +} + +// utility functions + +func (p *asyncProducer) shutdown() { + Logger.Println("Producer shutting down.") + p.inFlight.Add(1) + p.input <- &ProducerMessage{flags: shutdown} + + p.inFlight.Wait() + + if p.ownClient { + err := p.client.Close() + if err != nil { + Logger.Println("producer/shutdown failed to close the embedded client:", err) + } + } + + close(p.input) + close(p.retries) + close(p.errors) + close(p.successes) +} + +func (p *asyncProducer) returnError(msg *ProducerMessage, err error) { + msg.clear() + pErr := &ProducerError{Msg: msg, Err: err} + if p.conf.Producer.Return.Errors { + p.errors <- pErr + } else { + Logger.Println(pErr) + } + p.inFlight.Done() +} + +func (p *asyncProducer) returnErrors(batch []*ProducerMessage, err error) { + for _, msg := range batch { + p.returnError(msg, err) + } +} + +func (p *asyncProducer) returnSuccesses(batch []*ProducerMessage) { + for _, msg := range batch { + if p.conf.Producer.Return.Successes { + msg.clear() + p.successes <- msg + } + p.inFlight.Done() + } +} + +func (p *asyncProducer) retryMessage(msg *ProducerMessage, err error) { + if msg.retries >= p.conf.Producer.Retry.Max { + p.returnError(msg, err) + } else { + msg.retries++ + p.retries <- msg + } +} + +func (p *asyncProducer) retryMessages(batch []*ProducerMessage, err error) { + for _, msg := range batch { + p.retryMessage(msg, err) + } +} + +func (p *asyncProducer) getBrokerProducer(broker *Broker) chan<- *ProducerMessage { + p.brokerLock.Lock() + defer p.brokerLock.Unlock() + + bp := p.brokers[broker] + + if bp == nil { + bp = p.newBrokerProducer(broker) + p.brokers[broker] = bp + p.brokerRefs[bp] = 0 + } + + p.brokerRefs[bp]++ + + return bp +} + +func (p *asyncProducer) unrefBrokerProducer(broker *Broker, bp chan<- *ProducerMessage) { + p.brokerLock.Lock() + defer p.brokerLock.Unlock() + + p.brokerRefs[bp]-- + if p.brokerRefs[bp] == 0 { + close(bp) + delete(p.brokerRefs, bp) + + if p.brokers[broker] == bp { + delete(p.brokers, broker) + } + } +} + +func (p *asyncProducer) abandonBrokerConnection(broker *Broker) { + p.brokerLock.Lock() + defer p.brokerLock.Unlock() + + delete(p.brokers, broker) +} diff --git a/vendor/github.com/Shopify/sarama/broker.go b/vendor/github.com/Shopify/sarama/broker.go new file mode 100644 index 0000000..c4596f9 --- /dev/null +++ b/vendor/github.com/Shopify/sarama/broker.go @@ -0,0 +1,456 @@ +package sarama + +import ( + "crypto/tls" + "fmt" + "io" + "net" + "strconv" + "sync" + "sync/atomic" + "time" +) + +// Broker represents a single Kafka broker connection. All operations on this object are entirely concurrency-safe. +type Broker struct { + id int32 + addr string + + conf *Config + correlationID int32 + conn net.Conn + connErr error + lock sync.Mutex + opened int32 + + responses chan responsePromise + done chan bool +} + +type responsePromise struct { + correlationID int32 + packets chan []byte + errors chan error +} + +// NewBroker creates and returns a Broker targetting the given host:port address. +// This does not attempt to actually connect, you have to call Open() for that. +func NewBroker(addr string) *Broker { + return &Broker{id: -1, addr: addr} +} + +// Open tries to connect to the Broker if it is not already connected or connecting, but does not block +// waiting for the connection to complete. This means that any subsequent operations on the broker will +// block waiting for the connection to succeed or fail. To get the effect of a fully synchronous Open call, +// follow it by a call to Connected(). The only errors Open will return directly are ConfigurationError or +// AlreadyConnected. If conf is nil, the result of NewConfig() is used. +func (b *Broker) Open(conf *Config) error { + if !atomic.CompareAndSwapInt32(&b.opened, 0, 1) { + return ErrAlreadyConnected + } + + if conf == nil { + conf = NewConfig() + } + + err := conf.Validate() + if err != nil { + return err + } + + b.lock.Lock() + + go withRecover(func() { + defer b.lock.Unlock() + + dialer := net.Dialer{ + Timeout: conf.Net.DialTimeout, + KeepAlive: conf.Net.KeepAlive, + } + + if conf.Net.TLS.Enable { + b.conn, b.connErr = tls.DialWithDialer(&dialer, "tcp", b.addr, conf.Net.TLS.Config) + } else { + b.conn, b.connErr = dialer.Dial("tcp", b.addr) + } + if b.connErr != nil { + Logger.Printf("Failed to connect to broker %s: %s\n", b.addr, b.connErr) + b.conn = nil + atomic.StoreInt32(&b.opened, 0) + return + } + b.conn = newBufConn(b.conn) + + b.conf = conf + b.done = make(chan bool) + b.responses = make(chan responsePromise, b.conf.Net.MaxOpenRequests-1) + + if b.id >= 0 { + Logger.Printf("Connected to broker at %s (registered as #%d)\n", b.addr, b.id) + } else { + Logger.Printf("Connected to broker at %s (unregistered)\n", b.addr) + } + go withRecover(b.responseReceiver) + }) + + return nil +} + +// Connected returns true if the broker is connected and false otherwise. If the broker is not +// connected but it had tried to connect, the error from that connection attempt is also returned. +func (b *Broker) Connected() (bool, error) { + b.lock.Lock() + defer b.lock.Unlock() + + return b.conn != nil, b.connErr +} + +func (b *Broker) Close() error { + b.lock.Lock() + defer b.lock.Unlock() + + if b.conn == nil { + return ErrNotConnected + } + + close(b.responses) + <-b.done + + err := b.conn.Close() + + b.conn = nil + b.connErr = nil + b.done = nil + b.responses = nil + + if err == nil { + Logger.Printf("Closed connection to broker %s\n", b.addr) + } else { + Logger.Printf("Error while closing connection to broker %s: %s\n", b.addr, err) + } + + atomic.StoreInt32(&b.opened, 0) + + return err +} + +// ID returns the broker ID retrieved from Kafka's metadata, or -1 if that is not known. +func (b *Broker) ID() int32 { + return b.id +} + +// Addr returns the broker address as either retrieved from Kafka's metadata or passed to NewBroker. +func (b *Broker) Addr() string { + return b.addr +} + +func (b *Broker) GetMetadata(request *MetadataRequest) (*MetadataResponse, error) { + response := new(MetadataResponse) + + err := b.sendAndReceive(request, response) + + if err != nil { + return nil, err + } + + return response, nil +} + +func (b *Broker) GetConsumerMetadata(request *ConsumerMetadataRequest) (*ConsumerMetadataResponse, error) { + response := new(ConsumerMetadataResponse) + + err := b.sendAndReceive(request, response) + + if err != nil { + return nil, err + } + + return response, nil +} + +func (b *Broker) GetAvailableOffsets(request *OffsetRequest) (*OffsetResponse, error) { + response := new(OffsetResponse) + + err := b.sendAndReceive(request, response) + + if err != nil { + return nil, err + } + + return response, nil +} + +func (b *Broker) Produce(request *ProduceRequest) (*ProduceResponse, error) { + var response *ProduceResponse + var err error + + if request.RequiredAcks == NoResponse { + err = b.sendAndReceive(request, nil) + } else { + response = new(ProduceResponse) + err = b.sendAndReceive(request, response) + } + + if err != nil { + return nil, err + } + + return response, nil +} + +func (b *Broker) Fetch(request *FetchRequest) (*FetchResponse, error) { + response := new(FetchResponse) + + err := b.sendAndReceive(request, response) + + if err != nil { + return nil, err + } + + return response, nil +} + +func (b *Broker) CommitOffset(request *OffsetCommitRequest) (*OffsetCommitResponse, error) { + response := new(OffsetCommitResponse) + + err := b.sendAndReceive(request, response) + + if err != nil { + return nil, err + } + + return response, nil +} + +func (b *Broker) FetchOffset(request *OffsetFetchRequest) (*OffsetFetchResponse, error) { + response := new(OffsetFetchResponse) + + err := b.sendAndReceive(request, response) + + if err != nil { + return nil, err + } + + return response, nil +} + +func (b *Broker) JoinGroup(request *JoinGroupRequest) (*JoinGroupResponse, error) { + response := new(JoinGroupResponse) + + err := b.sendAndReceive(request, response) + if err != nil { + return nil, err + } + + return response, nil +} + +func (b *Broker) SyncGroup(request *SyncGroupRequest) (*SyncGroupResponse, error) { + response := new(SyncGroupResponse) + + err := b.sendAndReceive(request, response) + if err != nil { + return nil, err + } + + return response, nil +} + +func (b *Broker) LeaveGroup(request *LeaveGroupRequest) (*LeaveGroupResponse, error) { + response := new(LeaveGroupResponse) + + err := b.sendAndReceive(request, response) + if err != nil { + return nil, err + } + + return response, nil +} + +func (b *Broker) Heartbeat(request *HeartbeatRequest) (*HeartbeatResponse, error) { + response := new(HeartbeatResponse) + + err := b.sendAndReceive(request, response) + if err != nil { + return nil, err + } + + return response, nil +} + +func (b *Broker) ListGroups(request *ListGroupsRequest) (*ListGroupsResponse, error) { + response := new(ListGroupsResponse) + + err := b.sendAndReceive(request, response) + if err != nil { + return nil, err + } + + return response, nil +} + +func (b *Broker) DescribeGroups(request *DescribeGroupsRequest) (*DescribeGroupsResponse, error) { + response := new(DescribeGroupsResponse) + + err := b.sendAndReceive(request, response) + if err != nil { + return nil, err + } + + return response, nil +} + +func (b *Broker) send(rb requestBody, promiseResponse bool) (*responsePromise, error) { + b.lock.Lock() + defer b.lock.Unlock() + + if b.conn == nil { + if b.connErr != nil { + return nil, b.connErr + } + return nil, ErrNotConnected + } + + req := &request{correlationID: b.correlationID, clientID: b.conf.ClientID, body: rb} + buf, err := encode(req) + if err != nil { + return nil, err + } + + err = b.conn.SetWriteDeadline(time.Now().Add(b.conf.Net.WriteTimeout)) + if err != nil { + return nil, err + } + + _, err = b.conn.Write(buf) + if err != nil { + return nil, err + } + b.correlationID++ + + if !promiseResponse { + return nil, nil + } + + promise := responsePromise{req.correlationID, make(chan []byte), make(chan error)} + b.responses <- promise + + return &promise, nil +} + +func (b *Broker) sendAndReceive(req requestBody, res decoder) error { + promise, err := b.send(req, res != nil) + + if err != nil { + return err + } + + if promise == nil { + return nil + } + + select { + case buf := <-promise.packets: + return decode(buf, res) + case err = <-promise.errors: + return err + } +} + +func (b *Broker) decode(pd packetDecoder) (err error) { + b.id, err = pd.getInt32() + if err != nil { + return err + } + + host, err := pd.getString() + if err != nil { + return err + } + + port, err := pd.getInt32() + if err != nil { + return err + } + + b.addr = net.JoinHostPort(host, fmt.Sprint(port)) + if _, _, err := net.SplitHostPort(b.addr); err != nil { + return err + } + + return nil +} + +func (b *Broker) encode(pe packetEncoder) (err error) { + + host, portstr, err := net.SplitHostPort(b.addr) + if err != nil { + return err + } + port, err := strconv.Atoi(portstr) + if err != nil { + return err + } + + pe.putInt32(b.id) + + err = pe.putString(host) + if err != nil { + return err + } + + pe.putInt32(int32(port)) + + return nil +} + +func (b *Broker) responseReceiver() { + var dead error + header := make([]byte, 8) + for response := range b.responses { + if dead != nil { + response.errors <- dead + continue + } + + err := b.conn.SetReadDeadline(time.Now().Add(b.conf.Net.ReadTimeout)) + if err != nil { + dead = err + response.errors <- err + continue + } + + _, err = io.ReadFull(b.conn, header) + if err != nil { + dead = err + response.errors <- err + continue + } + + decodedHeader := responseHeader{} + err = decode(header, &decodedHeader) + if err != nil { + dead = err + response.errors <- err + continue + } + if decodedHeader.correlationID != response.correlationID { + // TODO if decoded ID < cur ID, discard until we catch up + // TODO if decoded ID > cur ID, save it so when cur ID catches up we have a response + dead = PacketDecodingError{fmt.Sprintf("correlation ID didn't match, wanted %d, got %d", response.correlationID, decodedHeader.correlationID)} + response.errors <- dead + continue + } + + buf := make([]byte, decodedHeader.length-4) + _, err = io.ReadFull(b.conn, buf) + if err != nil { + dead = err + response.errors <- err + continue + } + + response.packets <- buf + } + close(b.done) +} diff --git a/vendor/github.com/Shopify/sarama/client.go b/vendor/github.com/Shopify/sarama/client.go new file mode 100644 index 0000000..6643d66 --- /dev/null +++ b/vendor/github.com/Shopify/sarama/client.go @@ -0,0 +1,733 @@ +package sarama + +import ( + "math/rand" + "sort" + "sync" + "time" +) + +// Client is a generic Kafka client. It manages connections to one or more Kafka brokers. +// You MUST call Close() on a client to avoid leaks, it will not be garbage-collected +// automatically when it passes out of scope. It is safe to share a client amongst many +// users, however Kafka will process requests from a single client strictly in serial, +// so it is generally more efficient to use the default one client per producer/consumer. +type Client interface { + // Config returns the Config struct of the client. This struct should not be + // altered after it has been created. + Config() *Config + + // Topics returns the set of available topics as retrieved from cluster metadata. + Topics() ([]string, error) + + // Partitions returns the sorted list of all partition IDs for the given topic. + Partitions(topic string) ([]int32, error) + + // WritablePartitions returns the sorted list of all writable partition IDs for + // the given topic, where "writable" means "having a valid leader accepting + // writes". + WritablePartitions(topic string) ([]int32, error) + + // Leader returns the broker object that is the leader of the current + // topic/partition, as determined by querying the cluster metadata. + Leader(topic string, partitionID int32) (*Broker, error) + + // Replicas returns the set of all replica IDs for the given partition. + Replicas(topic string, partitionID int32) ([]int32, error) + + // RefreshMetadata takes a list of topics and queries the cluster to refresh the + // available metadata for those topics. If no topics are provided, it will refresh + // metadata for all topics. + RefreshMetadata(topics ...string) error + + // GetOffset queries the cluster to get the most recent available offset at the + // given time on the topic/partition combination. Time should be OffsetOldest for + // the earliest available offset, OffsetNewest for the offset of the message that + // will be produced next, or a time. + GetOffset(topic string, partitionID int32, time int64) (int64, error) + + // Coordinator returns the coordinating broker for a consumer group. It will + // return a locally cached value if it's available. You can call + // RefreshCoordinator to update the cached value. This function only works on + // Kafka 0.8.2 and higher. + Coordinator(consumerGroup string) (*Broker, error) + + // RefreshCoordinator retrieves the coordinator for a consumer group and stores it + // in local cache. This function only works on Kafka 0.8.2 and higher. + RefreshCoordinator(consumerGroup string) error + + // Close shuts down all broker connections managed by this client. It is required + // to call this function before a client object passes out of scope, as it will + // otherwise leak memory. You must close any Producers or Consumers using a client + // before you close the client. + Close() error + + // Closed returns true if the client has already had Close called on it + Closed() bool +} + +const ( + // OffsetNewest stands for the log head offset, i.e. the offset that will be + // assigned to the next message that will be produced to the partition. You + // can send this to a client's GetOffset method to get this offset, or when + // calling ConsumePartition to start consuming new messages. + OffsetNewest int64 = -1 + // OffsetOldest stands for the oldest offset available on the broker for a + // partition. You can send this to a client's GetOffset method to get this + // offset, or when calling ConsumePartition to start consuming from the + // oldest offset that is still available on the broker. + OffsetOldest int64 = -2 +) + +type client struct { + conf *Config + closer, closed chan none // for shutting down background metadata updater + + // the broker addresses given to us through the constructor are not guaranteed to be returned in + // the cluster metadata (I *think* it only returns brokers who are currently leading partitions?) + // so we store them separately + seedBrokers []*Broker + deadSeeds []*Broker + + brokers map[int32]*Broker // maps broker ids to brokers + metadata map[string]map[int32]*PartitionMetadata // maps topics to partition ids to metadata + coordinators map[string]int32 // Maps consumer group names to coordinating broker IDs + + // If the number of partitions is large, we can get some churn calling cachedPartitions, + // so the result is cached. It is important to update this value whenever metadata is changed + cachedPartitionsResults map[string][maxPartitionIndex][]int32 + + lock sync.RWMutex // protects access to the maps that hold cluster state. +} + +// NewClient creates a new Client. It connects to one of the given broker addresses +// and uses that broker to automatically fetch metadata on the rest of the kafka cluster. If metadata cannot +// be retrieved from any of the given broker addresses, the client is not created. +func NewClient(addrs []string, conf *Config) (Client, error) { + Logger.Println("Initializing new client") + + if conf == nil { + conf = NewConfig() + } + + if err := conf.Validate(); err != nil { + return nil, err + } + + if len(addrs) < 1 { + return nil, ConfigurationError("You must provide at least one broker address") + } + + client := &client{ + conf: conf, + closer: make(chan none), + closed: make(chan none), + brokers: make(map[int32]*Broker), + metadata: make(map[string]map[int32]*PartitionMetadata), + cachedPartitionsResults: make(map[string][maxPartitionIndex][]int32), + coordinators: make(map[string]int32), + } + + random := rand.New(rand.NewSource(time.Now().UnixNano())) + for _, index := range random.Perm(len(addrs)) { + client.seedBrokers = append(client.seedBrokers, NewBroker(addrs[index])) + } + + // do an initial fetch of all cluster metadata by specifing an empty list of topics + err := client.RefreshMetadata() + switch err { + case nil: + break + case ErrLeaderNotAvailable, ErrReplicaNotAvailable: + // indicates that maybe part of the cluster is down, but is not fatal to creating the client + Logger.Println(err) + default: + close(client.closed) // we haven't started the background updater yet, so we have to do this manually + _ = client.Close() + return nil, err + } + go withRecover(client.backgroundMetadataUpdater) + + Logger.Println("Successfully initialized new client") + + return client, nil +} + +func (client *client) Config() *Config { + return client.conf +} + +func (client *client) Close() error { + if client.Closed() { + // Chances are this is being called from a defer() and the error will go unobserved + // so we go ahead and log the event in this case. + Logger.Printf("Close() called on already closed client") + return ErrClosedClient + } + + // shutdown and wait for the background thread before we take the lock, to avoid races + close(client.closer) + <-client.closed + + client.lock.Lock() + defer client.lock.Unlock() + Logger.Println("Closing Client") + + for _, broker := range client.brokers { + safeAsyncClose(broker) + } + + for _, broker := range client.seedBrokers { + safeAsyncClose(broker) + } + + client.brokers = nil + client.metadata = nil + + return nil +} + +func (client *client) Closed() bool { + return client.brokers == nil +} + +func (client *client) Topics() ([]string, error) { + if client.Closed() { + return nil, ErrClosedClient + } + + client.lock.RLock() + defer client.lock.RUnlock() + + ret := make([]string, 0, len(client.metadata)) + for topic := range client.metadata { + ret = append(ret, topic) + } + + return ret, nil +} + +func (client *client) Partitions(topic string) ([]int32, error) { + if client.Closed() { + return nil, ErrClosedClient + } + + partitions := client.cachedPartitions(topic, allPartitions) + + if len(partitions) == 0 { + err := client.RefreshMetadata(topic) + if err != nil { + return nil, err + } + partitions = client.cachedPartitions(topic, allPartitions) + } + + if partitions == nil { + return nil, ErrUnknownTopicOrPartition + } + + return partitions, nil +} + +func (client *client) WritablePartitions(topic string) ([]int32, error) { + if client.Closed() { + return nil, ErrClosedClient + } + + partitions := client.cachedPartitions(topic, writablePartitions) + + // len==0 catches when it's nil (no such topic) and the odd case when every single + // partition is undergoing leader election simultaneously. Callers have to be able to handle + // this function returning an empty slice (which is a valid return value) but catching it + // here the first time (note we *don't* catch it below where we return ErrUnknownTopicOrPartition) triggers + // a metadata refresh as a nicety so callers can just try again and don't have to manually + // trigger a refresh (otherwise they'd just keep getting a stale cached copy). + if len(partitions) == 0 { + err := client.RefreshMetadata(topic) + if err != nil { + return nil, err + } + partitions = client.cachedPartitions(topic, writablePartitions) + } + + if partitions == nil { + return nil, ErrUnknownTopicOrPartition + } + + return partitions, nil +} + +func (client *client) Replicas(topic string, partitionID int32) ([]int32, error) { + if client.Closed() { + return nil, ErrClosedClient + } + + metadata := client.cachedMetadata(topic, partitionID) + + if metadata == nil { + err := client.RefreshMetadata(topic) + if err != nil { + return nil, err + } + metadata = client.cachedMetadata(topic, partitionID) + } + + if metadata == nil { + return nil, ErrUnknownTopicOrPartition + } + + if metadata.Err == ErrReplicaNotAvailable { + return nil, metadata.Err + } + return dupeAndSort(metadata.Replicas), nil +} + +func (client *client) Leader(topic string, partitionID int32) (*Broker, error) { + if client.Closed() { + return nil, ErrClosedClient + } + + leader, err := client.cachedLeader(topic, partitionID) + + if leader == nil { + err := client.RefreshMetadata(topic) + if err != nil { + return nil, err + } + leader, err = client.cachedLeader(topic, partitionID) + } + + return leader, err +} + +func (client *client) RefreshMetadata(topics ...string) error { + if client.Closed() { + return ErrClosedClient + } + + // Prior to 0.8.2, Kafka will throw exceptions on an empty topic and not return a proper + // error. This handles the case by returning an error instead of sending it + // off to Kafka. See: https://github.com/Shopify/sarama/pull/38#issuecomment-26362310 + for _, topic := range topics { + if len(topic) == 0 { + return ErrInvalidTopic // this is the error that 0.8.2 and later correctly return + } + } + + return client.tryRefreshMetadata(topics, client.conf.Metadata.Retry.Max) +} + +func (client *client) GetOffset(topic string, partitionID int32, time int64) (int64, error) { + if client.Closed() { + return -1, ErrClosedClient + } + + offset, err := client.getOffset(topic, partitionID, time) + + if err != nil { + if err := client.RefreshMetadata(topic); err != nil { + return -1, err + } + return client.getOffset(topic, partitionID, time) + } + + return offset, err +} + +func (client *client) Coordinator(consumerGroup string) (*Broker, error) { + if client.Closed() { + return nil, ErrClosedClient + } + + coordinator := client.cachedCoordinator(consumerGroup) + + if coordinator == nil { + if err := client.RefreshCoordinator(consumerGroup); err != nil { + return nil, err + } + coordinator = client.cachedCoordinator(consumerGroup) + } + + if coordinator == nil { + return nil, ErrConsumerCoordinatorNotAvailable + } + + _ = coordinator.Open(client.conf) + return coordinator, nil +} + +func (client *client) RefreshCoordinator(consumerGroup string) error { + if client.Closed() { + return ErrClosedClient + } + + response, err := client.getConsumerMetadata(consumerGroup, client.conf.Metadata.Retry.Max) + if err != nil { + return err + } + + client.lock.Lock() + defer client.lock.Unlock() + client.registerBroker(response.Coordinator) + client.coordinators[consumerGroup] = response.Coordinator.ID() + return nil +} + +// private broker management helpers + +// registerBroker makes sure a broker received by a Metadata or Coordinator request is registered +// in the brokers map. It returns the broker that is registered, which may be the provided broker, +// or a previously registered Broker instance. You must hold the write lock before calling this function. +func (client *client) registerBroker(broker *Broker) { + if client.brokers[broker.ID()] == nil { + client.brokers[broker.ID()] = broker + Logger.Printf("client/brokers registered new broker #%d at %s", broker.ID(), broker.Addr()) + } else if broker.Addr() != client.brokers[broker.ID()].Addr() { + safeAsyncClose(client.brokers[broker.ID()]) + client.brokers[broker.ID()] = broker + Logger.Printf("client/brokers replaced registered broker #%d with %s", broker.ID(), broker.Addr()) + } +} + +// deregisterBroker removes a broker from the seedsBroker list, and if it's +// not the seedbroker, removes it from brokers map completely. +func (client *client) deregisterBroker(broker *Broker) { + client.lock.Lock() + defer client.lock.Unlock() + + if len(client.seedBrokers) > 0 && broker == client.seedBrokers[0] { + client.deadSeeds = append(client.deadSeeds, broker) + client.seedBrokers = client.seedBrokers[1:] + } else { + // we do this so that our loop in `tryRefreshMetadata` doesn't go on forever, + // but we really shouldn't have to; once that loop is made better this case can be + // removed, and the function generally can be renamed from `deregisterBroker` to + // `nextSeedBroker` or something + Logger.Printf("client/brokers deregistered broker #%d at %s", broker.ID(), broker.Addr()) + delete(client.brokers, broker.ID()) + } +} + +func (client *client) resurrectDeadBrokers() { + client.lock.Lock() + defer client.lock.Unlock() + + Logger.Printf("client/brokers resurrecting %d dead seed brokers", len(client.deadSeeds)) + client.seedBrokers = append(client.seedBrokers, client.deadSeeds...) + client.deadSeeds = nil +} + +func (client *client) any() *Broker { + client.lock.RLock() + defer client.lock.RUnlock() + + if len(client.seedBrokers) > 0 { + _ = client.seedBrokers[0].Open(client.conf) + return client.seedBrokers[0] + } + + // not guaranteed to be random *or* deterministic + for _, broker := range client.brokers { + _ = broker.Open(client.conf) + return broker + } + + return nil +} + +// private caching/lazy metadata helpers + +type partitionType int + +const ( + allPartitions partitionType = iota + writablePartitions + // If you add any more types, update the partition cache in update() + + // Ensure this is the last partition type value + maxPartitionIndex +) + +func (client *client) cachedMetadata(topic string, partitionID int32) *PartitionMetadata { + client.lock.RLock() + defer client.lock.RUnlock() + + partitions := client.metadata[topic] + if partitions != nil { + return partitions[partitionID] + } + + return nil +} + +func (client *client) cachedPartitions(topic string, partitionSet partitionType) []int32 { + client.lock.RLock() + defer client.lock.RUnlock() + + partitions, exists := client.cachedPartitionsResults[topic] + + if !exists { + return nil + } + return partitions[partitionSet] +} + +func (client *client) setPartitionCache(topic string, partitionSet partitionType) []int32 { + partitions := client.metadata[topic] + + if partitions == nil { + return nil + } + + ret := make([]int32, 0, len(partitions)) + for _, partition := range partitions { + if partitionSet == writablePartitions && partition.Err == ErrLeaderNotAvailable { + continue + } + ret = append(ret, partition.ID) + } + + sort.Sort(int32Slice(ret)) + return ret +} + +func (client *client) cachedLeader(topic string, partitionID int32) (*Broker, error) { + client.lock.RLock() + defer client.lock.RUnlock() + + partitions := client.metadata[topic] + if partitions != nil { + metadata, ok := partitions[partitionID] + if ok { + if metadata.Err == ErrLeaderNotAvailable { + return nil, ErrLeaderNotAvailable + } + b := client.brokers[metadata.Leader] + if b == nil { + return nil, ErrLeaderNotAvailable + } + _ = b.Open(client.conf) + return b, nil + } + } + + return nil, ErrUnknownTopicOrPartition +} + +func (client *client) getOffset(topic string, partitionID int32, time int64) (int64, error) { + broker, err := client.Leader(topic, partitionID) + if err != nil { + return -1, err + } + + request := &OffsetRequest{} + request.AddBlock(topic, partitionID, time, 1) + + response, err := broker.GetAvailableOffsets(request) + if err != nil { + _ = broker.Close() + return -1, err + } + + block := response.GetBlock(topic, partitionID) + if block == nil { + _ = broker.Close() + return -1, ErrIncompleteResponse + } + if block.Err != ErrNoError { + return -1, block.Err + } + if len(block.Offsets) != 1 { + return -1, ErrOffsetOutOfRange + } + + return block.Offsets[0], nil +} + +// core metadata update logic + +func (client *client) backgroundMetadataUpdater() { + defer close(client.closed) + + if client.conf.Metadata.RefreshFrequency == time.Duration(0) { + return + } + + ticker := time.NewTicker(client.conf.Metadata.RefreshFrequency) + defer ticker.Stop() + + for { + select { + case <-ticker.C: + if err := client.RefreshMetadata(); err != nil { + Logger.Println("Client background metadata update:", err) + } + case <-client.closer: + return + } + } +} + +func (client *client) tryRefreshMetadata(topics []string, attemptsRemaining int) error { + retry := func(err error) error { + if attemptsRemaining > 0 { + Logger.Printf("client/metadata retrying after %dms... (%d attempts remaining)\n", client.conf.Metadata.Retry.Backoff/time.Millisecond, attemptsRemaining) + time.Sleep(client.conf.Metadata.Retry.Backoff) + return client.tryRefreshMetadata(topics, attemptsRemaining-1) + } + return err + } + + for broker := client.any(); broker != nil; broker = client.any() { + if len(topics) > 0 { + Logger.Printf("client/metadata fetching metadata for %v from broker %s\n", topics, broker.addr) + } else { + Logger.Printf("client/metadata fetching metadata for all topics from broker %s\n", broker.addr) + } + response, err := broker.GetMetadata(&MetadataRequest{Topics: topics}) + + switch err.(type) { + case nil: + // valid response, use it + if shouldRetry, err := client.updateMetadata(response); shouldRetry { + Logger.Println("client/metadata found some partitions to be leaderless") + return retry(err) // note: err can be nil + } else { + return err + } + + case PacketEncodingError: + // didn't even send, return the error + return err + default: + // some other error, remove that broker and try again + Logger.Println("client/metadata got error from broker while fetching metadata:", err) + _ = broker.Close() + client.deregisterBroker(broker) + } + } + + Logger.Println("client/metadata no available broker to send metadata request to") + client.resurrectDeadBrokers() + return retry(ErrOutOfBrokers) +} + +// if no fatal error, returns a list of topics that need retrying due to ErrLeaderNotAvailable +func (client *client) updateMetadata(data *MetadataResponse) (retry bool, err error) { + client.lock.Lock() + defer client.lock.Unlock() + + // For all the brokers we received: + // - if it is a new ID, save it + // - if it is an existing ID, but the address we have is stale, discard the old one and save it + // - otherwise ignore it, replacing our existing one would just bounce the connection + for _, broker := range data.Brokers { + client.registerBroker(broker) + } + + for _, topic := range data.Topics { + delete(client.metadata, topic.Name) + delete(client.cachedPartitionsResults, topic.Name) + + switch topic.Err { + case ErrNoError: + break + case ErrInvalidTopic: // don't retry, don't store partial results + err = topic.Err + continue + case ErrUnknownTopicOrPartition: // retry, do not store partial partition results + err = topic.Err + retry = true + continue + case ErrLeaderNotAvailable: // retry, but store partial partition results + retry = true + break + default: // don't retry, don't store partial results + Logger.Printf("Unexpected topic-level metadata error: %s", topic.Err) + err = topic.Err + continue + } + + client.metadata[topic.Name] = make(map[int32]*PartitionMetadata, len(topic.Partitions)) + for _, partition := range topic.Partitions { + client.metadata[topic.Name][partition.ID] = partition + if partition.Err == ErrLeaderNotAvailable { + retry = true + } + } + + var partitionCache [maxPartitionIndex][]int32 + partitionCache[allPartitions] = client.setPartitionCache(topic.Name, allPartitions) + partitionCache[writablePartitions] = client.setPartitionCache(topic.Name, writablePartitions) + client.cachedPartitionsResults[topic.Name] = partitionCache + } + + return +} + +func (client *client) cachedCoordinator(consumerGroup string) *Broker { + client.lock.RLock() + defer client.lock.RUnlock() + if coordinatorID, ok := client.coordinators[consumerGroup]; ok { + return client.brokers[coordinatorID] + } + return nil +} + +func (client *client) getConsumerMetadata(consumerGroup string, attemptsRemaining int) (*ConsumerMetadataResponse, error) { + retry := func(err error) (*ConsumerMetadataResponse, error) { + if attemptsRemaining > 0 { + Logger.Printf("client/coordinator retrying after %dms... (%d attempts remaining)\n", client.conf.Metadata.Retry.Backoff/time.Millisecond, attemptsRemaining) + time.Sleep(client.conf.Metadata.Retry.Backoff) + return client.getConsumerMetadata(consumerGroup, attemptsRemaining-1) + } + return nil, err + } + + for broker := client.any(); broker != nil; broker = client.any() { + Logger.Printf("client/coordinator requesting coordinator for consumergoup %s from %s\n", consumerGroup, broker.Addr()) + + request := new(ConsumerMetadataRequest) + request.ConsumerGroup = consumerGroup + + response, err := broker.GetConsumerMetadata(request) + + if err != nil { + Logger.Printf("client/coordinator request to broker %s failed: %s\n", broker.Addr(), err) + + switch err.(type) { + case PacketEncodingError: + return nil, err + default: + _ = broker.Close() + client.deregisterBroker(broker) + continue + } + } + + switch response.Err { + case ErrNoError: + Logger.Printf("client/coordinator coordinator for consumergoup %s is #%d (%s)\n", consumerGroup, response.Coordinator.ID(), response.Coordinator.Addr()) + return response, nil + + case ErrConsumerCoordinatorNotAvailable: + Logger.Printf("client/coordinator coordinator for consumer group %s is not available\n", consumerGroup) + + // This is very ugly, but this scenario will only happen once per cluster. + // The __consumer_offsets topic only has to be created one time. + // The number of partitions not configurable, but partition 0 should always exist. + if _, err := client.Leader("__consumer_offsets", 0); err != nil { + Logger.Printf("client/coordinator the __consumer_offsets topic is not initialized completely yet. Waiting 2 seconds...\n") + time.Sleep(2 * time.Second) + } + + return retry(ErrConsumerCoordinatorNotAvailable) + default: + return nil, response.Err + } + } + + Logger.Println("client/coordinator no available broker to send consumer metadata request to") + client.resurrectDeadBrokers() + return retry(ErrOutOfBrokers) +} diff --git a/vendor/github.com/Shopify/sarama/config.go b/vendor/github.com/Shopify/sarama/config.go new file mode 100644 index 0000000..308c2bc --- /dev/null +++ b/vendor/github.com/Shopify/sarama/config.go @@ -0,0 +1,352 @@ +package sarama + +import ( + "crypto/tls" + "time" +) + +// Config is used to pass multiple configuration options to Sarama's constructors. +type Config struct { + // Net is the namespace for network-level properties used by the Broker, and + // shared by the Client/Producer/Consumer. + Net struct { + // How many outstanding requests a connection is allowed to have before + // sending on it blocks (default 5). + MaxOpenRequests int + + // All three of the below configurations are similar to the + // `socket.timeout.ms` setting in JVM kafka. All of them default + // to 30 seconds. + DialTimeout time.Duration // How long to wait for the initial connection. + ReadTimeout time.Duration // How long to wait for a response. + WriteTimeout time.Duration // How long to wait for a transmit. + + TLS struct { + // Whether or not to use TLS when connecting to the broker + // (defaults to false). + Enable bool + // The TLS configuration to use for secure connections if + // enabled (defaults to nil). + Config *tls.Config + } + + // KeepAlive specifies the keep-alive period for an active network connection. + // If zero, keep-alives are disabled. (default is 0: disabled). + KeepAlive time.Duration + } + + // Metadata is the namespace for metadata management properties used by the + // Client, and shared by the Producer/Consumer. + Metadata struct { + Retry struct { + // The total number of times to retry a metadata request when the + // cluster is in the middle of a leader election (default 3). + Max int + // How long to wait for leader election to occur before retrying + // (default 250ms). Similar to the JVM's `retry.backoff.ms`. + Backoff time.Duration + } + // How frequently to refresh the cluster metadata in the background. + // Defaults to 10 minutes. Set to 0 to disable. Similar to + // `topic.metadata.refresh.interval.ms` in the JVM version. + RefreshFrequency time.Duration + } + + // Producer is the namespace for configuration related to producing messages, + // used by the Producer. + Producer struct { + // The maximum permitted size of a message (defaults to 1000000). Should be + // set equal to or smaller than the broker's `message.max.bytes`. + MaxMessageBytes int + // The level of acknowledgement reliability needed from the broker (defaults + // to WaitForLocal). Equivalent to the `request.required.acks` setting of the + // JVM producer. + RequiredAcks RequiredAcks + // The maximum duration the broker will wait the receipt of the number of + // RequiredAcks (defaults to 10 seconds). This is only relevant when + // RequiredAcks is set to WaitForAll or a number > 1. Only supports + // millisecond resolution, nanoseconds will be truncated. Equivalent to + // the JVM producer's `request.timeout.ms` setting. + Timeout time.Duration + // The type of compression to use on messages (defaults to no compression). + // Similar to `compression.codec` setting of the JVM producer. + Compression CompressionCodec + // Generates partitioners for choosing the partition to send messages to + // (defaults to hashing the message key). Similar to the `partitioner.class` + // setting for the JVM producer. + Partitioner PartitionerConstructor + + // Return specifies what channels will be populated. If they are set to true, + // you must read from the respective channels to prevent deadlock. + Return struct { + // If enabled, successfully delivered messages will be returned on the + // Successes channel (default disabled). + Successes bool + + // If enabled, messages that failed to deliver will be returned on the + // Errors channel, including error (default enabled). + Errors bool + } + + // The following config options control how often messages are batched up and + // sent to the broker. By default, messages are sent as fast as possible, and + // all messages received while the current batch is in-flight are placed + // into the subsequent batch. + Flush struct { + // The best-effort number of bytes needed to trigger a flush. Use the + // global sarama.MaxRequestSize to set a hard upper limit. + Bytes int + // The best-effort number of messages needed to trigger a flush. Use + // `MaxMessages` to set a hard upper limit. + Messages int + // The best-effort frequency of flushes. Equivalent to + // `queue.buffering.max.ms` setting of JVM producer. + Frequency time.Duration + // The maximum number of messages the producer will send in a single + // broker request. Defaults to 0 for unlimited. Similar to + // `queue.buffering.max.messages` in the JVM producer. + MaxMessages int + } + + Retry struct { + // The total number of times to retry sending a message (default 3). + // Similar to the `message.send.max.retries` setting of the JVM producer. + Max int + // How long to wait for the cluster to settle between retries + // (default 100ms). Similar to the `retry.backoff.ms` setting of the + // JVM producer. + Backoff time.Duration + } + } + + // Consumer is the namespace for configuration related to consuming messages, + // used by the Consumer. + Consumer struct { + Retry struct { + // How long to wait after a failing to read from a partition before + // trying again (default 2s). + Backoff time.Duration + } + + // Fetch is the namespace for controlling how many bytes are retrieved by any + // given request. + Fetch struct { + // The minimum number of message bytes to fetch in a request - the broker + // will wait until at least this many are available. The default is 1, + // as 0 causes the consumer to spin when no messages are available. + // Equivalent to the JVM's `fetch.min.bytes`. + Min int32 + // The default number of message bytes to fetch from the broker in each + // request (default 32768). This should be larger than the majority of + // your messages, or else the consumer will spend a lot of time + // negotiating sizes and not actually consuming. Similar to the JVM's + // `fetch.message.max.bytes`. + Default int32 + // The maximum number of message bytes to fetch from the broker in a + // single request. Messages larger than this will return + // ErrMessageTooLarge and will not be consumable, so you must be sure + // this is at least as large as your largest message. Defaults to 0 + // (no limit). Similar to the JVM's `fetch.message.max.bytes`. The + // global `sarama.MaxResponseSize` still applies. + Max int32 + } + // The maximum amount of time the broker will wait for Consumer.Fetch.Min + // bytes to become available before it returns fewer than that anyways. The + // default is 250ms, since 0 causes the consumer to spin when no events are + // available. 100-500ms is a reasonable range for most cases. Kafka only + // supports precision up to milliseconds; nanoseconds will be truncated. + // Equivalent to the JVM's `fetch.wait.max.ms`. + MaxWaitTime time.Duration + + // The maximum amount of time the consumer expects a message takes to process + // for the user. If writing to the Messages channel takes longer than this, + // that partition will stop fetching more messages until it can proceed again. + // Note that, since the Messages channel is buffered, the actual grace time is + // (MaxProcessingTime * ChanneBufferSize). Defaults to 100ms. + MaxProcessingTime time.Duration + + // Return specifies what channels will be populated. If they are set to true, + // you must read from them to prevent deadlock. + Return struct { + // If enabled, any errors that occured while consuming are returned on + // the Errors channel (default disabled). + Errors bool + } + + // Offsets specifies configuration for how and when to commit consumed + // offsets. This currently requires the manual use of an OffsetManager + // but will eventually be automated. + Offsets struct { + // How frequently to commit updated offsets. Defaults to 1s. + CommitInterval time.Duration + + // The initial offset to use if no offset was previously committed. + // Should be OffsetNewest or OffsetOldest. Defaults to OffsetNewest. + Initial int64 + + // The retention duration for committed offsets. If zero, disabled + // (in which case the `offsets.retention.minutes` option on the + // broker will be used). Kafka only supports precision up to + // milliseconds; nanoseconds will be truncated. + // (default is 0: disabled). + Retention time.Duration + } + } + + // A user-provided string sent with every request to the brokers for logging, + // debugging, and auditing purposes. Defaults to "sarama", but you should + // probably set it to something specific to your application. + ClientID string + // The number of events to buffer in internal and external channels. This + // permits the producer and consumer to continue processing some messages + // in the background while user code is working, greatly improving throughput. + // Defaults to 256. + ChannelBufferSize int +} + +// NewConfig returns a new configuration instance with sane defaults. +func NewConfig() *Config { + c := &Config{} + + c.Net.MaxOpenRequests = 5 + c.Net.DialTimeout = 30 * time.Second + c.Net.ReadTimeout = 30 * time.Second + c.Net.WriteTimeout = 30 * time.Second + + c.Metadata.Retry.Max = 3 + c.Metadata.Retry.Backoff = 250 * time.Millisecond + c.Metadata.RefreshFrequency = 10 * time.Minute + + c.Producer.MaxMessageBytes = 1000000 + c.Producer.RequiredAcks = WaitForLocal + c.Producer.Timeout = 10 * time.Second + c.Producer.Partitioner = NewHashPartitioner + c.Producer.Retry.Max = 3 + c.Producer.Retry.Backoff = 100 * time.Millisecond + c.Producer.Return.Errors = true + + c.Consumer.Fetch.Min = 1 + c.Consumer.Fetch.Default = 32768 + c.Consumer.Retry.Backoff = 2 * time.Second + c.Consumer.MaxWaitTime = 250 * time.Millisecond + c.Consumer.MaxProcessingTime = 100 * time.Millisecond + c.Consumer.Return.Errors = false + c.Consumer.Offsets.CommitInterval = 1 * time.Second + c.Consumer.Offsets.Initial = OffsetNewest + + c.ChannelBufferSize = 256 + + return c +} + +// Validate checks a Config instance. It will return a +// ConfigurationError if the specified values don't make sense. +func (c *Config) Validate() error { + // some configuration values should be warned on but not fail completely, do those first + if c.Net.TLS.Enable == false && c.Net.TLS.Config != nil { + Logger.Println("Net.TLS is disabled but a non-nil configuration was provided.") + } + if c.Producer.RequiredAcks > 1 { + Logger.Println("Producer.RequiredAcks > 1 is deprecated and will raise an exception with kafka >= 0.8.2.0.") + } + if c.Producer.MaxMessageBytes >= int(MaxRequestSize) { + Logger.Println("Producer.MaxMessageBytes is larger than MaxRequestSize; it will be ignored.") + } + if c.Producer.Flush.Bytes >= int(MaxRequestSize) { + Logger.Println("Producer.Flush.Bytes is larger than MaxRequestSize; it will be ignored.") + } + if c.Producer.Timeout%time.Millisecond != 0 { + Logger.Println("Producer.Timeout only supports millisecond resolution; nanoseconds will be truncated.") + } + if c.Consumer.MaxWaitTime < 100*time.Millisecond { + Logger.Println("Consumer.MaxWaitTime is very low, which can cause high CPU and network usage. See documentation for details.") + } + if c.Consumer.MaxWaitTime%time.Millisecond != 0 { + Logger.Println("Consumer.MaxWaitTime only supports millisecond precision; nanoseconds will be truncated.") + } + if c.Consumer.Offsets.Retention%time.Millisecond != 0 { + Logger.Println("Consumer.Offsets.Retention only supports millisecond precision; nanoseconds will be truncated.") + } + if c.ClientID == "sarama" { + Logger.Println("ClientID is the default of 'sarama', you should consider setting it to something application-specific.") + } + + // validate Net values + switch { + case c.Net.MaxOpenRequests <= 0: + return ConfigurationError("Net.MaxOpenRequests must be > 0") + case c.Net.DialTimeout <= 0: + return ConfigurationError("Net.DialTimeout must be > 0") + case c.Net.ReadTimeout <= 0: + return ConfigurationError("Net.ReadTimeout must be > 0") + case c.Net.WriteTimeout <= 0: + return ConfigurationError("Net.WriteTimeout must be > 0") + case c.Net.KeepAlive < 0: + return ConfigurationError("Net.KeepAlive must be >= 0") + } + + // validate the Metadata values + switch { + case c.Metadata.Retry.Max < 0: + return ConfigurationError("Metadata.Retry.Max must be >= 0") + case c.Metadata.Retry.Backoff < 0: + return ConfigurationError("Metadata.Retry.Backoff must be >= 0") + case c.Metadata.RefreshFrequency < 0: + return ConfigurationError("Metadata.RefreshFrequency must be >= 0") + } + + // validate the Producer values + switch { + case c.Producer.MaxMessageBytes <= 0: + return ConfigurationError("Producer.MaxMessageBytes must be > 0") + case c.Producer.RequiredAcks < -1: + return ConfigurationError("Producer.RequiredAcks must be >= -1") + case c.Producer.Timeout <= 0: + return ConfigurationError("Producer.Timeout must be > 0") + case c.Producer.Partitioner == nil: + return ConfigurationError("Producer.Partitioner must not be nil") + case c.Producer.Flush.Bytes < 0: + return ConfigurationError("Producer.Flush.Bytes must be >= 0") + case c.Producer.Flush.Messages < 0: + return ConfigurationError("Producer.Flush.Messages must be >= 0") + case c.Producer.Flush.Frequency < 0: + return ConfigurationError("Producer.Flush.Frequency must be >= 0") + case c.Producer.Flush.MaxMessages < 0: + return ConfigurationError("Producer.Flush.MaxMessages must be >= 0") + case c.Producer.Flush.MaxMessages > 0 && c.Producer.Flush.MaxMessages < c.Producer.Flush.Messages: + return ConfigurationError("Producer.Flush.MaxMessages must be >= Producer.Flush.Messages when set") + case c.Producer.Retry.Max < 0: + return ConfigurationError("Producer.Retry.Max must be >= 0") + case c.Producer.Retry.Backoff < 0: + return ConfigurationError("Producer.Retry.Backoff must be >= 0") + } + + // validate the Consumer values + switch { + case c.Consumer.Fetch.Min <= 0: + return ConfigurationError("Consumer.Fetch.Min must be > 0") + case c.Consumer.Fetch.Default <= 0: + return ConfigurationError("Consumer.Fetch.Default must be > 0") + case c.Consumer.Fetch.Max < 0: + return ConfigurationError("Consumer.Fetch.Max must be >= 0") + case c.Consumer.MaxWaitTime < 1*time.Millisecond: + return ConfigurationError("Consumer.MaxWaitTime must be >= 1ms") + case c.Consumer.MaxProcessingTime <= 0: + return ConfigurationError("Consumer.MaxProcessingTime must be > 0") + case c.Consumer.Retry.Backoff < 0: + return ConfigurationError("Consumer.Retry.Backoff must be >= 0") + case c.Consumer.Offsets.CommitInterval <= 0: + return ConfigurationError("Consumer.Offsets.CommitInterval must be > 0") + case c.Consumer.Offsets.Initial != OffsetOldest && c.Consumer.Offsets.Initial != OffsetNewest: + return ConfigurationError("Consumer.Offsets.Initial must be OffsetOldest or OffsetNewest") + + } + + // validate misc shared values + switch { + case c.ChannelBufferSize < 0: + return ConfigurationError("ChannelBufferSize must be >= 0") + } + + return nil +} diff --git a/vendor/github.com/Shopify/sarama/consumer.go b/vendor/github.com/Shopify/sarama/consumer.go new file mode 100644 index 0000000..877fb04 --- /dev/null +++ b/vendor/github.com/Shopify/sarama/consumer.go @@ -0,0 +1,690 @@ +package sarama + +import ( + "errors" + "fmt" + "sync" + "sync/atomic" + "time" +) + +// ConsumerMessage encapsulates a Kafka message returned by the consumer. +type ConsumerMessage struct { + Key, Value []byte + Topic string + Partition int32 + Offset int64 +} + +// ConsumerError is what is provided to the user when an error occurs. +// It wraps an error and includes the topic and partition. +type ConsumerError struct { + Topic string + Partition int32 + Err error +} + +func (ce ConsumerError) Error() string { + return fmt.Sprintf("kafka: error while consuming %s/%d: %s", ce.Topic, ce.Partition, ce.Err) +} + +// ConsumerErrors is a type that wraps a batch of errors and implements the Error interface. +// It can be returned from the PartitionConsumer's Close methods to avoid the need to manually drain errors +// when stopping. +type ConsumerErrors []*ConsumerError + +func (ce ConsumerErrors) Error() string { + return fmt.Sprintf("kafka: %d errors while consuming", len(ce)) +} + +// Consumer manages PartitionConsumers which process Kafka messages from brokers. You MUST call Close() +// on a consumer to avoid leaks, it will not be garbage-collected automatically when it passes out of +// scope. +// +// Sarama's Consumer type does not currently support automatic consumer group rebalancing and offset tracking, +// however the https://github.com/wvanbergen/kafka library builds on Sarama to add this support. We plan +// to properly integrate this functionality at a later date. +type Consumer interface { + + // Topics returns the set of available topics as retrieved from the cluster + // metadata. This method is the same as Client.Topics(), and is provided for + // convenience. + Topics() ([]string, error) + + // Partitions returns the sorted list of all partition IDs for the given topic. + // This method is the same as Client.Partitions(), and is provided for convenience. + Partitions(topic string) ([]int32, error) + + // ConsumePartition creates a PartitionConsumer on the given topic/partition with + // the given offset. It will return an error if this Consumer is already consuming + // on the given topic/partition. Offset can be a literal offset, or OffsetNewest + // or OffsetOldest + ConsumePartition(topic string, partition int32, offset int64) (PartitionConsumer, error) + + // Close shuts down the consumer. It must be called after all child + // PartitionConsumers have already been closed. + Close() error +} + +type consumer struct { + client Client + conf *Config + ownClient bool + + lock sync.Mutex + children map[string]map[int32]*partitionConsumer + brokerConsumers map[*Broker]*brokerConsumer +} + +// NewConsumer creates a new consumer using the given broker addresses and configuration. +func NewConsumer(addrs []string, config *Config) (Consumer, error) { + client, err := NewClient(addrs, config) + if err != nil { + return nil, err + } + + c, err := NewConsumerFromClient(client) + if err != nil { + return nil, err + } + c.(*consumer).ownClient = true + return c, nil +} + +// NewConsumerFromClient creates a new consumer using the given client. It is still +// necessary to call Close() on the underlying client when shutting down this consumer. +func NewConsumerFromClient(client Client) (Consumer, error) { + // Check that we are not dealing with a closed Client before processing any other arguments + if client.Closed() { + return nil, ErrClosedClient + } + + c := &consumer{ + client: client, + conf: client.Config(), + children: make(map[string]map[int32]*partitionConsumer), + brokerConsumers: make(map[*Broker]*brokerConsumer), + } + + return c, nil +} + +func (c *consumer) Close() error { + if c.ownClient { + return c.client.Close() + } + return nil +} + +func (c *consumer) Topics() ([]string, error) { + return c.client.Topics() +} + +func (c *consumer) Partitions(topic string) ([]int32, error) { + return c.client.Partitions(topic) +} + +func (c *consumer) ConsumePartition(topic string, partition int32, offset int64) (PartitionConsumer, error) { + child := &partitionConsumer{ + consumer: c, + conf: c.conf, + topic: topic, + partition: partition, + messages: make(chan *ConsumerMessage, c.conf.ChannelBufferSize), + errors: make(chan *ConsumerError, c.conf.ChannelBufferSize), + feeder: make(chan *FetchResponse, 1), + trigger: make(chan none, 1), + dying: make(chan none), + fetchSize: c.conf.Consumer.Fetch.Default, + } + + if err := child.chooseStartingOffset(offset); err != nil { + return nil, err + } + + var leader *Broker + var err error + if leader, err = c.client.Leader(child.topic, child.partition); err != nil { + return nil, err + } + + if err := c.addChild(child); err != nil { + return nil, err + } + + go withRecover(child.dispatcher) + go withRecover(child.responseFeeder) + + child.broker = c.refBrokerConsumer(leader) + child.broker.input <- child + + return child, nil +} + +func (c *consumer) addChild(child *partitionConsumer) error { + c.lock.Lock() + defer c.lock.Unlock() + + topicChildren := c.children[child.topic] + if topicChildren == nil { + topicChildren = make(map[int32]*partitionConsumer) + c.children[child.topic] = topicChildren + } + + if topicChildren[child.partition] != nil { + return ConfigurationError("That topic/partition is already being consumed") + } + + topicChildren[child.partition] = child + return nil +} + +func (c *consumer) removeChild(child *partitionConsumer) { + c.lock.Lock() + defer c.lock.Unlock() + + delete(c.children[child.topic], child.partition) +} + +func (c *consumer) refBrokerConsumer(broker *Broker) *brokerConsumer { + c.lock.Lock() + defer c.lock.Unlock() + + bc := c.brokerConsumers[broker] + if bc == nil { + bc = c.newBrokerConsumer(broker) + c.brokerConsumers[broker] = bc + } + + bc.refs++ + + return bc +} + +func (c *consumer) unrefBrokerConsumer(brokerWorker *brokerConsumer) { + c.lock.Lock() + defer c.lock.Unlock() + + brokerWorker.refs-- + + if brokerWorker.refs == 0 { + close(brokerWorker.input) + if c.brokerConsumers[brokerWorker.broker] == brokerWorker { + delete(c.brokerConsumers, brokerWorker.broker) + } + } +} + +func (c *consumer) abandonBrokerConsumer(brokerWorker *brokerConsumer) { + c.lock.Lock() + defer c.lock.Unlock() + + delete(c.brokerConsumers, brokerWorker.broker) +} + +// PartitionConsumer + +// PartitionConsumer processes Kafka messages from a given topic and partition. You MUST call Close() +// or AsyncClose() on a PartitionConsumer to avoid leaks, it will not be garbage-collected automatically +// when it passes out of scope. +// +// The simplest way of using a PartitionConsumer is to loop over its Messages channel using a for/range +// loop. The PartitionConsumer will only stop itself in one case: when the offset being consumed is reported +// as out of range by the brokers. In this case you should decide what you want to do (try a different offset, +// notify a human, etc) and handle it appropriately. For all other error cases, it will just keep retrying. +// By default, it logs these errors to sarama.Logger; if you want to be notified directly of all errors, set +// your config's Consumer.Return.Errors to true and read from the Errors channel, using a select statement +// or a separate goroutine. Check out the Consumer examples to see implementations of these different approaches. +type PartitionConsumer interface { + + // AsyncClose initiates a shutdown of the PartitionConsumer. This method will + // return immediately, after which you should wait until the 'messages' and + // 'errors' channel are drained. It is required to call this function, or + // Close before a consumer object passes out of scope, as it will otherwise + // leak memory. You must call this before calling Close on the underlying client. + AsyncClose() + + // Close stops the PartitionConsumer from fetching messages. It is required to + // call this function (or AsyncClose) before a consumer object passes out of + // scope, as it will otherwise leak memory. You must call this before calling + // Close on the underlying client. + Close() error + + // Messages returns the read channel for the messages that are returned by + // the broker. + Messages() <-chan *ConsumerMessage + + // Errors returns a read channel of errors that occured during consuming, if + // enabled. By default, errors are logged and not returned over this channel. + // If you want to implement any custom error handling, set your config's + // Consumer.Return.Errors setting to true, and read from this channel. + Errors() <-chan *ConsumerError + + // HighWaterMarkOffset returns the high water mark offset of the partition, + // i.e. the offset that will be used for the next message that will be produced. + // You can use this to determine how far behind the processing is. + HighWaterMarkOffset() int64 +} + +type partitionConsumer struct { + consumer *consumer + conf *Config + topic string + partition int32 + + broker *brokerConsumer + messages chan *ConsumerMessage + errors chan *ConsumerError + feeder chan *FetchResponse + + trigger, dying chan none + responseResult error + + fetchSize int32 + offset int64 + highWaterMarkOffset int64 +} + +var errTimedOut = errors.New("timed out feeding messages to the user") // not user-facing + +func (child *partitionConsumer) sendError(err error) { + cErr := &ConsumerError{ + Topic: child.topic, + Partition: child.partition, + Err: err, + } + + if child.conf.Consumer.Return.Errors { + child.errors <- cErr + } else { + Logger.Println(cErr) + } +} + +func (child *partitionConsumer) dispatcher() { + for _ = range child.trigger { + select { + case <-child.dying: + close(child.trigger) + case <-time.After(child.conf.Consumer.Retry.Backoff): + if child.broker != nil { + child.consumer.unrefBrokerConsumer(child.broker) + child.broker = nil + } + + Logger.Printf("consumer/%s/%d finding new broker\n", child.topic, child.partition) + if err := child.dispatch(); err != nil { + child.sendError(err) + child.trigger <- none{} + } + } + } + + if child.broker != nil { + child.consumer.unrefBrokerConsumer(child.broker) + } + child.consumer.removeChild(child) + close(child.feeder) +} + +func (child *partitionConsumer) dispatch() error { + if err := child.consumer.client.RefreshMetadata(child.topic); err != nil { + return err + } + + var leader *Broker + var err error + if leader, err = child.consumer.client.Leader(child.topic, child.partition); err != nil { + return err + } + + child.broker = child.consumer.refBrokerConsumer(leader) + + child.broker.input <- child + + return nil +} + +func (child *partitionConsumer) chooseStartingOffset(offset int64) error { + newestOffset, err := child.consumer.client.GetOffset(child.topic, child.partition, OffsetNewest) + if err != nil { + return err + } + oldestOffset, err := child.consumer.client.GetOffset(child.topic, child.partition, OffsetOldest) + if err != nil { + return err + } + + switch { + case offset == OffsetNewest: + child.offset = newestOffset + case offset == OffsetOldest: + child.offset = oldestOffset + case offset >= oldestOffset && offset <= newestOffset: + child.offset = offset + default: + return ErrOffsetOutOfRange + } + + return nil +} + +func (child *partitionConsumer) Messages() <-chan *ConsumerMessage { + return child.messages +} + +func (child *partitionConsumer) Errors() <-chan *ConsumerError { + return child.errors +} + +func (child *partitionConsumer) AsyncClose() { + // this triggers whatever broker owns this child to abandon it and close its trigger channel, which causes + // the dispatcher to exit its loop, which removes it from the consumer then closes its 'messages' and + // 'errors' channel (alternatively, if the child is already at the dispatcher for some reason, that will + // also just close itself) + close(child.dying) +} + +func (child *partitionConsumer) Close() error { + child.AsyncClose() + + go withRecover(func() { + for _ = range child.messages { + // drain + } + }) + + var errors ConsumerErrors + for err := range child.errors { + errors = append(errors, err) + } + + if len(errors) > 0 { + return errors + } + return nil +} + +func (child *partitionConsumer) HighWaterMarkOffset() int64 { + return atomic.LoadInt64(&child.highWaterMarkOffset) +} + +func (child *partitionConsumer) responseFeeder() { + var msgs []*ConsumerMessage + +feederLoop: + for response := range child.feeder { + msgs, child.responseResult = child.parseResponse(response) + + for i, msg := range msgs { + select { + case child.messages <- msg: + case <-time.After(child.conf.Consumer.MaxProcessingTime): + child.responseResult = errTimedOut + child.broker.acks.Done() + for _, msg = range msgs[i:] { + child.messages <- msg + } + child.broker.input <- child + continue feederLoop + } + } + + child.broker.acks.Done() + } + + close(child.messages) + close(child.errors) +} + +func (child *partitionConsumer) parseResponse(response *FetchResponse) ([]*ConsumerMessage, error) { + block := response.GetBlock(child.topic, child.partition) + if block == nil { + return nil, ErrIncompleteResponse + } + + if block.Err != ErrNoError { + return nil, block.Err + } + + if len(block.MsgSet.Messages) == 0 { + // We got no messages. If we got a trailing one then we need to ask for more data. + // Otherwise we just poll again and wait for one to be produced... + if block.MsgSet.PartialTrailingMessage { + if child.conf.Consumer.Fetch.Max > 0 && child.fetchSize == child.conf.Consumer.Fetch.Max { + // we can't ask for more data, we've hit the configured limit + child.sendError(ErrMessageTooLarge) + child.offset++ // skip this one so we can keep processing future messages + } else { + child.fetchSize *= 2 + if child.conf.Consumer.Fetch.Max > 0 && child.fetchSize > child.conf.Consumer.Fetch.Max { + child.fetchSize = child.conf.Consumer.Fetch.Max + } + } + } + + return nil, nil + } + + // we got messages, reset our fetch size in case it was increased for a previous request + child.fetchSize = child.conf.Consumer.Fetch.Default + atomic.StoreInt64(&child.highWaterMarkOffset, block.HighWaterMarkOffset) + + incomplete := false + prelude := true + var messages []*ConsumerMessage + for _, msgBlock := range block.MsgSet.Messages { + + for _, msg := range msgBlock.Messages() { + if prelude && msg.Offset < child.offset { + continue + } + prelude = false + + if msg.Offset >= child.offset { + messages = append(messages, &ConsumerMessage{ + Topic: child.topic, + Partition: child.partition, + Key: msg.Msg.Key, + Value: msg.Msg.Value, + Offset: msg.Offset, + }) + child.offset = msg.Offset + 1 + } else { + incomplete = true + } + } + + } + + if incomplete || len(messages) == 0 { + return nil, ErrIncompleteResponse + } + return messages, nil +} + +// brokerConsumer + +type brokerConsumer struct { + consumer *consumer + broker *Broker + input chan *partitionConsumer + newSubscriptions chan []*partitionConsumer + wait chan none + subscriptions map[*partitionConsumer]none + acks sync.WaitGroup + refs int +} + +func (c *consumer) newBrokerConsumer(broker *Broker) *brokerConsumer { + bc := &brokerConsumer{ + consumer: c, + broker: broker, + input: make(chan *partitionConsumer), + newSubscriptions: make(chan []*partitionConsumer), + wait: make(chan none), + subscriptions: make(map[*partitionConsumer]none), + refs: 0, + } + + go withRecover(bc.subscriptionManager) + go withRecover(bc.subscriptionConsumer) + + return bc +} + +func (bc *brokerConsumer) subscriptionManager() { + var buffer []*partitionConsumer + + // The subscriptionManager constantly accepts new subscriptions on `input` (even when the main subscriptionConsumer + // goroutine is in the middle of a network request) and batches it up. The main worker goroutine picks + // up a batch of new subscriptions between every network request by reading from `newSubscriptions`, so we give + // it nil if no new subscriptions are available. We also write to `wait` only when new subscriptions is available, + // so the main goroutine can block waiting for work if it has none. + for { + if len(buffer) > 0 { + select { + case event, ok := <-bc.input: + if !ok { + goto done + } + buffer = append(buffer, event) + case bc.newSubscriptions <- buffer: + buffer = nil + case bc.wait <- none{}: + } + } else { + select { + case event, ok := <-bc.input: + if !ok { + goto done + } + buffer = append(buffer, event) + case bc.newSubscriptions <- nil: + } + } + } + +done: + close(bc.wait) + if len(buffer) > 0 { + bc.newSubscriptions <- buffer + } + close(bc.newSubscriptions) +} + +func (bc *brokerConsumer) subscriptionConsumer() { + <-bc.wait // wait for our first piece of work + + // the subscriptionConsumer ensures we will get nil right away if no new subscriptions is available + for newSubscriptions := range bc.newSubscriptions { + bc.updateSubscriptions(newSubscriptions) + + if len(bc.subscriptions) == 0 { + // We're about to be shut down or we're about to receive more subscriptions. + // Either way, the signal just hasn't propagated to our goroutine yet. + <-bc.wait + continue + } + + response, err := bc.fetchNewMessages() + + if err != nil { + Logger.Printf("consumer/broker/%d disconnecting due to error processing FetchRequest: %s\n", bc.broker.ID(), err) + bc.abort(err) + return + } + + bc.acks.Add(len(bc.subscriptions)) + for child := range bc.subscriptions { + child.feeder <- response + } + bc.acks.Wait() + bc.handleResponses() + } +} + +func (bc *brokerConsumer) updateSubscriptions(newSubscriptions []*partitionConsumer) { + for _, child := range newSubscriptions { + bc.subscriptions[child] = none{} + Logger.Printf("consumer/broker/%d added subscription to %s/%d\n", bc.broker.ID(), child.topic, child.partition) + } + + for child := range bc.subscriptions { + select { + case <-child.dying: + Logger.Printf("consumer/broker/%d closed dead subscription to %s/%d\n", bc.broker.ID(), child.topic, child.partition) + close(child.trigger) + delete(bc.subscriptions, child) + default: + break + } + } +} + +func (bc *brokerConsumer) handleResponses() { + // handles the response codes left for us by our subscriptions, and abandons ones that have been closed + for child := range bc.subscriptions { + result := child.responseResult + child.responseResult = nil + + switch result { + case nil: + break + case errTimedOut: + Logger.Printf("consumer/broker/%d abandoned subscription to %s/%d because consuming was taking too long\n", + bc.broker.ID(), child.topic, child.partition) + delete(bc.subscriptions, child) + case ErrOffsetOutOfRange: + // there's no point in retrying this it will just fail the same way again + // shut it down and force the user to choose what to do + child.sendError(result) + Logger.Printf("consumer/%s/%d shutting down because %s\n", child.topic, child.partition, result) + close(child.trigger) + delete(bc.subscriptions, child) + case ErrUnknownTopicOrPartition, ErrNotLeaderForPartition, ErrLeaderNotAvailable: + // not an error, but does need redispatching + Logger.Printf("consumer/broker/%d abandoned subscription to %s/%d because %s\n", + bc.broker.ID(), child.topic, child.partition, result) + child.trigger <- none{} + delete(bc.subscriptions, child) + default: + // dunno, tell the user and try redispatching + child.sendError(result) + Logger.Printf("consumer/broker/%d abandoned subscription to %s/%d because %s\n", + bc.broker.ID(), child.topic, child.partition, result) + child.trigger <- none{} + delete(bc.subscriptions, child) + } + } +} + +func (bc *brokerConsumer) abort(err error) { + bc.consumer.abandonBrokerConsumer(bc) + _ = bc.broker.Close() // we don't care about the error this might return, we already have one + + for child := range bc.subscriptions { + child.sendError(err) + child.trigger <- none{} + } + + for newSubscription := range bc.newSubscriptions { + for _, child := range newSubscription { + child.sendError(err) + child.trigger <- none{} + } + } +} + +func (bc *brokerConsumer) fetchNewMessages() (*FetchResponse, error) { + request := &FetchRequest{ + MinBytes: bc.consumer.conf.Consumer.Fetch.Min, + MaxWaitTime: int32(bc.consumer.conf.Consumer.MaxWaitTime / time.Millisecond), + } + + for child := range bc.subscriptions { + request.AddBlock(child.topic, child.partition, child.offset, child.fetchSize) + } + + return bc.broker.Fetch(request) +} diff --git a/vendor/github.com/Shopify/sarama/consumer_group_members.go b/vendor/github.com/Shopify/sarama/consumer_group_members.go new file mode 100644 index 0000000..9d92d35 --- /dev/null +++ b/vendor/github.com/Shopify/sarama/consumer_group_members.go @@ -0,0 +1,94 @@ +package sarama + +type ConsumerGroupMemberMetadata struct { + Version int16 + Topics []string + UserData []byte +} + +func (m *ConsumerGroupMemberMetadata) encode(pe packetEncoder) error { + pe.putInt16(m.Version) + + if err := pe.putStringArray(m.Topics); err != nil { + return err + } + + if err := pe.putBytes(m.UserData); err != nil { + return err + } + + return nil +} + +func (m *ConsumerGroupMemberMetadata) decode(pd packetDecoder) (err error) { + if m.Version, err = pd.getInt16(); err != nil { + return + } + + if m.Topics, err = pd.getStringArray(); err != nil { + return + } + + if m.UserData, err = pd.getBytes(); err != nil { + return + } + + return nil +} + +type ConsumerGroupMemberAssignment struct { + Version int16 + Topics map[string][]int32 + UserData []byte +} + +func (m *ConsumerGroupMemberAssignment) encode(pe packetEncoder) error { + pe.putInt16(m.Version) + + if err := pe.putArrayLength(len(m.Topics)); err != nil { + return err + } + + for topic, partitions := range m.Topics { + if err := pe.putString(topic); err != nil { + return err + } + if err := pe.putInt32Array(partitions); err != nil { + return err + } + } + + if err := pe.putBytes(m.UserData); err != nil { + return err + } + + return nil +} + +func (m *ConsumerGroupMemberAssignment) decode(pd packetDecoder) (err error) { + if m.Version, err = pd.getInt16(); err != nil { + return + } + + var topicLen int + if topicLen, err = pd.getArrayLength(); err != nil { + return + } + + m.Topics = make(map[string][]int32, topicLen) + for i := 0; i < topicLen; i++ { + var topic string + if topic, err = pd.getString(); err != nil { + return + } + if m.Topics[topic], err = pd.getInt32Array(); err != nil { + return + } + } + + if m.UserData, err = pd.getBytes(); err != nil { + return + } + + return nil +} diff --git a/vendor/github.com/Shopify/sarama/consumer_metadata_request.go b/vendor/github.com/Shopify/sarama/consumer_metadata_request.go new file mode 100644 index 0000000..9b8fcd7 --- /dev/null +++ b/vendor/github.com/Shopify/sarama/consumer_metadata_request.go @@ -0,0 +1,22 @@ +package sarama + +type ConsumerMetadataRequest struct { + ConsumerGroup string +} + +func (r *ConsumerMetadataRequest) encode(pe packetEncoder) error { + return pe.putString(r.ConsumerGroup) +} + +func (r *ConsumerMetadataRequest) decode(pd packetDecoder) (err error) { + r.ConsumerGroup, err = pd.getString() + return err +} + +func (r *ConsumerMetadataRequest) key() int16 { + return 10 +} + +func (r *ConsumerMetadataRequest) version() int16 { + return 0 +} diff --git a/vendor/github.com/Shopify/sarama/consumer_metadata_response.go b/vendor/github.com/Shopify/sarama/consumer_metadata_response.go new file mode 100644 index 0000000..d6b5614 --- /dev/null +++ b/vendor/github.com/Shopify/sarama/consumer_metadata_response.go @@ -0,0 +1,73 @@ +package sarama + +import ( + "net" + "strconv" +) + +type ConsumerMetadataResponse struct { + Err KError + Coordinator *Broker + CoordinatorID int32 // deprecated: use Coordinator.ID() + CoordinatorHost string // deprecated: use Coordinator.Addr() + CoordinatorPort int32 // deprecated: use Coordinator.Addr() +} + +func (r *ConsumerMetadataResponse) decode(pd packetDecoder) (err error) { + tmp, err := pd.getInt16() + if err != nil { + return err + } + r.Err = KError(tmp) + + coordinator := new(Broker) + if err := coordinator.decode(pd); err != nil { + return err + } + if coordinator.addr == ":0" { + return nil + } + r.Coordinator = coordinator + + // this can all go away in 2.0, but we have to fill in deprecated fields to maintain + // backwards compatibility + host, portstr, err := net.SplitHostPort(r.Coordinator.Addr()) + if err != nil { + return err + } + port, err := strconv.ParseInt(portstr, 10, 32) + if err != nil { + return err + } + r.CoordinatorID = r.Coordinator.ID() + r.CoordinatorHost = host + r.CoordinatorPort = int32(port) + + return nil +} + +func (r *ConsumerMetadataResponse) encode(pe packetEncoder) error { + pe.putInt16(int16(r.Err)) + if r.Coordinator != nil { + host, portstr, err := net.SplitHostPort(r.Coordinator.Addr()) + if err != nil { + return err + } + port, err := strconv.ParseInt(portstr, 10, 32) + if err != nil { + return err + } + pe.putInt32(r.Coordinator.ID()) + if err := pe.putString(host); err != nil { + return err + } + pe.putInt32(int32(port)) + return nil + } + pe.putInt32(r.CoordinatorID) + if err := pe.putString(r.CoordinatorHost); err != nil { + return err + } + pe.putInt32(r.CoordinatorPort) + return nil +} diff --git a/vendor/github.com/Shopify/sarama/crc32_field.go b/vendor/github.com/Shopify/sarama/crc32_field.go new file mode 100644 index 0000000..5c28607 --- /dev/null +++ b/vendor/github.com/Shopify/sarama/crc32_field.go @@ -0,0 +1,36 @@ +package sarama + +import ( + "encoding/binary" + + "github.com/klauspost/crc32" +) + +// crc32Field implements the pushEncoder and pushDecoder interfaces for calculating CRC32s. +type crc32Field struct { + startOffset int +} + +func (c *crc32Field) saveOffset(in int) { + c.startOffset = in +} + +func (c *crc32Field) reserveLength() int { + return 4 +} + +func (c *crc32Field) run(curOffset int, buf []byte) error { + crc := crc32.ChecksumIEEE(buf[c.startOffset+4 : curOffset]) + binary.BigEndian.PutUint32(buf[c.startOffset:], crc) + return nil +} + +func (c *crc32Field) check(curOffset int, buf []byte) error { + crc := crc32.ChecksumIEEE(buf[c.startOffset+4 : curOffset]) + + if crc != binary.BigEndian.Uint32(buf[c.startOffset:]) { + return PacketDecodingError{"CRC didn't match"} + } + + return nil +} diff --git a/vendor/github.com/Shopify/sarama/describe_groups_request.go b/vendor/github.com/Shopify/sarama/describe_groups_request.go new file mode 100644 index 0000000..c9426a6 --- /dev/null +++ b/vendor/github.com/Shopify/sarama/describe_groups_request.go @@ -0,0 +1,26 @@ +package sarama + +type DescribeGroupsRequest struct { + Groups []string +} + +func (r *DescribeGroupsRequest) encode(pe packetEncoder) error { + return pe.putStringArray(r.Groups) +} + +func (r *DescribeGroupsRequest) decode(pd packetDecoder) (err error) { + r.Groups, err = pd.getStringArray() + return +} + +func (r *DescribeGroupsRequest) key() int16 { + return 15 +} + +func (r *DescribeGroupsRequest) version() int16 { + return 0 +} + +func (r *DescribeGroupsRequest) AddGroup(group string) { + r.Groups = append(r.Groups, group) +} diff --git a/vendor/github.com/Shopify/sarama/describe_groups_response.go b/vendor/github.com/Shopify/sarama/describe_groups_response.go new file mode 100644 index 0000000..b4b32dd --- /dev/null +++ b/vendor/github.com/Shopify/sarama/describe_groups_response.go @@ -0,0 +1,162 @@ +package sarama + +type DescribeGroupsResponse struct { + Groups []*GroupDescription +} + +func (r *DescribeGroupsResponse) encode(pe packetEncoder) error { + if err := pe.putArrayLength(len(r.Groups)); err != nil { + return err + } + + for _, groupDescription := range r.Groups { + if err := groupDescription.encode(pe); err != nil { + return err + } + } + + return nil +} + +func (r *DescribeGroupsResponse) decode(pd packetDecoder) (err error) { + n, err := pd.getArrayLength() + if err != nil { + return err + } + + r.Groups = make([]*GroupDescription, n) + for i := 0; i < n; i++ { + r.Groups[i] = new(GroupDescription) + if err := r.Groups[i].decode(pd); err != nil { + return err + } + } + + return nil +} + +type GroupDescription struct { + Err KError + GroupId string + State string + ProtocolType string + Protocol string + Members map[string]*GroupMemberDescription +} + +func (gd *GroupDescription) encode(pe packetEncoder) error { + pe.putInt16(int16(gd.Err)) + + if err := pe.putString(gd.GroupId); err != nil { + return err + } + if err := pe.putString(gd.State); err != nil { + return err + } + if err := pe.putString(gd.ProtocolType); err != nil { + return err + } + if err := pe.putString(gd.Protocol); err != nil { + return err + } + + if err := pe.putArrayLength(len(gd.Members)); err != nil { + return err + } + + for memberId, groupMemberDescription := range gd.Members { + if err := pe.putString(memberId); err != nil { + return err + } + if err := groupMemberDescription.encode(pe); err != nil { + return err + } + } + + return nil +} + +func (gd *GroupDescription) decode(pd packetDecoder) (err error) { + if kerr, err := pd.getInt16(); err != nil { + return err + } else { + gd.Err = KError(kerr) + } + + if gd.GroupId, err = pd.getString(); err != nil { + return + } + if gd.State, err = pd.getString(); err != nil { + return + } + if gd.ProtocolType, err = pd.getString(); err != nil { + return + } + if gd.Protocol, err = pd.getString(); err != nil { + return + } + + n, err := pd.getArrayLength() + if err != nil { + return err + } + if n == 0 { + return nil + } + + gd.Members = make(map[string]*GroupMemberDescription) + for i := 0; i < n; i++ { + memberId, err := pd.getString() + if err != nil { + return err + } + + gd.Members[memberId] = new(GroupMemberDescription) + if err := gd.Members[memberId].decode(pd); err != nil { + return err + } + } + + return nil +} + +type GroupMemberDescription struct { + ClientId string + ClientHost string + MemberMetadata []byte + MemberAssignment []byte +} + +func (gmd *GroupMemberDescription) encode(pe packetEncoder) error { + if err := pe.putString(gmd.ClientId); err != nil { + return err + } + if err := pe.putString(gmd.ClientHost); err != nil { + return err + } + if err := pe.putBytes(gmd.MemberMetadata); err != nil { + return err + } + if err := pe.putBytes(gmd.MemberAssignment); err != nil { + return err + } + + return nil +} + +func (gmd *GroupMemberDescription) decode(pd packetDecoder) (err error) { + if gmd.ClientId, err = pd.getString(); err != nil { + return + } + if gmd.ClientHost, err = pd.getString(); err != nil { + return + } + if gmd.MemberMetadata, err = pd.getBytes(); err != nil { + return + } + if gmd.MemberAssignment, err = pd.getBytes(); err != nil { + return + } + + return nil +} diff --git a/vendor/github.com/Shopify/sarama/encoder_decoder.go b/vendor/github.com/Shopify/sarama/encoder_decoder.go new file mode 100644 index 0000000..b91efaa --- /dev/null +++ b/vendor/github.com/Shopify/sarama/encoder_decoder.go @@ -0,0 +1,62 @@ +package sarama + +import "fmt" + +// Encoder is the interface that wraps the basic Encode method. +// Anything implementing Encoder can be turned into bytes using Kafka's encoding rules. +type encoder interface { + encode(pe packetEncoder) error +} + +// Encode takes an Encoder and turns it into bytes. +func encode(e encoder) ([]byte, error) { + if e == nil { + return nil, nil + } + + var prepEnc prepEncoder + var realEnc realEncoder + + err := e.encode(&prepEnc) + if err != nil { + return nil, err + } + + if prepEnc.length < 0 || prepEnc.length > int(MaxRequestSize) { + return nil, PacketEncodingError{fmt.Sprintf("invalid request size (%d)", prepEnc.length)} + } + + realEnc.raw = make([]byte, prepEnc.length) + err = e.encode(&realEnc) + if err != nil { + return nil, err + } + + return realEnc.raw, nil +} + +// Decoder is the interface that wraps the basic Decode method. +// Anything implementing Decoder can be extracted from bytes using Kafka's encoding rules. +type decoder interface { + decode(pd packetDecoder) error +} + +// Decode takes bytes and a Decoder and fills the fields of the decoder from the bytes, +// interpreted using Kafka's encoding rules. +func decode(buf []byte, in decoder) error { + if buf == nil { + return nil + } + + helper := realDecoder{raw: buf} + err := in.decode(&helper) + if err != nil { + return err + } + + if helper.off != len(buf) { + return PacketDecodingError{"invalid length"} + } + + return nil +} diff --git a/vendor/github.com/Shopify/sarama/errors.go b/vendor/github.com/Shopify/sarama/errors.go new file mode 100644 index 0000000..a837087 --- /dev/null +++ b/vendor/github.com/Shopify/sarama/errors.go @@ -0,0 +1,179 @@ +package sarama + +import ( + "errors" + "fmt" +) + +// ErrOutOfBrokers is the error returned when the client has run out of brokers to talk to because all of them errored +// or otherwise failed to respond. +var ErrOutOfBrokers = errors.New("kafka: client has run out of available brokers to talk to (Is your cluster reachable?)") + +// ErrClosedClient is the error returned when a method is called on a client that has been closed. +var ErrClosedClient = errors.New("kafka: tried to use a client that was closed") + +// ErrIncompleteResponse is the error returned when the server returns a syntactically valid response, but it does +// not contain the expected information. +var ErrIncompleteResponse = errors.New("kafka: response did not contain all the expected topic/partition blocks") + +// ErrInvalidPartition is the error returned when a partitioner returns an invalid partition index +// (meaning one outside of the range [0...numPartitions-1]). +var ErrInvalidPartition = errors.New("kafka: partitioner returned an invalid partition index") + +// ErrAlreadyConnected is the error returned when calling Open() on a Broker that is already connected or connecting. +var ErrAlreadyConnected = errors.New("kafka: broker connection already initiated") + +// ErrNotConnected is the error returned when trying to send or call Close() on a Broker that is not connected. +var ErrNotConnected = errors.New("kafka: broker not connected") + +// ErrInsufficientData is returned when decoding and the packet is truncated. This can be expected +// when requesting messages, since as an optimization the server is allowed to return a partial message at the end +// of the message set. +var ErrInsufficientData = errors.New("kafka: insufficient data to decode packet, more bytes expected") + +// ErrShuttingDown is returned when a producer receives a message during shutdown. +var ErrShuttingDown = errors.New("kafka: message received by producer in process of shutting down") + +// ErrMessageTooLarge is returned when the next message to consume is larger than the configured Consumer.Fetch.Max +var ErrMessageTooLarge = errors.New("kafka: message is larger than Consumer.Fetch.Max") + +// PacketEncodingError is returned from a failure while encoding a Kafka packet. This can happen, for example, +// if you try to encode a string over 2^15 characters in length, since Kafka's encoding rules do not permit that. +type PacketEncodingError struct { + Info string +} + +func (err PacketEncodingError) Error() string { + return fmt.Sprintf("kafka: error encoding packet: %s", err.Info) +} + +// PacketDecodingError is returned when there was an error (other than truncated data) decoding the Kafka broker's response. +// This can be a bad CRC or length field, or any other invalid value. +type PacketDecodingError struct { + Info string +} + +func (err PacketDecodingError) Error() string { + return fmt.Sprintf("kafka: error decoding packet: %s", err.Info) +} + +// ConfigurationError is the type of error returned from a constructor (e.g. NewClient, or NewConsumer) +// when the specified configuration is invalid. +type ConfigurationError string + +func (err ConfigurationError) Error() string { + return "kafka: invalid configuration (" + string(err) + ")" +} + +// KError is the type of error that can be returned directly by the Kafka broker. +// See https://cwiki.apache.org/confluence/display/KAFKA/A+Guide+To+The+Kafka+Protocol#AGuideToTheKafkaProtocol-ErrorCodes +type KError int16 + +// Numeric error codes returned by the Kafka server. +const ( + ErrNoError KError = 0 + ErrUnknown KError = -1 + ErrOffsetOutOfRange KError = 1 + ErrInvalidMessage KError = 2 + ErrUnknownTopicOrPartition KError = 3 + ErrInvalidMessageSize KError = 4 + ErrLeaderNotAvailable KError = 5 + ErrNotLeaderForPartition KError = 6 + ErrRequestTimedOut KError = 7 + ErrBrokerNotAvailable KError = 8 + ErrReplicaNotAvailable KError = 9 + ErrMessageSizeTooLarge KError = 10 + ErrStaleControllerEpochCode KError = 11 + ErrOffsetMetadataTooLarge KError = 12 + ErrOffsetsLoadInProgress KError = 14 + ErrConsumerCoordinatorNotAvailable KError = 15 + ErrNotCoordinatorForConsumer KError = 16 + ErrInvalidTopic KError = 17 + ErrMessageSetSizeTooLarge KError = 18 + ErrNotEnoughReplicas KError = 19 + ErrNotEnoughReplicasAfterAppend KError = 20 + ErrInvalidRequiredAcks KError = 21 + ErrIllegalGeneration KError = 22 + ErrInconsistentGroupProtocol KError = 23 + ErrInvalidGroupId KError = 24 + ErrUnknownMemberId KError = 25 + ErrInvalidSessionTimeout KError = 26 + ErrRebalanceInProgress KError = 27 + ErrInvalidCommitOffsetSize KError = 28 + ErrTopicAuthorizationFailed KError = 29 + ErrGroupAuthorizationFailed KError = 30 + ErrClusterAuthorizationFailed KError = 31 +) + +func (err KError) Error() string { + // Error messages stolen/adapted from + // https://cwiki.apache.org/confluence/display/KAFKA/A+Guide+To+The+Kafka+Protocol + switch err { + case ErrNoError: + return "kafka server: Not an error, why are you printing me?" + case ErrUnknown: + return "kafka server: Unexpected (unknown?) server error." + case ErrOffsetOutOfRange: + return "kafka server: The requested offset is outside the range of offsets maintained by the server for the given topic/partition." + case ErrInvalidMessage: + return "kafka server: Message contents does not match its CRC." + case ErrUnknownTopicOrPartition: + return "kafka server: Request was for a topic or partition that does not exist on this broker." + case ErrInvalidMessageSize: + return "kafka server: The message has a negative size." + case ErrLeaderNotAvailable: + return "kafka server: In the middle of a leadership election, there is currently no leader for this partition and hence it is unavailable for writes." + case ErrNotLeaderForPartition: + return "kafka server: Tried to send a message to a replica that is not the leader for some partition. Your metadata is out of date." + case ErrRequestTimedOut: + return "kafka server: Request exceeded the user-specified time limit in the request." + case ErrBrokerNotAvailable: + return "kafka server: Broker not available. Not a client facing error, we should never receive this!!!" + case ErrReplicaNotAvailable: + return "kafka server: Replica infomation not available, one or more brokers are down." + case ErrMessageSizeTooLarge: + return "kafka server: Message was too large, server rejected it to avoid allocation error." + case ErrStaleControllerEpochCode: + return "kafka server: StaleControllerEpochCode (internal error code for broker-to-broker communication)." + case ErrOffsetMetadataTooLarge: + return "kafka server: Specified a string larger than the configured maximum for offset metadata." + case ErrOffsetsLoadInProgress: + return "kafka server: The broker is still loading offsets after a leader change for that offset's topic partition." + case ErrConsumerCoordinatorNotAvailable: + return "kafka server: Offset's topic has not yet been created." + case ErrNotCoordinatorForConsumer: + return "kafka server: Request was for a consumer group that is not coordinated by this broker." + case ErrInvalidTopic: + return "kafka server: The request attempted to perform an operation on an invalid topic." + case ErrMessageSetSizeTooLarge: + return "kafka server: The request included message batch larger than the configured segment size on the server." + case ErrNotEnoughReplicas: + return "kafka server: Messages are rejected since there are fewer in-sync replicas than required." + case ErrNotEnoughReplicasAfterAppend: + return "kafka server: Messages are written to the log, but to fewer in-sync replicas than required." + case ErrInvalidRequiredAcks: + return "kafka server: The number of required acks is invalid (should be either -1, 0, or 1)." + case ErrIllegalGeneration: + return "kafka server: The provided generation id is not the current generation." + case ErrInconsistentGroupProtocol: + return "kafka server: The provider group protocol type is incompatible with the other members." + case ErrInvalidGroupId: + return "kafka server: The provided group id was empty." + case ErrUnknownMemberId: + return "kafka server: The provided member is not known in the current generation." + case ErrInvalidSessionTimeout: + return "kafka server: The provided session timeout is outside the allowed range." + case ErrRebalanceInProgress: + return "kafka server: A rebalance for the group is in progress. Please re-join the group." + case ErrInvalidCommitOffsetSize: + return "kafka server: The provided commit metadata was too large." + case ErrTopicAuthorizationFailed: + return "kafka server: The client is not authorized to access this topic." + case ErrGroupAuthorizationFailed: + return "kafka server: The client is not authorized to access this group." + case ErrClusterAuthorizationFailed: + return "kafka server: The client is not authorized to send this request type." + } + + return fmt.Sprintf("Unknown error, how did this happen? Error code = %d", err) +} diff --git a/vendor/github.com/Shopify/sarama/examples/README.md b/vendor/github.com/Shopify/sarama/examples/README.md new file mode 100644 index 0000000..b658805 --- /dev/null +++ b/vendor/github.com/Shopify/sarama/examples/README.md @@ -0,0 +1,9 @@ +# Sarama examples + +This folder contains example applications to demonstrate the use of Sarama. For code snippet examples on how to use the different types in Sarama, see [Sarams's API documentation on godoc.org](https://godoc.org/github.com/Shopify/sarama) + +In these examples, we use `github.com/Shopify/sarama` as import path. We do this to ensure all the examples are up to date with the latest changes in Sarama. For your own applications, you may want to use `gopkg.in/Shopify/sarama.v1` to lock into a stable API version. + +#### HTTP server + +[http_server](./http_server) is a simple HTTP server uses both the sync producer to produce data as part of the request handling cycle, as well as the async producer to maintain an access log. It also uses the [mocks subpackage](https://godoc.org/github.com/Shopify/sarama/mocks) to test both. diff --git a/vendor/github.com/Shopify/sarama/examples/http_server/.gitignore b/vendor/github.com/Shopify/sarama/examples/http_server/.gitignore new file mode 100644 index 0000000..9f6ed42 --- /dev/null +++ b/vendor/github.com/Shopify/sarama/examples/http_server/.gitignore @@ -0,0 +1,2 @@ +http_server +http_server.test diff --git a/vendor/github.com/Shopify/sarama/examples/http_server/README.md b/vendor/github.com/Shopify/sarama/examples/http_server/README.md new file mode 100644 index 0000000..5ff2bc2 --- /dev/null +++ b/vendor/github.com/Shopify/sarama/examples/http_server/README.md @@ -0,0 +1,7 @@ +# HTTP server example + +This HTTP server example shows you how to use the AsyncProducer and SyncProducer, and how to test them using mocks. The server simply sends the data of the HTTP request's query string to Kafka, and send a 200 result if that succeeds. For every request, it will send an access log entry to Kafka as well in the background. + +If you need to know whether a message was successfully sent to the Kafka cluster before you can send your HTTP response, using the `SyncProducer` is probably the simplest way to achieve this. If you don't care, e.g. for the access log, using the `AsyncProducer` will let you fire and forget. You can send the HTTP response, while the message is being produced in the background. + +One important thing to note is that both the `SyncProducer` and `AsyncProducer` are **thread-safe**. Go's `http.Server` handles requests concurrently in different goroutines, but you can use a single producer safely. This will actually achieve efficiency gains as the producer will be able to batch messages from concurrent requests together. diff --git a/vendor/github.com/Shopify/sarama/examples/http_server/http_server.go b/vendor/github.com/Shopify/sarama/examples/http_server/http_server.go new file mode 100644 index 0000000..03e47b6 --- /dev/null +++ b/vendor/github.com/Shopify/sarama/examples/http_server/http_server.go @@ -0,0 +1,246 @@ +package main + +import ( + "github.com/Shopify/sarama" + + "crypto/tls" + "crypto/x509" + "encoding/json" + "flag" + "fmt" + "io/ioutil" + "log" + "net/http" + "os" + "strings" + "time" +) + +var ( + addr = flag.String("addr", ":8080", "The address to bind to") + brokers = flag.String("brokers", os.Getenv("KAFKA_PEERS"), "The Kafka brokers to connect to, as a comma separated list") + verbose = flag.Bool("verbose", false, "Turn on Sarama logging") + certFile = flag.String("certificate", "", "The optional certificate file for client authentication") + keyFile = flag.String("key", "", "The optional key file for client authentication") + caFile = flag.String("ca", "", "The optional certificate authority file for TLS client authentication") + verifySsl = flag.Bool("verify", false, "Optional verify ssl certificates chain") +) + +func main() { + flag.Parse() + + if *verbose { + sarama.Logger = log.New(os.Stdout, "[sarama] ", log.LstdFlags) + } + + if *brokers == "" { + flag.PrintDefaults() + os.Exit(1) + } + + brokerList := strings.Split(*brokers, ",") + log.Printf("Kafka brokers: %s", strings.Join(brokerList, ", ")) + + server := &Server{ + DataCollector: newDataCollector(brokerList), + AccessLogProducer: newAccessLogProducer(brokerList), + } + defer func() { + if err := server.Close(); err != nil { + log.Println("Failed to close server", err) + } + }() + + log.Fatal(server.Run(*addr)) +} + +func createTlsConfiguration() (t *tls.Config) { + if *certFile != "" && *keyFile != "" && *caFile != "" { + cert, err := tls.LoadX509KeyPair(*certFile, *keyFile) + if err != nil { + log.Fatal(err) + } + + caCert, err := ioutil.ReadFile(*caFile) + if err != nil { + log.Fatal(err) + } + + caCertPool := x509.NewCertPool() + caCertPool.AppendCertsFromPEM(caCert) + + t = &tls.Config{ + Certificates: []tls.Certificate{cert}, + RootCAs: caCertPool, + InsecureSkipVerify: *verifySsl, + } + } + // will be nil by default if nothing is provided + return t +} + +type Server struct { + DataCollector sarama.SyncProducer + AccessLogProducer sarama.AsyncProducer +} + +func (s *Server) Close() error { + if err := s.DataCollector.Close(); err != nil { + log.Println("Failed to shut down data collector cleanly", err) + } + + if err := s.AccessLogProducer.Close(); err != nil { + log.Println("Failed to shut down access log producer cleanly", err) + } + + return nil +} + +func (s *Server) Handler() http.Handler { + return s.withAccessLog(s.collectQueryStringData()) +} + +func (s *Server) Run(addr string) error { + httpServer := &http.Server{ + Addr: addr, + Handler: s.Handler(), + } + + log.Printf("Listening for requests on %s...\n", addr) + return httpServer.ListenAndServe() +} + +func (s *Server) collectQueryStringData() http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if r.URL.Path != "/" { + http.NotFound(w, r) + return + } + + // We are not setting a message key, which means that all messages will + // be distributed randomly over the different partitions. + partition, offset, err := s.DataCollector.SendMessage(&sarama.ProducerMessage{ + Topic: "important", + Value: sarama.StringEncoder(r.URL.RawQuery), + }) + + if err != nil { + w.WriteHeader(http.StatusInternalServerError) + fmt.Fprintf(w, "Failed to store your data:, %s", err) + } else { + // The tuple (topic, partition, offset) can be used as a unique identifier + // for a message in a Kafka cluster. + fmt.Fprintf(w, "Your data is stored with unique identifier important/%d/%d", partition, offset) + } + }) +} + +type accessLogEntry struct { + Method string `json:"method"` + Host string `json:"host"` + Path string `json:"path"` + IP string `json:"ip"` + ResponseTime float64 `json:"response_time"` + + encoded []byte + err error +} + +func (ale *accessLogEntry) ensureEncoded() { + if ale.encoded == nil && ale.err == nil { + ale.encoded, ale.err = json.Marshal(ale) + } +} + +func (ale *accessLogEntry) Length() int { + ale.ensureEncoded() + return len(ale.encoded) +} + +func (ale *accessLogEntry) Encode() ([]byte, error) { + ale.ensureEncoded() + return ale.encoded, ale.err +} + +func (s *Server) withAccessLog(next http.Handler) http.Handler { + + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + started := time.Now() + + next.ServeHTTP(w, r) + + entry := &accessLogEntry{ + Method: r.Method, + Host: r.Host, + Path: r.RequestURI, + IP: r.RemoteAddr, + ResponseTime: float64(time.Since(started)) / float64(time.Second), + } + + // We will use the client's IP address as key. This will cause + // all the access log entries of the same IP address to end up + // on the same partition. + s.AccessLogProducer.Input() <- &sarama.ProducerMessage{ + Topic: "access_log", + Key: sarama.StringEncoder(r.RemoteAddr), + Value: entry, + } + }) +} + +func newDataCollector(brokerList []string) sarama.SyncProducer { + + // For the data collector, we are looking for strong consistency semantics. + // Because we don't change the flush settings, sarama will try to produce messages + // as fast as possible to keep latency low. + config := sarama.NewConfig() + config.Producer.RequiredAcks = sarama.WaitForAll // Wait for all in-sync replicas to ack the message + config.Producer.Retry.Max = 10 // Retry up to 10 times to produce the message + tlsConfig := createTlsConfiguration() + if tlsConfig != nil { + config.Net.TLS.Config = tlsConfig + config.Net.TLS.Enable = true + } + + // On the broker side, you may want to change the following settings to get + // stronger consistency guarantees: + // - For your broker, set `unclean.leader.election.enable` to false + // - For the topic, you could increase `min.insync.replicas`. + + producer, err := sarama.NewSyncProducer(brokerList, config) + if err != nil { + log.Fatalln("Failed to start Sarama producer:", err) + } + + return producer +} + +func newAccessLogProducer(brokerList []string) sarama.AsyncProducer { + + // For the access log, we are looking for AP semantics, with high throughput. + // By creating batches of compressed messages, we reduce network I/O at a cost of more latency. + config := sarama.NewConfig() + tlsConfig := createTlsConfiguration() + if tlsConfig != nil { + config.Net.TLS.Enable = true + config.Net.TLS.Config = tlsConfig + } + config.Producer.RequiredAcks = sarama.WaitForLocal // Only wait for the leader to ack + config.Producer.Compression = sarama.CompressionSnappy // Compress messages + config.Producer.Flush.Frequency = 500 * time.Millisecond // Flush batches every 500ms + + producer, err := sarama.NewAsyncProducer(brokerList, config) + if err != nil { + log.Fatalln("Failed to start Sarama producer:", err) + } + + // We will just log to STDOUT if we're not able to produce messages. + // Note: messages will only be returned here after all retry attempts are exhausted. + go func() { + for err := range producer.Errors() { + log.Println("Failed to write access log entry:", err) + } + }() + + return producer +} diff --git a/vendor/github.com/Shopify/sarama/fetch_request.go b/vendor/github.com/Shopify/sarama/fetch_request.go new file mode 100644 index 0000000..3c00fad --- /dev/null +++ b/vendor/github.com/Shopify/sarama/fetch_request.go @@ -0,0 +1,123 @@ +package sarama + +type fetchRequestBlock struct { + fetchOffset int64 + maxBytes int32 +} + +func (f *fetchRequestBlock) encode(pe packetEncoder) error { + pe.putInt64(f.fetchOffset) + pe.putInt32(f.maxBytes) + return nil +} + +func (f *fetchRequestBlock) decode(pd packetDecoder) (err error) { + if f.fetchOffset, err = pd.getInt64(); err != nil { + return err + } + if f.maxBytes, err = pd.getInt32(); err != nil { + return err + } + return nil +} + +type FetchRequest struct { + MaxWaitTime int32 + MinBytes int32 + blocks map[string]map[int32]*fetchRequestBlock +} + +func (f *FetchRequest) encode(pe packetEncoder) (err error) { + pe.putInt32(-1) // replica ID is always -1 for clients + pe.putInt32(f.MaxWaitTime) + pe.putInt32(f.MinBytes) + err = pe.putArrayLength(len(f.blocks)) + if err != nil { + return err + } + for topic, blocks := range f.blocks { + err = pe.putString(topic) + if err != nil { + return err + } + err = pe.putArrayLength(len(blocks)) + if err != nil { + return err + } + for partition, block := range blocks { + pe.putInt32(partition) + err = block.encode(pe) + if err != nil { + return err + } + } + } + return nil +} + +func (f *FetchRequest) decode(pd packetDecoder) (err error) { + if _, err = pd.getInt32(); err != nil { + return err + } + if f.MaxWaitTime, err = pd.getInt32(); err != nil { + return err + } + if f.MinBytes, err = pd.getInt32(); err != nil { + return err + } + topicCount, err := pd.getArrayLength() + if err != nil { + return err + } + if topicCount == 0 { + return nil + } + f.blocks = make(map[string]map[int32]*fetchRequestBlock) + for i := 0; i < topicCount; i++ { + topic, err := pd.getString() + if err != nil { + return err + } + partitionCount, err := pd.getArrayLength() + if err != nil { + return err + } + f.blocks[topic] = make(map[int32]*fetchRequestBlock) + for j := 0; j < partitionCount; j++ { + partition, err := pd.getInt32() + if err != nil { + return err + } + fetchBlock := &fetchRequestBlock{} + if err = fetchBlock.decode(pd); err != nil { + return nil + } + f.blocks[topic][partition] = fetchBlock + } + } + return nil +} + +func (f *FetchRequest) key() int16 { + return 1 +} + +func (f *FetchRequest) version() int16 { + return 0 +} + +func (f *FetchRequest) AddBlock(topic string, partitionID int32, fetchOffset int64, maxBytes int32) { + if f.blocks == nil { + f.blocks = make(map[string]map[int32]*fetchRequestBlock) + } + + if f.blocks[topic] == nil { + f.blocks[topic] = make(map[int32]*fetchRequestBlock) + } + + tmp := new(fetchRequestBlock) + tmp.maxBytes = maxBytes + tmp.fetchOffset = fetchOffset + + f.blocks[topic][partitionID] = tmp +} diff --git a/vendor/github.com/Shopify/sarama/fetch_response.go b/vendor/github.com/Shopify/sarama/fetch_response.go new file mode 100644 index 0000000..1ac5439 --- /dev/null +++ b/vendor/github.com/Shopify/sarama/fetch_response.go @@ -0,0 +1,173 @@ +package sarama + +type FetchResponseBlock struct { + Err KError + HighWaterMarkOffset int64 + MsgSet MessageSet +} + +func (pr *FetchResponseBlock) decode(pd packetDecoder) (err error) { + tmp, err := pd.getInt16() + if err != nil { + return err + } + pr.Err = KError(tmp) + + pr.HighWaterMarkOffset, err = pd.getInt64() + if err != nil { + return err + } + + msgSetSize, err := pd.getInt32() + if err != nil { + return err + } + + msgSetDecoder, err := pd.getSubset(int(msgSetSize)) + if err != nil { + return err + } + err = (&pr.MsgSet).decode(msgSetDecoder) + + return err +} + +type FetchResponse struct { + Blocks map[string]map[int32]*FetchResponseBlock +} + +func (pr *FetchResponseBlock) encode(pe packetEncoder) (err error) { + pe.putInt16(int16(pr.Err)) + + pe.putInt64(pr.HighWaterMarkOffset) + + pe.push(&lengthField{}) + err = pr.MsgSet.encode(pe) + if err != nil { + return err + } + return pe.pop() +} + +func (fr *FetchResponse) decode(pd packetDecoder) (err error) { + numTopics, err := pd.getArrayLength() + if err != nil { + return err + } + + fr.Blocks = make(map[string]map[int32]*FetchResponseBlock, numTopics) + for i := 0; i < numTopics; i++ { + name, err := pd.getString() + if err != nil { + return err + } + + numBlocks, err := pd.getArrayLength() + if err != nil { + return err + } + + fr.Blocks[name] = make(map[int32]*FetchResponseBlock, numBlocks) + + for j := 0; j < numBlocks; j++ { + id, err := pd.getInt32() + if err != nil { + return err + } + + block := new(FetchResponseBlock) + err = block.decode(pd) + if err != nil { + return err + } + fr.Blocks[name][id] = block + } + } + + return nil +} + +func (fr *FetchResponse) encode(pe packetEncoder) (err error) { + err = pe.putArrayLength(len(fr.Blocks)) + if err != nil { + return err + } + + for topic, partitions := range fr.Blocks { + err = pe.putString(topic) + if err != nil { + return err + } + + err = pe.putArrayLength(len(partitions)) + if err != nil { + return err + } + + for id, block := range partitions { + pe.putInt32(id) + err = block.encode(pe) + if err != nil { + return err + } + } + + } + return nil +} + +func (fr *FetchResponse) GetBlock(topic string, partition int32) *FetchResponseBlock { + if fr.Blocks == nil { + return nil + } + + if fr.Blocks[topic] == nil { + return nil + } + + return fr.Blocks[topic][partition] +} + +func (fr *FetchResponse) AddError(topic string, partition int32, err KError) { + if fr.Blocks == nil { + fr.Blocks = make(map[string]map[int32]*FetchResponseBlock) + } + partitions, ok := fr.Blocks[topic] + if !ok { + partitions = make(map[int32]*FetchResponseBlock) + fr.Blocks[topic] = partitions + } + frb, ok := partitions[partition] + if !ok { + frb = new(FetchResponseBlock) + partitions[partition] = frb + } + frb.Err = err +} + +func (fr *FetchResponse) AddMessage(topic string, partition int32, key, value Encoder, offset int64) { + if fr.Blocks == nil { + fr.Blocks = make(map[string]map[int32]*FetchResponseBlock) + } + partitions, ok := fr.Blocks[topic] + if !ok { + partitions = make(map[int32]*FetchResponseBlock) + fr.Blocks[topic] = partitions + } + frb, ok := partitions[partition] + if !ok { + frb = new(FetchResponseBlock) + partitions[partition] = frb + } + var kb []byte + var vb []byte + if key != nil { + kb, _ = key.Encode() + } + if value != nil { + vb, _ = value.Encode() + } + msg := &Message{Key: kb, Value: vb} + msgBlock := &MessageBlock{Msg: msg, Offset: offset} + frb.MsgSet.Messages = append(frb.MsgSet.Messages, msgBlock) +} diff --git a/vendor/github.com/Shopify/sarama/heartbeat_request.go b/vendor/github.com/Shopify/sarama/heartbeat_request.go new file mode 100644 index 0000000..b89d290 --- /dev/null +++ b/vendor/github.com/Shopify/sarama/heartbeat_request.go @@ -0,0 +1,43 @@ +package sarama + +type HeartbeatRequest struct { + GroupId string + GenerationId int32 + MemberId string +} + +func (r *HeartbeatRequest) encode(pe packetEncoder) error { + if err := pe.putString(r.GroupId); err != nil { + return err + } + + pe.putInt32(r.GenerationId) + + if err := pe.putString(r.MemberId); err != nil { + return err + } + + return nil +} + +func (r *HeartbeatRequest) decode(pd packetDecoder) (err error) { + if r.GroupId, err = pd.getString(); err != nil { + return + } + if r.GenerationId, err = pd.getInt32(); err != nil { + return + } + if r.MemberId, err = pd.getString(); err != nil { + return + } + + return nil +} + +func (r *HeartbeatRequest) key() int16 { + return 12 +} + +func (r *HeartbeatRequest) version() int16 { + return 0 +} diff --git a/vendor/github.com/Shopify/sarama/heartbeat_response.go b/vendor/github.com/Shopify/sarama/heartbeat_response.go new file mode 100644 index 0000000..b48b8c1 --- /dev/null +++ b/vendor/github.com/Shopify/sarama/heartbeat_response.go @@ -0,0 +1,20 @@ +package sarama + +type HeartbeatResponse struct { + Err KError +} + +func (r *HeartbeatResponse) encode(pe packetEncoder) error { + pe.putInt16(int16(r.Err)) + return nil +} + +func (r *HeartbeatResponse) decode(pd packetDecoder) error { + if kerr, err := pd.getInt16(); err != nil { + return err + } else { + r.Err = KError(kerr) + } + + return nil +} diff --git a/vendor/github.com/Shopify/sarama/join_group_request.go b/vendor/github.com/Shopify/sarama/join_group_request.go new file mode 100644 index 0000000..5884d79 --- /dev/null +++ b/vendor/github.com/Shopify/sarama/join_group_request.go @@ -0,0 +1,104 @@ +package sarama + +type JoinGroupRequest struct { + GroupId string + SessionTimeout int32 + MemberId string + ProtocolType string + GroupProtocols map[string][]byte +} + +func (r *JoinGroupRequest) encode(pe packetEncoder) error { + if err := pe.putString(r.GroupId); err != nil { + return err + } + pe.putInt32(r.SessionTimeout) + if err := pe.putString(r.MemberId); err != nil { + return err + } + if err := pe.putString(r.ProtocolType); err != nil { + return err + } + + if err := pe.putArrayLength(len(r.GroupProtocols)); err != nil { + return err + } + for name, metadata := range r.GroupProtocols { + if err := pe.putString(name); err != nil { + return err + } + if err := pe.putBytes(metadata); err != nil { + return err + } + } + + return nil +} + +func (r *JoinGroupRequest) decode(pd packetDecoder) (err error) { + if r.GroupId, err = pd.getString(); err != nil { + return + } + + if r.SessionTimeout, err = pd.getInt32(); err != nil { + return + } + + if r.MemberId, err = pd.getString(); err != nil { + return + } + + if r.ProtocolType, err = pd.getString(); err != nil { + return + } + + n, err := pd.getArrayLength() + if err != nil { + return err + } + if n == 0 { + return nil + } + + r.GroupProtocols = make(map[string][]byte) + for i := 0; i < n; i++ { + name, err := pd.getString() + if err != nil { + return err + } + metadata, err := pd.getBytes() + if err != nil { + return err + } + + r.GroupProtocols[name] = metadata + } + + return nil +} + +func (r *JoinGroupRequest) key() int16 { + return 11 +} + +func (r *JoinGroupRequest) version() int16 { + return 0 +} + +func (r *JoinGroupRequest) AddGroupProtocol(name string, metadata []byte) { + if r.GroupProtocols == nil { + r.GroupProtocols = make(map[string][]byte) + } + + r.GroupProtocols[name] = metadata +} + +func (r *JoinGroupRequest) AddGroupProtocolMetadata(name string, metadata *ConsumerGroupMemberMetadata) error { + bin, err := encode(metadata) + if err != nil { + return err + } + + r.AddGroupProtocol(name, bin) + return nil +} diff --git a/vendor/github.com/Shopify/sarama/join_group_response.go b/vendor/github.com/Shopify/sarama/join_group_response.go new file mode 100644 index 0000000..16f6b9b --- /dev/null +++ b/vendor/github.com/Shopify/sarama/join_group_response.go @@ -0,0 +1,102 @@ +package sarama + +type JoinGroupResponse struct { + Err KError + GenerationId int32 + GroupProtocol string + LeaderId string + MemberId string + Members map[string][]byte +} + +func (r *JoinGroupResponse) GetMembers() (map[string]ConsumerGroupMemberMetadata, error) { + members := make(map[string]ConsumerGroupMemberMetadata, len(r.Members)) + for id, bin := range r.Members { + meta := new(ConsumerGroupMemberMetadata) + if err := decode(bin, meta); err != nil { + return nil, err + } + members[id] = *meta + } + return members, nil +} + +func (r *JoinGroupResponse) encode(pe packetEncoder) error { + pe.putInt16(int16(r.Err)) + pe.putInt32(r.GenerationId) + + if err := pe.putString(r.GroupProtocol); err != nil { + return err + } + if err := pe.putString(r.LeaderId); err != nil { + return err + } + if err := pe.putString(r.MemberId); err != nil { + return err + } + + if err := pe.putArrayLength(len(r.Members)); err != nil { + return err + } + + for memberId, memberMetadata := range r.Members { + if err := pe.putString(memberId); err != nil { + return err + } + + if err := pe.putBytes(memberMetadata); err != nil { + return err + } + } + + return nil +} + +func (r *JoinGroupResponse) decode(pd packetDecoder) (err error) { + if kerr, err := pd.getInt16(); err != nil { + return err + } else { + r.Err = KError(kerr) + } + + if r.GenerationId, err = pd.getInt32(); err != nil { + return + } + + if r.GroupProtocol, err = pd.getString(); err != nil { + return + } + + if r.LeaderId, err = pd.getString(); err != nil { + return + } + + if r.MemberId, err = pd.getString(); err != nil { + return + } + + n, err := pd.getArrayLength() + if err != nil { + return err + } + if n == 0 { + return nil + } + + r.Members = make(map[string][]byte) + for i := 0; i < n; i++ { + memberId, err := pd.getString() + if err != nil { + return err + } + + memberMetadata, err := pd.getBytes() + if err != nil { + return err + } + + r.Members[memberId] = memberMetadata + } + + return nil +} diff --git a/vendor/github.com/Shopify/sarama/leave_group_request.go b/vendor/github.com/Shopify/sarama/leave_group_request.go new file mode 100644 index 0000000..cdb4d14 --- /dev/null +++ b/vendor/github.com/Shopify/sarama/leave_group_request.go @@ -0,0 +1,36 @@ +package sarama + +type LeaveGroupRequest struct { + GroupId string + MemberId string +} + +func (r *LeaveGroupRequest) encode(pe packetEncoder) error { + if err := pe.putString(r.GroupId); err != nil { + return err + } + if err := pe.putString(r.MemberId); err != nil { + return err + } + + return nil +} + +func (r *LeaveGroupRequest) decode(pd packetDecoder) (err error) { + if r.GroupId, err = pd.getString(); err != nil { + return + } + if r.MemberId, err = pd.getString(); err != nil { + return + } + + return nil +} + +func (r *LeaveGroupRequest) key() int16 { + return 13 +} + +func (r *LeaveGroupRequest) version() int16 { + return 0 +} diff --git a/vendor/github.com/Shopify/sarama/leave_group_response.go b/vendor/github.com/Shopify/sarama/leave_group_response.go new file mode 100644 index 0000000..bad1dba --- /dev/null +++ b/vendor/github.com/Shopify/sarama/leave_group_response.go @@ -0,0 +1,20 @@ +package sarama + +type LeaveGroupResponse struct { + Err KError +} + +func (r *LeaveGroupResponse) encode(pe packetEncoder) error { + pe.putInt16(int16(r.Err)) + return nil +} + +func (r *LeaveGroupResponse) decode(pd packetDecoder) (err error) { + if kerr, err := pd.getInt16(); err != nil { + return err + } else { + r.Err = KError(kerr) + } + + return nil +} diff --git a/vendor/github.com/Shopify/sarama/length_field.go b/vendor/github.com/Shopify/sarama/length_field.go new file mode 100644 index 0000000..70078be --- /dev/null +++ b/vendor/github.com/Shopify/sarama/length_field.go @@ -0,0 +1,29 @@ +package sarama + +import "encoding/binary" + +// LengthField implements the PushEncoder and PushDecoder interfaces for calculating 4-byte lengths. +type lengthField struct { + startOffset int +} + +func (l *lengthField) saveOffset(in int) { + l.startOffset = in +} + +func (l *lengthField) reserveLength() int { + return 4 +} + +func (l *lengthField) run(curOffset int, buf []byte) error { + binary.BigEndian.PutUint32(buf[l.startOffset:], uint32(curOffset-l.startOffset-4)) + return nil +} + +func (l *lengthField) check(curOffset int, buf []byte) error { + if uint32(curOffset-l.startOffset-4) != binary.BigEndian.Uint32(buf[l.startOffset:]) { + return PacketDecodingError{"length field invalid"} + } + + return nil +} diff --git a/vendor/github.com/Shopify/sarama/list_groups_request.go b/vendor/github.com/Shopify/sarama/list_groups_request.go new file mode 100644 index 0000000..4d74c26 --- /dev/null +++ b/vendor/github.com/Shopify/sarama/list_groups_request.go @@ -0,0 +1,20 @@ +package sarama + +type ListGroupsRequest struct { +} + +func (r *ListGroupsRequest) encode(pe packetEncoder) error { + return nil +} + +func (r *ListGroupsRequest) decode(pd packetDecoder) (err error) { + return nil +} + +func (r *ListGroupsRequest) key() int16 { + return 16 +} + +func (r *ListGroupsRequest) version() int16 { + return 0 +} diff --git a/vendor/github.com/Shopify/sarama/list_groups_response.go b/vendor/github.com/Shopify/sarama/list_groups_response.go new file mode 100644 index 0000000..2f53149 --- /dev/null +++ b/vendor/github.com/Shopify/sarama/list_groups_response.go @@ -0,0 +1,56 @@ +package sarama + +type ListGroupsResponse struct { + Err KError + Groups map[string]string +} + +func (r *ListGroupsResponse) encode(pe packetEncoder) error { + pe.putInt16(int16(r.Err)) + + if err := pe.putArrayLength(len(r.Groups)); err != nil { + return err + } + for groupId, protocolType := range r.Groups { + if err := pe.putString(groupId); err != nil { + return err + } + if err := pe.putString(protocolType); err != nil { + return err + } + } + + return nil +} + +func (r *ListGroupsResponse) decode(pd packetDecoder) error { + if kerr, err := pd.getInt16(); err != nil { + return err + } else { + r.Err = KError(kerr) + } + + n, err := pd.getArrayLength() + if err != nil { + return err + } + if n == 0 { + return nil + } + + r.Groups = make(map[string]string) + for i := 0; i < n; i++ { + groupId, err := pd.getString() + if err != nil { + return err + } + protocolType, err := pd.getString() + if err != nil { + return err + } + + r.Groups[groupId] = protocolType + } + + return nil +} diff --git a/vendor/github.com/Shopify/sarama/message.go b/vendor/github.com/Shopify/sarama/message.go new file mode 100644 index 0000000..c4bdb9e --- /dev/null +++ b/vendor/github.com/Shopify/sarama/message.go @@ -0,0 +1,153 @@ +package sarama + +import ( + "bytes" + "compress/gzip" + "fmt" + "io/ioutil" +) + +// CompressionCodec represents the various compression codecs recognized by Kafka in messages. +type CompressionCodec int8 + +// only the last two bits are really used +const compressionCodecMask int8 = 0x03 + +const ( + CompressionNone CompressionCodec = 0 + CompressionGZIP CompressionCodec = 1 + CompressionSnappy CompressionCodec = 2 +) + +// The spec just says: "This is a version id used to allow backwards compatible evolution of the message +// binary format." but it doesn't say what the current value is, so presumably 0... +const messageFormat int8 = 0 + +type Message struct { + Codec CompressionCodec // codec used to compress the message contents + Key []byte // the message key, may be nil + Value []byte // the message contents + Set *MessageSet // the message set a message might wrap + + compressedCache []byte +} + +func (m *Message) encode(pe packetEncoder) error { + pe.push(&crc32Field{}) + + pe.putInt8(messageFormat) + + attributes := int8(m.Codec) & compressionCodecMask + pe.putInt8(attributes) + + err := pe.putBytes(m.Key) + if err != nil { + return err + } + + var payload []byte + + if m.compressedCache != nil { + payload = m.compressedCache + m.compressedCache = nil + } else { + switch m.Codec { + case CompressionNone: + payload = m.Value + case CompressionGZIP: + var buf bytes.Buffer + writer := gzip.NewWriter(&buf) + if _, err = writer.Write(m.Value); err != nil { + return err + } + if err = writer.Close(); err != nil { + return err + } + m.compressedCache = buf.Bytes() + payload = m.compressedCache + case CompressionSnappy: + tmp := snappyEncode(m.Value) + m.compressedCache = tmp + payload = m.compressedCache + default: + return PacketEncodingError{fmt.Sprintf("unsupported compression codec (%d)", m.Codec)} + } + } + + if err = pe.putBytes(payload); err != nil { + return err + } + + return pe.pop() +} + +func (m *Message) decode(pd packetDecoder) (err error) { + err = pd.push(&crc32Field{}) + if err != nil { + return err + } + + format, err := pd.getInt8() + if err != nil { + return err + } + if format != messageFormat { + return PacketDecodingError{"unexpected messageFormat"} + } + + attribute, err := pd.getInt8() + if err != nil { + return err + } + m.Codec = CompressionCodec(attribute & compressionCodecMask) + + m.Key, err = pd.getBytes() + if err != nil { + return err + } + + m.Value, err = pd.getBytes() + if err != nil { + return err + } + + switch m.Codec { + case CompressionNone: + // nothing to do + case CompressionGZIP: + if m.Value == nil { + return PacketDecodingError{"GZIP compression specified, but no data to uncompress"} + } + reader, err := gzip.NewReader(bytes.NewReader(m.Value)) + if err != nil { + return err + } + if m.Value, err = ioutil.ReadAll(reader); err != nil { + return err + } + if err := m.decodeSet(); err != nil { + return err + } + case CompressionSnappy: + if m.Value == nil { + return PacketDecodingError{"Snappy compression specified, but no data to uncompress"} + } + if m.Value, err = snappyDecode(m.Value); err != nil { + return err + } + if err := m.decodeSet(); err != nil { + return err + } + default: + return PacketDecodingError{fmt.Sprintf("invalid compression specified (%d)", m.Codec)} + } + + return pd.pop() +} + +// decodes a message set from a previousy encoded bulk-message +func (m *Message) decodeSet() (err error) { + pd := realDecoder{raw: m.Value} + m.Set = &MessageSet{} + return m.Set.decode(&pd) +} diff --git a/vendor/github.com/Shopify/sarama/message_set.go b/vendor/github.com/Shopify/sarama/message_set.go new file mode 100644 index 0000000..f028784 --- /dev/null +++ b/vendor/github.com/Shopify/sarama/message_set.go @@ -0,0 +1,89 @@ +package sarama + +type MessageBlock struct { + Offset int64 + Msg *Message +} + +// Messages convenience helper which returns either all the +// messages that are wrapped in this block +func (msb *MessageBlock) Messages() []*MessageBlock { + if msb.Msg.Set != nil { + return msb.Msg.Set.Messages + } + return []*MessageBlock{msb} +} + +func (msb *MessageBlock) encode(pe packetEncoder) error { + pe.putInt64(msb.Offset) + pe.push(&lengthField{}) + err := msb.Msg.encode(pe) + if err != nil { + return err + } + return pe.pop() +} + +func (msb *MessageBlock) decode(pd packetDecoder) (err error) { + if msb.Offset, err = pd.getInt64(); err != nil { + return err + } + + if err = pd.push(&lengthField{}); err != nil { + return err + } + + msb.Msg = new(Message) + if err = msb.Msg.decode(pd); err != nil { + return err + } + + if err = pd.pop(); err != nil { + return err + } + + return nil +} + +type MessageSet struct { + PartialTrailingMessage bool // whether the set on the wire contained an incomplete trailing MessageBlock + Messages []*MessageBlock +} + +func (ms *MessageSet) encode(pe packetEncoder) error { + for i := range ms.Messages { + err := ms.Messages[i].encode(pe) + if err != nil { + return err + } + } + return nil +} + +func (ms *MessageSet) decode(pd packetDecoder) (err error) { + ms.Messages = nil + + for pd.remaining() > 0 { + msb := new(MessageBlock) + err = msb.decode(pd) + switch err { + case nil: + ms.Messages = append(ms.Messages, msb) + case ErrInsufficientData: + // As an optimization the server is allowed to return a partial message at the + // end of the message set. Clients should handle this case. So we just ignore such things. + ms.PartialTrailingMessage = true + return nil + default: + return err + } + } + + return nil +} + +func (ms *MessageSet) addMessage(msg *Message) { + block := new(MessageBlock) + block.Msg = msg + ms.Messages = append(ms.Messages, block) +} diff --git a/vendor/github.com/Shopify/sarama/metadata_request.go b/vendor/github.com/Shopify/sarama/metadata_request.go new file mode 100644 index 0000000..130cfd4 --- /dev/null +++ b/vendor/github.com/Shopify/sarama/metadata_request.go @@ -0,0 +1,48 @@ +package sarama + +type MetadataRequest struct { + Topics []string +} + +func (mr *MetadataRequest) encode(pe packetEncoder) error { + err := pe.putArrayLength(len(mr.Topics)) + if err != nil { + return err + } + + for i := range mr.Topics { + err = pe.putString(mr.Topics[i]) + if err != nil { + return err + } + } + return nil +} + +func (mr *MetadataRequest) decode(pd packetDecoder) error { + topicCount, err := pd.getArrayLength() + if err != nil { + return err + } + if topicCount == 0 { + return nil + } + + mr.Topics = make([]string, topicCount) + for i := range mr.Topics { + topic, err := pd.getString() + if err != nil { + return err + } + mr.Topics[i] = topic + } + return nil +} + +func (mr *MetadataRequest) key() int16 { + return 3 +} + +func (mr *MetadataRequest) version() int16 { + return 0 +} diff --git a/vendor/github.com/Shopify/sarama/metadata_response.go b/vendor/github.com/Shopify/sarama/metadata_response.go new file mode 100644 index 0000000..b82221f --- /dev/null +++ b/vendor/github.com/Shopify/sarama/metadata_response.go @@ -0,0 +1,227 @@ +package sarama + +type PartitionMetadata struct { + Err KError + ID int32 + Leader int32 + Replicas []int32 + Isr []int32 +} + +func (pm *PartitionMetadata) decode(pd packetDecoder) (err error) { + tmp, err := pd.getInt16() + if err != nil { + return err + } + pm.Err = KError(tmp) + + pm.ID, err = pd.getInt32() + if err != nil { + return err + } + + pm.Leader, err = pd.getInt32() + if err != nil { + return err + } + + pm.Replicas, err = pd.getInt32Array() + if err != nil { + return err + } + + pm.Isr, err = pd.getInt32Array() + if err != nil { + return err + } + + return nil +} + +func (pm *PartitionMetadata) encode(pe packetEncoder) (err error) { + pe.putInt16(int16(pm.Err)) + pe.putInt32(pm.ID) + pe.putInt32(pm.Leader) + + err = pe.putInt32Array(pm.Replicas) + if err != nil { + return err + } + + err = pe.putInt32Array(pm.Isr) + if err != nil { + return err + } + + return nil +} + +type TopicMetadata struct { + Err KError + Name string + Partitions []*PartitionMetadata +} + +func (tm *TopicMetadata) decode(pd packetDecoder) (err error) { + tmp, err := pd.getInt16() + if err != nil { + return err + } + tm.Err = KError(tmp) + + tm.Name, err = pd.getString() + if err != nil { + return err + } + + n, err := pd.getArrayLength() + if err != nil { + return err + } + tm.Partitions = make([]*PartitionMetadata, n) + for i := 0; i < n; i++ { + tm.Partitions[i] = new(PartitionMetadata) + err = tm.Partitions[i].decode(pd) + if err != nil { + return err + } + } + + return nil +} + +func (tm *TopicMetadata) encode(pe packetEncoder) (err error) { + pe.putInt16(int16(tm.Err)) + + err = pe.putString(tm.Name) + if err != nil { + return err + } + + err = pe.putArrayLength(len(tm.Partitions)) + if err != nil { + return err + } + + for _, pm := range tm.Partitions { + err = pm.encode(pe) + if err != nil { + return err + } + } + + return nil +} + +type MetadataResponse struct { + Brokers []*Broker + Topics []*TopicMetadata +} + +func (m *MetadataResponse) decode(pd packetDecoder) (err error) { + n, err := pd.getArrayLength() + if err != nil { + return err + } + + m.Brokers = make([]*Broker, n) + for i := 0; i < n; i++ { + m.Brokers[i] = new(Broker) + err = m.Brokers[i].decode(pd) + if err != nil { + return err + } + } + + n, err = pd.getArrayLength() + if err != nil { + return err + } + + m.Topics = make([]*TopicMetadata, n) + for i := 0; i < n; i++ { + m.Topics[i] = new(TopicMetadata) + err = m.Topics[i].decode(pd) + if err != nil { + return err + } + } + + return nil +} + +func (m *MetadataResponse) encode(pe packetEncoder) error { + err := pe.putArrayLength(len(m.Brokers)) + if err != nil { + return err + } + for _, broker := range m.Brokers { + err = broker.encode(pe) + if err != nil { + return err + } + } + + err = pe.putArrayLength(len(m.Topics)) + if err != nil { + return err + } + for _, tm := range m.Topics { + err = tm.encode(pe) + if err != nil { + return err + } + } + + return nil +} + +// testing API + +func (m *MetadataResponse) AddBroker(addr string, id int32) { + m.Brokers = append(m.Brokers, &Broker{id: id, addr: addr}) +} + +func (m *MetadataResponse) AddTopic(topic string, err KError) *TopicMetadata { + var tmatch *TopicMetadata + + for _, tm := range m.Topics { + if tm.Name == topic { + tmatch = tm + goto foundTopic + } + } + + tmatch = new(TopicMetadata) + tmatch.Name = topic + m.Topics = append(m.Topics, tmatch) + +foundTopic: + + tmatch.Err = err + return tmatch +} + +func (m *MetadataResponse) AddTopicPartition(topic string, partition, brokerID int32, replicas, isr []int32, err KError) { + tmatch := m.AddTopic(topic, ErrNoError) + var pmatch *PartitionMetadata + + for _, pm := range tmatch.Partitions { + if pm.ID == partition { + pmatch = pm + goto foundPartition + } + } + + pmatch = new(PartitionMetadata) + pmatch.ID = partition + tmatch.Partitions = append(tmatch.Partitions, pmatch) + +foundPartition: + + pmatch.Leader = brokerID + pmatch.Replicas = replicas + pmatch.Isr = isr + pmatch.Err = err + +} diff --git a/vendor/github.com/Shopify/sarama/mockbroker.go b/vendor/github.com/Shopify/sarama/mockbroker.go new file mode 100644 index 0000000..1ff802c --- /dev/null +++ b/vendor/github.com/Shopify/sarama/mockbroker.go @@ -0,0 +1,301 @@ +package sarama + +import ( + "bytes" + "encoding/binary" + "fmt" + "io" + "net" + "reflect" + "strconv" + "sync" + "testing" + "time" + + "github.com/davecgh/go-spew/spew" +) + +const ( + expectationTimeout = 500 * time.Millisecond +) + +type requestHandlerFunc func(req *request) (res encoder) + +// MockBroker is a mock Kafka broker that is used in unit tests. It is exposed +// to facilitate testing of higher level or specialized consumers and producers +// built on top of Sarama. Note that it does not 'mimic' the Kafka API protocol, +// but rather provides a facility to do that. It takes care of the TCP +// transport, request unmarshaling, response marshaling, and makes it the test +// writer responsibility to program correct according to the Kafka API protocol +// MockBroker behaviour. +// +// MockBroker is implemented as a TCP server listening on a kernel-selected +// localhost port that can accept many connections. It reads Kafka requests +// from that connection and returns responses programmed by the SetHandlerByMap +// function. If a MockBroker receives a request that it has no programmed +// response for, then it returns nothing and the request times out. +// +// A set of MockRequest builders to define mappings used by MockBroker is +// provided by Sarama. But users can develop MockRequests of their own and use +// them along with or instead of the standard ones. +// +// When running tests with MockBroker it is strongly recommended to specify +// a timeout to `go test` so that if the broker hangs waiting for a response, +// the test panics. +// +// It is not necessary to prefix message length or correlation ID to your +// response bytes, the server does that automatically as a convenience. +type MockBroker struct { + brokerID int32 + port int32 + closing chan none + stopper chan none + expectations chan encoder + listener net.Listener + t *testing.T + latency time.Duration + handler requestHandlerFunc + history []RequestResponse + lock sync.Mutex +} + +// RequestResponse represents a Request/Response pair processed by MockBroker. +type RequestResponse struct { + Request requestBody + Response encoder +} + +// SetLatency makes broker pause for the specified period every time before +// replying. +func (b *MockBroker) SetLatency(latency time.Duration) { + b.latency = latency +} + +// SetHandlerByMap defines mapping of Request types to MockResponses. When a +// request is received by the broker, it looks up the request type in the map +// and uses the found MockResponse instance to generate an appropriate reply. +// If the request type is not found in the map then nothing is sent. +func (b *MockBroker) SetHandlerByMap(handlerMap map[string]MockResponse) { + b.setHandler(func(req *request) (res encoder) { + reqTypeName := reflect.TypeOf(req.body).Elem().Name() + mockResponse := handlerMap[reqTypeName] + if mockResponse == nil { + return nil + } + return mockResponse.For(req.body) + }) +} + +// BrokerID returns broker ID assigned to the broker. +func (b *MockBroker) BrokerID() int32 { + return b.brokerID +} + +// History returns a slice of RequestResponse pairs in the order they were +// processed by the broker. Note that in case of multiple connections to the +// broker the order expected by a test can be different from the order recorded +// in the history, unless some synchronization is implemented in the test. +func (b *MockBroker) History() []RequestResponse { + b.lock.Lock() + history := make([]RequestResponse, len(b.history)) + copy(history, b.history) + b.lock.Unlock() + return history +} + +// Port returns the TCP port number the broker is listening for requests on. +func (b *MockBroker) Port() int32 { + return b.port +} + +// Addr returns the broker connection string in the form "
:". +func (b *MockBroker) Addr() string { + return b.listener.Addr().String() +} + +// Close terminates the broker blocking until it stops internal goroutines and +// releases all resources. +func (b *MockBroker) Close() { + close(b.expectations) + if len(b.expectations) > 0 { + buf := bytes.NewBufferString(fmt.Sprintf("mockbroker/%d: not all expectations were satisfied! Still waiting on:\n", b.BrokerID())) + for e := range b.expectations { + _, _ = buf.WriteString(spew.Sdump(e)) + } + b.t.Error(buf.String()) + } + close(b.closing) + <-b.stopper +} + +// setHandler sets the specified function as the request handler. Whenever +// a mock broker reads a request from the wire it passes the request to the +// function and sends back whatever the handler function returns. +func (b *MockBroker) setHandler(handler requestHandlerFunc) { + b.lock.Lock() + b.handler = handler + b.lock.Unlock() +} + +func (b *MockBroker) serverLoop() { + defer close(b.stopper) + var err error + var conn net.Conn + + go func() { + <-b.closing + err := b.listener.Close() + if err != nil { + b.t.Error(err) + } + }() + + wg := &sync.WaitGroup{} + i := 0 + for conn, err = b.listener.Accept(); err == nil; conn, err = b.listener.Accept() { + wg.Add(1) + go b.handleRequests(conn, i, wg) + i++ + } + wg.Wait() + Logger.Printf("*** mockbroker/%d: listener closed, err=%v", b.BrokerID(), err) +} + +func (b *MockBroker) handleRequests(conn net.Conn, idx int, wg *sync.WaitGroup) { + defer wg.Done() + defer func() { + _ = conn.Close() + }() + Logger.Printf("*** mockbroker/%d/%d: connection opened", b.BrokerID(), idx) + var err error + + abort := make(chan none) + defer close(abort) + go func() { + select { + case <-b.closing: + _ = conn.Close() + case <-abort: + } + }() + + resHeader := make([]byte, 8) + for { + req, err := decodeRequest(conn) + if err != nil { + Logger.Printf("*** mockbroker/%d/%d: invalid request: err=%+v, %+v", b.brokerID, idx, err, spew.Sdump(req)) + b.serverError(err) + break + } + + if b.latency > 0 { + time.Sleep(b.latency) + } + + b.lock.Lock() + res := b.handler(req) + b.history = append(b.history, RequestResponse{req.body, res}) + b.lock.Unlock() + + if res == nil { + Logger.Printf("*** mockbroker/%d/%d: ignored %v", b.brokerID, idx, spew.Sdump(req)) + continue + } + Logger.Printf("*** mockbroker/%d/%d: served %v -> %v", b.brokerID, idx, req, res) + + encodedRes, err := encode(res) + if err != nil { + b.serverError(err) + break + } + if len(encodedRes) == 0 { + continue + } + + binary.BigEndian.PutUint32(resHeader, uint32(len(encodedRes)+4)) + binary.BigEndian.PutUint32(resHeader[4:], uint32(req.correlationID)) + if _, err = conn.Write(resHeader); err != nil { + b.serverError(err) + break + } + if _, err = conn.Write(encodedRes); err != nil { + b.serverError(err) + break + } + } + Logger.Printf("*** mockbroker/%d/%d: connection closed, err=%v", b.BrokerID(), idx, err) +} + +func (b *MockBroker) defaultRequestHandler(req *request) (res encoder) { + select { + case res, ok := <-b.expectations: + if !ok { + return nil + } + return res + case <-time.After(expectationTimeout): + return nil + } +} + +func (b *MockBroker) serverError(err error) { + isConnectionClosedError := false + if _, ok := err.(*net.OpError); ok { + isConnectionClosedError = true + } else if err == io.EOF { + isConnectionClosedError = true + } else if err.Error() == "use of closed network connection" { + isConnectionClosedError = true + } + + if isConnectionClosedError { + return + } + + b.t.Errorf(err.Error()) +} + +// NewMockBroker launches a fake Kafka broker. It takes a *testing.T as provided by the +// test framework and a channel of responses to use. If an error occurs it is +// simply logged to the *testing.T and the broker exits. +func NewMockBroker(t *testing.T, brokerID int32) *MockBroker { + return NewMockBrokerAddr(t, brokerID, "localhost:0") +} + +// NewMockBrokerAddr behaves like newMockBroker but listens on the address you give +// it rather than just some ephemeral port. +func NewMockBrokerAddr(t *testing.T, brokerID int32, addr string) *MockBroker { + var err error + + broker := &MockBroker{ + closing: make(chan none), + stopper: make(chan none), + t: t, + brokerID: brokerID, + expectations: make(chan encoder, 512), + } + broker.handler = broker.defaultRequestHandler + + broker.listener, err = net.Listen("tcp", addr) + if err != nil { + t.Fatal(err) + } + Logger.Printf("*** mockbroker/%d listening on %s\n", brokerID, broker.listener.Addr().String()) + _, portStr, err := net.SplitHostPort(broker.listener.Addr().String()) + if err != nil { + t.Fatal(err) + } + tmp, err := strconv.ParseInt(portStr, 10, 32) + if err != nil { + t.Fatal(err) + } + broker.port = int32(tmp) + + go broker.serverLoop() + + return broker +} + +func (b *MockBroker) Returns(e encoder) { + b.expectations <- e +} diff --git a/vendor/github.com/Shopify/sarama/mockresponses.go b/vendor/github.com/Shopify/sarama/mockresponses.go new file mode 100644 index 0000000..a0525d5 --- /dev/null +++ b/vendor/github.com/Shopify/sarama/mockresponses.go @@ -0,0 +1,447 @@ +package sarama + +import ( + "fmt" + "testing" +) + +// MockResponse is a response builder interface it defines one method that +// allows generating a response based on a request body. MockResponses are used +// to program behavior of MockBroker in tests. +type MockResponse interface { + For(reqBody decoder) (res encoder) +} + +// MockWrapper is a mock response builder that returns a particular concrete +// response regardless of the actual request passed to the `For` method. +type MockWrapper struct { + res encoder +} + +func (mw *MockWrapper) For(reqBody decoder) (res encoder) { + return mw.res +} + +func NewMockWrapper(res encoder) *MockWrapper { + return &MockWrapper{res: res} +} + +// MockSequence is a mock response builder that is created from a sequence of +// concrete responses. Every time when a `MockBroker` calls its `For` method +// the next response from the sequence is returned. When the end of the +// sequence is reached the last element from the sequence is returned. +type MockSequence struct { + responses []MockResponse +} + +func NewMockSequence(responses ...interface{}) *MockSequence { + ms := &MockSequence{} + ms.responses = make([]MockResponse, len(responses)) + for i, res := range responses { + switch res := res.(type) { + case MockResponse: + ms.responses[i] = res + case encoder: + ms.responses[i] = NewMockWrapper(res) + default: + panic(fmt.Sprintf("Unexpected response type: %T", res)) + } + } + return ms +} + +func (mc *MockSequence) For(reqBody decoder) (res encoder) { + res = mc.responses[0].For(reqBody) + if len(mc.responses) > 1 { + mc.responses = mc.responses[1:] + } + return res +} + +// MockMetadataResponse is a `MetadataResponse` builder. +type MockMetadataResponse struct { + leaders map[string]map[int32]int32 + brokers map[string]int32 + t *testing.T +} + +func NewMockMetadataResponse(t *testing.T) *MockMetadataResponse { + return &MockMetadataResponse{ + leaders: make(map[string]map[int32]int32), + brokers: make(map[string]int32), + t: t, + } +} + +func (mmr *MockMetadataResponse) SetLeader(topic string, partition, brokerID int32) *MockMetadataResponse { + partitions := mmr.leaders[topic] + if partitions == nil { + partitions = make(map[int32]int32) + mmr.leaders[topic] = partitions + } + partitions[partition] = brokerID + return mmr +} + +func (mmr *MockMetadataResponse) SetBroker(addr string, brokerID int32) *MockMetadataResponse { + mmr.brokers[addr] = brokerID + return mmr +} + +func (mmr *MockMetadataResponse) For(reqBody decoder) encoder { + metadataRequest := reqBody.(*MetadataRequest) + metadataResponse := &MetadataResponse{} + for addr, brokerID := range mmr.brokers { + metadataResponse.AddBroker(addr, brokerID) + } + if len(metadataRequest.Topics) == 0 { + for topic, partitions := range mmr.leaders { + for partition, brokerID := range partitions { + metadataResponse.AddTopicPartition(topic, partition, brokerID, nil, nil, ErrNoError) + } + } + return metadataResponse + } + for _, topic := range metadataRequest.Topics { + for partition, brokerID := range mmr.leaders[topic] { + metadataResponse.AddTopicPartition(topic, partition, brokerID, nil, nil, ErrNoError) + } + } + return metadataResponse +} + +// MockOffsetResponse is an `OffsetResponse` builder. +type MockOffsetResponse struct { + offsets map[string]map[int32]map[int64]int64 + t *testing.T +} + +func NewMockOffsetResponse(t *testing.T) *MockOffsetResponse { + return &MockOffsetResponse{ + offsets: make(map[string]map[int32]map[int64]int64), + t: t, + } +} + +func (mor *MockOffsetResponse) SetOffset(topic string, partition int32, time, offset int64) *MockOffsetResponse { + partitions := mor.offsets[topic] + if partitions == nil { + partitions = make(map[int32]map[int64]int64) + mor.offsets[topic] = partitions + } + times := partitions[partition] + if times == nil { + times = make(map[int64]int64) + partitions[partition] = times + } + times[time] = offset + return mor +} + +func (mor *MockOffsetResponse) For(reqBody decoder) encoder { + offsetRequest := reqBody.(*OffsetRequest) + offsetResponse := &OffsetResponse{} + for topic, partitions := range offsetRequest.blocks { + for partition, block := range partitions { + offset := mor.getOffset(topic, partition, block.time) + offsetResponse.AddTopicPartition(topic, partition, offset) + } + } + return offsetResponse +} + +func (mor *MockOffsetResponse) getOffset(topic string, partition int32, time int64) int64 { + partitions := mor.offsets[topic] + if partitions == nil { + mor.t.Errorf("missing topic: %s", topic) + } + times := partitions[partition] + if times == nil { + mor.t.Errorf("missing partition: %d", partition) + } + offset, ok := times[time] + if !ok { + mor.t.Errorf("missing time: %d", time) + } + return offset +} + +// MockFetchResponse is a `FetchResponse` builder. +type MockFetchResponse struct { + messages map[string]map[int32]map[int64]Encoder + highWaterMarks map[string]map[int32]int64 + t *testing.T + batchSize int +} + +func NewMockFetchResponse(t *testing.T, batchSize int) *MockFetchResponse { + return &MockFetchResponse{ + messages: make(map[string]map[int32]map[int64]Encoder), + highWaterMarks: make(map[string]map[int32]int64), + t: t, + batchSize: batchSize, + } +} + +func (mfr *MockFetchResponse) SetMessage(topic string, partition int32, offset int64, msg Encoder) *MockFetchResponse { + partitions := mfr.messages[topic] + if partitions == nil { + partitions = make(map[int32]map[int64]Encoder) + mfr.messages[topic] = partitions + } + messages := partitions[partition] + if messages == nil { + messages = make(map[int64]Encoder) + partitions[partition] = messages + } + messages[offset] = msg + return mfr +} + +func (mfr *MockFetchResponse) SetHighWaterMark(topic string, partition int32, offset int64) *MockFetchResponse { + partitions := mfr.highWaterMarks[topic] + if partitions == nil { + partitions = make(map[int32]int64) + mfr.highWaterMarks[topic] = partitions + } + partitions[partition] = offset + return mfr +} + +func (mfr *MockFetchResponse) For(reqBody decoder) encoder { + fetchRequest := reqBody.(*FetchRequest) + res := &FetchResponse{} + for topic, partitions := range fetchRequest.blocks { + for partition, block := range partitions { + initialOffset := block.fetchOffset + offset := initialOffset + maxOffset := initialOffset + int64(mfr.getMessageCount(topic, partition)) + for i := 0; i < mfr.batchSize && offset < maxOffset; { + msg := mfr.getMessage(topic, partition, offset) + if msg != nil { + res.AddMessage(topic, partition, nil, msg, offset) + i++ + } + offset++ + } + fb := res.GetBlock(topic, partition) + if fb == nil { + res.AddError(topic, partition, ErrNoError) + fb = res.GetBlock(topic, partition) + } + fb.HighWaterMarkOffset = mfr.getHighWaterMark(topic, partition) + } + } + return res +} + +func (mfr *MockFetchResponse) getMessage(topic string, partition int32, offset int64) Encoder { + partitions := mfr.messages[topic] + if partitions == nil { + return nil + } + messages := partitions[partition] + if messages == nil { + return nil + } + return messages[offset] +} + +func (mfr *MockFetchResponse) getMessageCount(topic string, partition int32) int { + partitions := mfr.messages[topic] + if partitions == nil { + return 0 + } + messages := partitions[partition] + if messages == nil { + return 0 + } + return len(messages) +} + +func (mfr *MockFetchResponse) getHighWaterMark(topic string, partition int32) int64 { + partitions := mfr.highWaterMarks[topic] + if partitions == nil { + return 0 + } + return partitions[partition] +} + +// MockConsumerMetadataResponse is a `ConsumerMetadataResponse` builder. +type MockConsumerMetadataResponse struct { + coordinators map[string]interface{} + t *testing.T +} + +func NewMockConsumerMetadataResponse(t *testing.T) *MockConsumerMetadataResponse { + return &MockConsumerMetadataResponse{ + coordinators: make(map[string]interface{}), + t: t, + } +} + +func (mr *MockConsumerMetadataResponse) SetCoordinator(group string, broker *MockBroker) *MockConsumerMetadataResponse { + mr.coordinators[group] = broker + return mr +} + +func (mr *MockConsumerMetadataResponse) SetError(group string, kerror KError) *MockConsumerMetadataResponse { + mr.coordinators[group] = kerror + return mr +} + +func (mr *MockConsumerMetadataResponse) For(reqBody decoder) encoder { + req := reqBody.(*ConsumerMetadataRequest) + group := req.ConsumerGroup + res := &ConsumerMetadataResponse{} + v := mr.coordinators[group] + switch v := v.(type) { + case *MockBroker: + res.Coordinator = &Broker{id: v.BrokerID(), addr: v.Addr()} + case KError: + res.Err = v + } + return res +} + +// MockOffsetCommitResponse is a `OffsetCommitResponse` builder. +type MockOffsetCommitResponse struct { + errors map[string]map[string]map[int32]KError + t *testing.T +} + +func NewMockOffsetCommitResponse(t *testing.T) *MockOffsetCommitResponse { + return &MockOffsetCommitResponse{t: t} +} + +func (mr *MockOffsetCommitResponse) SetError(group, topic string, partition int32, kerror KError) *MockOffsetCommitResponse { + if mr.errors == nil { + mr.errors = make(map[string]map[string]map[int32]KError) + } + topics := mr.errors[group] + if topics == nil { + topics = make(map[string]map[int32]KError) + mr.errors[group] = topics + } + partitions := topics[topic] + if partitions == nil { + partitions = make(map[int32]KError) + topics[topic] = partitions + } + partitions[partition] = kerror + return mr +} + +func (mr *MockOffsetCommitResponse) For(reqBody decoder) encoder { + req := reqBody.(*OffsetCommitRequest) + group := req.ConsumerGroup + res := &OffsetCommitResponse{} + for topic, partitions := range req.blocks { + for partition := range partitions { + res.AddError(topic, partition, mr.getError(group, topic, partition)) + } + } + return res +} + +func (mr *MockOffsetCommitResponse) getError(group, topic string, partition int32) KError { + topics := mr.errors[group] + if topics == nil { + return ErrNoError + } + partitions := topics[topic] + if partitions == nil { + return ErrNoError + } + kerror, ok := partitions[partition] + if !ok { + return ErrNoError + } + return kerror +} + +// MockProduceResponse is a `ProduceResponse` builder. +type MockProduceResponse struct { + errors map[string]map[int32]KError + t *testing.T +} + +func NewMockProduceResponse(t *testing.T) *MockProduceResponse { + return &MockProduceResponse{t: t} +} + +func (mr *MockProduceResponse) SetError(topic string, partition int32, kerror KError) *MockProduceResponse { + if mr.errors == nil { + mr.errors = make(map[string]map[int32]KError) + } + partitions := mr.errors[topic] + if partitions == nil { + partitions = make(map[int32]KError) + mr.errors[topic] = partitions + } + partitions[partition] = kerror + return mr +} + +func (mr *MockProduceResponse) For(reqBody decoder) encoder { + req := reqBody.(*ProduceRequest) + res := &ProduceResponse{} + for topic, partitions := range req.msgSets { + for partition := range partitions { + res.AddTopicPartition(topic, partition, mr.getError(topic, partition)) + } + } + return res +} + +func (mr *MockProduceResponse) getError(topic string, partition int32) KError { + partitions := mr.errors[topic] + if partitions == nil { + return ErrNoError + } + kerror, ok := partitions[partition] + if !ok { + return ErrNoError + } + return kerror +} + +// MockOffsetFetchResponse is a `OffsetFetchResponse` builder. +type MockOffsetFetchResponse struct { + offsets map[string]map[string]map[int32]*OffsetFetchResponseBlock + t *testing.T +} + +func NewMockOffsetFetchResponse(t *testing.T) *MockOffsetFetchResponse { + return &MockOffsetFetchResponse{t: t} +} + +func (mr *MockOffsetFetchResponse) SetOffset(group, topic string, partition int32, offset int64, metadata string, kerror KError) *MockOffsetFetchResponse { + if mr.offsets == nil { + mr.offsets = make(map[string]map[string]map[int32]*OffsetFetchResponseBlock) + } + topics := mr.offsets[group] + if topics == nil { + topics = make(map[string]map[int32]*OffsetFetchResponseBlock) + mr.offsets[group] = topics + } + partitions := topics[topic] + if partitions == nil { + partitions = make(map[int32]*OffsetFetchResponseBlock) + topics[topic] = partitions + } + partitions[partition] = &OffsetFetchResponseBlock{offset, metadata, kerror} + return mr +} + +func (mr *MockOffsetFetchResponse) For(reqBody decoder) encoder { + req := reqBody.(*OffsetFetchRequest) + group := req.ConsumerGroup + res := &OffsetFetchResponse{} + for topic, partitions := range mr.offsets[group] { + for partition, block := range partitions { + res.AddBlock(topic, partition, block) + } + } + return res +} diff --git a/vendor/github.com/Shopify/sarama/mocks/README.md b/vendor/github.com/Shopify/sarama/mocks/README.md new file mode 100644 index 0000000..55a6c2e --- /dev/null +++ b/vendor/github.com/Shopify/sarama/mocks/README.md @@ -0,0 +1,13 @@ +# sarama/mocks + +The `mocks` subpackage includes mock implementations that implement the interfaces of the major sarama types. +You can use them to test your sarama applications using dependency injection. + +The following mock objects are available: + +- [Consumer](https://godoc.org/github.com/Shopify/sarama/mocks#Consumer), which will create [PartitionConsumer](https://godoc.org/github.com/Shopify/sarama/mocks#PartitionConsumer) mocks. +- [AsyncProducer](https://godoc.org/github.com/Shopify/sarama/mocks#AsyncProducer) +- [SyncProducer](https://godoc.org/github.com/Shopify/sarama/mocks#SyncProducer) + +The mocks allow you to set expectations on them. When you close the mocks, the expectations will be verified, +and the results will be reported to the `*testing.T` object you provided when creating the mock. diff --git a/vendor/github.com/Shopify/sarama/mocks/async_producer.go b/vendor/github.com/Shopify/sarama/mocks/async_producer.go new file mode 100644 index 0000000..6ccf1f1 --- /dev/null +++ b/vendor/github.com/Shopify/sarama/mocks/async_producer.go @@ -0,0 +1,142 @@ +package mocks + +import ( + "sync" + + "github.com/Shopify/sarama" +) + +// AsyncProducer implements sarama's Producer interface for testing purposes. +// Before you can send messages to it's Input channel, you have to set expectations +// so it knows how to handle the input. This way you can easily test success and +// failure scenarios. +type AsyncProducer struct { + l sync.Mutex + t ErrorReporter + expectations []*producerExpectation + closed chan struct{} + input chan *sarama.ProducerMessage + successes chan *sarama.ProducerMessage + errors chan *sarama.ProducerError + lastOffset int64 +} + +// NewAsyncProducer instantiates a new Producer mock. The t argument should +// be the *testing.T instance of your test method. An error will be written to it if +// an expectation is violated. The config argument is used to determine whether it +// should ack successes on the Successes channel. +func NewAsyncProducer(t ErrorReporter, config *sarama.Config) *AsyncProducer { + if config == nil { + config = sarama.NewConfig() + } + mp := &AsyncProducer{ + t: t, + closed: make(chan struct{}, 0), + expectations: make([]*producerExpectation, 0), + input: make(chan *sarama.ProducerMessage, config.ChannelBufferSize), + successes: make(chan *sarama.ProducerMessage, config.ChannelBufferSize), + errors: make(chan *sarama.ProducerError, config.ChannelBufferSize), + } + + go func() { + defer func() { + close(mp.successes) + close(mp.errors) + }() + + for msg := range mp.input { + mp.l.Lock() + if mp.expectations == nil || len(mp.expectations) == 0 { + mp.expectations = nil + mp.t.Errorf("No more expectation set on this mock producer to handle the input message.") + } else { + expectation := mp.expectations[0] + mp.expectations = mp.expectations[1:] + if expectation.Result == errProduceSuccess { + mp.lastOffset++ + if config.Producer.Return.Successes { + msg.Offset = mp.lastOffset + mp.successes <- msg + } + } else { + if config.Producer.Return.Errors { + mp.errors <- &sarama.ProducerError{Err: expectation.Result, Msg: msg} + } + } + } + mp.l.Unlock() + } + + mp.l.Lock() + if len(mp.expectations) > 0 { + mp.t.Errorf("Expected to exhaust all expectations, but %d are left.", len(mp.expectations)) + } + mp.l.Unlock() + + close(mp.closed) + }() + + return mp +} + +//////////////////////////////////////////////// +// Implement Producer interface +//////////////////////////////////////////////// + +// AsyncClose corresponds with the AsyncClose method of sarama's Producer implementation. +// By closing a mock producer, you also tell it that no more input will be provided, so it will +// write an error to the test state if there's any remaining expectations. +func (mp *AsyncProducer) AsyncClose() { + close(mp.input) +} + +// Close corresponds with the Close method of sarama's Producer implementation. +// By closing a mock producer, you also tell it that no more input will be provided, so it will +// write an error to the test state if there's any remaining expectations. +func (mp *AsyncProducer) Close() error { + mp.AsyncClose() + <-mp.closed + return nil +} + +// Input corresponds with the Input method of sarama's Producer implementation. +// You have to set expectations on the mock producer before writing messages to the Input +// channel, so it knows how to handle them. If there is no more remaining expectations and +// a messages is written to the Input channel, the mock producer will write an error to the test +// state object. +func (mp *AsyncProducer) Input() chan<- *sarama.ProducerMessage { + return mp.input +} + +// Successes corresponds with the Successes method of sarama's Producer implementation. +func (mp *AsyncProducer) Successes() <-chan *sarama.ProducerMessage { + return mp.successes +} + +// Errors corresponds with the Errors method of sarama's Producer implementation. +func (mp *AsyncProducer) Errors() <-chan *sarama.ProducerError { + return mp.errors +} + +//////////////////////////////////////////////// +// Setting expectations +//////////////////////////////////////////////// + +// ExpectInputAndSucceed sets an expectation on the mock producer that a message will be provided +// on the input channel. The mock producer will handle the message as if it is produced successfully, +// i.e. it will make it available on the Successes channel if the Producer.Return.Successes setting +// is set to true. +func (mp *AsyncProducer) ExpectInputAndSucceed() { + mp.l.Lock() + defer mp.l.Unlock() + mp.expectations = append(mp.expectations, &producerExpectation{Result: errProduceSuccess}) +} + +// ExpectInputAndFail sets an expectation on the mock producer that a message will be provided +// on the input channel. The mock producer will handle the message as if it failed to produce +// successfully. This means it will make a ProducerError available on the Errors channel. +func (mp *AsyncProducer) ExpectInputAndFail(err error) { + mp.l.Lock() + defer mp.l.Unlock() + mp.expectations = append(mp.expectations, &producerExpectation{Result: err}) +} diff --git a/vendor/github.com/Shopify/sarama/mocks/consumer.go b/vendor/github.com/Shopify/sarama/mocks/consumer.go new file mode 100644 index 0000000..a2c394e --- /dev/null +++ b/vendor/github.com/Shopify/sarama/mocks/consumer.go @@ -0,0 +1,299 @@ +package mocks + +import ( + "sync" + "sync/atomic" + + "github.com/Shopify/sarama" +) + +// Consumer implements sarama's Consumer interface for testing purposes. +// Before you can start consuming from this consumer, you have to register +// topic/partitions using ExpectConsumePartition, and set expectations on them. +type Consumer struct { + l sync.Mutex + t ErrorReporter + config *sarama.Config + partitionConsumers map[string]map[int32]*PartitionConsumer + metadata map[string][]int32 +} + +// NewConsumer returns a new mock Consumer instance. The t argument should +// be the *testing.T instance of your test method. An error will be written to it if +// an expectation is violated. The config argument is currently unused and can be set to nil. +func NewConsumer(t ErrorReporter, config *sarama.Config) *Consumer { + if config == nil { + config = sarama.NewConfig() + } + + c := &Consumer{ + t: t, + config: config, + partitionConsumers: make(map[string]map[int32]*PartitionConsumer), + } + return c +} + +/////////////////////////////////////////////////// +// Consumer interface implementation +/////////////////////////////////////////////////// + +// ConsumePartition implements the ConsumePartition method from the sarama.Consumer interface. +// Before you can start consuming a partition, you have to set expectations on it using +// ExpectConsumePartition. You can only consume a partition once per consumer. +func (c *Consumer) ConsumePartition(topic string, partition int32, offset int64) (sarama.PartitionConsumer, error) { + c.l.Lock() + defer c.l.Unlock() + + if c.partitionConsumers[topic] == nil || c.partitionConsumers[topic][partition] == nil { + c.t.Errorf("No expectations set for %s/%d", topic, partition) + return nil, errOutOfExpectations + } + + pc := c.partitionConsumers[topic][partition] + if pc.consumed { + return nil, sarama.ConfigurationError("The topic/partition is already being consumed") + } + + if pc.offset != AnyOffset && pc.offset != offset { + c.t.Errorf("Unexpected offset when calling ConsumePartition for %s/%d. Expected %d, got %d.", topic, partition, pc.offset, offset) + } + + pc.consumed = true + return pc, nil +} + +// Topics returns a list of topics, as registered with SetMetadata +func (c *Consumer) Topics() ([]string, error) { + c.l.Lock() + defer c.l.Unlock() + + if c.metadata == nil { + c.t.Errorf("Unexpected call to Topics. Initialize the mock's topic metadata with SetMetadata.") + return nil, sarama.ErrOutOfBrokers + } + + var result []string + for topic := range c.metadata { + result = append(result, topic) + } + return result, nil +} + +// Partitions returns the list of parititons for the given topic, as registered with SetMetadata +func (c *Consumer) Partitions(topic string) ([]int32, error) { + c.l.Lock() + defer c.l.Unlock() + + if c.metadata == nil { + c.t.Errorf("Unexpected call to Partitions. Initialize the mock's topic metadata with SetMetadata.") + return nil, sarama.ErrOutOfBrokers + } + if c.metadata[topic] == nil { + return nil, sarama.ErrUnknownTopicOrPartition + } + + return c.metadata[topic], nil +} + +// Close implements the Close method from the sarama.Consumer interface. It will close +// all registered PartitionConsumer instances. +func (c *Consumer) Close() error { + c.l.Lock() + defer c.l.Unlock() + + for _, partitions := range c.partitionConsumers { + for _, partitionConsumer := range partitions { + _ = partitionConsumer.Close() + } + } + + return nil +} + +/////////////////////////////////////////////////// +// Expectation API +/////////////////////////////////////////////////// + +// SetTopicMetadata sets the clusters topic/partition metadata, +// which will be returned by Topics() and Partitions(). +func (c *Consumer) SetTopicMetadata(metadata map[string][]int32) { + c.l.Lock() + defer c.l.Unlock() + + c.metadata = metadata +} + +// ExpectConsumePartition will register a topic/partition, so you can set expectations on it. +// The registered PartitionConsumer will be returned, so you can set expectations +// on it using method chanining. Once a topic/partition is registered, you are +// expected to start consuming it using ConsumePartition. If that doesn't happen, +// an error will be written to the error reporter once the mock consumer is closed. It will +// also expect that the +func (c *Consumer) ExpectConsumePartition(topic string, partition int32, offset int64) *PartitionConsumer { + c.l.Lock() + defer c.l.Unlock() + + if c.partitionConsumers[topic] == nil { + c.partitionConsumers[topic] = make(map[int32]*PartitionConsumer) + } + + if c.partitionConsumers[topic][partition] == nil { + c.partitionConsumers[topic][partition] = &PartitionConsumer{ + t: c.t, + topic: topic, + partition: partition, + offset: offset, + messages: make(chan *sarama.ConsumerMessage, c.config.ChannelBufferSize), + errors: make(chan *sarama.ConsumerError, c.config.ChannelBufferSize), + } + } + + return c.partitionConsumers[topic][partition] +} + +/////////////////////////////////////////////////// +// PartitionConsumer mock type +/////////////////////////////////////////////////// + +// PartitionConsumer implements sarama's PartitionConsumer interface for testing purposes. +// It is returned by the mock Consumers ConsumePartitionMethod, but only if it is +// registered first using the Consumer's ExpectConsumePartition method. Before consuming the +// Errors and Messages channel, you should specify what values will be provided on these +// channels using YieldMessage and YieldError. +type PartitionConsumer struct { + l sync.Mutex + t ErrorReporter + topic string + partition int32 + offset int64 + messages chan *sarama.ConsumerMessage + errors chan *sarama.ConsumerError + singleClose sync.Once + consumed bool + errorsShouldBeDrained bool + messagesShouldBeDrained bool + highWaterMarkOffset int64 +} + +/////////////////////////////////////////////////// +// PartitionConsumer interface implementation +/////////////////////////////////////////////////// + +// AsyncClose implements the AsyncClose method from the sarama.PartitionConsumer interface. +func (pc *PartitionConsumer) AsyncClose() { + pc.singleClose.Do(func() { + close(pc.messages) + close(pc.errors) + }) +} + +// Close implements the Close method from the sarama.PartitionConsumer interface. It will +// verify whether the partition consumer was actually started. +func (pc *PartitionConsumer) Close() error { + if !pc.consumed { + pc.t.Errorf("Expectations set on %s/%d, but no partition consumer was started.", pc.topic, pc.partition) + return errPartitionConsumerNotStarted + } + + if pc.errorsShouldBeDrained && len(pc.errors) > 0 { + pc.t.Errorf("Expected the errors channel for %s/%d to be drained on close, but found %d errors.", pc.topic, pc.partition, len(pc.errors)) + } + + if pc.messagesShouldBeDrained && len(pc.messages) > 0 { + pc.t.Errorf("Expected the messages channel for %s/%d to be drained on close, but found %d messages.", pc.topic, pc.partition, len(pc.messages)) + } + + pc.AsyncClose() + + var ( + closeErr error + wg sync.WaitGroup + ) + + wg.Add(1) + go func() { + defer wg.Done() + + var errs = make(sarama.ConsumerErrors, 0) + for err := range pc.errors { + errs = append(errs, err) + } + + if len(errs) > 0 { + closeErr = errs + } + }() + + wg.Add(1) + go func() { + defer wg.Done() + for _ = range pc.messages { + // drain + } + }() + + wg.Wait() + return closeErr +} + +// Errors implements the Errors method from the sarama.PartitionConsumer interface. +func (pc *PartitionConsumer) Errors() <-chan *sarama.ConsumerError { + return pc.errors +} + +// Messages implements the Messages method from the sarama.PartitionConsumer interface. +func (pc *PartitionConsumer) Messages() <-chan *sarama.ConsumerMessage { + return pc.messages +} + +func (pc *PartitionConsumer) HighWaterMarkOffset() int64 { + return atomic.LoadInt64(&pc.highWaterMarkOffset) + 1 +} + +/////////////////////////////////////////////////// +// Expectation API +/////////////////////////////////////////////////// + +// YieldMessage will yield a messages Messages channel of this partition consumer +// when it is consumed. By default, the mock consumer will not verify whether this +// message was consumed from the Messages channel, because there are legitimate +// reasons forthis not to happen. ou can call ExpectMessagesDrainedOnClose so it will +// verify that the channel is empty on close. +func (pc *PartitionConsumer) YieldMessage(msg *sarama.ConsumerMessage) { + pc.l.Lock() + defer pc.l.Unlock() + + msg.Topic = pc.topic + msg.Partition = pc.partition + msg.Offset = atomic.AddInt64(&pc.highWaterMarkOffset, 1) + + pc.messages <- msg +} + +// YieldError will yield an error on the Errors channel of this partition consumer +// when it is consumed. By default, the mock consumer will not verify whether this error was +// consumed from the Errors channel, because there are legitimate reasons for this +// not to happen. You can call ExpectErrorsDrainedOnClose so it will verify that +// the channel is empty on close. +func (pc *PartitionConsumer) YieldError(err error) { + pc.errors <- &sarama.ConsumerError{ + Topic: pc.topic, + Partition: pc.partition, + Err: err, + } +} + +// ExpectMessagesDrainedOnClose sets an expectation on the partition consumer +// that the messages channel will be fully drained when Close is called. If this +// expectation is not met, an error is reported to the error reporter. +func (pc *PartitionConsumer) ExpectMessagesDrainedOnClose() { + pc.messagesShouldBeDrained = true +} + +// ExpectErrorsDrainedOnClose sets an expectation on the partition consumer +// that the errors channel will be fully drained when Close is called. If this +// expectation is not met, an error is reported to the error reporter. +func (pc *PartitionConsumer) ExpectErrorsDrainedOnClose() { + pc.errorsShouldBeDrained = true +} diff --git a/vendor/github.com/Shopify/sarama/mocks/mocks.go b/vendor/github.com/Shopify/sarama/mocks/mocks.go new file mode 100644 index 0000000..96b79bc --- /dev/null +++ b/vendor/github.com/Shopify/sarama/mocks/mocks.go @@ -0,0 +1,43 @@ +/* +Package mocks provides mocks that can be used for testing applications +that use Sarama. The mock types provided by this package implement the +interfaces Sarama exports, so you can use them for dependency injection +in your tests. + +All mock instances require you to set expectations on them before you +can use them. It will determine how the mock will behave. If an +expectation is not met, it will make your test fail. + +NOTE: this package currently does not fall under the API stability +guarantee of Sarama as it is still considered experimental. +*/ +package mocks + +import ( + "errors" + + "github.com/Shopify/sarama" +) + +// ErrorReporter is a simple interface that includes the testing.T methods we use to report +// expectation violations when using the mock objects. +type ErrorReporter interface { + Errorf(string, ...interface{}) +} + +var ( + errProduceSuccess error = nil + errOutOfExpectations = errors.New("No more expectations set on mock") + errPartitionConsumerNotStarted = errors.New("The partition consumer was never started") +) + +const AnyOffset int64 = -1000 + +type producerExpectation struct { + Result error +} + +type consumerExpectation struct { + Err error + Msg *sarama.ConsumerMessage +} diff --git a/vendor/github.com/Shopify/sarama/mocks/sync_producer.go b/vendor/github.com/Shopify/sarama/mocks/sync_producer.go new file mode 100644 index 0000000..fa86b24 --- /dev/null +++ b/vendor/github.com/Shopify/sarama/mocks/sync_producer.go @@ -0,0 +1,94 @@ +package mocks + +import ( + "sync" + + "github.com/Shopify/sarama" +) + +// SyncProducer implements sarama's SyncProducer interface for testing purposes. +// Before you can use it, you have to set expectations on the mock SyncProducer +// to tell it how to handle calls to SendMessage, so you can easily test success +// and failure scenarios. +type SyncProducer struct { + l sync.Mutex + t ErrorReporter + expectations []*producerExpectation + lastOffset int64 +} + +// NewSyncProducer instantiates a new SyncProducer mock. The t argument should +// be the *testing.T instance of your test method. An error will be written to it if +// an expectation is violated. The config argument is currently unused, but is +// maintained to be compatible with the async Producer. +func NewSyncProducer(t ErrorReporter, config *sarama.Config) *SyncProducer { + return &SyncProducer{ + t: t, + expectations: make([]*producerExpectation, 0), + } +} + +//////////////////////////////////////////////// +// Implement SyncProducer interface +//////////////////////////////////////////////// + +// SendMessage corresponds with the SendMessage method of sarama's SyncProducer implementation. +// You have to set expectations on the mock producer before calling SendMessage, so it knows +// how to handle them. If there is no more remaining expectations when SendMessage is called, +// the mock producer will write an error to the test state object. +func (sp *SyncProducer) SendMessage(msg *sarama.ProducerMessage) (partition int32, offset int64, err error) { + sp.l.Lock() + defer sp.l.Unlock() + + if len(sp.expectations) > 0 { + expectation := sp.expectations[0] + sp.expectations = sp.expectations[1:] + + if expectation.Result == errProduceSuccess { + sp.lastOffset++ + msg.Offset = sp.lastOffset + return 0, msg.Offset, nil + } else { + return -1, -1, expectation.Result + } + } else { + sp.t.Errorf("No more expectation set on this mock producer to handle the input message.") + return -1, -1, errOutOfExpectations + } +} + +// Close corresponds with the Close method of sarama's SyncProducer implementation. +// By closing a mock syncproducer, you also tell it that no more SendMessage calls will follow, +// so it will write an error to the test state if there's any remaining expectations. +func (sp *SyncProducer) Close() error { + sp.l.Lock() + defer sp.l.Unlock() + + if len(sp.expectations) > 0 { + sp.t.Errorf("Expected to exhaust all expectations, but %d are left.", len(sp.expectations)) + } + + return nil +} + +//////////////////////////////////////////////// +// Setting expectations +//////////////////////////////////////////////// + +// ExpectSendMessageAndSucceed sets an expectation on the mock producer that SendMessage will be +// called. The mock producer will handle the message as if it produced successfully, i.e. by +// returning a valid partition, and offset, and a nil error. +func (sp *SyncProducer) ExpectSendMessageAndSucceed() { + sp.l.Lock() + defer sp.l.Unlock() + sp.expectations = append(sp.expectations, &producerExpectation{Result: errProduceSuccess}) +} + +// ExpectSendMessageAndFail sets an expectation on the mock producer that SendMessage will be +// called. The mock producer will handle the message as if it failed to produce +// successfully, i.e. by returning the provided error. +func (sp *SyncProducer) ExpectSendMessageAndFail(err error) { + sp.l.Lock() + defer sp.l.Unlock() + sp.expectations = append(sp.expectations, &producerExpectation{Result: err}) +} diff --git a/vendor/github.com/Shopify/sarama/offset_commit_request.go b/vendor/github.com/Shopify/sarama/offset_commit_request.go new file mode 100644 index 0000000..f518152 --- /dev/null +++ b/vendor/github.com/Shopify/sarama/offset_commit_request.go @@ -0,0 +1,177 @@ +package sarama + +// ReceiveTime is a special value for the timestamp field of Offset Commit Requests which +// tells the broker to set the timestamp to the time at which the request was received. +// The timestamp is only used if message version 1 is used, which requires kafka 0.8.2. +const ReceiveTime int64 = -1 + +// GroupGenerationUndefined is a special value for the group generation field of +// Offset Commit Requests that should be used when a consumer group does not rely +// on Kafka for partition management. +const GroupGenerationUndefined = -1 + +type offsetCommitRequestBlock struct { + offset int64 + timestamp int64 + metadata string +} + +func (r *offsetCommitRequestBlock) encode(pe packetEncoder, version int16) error { + pe.putInt64(r.offset) + if version == 1 { + pe.putInt64(r.timestamp) + } else if r.timestamp != 0 { + Logger.Println("Non-zero timestamp specified for OffsetCommitRequest not v1, it will be ignored") + } + + return pe.putString(r.metadata) +} + +func (r *offsetCommitRequestBlock) decode(pd packetDecoder, version int16) (err error) { + if r.offset, err = pd.getInt64(); err != nil { + return err + } + if version == 1 { + if r.timestamp, err = pd.getInt64(); err != nil { + return err + } + } + r.metadata, err = pd.getString() + return err +} + +type OffsetCommitRequest struct { + ConsumerGroup string + ConsumerGroupGeneration int32 // v1 or later + ConsumerID string // v1 or later + RetentionTime int64 // v2 or later + + // Version can be: + // - 0 (kafka 0.8.1 and later) + // - 1 (kafka 0.8.2 and later) + // - 2 (kafka 0.8.3 and later) + Version int16 + blocks map[string]map[int32]*offsetCommitRequestBlock +} + +func (r *OffsetCommitRequest) encode(pe packetEncoder) error { + if r.Version < 0 || r.Version > 2 { + return PacketEncodingError{"invalid or unsupported OffsetCommitRequest version field"} + } + + if err := pe.putString(r.ConsumerGroup); err != nil { + return err + } + + if r.Version >= 1 { + pe.putInt32(r.ConsumerGroupGeneration) + if err := pe.putString(r.ConsumerID); err != nil { + return err + } + } else { + if r.ConsumerGroupGeneration != 0 { + Logger.Println("Non-zero ConsumerGroupGeneration specified for OffsetCommitRequest v0, it will be ignored") + } + if r.ConsumerID != "" { + Logger.Println("Non-empty ConsumerID specified for OffsetCommitRequest v0, it will be ignored") + } + } + + if r.Version >= 2 { + pe.putInt64(r.RetentionTime) + } else if r.RetentionTime != 0 { + Logger.Println("Non-zero RetentionTime specified for OffsetCommitRequest version <2, it will be ignored") + } + + if err := pe.putArrayLength(len(r.blocks)); err != nil { + return err + } + for topic, partitions := range r.blocks { + if err := pe.putString(topic); err != nil { + return err + } + if err := pe.putArrayLength(len(partitions)); err != nil { + return err + } + for partition, block := range partitions { + pe.putInt32(partition) + if err := block.encode(pe, r.Version); err != nil { + return err + } + } + } + return nil +} + +func (r *OffsetCommitRequest) decode(pd packetDecoder) (err error) { + if r.ConsumerGroup, err = pd.getString(); err != nil { + return err + } + + if r.Version >= 1 { + if r.ConsumerGroupGeneration, err = pd.getInt32(); err != nil { + return err + } + if r.ConsumerID, err = pd.getString(); err != nil { + return err + } + } + + if r.Version >= 2 { + if r.RetentionTime, err = pd.getInt64(); err != nil { + return err + } + } + + topicCount, err := pd.getArrayLength() + if err != nil { + return err + } + if topicCount == 0 { + return nil + } + r.blocks = make(map[string]map[int32]*offsetCommitRequestBlock) + for i := 0; i < topicCount; i++ { + topic, err := pd.getString() + if err != nil { + return err + } + partitionCount, err := pd.getArrayLength() + if err != nil { + return err + } + r.blocks[topic] = make(map[int32]*offsetCommitRequestBlock) + for j := 0; j < partitionCount; j++ { + partition, err := pd.getInt32() + if err != nil { + return err + } + block := &offsetCommitRequestBlock{} + if err := block.decode(pd, r.Version); err != nil { + return err + } + r.blocks[topic][partition] = block + } + } + return nil +} + +func (r *OffsetCommitRequest) key() int16 { + return 8 +} + +func (r *OffsetCommitRequest) version() int16 { + return r.Version +} + +func (r *OffsetCommitRequest) AddBlock(topic string, partitionID int32, offset int64, timestamp int64, metadata string) { + if r.blocks == nil { + r.blocks = make(map[string]map[int32]*offsetCommitRequestBlock) + } + + if r.blocks[topic] == nil { + r.blocks[topic] = make(map[int32]*offsetCommitRequestBlock) + } + + r.blocks[topic][partitionID] = &offsetCommitRequestBlock{offset, timestamp, metadata} +} diff --git a/vendor/github.com/Shopify/sarama/offset_commit_response.go b/vendor/github.com/Shopify/sarama/offset_commit_response.go new file mode 100644 index 0000000..573a3b6 --- /dev/null +++ b/vendor/github.com/Shopify/sarama/offset_commit_response.go @@ -0,0 +1,73 @@ +package sarama + +type OffsetCommitResponse struct { + Errors map[string]map[int32]KError +} + +func (r *OffsetCommitResponse) AddError(topic string, partition int32, kerror KError) { + if r.Errors == nil { + r.Errors = make(map[string]map[int32]KError) + } + partitions := r.Errors[topic] + if partitions == nil { + partitions = make(map[int32]KError) + r.Errors[topic] = partitions + } + partitions[partition] = kerror +} + +func (r *OffsetCommitResponse) encode(pe packetEncoder) error { + if err := pe.putArrayLength(len(r.Errors)); err != nil { + return err + } + for topic, partitions := range r.Errors { + if err := pe.putString(topic); err != nil { + return err + } + if err := pe.putArrayLength(len(partitions)); err != nil { + return err + } + for partition, kerror := range partitions { + pe.putInt32(partition) + pe.putInt16(int16(kerror)) + } + } + return nil +} + +func (r *OffsetCommitResponse) decode(pd packetDecoder) (err error) { + numTopics, err := pd.getArrayLength() + if err != nil || numTopics == 0 { + return err + } + + r.Errors = make(map[string]map[int32]KError, numTopics) + for i := 0; i < numTopics; i++ { + name, err := pd.getString() + if err != nil { + return err + } + + numErrors, err := pd.getArrayLength() + if err != nil { + return err + } + + r.Errors[name] = make(map[int32]KError, numErrors) + + for j := 0; j < numErrors; j++ { + id, err := pd.getInt32() + if err != nil { + return err + } + + tmp, err := pd.getInt16() + if err != nil { + return err + } + r.Errors[name][id] = KError(tmp) + } + } + + return nil +} diff --git a/vendor/github.com/Shopify/sarama/offset_fetch_request.go b/vendor/github.com/Shopify/sarama/offset_fetch_request.go new file mode 100644 index 0000000..30bbbbb --- /dev/null +++ b/vendor/github.com/Shopify/sarama/offset_fetch_request.go @@ -0,0 +1,71 @@ +package sarama + +type OffsetFetchRequest struct { + ConsumerGroup string + Version int16 + partitions map[string][]int32 +} + +func (r *OffsetFetchRequest) encode(pe packetEncoder) (err error) { + if r.Version < 0 || r.Version > 1 { + return PacketEncodingError{"invalid or unsupported OffsetFetchRequest version field"} + } + + if err = pe.putString(r.ConsumerGroup); err != nil { + return err + } + if err = pe.putArrayLength(len(r.partitions)); err != nil { + return err + } + for topic, partitions := range r.partitions { + if err = pe.putString(topic); err != nil { + return err + } + if err = pe.putInt32Array(partitions); err != nil { + return err + } + } + return nil +} + +func (r *OffsetFetchRequest) decode(pd packetDecoder) (err error) { + if r.ConsumerGroup, err = pd.getString(); err != nil { + return err + } + partitionCount, err := pd.getArrayLength() + if err != nil { + return err + } + if partitionCount == 0 { + return nil + } + r.partitions = make(map[string][]int32) + for i := 0; i < partitionCount; i++ { + topic, err := pd.getString() + if err != nil { + return err + } + partitions, err := pd.getInt32Array() + if err != nil { + return err + } + r.partitions[topic] = partitions + } + return nil +} + +func (r *OffsetFetchRequest) key() int16 { + return 9 +} + +func (r *OffsetFetchRequest) version() int16 { + return r.Version +} + +func (r *OffsetFetchRequest) AddPartition(topic string, partitionID int32) { + if r.partitions == nil { + r.partitions = make(map[string][]int32) + } + + r.partitions[topic] = append(r.partitions[topic], partitionID) +} diff --git a/vendor/github.com/Shopify/sarama/offset_fetch_response.go b/vendor/github.com/Shopify/sarama/offset_fetch_response.go new file mode 100644 index 0000000..93078c3 --- /dev/null +++ b/vendor/github.com/Shopify/sarama/offset_fetch_response.go @@ -0,0 +1,131 @@ +package sarama + +type OffsetFetchResponseBlock struct { + Offset int64 + Metadata string + Err KError +} + +func (r *OffsetFetchResponseBlock) decode(pd packetDecoder) (err error) { + r.Offset, err = pd.getInt64() + if err != nil { + return err + } + + r.Metadata, err = pd.getString() + if err != nil { + return err + } + + tmp, err := pd.getInt16() + if err != nil { + return err + } + r.Err = KError(tmp) + + return nil +} + +func (r *OffsetFetchResponseBlock) encode(pe packetEncoder) (err error) { + pe.putInt64(r.Offset) + + err = pe.putString(r.Metadata) + if err != nil { + return err + } + + pe.putInt16(int16(r.Err)) + + return nil +} + +type OffsetFetchResponse struct { + Blocks map[string]map[int32]*OffsetFetchResponseBlock +} + +func (r *OffsetFetchResponse) encode(pe packetEncoder) error { + if err := pe.putArrayLength(len(r.Blocks)); err != nil { + return err + } + for topic, partitions := range r.Blocks { + if err := pe.putString(topic); err != nil { + return err + } + if err := pe.putArrayLength(len(partitions)); err != nil { + return err + } + for partition, block := range partitions { + pe.putInt32(partition) + if err := block.encode(pe); err != nil { + return err + } + } + } + return nil +} + +func (r *OffsetFetchResponse) decode(pd packetDecoder) (err error) { + numTopics, err := pd.getArrayLength() + if err != nil || numTopics == 0 { + return err + } + + r.Blocks = make(map[string]map[int32]*OffsetFetchResponseBlock, numTopics) + for i := 0; i < numTopics; i++ { + name, err := pd.getString() + if err != nil { + return err + } + + numBlocks, err := pd.getArrayLength() + if err != nil { + return err + } + + if numBlocks == 0 { + r.Blocks[name] = nil + continue + } + r.Blocks[name] = make(map[int32]*OffsetFetchResponseBlock, numBlocks) + + for j := 0; j < numBlocks; j++ { + id, err := pd.getInt32() + if err != nil { + return err + } + + block := new(OffsetFetchResponseBlock) + err = block.decode(pd) + if err != nil { + return err + } + r.Blocks[name][id] = block + } + } + + return nil +} + +func (r *OffsetFetchResponse) GetBlock(topic string, partition int32) *OffsetFetchResponseBlock { + if r.Blocks == nil { + return nil + } + + if r.Blocks[topic] == nil { + return nil + } + + return r.Blocks[topic][partition] +} + +func (r *OffsetFetchResponse) AddBlock(topic string, partition int32, block *OffsetFetchResponseBlock) { + if r.Blocks == nil { + r.Blocks = make(map[string]map[int32]*OffsetFetchResponseBlock) + } + partitions := r.Blocks[topic] + if partitions == nil { + partitions = make(map[int32]*OffsetFetchResponseBlock) + r.Blocks[topic] = partitions + } + partitions[partition] = block +} diff --git a/vendor/github.com/Shopify/sarama/offset_manager.go b/vendor/github.com/Shopify/sarama/offset_manager.go new file mode 100644 index 0000000..16fa1da --- /dev/null +++ b/vendor/github.com/Shopify/sarama/offset_manager.go @@ -0,0 +1,527 @@ +package sarama + +import ( + "sync" + "time" +) + +// Offset Manager + +// OffsetManager uses Kafka to store and fetch consumed partition offsets. +type OffsetManager interface { + // ManagePartition creates a PartitionOffsetManager on the given topic/partition. + // It will return an error if this OffsetManager is already managing the given + // topic/partition. + ManagePartition(topic string, partition int32) (PartitionOffsetManager, error) + + // Close stops the OffsetManager from managing offsets. It is required to call + // this function before an OffsetManager object passes out of scope, as it + // will otherwise leak memory. You must call this after all the + // PartitionOffsetManagers are closed. + Close() error +} + +type offsetManager struct { + client Client + conf *Config + group string + + lock sync.Mutex + poms map[string]map[int32]*partitionOffsetManager + boms map[*Broker]*brokerOffsetManager +} + +// NewOffsetManagerFromClient creates a new OffsetManager from the given client. +// It is still necessary to call Close() on the underlying client when finished with the partition manager. +func NewOffsetManagerFromClient(group string, client Client) (OffsetManager, error) { + // Check that we are not dealing with a closed Client before processing any other arguments + if client.Closed() { + return nil, ErrClosedClient + } + + om := &offsetManager{ + client: client, + conf: client.Config(), + group: group, + poms: make(map[string]map[int32]*partitionOffsetManager), + boms: make(map[*Broker]*brokerOffsetManager), + } + + return om, nil +} + +func (om *offsetManager) ManagePartition(topic string, partition int32) (PartitionOffsetManager, error) { + pom, err := om.newPartitionOffsetManager(topic, partition) + if err != nil { + return nil, err + } + + om.lock.Lock() + defer om.lock.Unlock() + + topicManagers := om.poms[topic] + if topicManagers == nil { + topicManagers = make(map[int32]*partitionOffsetManager) + om.poms[topic] = topicManagers + } + + if topicManagers[partition] != nil { + return nil, ConfigurationError("That topic/partition is already being managed") + } + + topicManagers[partition] = pom + return pom, nil +} + +func (om *offsetManager) Close() error { + return nil +} + +func (om *offsetManager) refBrokerOffsetManager(broker *Broker) *brokerOffsetManager { + om.lock.Lock() + defer om.lock.Unlock() + + bom := om.boms[broker] + if bom == nil { + bom = om.newBrokerOffsetManager(broker) + om.boms[broker] = bom + } + + bom.refs++ + + return bom +} + +func (om *offsetManager) unrefBrokerOffsetManager(bom *brokerOffsetManager) { + om.lock.Lock() + defer om.lock.Unlock() + + bom.refs-- + + if bom.refs == 0 { + close(bom.updateSubscriptions) + if om.boms[bom.broker] == bom { + delete(om.boms, bom.broker) + } + } +} + +func (om *offsetManager) abandonBroker(bom *brokerOffsetManager) { + om.lock.Lock() + defer om.lock.Unlock() + + delete(om.boms, bom.broker) +} + +func (om *offsetManager) abandonPartitionOffsetManager(pom *partitionOffsetManager) { + om.lock.Lock() + defer om.lock.Unlock() + + delete(om.poms[pom.topic], pom.partition) + if len(om.poms[pom.topic]) == 0 { + delete(om.poms, pom.topic) + } +} + +// Partition Offset Manager + +// PartitionOffsetManager uses Kafka to store and fetch consumed partition offsets. You MUST call Close() +// on a partition offset manager to avoid leaks, it will not be garbage-collected automatically when it passes +// out of scope. +type PartitionOffsetManager interface { + // NextOffset returns the next offset that should be consumed for the managed + // partition, accompanied by metadata which can be used to reconstruct the state + // of the partition consumer when it resumes. NextOffset() will return + // `config.Consumer.Offsets.Initial` and an empty metadata string if no offset + // was committed for this partition yet. + NextOffset() (int64, string) + + // MarkOffset marks the provided offset as processed, alongside a metadata string + // that represents the state of the partition consumer at that point in time. The + // metadata string can be used by another consumer to restore that state, so it + // can resume consumption. + // + // Note: calling MarkOffset does not necessarily commit the offset to the backend + // store immediately for efficiency reasons, and it may never be committed if + // your application crashes. This means that you may end up processing the same + // message twice, and your processing should ideally be idempotent. + MarkOffset(offset int64, metadata string) + + // Errors returns a read channel of errors that occur during offset management, if + // enabled. By default, errors are logged and not returned over this channel. If + // you want to implement any custom error handling, set your config's + // Consumer.Return.Errors setting to true, and read from this channel. + Errors() <-chan *ConsumerError + + // AsyncClose initiates a shutdown of the PartitionOffsetManager. This method will + // return immediately, after which you should wait until the 'errors' channel has + // been drained and closed. It is required to call this function, or Close before + // a consumer object passes out of scope, as it will otherwise leak memory. You + // must call this before calling Close on the underlying client. + AsyncClose() + + // Close stops the PartitionOffsetManager from managing offsets. It is required to + // call this function (or AsyncClose) before a PartitionOffsetManager object + // passes out of scope, as it will otherwise leak memory. You must call this + // before calling Close on the underlying client. + Close() error +} + +type partitionOffsetManager struct { + parent *offsetManager + topic string + partition int32 + + lock sync.Mutex + offset int64 + metadata string + dirty bool + clean chan none + broker *brokerOffsetManager + + errors chan *ConsumerError + rebalance chan none + dying chan none +} + +func (om *offsetManager) newPartitionOffsetManager(topic string, partition int32) (*partitionOffsetManager, error) { + pom := &partitionOffsetManager{ + parent: om, + topic: topic, + partition: partition, + clean: make(chan none), + errors: make(chan *ConsumerError, om.conf.ChannelBufferSize), + rebalance: make(chan none, 1), + dying: make(chan none), + } + + if err := pom.selectBroker(); err != nil { + return nil, err + } + + if err := pom.fetchInitialOffset(om.conf.Metadata.Retry.Max); err != nil { + return nil, err + } + + pom.broker.updateSubscriptions <- pom + + go withRecover(pom.mainLoop) + + return pom, nil +} + +func (pom *partitionOffsetManager) mainLoop() { + for { + select { + case <-pom.rebalance: + if err := pom.selectBroker(); err != nil { + pom.handleError(err) + pom.rebalance <- none{} + } else { + pom.broker.updateSubscriptions <- pom + } + case <-pom.dying: + if pom.broker != nil { + select { + case <-pom.rebalance: + case pom.broker.updateSubscriptions <- pom: + } + pom.parent.unrefBrokerOffsetManager(pom.broker) + } + pom.parent.abandonPartitionOffsetManager(pom) + close(pom.errors) + return + } + } +} + +func (pom *partitionOffsetManager) selectBroker() error { + if pom.broker != nil { + pom.parent.unrefBrokerOffsetManager(pom.broker) + pom.broker = nil + } + + var broker *Broker + var err error + + if err = pom.parent.client.RefreshCoordinator(pom.parent.group); err != nil { + return err + } + + if broker, err = pom.parent.client.Coordinator(pom.parent.group); err != nil { + return err + } + + pom.broker = pom.parent.refBrokerOffsetManager(broker) + return nil +} + +func (pom *partitionOffsetManager) fetchInitialOffset(retries int) error { + request := new(OffsetFetchRequest) + request.Version = 1 + request.ConsumerGroup = pom.parent.group + request.AddPartition(pom.topic, pom.partition) + + response, err := pom.broker.broker.FetchOffset(request) + if err != nil { + return err + } + + block := response.GetBlock(pom.topic, pom.partition) + if block == nil { + return ErrIncompleteResponse + } + + switch block.Err { + case ErrNoError: + pom.offset = block.Offset + pom.metadata = block.Metadata + return nil + case ErrNotCoordinatorForConsumer: + if retries <= 0 { + return block.Err + } + if err := pom.selectBroker(); err != nil { + return err + } + return pom.fetchInitialOffset(retries - 1) + case ErrOffsetsLoadInProgress: + if retries <= 0 { + return block.Err + } + time.Sleep(pom.parent.conf.Metadata.Retry.Backoff) + return pom.fetchInitialOffset(retries - 1) + default: + return block.Err + } +} + +func (pom *partitionOffsetManager) handleError(err error) { + cErr := &ConsumerError{ + Topic: pom.topic, + Partition: pom.partition, + Err: err, + } + + if pom.parent.conf.Consumer.Return.Errors { + pom.errors <- cErr + } else { + Logger.Println(cErr) + } +} + +func (pom *partitionOffsetManager) Errors() <-chan *ConsumerError { + return pom.errors +} + +func (pom *partitionOffsetManager) MarkOffset(offset int64, metadata string) { + pom.lock.Lock() + defer pom.lock.Unlock() + + if offset > pom.offset { + pom.offset = offset + pom.metadata = metadata + pom.dirty = true + } +} + +func (pom *partitionOffsetManager) updateCommitted(offset int64, metadata string) { + pom.lock.Lock() + defer pom.lock.Unlock() + + if pom.offset == offset && pom.metadata == metadata { + pom.dirty = false + + select { + case pom.clean <- none{}: + default: + } + } +} + +func (pom *partitionOffsetManager) NextOffset() (int64, string) { + pom.lock.Lock() + defer pom.lock.Unlock() + + if pom.offset >= 0 { + return pom.offset + 1, pom.metadata + } + + return pom.parent.conf.Consumer.Offsets.Initial, "" +} + +func (pom *partitionOffsetManager) AsyncClose() { + go func() { + pom.lock.Lock() + dirty := pom.dirty + pom.lock.Unlock() + + if dirty { + <-pom.clean + } + + close(pom.dying) + }() +} + +func (pom *partitionOffsetManager) Close() error { + pom.AsyncClose() + + var errors ConsumerErrors + for err := range pom.errors { + errors = append(errors, err) + } + + if len(errors) > 0 { + return errors + } + return nil +} + +// Broker Offset Manager + +type brokerOffsetManager struct { + parent *offsetManager + broker *Broker + timer *time.Ticker + updateSubscriptions chan *partitionOffsetManager + subscriptions map[*partitionOffsetManager]none + refs int +} + +func (om *offsetManager) newBrokerOffsetManager(broker *Broker) *brokerOffsetManager { + bom := &brokerOffsetManager{ + parent: om, + broker: broker, + timer: time.NewTicker(om.conf.Consumer.Offsets.CommitInterval), + updateSubscriptions: make(chan *partitionOffsetManager), + subscriptions: make(map[*partitionOffsetManager]none), + } + + go withRecover(bom.mainLoop) + + return bom +} + +func (bom *brokerOffsetManager) mainLoop() { + for { + select { + case <-bom.timer.C: + if len(bom.subscriptions) > 0 { + bom.flushToBroker() + } + case s, ok := <-bom.updateSubscriptions: + if !ok { + bom.timer.Stop() + return + } + if _, ok := bom.subscriptions[s]; ok { + delete(bom.subscriptions, s) + } else { + bom.subscriptions[s] = none{} + } + } + } +} + +func (bom *brokerOffsetManager) flushToBroker() { + request := bom.constructRequest() + if request == nil { + return + } + + response, err := bom.broker.CommitOffset(request) + + if err != nil { + bom.abort(err) + return + } + + for s := range bom.subscriptions { + if request.blocks[s.topic] == nil || request.blocks[s.topic][s.partition] == nil { + continue + } + + var err KError + var ok bool + + if response.Errors[s.topic] == nil { + s.handleError(ErrIncompleteResponse) + delete(bom.subscriptions, s) + s.rebalance <- none{} + continue + } + if err, ok = response.Errors[s.topic][s.partition]; !ok { + s.handleError(ErrIncompleteResponse) + delete(bom.subscriptions, s) + s.rebalance <- none{} + continue + } + + switch err { + case ErrNoError: + block := request.blocks[s.topic][s.partition] + s.updateCommitted(block.offset, block.metadata) + break + case ErrUnknownTopicOrPartition, ErrNotLeaderForPartition, ErrLeaderNotAvailable: + delete(bom.subscriptions, s) + s.rebalance <- none{} + default: + s.handleError(err) + delete(bom.subscriptions, s) + s.rebalance <- none{} + } + } +} + +func (bom *brokerOffsetManager) constructRequest() *OffsetCommitRequest { + var r *OffsetCommitRequest + if bom.parent.conf.Consumer.Offsets.Retention == 0 { + r = &OffsetCommitRequest{ + Version: 1, + ConsumerGroup: bom.parent.group, + ConsumerGroupGeneration: GroupGenerationUndefined, + } + } else { + r = &OffsetCommitRequest{ + Version: 2, + RetentionTime: int64(bom.parent.conf.Consumer.Offsets.Retention / time.Millisecond), + ConsumerGroup: bom.parent.group, + ConsumerGroupGeneration: GroupGenerationUndefined, + } + + } + + for s := range bom.subscriptions { + s.lock.Lock() + if s.dirty { + r.AddBlock(s.topic, s.partition, s.offset, ReceiveTime, s.metadata) + } + s.lock.Unlock() + } + + if len(r.blocks) > 0 { + return r + } + + return nil +} + +func (bom *brokerOffsetManager) abort(err error) { + _ = bom.broker.Close() // we don't care about the error this might return, we already have one + bom.parent.abandonBroker(bom) + + for pom := range bom.subscriptions { + pom.handleError(err) + pom.rebalance <- none{} + } + + for s := range bom.updateSubscriptions { + if _, ok := bom.subscriptions[s]; !ok { + s.handleError(err) + s.rebalance <- none{} + } + } + + bom.subscriptions = make(map[*partitionOffsetManager]none) +} diff --git a/vendor/github.com/Shopify/sarama/offset_request.go b/vendor/github.com/Shopify/sarama/offset_request.go new file mode 100644 index 0000000..842d5c0 --- /dev/null +++ b/vendor/github.com/Shopify/sarama/offset_request.go @@ -0,0 +1,113 @@ +package sarama + +type offsetRequestBlock struct { + time int64 + maxOffsets int32 +} + +func (r *offsetRequestBlock) encode(pe packetEncoder) error { + pe.putInt64(int64(r.time)) + pe.putInt32(r.maxOffsets) + return nil +} + +func (r *offsetRequestBlock) decode(pd packetDecoder) (err error) { + if r.time, err = pd.getInt64(); err != nil { + return err + } + if r.maxOffsets, err = pd.getInt32(); err != nil { + return err + } + return nil +} + +type OffsetRequest struct { + blocks map[string]map[int32]*offsetRequestBlock +} + +func (r *OffsetRequest) encode(pe packetEncoder) error { + pe.putInt32(-1) // replica ID is always -1 for clients + err := pe.putArrayLength(len(r.blocks)) + if err != nil { + return err + } + for topic, partitions := range r.blocks { + err = pe.putString(topic) + if err != nil { + return err + } + err = pe.putArrayLength(len(partitions)) + if err != nil { + return err + } + for partition, block := range partitions { + pe.putInt32(partition) + if err = block.encode(pe); err != nil { + return err + } + } + } + return nil +} + +func (r *OffsetRequest) decode(pd packetDecoder) error { + // Ignore replica ID + if _, err := pd.getInt32(); err != nil { + return err + } + blockCount, err := pd.getArrayLength() + if err != nil { + return err + } + if blockCount == 0 { + return nil + } + r.blocks = make(map[string]map[int32]*offsetRequestBlock) + for i := 0; i < blockCount; i++ { + topic, err := pd.getString() + if err != nil { + return err + } + partitionCount, err := pd.getArrayLength() + if err != nil { + return err + } + r.blocks[topic] = make(map[int32]*offsetRequestBlock) + for j := 0; j < partitionCount; j++ { + partition, err := pd.getInt32() + if err != nil { + return err + } + block := &offsetRequestBlock{} + if err := block.decode(pd); err != nil { + return err + } + r.blocks[topic][partition] = block + } + } + return nil +} + +func (r *OffsetRequest) key() int16 { + return 2 +} + +func (r *OffsetRequest) version() int16 { + return 0 +} + +func (r *OffsetRequest) AddBlock(topic string, partitionID int32, time int64, maxOffsets int32) { + if r.blocks == nil { + r.blocks = make(map[string]map[int32]*offsetRequestBlock) + } + + if r.blocks[topic] == nil { + r.blocks[topic] = make(map[int32]*offsetRequestBlock) + } + + tmp := new(offsetRequestBlock) + tmp.time = time + tmp.maxOffsets = maxOffsets + + r.blocks[topic][partitionID] = tmp +} diff --git a/vendor/github.com/Shopify/sarama/offset_response.go b/vendor/github.com/Shopify/sarama/offset_response.go new file mode 100644 index 0000000..07d71ca --- /dev/null +++ b/vendor/github.com/Shopify/sarama/offset_response.go @@ -0,0 +1,130 @@ +package sarama + +type OffsetResponseBlock struct { + Err KError + Offsets []int64 +} + +func (r *OffsetResponseBlock) decode(pd packetDecoder) (err error) { + tmp, err := pd.getInt16() + if err != nil { + return err + } + r.Err = KError(tmp) + + r.Offsets, err = pd.getInt64Array() + + return err +} + +func (r *OffsetResponseBlock) encode(pe packetEncoder) (err error) { + pe.putInt16(int16(r.Err)) + + return pe.putInt64Array(r.Offsets) +} + +type OffsetResponse struct { + Blocks map[string]map[int32]*OffsetResponseBlock +} + +func (r *OffsetResponse) decode(pd packetDecoder) (err error) { + numTopics, err := pd.getArrayLength() + if err != nil { + return err + } + + r.Blocks = make(map[string]map[int32]*OffsetResponseBlock, numTopics) + for i := 0; i < numTopics; i++ { + name, err := pd.getString() + if err != nil { + return err + } + + numBlocks, err := pd.getArrayLength() + if err != nil { + return err + } + + r.Blocks[name] = make(map[int32]*OffsetResponseBlock, numBlocks) + + for j := 0; j < numBlocks; j++ { + id, err := pd.getInt32() + if err != nil { + return err + } + + block := new(OffsetResponseBlock) + err = block.decode(pd) + if err != nil { + return err + } + r.Blocks[name][id] = block + } + } + + return nil +} + +func (r *OffsetResponse) GetBlock(topic string, partition int32) *OffsetResponseBlock { + if r.Blocks == nil { + return nil + } + + if r.Blocks[topic] == nil { + return nil + } + + return r.Blocks[topic][partition] +} + +/* +// [0 0 0 1 ntopics +0 8 109 121 95 116 111 112 105 99 topic +0 0 0 1 npartitions +0 0 0 0 id +0 0 + +0 0 0 1 0 0 0 0 +0 1 1 1 0 0 0 1 +0 8 109 121 95 116 111 112 +105 99 0 0 0 1 0 0 +0 0 0 0 0 0 0 1 +0 0 0 0 0 1 1 1] + +*/ +func (r *OffsetResponse) encode(pe packetEncoder) (err error) { + if err = pe.putArrayLength(len(r.Blocks)); err != nil { + return err + } + + for topic, partitions := range r.Blocks { + if err = pe.putString(topic); err != nil { + return err + } + if err = pe.putArrayLength(len(partitions)); err != nil { + return err + } + for partition, block := range partitions { + pe.putInt32(partition) + if err = block.encode(pe); err != nil { + return err + } + } + } + + return nil +} + +// testing API + +func (r *OffsetResponse) AddTopicPartition(topic string, partition int32, offset int64) { + if r.Blocks == nil { + r.Blocks = make(map[string]map[int32]*OffsetResponseBlock) + } + byTopic, ok := r.Blocks[topic] + if !ok { + byTopic = make(map[int32]*OffsetResponseBlock) + r.Blocks[topic] = byTopic + } + byTopic[partition] = &OffsetResponseBlock{Offsets: []int64{offset}} +} diff --git a/vendor/github.com/Shopify/sarama/packet_decoder.go b/vendor/github.com/Shopify/sarama/packet_decoder.go new file mode 100644 index 0000000..28670c0 --- /dev/null +++ b/vendor/github.com/Shopify/sarama/packet_decoder.go @@ -0,0 +1,45 @@ +package sarama + +// PacketDecoder is the interface providing helpers for reading with Kafka's encoding rules. +// Types implementing Decoder only need to worry about calling methods like GetString, +// not about how a string is represented in Kafka. +type packetDecoder interface { + // Primitives + getInt8() (int8, error) + getInt16() (int16, error) + getInt32() (int32, error) + getInt64() (int64, error) + getArrayLength() (int, error) + + // Collections + getBytes() ([]byte, error) + getString() (string, error) + getInt32Array() ([]int32, error) + getInt64Array() ([]int64, error) + getStringArray() ([]string, error) + + // Subsets + remaining() int + getSubset(length int) (packetDecoder, error) + + // Stacks, see PushDecoder + push(in pushDecoder) error + pop() error +} + +// PushDecoder is the interface for decoding fields like CRCs and lengths where the validity +// of the field depends on what is after it in the packet. Start them with PacketDecoder.Push() where +// the actual value is located in the packet, then PacketDecoder.Pop() them when all the bytes they +// depend upon have been decoded. +type pushDecoder interface { + // Saves the offset into the input buffer as the location to actually read the calculated value when able. + saveOffset(in int) + + // Returns the length of data to reserve for the input of this encoder (eg 4 bytes for a CRC32). + reserveLength() int + + // Indicates that all required data is now available to calculate and check the field. + // SaveOffset is guaranteed to have been called first. The implementation should read ReserveLength() bytes + // of data from the saved offset, and verify it based on the data between the saved offset and curOffset. + check(curOffset int, buf []byte) error +} diff --git a/vendor/github.com/Shopify/sarama/packet_encoder.go b/vendor/github.com/Shopify/sarama/packet_encoder.go new file mode 100644 index 0000000..0df6e24 --- /dev/null +++ b/vendor/github.com/Shopify/sarama/packet_encoder.go @@ -0,0 +1,42 @@ +package sarama + +// PacketEncoder is the interface providing helpers for writing with Kafka's encoding rules. +// Types implementing Encoder only need to worry about calling methods like PutString, +// not about how a string is represented in Kafka. +type packetEncoder interface { + // Primitives + putInt8(in int8) + putInt16(in int16) + putInt32(in int32) + putInt64(in int64) + putArrayLength(in int) error + + // Collections + putBytes(in []byte) error + putRawBytes(in []byte) error + putString(in string) error + putStringArray(in []string) error + putInt32Array(in []int32) error + putInt64Array(in []int64) error + + // Stacks, see PushEncoder + push(in pushEncoder) + pop() error +} + +// PushEncoder is the interface for encoding fields like CRCs and lengths where the value +// of the field depends on what is encoded after it in the packet. Start them with PacketEncoder.Push() where +// the actual value is located in the packet, then PacketEncoder.Pop() them when all the bytes they +// depend upon have been written. +type pushEncoder interface { + // Saves the offset into the input buffer as the location to actually write the calculated value when able. + saveOffset(in int) + + // Returns the length of data to reserve for the output of this encoder (eg 4 bytes for a CRC32). + reserveLength() int + + // Indicates that all required data is now available to calculate and write the field. + // SaveOffset is guaranteed to have been called first. The implementation should write ReserveLength() bytes + // of data to the saved offset, based on the data between the saved offset and curOffset. + run(curOffset int, buf []byte) error +} diff --git a/vendor/github.com/Shopify/sarama/partitioner.go b/vendor/github.com/Shopify/sarama/partitioner.go new file mode 100644 index 0000000..8c2bca4 --- /dev/null +++ b/vendor/github.com/Shopify/sarama/partitioner.go @@ -0,0 +1,123 @@ +package sarama + +import ( + "hash" + "hash/fnv" + "math/rand" + "time" +) + +// Partitioner is anything that, given a Kafka message and a number of partitions indexed [0...numPartitions-1], +// decides to which partition to send the message. RandomPartitioner, RoundRobinPartitioner and HashPartitioner are provided +// as simple default implementations. +type Partitioner interface { + // Partition takes a message and partition count and chooses a partition + Partition(message *ProducerMessage, numPartitions int32) (int32, error) + + // RequiresConsistency indicates to the user of the partitioner whether the + // mapping of key->partition is consistent or not. Specifically, if a + // partitioner requires consistency then it must be allowed to choose from all + // partitions (even ones known to be unavailable), and its choice must be + // respected by the caller. The obvious example is the HashPartitioner. + RequiresConsistency() bool +} + +// PartitionerConstructor is the type for a function capable of constructing new Partitioners. +type PartitionerConstructor func(topic string) Partitioner + +type manualPartitioner struct{} + +// NewManualPartitioner returns a Partitioner which uses the partition manually set in the provided +// ProducerMessage's Partition field as the partition to produce to. +func NewManualPartitioner(topic string) Partitioner { + return new(manualPartitioner) +} + +func (p *manualPartitioner) Partition(message *ProducerMessage, numPartitions int32) (int32, error) { + return message.Partition, nil +} + +func (p *manualPartitioner) RequiresConsistency() bool { + return true +} + +type randomPartitioner struct { + generator *rand.Rand +} + +// NewRandomPartitioner returns a Partitioner which chooses a random partition each time. +func NewRandomPartitioner(topic string) Partitioner { + p := new(randomPartitioner) + p.generator = rand.New(rand.NewSource(time.Now().UTC().UnixNano())) + return p +} + +func (p *randomPartitioner) Partition(message *ProducerMessage, numPartitions int32) (int32, error) { + return int32(p.generator.Intn(int(numPartitions))), nil +} + +func (p *randomPartitioner) RequiresConsistency() bool { + return false +} + +type roundRobinPartitioner struct { + partition int32 +} + +// NewRoundRobinPartitioner returns a Partitioner which walks through the available partitions one at a time. +func NewRoundRobinPartitioner(topic string) Partitioner { + return &roundRobinPartitioner{} +} + +func (p *roundRobinPartitioner) Partition(message *ProducerMessage, numPartitions int32) (int32, error) { + if p.partition >= numPartitions { + p.partition = 0 + } + ret := p.partition + p.partition++ + return ret, nil +} + +func (p *roundRobinPartitioner) RequiresConsistency() bool { + return false +} + +type hashPartitioner struct { + random Partitioner + hasher hash.Hash32 +} + +// NewHashPartitioner returns a Partitioner which behaves as follows. If the message's key is nil, or fails to +// encode, then a random partition is chosen. Otherwise the FNV-1a hash of the encoded bytes of the message key +// is used, modulus the number of partitions. This ensures that messages with the same key always end up on the +// same partition. +func NewHashPartitioner(topic string) Partitioner { + p := new(hashPartitioner) + p.random = NewRandomPartitioner(topic) + p.hasher = fnv.New32a() + return p +} + +func (p *hashPartitioner) Partition(message *ProducerMessage, numPartitions int32) (int32, error) { + if message.Key == nil { + return p.random.Partition(message, numPartitions) + } + bytes, err := message.Key.Encode() + if err != nil { + return -1, err + } + p.hasher.Reset() + _, err = p.hasher.Write(bytes) + if err != nil { + return -1, err + } + hash := int32(p.hasher.Sum32()) + if hash < 0 { + hash = -hash + } + return hash % numPartitions, nil +} + +func (p *hashPartitioner) RequiresConsistency() bool { + return true +} diff --git a/vendor/github.com/Shopify/sarama/prep_encoder.go b/vendor/github.com/Shopify/sarama/prep_encoder.go new file mode 100644 index 0000000..8c6ba85 --- /dev/null +++ b/vendor/github.com/Shopify/sarama/prep_encoder.go @@ -0,0 +1,110 @@ +package sarama + +import ( + "fmt" + "math" +) + +type prepEncoder struct { + length int +} + +// primitives + +func (pe *prepEncoder) putInt8(in int8) { + pe.length++ +} + +func (pe *prepEncoder) putInt16(in int16) { + pe.length += 2 +} + +func (pe *prepEncoder) putInt32(in int32) { + pe.length += 4 +} + +func (pe *prepEncoder) putInt64(in int64) { + pe.length += 8 +} + +func (pe *prepEncoder) putArrayLength(in int) error { + if in > math.MaxInt32 { + return PacketEncodingError{fmt.Sprintf("array too long (%d)", in)} + } + pe.length += 4 + return nil +} + +// arrays + +func (pe *prepEncoder) putBytes(in []byte) error { + pe.length += 4 + if in == nil { + return nil + } + if len(in) > math.MaxInt32 { + return PacketEncodingError{fmt.Sprintf("byteslice too long (%d)", len(in))} + } + pe.length += len(in) + return nil +} + +func (pe *prepEncoder) putRawBytes(in []byte) error { + if len(in) > math.MaxInt32 { + return PacketEncodingError{fmt.Sprintf("byteslice too long (%d)", len(in))} + } + pe.length += len(in) + return nil +} + +func (pe *prepEncoder) putString(in string) error { + pe.length += 2 + if len(in) > math.MaxInt16 { + return PacketEncodingError{fmt.Sprintf("string too long (%d)", len(in))} + } + pe.length += len(in) + return nil +} + +func (pe *prepEncoder) putStringArray(in []string) error { + err := pe.putArrayLength(len(in)) + if err != nil { + return err + } + + for _, str := range in { + if err := pe.putString(str); err != nil { + return err + } + } + + return nil +} + +func (pe *prepEncoder) putInt32Array(in []int32) error { + err := pe.putArrayLength(len(in)) + if err != nil { + return err + } + pe.length += 4 * len(in) + return nil +} + +func (pe *prepEncoder) putInt64Array(in []int64) error { + err := pe.putArrayLength(len(in)) + if err != nil { + return err + } + pe.length += 8 * len(in) + return nil +} + +// stackable + +func (pe *prepEncoder) push(in pushEncoder) { + pe.length += in.reserveLength() +} + +func (pe *prepEncoder) pop() error { + return nil +} diff --git a/vendor/github.com/Shopify/sarama/produce_request.go b/vendor/github.com/Shopify/sarama/produce_request.go new file mode 100644 index 0000000..473513c --- /dev/null +++ b/vendor/github.com/Shopify/sarama/produce_request.go @@ -0,0 +1,145 @@ +package sarama + +// RequiredAcks is used in Produce Requests to tell the broker how many replica acknowledgements +// it must see before responding. Any of the constants defined here are valid. On broker versions +// prior to 0.8.2.0 any other positive int16 is also valid (the broker will wait for that many +// acknowledgements) but in 0.8.2.0 and later this will raise an exception (it has been replaced +// by setting the `min.isr` value in the brokers configuration). +type RequiredAcks int16 + +const ( + // NoResponse doesn't send any response, the TCP ACK is all you get. + NoResponse RequiredAcks = 0 + // WaitForLocal waits for only the local commit to succeed before responding. + WaitForLocal RequiredAcks = 1 + // WaitForAll waits for all replicas to commit before responding. + WaitForAll RequiredAcks = -1 +) + +type ProduceRequest struct { + RequiredAcks RequiredAcks + Timeout int32 + msgSets map[string]map[int32]*MessageSet +} + +func (p *ProduceRequest) encode(pe packetEncoder) error { + pe.putInt16(int16(p.RequiredAcks)) + pe.putInt32(p.Timeout) + err := pe.putArrayLength(len(p.msgSets)) + if err != nil { + return err + } + for topic, partitions := range p.msgSets { + err = pe.putString(topic) + if err != nil { + return err + } + err = pe.putArrayLength(len(partitions)) + if err != nil { + return err + } + for id, msgSet := range partitions { + pe.putInt32(id) + pe.push(&lengthField{}) + err = msgSet.encode(pe) + if err != nil { + return err + } + err = pe.pop() + if err != nil { + return err + } + } + } + return nil +} + +func (p *ProduceRequest) decode(pd packetDecoder) error { + requiredAcks, err := pd.getInt16() + if err != nil { + return err + } + p.RequiredAcks = RequiredAcks(requiredAcks) + if p.Timeout, err = pd.getInt32(); err != nil { + return err + } + topicCount, err := pd.getArrayLength() + if err != nil { + return err + } + if topicCount == 0 { + return nil + } + p.msgSets = make(map[string]map[int32]*MessageSet) + for i := 0; i < topicCount; i++ { + topic, err := pd.getString() + if err != nil { + return err + } + partitionCount, err := pd.getArrayLength() + if err != nil { + return err + } + p.msgSets[topic] = make(map[int32]*MessageSet) + for j := 0; j < partitionCount; j++ { + partition, err := pd.getInt32() + if err != nil { + return err + } + messageSetSize, err := pd.getInt32() + if err != nil { + return err + } + msgSetDecoder, err := pd.getSubset(int(messageSetSize)) + if err != nil { + return err + } + msgSet := &MessageSet{} + err = msgSet.decode(msgSetDecoder) + if err != nil { + return err + } + p.msgSets[topic][partition] = msgSet + } + } + return nil +} + +func (p *ProduceRequest) key() int16 { + return 0 +} + +func (p *ProduceRequest) version() int16 { + return 0 +} + +func (p *ProduceRequest) AddMessage(topic string, partition int32, msg *Message) { + if p.msgSets == nil { + p.msgSets = make(map[string]map[int32]*MessageSet) + } + + if p.msgSets[topic] == nil { + p.msgSets[topic] = make(map[int32]*MessageSet) + } + + set := p.msgSets[topic][partition] + + if set == nil { + set = new(MessageSet) + p.msgSets[topic][partition] = set + } + + set.addMessage(msg) +} + +func (p *ProduceRequest) AddSet(topic string, partition int32, set *MessageSet) { + if p.msgSets == nil { + p.msgSets = make(map[string]map[int32]*MessageSet) + } + + if p.msgSets[topic] == nil { + p.msgSets[topic] = make(map[int32]*MessageSet) + } + + p.msgSets[topic][partition] = set +} diff --git a/vendor/github.com/Shopify/sarama/produce_response.go b/vendor/github.com/Shopify/sarama/produce_response.go new file mode 100644 index 0000000..1f49a85 --- /dev/null +++ b/vendor/github.com/Shopify/sarama/produce_response.go @@ -0,0 +1,112 @@ +package sarama + +type ProduceResponseBlock struct { + Err KError + Offset int64 +} + +func (pr *ProduceResponseBlock) decode(pd packetDecoder) (err error) { + tmp, err := pd.getInt16() + if err != nil { + return err + } + pr.Err = KError(tmp) + + pr.Offset, err = pd.getInt64() + if err != nil { + return err + } + + return nil +} + +type ProduceResponse struct { + Blocks map[string]map[int32]*ProduceResponseBlock +} + +func (pr *ProduceResponse) decode(pd packetDecoder) (err error) { + numTopics, err := pd.getArrayLength() + if err != nil { + return err + } + + pr.Blocks = make(map[string]map[int32]*ProduceResponseBlock, numTopics) + for i := 0; i < numTopics; i++ { + name, err := pd.getString() + if err != nil { + return err + } + + numBlocks, err := pd.getArrayLength() + if err != nil { + return err + } + + pr.Blocks[name] = make(map[int32]*ProduceResponseBlock, numBlocks) + + for j := 0; j < numBlocks; j++ { + id, err := pd.getInt32() + if err != nil { + return err + } + + block := new(ProduceResponseBlock) + err = block.decode(pd) + if err != nil { + return err + } + pr.Blocks[name][id] = block + } + } + + return nil +} + +func (pr *ProduceResponse) encode(pe packetEncoder) error { + err := pe.putArrayLength(len(pr.Blocks)) + if err != nil { + return err + } + for topic, partitions := range pr.Blocks { + err = pe.putString(topic) + if err != nil { + return err + } + err = pe.putArrayLength(len(partitions)) + if err != nil { + return err + } + for id, prb := range partitions { + pe.putInt32(id) + pe.putInt16(int16(prb.Err)) + pe.putInt64(prb.Offset) + } + } + return nil +} + +func (pr *ProduceResponse) GetBlock(topic string, partition int32) *ProduceResponseBlock { + if pr.Blocks == nil { + return nil + } + + if pr.Blocks[topic] == nil { + return nil + } + + return pr.Blocks[topic][partition] +} + +// Testing API + +func (pr *ProduceResponse) AddTopicPartition(topic string, partition int32, err KError) { + if pr.Blocks == nil { + pr.Blocks = make(map[string]map[int32]*ProduceResponseBlock) + } + byTopic, ok := pr.Blocks[topic] + if !ok { + byTopic = make(map[int32]*ProduceResponseBlock) + pr.Blocks[topic] = byTopic + } + byTopic[partition] = &ProduceResponseBlock{Err: err} +} diff --git a/vendor/github.com/Shopify/sarama/produce_set.go b/vendor/github.com/Shopify/sarama/produce_set.go new file mode 100644 index 0000000..9fe5f79 --- /dev/null +++ b/vendor/github.com/Shopify/sarama/produce_set.go @@ -0,0 +1,158 @@ +package sarama + +import "time" + +type partitionSet struct { + msgs []*ProducerMessage + setToSend *MessageSet + bufferBytes int +} + +type produceSet struct { + parent *asyncProducer + msgs map[string]map[int32]*partitionSet + + bufferBytes int + bufferCount int +} + +func newProduceSet(parent *asyncProducer) *produceSet { + return &produceSet{ + msgs: make(map[string]map[int32]*partitionSet), + parent: parent, + } +} + +func (ps *produceSet) add(msg *ProducerMessage) error { + var err error + var key, val []byte + + if msg.Key != nil { + if key, err = msg.Key.Encode(); err != nil { + return err + } + } + + if msg.Value != nil { + if val, err = msg.Value.Encode(); err != nil { + return err + } + } + + partitions := ps.msgs[msg.Topic] + if partitions == nil { + partitions = make(map[int32]*partitionSet) + ps.msgs[msg.Topic] = partitions + } + + set := partitions[msg.Partition] + if set == nil { + set = &partitionSet{setToSend: new(MessageSet)} + partitions[msg.Partition] = set + } + + set.msgs = append(set.msgs, msg) + set.setToSend.addMessage(&Message{Codec: CompressionNone, Key: key, Value: val}) + + size := producerMessageOverhead + len(key) + len(val) + set.bufferBytes += size + ps.bufferBytes += size + ps.bufferCount++ + + return nil +} + +func (ps *produceSet) buildRequest() *ProduceRequest { + req := &ProduceRequest{ + RequiredAcks: ps.parent.conf.Producer.RequiredAcks, + Timeout: int32(ps.parent.conf.Producer.Timeout / time.Millisecond), + } + + for topic, partitionSet := range ps.msgs { + for partition, set := range partitionSet { + if ps.parent.conf.Producer.Compression == CompressionNone { + req.AddSet(topic, partition, set.setToSend) + } else { + // When compression is enabled, the entire set for each partition is compressed + // and sent as the payload of a single fake "message" with the appropriate codec + // set and no key. When the server sees a message with a compression codec, it + // decompresses the payload and treats the result as its message set. + payload, err := encode(set.setToSend) + if err != nil { + Logger.Println(err) // if this happens, it's basically our fault. + panic(err) + } + req.AddMessage(topic, partition, &Message{ + Codec: ps.parent.conf.Producer.Compression, + Key: nil, + Value: payload, + }) + } + } + } + + return req +} + +func (ps *produceSet) eachPartition(cb func(topic string, partition int32, msgs []*ProducerMessage)) { + for topic, partitionSet := range ps.msgs { + for partition, set := range partitionSet { + cb(topic, partition, set.msgs) + } + } +} + +func (ps *produceSet) dropPartition(topic string, partition int32) []*ProducerMessage { + if ps.msgs[topic] == nil { + return nil + } + set := ps.msgs[topic][partition] + if set == nil { + return nil + } + ps.bufferBytes -= set.bufferBytes + ps.bufferCount -= len(set.msgs) + delete(ps.msgs[topic], partition) + return set.msgs +} + +func (ps *produceSet) wouldOverflow(msg *ProducerMessage) bool { + switch { + // Would we overflow our maximum possible size-on-the-wire? 10KiB is arbitrary overhead for safety. + case ps.bufferBytes+msg.byteSize() >= int(MaxRequestSize-(10*1024)): + return true + // Would we overflow the size-limit of a compressed message-batch for this partition? + case ps.parent.conf.Producer.Compression != CompressionNone && + ps.msgs[msg.Topic] != nil && ps.msgs[msg.Topic][msg.Partition] != nil && + ps.msgs[msg.Topic][msg.Partition].bufferBytes+msg.byteSize() >= ps.parent.conf.Producer.MaxMessageBytes: + return true + // Would we overflow simply in number of messages? + case ps.parent.conf.Producer.Flush.MaxMessages > 0 && ps.bufferCount >= ps.parent.conf.Producer.Flush.MaxMessages: + return true + default: + return false + } +} + +func (ps *produceSet) readyToFlush() bool { + switch { + // If we don't have any messages, nothing else matters + case ps.empty(): + return false + // If all three config values are 0, we always flush as-fast-as-possible + case ps.parent.conf.Producer.Flush.Frequency == 0 && ps.parent.conf.Producer.Flush.Bytes == 0 && ps.parent.conf.Producer.Flush.Messages == 0: + return true + // If we've passed the message trigger-point + case ps.parent.conf.Producer.Flush.Messages > 0 && ps.bufferCount >= ps.parent.conf.Producer.Flush.Messages: + return true + // If we've passed the byte trigger-point + case ps.parent.conf.Producer.Flush.Bytes > 0 && ps.bufferBytes >= ps.parent.conf.Producer.Flush.Bytes: + return true + default: + return false + } +} + +func (ps *produceSet) empty() bool { + return ps.bufferCount == 0 +} diff --git a/vendor/github.com/Shopify/sarama/real_decoder.go b/vendor/github.com/Shopify/sarama/real_decoder.go new file mode 100644 index 0000000..e3ea331 --- /dev/null +++ b/vendor/github.com/Shopify/sarama/real_decoder.go @@ -0,0 +1,254 @@ +package sarama + +import ( + "encoding/binary" + "math" +) + +type realDecoder struct { + raw []byte + off int + stack []pushDecoder +} + +// primitives + +func (rd *realDecoder) getInt8() (int8, error) { + if rd.remaining() < 1 { + rd.off = len(rd.raw) + return -1, ErrInsufficientData + } + tmp := int8(rd.raw[rd.off]) + rd.off++ + return tmp, nil +} + +func (rd *realDecoder) getInt16() (int16, error) { + if rd.remaining() < 2 { + rd.off = len(rd.raw) + return -1, ErrInsufficientData + } + tmp := int16(binary.BigEndian.Uint16(rd.raw[rd.off:])) + rd.off += 2 + return tmp, nil +} + +func (rd *realDecoder) getInt32() (int32, error) { + if rd.remaining() < 4 { + rd.off = len(rd.raw) + return -1, ErrInsufficientData + } + tmp := int32(binary.BigEndian.Uint32(rd.raw[rd.off:])) + rd.off += 4 + return tmp, nil +} + +func (rd *realDecoder) getInt64() (int64, error) { + if rd.remaining() < 8 { + rd.off = len(rd.raw) + return -1, ErrInsufficientData + } + tmp := int64(binary.BigEndian.Uint64(rd.raw[rd.off:])) + rd.off += 8 + return tmp, nil +} + +func (rd *realDecoder) getArrayLength() (int, error) { + if rd.remaining() < 4 { + rd.off = len(rd.raw) + return -1, ErrInsufficientData + } + tmp := int(binary.BigEndian.Uint32(rd.raw[rd.off:])) + rd.off += 4 + if tmp > rd.remaining() { + rd.off = len(rd.raw) + return -1, ErrInsufficientData + } else if tmp > 2*math.MaxUint16 { + return -1, PacketDecodingError{"invalid array length"} + } + return tmp, nil +} + +// collections + +func (rd *realDecoder) getBytes() ([]byte, error) { + tmp, err := rd.getInt32() + + if err != nil { + return nil, err + } + + n := int(tmp) + + switch { + case n < -1: + return nil, PacketDecodingError{"invalid byteslice length"} + case n == -1: + return nil, nil + case n == 0: + return make([]byte, 0), nil + case n > rd.remaining(): + rd.off = len(rd.raw) + return nil, ErrInsufficientData + } + + tmpStr := rd.raw[rd.off : rd.off+n] + rd.off += n + return tmpStr, nil +} + +func (rd *realDecoder) getString() (string, error) { + tmp, err := rd.getInt16() + + if err != nil { + return "", err + } + + n := int(tmp) + + switch { + case n < -1: + return "", PacketDecodingError{"invalid string length"} + case n == -1: + return "", nil + case n == 0: + return "", nil + case n > rd.remaining(): + rd.off = len(rd.raw) + return "", ErrInsufficientData + } + + tmpStr := string(rd.raw[rd.off : rd.off+n]) + rd.off += n + return tmpStr, nil +} + +func (rd *realDecoder) getInt32Array() ([]int32, error) { + if rd.remaining() < 4 { + rd.off = len(rd.raw) + return nil, ErrInsufficientData + } + n := int(binary.BigEndian.Uint32(rd.raw[rd.off:])) + rd.off += 4 + + if rd.remaining() < 4*n { + rd.off = len(rd.raw) + return nil, ErrInsufficientData + } + + if n == 0 { + return nil, nil + } + + if n < 0 { + return nil, PacketDecodingError{"invalid array length"} + } + + ret := make([]int32, n) + for i := range ret { + ret[i] = int32(binary.BigEndian.Uint32(rd.raw[rd.off:])) + rd.off += 4 + } + return ret, nil +} + +func (rd *realDecoder) getInt64Array() ([]int64, error) { + if rd.remaining() < 4 { + rd.off = len(rd.raw) + return nil, ErrInsufficientData + } + n := int(binary.BigEndian.Uint32(rd.raw[rd.off:])) + rd.off += 4 + + if rd.remaining() < 8*n { + rd.off = len(rd.raw) + return nil, ErrInsufficientData + } + + if n == 0 { + return nil, nil + } + + if n < 0 { + return nil, PacketDecodingError{"invalid array length"} + } + + ret := make([]int64, n) + for i := range ret { + ret[i] = int64(binary.BigEndian.Uint64(rd.raw[rd.off:])) + rd.off += 8 + } + return ret, nil +} + +func (rd *realDecoder) getStringArray() ([]string, error) { + if rd.remaining() < 4 { + rd.off = len(rd.raw) + return nil, ErrInsufficientData + } + n := int(binary.BigEndian.Uint32(rd.raw[rd.off:])) + rd.off += 4 + + if n == 0 { + return nil, nil + } + + if n < 0 { + return nil, PacketDecodingError{"invalid array length"} + } + + ret := make([]string, n) + for i := range ret { + if str, err := rd.getString(); err != nil { + return nil, err + } else { + ret[i] = str + } + } + return ret, nil +} + +// subsets + +func (rd *realDecoder) remaining() int { + return len(rd.raw) - rd.off +} + +func (rd *realDecoder) getSubset(length int) (packetDecoder, error) { + if length < 0 { + return nil, PacketDecodingError{"invalid subset size"} + } else if length > rd.remaining() { + rd.off = len(rd.raw) + return nil, ErrInsufficientData + } + + start := rd.off + rd.off += length + return &realDecoder{raw: rd.raw[start:rd.off]}, nil +} + +// stacks + +func (rd *realDecoder) push(in pushDecoder) error { + in.saveOffset(rd.off) + + reserve := in.reserveLength() + if rd.remaining() < reserve { + rd.off = len(rd.raw) + return ErrInsufficientData + } + + rd.stack = append(rd.stack, in) + + rd.off += reserve + + return nil +} + +func (rd *realDecoder) pop() error { + // this is go's ugly pop pattern (the inverse of append) + in := rd.stack[len(rd.stack)-1] + rd.stack = rd.stack[:len(rd.stack)-1] + + return in.check(rd.off, rd.raw) +} diff --git a/vendor/github.com/Shopify/sarama/real_encoder.go b/vendor/github.com/Shopify/sarama/real_encoder.go new file mode 100644 index 0000000..076fdd0 --- /dev/null +++ b/vendor/github.com/Shopify/sarama/real_encoder.go @@ -0,0 +1,115 @@ +package sarama + +import "encoding/binary" + +type realEncoder struct { + raw []byte + off int + stack []pushEncoder +} + +// primitives + +func (re *realEncoder) putInt8(in int8) { + re.raw[re.off] = byte(in) + re.off++ +} + +func (re *realEncoder) putInt16(in int16) { + binary.BigEndian.PutUint16(re.raw[re.off:], uint16(in)) + re.off += 2 +} + +func (re *realEncoder) putInt32(in int32) { + binary.BigEndian.PutUint32(re.raw[re.off:], uint32(in)) + re.off += 4 +} + +func (re *realEncoder) putInt64(in int64) { + binary.BigEndian.PutUint64(re.raw[re.off:], uint64(in)) + re.off += 8 +} + +func (re *realEncoder) putArrayLength(in int) error { + re.putInt32(int32(in)) + return nil +} + +// collection + +func (re *realEncoder) putRawBytes(in []byte) error { + copy(re.raw[re.off:], in) + re.off += len(in) + return nil +} + +func (re *realEncoder) putBytes(in []byte) error { + if in == nil { + re.putInt32(-1) + return nil + } + re.putInt32(int32(len(in))) + copy(re.raw[re.off:], in) + re.off += len(in) + return nil +} + +func (re *realEncoder) putString(in string) error { + re.putInt16(int16(len(in))) + copy(re.raw[re.off:], in) + re.off += len(in) + return nil +} + +func (re *realEncoder) putStringArray(in []string) error { + err := re.putArrayLength(len(in)) + if err != nil { + return err + } + + for _, val := range in { + if err := re.putString(val); err != nil { + return err + } + } + + return nil +} + +func (re *realEncoder) putInt32Array(in []int32) error { + err := re.putArrayLength(len(in)) + if err != nil { + return err + } + for _, val := range in { + re.putInt32(val) + } + return nil +} + +func (re *realEncoder) putInt64Array(in []int64) error { + err := re.putArrayLength(len(in)) + if err != nil { + return err + } + for _, val := range in { + re.putInt64(val) + } + return nil +} + +// stacks + +func (re *realEncoder) push(in pushEncoder) { + in.saveOffset(re.off) + re.off += in.reserveLength() + re.stack = append(re.stack, in) +} + +func (re *realEncoder) pop() error { + // this is go's ugly pop pattern (the inverse of append) + in := re.stack[len(re.stack)-1] + re.stack = re.stack[:len(re.stack)-1] + + return in.run(re.off, re.raw) +} diff --git a/vendor/github.com/Shopify/sarama/request.go b/vendor/github.com/Shopify/sarama/request.go new file mode 100644 index 0000000..b9f654b --- /dev/null +++ b/vendor/github.com/Shopify/sarama/request.go @@ -0,0 +1,112 @@ +package sarama + +import ( + "encoding/binary" + "fmt" + "io" +) + +type requestBody interface { + encoder + decoder + key() int16 + version() int16 +} + +type request struct { + correlationID int32 + clientID string + body requestBody +} + +func (r *request) encode(pe packetEncoder) (err error) { + pe.push(&lengthField{}) + pe.putInt16(r.body.key()) + pe.putInt16(r.body.version()) + pe.putInt32(r.correlationID) + err = pe.putString(r.clientID) + if err != nil { + return err + } + err = r.body.encode(pe) + if err != nil { + return err + } + return pe.pop() +} + +func (r *request) decode(pd packetDecoder) (err error) { + var key int16 + if key, err = pd.getInt16(); err != nil { + return err + } + var version int16 + if version, err = pd.getInt16(); err != nil { + return err + } + if r.correlationID, err = pd.getInt32(); err != nil { + return err + } + r.clientID, err = pd.getString() + + r.body = allocateBody(key, version) + if r.body == nil { + return PacketDecodingError{fmt.Sprintf("unknown request key (%d)", key)} + } + return r.body.decode(pd) +} + +func decodeRequest(r io.Reader) (req *request, err error) { + lengthBytes := make([]byte, 4) + if _, err := io.ReadFull(r, lengthBytes); err != nil { + return nil, err + } + + length := int32(binary.BigEndian.Uint32(lengthBytes)) + if length <= 4 || length > MaxRequestSize { + return nil, PacketDecodingError{fmt.Sprintf("message of length %d too large or too small", length)} + } + + encodedReq := make([]byte, length) + if _, err := io.ReadFull(r, encodedReq); err != nil { + return nil, err + } + + req = &request{} + if err := decode(encodedReq, req); err != nil { + return nil, err + } + return req, nil +} + +func allocateBody(key, version int16) requestBody { + switch key { + case 0: + return &ProduceRequest{} + case 1: + return &FetchRequest{} + case 2: + return &OffsetRequest{} + case 3: + return &MetadataRequest{} + case 8: + return &OffsetCommitRequest{Version: version} + case 9: + return &OffsetFetchRequest{} + case 10: + return &ConsumerMetadataRequest{} + case 11: + return &JoinGroupRequest{} + case 12: + return &HeartbeatRequest{} + case 13: + return &LeaveGroupRequest{} + case 14: + return &SyncGroupRequest{} + case 15: + return &DescribeGroupsRequest{} + case 16: + return &ListGroupsRequest{} + } + return nil +} diff --git a/vendor/github.com/Shopify/sarama/response_header.go b/vendor/github.com/Shopify/sarama/response_header.go new file mode 100644 index 0000000..f3f4d27 --- /dev/null +++ b/vendor/github.com/Shopify/sarama/response_header.go @@ -0,0 +1,21 @@ +package sarama + +import "fmt" + +type responseHeader struct { + length int32 + correlationID int32 +} + +func (r *responseHeader) decode(pd packetDecoder) (err error) { + r.length, err = pd.getInt32() + if err != nil { + return err + } + if r.length <= 4 || r.length > MaxResponseSize { + return PacketDecodingError{fmt.Sprintf("message of length %d too large or too small", r.length)} + } + + r.correlationID, err = pd.getInt32() + return err +} diff --git a/vendor/github.com/Shopify/sarama/sarama.go b/vendor/github.com/Shopify/sarama/sarama.go new file mode 100644 index 0000000..d598217 --- /dev/null +++ b/vendor/github.com/Shopify/sarama/sarama.go @@ -0,0 +1,47 @@ +/* +Package sarama provides client libraries for the Kafka 0.8 protocol. The AsyncProducer object is the high-level +API for producing messages asynchronously; the SyncProducer provides a blocking API for the same purpose. +The Consumer object is the high-level API for consuming messages. The Client object provides metadata +management functionality that is shared between the higher-level objects. + +For lower-level needs, the Broker and Request/Response objects permit precise control over each connection +and message sent on the wire. + +The Request/Response objects and properties are mostly undocumented, as they line up exactly with the +protocol fields documented by Kafka at https://cwiki.apache.org/confluence/display/KAFKA/A+Guide+To+The+Kafka+Protocol +*/ +package sarama + +import ( + "io/ioutil" + "log" +) + +// Logger is the instance of a StdLogger interface that Sarama writes connection +// management events to. By default it is set to discard all log messages via ioutil.Discard, +// but you can set it to redirect wherever you want. +var Logger StdLogger = log.New(ioutil.Discard, "[Sarama] ", log.LstdFlags) + +// StdLogger is used to log error messages. +type StdLogger interface { + Print(v ...interface{}) + Printf(format string, v ...interface{}) + Println(v ...interface{}) +} + +// PanicHandler is called for recovering from panics spawned internally to the library (and thus +// not recoverable by the caller's goroutine). Defaults to nil, which means panics are not recovered. +var PanicHandler func(interface{}) + +// MaxRequestSize is the maximum size (in bytes) of any request that Sarama will attempt to send. Trying +// to send a request larger than this will result in an PacketEncodingError. The default of 100 MiB is aligned +// with Kafka's default `socket.request.max.bytes`, which is the largest request the broker will attempt +// to process. +var MaxRequestSize int32 = 100 * 1024 * 1024 + +// MaxResponseSize is the maximum size (in bytes) of any response that Sarama will attempt to parse. If +// a broker returns a response message larger than this value, Sarama will return a PacketDecodingError to +// protect the client from running out of memory. Please note that brokers do not have any natural limit on +// the size of responses they send. In particular, they can send arbitrarily large fetch responses to consumers +// (see https://issues.apache.org/jira/browse/KAFKA-2063). +var MaxResponseSize int32 = 100 * 1024 * 1024 diff --git a/vendor/github.com/Shopify/sarama/snappy.go b/vendor/github.com/Shopify/sarama/snappy.go new file mode 100644 index 0000000..e86cb70 --- /dev/null +++ b/vendor/github.com/Shopify/sarama/snappy.go @@ -0,0 +1,41 @@ +package sarama + +import ( + "bytes" + "encoding/binary" + + "github.com/golang/snappy" +) + +var snappyMagic = []byte{130, 83, 78, 65, 80, 80, 89, 0} + +// SnappyEncode encodes binary data +func snappyEncode(src []byte) []byte { + return snappy.Encode(nil, src) +} + +// SnappyDecode decodes snappy data +func snappyDecode(src []byte) ([]byte, error) { + if bytes.Equal(src[:8], snappyMagic) { + var ( + pos = uint32(16) + max = uint32(len(src)) + dst = make([]byte, 0, len(src)) + chunk []byte + err error + ) + for pos < max { + size := binary.BigEndian.Uint32(src[pos : pos+4]) + pos += 4 + + chunk, err = snappy.Decode(chunk, src[pos:pos+size]) + if err != nil { + return nil, err + } + pos += size + dst = append(dst, chunk...) + } + return dst, nil + } + return snappy.Decode(nil, src) +} diff --git a/vendor/github.com/Shopify/sarama/sync_group_request.go b/vendor/github.com/Shopify/sarama/sync_group_request.go new file mode 100644 index 0000000..031cf0f --- /dev/null +++ b/vendor/github.com/Shopify/sarama/sync_group_request.go @@ -0,0 +1,96 @@ +package sarama + +type SyncGroupRequest struct { + GroupId string + GenerationId int32 + MemberId string + GroupAssignments map[string][]byte +} + +func (r *SyncGroupRequest) encode(pe packetEncoder) error { + if err := pe.putString(r.GroupId); err != nil { + return err + } + + pe.putInt32(r.GenerationId) + + if err := pe.putString(r.MemberId); err != nil { + return err + } + + if err := pe.putArrayLength(len(r.GroupAssignments)); err != nil { + return err + } + for memberId, memberAssignment := range r.GroupAssignments { + if err := pe.putString(memberId); err != nil { + return err + } + if err := pe.putBytes(memberAssignment); err != nil { + return err + } + } + + return nil +} + +func (r *SyncGroupRequest) decode(pd packetDecoder) (err error) { + if r.GroupId, err = pd.getString(); err != nil { + return + } + if r.GenerationId, err = pd.getInt32(); err != nil { + return + } + if r.MemberId, err = pd.getString(); err != nil { + return + } + + n, err := pd.getArrayLength() + if err != nil { + return err + } + if n == 0 { + return nil + } + + r.GroupAssignments = make(map[string][]byte) + for i := 0; i < n; i++ { + memberId, err := pd.getString() + if err != nil { + return err + } + memberAssignment, err := pd.getBytes() + if err != nil { + return err + } + + r.GroupAssignments[memberId] = memberAssignment + } + + return nil +} + +func (r *SyncGroupRequest) key() int16 { + return 14 +} + +func (r *SyncGroupRequest) version() int16 { + return 0 +} + +func (r *SyncGroupRequest) AddGroupAssignment(memberId string, memberAssignment []byte) { + if r.GroupAssignments == nil { + r.GroupAssignments = make(map[string][]byte) + } + + r.GroupAssignments[memberId] = memberAssignment +} + +func (r *SyncGroupRequest) AddGroupAssignmentMember(memberId string, memberAssignment *ConsumerGroupMemberAssignment) error { + bin, err := encode(memberAssignment) + if err != nil { + return err + } + + r.AddGroupAssignment(memberId, bin) + return nil +} diff --git a/vendor/github.com/Shopify/sarama/sync_group_response.go b/vendor/github.com/Shopify/sarama/sync_group_response.go new file mode 100644 index 0000000..49c8692 --- /dev/null +++ b/vendor/github.com/Shopify/sarama/sync_group_response.go @@ -0,0 +1,28 @@ +package sarama + +type SyncGroupResponse struct { + Err KError + MemberAssignment []byte +} + +func (r *SyncGroupResponse) GetMemberAssignment() (*ConsumerGroupMemberAssignment, error) { + assignment := new(ConsumerGroupMemberAssignment) + err := decode(r.MemberAssignment, assignment) + return assignment, err +} + +func (r *SyncGroupResponse) encode(pe packetEncoder) error { + pe.putInt16(int16(r.Err)) + return pe.putBytes(r.MemberAssignment) +} + +func (r *SyncGroupResponse) decode(pd packetDecoder) (err error) { + if kerr, err := pd.getInt16(); err != nil { + return err + } else { + r.Err = KError(kerr) + } + + r.MemberAssignment, err = pd.getBytes() + return +} diff --git a/vendor/github.com/Shopify/sarama/sync_producer.go b/vendor/github.com/Shopify/sarama/sync_producer.go new file mode 100644 index 0000000..69a26d1 --- /dev/null +++ b/vendor/github.com/Shopify/sarama/sync_producer.go @@ -0,0 +1,95 @@ +package sarama + +import "sync" + +// SyncProducer publishes Kafka messages. It routes messages to the correct broker, refreshing metadata as appropriate, +// and parses responses for errors. You must call Close() on a producer to avoid leaks, it may not be garbage-collected automatically when +// it passes out of scope. +type SyncProducer interface { + + // SendMessage produces a given message, and returns only when it either has + // succeeded or failed to produce. It will return the partition and the offset + // of the produced message, or an error if the message failed to produce. + SendMessage(msg *ProducerMessage) (partition int32, offset int64, err error) + + // Close shuts down the producer and flushes any messages it may have buffered. + // You must call this function before a producer object passes out of scope, as + // it may otherwise leak memory. You must call this before calling Close on the + // underlying client. + Close() error +} + +type syncProducer struct { + producer *asyncProducer + wg sync.WaitGroup +} + +// NewSyncProducer creates a new SyncProducer using the given broker addresses and configuration. +func NewSyncProducer(addrs []string, config *Config) (SyncProducer, error) { + p, err := NewAsyncProducer(addrs, config) + if err != nil { + return nil, err + } + return newSyncProducerFromAsyncProducer(p.(*asyncProducer)), nil +} + +// NewSyncProducerFromClient creates a new SyncProducer using the given client. It is still +// necessary to call Close() on the underlying client when shutting down this producer. +func NewSyncProducerFromClient(client Client) (SyncProducer, error) { + p, err := NewAsyncProducerFromClient(client) + if err != nil { + return nil, err + } + return newSyncProducerFromAsyncProducer(p.(*asyncProducer)), nil +} + +func newSyncProducerFromAsyncProducer(p *asyncProducer) *syncProducer { + p.conf.Producer.Return.Successes = true + p.conf.Producer.Return.Errors = true + sp := &syncProducer{producer: p} + + sp.wg.Add(2) + go withRecover(sp.handleSuccesses) + go withRecover(sp.handleErrors) + + return sp +} + +func (sp *syncProducer) SendMessage(msg *ProducerMessage) (partition int32, offset int64, err error) { + oldMetadata := msg.Metadata + defer func() { + msg.Metadata = oldMetadata + }() + + expectation := make(chan error, 1) + msg.Metadata = expectation + sp.producer.Input() <- msg + + if err := <-expectation; err != nil { + return -1, -1, err + } + + return msg.Partition, msg.Offset, nil +} + +func (sp *syncProducer) handleSuccesses() { + defer sp.wg.Done() + for msg := range sp.producer.Successes() { + expectation := msg.Metadata.(chan error) + expectation <- nil + } +} + +func (sp *syncProducer) handleErrors() { + defer sp.wg.Done() + for err := range sp.producer.Errors() { + expectation := err.Msg.Metadata.(chan error) + expectation <- err.Err + } +} + +func (sp *syncProducer) Close() error { + sp.producer.AsyncClose() + sp.wg.Wait() + return nil +} diff --git a/vendor/github.com/Shopify/sarama/tools/README.md b/vendor/github.com/Shopify/sarama/tools/README.md new file mode 100644 index 0000000..3464c4a --- /dev/null +++ b/vendor/github.com/Shopify/sarama/tools/README.md @@ -0,0 +1,10 @@ +# Sarama tools + +This folder contains applications that are useful for exploration of your Kafka cluster, or instrumentation. +Some of these tools mirror tools that ship with Kafka, but these tools won't require installing the JVM to function. + +- [kafka-console-producer](./kafka-console-producer): a command line tool to produce a single message to your Kafka custer. +- [kafka-console-partitionconsumer](./kafka-console-partitionconsumer): (deprecated) a command line tool to consume a single partition of a topic on your Kafka cluster. +- [kafka-console-consumer](./kafka-console-consumer): a command line tool to consume arbitrary partitions of a topic on your Kafka cluster. + +To install all tools, run `go get github.com/Shopify/sarama/tools/...` diff --git a/vendor/github.com/Shopify/sarama/tools/kafka-console-consumer/.gitignore b/vendor/github.com/Shopify/sarama/tools/kafka-console-consumer/.gitignore new file mode 100644 index 0000000..67da9df --- /dev/null +++ b/vendor/github.com/Shopify/sarama/tools/kafka-console-consumer/.gitignore @@ -0,0 +1,2 @@ +kafka-console-consumer +kafka-console-consumer.test diff --git a/vendor/github.com/Shopify/sarama/tools/kafka-console-consumer/README.md b/vendor/github.com/Shopify/sarama/tools/kafka-console-consumer/README.md new file mode 100644 index 0000000..4e77f0b --- /dev/null +++ b/vendor/github.com/Shopify/sarama/tools/kafka-console-consumer/README.md @@ -0,0 +1,29 @@ +# kafka-console-consumer + +A simple command line tool to consume partitions of a topic and print the +messages on the standard output. + +### Installation + + go get github.com/Shopify/sarama/tools/kafka-console-consumer + +### Usage + + # Minimum invocation + kafka-console-consumer -topic=test -brokers=kafka1:9092 + + # It will pick up a KAFKA_PEERS environment variable + export KAFKA_PEERS=kafka1:9092,kafka2:9092,kafka3:9092 + kafka-console-consumer -topic=test + + # You can specify the offset you want to start at. It can be either + # `oldest`, `newest`. The default is `newest`. + kafka-console-consumer -topic=test -offset=oldest + kafka-console-consumer -topic=test -offset=newest + + # You can specify the partition(s) you want to consume as a comma-separated + # list. The default is `all`. + kafka-console-consumer -topic=test -partitions=1,2,3 + + # Display all command line options + kafka-console-consumer -help diff --git a/vendor/github.com/Shopify/sarama/tools/kafka-console-consumer/kafka-console-consumer.go b/vendor/github.com/Shopify/sarama/tools/kafka-console-consumer/kafka-console-consumer.go new file mode 100644 index 0000000..0f1eb89 --- /dev/null +++ b/vendor/github.com/Shopify/sarama/tools/kafka-console-consumer/kafka-console-consumer.go @@ -0,0 +1,145 @@ +package main + +import ( + "flag" + "fmt" + "log" + "os" + "os/signal" + "strconv" + "strings" + "sync" + + "github.com/Shopify/sarama" +) + +var ( + brokerList = flag.String("brokers", os.Getenv("KAFKA_PEERS"), "The comma separated list of brokers in the Kafka cluster") + topic = flag.String("topic", "", "REQUIRED: the topic to consume") + partitions = flag.String("partitions", "all", "The partitions to consume, can be 'all' or comma-separated numbers") + offset = flag.String("offset", "newest", "The offset to start with. Can be `oldest`, `newest`") + verbose = flag.Bool("verbose", false, "Whether to turn on sarama logging") + bufferSize = flag.Int("buffer-size", 256, "The buffer size of the message channel.") + + logger = log.New(os.Stderr, "", log.LstdFlags) +) + +func main() { + flag.Parse() + + if *brokerList == "" { + printUsageErrorAndExit("You have to provide -brokers as a comma-separated list, or set the KAFKA_PEERS environment variable.") + } + + if *topic == "" { + printUsageErrorAndExit("-topic is required") + } + + if *verbose { + sarama.Logger = logger + } + + var initialOffset int64 + switch *offset { + case "oldest": + initialOffset = sarama.OffsetOldest + case "newest": + initialOffset = sarama.OffsetNewest + default: + printUsageErrorAndExit("-offset should be `oldest` or `newest`") + } + + c, err := sarama.NewConsumer(strings.Split(*brokerList, ","), nil) + if err != nil { + printErrorAndExit(69, "Failed to start consumer: %s", err) + } + + partitionList, err := getPartitions(c) + if err != nil { + printErrorAndExit(69, "Failed to get the list of partitions: %s", err) + } + + var ( + messages = make(chan *sarama.ConsumerMessage, *bufferSize) + closing = make(chan struct{}) + wg sync.WaitGroup + ) + + go func() { + signals := make(chan os.Signal, 1) + signal.Notify(signals, os.Kill, os.Interrupt) + <-signals + logger.Println("Initiating shutdown of consumer...") + close(closing) + }() + + for _, partition := range partitionList { + pc, err := c.ConsumePartition(*topic, partition, initialOffset) + if err != nil { + printErrorAndExit(69, "Failed to start consumer for partition %d: %s", partition, err) + } + + go func(pc sarama.PartitionConsumer) { + <-closing + pc.AsyncClose() + }(pc) + + wg.Add(1) + go func(pc sarama.PartitionConsumer) { + defer wg.Done() + for message := range pc.Messages() { + messages <- message + } + }(pc) + } + + go func() { + for msg := range messages { + fmt.Printf("Partition:\t%d\n", msg.Partition) + fmt.Printf("Offset:\t%d\n", msg.Offset) + fmt.Printf("Key:\t%s\n", string(msg.Key)) + fmt.Printf("Value:\t%s\n", string(msg.Value)) + fmt.Println() + } + }() + + wg.Wait() + logger.Println("Done consuming topic", *topic) + close(messages) + + if err := c.Close(); err != nil { + logger.Println("Failed to close consumer: ", err) + } +} + +func getPartitions(c sarama.Consumer) ([]int32, error) { + if *partitions == "all" { + return c.Partitions(*topic) + } + + tmp := strings.Split(*partitions, ",") + var pList []int32 + for i := range tmp { + val, err := strconv.ParseInt(tmp[i], 10, 32) + if err != nil { + return nil, err + } + pList = append(pList, int32(val)) + } + + return pList, nil +} + +func printErrorAndExit(code int, format string, values ...interface{}) { + fmt.Fprintf(os.Stderr, "ERROR: %s\n", fmt.Sprintf(format, values...)) + fmt.Fprintln(os.Stderr) + os.Exit(code) +} + +func printUsageErrorAndExit(format string, values ...interface{}) { + fmt.Fprintf(os.Stderr, "ERROR: %s\n", fmt.Sprintf(format, values...)) + fmt.Fprintln(os.Stderr) + fmt.Fprintln(os.Stderr, "Available command line options:") + flag.PrintDefaults() + os.Exit(64) +} diff --git a/vendor/github.com/Shopify/sarama/tools/kafka-console-partitionconsumer/.gitignore b/vendor/github.com/Shopify/sarama/tools/kafka-console-partitionconsumer/.gitignore new file mode 100644 index 0000000..5837fe8 --- /dev/null +++ b/vendor/github.com/Shopify/sarama/tools/kafka-console-partitionconsumer/.gitignore @@ -0,0 +1,2 @@ +kafka-console-partitionconsumer +kafka-console-partitionconsumer.test diff --git a/vendor/github.com/Shopify/sarama/tools/kafka-console-partitionconsumer/README.md b/vendor/github.com/Shopify/sarama/tools/kafka-console-partitionconsumer/README.md new file mode 100644 index 0000000..646dd5f --- /dev/null +++ b/vendor/github.com/Shopify/sarama/tools/kafka-console-partitionconsumer/README.md @@ -0,0 +1,28 @@ +# kafka-console-partitionconsumer + +NOTE: this tool is deprecated in favour of the more general and more powerful +`kafka-console-consumer`. + +A simple command line tool to consume a partition of a topic and print the messages +on the standard output. + +### Installation + + go get github.com/Shopify/sarama/tools/kafka-console-partitionconsumer + +### Usage + + # Minimum invocation + kafka-console-partitionconsumer -topic=test -partition=4 -brokers=kafka1:9092 + + # It will pick up a KAFKA_PEERS environment variable + export KAFKA_PEERS=kafka1:9092,kafka2:9092,kafka3:9092 + kafka-console-partitionconsumer -topic=test -partition=4 + + # You can specify the offset you want to start at. It can be either + # `oldest`, `newest`, or a specific offset number + kafka-console-partitionconsumer -topic=test -partition=3 -offset=oldest + kafka-console-partitionconsumer -topic=test -partition=2 -offset=1337 + + # Display all command line options + kafka-console-partitionconsumer -help diff --git a/vendor/github.com/Shopify/sarama/tools/kafka-console-partitionconsumer/kafka-console-partitionconsumer.go b/vendor/github.com/Shopify/sarama/tools/kafka-console-partitionconsumer/kafka-console-partitionconsumer.go new file mode 100644 index 0000000..d5e4464 --- /dev/null +++ b/vendor/github.com/Shopify/sarama/tools/kafka-console-partitionconsumer/kafka-console-partitionconsumer.go @@ -0,0 +1,102 @@ +package main + +import ( + "flag" + "fmt" + "log" + "os" + "os/signal" + "strconv" + "strings" + + "github.com/Shopify/sarama" +) + +var ( + brokerList = flag.String("brokers", os.Getenv("KAFKA_PEERS"), "The comma separated list of brokers in the Kafka cluster") + topic = flag.String("topic", "", "REQUIRED: the topic to consume") + partition = flag.Int("partition", -1, "REQUIRED: the partition to consume") + offset = flag.String("offset", "newest", "The offset to start with. Can be `oldest`, `newest`, or an actual offset") + verbose = flag.Bool("verbose", false, "Whether to turn on sarama logging") + + logger = log.New(os.Stderr, "", log.LstdFlags) +) + +func main() { + flag.Parse() + + if *brokerList == "" { + printUsageErrorAndExit("You have to provide -brokers as a comma-separated list, or set the KAFKA_PEERS environment variable.") + } + + if *topic == "" { + printUsageErrorAndExit("-topic is required") + } + + if *partition == -1 { + printUsageErrorAndExit("-partition is required") + } + + if *verbose { + sarama.Logger = logger + } + + var ( + initialOffset int64 + offsetError error + ) + switch *offset { + case "oldest": + initialOffset = sarama.OffsetOldest + case "newest": + initialOffset = sarama.OffsetNewest + default: + initialOffset, offsetError = strconv.ParseInt(*offset, 10, 64) + } + + if offsetError != nil { + printUsageErrorAndExit("Invalid initial offset: %s", *offset) + } + + c, err := sarama.NewConsumer(strings.Split(*brokerList, ","), nil) + if err != nil { + printErrorAndExit(69, "Failed to start consumer: %s", err) + } + + pc, err := c.ConsumePartition(*topic, int32(*partition), initialOffset) + if err != nil { + printErrorAndExit(69, "Failed to start partition consumer: %s", err) + } + + go func() { + signals := make(chan os.Signal, 1) + signal.Notify(signals, os.Kill, os.Interrupt) + <-signals + pc.AsyncClose() + }() + + for msg := range pc.Messages() { + fmt.Printf("Offset:\t%d\n", msg.Offset) + fmt.Printf("Key:\t%s\n", string(msg.Key)) + fmt.Printf("Value:\t%s\n", string(msg.Value)) + fmt.Println() + } + + if err := c.Close(); err != nil { + logger.Println("Failed to close consumer: ", err) + } +} + +func printErrorAndExit(code int, format string, values ...interface{}) { + fmt.Fprintf(os.Stderr, "ERROR: %s\n", fmt.Sprintf(format, values...)) + fmt.Fprintln(os.Stderr) + os.Exit(code) +} + +func printUsageErrorAndExit(format string, values ...interface{}) { + fmt.Fprintf(os.Stderr, "ERROR: %s\n", fmt.Sprintf(format, values...)) + fmt.Fprintln(os.Stderr) + fmt.Fprintln(os.Stderr, "Available command line options:") + flag.PrintDefaults() + os.Exit(64) +} diff --git a/vendor/github.com/Shopify/sarama/tools/kafka-console-producer/.gitignore b/vendor/github.com/Shopify/sarama/tools/kafka-console-producer/.gitignore new file mode 100644 index 0000000..2b9e563 --- /dev/null +++ b/vendor/github.com/Shopify/sarama/tools/kafka-console-producer/.gitignore @@ -0,0 +1,2 @@ +kafka-console-producer +kafka-console-producer.test diff --git a/vendor/github.com/Shopify/sarama/tools/kafka-console-producer/README.md b/vendor/github.com/Shopify/sarama/tools/kafka-console-producer/README.md new file mode 100644 index 0000000..6b3a65f --- /dev/null +++ b/vendor/github.com/Shopify/sarama/tools/kafka-console-producer/README.md @@ -0,0 +1,34 @@ +# kafka-console-producer + +A simple command line tool to produce a single message to Kafka. + +### Installation + + go get github.com/Shopify/sarama/tools/kafka-console-producer + + +### Usage + + # Minimum invocation + kafka-console-producer -topic=test -value=value -brokers=kafka1:9092 + + # It will pick up a KAFKA_PEERS environment variable + export KAFKA_PEERS=kafka1:9092,kafka2:9092,kafka3:9092 + kafka-console-producer -topic=test -value=value + + # It will read the value from stdin by using pipes + echo "hello world" | kafka-console-producer -topic=test + + # Specify a key: + echo "hello world" | kafka-console-producer -topic=test -key=key + + # Partitioning: by default, kafka-console-producer will partition as follows: + # - manual partitioning if a -partition is provided + # - hash partitioning by key if a -key is provided + # - random partioning otherwise. + # + # You can override this using the -partitioner argument: + echo "hello world" | kafka-console-producer -topic=test -key=key -partitioner=random + + # Display all command line options + kafka-console-producer -help diff --git a/vendor/github.com/Shopify/sarama/tools/kafka-console-producer/kafka-console-producer.go b/vendor/github.com/Shopify/sarama/tools/kafka-console-producer/kafka-console-producer.go new file mode 100644 index 0000000..6a1765d --- /dev/null +++ b/vendor/github.com/Shopify/sarama/tools/kafka-console-producer/kafka-console-producer.go @@ -0,0 +1,118 @@ +package main + +import ( + "flag" + "fmt" + "io/ioutil" + "log" + "os" + "strings" + + "github.com/Shopify/sarama" +) + +var ( + brokerList = flag.String("brokers", os.Getenv("KAFKA_PEERS"), "The comma separated list of brokers in the Kafka cluster. You can also set the KAFKA_PEERS environment variable") + topic = flag.String("topic", "", "REQUIRED: the topic to produce to") + key = flag.String("key", "", "The key of the message to produce. Can be empty.") + value = flag.String("value", "", "REQUIRED: the value of the message to produce. You can also provide the value on stdin.") + partitioner = flag.String("partitioner", "", "The partitioning scheme to use. Can be `hash`, `manual`, or `random`") + partition = flag.Int("partition", -1, "The partition to produce to.") + verbose = flag.Bool("verbose", false, "Turn on sarama logging to stderr") + silent = flag.Bool("silent", false, "Turn off printing the message's topic, partition, and offset to stdout") + + logger = log.New(os.Stderr, "", log.LstdFlags) +) + +func main() { + flag.Parse() + + if *brokerList == "" { + printUsageErrorAndExit("no -brokers specified. Alternatively, set the KAFKA_PEERS environment variable") + } + + if *topic == "" { + printUsageErrorAndExit("no -topic specified") + } + + if *verbose { + sarama.Logger = logger + } + + config := sarama.NewConfig() + config.Producer.RequiredAcks = sarama.WaitForAll + + switch *partitioner { + case "": + if *partition >= 0 { + config.Producer.Partitioner = sarama.NewManualPartitioner + } else { + config.Producer.Partitioner = sarama.NewHashPartitioner + } + case "hash": + config.Producer.Partitioner = sarama.NewHashPartitioner + case "random": + config.Producer.Partitioner = sarama.NewRandomPartitioner + case "manual": + config.Producer.Partitioner = sarama.NewManualPartitioner + if *partition == -1 { + printUsageErrorAndExit("-partition is required when partitioning manually") + } + default: + printUsageErrorAndExit(fmt.Sprintf("Partitioner %s not supported.", *partitioner)) + } + + message := &sarama.ProducerMessage{Topic: *topic, Partition: int32(*partition)} + + if *key != "" { + message.Key = sarama.StringEncoder(*key) + } + + if *value != "" { + message.Value = sarama.StringEncoder(*value) + } else if stdinAvailable() { + bytes, err := ioutil.ReadAll(os.Stdin) + if err != nil { + printErrorAndExit(66, "Failed to read data from the standard input: %s", err) + } + message.Value = sarama.ByteEncoder(bytes) + } else { + printUsageErrorAndExit("-value is required, or you have to provide the value on stdin") + } + + producer, err := sarama.NewSyncProducer(strings.Split(*brokerList, ","), config) + if err != nil { + printErrorAndExit(69, "Failed to open Kafka producer: %s", err) + } + defer func() { + if err := producer.Close(); err != nil { + logger.Println("Failed to close Kafka producer cleanly:", err) + } + }() + + partition, offset, err := producer.SendMessage(message) + if err != nil { + printErrorAndExit(69, "Failed to produce message: %s", err) + } else if !*silent { + fmt.Printf("topic=%s\tpartition=%d\toffset=%d\n", *topic, partition, offset) + } +} + +func printErrorAndExit(code int, format string, values ...interface{}) { + fmt.Fprintf(os.Stderr, "ERROR: %s\n", fmt.Sprintf(format, values...)) + fmt.Fprintln(os.Stderr) + os.Exit(code) +} + +func printUsageErrorAndExit(message string) { + fmt.Fprintln(os.Stderr, "ERROR:", message) + fmt.Fprintln(os.Stderr) + fmt.Fprintln(os.Stderr, "Available command line options:") + flag.PrintDefaults() + os.Exit(64) +} + +func stdinAvailable() bool { + stat, _ := os.Stdin.Stat() + return (stat.Mode() & os.ModeCharDevice) == 0 +} diff --git a/vendor/github.com/Shopify/sarama/utils.go b/vendor/github.com/Shopify/sarama/utils.go new file mode 100644 index 0000000..04ca887 --- /dev/null +++ b/vendor/github.com/Shopify/sarama/utils.go @@ -0,0 +1,111 @@ +package sarama + +import ( + "bufio" + "net" + "sort" +) + +type none struct{} + +// make []int32 sortable so we can sort partition numbers +type int32Slice []int32 + +func (slice int32Slice) Len() int { + return len(slice) +} + +func (slice int32Slice) Less(i, j int) bool { + return slice[i] < slice[j] +} + +func (slice int32Slice) Swap(i, j int) { + slice[i], slice[j] = slice[j], slice[i] +} + +func dupeAndSort(input []int32) []int32 { + ret := make([]int32, 0, len(input)) + for _, val := range input { + ret = append(ret, val) + } + + sort.Sort(int32Slice(ret)) + return ret +} + +func withRecover(fn func()) { + defer func() { + handler := PanicHandler + if handler != nil { + if err := recover(); err != nil { + handler(err) + } + } + }() + + fn() +} + +func safeAsyncClose(b *Broker) { + tmp := b // local var prevents clobbering in goroutine + go withRecover(func() { + if connected, _ := tmp.Connected(); connected { + if err := tmp.Close(); err != nil { + Logger.Println("Error closing broker", tmp.ID(), ":", err) + } + } + }) +} + +// Encoder is a simple interface for any type that can be encoded as an array of bytes +// in order to be sent as the key or value of a Kafka message. Length() is provided as an +// optimization, and must return the same as len() on the result of Encode(). +type Encoder interface { + Encode() ([]byte, error) + Length() int +} + +// make strings and byte slices encodable for convenience so they can be used as keys +// and/or values in kafka messages + +// StringEncoder implements the Encoder interface for Go strings so that they can be used +// as the Key or Value in a ProducerMessage. +type StringEncoder string + +func (s StringEncoder) Encode() ([]byte, error) { + return []byte(s), nil +} + +func (s StringEncoder) Length() int { + return len(s) +} + +// ByteEncoder implements the Encoder interface for Go byte slices so that they can be used +// as the Key or Value in a ProducerMessage. +type ByteEncoder []byte + +func (b ByteEncoder) Encode() ([]byte, error) { + return b, nil +} + +func (b ByteEncoder) Length() int { + return len(b) +} + +// bufConn wraps a net.Conn with a buffer for reads to reduce the number of +// reads that trigger syscalls. +type bufConn struct { + net.Conn + buf *bufio.Reader +} + +func newBufConn(conn net.Conn) *bufConn { + return &bufConn{ + Conn: conn, + buf: bufio.NewReader(conn), + } +} + +func (bc *bufConn) Read(b []byte) (n int, err error) { + return bc.buf.Read(b) +} diff --git a/vendor/github.com/Shopify/sarama/vagrant/boot_cluster.sh b/vendor/github.com/Shopify/sarama/vagrant/boot_cluster.sh new file mode 100644 index 0000000..95e47dd --- /dev/null +++ b/vendor/github.com/Shopify/sarama/vagrant/boot_cluster.sh @@ -0,0 +1,22 @@ +#!/bin/sh + +set -ex + +# Launch and wait for toxiproxy +${REPOSITORY_ROOT}/vagrant/run_toxiproxy.sh & +while ! nc -q 1 localhost 2181 ${KAFKA_INSTALL_ROOT}/zookeeper-${ZK_PORT}/myid +done diff --git a/vendor/github.com/Shopify/sarama/vagrant/kafka.conf b/vendor/github.com/Shopify/sarama/vagrant/kafka.conf new file mode 100644 index 0000000..d975de4 --- /dev/null +++ b/vendor/github.com/Shopify/sarama/vagrant/kafka.conf @@ -0,0 +1,5 @@ +start on started zookeeper-ZK_PORT +stop on stopping zookeeper-ZK_PORT + +pre-start exec sleep 2 +exec /opt/kafka-KAFKAID/bin/kafka-server-start.sh /opt/kafka-KAFKAID/config/server.properties diff --git a/vendor/github.com/Shopify/sarama/vagrant/provision.sh b/vendor/github.com/Shopify/sarama/vagrant/provision.sh new file mode 100644 index 0000000..ace768f --- /dev/null +++ b/vendor/github.com/Shopify/sarama/vagrant/provision.sh @@ -0,0 +1,15 @@ +#!/bin/sh + +set -ex + +apt-get update +yes | apt-get install default-jre + +export KAFKA_INSTALL_ROOT=/opt +export KAFKA_HOSTNAME=192.168.100.67 +export KAFKA_VERSION=0.9.0.1 +export REPOSITORY_ROOT=/vagrant + +sh /vagrant/vagrant/install_cluster.sh +sh /vagrant/vagrant/setup_services.sh +sh /vagrant/vagrant/create_topics.sh diff --git a/vendor/github.com/Shopify/sarama/vagrant/run_toxiproxy.sh b/vendor/github.com/Shopify/sarama/vagrant/run_toxiproxy.sh new file mode 100644 index 0000000..e52c00e --- /dev/null +++ b/vendor/github.com/Shopify/sarama/vagrant/run_toxiproxy.sh @@ -0,0 +1,22 @@ +#!/bin/sh + +set -ex + +${KAFKA_INSTALL_ROOT}/toxiproxy -port 8474 -host 0.0.0.0 & +PID=$! + +while ! nc -q 1 localhost 8474 + +# The number of threads handling network requests +num.network.threads=2 + +# The number of threads doing disk I/O +num.io.threads=8 + +# The send buffer (SO_SNDBUF) used by the socket server +socket.send.buffer.bytes=1048576 + +# The receive buffer (SO_RCVBUF) used by the socket server +socket.receive.buffer.bytes=1048576 + +# The maximum size of a request that the socket server will accept (protection against OOM) +socket.request.max.bytes=104857600 + + +############################# Log Basics ############################# + +# A comma seperated list of directories under which to store log files +log.dirs=KAFKA_DATADIR + +# The default number of log partitions per topic. More partitions allow greater +# parallelism for consumption, but this will also result in more files across +# the brokers. +num.partitions=2 + +# Create new topics with a replication factor of 2 so failover can be tested +# more easily. +default.replication.factor=2 + +auto.create.topics.enable=false +delete.topic.enable=true + +############################# Log Flush Policy ############################# + +# Messages are immediately written to the filesystem but by default we only fsync() to sync +# the OS cache lazily. The following configurations control the flush of data to disk. +# There are a few important trade-offs here: +# 1. Durability: Unflushed data may be lost if you are not using replication. +# 2. Latency: Very large flush intervals may lead to latency spikes when the flush does occur as there will be a lot of data to flush. +# 3. Throughput: The flush is generally the most expensive operation, and a small flush interval may lead to exceessive seeks. +# The settings below allow one to configure the flush policy to flush data after a period of time or +# every N messages (or both). This can be done globally and overridden on a per-topic basis. + +# The number of messages to accept before forcing a flush of data to disk +#log.flush.interval.messages=10000 + +# The maximum amount of time a message can sit in a log before we force a flush +#log.flush.interval.ms=1000 + +############################# Log Retention Policy ############################# + +# The following configurations control the disposal of log segments. The policy can +# be set to delete segments after a period of time, or after a given size has accumulated. +# A segment will be deleted whenever *either* of these criteria are met. Deletion always happens +# from the end of the log. + +# The minimum age of a log file to be eligible for deletion +log.retention.hours=168 + +# A size-based retention policy for logs. Segments are pruned from the log as long as the remaining +# segments don't drop below log.retention.bytes. +log.retention.bytes=268435456 + +# The maximum size of a log segment file. When this size is reached a new log segment will be created. +log.segment.bytes=268435456 + +# The interval at which log segments are checked to see if they can be deleted according +# to the retention policies +log.retention.check.interval.ms=60000 + +# By default the log cleaner is disabled and the log retention policy will default to just delete segments after their retention expires. +# If log.cleaner.enable=true is set the cleaner will be enabled and individual logs can then be marked for log compaction. +log.cleaner.enable=false + +############################# Zookeeper ############################# + +# Zookeeper connection string (see zookeeper docs for details). +# This is a comma separated host:port pairs, each corresponding to a zk +# server. e.g. "127.0.0.1:3000,127.0.0.1:3001,127.0.0.1:3002". +# You can also append an optional chroot string to the urls to specify the +# root directory for all kafka znodes. +zookeeper.connect=localhost:ZK_PORT + +# Timeout in ms for connecting to zookeeper +zookeeper.session.timeout.ms=3000 +zookeeper.connection.timeout.ms=3000 diff --git a/vendor/github.com/Shopify/sarama/vagrant/setup_services.sh b/vendor/github.com/Shopify/sarama/vagrant/setup_services.sh new file mode 100644 index 0000000..81d8ea0 --- /dev/null +++ b/vendor/github.com/Shopify/sarama/vagrant/setup_services.sh @@ -0,0 +1,29 @@ +#!/bin/sh + +set -ex + +stop toxiproxy || true +cp ${REPOSITORY_ROOT}/vagrant/toxiproxy.conf /etc/init/toxiproxy.conf +cp ${REPOSITORY_ROOT}/vagrant/run_toxiproxy.sh ${KAFKA_INSTALL_ROOT}/ +start toxiproxy + +for i in 1 2 3 4 5; do + ZK_PORT=`expr $i + 2180` + KAFKA_PORT=`expr $i + 9090` + + stop zookeeper-${ZK_PORT} || true + + # set up zk service + cp ${REPOSITORY_ROOT}/vagrant/zookeeper.conf /etc/init/zookeeper-${ZK_PORT}.conf + sed -i s/KAFKAID/${KAFKA_PORT}/g /etc/init/zookeeper-${ZK_PORT}.conf + + # set up kafka service + cp ${REPOSITORY_ROOT}/vagrant/kafka.conf /etc/init/kafka-${KAFKA_PORT}.conf + sed -i s/KAFKAID/${KAFKA_PORT}/g /etc/init/kafka-${KAFKA_PORT}.conf + sed -i s/ZK_PORT/${ZK_PORT}/g /etc/init/kafka-${KAFKA_PORT}.conf + + start zookeeper-${ZK_PORT} +done + +# Wait for the last kafka node to finish booting +while ! nc -q 1 localhost 29095 0 { + ret, err := file.Seek(offset, 0) + if err != nil { + log.Printf("Failed to seek to offset %d: %s", offset, err) + file.Close() + return nil, err + } else if ret != offset { + log.Printf("Failed to seek to offset %d: current offset: %s", + offset, ret) + file.Close() + return nil, err + } + } + + return &RecordReader{file}, nil +} + +// Next reads and returns the next unified2 record. The record is +// returned as an interface{} which will be one of the types +// EventRecord, PacketRecord or ExtraDataRecord. +func (r *RecordReader) Next() (interface{}, error) { + return ReadRecord(r.File) +} + +// Close closes this reader and the underlying file. +func (r *RecordReader) Close() { + r.File.Close() +} + +// Offset returns the current offset of this reader. +func (r *RecordReader) Offset() int64 { + offset, err := r.File.Seek(0, 1) + if err != nil { + return 0 + } + return offset +} + +// Name returns the name of the file being read. +func (r *RecordReader) Name() string { + return r.File.Name() +} diff --git a/vendor/github.com/cleesmith/go-unified2/sample_data/indexed_1455467317.snort.log.1455459821 b/vendor/github.com/cleesmith/go-unified2/sample_data/indexed_1455467317.snort.log.1455459821 new file mode 100644 index 0000000..99ce5a0 Binary files /dev/null and b/vendor/github.com/cleesmith/go-unified2/sample_data/indexed_1455467317.snort.log.1455459821 differ diff --git a/vendor/github.com/cleesmith/go-unified2/sample_data/snort.log.1452978988 b/vendor/github.com/cleesmith/go-unified2/sample_data/snort.log.1452978988 new file mode 100644 index 0000000..99ce5a0 Binary files /dev/null and b/vendor/github.com/cleesmith/go-unified2/sample_data/snort.log.1452978988 differ diff --git a/vendor/github.com/cleesmith/go-unified2/spoolrecordreader.go b/vendor/github.com/cleesmith/go-unified2/spoolrecordreader.go new file mode 100644 index 0000000..647bbf2 --- /dev/null +++ b/vendor/github.com/cleesmith/go-unified2/spoolrecordreader.go @@ -0,0 +1,209 @@ +/* Copyright (c) 2013 Jason Ish + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +package unified2 + +import ( + "io" + "io/ioutil" + "log" + "os" + "path" + "strings" +) + +// SpoolRecordReader is a unified2 record reader that reads from a +// directory containing unified2 "spool" files. +// +// Unified2 spool files are files that have a common prefix and are +// suffixed by a timestamp. This is the typical format used by Snort +// and Suricata as new unified2 files are closed and a new one is +// created when they reach a certain size. +type SpoolRecordReader struct { + // CloseHook will be called when a file is closed. + // It can be used to delete, archive, or rename the file. + CloseHook func(string) + FileSource string + FileOffset int64 + directory string + prefix string + logger *log.Logger + reader *RecordReader +} + +// NewSpoolRecordReader creates a new RecordSpoolReader reading files +// prefixed with the provided prefix in the passed in directory. +func NewSpoolRecordReader(directory string, prefix string) *SpoolRecordReader { + reader := new(SpoolRecordReader) + reader.directory = directory + reader.prefix = prefix + return reader +} + +func (r *SpoolRecordReader) log(format string, v ...interface{}) { + if r.logger != nil { + r.logger.Printf(format, v...) + } +} + +// Logger sets a logger. Useful while testing/debugging. +func (r *SpoolRecordReader) Logger(logger *log.Logger) { + r.logger = logger +} + +// getFiles returns a sorted list of filename in the spool +// directory with the specified prefix. +func (r *SpoolRecordReader) getFiles() ([]os.FileInfo, error) { + files, err := ioutil.ReadDir(r.directory) + if err != nil { + return nil, err + } + + filtered := make([]os.FileInfo, len(files)) + filtered_idx := 0 + + for _, file := range files { + if strings.HasPrefix(file.Name(), r.prefix) { + filtered[filtered_idx] = file + filtered_idx++ + } + } + + return filtered[0:filtered_idx], nil +} + +// openNext opens the next available file if it exists. +// If a new file is opened its filename will be returned. +func (r *SpoolRecordReader) openNext() bool { + // feb 2016: "r.getFiles" calls "ioutil.ReadDir" which + // as the golang docs say are sorted by filename ... + // that's "sorted" as in ascending alphabetical order + files, err := r.getFiles() + if err != nil { + r.log("openNext: failed to get filenames: %s", err) + return false + } + + if len(files) == 0 { + // Nothing to do. + return false + } + + if r.reader != nil { + r.log("openNext: currently open file: %s", r.reader.Name()) + } + + var nextFilename string + + for _, file := range files { + if r.reader == nil { + nextFilename = path.Join(r.directory, file.Name()) + break + } else { + if path.Base(r.reader.Name()) != file.Name() { + nextFilename = path.Join(r.directory, file.Name()) + break + } + } + } + + // r.log("openNext: nextFilename: %#v", nextFilename) + if nextFilename == "" { + r.log("openNext: no new files found.") + return false + } + + if r.reader != nil { + r.log("openNext: closing file '%s'.", r.reader.Name()) + r.reader.Close() + // Call the close hook if set. + if r.CloseHook != nil { + r.CloseHook(r.reader.Name()) + } + } + + r.log("openNext: opening file '%v'", nextFilename) + r.log("openNext: FileSource.: '%v'", r.FileSource) + r.log("openNext: FileOffset=%v", r.FileOffset) + if nextFilename == r.FileSource { + r.reader, err = NewRecordReader(nextFilename, r.FileOffset) + } else { + r.reader, err = NewRecordReader(nextFilename, 0) + } + if err != nil { + r.log("openNext: failed to open '%s': err: %s", nextFilename, err) + return false + } + return true +} + +// Next returns the next record read from the spool. +func (r *SpoolRecordReader) Next() (interface{}, error) { + for { + + // If we have no current file, try to open one. + if r.reader == nil { + r.openNext() + } + + // If we still don't have a current file, return. + if r.reader == nil { + return nil, nil + } + + record, err := r.reader.Next() + if err == io.EOF { + if r.openNext() { + continue + } + } + + // Check if the file name exists. + // Errors if the file was removed/rotated after reading and before + // calling the stat function + // info, statErr := r.reader.File.Stat() + _, statErr := os.Stat(r.reader.File.Name()) + if statErr != nil { + r.log("Next: unexpected error reading from '%s'; error: '%s'", r.reader.File.Name(), statErr) + return nil, statErr + } + + return record, err + + } + +} + +// Offset returns the current filename that is being processed, +// and its read position (the offset). +func (r *SpoolRecordReader) Offset() (string, int64) { + if r.reader != nil { + // return path.Base(r.reader.Name()), r.reader.Offset() + return r.reader.Name(), r.reader.Offset() + } else { + return "", 0 + } +} diff --git a/vendor/github.com/cleesmith/go-unified2/test/multi-record-event-x2.log b/vendor/github.com/cleesmith/go-unified2/test/multi-record-event-x2.log new file mode 100644 index 0000000..8afd01f Binary files /dev/null and b/vendor/github.com/cleesmith/go-unified2/test/multi-record-event-x2.log differ diff --git a/vendor/github.com/cleesmith/go-unified2/test/multi-record-event.log b/vendor/github.com/cleesmith/go-unified2/test/multi-record-event.log new file mode 100644 index 0000000..6570353 Binary files /dev/null and b/vendor/github.com/cleesmith/go-unified2/test/multi-record-event.log differ diff --git a/vendor/github.com/cleesmith/go-unified2/test/short-read-on-body.log b/vendor/github.com/cleesmith/go-unified2/test/short-read-on-body.log new file mode 100644 index 0000000..0163ef3 Binary files /dev/null and b/vendor/github.com/cleesmith/go-unified2/test/short-read-on-body.log differ diff --git a/vendor/github.com/cleesmith/go-unified2/test/short-read-on-header.log b/vendor/github.com/cleesmith/go-unified2/test/short-read-on-header.log new file mode 100644 index 0000000..da649b9 Binary files /dev/null and b/vendor/github.com/cleesmith/go-unified2/test/short-read-on-header.log differ diff --git a/vendor/github.com/cleesmith/go-unified2/unified2.go b/vendor/github.com/cleesmith/go-unified2/unified2.go new file mode 100644 index 0000000..1922c7f --- /dev/null +++ b/vendor/github.com/cleesmith/go-unified2/unified2.go @@ -0,0 +1,207 @@ +/* Copyright (c) 2013 Jason Ish + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* + +Package unified2 provides a decoder for unified v2 log files +produced by Snort and Suricata. + +Currently the unified2 package provides: + - Unified2 record decoders. + - A record aggregator to aggregate records into an event. + +*/ +package unified2 + +import ( + "encoding/binary" + "io" +) + +// Unified2 record types. +const ( + UNIFIED2_PACKET = 2 + UNIFIED2_IDS_EVENT = 7 + UNIFIED2_IDS_EVENT_IP6 = 72 + UNIFIED2_IDS_EVENT_V2 = 104 + UNIFIED2_IDS_EVENT_IP6_V2 = 105 + UNIFIED2_EXTRA_DATA = 110 +) + +// RawHeader is the raw unified2 record header. +type RawHeader struct { + Type uint32 + Len uint32 +} + +// RawRecord is a holder type for a raw un-decoded record. +type RawRecord struct { + Type uint32 + Data []byte +} + +// EventRecord is a struct representing a decoded event record. +// +// This struct is used to represent the decoded form of all the event +// types. The difference between an IPv4 and IPv6 event will be the +// length of the IP address IpSource and IpDestination. +type EventRecord struct { + SensorId uint32 + EventId uint32 + EventSecond uint32 + EventMicrosecond uint32 + SignatureId uint32 + GeneratorId uint32 + SignatureRevision uint32 + ClassificationId uint32 + Priority uint32 + IpSource []byte + IpDestination []byte + SportItype uint16 + DportIcode uint16 + Protocol uint8 + ImpactFlag uint8 + Impact uint8 + Blocked uint8 + MplsLabel uint32 + VlanId uint16 +} + +// PacketRecord is a struct representing a decoded packet record. +type PacketRecord struct { + SensorId uint32 + EventId uint32 + EventSecond uint32 + PacketSecond uint32 + PacketMicrosecond uint32 + LinkType uint32 + Length uint32 + Data []byte +} + +// The length of a PacketRecord before variable length data. +const PACKET_RECORD_HDR_LEN = 28 + +// ExtraDataRecord is a struct representing a decoded extra data record. +type ExtraDataRecord struct { + EventType uint32 + EventLength uint32 + SensorId uint32 + EventId uint32 + EventSecond uint32 + Type uint32 + DataType uint32 + DataLength uint32 + Data []byte +} + +// The length of an ExtraDataRecord before variable length data. +const EXTRA_DATA_RECORD_HDR_LEN = 32 + +// ReadRawRecord reads a raw record from the provided file. +// +// On error, err will no non-nil. Expected error values are io.EOF +// when the end of the file has been reached or io.ErrUnexpectedEOF if +// a complete record was unable to be read. +// +// In the case of io.ErrUnexpectedEOF the file offset will be reset +// back to where it was upon entering this function so it is ready to +// be read from again if it is expected more data will be written to +// the file. +func ReadRawRecord(file io.ReadWriteSeeker) (*RawRecord, error) { + var header RawHeader + + /* Get the current offset so we can seek back to it. */ + offset, _ := file.Seek(0, 1) + + /* Now read in the header. */ + err := binary.Read(file, binary.BigEndian, &header) + if err != nil { + file.Seek(offset, 0) + return nil, err + } + + /* Create a buffer to hold the raw record data and read the + /* record data into it */ + data := make([]byte, header.Len) + n, err := file.Read(data) + if err != nil { + file.Seek(offset, 0) + return nil, err + } + if uint32(n) != header.Len { + file.Seek(offset, 0) + return nil, io.ErrUnexpectedEOF + } + + return &RawRecord{header.Type, data}, nil +} + +// ReadRecord reads a record from the provided file and returns a +// decoded record. +// +// On error, err will no non-nil. Expected error values are io.EOF +// when the end of the file has been reached or io.ErrUnexpectedEOF if +// a complete record was unable to be read. +// +// In the case of io.ErrUnexpectedEOF the file offset will be reset +// back to where it was upon entering this function so it is ready to +// be read from again if it is expected more data will be written to +// the file. +// +// If an error occurred during decoding of the read data a +// DecodingError will be returned. This likely means the input is +// corrupt. +func ReadRecord(file io.ReadWriteSeeker) (interface{}, error) { + + record, err := ReadRawRecord(file) + if err != nil { + return nil, err + } + + var decoded interface{} + + switch record.Type { + case UNIFIED2_IDS_EVENT, + UNIFIED2_IDS_EVENT_IP6, + UNIFIED2_IDS_EVENT_V2, + UNIFIED2_IDS_EVENT_IP6_V2: + decoded, err = DecodeEventRecord(record.Type, record.Data) + case UNIFIED2_PACKET: + decoded, err = DecodePacketRecord(record.Data) + case UNIFIED2_EXTRA_DATA: + decoded, err = DecodeExtraDataRecord(record.Data) + } + + if err != nil { + return nil, err + } else if decoded != nil { + return decoded, nil + } else { + // Unknown record type. + return nil, nil + } +} diff --git a/vendor/github.com/dustin/go-humanize/.gitignore b/vendor/github.com/dustin/go-humanize/.gitignore new file mode 100644 index 0000000..05b4051 --- /dev/null +++ b/vendor/github.com/dustin/go-humanize/.gitignore @@ -0,0 +1,6 @@ +#* +*.[568] +*.a +*~ +[568].out +_* diff --git a/vendor/github.com/dustin/go-humanize/LICENSE b/vendor/github.com/dustin/go-humanize/LICENSE new file mode 100644 index 0000000..8d9a94a --- /dev/null +++ b/vendor/github.com/dustin/go-humanize/LICENSE @@ -0,0 +1,21 @@ +Copyright (c) 2005-2008 Dustin Sallings + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + diff --git a/vendor/github.com/dustin/go-humanize/README.markdown b/vendor/github.com/dustin/go-humanize/README.markdown new file mode 100644 index 0000000..5fcdfa4 --- /dev/null +++ b/vendor/github.com/dustin/go-humanize/README.markdown @@ -0,0 +1,92 @@ +# Humane Units + +Just a few functions for helping humanize times and sizes. + +`go get` it as `github.com/dustin/go-humanize`, import it as +`"github.com/dustin/go-humanize"`, use it as `humanize` + +See [godoc](https://godoc.org/github.com/dustin/go-humanize) for +complete documentation. + +## Sizes + +This lets you take numbers like `82854982` and convert them to useful +strings like, `83MB` or `79MiB` (whichever you prefer). + +Example: + +```go +fmt.Printf("That file is %s.", humanize.Bytes(82854982)) +``` + +## Times + +This lets you take a `time.Time` and spit it out in relative terms. +For example, `12 seconds ago` or `3 days from now`. + +Example: + +```go +fmt.Printf("This was touched %s", humanize.Time(someTimeInstance)) +``` + +Thanks to Kyle Lemons for the time implementation from an IRC +conversation one day. It's pretty neat. + +## Ordinals + +From a [mailing list discussion][odisc] where a user wanted to be able +to label ordinals. + + 0 -> 0th + 1 -> 1st + 2 -> 2nd + 3 -> 3rd + 4 -> 4th + [...] + +Example: + +```go +fmt.Printf("You're my %s best friend.", humanize.Ordinal(193)) +``` + +## Commas + +Want to shove commas into numbers? Be my guest. + + 0 -> 0 + 100 -> 100 + 1000 -> 1,000 + 1000000000 -> 1,000,000,000 + -100000 -> -100,000 + +Example: + +```go +fmt.Printf("You owe $%s.\n", humanize.Comma(6582491)) +``` + +## Ftoa + +Nicer float64 formatter that removes trailing zeros. + +```go +fmt.Printf("%f", 2.24) // 2.240000 +fmt.Printf("%s", humanize.Ftoa(2.24)) // 2.24 +fmt.Printf("%f", 2.0) // 2.000000 +fmt.Printf("%s", humanize.Ftoa(2.0)) // 2 +``` + +## SI notation + +Format numbers with [SI notation][sinotation]. + +Example: + +```go +humanize.SI(0.00000000223, "M") // 2.23nM +``` + +[odisc]: https://groups.google.com/d/topic/golang-nuts/l8NhI74jl-4/discussion +[sinotation]: http://en.wikipedia.org/wiki/Metric_prefix diff --git a/vendor/github.com/dustin/go-humanize/big.go b/vendor/github.com/dustin/go-humanize/big.go new file mode 100644 index 0000000..f49dc33 --- /dev/null +++ b/vendor/github.com/dustin/go-humanize/big.go @@ -0,0 +1,31 @@ +package humanize + +import ( + "math/big" +) + +// order of magnitude (to a max order) +func oomm(n, b *big.Int, maxmag int) (float64, int) { + mag := 0 + m := &big.Int{} + for n.Cmp(b) >= 0 { + n.DivMod(n, b, m) + mag++ + if mag == maxmag && maxmag >= 0 { + break + } + } + return float64(n.Int64()) + (float64(m.Int64()) / float64(b.Int64())), mag +} + +// total order of magnitude +// (same as above, but with no upper limit) +func oom(n, b *big.Int) (float64, int) { + mag := 0 + m := &big.Int{} + for n.Cmp(b) >= 0 { + n.DivMod(n, b, m) + mag++ + } + return float64(n.Int64()) + (float64(m.Int64()) / float64(b.Int64())), mag +} diff --git a/vendor/github.com/dustin/go-humanize/bigbytes.go b/vendor/github.com/dustin/go-humanize/bigbytes.go new file mode 100644 index 0000000..67ea5c8 --- /dev/null +++ b/vendor/github.com/dustin/go-humanize/bigbytes.go @@ -0,0 +1,164 @@ +package humanize + +import ( + "fmt" + "math/big" + "strings" + "unicode" +) + +var ( + bigIECExp = big.NewInt(1024) + + // BigByte is one byte in bit.Ints + BigByte = big.NewInt(1) + // BigKiByte is 1,024 bytes in bit.Ints + BigKiByte = (&big.Int{}).Mul(BigByte, bigIECExp) + // BigMiByte is 1,024 k bytes in bit.Ints + BigMiByte = (&big.Int{}).Mul(BigKiByte, bigIECExp) + // BigGiByte is 1,024 m bytes in bit.Ints + BigGiByte = (&big.Int{}).Mul(BigMiByte, bigIECExp) + // BigTiByte is 1,024 g bytes in bit.Ints + BigTiByte = (&big.Int{}).Mul(BigGiByte, bigIECExp) + // BigPiByte is 1,024 t bytes in bit.Ints + BigPiByte = (&big.Int{}).Mul(BigTiByte, bigIECExp) + // BigEiByte is 1,024 p bytes in bit.Ints + BigEiByte = (&big.Int{}).Mul(BigPiByte, bigIECExp) + // BigZiByte is 1,024 e bytes in bit.Ints + BigZiByte = (&big.Int{}).Mul(BigEiByte, bigIECExp) + // BigYiByte is 1,024 z bytes in bit.Ints + BigYiByte = (&big.Int{}).Mul(BigZiByte, bigIECExp) +) + +var ( + bigSIExp = big.NewInt(1000) + + // BigSIByte is one SI byte in big.Ints + BigSIByte = big.NewInt(1) + // BigKByte is 1,000 SI bytes in big.Ints + BigKByte = (&big.Int{}).Mul(BigSIByte, bigSIExp) + // BigMByte is 1,000 SI k bytes in big.Ints + BigMByte = (&big.Int{}).Mul(BigKByte, bigSIExp) + // BigGByte is 1,000 SI m bytes in big.Ints + BigGByte = (&big.Int{}).Mul(BigMByte, bigSIExp) + // BigTByte is 1,000 SI g bytes in big.Ints + BigTByte = (&big.Int{}).Mul(BigGByte, bigSIExp) + // BigPByte is 1,000 SI t bytes in big.Ints + BigPByte = (&big.Int{}).Mul(BigTByte, bigSIExp) + // BigEByte is 1,000 SI p bytes in big.Ints + BigEByte = (&big.Int{}).Mul(BigPByte, bigSIExp) + // BigZByte is 1,000 SI e bytes in big.Ints + BigZByte = (&big.Int{}).Mul(BigEByte, bigSIExp) + // BigYByte is 1,000 SI z bytes in big.Ints + BigYByte = (&big.Int{}).Mul(BigZByte, bigSIExp) +) + +var bigBytesSizeTable = map[string]*big.Int{ + "b": BigByte, + "kib": BigKiByte, + "kb": BigKByte, + "mib": BigMiByte, + "mb": BigMByte, + "gib": BigGiByte, + "gb": BigGByte, + "tib": BigTiByte, + "tb": BigTByte, + "pib": BigPiByte, + "pb": BigPByte, + "eib": BigEiByte, + "eb": BigEByte, + "zib": BigZiByte, + "zb": BigZByte, + "yib": BigYiByte, + "yb": BigYByte, + // Without suffix + "": BigByte, + "ki": BigKiByte, + "k": BigKByte, + "mi": BigMiByte, + "m": BigMByte, + "gi": BigGiByte, + "g": BigGByte, + "ti": BigTiByte, + "t": BigTByte, + "pi": BigPiByte, + "p": BigPByte, + "ei": BigEiByte, + "e": BigEByte, + "z": BigZByte, + "zi": BigZiByte, + "y": BigYByte, + "yi": BigYiByte, +} + +var ten = big.NewInt(10) + +func humanateBigBytes(s, base *big.Int, sizes []string) string { + if s.Cmp(ten) < 0 { + return fmt.Sprintf("%d B", s) + } + c := (&big.Int{}).Set(s) + val, mag := oomm(c, base, len(sizes)-1) + suffix := sizes[mag] + f := "%.0f %s" + if val < 10 { + f = "%.1f %s" + } + + return fmt.Sprintf(f, val, suffix) + +} + +// BigBytes produces a human readable representation of an SI size. +// +// See also: ParseBigBytes. +// +// BigBytes(82854982) -> 83MB +func BigBytes(s *big.Int) string { + sizes := []string{"B", "kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"} + return humanateBigBytes(s, bigSIExp, sizes) +} + +// BigIBytes produces a human readable representation of an IEC size. +// +// See also: ParseBigBytes. +// +// BigIBytes(82854982) -> 79MiB +func BigIBytes(s *big.Int) string { + sizes := []string{"B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB"} + return humanateBigBytes(s, bigIECExp, sizes) +} + +// ParseBigBytes parses a string representation of bytes into the number +// of bytes it represents. +// +// See also: BigBytes, BigIBytes. +// +// ParseBigBytes("42MB") -> 42000000, nil +// ParseBigBytes("42mib") -> 44040192, nil +func ParseBigBytes(s string) (*big.Int, error) { + lastDigit := 0 + for _, r := range s { + if !(unicode.IsDigit(r) || r == '.') { + break + } + lastDigit++ + } + + val := &big.Rat{} + _, err := fmt.Sscanf(s[:lastDigit], "%f", val) + if err != nil { + return nil, err + } + + extra := strings.ToLower(strings.TrimSpace(s[lastDigit:])) + if m, ok := bigBytesSizeTable[extra]; ok { + mv := (&big.Rat{}).SetInt(m) + val.Mul(val, mv) + rv := &big.Int{} + rv.Div(val.Num(), val.Denom()) + return rv, nil + } + + return nil, fmt.Errorf("unhandled size name: %v", extra) +} diff --git a/vendor/github.com/dustin/go-humanize/bytes.go b/vendor/github.com/dustin/go-humanize/bytes.go new file mode 100644 index 0000000..dacbb9c --- /dev/null +++ b/vendor/github.com/dustin/go-humanize/bytes.go @@ -0,0 +1,134 @@ +package humanize + +import ( + "fmt" + "math" + "strconv" + "strings" + "unicode" +) + +// IEC Sizes. +// kibis of bits +const ( + Byte = 1 << (iota * 10) + KiByte + MiByte + GiByte + TiByte + PiByte + EiByte +) + +// SI Sizes. +const ( + IByte = 1 + KByte = IByte * 1000 + MByte = KByte * 1000 + GByte = MByte * 1000 + TByte = GByte * 1000 + PByte = TByte * 1000 + EByte = PByte * 1000 +) + +var bytesSizeTable = map[string]uint64{ + "b": Byte, + "kib": KiByte, + "kb": KByte, + "mib": MiByte, + "mb": MByte, + "gib": GiByte, + "gb": GByte, + "tib": TiByte, + "tb": TByte, + "pib": PiByte, + "pb": PByte, + "eib": EiByte, + "eb": EByte, + // Without suffix + "": Byte, + "ki": KiByte, + "k": KByte, + "mi": MiByte, + "m": MByte, + "gi": GiByte, + "g": GByte, + "ti": TiByte, + "t": TByte, + "pi": PiByte, + "p": PByte, + "ei": EiByte, + "e": EByte, +} + +func logn(n, b float64) float64 { + return math.Log(n) / math.Log(b) +} + +func humanateBytes(s uint64, base float64, sizes []string) string { + if s < 10 { + return fmt.Sprintf("%d B", s) + } + e := math.Floor(logn(float64(s), base)) + suffix := sizes[int(e)] + val := math.Floor(float64(s)/math.Pow(base, e)*10+0.5) / 10 + f := "%.0f %s" + if val < 10 { + f = "%.1f %s" + } + + return fmt.Sprintf(f, val, suffix) +} + +// Bytes produces a human readable representation of an SI size. +// +// See also: ParseBytes. +// +// Bytes(82854982) -> 83MB +func Bytes(s uint64) string { + sizes := []string{"B", "kB", "MB", "GB", "TB", "PB", "EB"} + return humanateBytes(s, 1000, sizes) +} + +// IBytes produces a human readable representation of an IEC size. +// +// See also: ParseBytes. +// +// IBytes(82854982) -> 79MiB +func IBytes(s uint64) string { + sizes := []string{"B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB"} + return humanateBytes(s, 1024, sizes) +} + +// ParseBytes parses a string representation of bytes into the number +// of bytes it represents. +// +// See Also: Bytes, IBytes. +// +// ParseBytes("42MB") -> 42000000, nil +// ParseBytes("42mib") -> 44040192, nil +func ParseBytes(s string) (uint64, error) { + lastDigit := 0 + for _, r := range s { + if !(unicode.IsDigit(r) || r == '.') { + break + } + lastDigit++ + } + + f, err := strconv.ParseFloat(s[:lastDigit], 64) + if err != nil { + return 0, err + } + + extra := strings.ToLower(strings.TrimSpace(s[lastDigit:])) + if m, ok := bytesSizeTable[extra]; ok { + f *= float64(m) + if f >= math.MaxUint64 { + return 0, fmt.Errorf("too large: %v", s) + } + return uint64(f), nil + } + + return 0, fmt.Errorf("unhandled size name: %v", extra) +} diff --git a/vendor/github.com/dustin/go-humanize/comma.go b/vendor/github.com/dustin/go-humanize/comma.go new file mode 100644 index 0000000..b65ea6f --- /dev/null +++ b/vendor/github.com/dustin/go-humanize/comma.go @@ -0,0 +1,101 @@ +package humanize + +import ( + "bytes" + "math/big" + "strconv" + "strings" +) + +// Comma produces a string form of the given number in base 10 with +// commas after every three orders of magnitude. +// +// e.g. Comma(834142) -> 834,142 +func Comma(v int64) string { + sign := "" + if v < 0 { + sign = "-" + v = 0 - v + } + + parts := []string{"", "", "", "", "", "", ""} + j := len(parts) - 1 + + for v > 999 { + parts[j] = strconv.FormatInt(v%1000, 10) + switch len(parts[j]) { + case 2: + parts[j] = "0" + parts[j] + case 1: + parts[j] = "00" + parts[j] + } + v = v / 1000 + j-- + } + parts[j] = strconv.Itoa(int(v)) + return sign + strings.Join(parts[j:], ",") +} + +// Commaf produces a string form of the given number in base 10 with +// commas after every three orders of magnitude. +// +// e.g. Comma(834142.32) -> 834,142.32 +func Commaf(v float64) string { + buf := &bytes.Buffer{} + if v < 0 { + buf.Write([]byte{'-'}) + v = 0 - v + } + + comma := []byte{','} + + parts := strings.Split(strconv.FormatFloat(v, 'f', -1, 64), ".") + pos := 0 + if len(parts[0])%3 != 0 { + pos += len(parts[0]) % 3 + buf.WriteString(parts[0][:pos]) + buf.Write(comma) + } + for ; pos < len(parts[0]); pos += 3 { + buf.WriteString(parts[0][pos : pos+3]) + buf.Write(comma) + } + buf.Truncate(buf.Len() - 1) + + if len(parts) > 1 { + buf.Write([]byte{'.'}) + buf.WriteString(parts[1]) + } + return buf.String() +} + +// BigComma produces a string form of the given big.Int in base 10 +// with commas after every three orders of magnitude. +func BigComma(b *big.Int) string { + sign := "" + if b.Sign() < 0 { + sign = "-" + b.Abs(b) + } + + athousand := big.NewInt(1000) + c := (&big.Int{}).Set(b) + _, m := oom(c, athousand) + parts := make([]string, m+1) + j := len(parts) - 1 + + mod := &big.Int{} + for b.Cmp(athousand) >= 0 { + b.DivMod(b, athousand, mod) + parts[j] = strconv.FormatInt(mod.Int64(), 10) + switch len(parts[j]) { + case 2: + parts[j] = "0" + parts[j] + case 1: + parts[j] = "00" + parts[j] + } + j-- + } + parts[j] = strconv.Itoa(int(b.Int64())) + return sign + strings.Join(parts[j:], ",") +} diff --git a/vendor/github.com/dustin/go-humanize/ftoa.go b/vendor/github.com/dustin/go-humanize/ftoa.go new file mode 100644 index 0000000..c76190b --- /dev/null +++ b/vendor/github.com/dustin/go-humanize/ftoa.go @@ -0,0 +1,23 @@ +package humanize + +import "strconv" + +func stripTrailingZeros(s string) string { + offset := len(s) - 1 + for offset > 0 { + if s[offset] == '.' { + offset-- + break + } + if s[offset] != '0' { + break + } + offset-- + } + return s[:offset+1] +} + +// Ftoa converts a float to a string with no trailing zeros. +func Ftoa(num float64) string { + return stripTrailingZeros(strconv.FormatFloat(num, 'f', 6, 64)) +} diff --git a/vendor/github.com/dustin/go-humanize/humanize.go b/vendor/github.com/dustin/go-humanize/humanize.go new file mode 100644 index 0000000..a69540a --- /dev/null +++ b/vendor/github.com/dustin/go-humanize/humanize.go @@ -0,0 +1,8 @@ +/* +Package humanize converts boring ugly numbers to human-friendly strings and back. + +Durations can be turned into strings such as "3 days ago", numbers +representing sizes like 82854982 into useful strings like, "83MB" or +"79MiB" (whichever you prefer). +*/ +package humanize diff --git a/vendor/github.com/dustin/go-humanize/number.go b/vendor/github.com/dustin/go-humanize/number.go new file mode 100644 index 0000000..3214134 --- /dev/null +++ b/vendor/github.com/dustin/go-humanize/number.go @@ -0,0 +1,192 @@ +package humanize + +/* +Slightly adapted from the source to fit go-humanize. + +Author: https://github.com/gorhill +Source: https://gist.github.com/gorhill/5285193 + +*/ + +import ( + "math" + "strconv" +) + +var ( + renderFloatPrecisionMultipliers = [...]float64{ + 1, + 10, + 100, + 1000, + 10000, + 100000, + 1000000, + 10000000, + 100000000, + 1000000000, + } + + renderFloatPrecisionRounders = [...]float64{ + 0.5, + 0.05, + 0.005, + 0.0005, + 0.00005, + 0.000005, + 0.0000005, + 0.00000005, + 0.000000005, + 0.0000000005, + } +) + +// FormatFloat produces a formatted number as string based on the following user-specified criteria: +// * thousands separator +// * decimal separator +// * decimal precision +// +// Usage: s := RenderFloat(format, n) +// The format parameter tells how to render the number n. +// +// See examples: http://play.golang.org/p/LXc1Ddm1lJ +// +// Examples of format strings, given n = 12345.6789: +// "#,###.##" => "12,345.67" +// "#,###." => "12,345" +// "#,###" => "12345,678" +// "#\u202F###,##" => "12 345,68" +// "#.###,###### => 12.345,678900 +// "" (aka default format) => 12,345.67 +// +// The highest precision allowed is 9 digits after the decimal symbol. +// There is also a version for integer number, FormatInteger(), +// which is convenient for calls within template. +func FormatFloat(format string, n float64) string { + // Special cases: + // NaN = "NaN" + // +Inf = "+Infinity" + // -Inf = "-Infinity" + if math.IsNaN(n) { + return "NaN" + } + if n > math.MaxFloat64 { + return "Infinity" + } + if n < -math.MaxFloat64 { + return "-Infinity" + } + + // default format + precision := 2 + decimalStr := "." + thousandStr := "," + positiveStr := "" + negativeStr := "-" + + if len(format) > 0 { + format := []rune(format) + + // If there is an explicit format directive, + // then default values are these: + precision = 9 + thousandStr = "" + + // collect indices of meaningful formatting directives + formatIndx := []int{} + for i, char := range format { + if char != '#' && char != '0' { + formatIndx = append(formatIndx, i) + } + } + + if len(formatIndx) > 0 { + // Directive at index 0: + // Must be a '+' + // Raise an error if not the case + // index: 0123456789 + // +0.000,000 + // +000,000.0 + // +0000.00 + // +0000 + if formatIndx[0] == 0 { + if format[formatIndx[0]] != '+' { + panic("RenderFloat(): invalid positive sign directive") + } + positiveStr = "+" + formatIndx = formatIndx[1:] + } + + // Two directives: + // First is thousands separator + // Raise an error if not followed by 3-digit + // 0123456789 + // 0.000,000 + // 000,000.00 + if len(formatIndx) == 2 { + if (formatIndx[1] - formatIndx[0]) != 4 { + panic("RenderFloat(): thousands separator directive must be followed by 3 digit-specifiers") + } + thousandStr = string(format[formatIndx[0]]) + formatIndx = formatIndx[1:] + } + + // One directive: + // Directive is decimal separator + // The number of digit-specifier following the separator indicates wanted precision + // 0123456789 + // 0.00 + // 000,0000 + if len(formatIndx) == 1 { + decimalStr = string(format[formatIndx[0]]) + precision = len(format) - formatIndx[0] - 1 + } + } + } + + // generate sign part + var signStr string + if n >= 0.000000001 { + signStr = positiveStr + } else if n <= -0.000000001 { + signStr = negativeStr + n = -n + } else { + signStr = "" + n = 0.0 + } + + // split number into integer and fractional parts + intf, fracf := math.Modf(n + renderFloatPrecisionRounders[precision]) + + // generate integer part string + intStr := strconv.Itoa(int(intf)) + + // add thousand separator if required + if len(thousandStr) > 0 { + for i := len(intStr); i > 3; { + i -= 3 + intStr = intStr[:i] + thousandStr + intStr[i:] + } + } + + // no fractional part, we can leave now + if precision == 0 { + return signStr + intStr + } + + // generate fractional part + fracStr := strconv.Itoa(int(fracf * renderFloatPrecisionMultipliers[precision])) + // may need padding + if len(fracStr) < precision { + fracStr = "000000000000000"[:precision-len(fracStr)] + fracStr + } + + return signStr + intStr + decimalStr + fracStr +} + +// FormatInteger produces a formatted number as string. +// See FormatFloat. +func FormatInteger(format string, n int) string { + return FormatFloat(format, float64(n)) +} diff --git a/vendor/github.com/dustin/go-humanize/ordinals.go b/vendor/github.com/dustin/go-humanize/ordinals.go new file mode 100644 index 0000000..43d88a8 --- /dev/null +++ b/vendor/github.com/dustin/go-humanize/ordinals.go @@ -0,0 +1,25 @@ +package humanize + +import "strconv" + +// Ordinal gives you the input number in a rank/ordinal format. +// +// Ordinal(3) -> 3rd +func Ordinal(x int) string { + suffix := "th" + switch x % 10 { + case 1: + if x%100 != 11 { + suffix = "st" + } + case 2: + if x%100 != 12 { + suffix = "nd" + } + case 3: + if x%100 != 13 { + suffix = "rd" + } + } + return strconv.Itoa(x) + suffix +} diff --git a/vendor/github.com/dustin/go-humanize/si.go b/vendor/github.com/dustin/go-humanize/si.go new file mode 100644 index 0000000..fe86fe5 --- /dev/null +++ b/vendor/github.com/dustin/go-humanize/si.go @@ -0,0 +1,110 @@ +package humanize + +import ( + "errors" + "math" + "regexp" + "strconv" +) + +var siPrefixTable = map[float64]string{ + -24: "y", // yocto + -21: "z", // zepto + -18: "a", // atto + -15: "f", // femto + -12: "p", // pico + -9: "n", // nano + -6: "µ", // micro + -3: "m", // milli + 0: "", + 3: "k", // kilo + 6: "M", // mega + 9: "G", // giga + 12: "T", // tera + 15: "P", // peta + 18: "E", // exa + 21: "Z", // zetta + 24: "Y", // yotta +} + +var revSIPrefixTable = revfmap(siPrefixTable) + +// revfmap reverses the map and precomputes the power multiplier +func revfmap(in map[float64]string) map[string]float64 { + rv := map[string]float64{} + for k, v := range in { + rv[v] = math.Pow(10, k) + } + return rv +} + +var riParseRegex *regexp.Regexp + +func init() { + ri := `^([0-9.]+)\s?([` + for _, v := range siPrefixTable { + ri += v + } + ri += `]?)(.*)` + + riParseRegex = regexp.MustCompile(ri) +} + +// ComputeSI finds the most appropriate SI prefix for the given number +// and returns the prefix along with the value adjusted to be within +// that prefix. +// +// See also: SI, ParseSI. +// +// e.g. ComputeSI(2.2345e-12) -> (2.2345, "p") +func ComputeSI(input float64) (float64, string) { + if input == 0 { + return 0, "" + } + exponent := math.Floor(logn(input, 10)) + exponent = math.Floor(exponent/3) * 3 + + value := input / math.Pow(10, exponent) + + // Handle special case where value is exactly 1000.0 + // Should return 1M instead of 1000k + if value == 1000.0 { + exponent += 3 + value = input / math.Pow(10, exponent) + } + + prefix := siPrefixTable[exponent] + return value, prefix +} + +// SI returns a string with default formatting. +// +// SI uses Ftoa to format float value, removing trailing zeros. +// +// See also: ComputeSI, ParseSI. +// +// e.g. SI(1000000, B) -> 1MB +// e.g. SI(2.2345e-12, "F") -> 2.2345pF +func SI(input float64, unit string) string { + value, prefix := ComputeSI(input) + return Ftoa(value) + " " + prefix + unit +} + +var errInvalid = errors.New("invalid input") + +// ParseSI parses an SI string back into the number and unit. +// +// See also: SI, ComputeSI. +// +// e.g. ParseSI(2.2345pF) -> (2.2345e-12, "F", nil) +func ParseSI(input string) (float64, string, error) { + found := riParseRegex.FindStringSubmatch(input) + if len(found) != 4 { + return 0, "", errInvalid + } + mag := revSIPrefixTable[found[2]] + unit := found[3] + + base, err := strconv.ParseFloat(found[1], 64) + return base * mag, unit, err +} diff --git a/vendor/github.com/dustin/go-humanize/times.go b/vendor/github.com/dustin/go-humanize/times.go new file mode 100644 index 0000000..592ebe1 --- /dev/null +++ b/vendor/github.com/dustin/go-humanize/times.go @@ -0,0 +1,91 @@ +package humanize + +import ( + "fmt" + "math" + "sort" + "time" +) + +// Seconds-based time units +const ( + Minute = 60 + Hour = 60 * Minute + Day = 24 * Hour + Week = 7 * Day + Month = 30 * Day + Year = 12 * Month + LongTime = 37 * Year +) + +// Time formats a time into a relative string. +// +// Time(someT) -> "3 weeks ago" +func Time(then time.Time) string { + return RelTime(then, time.Now(), "ago", "from now") +} + +var magnitudes = []struct { + d int64 + format string + divby int64 +}{ + {1, "now", 1}, + {2, "1 second %s", 1}, + {Minute, "%d seconds %s", 1}, + {2 * Minute, "1 minute %s", 1}, + {Hour, "%d minutes %s", Minute}, + {2 * Hour, "1 hour %s", 1}, + {Day, "%d hours %s", Hour}, + {2 * Day, "1 day %s", 1}, + {Week, "%d days %s", Day}, + {2 * Week, "1 week %s", 1}, + {Month, "%d weeks %s", Week}, + {2 * Month, "1 month %s", 1}, + {Year, "%d months %s", Month}, + {18 * Month, "1 year %s", 1}, + {2 * Year, "2 years %s", 1}, + {LongTime, "%d years %s", Year}, + {math.MaxInt64, "a long while %s", 1}, +} + +// RelTime formats a time into a relative string. +// +// It takes two times and two labels. In addition to the generic time +// delta string (e.g. 5 minutes), the labels are used applied so that +// the label corresponding to the smaller time is applied. +// +// RelTime(timeInPast, timeInFuture, "earlier", "later") -> "3 weeks earlier" +func RelTime(a, b time.Time, albl, blbl string) string { + lbl := albl + diff := b.Unix() - a.Unix() + + after := a.After(b) + if after { + lbl = blbl + diff = a.Unix() - b.Unix() + } + + n := sort.Search(len(magnitudes), func(i int) bool { + return magnitudes[i].d > diff + }) + + mag := magnitudes[n] + args := []interface{}{} + escaped := false + for _, ch := range mag.format { + if escaped { + switch ch { + case '%': + case 's': + args = append(args, lbl) + case 'd': + args = append(args, diff/mag.divby) + } + escaped = false + } else { + escaped = ch == '%' + } + } + return fmt.Sprintf(mag.format, args...) +} diff --git a/vendor/github.com/eapache/go-resiliency/breaker/README.md b/vendor/github.com/eapache/go-resiliency/breaker/README.md new file mode 100644 index 0000000..2d1b3d9 --- /dev/null +++ b/vendor/github.com/eapache/go-resiliency/breaker/README.md @@ -0,0 +1,34 @@ +circuit-breaker +=============== + +[![Build Status](https://travis-ci.org/eapache/go-resiliency.svg?branch=master)](https://travis-ci.org/eapache/go-resiliency) +[![GoDoc](https://godoc.org/github.com/eapache/go-resiliency/breaker?status.svg)](https://godoc.org/github.com/eapache/go-resiliency/breaker) +[![Code of Conduct](https://img.shields.io/badge/code%20of%20conduct-active-blue.svg)](https://eapache.github.io/conduct.html) + +The circuit-breaker resiliency pattern for golang. + +Creating a breaker takes three parameters: +- error threshold (for opening the breaker) +- success threshold (for closing the breaker) +- timeout (how long to keep the breaker open) + +```go +b := breaker.New(3, 1, 5*time.Second) + +for { + result := b.Run(func() error { + // communicate with some external service and + // return an error if the communication failed + return nil + }) + + switch result { + case nil: + // success! + case breaker.ErrBreakerOpen: + // our function wasn't run because the breaker was open + default: + // some other error + } +} +``` diff --git a/vendor/github.com/eapache/go-resiliency/breaker/breaker.go b/vendor/github.com/eapache/go-resiliency/breaker/breaker.go new file mode 100644 index 0000000..f88ca72 --- /dev/null +++ b/vendor/github.com/eapache/go-resiliency/breaker/breaker.go @@ -0,0 +1,161 @@ +// Package breaker implements the circuit-breaker resiliency pattern for Go. +package breaker + +import ( + "errors" + "sync" + "sync/atomic" + "time" +) + +// ErrBreakerOpen is the error returned from Run() when the function is not executed +// because the breaker is currently open. +var ErrBreakerOpen = errors.New("circuit breaker is open") + +const ( + closed uint32 = iota + open + halfOpen +) + +// Breaker implements the circuit-breaker resiliency pattern +type Breaker struct { + errorThreshold, successThreshold int + timeout time.Duration + + lock sync.Mutex + state uint32 + errors, successes int + lastError time.Time +} + +// New constructs a new circuit-breaker that starts closed. +// From closed, the breaker opens if "errorThreshold" errors are seen +// without an error-free period of at least "timeout". From open, the +// breaker half-closes after "timeout". From half-open, the breaker closes +// after "successThreshold" consecutive successes, or opens on a single error. +func New(errorThreshold, successThreshold int, timeout time.Duration) *Breaker { + return &Breaker{ + errorThreshold: errorThreshold, + successThreshold: successThreshold, + timeout: timeout, + } +} + +// Run will either return ErrBreakerOpen immediately if the circuit-breaker is +// already open, or it will run the given function and pass along its return +// value. It is safe to call Run concurrently on the same Breaker. +func (b *Breaker) Run(work func() error) error { + state := atomic.LoadUint32(&b.state) + + if state == open { + return ErrBreakerOpen + } + + return b.doWork(state, work) +} + +// Go will either return ErrBreakerOpen immediately if the circuit-breaker is +// already open, or it will run the given function in a separate goroutine. +// If the function is run, Go will return nil immediately, and will *not* return +// the return value of the function. It is safe to call Go concurrently on the +// same Breaker. +func (b *Breaker) Go(work func() error) error { + state := atomic.LoadUint32(&b.state) + + if state == open { + return ErrBreakerOpen + } + + // errcheck complains about ignoring the error return value, but + // that's on purpose; if you want an error from a goroutine you have to + // get it over a channel or something + go b.doWork(state, work) + + return nil +} + +func (b *Breaker) doWork(state uint32, work func() error) error { + var panicValue interface{} + + result := func() error { + defer func() { + panicValue = recover() + }() + return work() + }() + + if result == nil && panicValue == nil && state == closed { + // short-circuit the normal, success path without contending + // on the lock + return nil + } + + // oh well, I guess we have to contend on the lock + b.processResult(result, panicValue) + + if panicValue != nil { + // as close as Go lets us come to a "rethrow" although unfortunately + // we lose the original panicing location + panic(panicValue) + } + + return result +} + +func (b *Breaker) processResult(result error, panicValue interface{}) { + b.lock.Lock() + defer b.lock.Unlock() + + if result == nil && panicValue == nil { + if b.state == halfOpen { + b.successes++ + if b.successes == b.successThreshold { + b.closeBreaker() + } + } + } else { + if b.errors > 0 { + expiry := b.lastError.Add(b.timeout) + if time.Now().After(expiry) { + b.errors = 0 + } + } + + switch b.state { + case closed: + b.errors++ + if b.errors == b.errorThreshold { + b.openBreaker() + } else { + b.lastError = time.Now() + } + case halfOpen: + b.openBreaker() + } + } +} + +func (b *Breaker) openBreaker() { + b.changeState(open) + go b.timer() +} + +func (b *Breaker) closeBreaker() { + b.changeState(closed) +} + +func (b *Breaker) timer() { + time.Sleep(b.timeout) + + b.lock.Lock() + defer b.lock.Unlock() + + b.changeState(halfOpen) +} + +func (b *Breaker) changeState(newState uint32) { + b.errors = 0 + b.successes = 0 + atomic.StoreUint32(&b.state, newState) +} diff --git a/vendor/github.com/eapache/queue/.gitignore b/vendor/github.com/eapache/queue/.gitignore new file mode 100644 index 0000000..8365624 --- /dev/null +++ b/vendor/github.com/eapache/queue/.gitignore @@ -0,0 +1,23 @@ +# 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 +*.test diff --git a/vendor/github.com/eapache/queue/.travis.yml b/vendor/github.com/eapache/queue/.travis.yml new file mode 100644 index 0000000..235a40a --- /dev/null +++ b/vendor/github.com/eapache/queue/.travis.yml @@ -0,0 +1,7 @@ +language: go +sudo: false + +go: + - 1.2 + - 1.3 + - 1.4 diff --git a/vendor/github.com/eapache/queue/LICENSE b/vendor/github.com/eapache/queue/LICENSE new file mode 100644 index 0000000..d5f36db --- /dev/null +++ b/vendor/github.com/eapache/queue/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014 Evan Huus + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/vendor/github.com/eapache/queue/README.md b/vendor/github.com/eapache/queue/README.md new file mode 100644 index 0000000..8e78233 --- /dev/null +++ b/vendor/github.com/eapache/queue/README.md @@ -0,0 +1,16 @@ +Queue +===== + +[![Build Status](https://travis-ci.org/eapache/queue.svg)](https://travis-ci.org/eapache/queue) +[![GoDoc](https://godoc.org/github.com/eapache/queue?status.png)](https://godoc.org/github.com/eapache/queue) +[![Code of Conduct](https://img.shields.io/badge/code%20of%20conduct-active-blue.svg)](https://eapache.github.io/conduct.html) + +A fast Golang queue using a ring-buffer, based on the version suggested by Dariusz Górecki. +Using this instead of other, simpler, queue implementations (slice+append or linked list) provides +substantial memory and time benefits, and fewer GC pauses. + +The queue implemented here is as fast as it is in part because it is *not* thread-safe. + +Follows semantic versioning using https://gopkg.in/ - import from +[`gopkg.in/eapache/queue.v1`](https://gopkg.in/eapache/queue.v1) +for guaranteed API stability. diff --git a/vendor/github.com/eapache/queue/queue.go b/vendor/github.com/eapache/queue/queue.go new file mode 100644 index 0000000..2dc8d93 --- /dev/null +++ b/vendor/github.com/eapache/queue/queue.go @@ -0,0 +1,88 @@ +/* +Package queue provides a fast, ring-buffer queue based on the version suggested by Dariusz Górecki. +Using this instead of other, simpler, queue implementations (slice+append or linked list) provides +substantial memory and time benefits, and fewer GC pauses. + +The queue implemented here is as fast as it is for an additional reason: it is *not* thread-safe. +*/ +package queue + +const minQueueLen = 16 + +// Queue represents a single instance of the queue data structure. +type Queue struct { + buf []interface{} + head, tail, count int +} + +// New constructs and returns a new Queue. +func New() *Queue { + return &Queue{ + buf: make([]interface{}, minQueueLen), + } +} + +// Length returns the number of elements currently stored in the queue. +func (q *Queue) Length() int { + return q.count +} + +// resizes the queue to fit exactly twice its current contents +// this can result in shrinking if the queue is less than half-full +func (q *Queue) resize() { + newBuf := make([]interface{}, q.count*2) + + if q.tail > q.head { + copy(newBuf, q.buf[q.head:q.tail]) + } else { + n := copy(newBuf, q.buf[q.head:]) + copy(newBuf[n:], q.buf[:q.tail]) + } + + q.head = 0 + q.tail = q.count + q.buf = newBuf +} + +// Add puts an element on the end of the queue. +func (q *Queue) Add(elem interface{}) { + if q.count == len(q.buf) { + q.resize() + } + + q.buf[q.tail] = elem + q.tail = (q.tail + 1) % len(q.buf) + q.count++ +} + +// Peek returns the element at the head of the queue. This call panics +// if the queue is empty. +func (q *Queue) Peek() interface{} { + if q.count <= 0 { + panic("queue: Peek() called on empty queue") + } + return q.buf[q.head] +} + +// Get returns the element at index i in the queue. If the index is +// invalid, the call will panic. +func (q *Queue) Get(i int) interface{} { + if i < 0 || i >= q.count { + panic("queue: Get() called with index out of range") + } + return q.buf[(q.head+i)%len(q.buf)] +} + +// Remove removes the element from the front of the queue. If you actually +// want the element, call Peek first. This call panics if the queue is empty. +func (q *Queue) Remove() { + if q.count <= 0 { + panic("queue: Remove() called on empty queue") + } + q.buf[q.head] = nil + q.head = (q.head + 1) % len(q.buf) + q.count-- + if len(q.buf) > minQueueLen && q.count*4 == len(q.buf) { + q.resize() + } +} diff --git a/vendor/github.com/elastic/beats/libbeat/beat/beat.go b/vendor/github.com/elastic/beats/libbeat/beat/beat.go new file mode 100644 index 0000000..9ab50c4 --- /dev/null +++ b/vendor/github.com/elastic/beats/libbeat/beat/beat.go @@ -0,0 +1,324 @@ +/* + +Package beat provides the basic environment for each beat. + +Each beat implementation has to implement the beater interface. + + +# Start / Stop / Exit a Beat + +A beat is start by calling the Run(name string, version string, bt Beater) function and passing the beater object. +This will create new beat and will Start the beat in its own go process. The Run function is blocked until +the Beat.exit channel is closed. This can be done through calling Beat.Exit(). This happens for example when CTRL-C +is pressed. + +A beat can be stopped and started again through beat.Stop and beat.Start. When starting a beat again, it is important to +run it again in it's own go process. To allow a beat to be properly reastarted, it is important that Beater.Stop() properly +closes all channels and go processes. + +In case a beat should not run as a long running process, the beater implementation must make sure to call Beat.Exit() +when the task is completed to stop the beat. + +*/ +package beat + +import ( + "flag" + "fmt" + "runtime" + "sync" + + "github.com/satori/go.uuid" + + "github.com/elastic/beats/libbeat/cfgfile" + "github.com/elastic/beats/libbeat/logp" + "github.com/elastic/beats/libbeat/outputs" + "github.com/elastic/beats/libbeat/publisher" + "github.com/elastic/beats/libbeat/service" +) + +// Beater interface that every beat must use +type Beater interface { + Config(*Beat) error + Setup(*Beat) error + Run(*Beat) error + Cleanup(*Beat) error + Stop() +} + +// FlagsHandler (optional) Beater extension for +// handling flags input on startup. The HandleFlags callback will +// be called after parsing the command line arguments and handling +// the '--help' or '--version' flags. +type FlagsHandler interface { + HandleFlags(*Beat) +} + +// Beat struct contains the basic beat information +type Beat struct { + Name string + Version string + Config *BeatConfig + BT Beater + Publisher *publisher.PublisherType + Events publisher.Client + UUID uuid.UUID + + exit chan struct{} + error error + state int8 + stateMutex sync.Mutex + callback sync.Once +} + +// Defaults for config variables which are not set +const ( + StopState = 0 + ConfigState = 1 + SetupState = 2 + RunState = 3 +) + +// BeatConfig struct contains the basic configuration of every beat +type BeatConfig struct { + Output map[string]outputs.MothershipConfig + Logging logp.Logging + Shipper publisher.ShipperConfig +} + +var printVersion *bool + +// Channel that is closed as soon as the beat should exit +func init() { + printVersion = flag.Bool("version", false, "Print version and exit") +} + +// NewBeat initiates a new beat object +func NewBeat(name string, version string, bt Beater) *Beat { + if version == "" { + version = defaultBeatVersion + } + b := Beat{ + Version: version, + Name: name, + BT: bt, + UUID: uuid.NewV4(), + + exit: make(chan struct{}), + state: StopState, + } + + return &b +} + +// Run initiates and runs a new beat object +func Run(name string, version string, bt Beater) error { + + b := NewBeat(name, version, bt) + + // Runs beat inside a go process + go func() { + err := b.Start() + + if err != nil { + // TODO: detect if logging was already fully setup or not + fmt.Printf("Start error: %v\n", err) + logp.Critical("Start error: %v", err) + b.error = err + } + + // If start finishes, exit has to be called. This requires start to be blocking + // which is currently the default. + b.Exit() + }() + + // Waits until beats channel is closed + select { + case <-b.exit: + b.Stop() + logp.Info("Exit beat completed") + return b.error + } +} + +// Start starts the Beat by parsing and interpreting the command line flags, +// loading and parsing the configuration file, and running the Beat. This +// method blocks until the Beat exits. If an error occurs while initializing +// or running the Beat it will be returned. +func (b *Beat) Start() error { + // Additional command line args are used to overwrite config options + err, exit := b.CommandLineSetup() + if err != nil { + return err + } + + if exit { + return nil + } + + // Loads base config + err = b.LoadConfig() + if err != nil { + return err + } + + // Configures beat + err = b.BT.Config(b) + if err != nil { + return err + } + b.setState(ConfigState) + + // Run beat. This calls first beater.Setup, + // then beater.Run and beater.Cleanup in the end + return b.Run() +} + +// CommandLineSetup reads and parses the default command line params +// To set additional cmd line args use the beat.CmdLine type before calling the function +// The second return param is to detect if system should exit. True if should exit +// Exit can also be without error +func (beat *Beat) CommandLineSetup() (error, bool) { + + // The -c flag is treated separately because it needs the Beat name + err := cfgfile.ChangeDefaultCfgfileFlag(beat.Name) + if err != nil { + return fmt.Errorf("failed to fix the -c flag: %v\n", err), true + } + + flag.Parse() + + if *printVersion { + fmt.Printf("%s version %s (%s)\n", beat.Name, beat.Version, runtime.GOARCH) + return nil, true + } + + // if beater implements CLIFlags for additional CLI handling, call it now + if flagsHandler, ok := beat.BT.(FlagsHandler); ok { + flagsHandler.HandleFlags(beat) + } + + return nil, false +} + +// LoadConfig inits the config file and reads the default config information +// into Beat.Config. It exists the processes in case of errors. +func (b *Beat) LoadConfig() error { + + err := cfgfile.Read(&b.Config, "") + if err != nil { + return fmt.Errorf("loading config file error: %v\n", err) + } + + err = logp.Init(b.Name, &b.Config.Logging) + if err != nil { + return fmt.Errorf("error initializing logging: %v\n", err) + } + + // Disable stderr logging if requested by cmdline flag + logp.SetStderr() + + logp.Debug("beat", "Initializing output plugins") + + if b.Config.Shipper.MaxProcs != nil { + maxProcs := *b.Config.Shipper.MaxProcs + if maxProcs > 0 { + runtime.GOMAXPROCS(maxProcs) + } + } + + pub, err := publisher.New(b.Name, b.Config.Output, b.Config.Shipper) + if err != nil { + return fmt.Errorf("error Initialising publisher: %v\n", err) + } + + b.Publisher = pub + b.Events = pub.Client() + + logp.Info("Init Beat: %s; Version: %s", b.Name, b.Version) + + return nil +} + +// Run calls the beater Setup and Run methods. In case of errors +// during the setup phase, it exits the process. +func (b *Beat) Run() error { + + // Setup beater object + err := b.BT.Setup(b) + if err != nil { + return fmt.Errorf("setup returned an error: %v", err) + } + b.setState(SetupState) + + // Up to here was the initialization, now about running + if cfgfile.IsTestConfig() { + logp.Info("Testing configuration file") + // all good, exit + return nil + } + service.BeforeRun() + + // Callback is called if the processes is asked to stop. + // This needs to be called before the main loop is started so that + // it can register the signals that stop or query (on Windows) the loop. + service.HandleSignals(b.Exit) + + logp.Info("%s sucessfully setup. Start running.", b.Name) + + b.setState(RunState) + // Run beater specific stuff + err = b.BT.Run(b) + if err != nil { + logp.Critical("Running the beat returned an error: %v", err) + } + + return err +} + +// Stop calls the beater Stop action. +// It can happen that this function is called more then once. +func (b *Beat) Stop() { + logp.Info("Stopping Beat") + + if b.getState() == RunState { + b.BT.Stop() + } + + service.Cleanup() + + logp.Info("Cleaning up %s before shutting down.", b.Name) + + if b.getState() > StopState { + // Call beater cleanup function + err := b.BT.Cleanup(b) + if err != nil { + logp.Err("Cleanup returned an error: %v", err) + } + } + + b.setState(StopState) +} + +// Exit begins exiting the beat and initiating shutdown +func (b *Beat) Exit() { + + b.callback.Do(func() { + logp.Info("Start exiting beat") + close(b.exit) + }) +} + +// setState updates the state +func (b *Beat) setState(state int8) { + b.stateMutex.Lock() + defer b.stateMutex.Unlock() + b.state = state +} + +// getState fetches the state +func (b *Beat) getState() int8 { + b.stateMutex.Lock() + defer b.stateMutex.Unlock() + return b.state +} diff --git a/vendor/github.com/elastic/beats/libbeat/beat/version.go b/vendor/github.com/elastic/beats/libbeat/beat/version.go new file mode 100644 index 0000000..c1897f9 --- /dev/null +++ b/vendor/github.com/elastic/beats/libbeat/beat/version.go @@ -0,0 +1,3 @@ +package beat + +const defaultBeatVersion = "1.2.0-SNAPSHOT" diff --git a/vendor/github.com/elastic/beats/libbeat/cfgfile/cfgfile.go b/vendor/github.com/elastic/beats/libbeat/cfgfile/cfgfile.go new file mode 100644 index 0000000..51c9baa --- /dev/null +++ b/vendor/github.com/elastic/beats/libbeat/cfgfile/cfgfile.go @@ -0,0 +1,93 @@ +package cfgfile + +import ( + "flag" + "fmt" + "io/ioutil" + "os" + "path/filepath" + "strings" + + "github.com/elastic/beats/libbeat/logp" + "gopkg.in/yaml.v2" +) + +// Command line flags +var configfile *string +var testConfig *bool + +func init() { + // The default config cannot include the beat name as it is not initialised when this + // function is called, but see ChangeDefaultCfgfileFlag + configfile = flag.String("c", "beat.yml", "Configuration file") + testConfig = flag.Bool("configtest", false, "Test configuration and exit.") +} + +// ChangeDefaultCfgfileFlag replaces the value and default value for the `-c` flag so that +// it reflects the beat name. +func ChangeDefaultCfgfileFlag(beatName string) error { + cliflag := flag.Lookup("c") + if cliflag == nil { + return fmt.Errorf("Flag -c not found") + } + + path, err := filepath.Abs(filepath.Dir(os.Args[0])) + if err != nil { + return fmt.Errorf("Failed to set default config file location because the absolute path to %s could not be obtained. %v", os.Args[0], err) + } + + cliflag.DefValue = filepath.Join(path, beatName+".yml") + + return cliflag.Value.Set(cliflag.DefValue) +} + +// Read reads the configuration from a yaml file into the given interface structure. +// In case path is not set this method reads from the default configuration file for the beat. +func Read(out interface{}, path string) error { + + if path == "" { + path = *configfile + } + + filecontent, err := ioutil.ReadFile(path) + if err != nil { + return fmt.Errorf("Failed to read %s: %v. Exiting.", path, err) + } + + filecontent = expandEnv(filecontent) + + if err = yaml.Unmarshal(filecontent, out); err != nil { + return fmt.Errorf("YAML config parsing failed on %s: %v. Exiting", path, err) + } + + return nil +} + +// IsTestConfig returns whether or not this is configuration used for testing +func IsTestConfig() bool { + return *testConfig +} + +// expandEnv replaces ${var} or $var in config according to the values of the +// current environment variables. The replacement is case-sensitive. References +// to undefined variables are replaced by the empty string. A default value +// can be given by using the form ${var:default value}. +func expandEnv(config []byte) []byte { + return []byte(os.Expand(string(config), func(key string) string { + keyAndDefault := strings.SplitN(key, ":", 2) + key = keyAndDefault[0] + + v := os.Getenv(key) + if v == "" && len(keyAndDefault) == 2 { + // Set value to the default. + v = keyAndDefault[1] + logp.Info("Replacing config environment variable '${%s}' with "+ + "default '%s'", key, keyAndDefault[1]) + } else { + logp.Info("Replacing config environment variable '${%s}' with '%s'", + key, v) + } + + return v + })) +} diff --git a/vendor/github.com/elastic/beats/libbeat/common/bytes.go b/vendor/github.com/elastic/beats/libbeat/common/bytes.go new file mode 100644 index 0000000..c8be0c5 --- /dev/null +++ b/vendor/github.com/elastic/beats/libbeat/common/bytes.go @@ -0,0 +1,48 @@ +package common + +import ( + "bytes" + "errors" + "fmt" +) + +// Byte order utilities + +func Bytes_Ntohs(b []byte) uint16 { + return uint16(b[0])<<8 | uint16(b[1]) +} + +func Bytes_Ntohl(b []byte) uint32 { + return uint32(b[0])<<24 | uint32(b[1])<<16 | + uint32(b[2])<<8 | uint32(b[3]) +} + +func Bytes_Htohl(b []byte) uint32 { + return uint32(b[3])<<24 | uint32(b[2])<<16 | + uint32(b[1])<<8 | uint32(b[0]) +} + +func Bytes_Ntohll(b []byte) uint64 { + return uint64(b[0])<<56 | uint64(b[1])<<48 | + uint64(b[2])<<40 | uint64(b[3])<<32 | + uint64(b[4])<<24 | uint64(b[5])<<16 | + uint64(b[6])<<8 | uint64(b[7]) +} + +// Ipv4_Ntoa transforms an IP4 address in it's dotted notation +func Ipv4_Ntoa(ip uint32) string { + return fmt.Sprintf("%d.%d.%d.%d", + byte(ip>>24), byte(ip>>16), + byte(ip>>8), byte(ip)) +} + +// ReadString extracts the first null terminated string from +// a slice of bytes. +func ReadString(s []byte) (string, error) { + i := bytes.IndexByte(s, 0) + if i < 0 { + return "", errors.New("No string found") + } + res := string(s[:i]) + return res, nil +} diff --git a/vendor/github.com/elastic/beats/libbeat/common/cache.go b/vendor/github.com/elastic/beats/libbeat/common/cache.go new file mode 100644 index 0000000..526a15a --- /dev/null +++ b/vendor/github.com/elastic/beats/libbeat/common/cache.go @@ -0,0 +1,260 @@ +package common + +import ( + "sync" + "time" +) + +// Key type used in the cache. +type Key interface{} + +// Value type held in the cache. Cannot be nil. +type Value interface{} + +// RemovalListener is the callback function type that can be registered with +// the cache to receive notification of the removal of expired elements. +type RemovalListener func(k Key, v Value) + +// Clock is the function type used to get the current time. +type clock func() time.Time + +// element represents an element stored in the cache. +type element struct { + expiration time.Time + timeout time.Duration + value Value +} + +// IsExpired returns true if the element is expired (current time is greater +// than the expiration time). +func (e *element) IsExpired(now time.Time) bool { + return now.After(e.expiration) +} + +// UpdateLastAccessTime updates the expiration time of the element. This +// should be called each time the element is accessed. +func (e *element) UpdateLastAccessTime(now time.Time, expiration time.Duration) { + e.expiration = now.Add(expiration) +} + +// Cache is a semi-persistent mapping of keys to values. Elements added to the +// cache are store until they are explicitly deleted or are expired due time- +// based eviction based on last access time. +// +// Expired elements are not visible through classes methods, but they do remain +// stored in the cache until CleanUp() is invoked. Therefore CleanUp() must be +// invoked periodically to prevent the cache from becoming a memory leak. If +// you want to start a goroutine to perform periodic clean-up then see +// StartJanitor(). +// +// Cache does not support storing nil values. Any attempt to put nil into +// the cache will cause a panic. +type Cache struct { + sync.RWMutex + timeout time.Duration // Length of time before cache elements expire. + elements map[Key]*element // Data stored by the cache. + clock clock // Function used to get the current time. + listener RemovalListener // Callback listen to notify of evictions. + janitorQuit chan struct{} // Closing this channel stop the janitor. +} + +// NewCache creates and returns a new Cache. d is the length of time after last +// access that cache elements expire. initialSize is the initial allocation size +// used for the Cache's underlying map. +func NewCache(d time.Duration, initialSize int) *Cache { + return newCache(d, initialSize, nil, time.Now) +} + +// NewCacheWithRemovalListener creates and returns a new Cache and register a +// RemovalListener callback function. d is the length of time after last access +// that cache elements expire. initialSize is the initial allocation size used +// for the Cache's underlying map. l is the callback function that will be +// invoked when cache elements are removed from the map on CleanUp. +func NewCacheWithRemovalListener(d time.Duration, initialSize int, l RemovalListener) *Cache { + return newCache(d, initialSize, l, time.Now) +} + +func newCache(d time.Duration, initialSize int, l RemovalListener, t clock) *Cache { + return &Cache{ + timeout: d, + elements: make(map[Key]*element, initialSize), + listener: l, + clock: t, + } +} + +// PutIfAbsent writes the given key and value to the cache only if the key is +// absent from the cache. Nil is returned if the key-value pair were written, +// otherwise the old value is returned. +func (c *Cache) PutIfAbsent(k Key, v Value) Value { + return c.PutIfAbsentWithTimeout(k, v, 0) +} + +// PutIfAbsentWithTimeout writes the given key and value to the cache only if +// the key is absent from the cache. Nil is returned if the key-value pair were +// written, otherwise the old value is returned. +// The cache expiration time will be overwritten by timeout of the key being +// inserted. +func (c *Cache) PutIfAbsentWithTimeout(k Key, v Value, timeout time.Duration) Value { + c.Lock() + defer c.Unlock() + oldValue, exists := c.get(k) + if exists { + return oldValue + } + + c.put(k, v, timeout) + return nil +} + +// Put writes the given key and value to the map replacing any existing value +// if it exists. The previous value associated with the key returned or nil +// if the key was not present. +func (c *Cache) Put(k Key, v Value) Value { + return c.PutWithTimeout(k, v, 0) +} + +// PutWithTimeout writes the given key and value to the map replacing any +// existing value if it exists. The previous value associated with the key +// returned or nil if the key was not present. +// The cache expiration time will be overwritten by timeout of the key being +// inserted. +func (c *Cache) PutWithTimeout(k Key, v Value, timeout time.Duration) Value { + c.Lock() + defer c.Unlock() + oldValue, _ := c.get(k) + c.put(k, v, timeout) + return oldValue +} + +// Replace overwrites the value for a key only if the key exists. The old +// value is returned if the value is updated, otherwise nil is returned. +func (c *Cache) Replace(k Key, v Value) Value { + return c.ReplaceWithTimeout(k, v, 0) +} + +// ReplaceWithTimeout overwrites the value for a key only if the key exists. The +// old value is returned if the value is updated, otherwise nil is returned. +// The cache expiration time will be overwritten by timeout of the key being +// inserted. +func (c *Cache) ReplaceWithTimeout(k Key, v Value, timeout time.Duration) Value { + c.Lock() + defer c.Unlock() + oldValue, exists := c.get(k) + if !exists { + return nil + } + + c.put(k, v, timeout) + return oldValue +} + +// Get the current value associated with a key or nil if the key is not +// present. The last access time of the element is updated. +func (c *Cache) Get(k Key) Value { + c.RLock() + defer c.RUnlock() + v, _ := c.get(k) + return v +} + +// Delete a key from the map and return the value or nil if the key does +// not exist. The RemovalListener is not notified for explicit deletions. +func (c *Cache) Delete(k Key) Value { + c.Lock() + defer c.Unlock() + v, _ := c.get(k) + delete(c.elements, k) + return v +} + +// CleanUp performs maintenance on the cache by removing expired elements from +// the cache. If a RemoveListener is registered it will be invoked for each +// element that is removed during this clean up operation. The RemovalListener +// is invoked on the caller's goroutine. +func (c *Cache) CleanUp() int { + c.Lock() + defer c.Unlock() + count := 0 + for k, v := range c.elements { + if v.IsExpired(c.clock()) { + delete(c.elements, k) + count++ + if c.listener != nil { + c.listener(k, v.value) + } + } + } + return count +} + +// Entries returns a copy of the non-expired elements in the cache. +func (c *Cache) Entries() map[Key]Value { + c.RLock() + defer c.RUnlock() + copy := make(map[Key]Value, len(c.elements)) + for k, v := range c.elements { + if !v.IsExpired(c.clock()) { + copy[k] = v.value + } + } + return copy +} + +// Size returns the number of elements in the cache. The number includes both +// active elements and expired elements that have not been cleaned up. +func (c *Cache) Size() int { + c.RLock() + defer c.RUnlock() + return len(c.elements) +} + +// StartJanitor starts a goroutine that will periodically invoke the cache's +// CleanUp() method. +func (c *Cache) StartJanitor(interval time.Duration) { + ticker := time.NewTicker(interval) + c.janitorQuit = make(chan struct{}) + go func() { + for { + select { + case <-ticker.C: + c.CleanUp() + case <-c.janitorQuit: + ticker.Stop() + return + } + } + }() +} + +// StopJanitor stops the goroutine created by StartJanitor. +func (c *Cache) StopJanitor() { + close(c.janitorQuit) +} + +// get returns the non-expired values from the cache. +func (c *Cache) get(k Key) (Value, bool) { + elem, exists := c.elements[k] + now := c.clock() + if exists && !elem.IsExpired(now) { + elem.UpdateLastAccessTime(now, elem.timeout) + return elem.value, true + } + return nil, false +} + +// put writes a key-value to the cache replacing any existing mapping. +func (c *Cache) put(k Key, v Value, timeout time.Duration) { + if v == nil { + panic("Cache does not support storing nil values.") + } + + if timeout <= 0 { + timeout = c.timeout + } + c.elements[k] = &element{ + expiration: c.clock().Add(timeout), + timeout: timeout, + value: v, + } +} diff --git a/vendor/github.com/elastic/beats/libbeat/common/csv.go b/vendor/github.com/elastic/beats/libbeat/common/csv.go new file mode 100644 index 0000000..5f7a2c4 --- /dev/null +++ b/vendor/github.com/elastic/beats/libbeat/common/csv.go @@ -0,0 +1,35 @@ +package common + +import ( + "bytes" + "encoding/csv" + "strings" +) + +// DumpInCSVFormat takes a set of fields and rows and returns a string +// representing the CSV representation for the fields and rows. +func DumpInCSVFormat(fields []string, rows [][]string) string { + + var buf bytes.Buffer + writer := csv.NewWriter(&buf) + + for i, field := range fields { + fields[i] = strings.Replace(field, "\n", "\\n", -1) + } + if len(fields) > 0 { + writer.Write(fields) + } + + for _, row := range rows { + for i, field := range row { + field = strings.Replace(field, "\n", "\\n", -1) + field = strings.Replace(field, "\r", "\\r", -1) + row[i] = field + } + writer.Write(row) + } + writer.Flush() + + csv := buf.String() + return csv +} diff --git a/vendor/github.com/elastic/beats/libbeat/common/datetime.go b/vendor/github.com/elastic/beats/libbeat/common/datetime.go new file mode 100644 index 0000000..7c5010d --- /dev/null +++ b/vendor/github.com/elastic/beats/libbeat/common/datetime.go @@ -0,0 +1,47 @@ +package common + +import ( + "encoding/json" + "errors" + "time" +) + +// TsLayout is the layout to be used in the timestamp marshaling/unmarshaling everywhere. +// The timezone must always be UTC. +const TsLayout = "2006-01-02T15:04:05.000Z" + +// Time is an abstraction for the time.Time type +type Time time.Time + +// MarshalJSON implements json.Marshaler interface. +// The time is a quoted string in the JsTsLayout format. +func (t Time) MarshalJSON() ([]byte, error) { + return json.Marshal(time.Time(t).UTC().Format(TsLayout)) +} + +// UnmarshalJSON implements js.Unmarshaler interface. +// The time is expected to be a quoted string in TsLayout +// format. +func (t *Time) UnmarshalJSON(data []byte) (err error) { + if data[0] != []byte(`"`)[0] || data[len(data)-1] != []byte(`"`)[0] { + return errors.New("Not quoted") + } + *t, err = ParseTime(string(data[1 : len(data)-1])) + return +} + +// ParseTime parses a time in the TsLayout format. +func ParseTime(timespec string) (Time, error) { + t, err := time.Parse(TsLayout, timespec) + return Time(t), err +} + +// MustParseTime is a convenience equivalent of the ParseTime function +// that panics in case of errors. +func MustParseTime(timespec string) Time { + ts, err := ParseTime(timespec) + if err != nil { + panic(err) + } + return ts +} diff --git a/vendor/github.com/elastic/beats/libbeat/common/droppriv/droppriv_unix.go b/vendor/github.com/elastic/beats/libbeat/common/droppriv/droppriv_unix.go new file mode 100644 index 0000000..b147cda --- /dev/null +++ b/vendor/github.com/elastic/beats/libbeat/common/droppriv/droppriv_unix.go @@ -0,0 +1,41 @@ +// +build !windows + +package droppriv + +import ( + "errors" + "fmt" + "syscall" + + "github.com/elastic/beats/libbeat/logp" +) + +type RunOptions struct { + Uid *int + Gid *int +} + +func DropPrivileges(config RunOptions) error { + var err error + + if config.Uid == nil { + // not found, no dropping privileges but no err + return nil + } + + if config.Gid == nil { + return errors.New("GID must be specified for dropping privileges") + } + + logp.Info("Switching to user: %d.%d", config.Uid, config.Gid) + + if err = syscall.Setgid(*config.Gid); err != nil { + return fmt.Errorf("setgid: %s", err.Error()) + } + + if err = syscall.Setuid(*config.Uid); err != nil { + return fmt.Errorf("setuid: %s", err.Error()) + } + + return nil +} diff --git a/vendor/github.com/elastic/beats/libbeat/common/droppriv/droppriv_windows.go b/vendor/github.com/elastic/beats/libbeat/common/droppriv/droppriv_windows.go new file mode 100644 index 0000000..136c80e --- /dev/null +++ b/vendor/github.com/elastic/beats/libbeat/common/droppriv/droppriv_windows.go @@ -0,0 +1,18 @@ +package droppriv + +import "errors" + +type RunOptions struct { + Uid *int + Gid *int +} + +func DropPrivileges(config RunOptions) error { + + if config.Uid == nil { + // not found, no dropping privileges but no err + return nil + } + + return errors.New("Dropping privileges is not supported on Windows") +} diff --git a/vendor/github.com/elastic/beats/libbeat/common/endpoint.go b/vendor/github.com/elastic/beats/libbeat/common/endpoint.go new file mode 100644 index 0000000..622f85c --- /dev/null +++ b/vendor/github.com/elastic/beats/libbeat/common/endpoint.go @@ -0,0 +1,10 @@ +package common + +// Endpoint represents an endpoint in the communication. +type Endpoint struct { + Ip string + Port uint16 + Name string + Cmdline string + Proc string +} diff --git a/vendor/github.com/elastic/beats/libbeat/common/geolite.go b/vendor/github.com/elastic/beats/libbeat/common/geolite.go new file mode 100644 index 0000000..95d1a8a --- /dev/null +++ b/vendor/github.com/elastic/beats/libbeat/common/geolite.go @@ -0,0 +1,63 @@ +package common + +import ( + "os" + "path/filepath" + + "github.com/elastic/beats/libbeat/logp" + + "github.com/nranchev/go-libGeoIP" +) + +// Geoip represents a string slice of GeoIP paths +type Geoip struct { + Paths *[]string +} + +func LoadGeoIPData(config Geoip) *libgeo.GeoIP { + geoipPaths := []string{} + + if config.Paths != nil { + geoipPaths = *config.Paths + } + if len(geoipPaths) == 0 { + logp.Info("GeoIP disabled: No paths were set under shipper.geoip.paths") + // disabled + return nil + } + + // look for the first existing path + var geoipPath string + for _, path := range geoipPaths { + fi, err := os.Lstat(path) + if err != nil { + logp.Err("GeoIP path could not be loaded: %s", path) + continue + } + + if fi.Mode()&os.ModeSymlink == os.ModeSymlink { + // follow symlink + geoipPath, err = filepath.EvalSymlinks(path) + if err != nil { + logp.Warn("Could not load GeoIP data: %s", err.Error()) + return nil + } + } else { + geoipPath = path + } + break + } + + if len(geoipPath) == 0 { + logp.Warn("Couldn't load GeoIP database") + return nil + } + + geoLite, err := libgeo.Load(geoipPath) + if err != nil { + logp.Warn("Could not load GeoIP data: %s", err.Error()) + } + + logp.Info("Loaded GeoIP data from: %s", geoipPath) + return geoLite +} diff --git a/vendor/github.com/elastic/beats/libbeat/common/mapstr.go b/vendor/github.com/elastic/beats/libbeat/common/mapstr.go new file mode 100644 index 0000000..81530b0 --- /dev/null +++ b/vendor/github.com/elastic/beats/libbeat/common/mapstr.go @@ -0,0 +1,136 @@ +package common + +import ( + "encoding/json" + "fmt" + "time" +) + +// Commonly used map of things, used in JSON creation and the like. +type MapStr map[string]interface{} + +// Eventer defines a type its ability to fill a MapStr. +type Eventer interface { + // Add fields to MapStr. + Event(event MapStr) error +} + +// MapStrUnion creates a new MapStr containing the union of the +// key-value pairs of the two maps. If the same key is present in +// both, the key-value pairs from dict2 overwrite the ones from dict1. +func MapStrUnion(dict1 MapStr, dict2 MapStr) MapStr { + dict := MapStr{} + + for k, v := range dict1 { + dict[k] = v + } + + for k, v := range dict2 { + dict[k] = v + } + return dict +} + +// Update copies all the key-value pairs from the +// d map overwriting any existing keys. +func (m MapStr) Update(d MapStr) { + for k, v := range d { + m[k] = v + } +} + +// Checks if a timestamp field exists and if it doesn't it adds +// one by using the injected now() function as a time source. +func (m MapStr) EnsureTimestampField(now func() time.Time) error { + ts, exists := m["@timestamp"] + if !exists { + m["@timestamp"] = Time(now()) + return nil + } + + _, is_common_time := ts.(Time) + if is_common_time { + // already perfect + return nil + } + + tstime, is_time := ts.(time.Time) + if is_time { + m["@timestamp"] = Time(tstime) + return nil + } + + tsstr, is_string := ts.(string) + if is_string { + var err error + m["@timestamp"], err = ParseTime(tsstr) + return err + } + return fmt.Errorf("Don't know how to convert %v to a Time value", ts) +} + +func (m MapStr) EnsureCountField() error { + _, exists := m["count"] + if !exists { + m["count"] = 1 + } + return nil +} + +// Prints the dict as a json +func (m MapStr) String() string { + bytes, err := json.Marshal(m) + if err != nil { + return fmt.Sprintf("Not valid json: %v", err) + } + return string(bytes) +} + +// UnmarshalYAML helps out with the YAML unmarshalling when the target +// variable is a MapStr. The default behavior is to unmarshal nested +// maps to map[interface{}]interface{} values, and such values can't +// be marshalled as JSON. +// +// The keys of map[interface{}]interface{} maps will be converted to +// strings with a %v format string, as will any scalar values that +// aren't already strings (i.e. numbers and boolean values). +// +// Since we want to modify the receiver it needs to be a pointer. +func (ms *MapStr) UnmarshalYAML(unmarshal func(interface{}) error) error { + var result map[interface{}]interface{} + err := unmarshal(&result) + if err != nil { + panic(err) + } + *ms = cleanUpInterfaceMap(result) + return nil +} + +func cleanUpInterfaceArray(in []interface{}) []interface{} { + result := make([]interface{}, len(in)) + for i, v := range in { + result[i] = cleanUpMapValue(v) + } + return result +} + +func cleanUpInterfaceMap(in map[interface{}]interface{}) MapStr { + result := make(MapStr) + for k, v := range in { + result[fmt.Sprintf("%v", k)] = cleanUpMapValue(v) + } + return result +} + +func cleanUpMapValue(v interface{}) interface{} { + switch v := v.(type) { + case []interface{}: + return cleanUpInterfaceArray(v) + case map[interface{}]interface{}: + return cleanUpInterfaceMap(v) + case string: + return v + default: + return fmt.Sprintf("%v", v) + } +} diff --git a/vendor/github.com/elastic/beats/libbeat/common/net.go b/vendor/github.com/elastic/beats/libbeat/common/net.go new file mode 100644 index 0000000..9162f52 --- /dev/null +++ b/vendor/github.com/elastic/beats/libbeat/common/net.go @@ -0,0 +1,50 @@ +package common + +import ( + "fmt" + "net" +) + +// LocalIpAddrs finds the IP addresses of the hosts on which +// the shipper currently runs on. +func LocalIpAddrs() ([]net.IP, error) { + var localIPAddrs = []net.IP{} + ipaddrs, err := net.InterfaceAddrs() + if err != nil { + return []net.IP{}, err + } + for _, ipaddr := range ipaddrs { + if ipnet, ok := ipaddr.(*net.IPNet); ok { + localIPAddrs = append(localIPAddrs, ipnet.IP) + } + } + return localIPAddrs, nil +} + +// LocalIpAddrsAsStrings finds the IP addresses of the hosts on which +// the shipper currently runs on and returns them as an array of +// strings. +func LocalIpAddrsAsStrings(include_loopbacks bool) ([]string, error) { + var localIPAddrsStrings = []string{} + var err error + ipaddrs, err := LocalIpAddrs() + if err != nil { + return []string{}, err + } + for _, ipaddr := range ipaddrs { + if include_loopbacks || !ipaddr.IsLoopback() { + localIPAddrsStrings = append(localIPAddrsStrings, ipaddr.String()) + } + } + return localIPAddrsStrings, err +} + +// IsLoopback check if a particular IP notation corresponds +// to a loopback interface. +func IsLoopback(ip_str string) (bool, error) { + ip := net.ParseIP(ip_str) + if ip == nil { + return false, fmt.Errorf("Wrong IP format %s", ip_str) + } + return ip.IsLoopback(), nil +} diff --git a/vendor/github.com/elastic/beats/libbeat/common/statuses.go b/vendor/github.com/elastic/beats/libbeat/common/statuses.go new file mode 100644 index 0000000..2d5096a --- /dev/null +++ b/vendor/github.com/elastic/beats/libbeat/common/statuses.go @@ -0,0 +1,9 @@ +package common + +// standardized status values +const ( + OK_STATUS = "OK" + ERROR_STATUS = "Error" + SERVER_ERROR_STATUS = "Server Error" + CLIENT_ERROR_STATUS = "Client Error" +) diff --git a/vendor/github.com/elastic/beats/libbeat/common/streambuf/ascii.go b/vendor/github.com/elastic/beats/libbeat/common/streambuf/ascii.go new file mode 100644 index 0000000..30933a3 --- /dev/null +++ b/vendor/github.com/elastic/beats/libbeat/common/streambuf/ascii.go @@ -0,0 +1,236 @@ +package streambuf + +// ASCII parsing support + +import ( + "bytes" + "errors" +) + +var ErrExpectedDigit = errors.New("Expected digit") + +// UntilCRLF collects all bytes until a CRLF ("\r\n") sequence is found. The +// returned byte slice will not contain the CRLF sequence. +// If CRLF was not found yet one of ErrNoMoreBytes or ErrUnexpectedEOB will be +// reported. +func (b *Buffer) UntilCRLF() ([]byte, error) { + if b.err != nil { + return nil, b.err + } + + data := b.data[b.offset:] + for i, byte := range data { + if byte != '\r' { + continue + } + + if len(data) < i+2 { + b.offset += i + return nil, b.bufferEndError() + } + + if data[i+1] != '\n' { + // false alarm, continue + continue + } + + // yay, found + end := i + data = b.data[b.mark : b.offset+end] + b.Advance(len(data) + 2) + return data, nil + } + + b.offset += len(data) + return nil, b.bufferEndError() +} + +// Ignore symbol will advance the read pointer until the first symbol not +// matching s is found. +func (b *Buffer) IgnoreSymbol(s uint8) error { + if b.err != nil { + return b.err + } + + data := b.data[b.offset:] + for i, byte := range data { + if byte != s { + b.Advance(b.offset + i - b.mark) + return nil + } + } + b.offset += len(data) + return b.bufferEndError() +} + +// IgnoreSymbols will advance the read pointer until the first symbol not matching +// set of symbols is found +func (b *Buffer) IgnoreSymbols(syms []byte) error { + if b.err != nil { + return b.err + } + + data := b.data[b.offset:] + for i, byte := range data { + for _, other := range syms { + if byte == other { + goto next + } + } + // no match + b.Advance(b.offset + i - b.mark) + return nil + + next: + } + b.offset += len(data) + return b.bufferEndError() +} + +// UntilSymbol collects all bytes until symbol s is found. If errOnEnd is set to +// true, the collected byte slice will be returned if no more bytes are available +// for parsing, but s has not matched yet. +func (b *Buffer) UntilSymbol(s uint8, errOnEnd bool) ([]byte, error) { + if b.err != nil { + return nil, b.err + } + + data := b.data[b.offset:] + for i, byte := range data { + if byte == s { + data := b.data[b.mark : b.offset+i] + b.Advance(len(data)) + return data, nil + } + } + + if errOnEnd { + b.offset += len(data) + return nil, b.bufferEndError() + } else { + data := b.data[b.mark:] + b.Advance(len(data)) + return data, nil + } +} + +// AsciiUint will parse unsigned number from Buffer. +func (b *Buffer) AsciiUint(errOnEnd bool) (uint64, error) { + if b.err != nil { + return 0, b.err + } + if len(b.data) <= b.mark { // end of buffer + return 0, b.bufferEndError() + } + + end, err := b.asciiFindNumberEnd(b.offset, errOnEnd) + if err != nil { + return 0, err + } + + // parse value + value, err := doParseNumber(b.data[b.mark:end]) + if err != nil { + return 0, err + } + b.Advance(end - b.mark) + return value, nil +} + +// AsciiInt will parse (optionally) signed number from Buffer. +func (b *Buffer) AsciiInt(errOnEnd bool) (int64, error) { + if b.err != nil { + return 0, b.err + } + if len(b.data) <= b.mark { // end of buffer + return 0, b.bufferEndError() + } + + // check signedness of number + signed := b.data[b.mark] == '-' + start := b.mark + if signed { + start++ + if len(b.data) <= start { + return 0, b.bufferEndError() + } + } else if b.data[b.mark] == '+' { + start++ + if len(b.data) <= start { + return 0, b.bufferEndError() + } + } + + // adapt offset to point to start of number + offset := b.offset + if b.offset == b.mark { + offset = start + } + + end, err := b.asciiFindNumberEnd(offset, errOnEnd) + if err != nil { + return 0, err + } + + value, err := doParseNumber(b.data[start:end]) + if err != nil { + return 0, err + } + + b.Advance(end - b.mark) + if signed { + return -int64(value), nil + } else { + return int64(value), nil + } +} + +// AsciiMatch checks the Buffer it's next byte sequence matched prefix. The +// read pointer is not advanced by AsciiPrefix. +func (b *Buffer) AsciiMatch(prefix []byte) (bool, error) { + if b.err != nil { + return false, b.err + } + if !b.Avail(len(prefix)) { + return false, b.bufferEndError() + } + + has := bytes.HasPrefix(b.data[b.mark:], prefix) + return has, nil +} + +func (b *Buffer) asciiFindNumberEnd(start int, errOnEnd bool) (int, error) { + // find end of number + end := -1 + for i, byte := range b.data[start:] { + if byte < '0' || '9' < byte { + end = i + start + break + } + } + + // check end + if end < 0 { + if errOnEnd { + return -1, b.bufferEndError() + } else { + end = len(b.data) + } + } + + return end, nil +} + +func doParseNumber(buf []byte) (uint64, error) { + if len(buf) == 0 { + return 0, ErrExpectedDigit + } + + var value uint64 + for _, byte := range buf { + value = uint64(byte-'0') + 10*value + } + return value, nil +} + +// binary parsing support diff --git a/vendor/github.com/elastic/beats/libbeat/common/streambuf/io.go b/vendor/github.com/elastic/beats/libbeat/common/streambuf/io.go new file mode 100644 index 0000000..b58b871 --- /dev/null +++ b/vendor/github.com/elastic/beats/libbeat/common/streambuf/io.go @@ -0,0 +1,187 @@ +package streambuf + +import ( + "io" + "unicode/utf8" +) + +func (b *Buffer) ioErr() error { + err := b.Err() + if err == ErrUnexpectedEOB || err == ErrNoMoreBytes { + return io.EOF + } + return err +} + +func (b *Buffer) ioBufferEndError() error { + err := b.bufferEndError() + if err == ErrUnexpectedEOB || err == ErrNoMoreBytes { + return io.EOF + } + return err +} + +// ReadByte reads and returns next byte from the buffer. +// If no byte is available returns either ErrNoMoreBytes (if buffer allows +// adding more bytes) or io.EOF +func (b *Buffer) ReadByte() (byte, error) { + if b.Failed() { + return 0, b.ioErr() + } + if !b.Avail(1) { + return 0, b.ioBufferEndError() + } + c := b.data[b.mark] + b.Advance(1) + return c, nil +} + +// Unreads the last byte returned by most recent read operation. +func (b *Buffer) UnreadByte() error { + err := b.ioErr() + if err != nil && err != io.EOF { + return err + } + if b.mark == 0 { + return ErrOutOfRange + } + + if b.mark == b.offset { + b.offset-- + } + b.mark-- + b.available++ + return nil +} + +// WriteByte appends the byte c to the buffer if buffer is not fixed. +func (b *Buffer) WriteByte(c byte) error { + p := [1]byte{c} + _, err := b.Write(p[:]) + return err +} + +// Read reads up to len(p) bytes into p if buffer is not in a failed state. +// Returns ErrNoMoreBytes or io.EOF (fixed buffer) if no bytes are available. +func (b *Buffer) Read(p []byte) (int, error) { + if b.Failed() { + return 0, b.ioErr() + } + if b.Len() == 0 { + return 0, b.ioBufferEndError() + } + + tmp := b.Bytes() + n := copy(p, tmp) + b.Advance(n) + return n, nil +} + +// Write writes p to the buffer if buffer is not fixed. Returns the number of +// bytes written or ErrOperationNotAllowed if buffer is fixed. +func (b *Buffer) Write(p []byte) (int, error) { + err := b.doAppend(p, false, -1) + if err != nil { + return 0, b.ioErr() + } + return len(p), nil +} + +// ReadFrom reads data from r until error or io.EOF and appends it to the buffer. +// The amount of bytes read is returned plus any error except io.EOF. +func (b *Buffer) ReadFrom(r io.Reader) (int64, error) { + err := b.err + if err != nil && err != ErrNoMoreBytes { + return 0, b.ioErr() + } + if b.fixed { + return 0, ErrOperationNotAllowed + } + + var buf [4096]byte + var total int64 + for { + n, err := r.Read(buf[:]) + if err != nil { + if err == io.EOF { + break + } + return total, err + } + _, err = b.Write(buf[:n]) + if err != nil { + return total, err + } + total += int64(n) + } + + return total, nil +} + +// ReadRune reads and returns the next UTF-8-encoded Unicode code point from the +// buffer. If no bytes are available, the error returned is ErrNoMoreBytes (if +// buffer supports adding more bytes) or io.EOF. If the bytes are an erroneous +// UTF-8 encoding, it consumes one byte and returns U+FFFD, 1. +func (b *Buffer) ReadRune() (rune, int, error) { + if b.err != nil { + return 0, 0, b.ioErr() + } + if b.available == 0 { + return 0, 0, b.ioBufferEndError() + } + + if c := b.data[b.mark]; c < utf8.RuneSelf { + b.Advance(1) + return rune(c), 1, nil + } + c, size := utf8.DecodeRune(b.data[b.mark:]) + b.Advance(size) + return c, size, nil +} + +// ReadAt reads bytes at off into p starting at the buffer its read marker. +// The read marker is not updated. If number of bytes returned is less len(p) or +// no bytes are available at off, io.EOF will be returned in err. If off is < 0, +// err is set to ErrOutOfRange. +func (b *Buffer) ReadAt(p []byte, off int64) (n int, err error) { + if b.err != nil { + return 0, b.ioErr() + } + + if off < 0 { + return 0, ErrOutOfRange + } + + off += int64(b.mark) + if off >= int64(len(b.data)) { + return 0, ErrOutOfRange + } + + end := off + int64(len(p)) + if end > int64(len(b.data)) { + err = io.EOF + end = int64(len(b.data)) + } + copy(p, b.data[off:end]) + return int(end - off), err +} + +// WriteAt writes the content of p at off starting at recent read marker +// (already consumed bytes). Returns number of bytes written n = len(p) and err +// is nil if off and off+len(p) are within bounds, else n=0 and err is set to +// ErrOutOfRange. +func (b *Buffer) WriteAt(p []byte, off int64) (n int, err error) { + if b.err != nil { + return 0, b.ioErr() + } + + end := off + int64(b.mark) + int64(len(p)) + maxInt := int((^uint(0)) >> 1) + if off < 0 || end > int64(maxInt) { + return 0, ErrOutOfRange + } + + // copy p into buffer + n = copy(b.sliceAt(int(off), len(p)), p) + return n, nil +} diff --git a/vendor/github.com/elastic/beats/libbeat/common/streambuf/net.go b/vendor/github.com/elastic/beats/libbeat/common/streambuf/net.go new file mode 100644 index 0000000..8b3a952 --- /dev/null +++ b/vendor/github.com/elastic/beats/libbeat/common/streambuf/net.go @@ -0,0 +1,183 @@ +package streambuf + +// read integers in network byte order + +import ( + "github.com/elastic/beats/libbeat/common" +) + +// Parse 8bit binary value from Buffer. +func (b *Buffer) ReadNetUint8() (uint8, error) { + if b.Failed() { + return 0, b.err + } + tmp := b.data[b.mark:] + if err := b.Advance(1); err != nil { + return 0, err + } + value := tmp[0] + return value, nil +} + +// Write 8bit binary value to Buffer. +func (b *Buffer) WriteNetUint8(u uint8) error { + return b.Append([]byte{u}) +} + +// Parse 8bit binary value from the buffer at index. Will not advance the read +// buffer +func (b *Buffer) ReadNetUint8At(index int) (uint8, error) { + if b.Failed() { + return 0, b.err + } + if !b.Avail(1 + index) { + return 0, b.bufferEndError() + } + return b.data[index+b.mark], nil +} + +// Write 8bit binary value at index. +func (b *Buffer) WriteNetUint8At(u uint8, index int) error { + if b.err != nil { + return b.err + } + b.sliceAt(index, 1)[0] = u + return nil +} + +// Parse 16bit binary value in network byte order from Buffer +// (converted to Host order). +func (b *Buffer) ReadNetUint16() (uint16, error) { + if b.Failed() { + return 0, b.err + } + tmp := b.data[b.mark:] + if err := b.Advance(2); err != nil { + return 0, err + } + value := common.Bytes_Ntohs(tmp) + return value, nil +} + +// Write 16bit binary value in network byte order to buffer. +func (b *Buffer) WriteNetUint16(u uint16) error { + return b.WriteNetUint16At(u, b.available) +} + +// Parse 16bit binary value from the buffer at index. Will not advance the read +// buffer +func (b *Buffer) ReadNetUint16At(index int) (uint16, error) { + if b.Failed() { + return 0, b.err + } + if !b.Avail(2 + index) { + return 0, b.bufferEndError() + } + return common.Bytes_Ntohs(b.data[index+b.mark:]), nil + +} + +// Write 16bit binary value at index in network byte order to buffer. +func (b *Buffer) WriteNetUint16At(u uint16, index int) error { + if b.err != nil { + return b.err + } + tmp := b.sliceAt(index, 2) + tmp[0] = uint8(u >> 8) + tmp[1] = uint8(u) + return nil +} + +// Parse 32bit binary value in network byte order from Buffer +// (converted to Host order). +func (b *Buffer) ReadNetUint32() (uint32, error) { + if b.Failed() { + return 0, b.err + } + tmp := b.data[b.mark:] + if err := b.Advance(4); err != nil { + return 0, err + } + value := common.Bytes_Ntohl(tmp) + return value, nil +} + +// Write 32bit binary value in network byte order to buffer. +func (b *Buffer) WriteNetUint32(u uint32) error { + return b.WriteNetUint32At(u, b.available) +} + +// Parse 32bit binary value from the buffer at index. Will not advance the read +// buffer +func (b *Buffer) ReadNetUint32At(index int) (uint32, error) { + if b.Failed() { + return 0, b.err + } + if !b.Avail(4 + index) { + return 0, b.bufferEndError() + } + return common.Bytes_Ntohl(b.data[index+b.mark:]), nil + +} + +// Write 32bit binary value at index in network byte order to buffer. +func (b *Buffer) WriteNetUint32At(u uint32, index int) error { + if b.err != nil { + return b.err + } + tmp := b.sliceAt(index, 4) + tmp[0] = uint8(u >> 24) + tmp[1] = uint8(u >> 16) + tmp[2] = uint8(u >> 8) + tmp[3] = uint8(u) + return nil +} + +// Parse 64bit binary value in network byte order from Buffer +// (converted to Host order). +func (b *Buffer) ReadNetUint64() (uint64, error) { + if b.Failed() { + return 0, b.err + } + tmp := b.data[b.mark:] + if err := b.Advance(8); err != nil { + return 0, err + } + value := common.Bytes_Ntohll(tmp) + return value, nil +} + +// Write 64bit binary value in network byte order to buffer. +func (b *Buffer) WriteNetUint64(u uint64) error { + return b.WriteNetUint64At(u, b.available) +} + +// Parse 64bit binary value from the buffer at index. Will not advance the read +// buffer +func (b *Buffer) ReadNetUint64At(index int) (uint64, error) { + if b.Failed() { + return 0, b.err + } + if !b.Avail(8 + index) { + return 0, b.bufferEndError() + } + return common.Bytes_Ntohll(b.data[index+b.mark:]), nil + +} + +// Write 64bit binary value at index in network byte order to buffer. +func (b *Buffer) WriteNetUint64At(u uint64, index int) error { + if b.err != nil { + return b.err + } + tmp := b.sliceAt(index, 8) + tmp[0] = uint8(u >> 56) + tmp[1] = uint8(u >> 48) + tmp[2] = uint8(u >> 40) + tmp[3] = uint8(u >> 32) + tmp[4] = uint8(u >> 24) + tmp[5] = uint8(u >> 16) + tmp[6] = uint8(u >> 8) + tmp[7] = uint8(u) + return nil +} diff --git a/vendor/github.com/elastic/beats/libbeat/common/streambuf/streambuf.go b/vendor/github.com/elastic/beats/libbeat/common/streambuf/streambuf.go new file mode 100644 index 0000000..70b0f4d --- /dev/null +++ b/vendor/github.com/elastic/beats/libbeat/common/streambuf/streambuf.go @@ -0,0 +1,482 @@ +// The streambuf module provides helpers for buffering multiple packet payloads +// and some general parsing functions. All parsing functions are re-entrant, +// that is if a parse function fails due do not having buffered enough bytes yet +// (error value ErrNoMoreBytes) the parser can be called again after appending more +// bytes to the buffer. Parsers potentially reading large amount of bytes might +// remember the last position. +// Additionally a Buffer can be marked as fixed. Fixed buffers to not support +// adding new data, plus ErrNoMoreBytes will never be returned. Instead if a parser +// decides it need more bytes ErrUnexpectedEOB will be returned. +// +// Error handling: +// All functions that might fail, will return an error. The last error reported +// will be stored with the buffer itself. Instead of checking every single error +// one can use the Failed() and Err() methods to check if the buffer is still in a +// valid state and all parsing was successfull. +package streambuf + +import ( + "github.com/elastic/beats/libbeat/logp" + + "bytes" + "errors" +) + +// Error returned if Append or Write operation is not allowed due to the buffer +// being fixed +var ErrOperationNotAllowed = errors.New("Operation not allowed") + +var ErrOutOfRange = errors.New("Data access out of range") + +// Parse operation can not be continued. More bytes required. Only returned if +// buffer is not fixed +var ErrNoMoreBytes = errors.New("No more bytes") + +// Parse operation failed cause of buffer snapped short + buffer is fixed. +var ErrUnexpectedEOB = errors.New("unexpected end of buffer") + +var ErrExpectedByteSequenceMismatch = errors.New("expected byte sequence did not match") + +// A Buffer is a variable sized buffer of bytes with Read, Write and simple +// parsing methods. The zero value is an empty buffer ready for use. +// +// A Buffer can be marked as fixed. In this case no data can be appended to the +// buffer anymore and parser/reader methods will fail with ErrUnexpectedEOB if they +// would expect more bytes to come. Mark buffers fixed if some slice was separated +// for further parsing first. +type Buffer struct { + data []byte + err error + fixed bool + + // Internal parser state offsets. + // Offset is the position a parse might continue to work at when called + // again (e.g. usefull for parsing tcp streams.). The mark is used to remember + // the position last parse operation ended at. The variable available is used + // for faster lookup + // Invariants: + // (1) 0 <= mark <= offset + // (2) 0 <= available <= len(data) + // (3) available = len(data) - mark + mark, offset, available int +} + +// Init initializes a zero buffer with some byte slice being retained by the +// buffer. Usage of Init is optional as zero value Buffer is already in valid state. +func (b *Buffer) Init(d []byte, fixed bool) { + b.data = d + b.err = nil + b.fixed = fixed + b.mark = 0 + b.offset = 0 + b.available = len(d) +} + +// New creates new extensible buffer from data slice being retained by the buffer. +func New(data []byte) *Buffer { + return &Buffer{ + data: data, + fixed: false, + available: len(data), + } +} + +// NewFixed create new fixed buffer from data slice being retained by the buffer. +func NewFixed(data []byte) *Buffer { + return &Buffer{ + data: data, + fixed: true, + available: len(data), + } +} + +// Snapshot creates a snapshot of buffers current state. Use in conjunction with +// Restore to get simple backtracking support. Between Snapshot and Restore the +// Reset method MUST not be called, as restored buffer will be in invalid state +// after. +func (b *Buffer) Snapshot() *Buffer { + tmp := *b + return &tmp +} + +// Restore restores a buffers state. Use in conjunction with +// Snapshot to get simple backtracking support. Between Snapshot and Restore the +// Reset method MUST not be called, as restored buffer will be in invalid state +// after. +func (b *Buffer) Restore(snapshot *Buffer) { + b.err = snapshot.err + b.fixed = snapshot.fixed + b.mark = snapshot.mark + b.offset = snapshot.offset + b.available = snapshot.available +} + +func (b *Buffer) doAppend(data []byte, retainable bool, newCap int) error { + if b.fixed { + return b.SetError(ErrOperationNotAllowed) + } + if b.err != nil && b.err != ErrNoMoreBytes { + return b.err + } + + if len(b.data) == 0 { + retain := retainable && cap(data) > newCap + if retain { + b.data = data + } else { + if newCap < len(data) { + b.data = make([]byte, len(data)) + } else { + b.data = make([]byte, len(data), newCap) + } + copy(b.data, data) + } + } else { + if newCap > 0 && cap(b.data[b.offset:]) < len(data) { + required := cap(b.data) + len(data) + if required < newCap { + tmp := make([]byte, len(b.data), newCap) + copy(tmp, b.data) + b.data = tmp + } + } + b.data = append(b.data, data...) + } + b.available += len(data) + + // reset error status (continue parsing) + if b.err == ErrNoMoreBytes { + b.err = nil + } + + return nil +} + +// Append will append the given data to the buffer. If Buffer is fixed +// ErrOperationNotAllowed will be returned. +func (b *Buffer) Append(data []byte) error { + return b.doAppend(data, true, -1) +} + +func (b *Buffer) AppendWithCapLimits(data []byte, newCap int) error { + return b.doAppend(data, true, newCap) +} + +// Fix marks a buffer as fixed. No more data can be added to the buffer and +// parse operation might fail if they expect more bytes. +func (b *Buffer) Fix() { + b.fixed = true +} + +// Total returns the total number of bytes stored in the buffer +func (b *Buffer) Total() int { + return len(b.data) +} + +// Avail checks if count bytes are available for reading from the buffer. +func (b *Buffer) Avail(count int) bool { + return count <= b.available +} + +// Len returns the number of bytes of the unread portion. +func (b *Buffer) Len() int { + return b.available +} + +// Cap returns the buffer capacity until new memory must be allocated +func (b *Buffer) Cap() int { + return cap(b.data) +} + +// LeftBehind returns the number of bytes a re-entrant but not yet finished +// parser did already read. +func (b *Buffer) LeftBehind() int { + return b.offset - b.mark +} + +// BufferConsumed returns the number of bytes already consumed since last call to Reset. +func (b *Buffer) BufferConsumed() int { + return b.mark +} + +// Advance will advance the buffers read pointer by count bytes. Returns +// ErrNoMoreBytes or ErrUnexpectedEOB if count bytes are not available. +func (b *Buffer) Advance(count int) error { + if !b.Avail(count) { + return b.bufferEndError() + } + b.mark += count + b.offset = b.mark + b.available -= count + return nil +} + +// Failed returns true if buffer is in failed state. If buffer is in failed +// state, almost all buffer operations will fail +func (b *Buffer) Failed() bool { + failed := b.err != nil + if failed { + logp.Debug("streambuf", "buf parser already failed with: %s", b.err) + } + return failed +} + +// Returns the error value of the last failed operation. +func (b *Buffer) Err() error { + return b.err +} + +// Check if n bytes are addressable in the buffer offset at b.mark and +// increases either the length or allocates bigger slice if necessary +func (b *Buffer) ensureLen(n int) { + delta := n - b.available + if delta <= 0 { + // no additional space required: + return + } + + // newly available bytes + b.available += delta + + total := len(b.data) + delta + if total <= cap(b.data) { + // enough space in slice -> grow it + b.data = b.data[0:total] + return + } + + tmp := make([]byte, total) + copy(tmp, b.data) + b.data = tmp +} + +// return slice to write to starting at off + b.mark with given length. +func (b *Buffer) sliceAt(off, len int) []byte { + off += b.mark + end := off + len + b.ensureLen(end - b.mark) + return b.data[off:end] +} + +// Consume removes the first n bytes (special variant of Reset) from the +// beginning of the buffer, if at least n bytes have already been processed. +// Returns the byte slice of all bytes being removed from the buffer. +// If total buffer is < n, ErrOutOfRange will be reported or ErrOutOfRange if +// not enough bytes have been processed yet. +func (b *Buffer) Consume(n int) ([]byte, error) { + if n > len(b.data) { + return nil, ErrOutOfRange + } + + new_mark := b.mark - n + if new_mark < 0 { + return nil, ErrOutOfRange + } + + old := b.data[:n] + b.data = b.data[n:] + b.mark = new_mark + b.offset -= n + b.available = len(b.data) - b.mark + return old, nil +} + +// Reset remove all bytes already processed from the buffer. Use Reset after +// processing message to limit amount of buffered data. +func (b *Buffer) Reset() { + b.data = b.data[b.mark:] + b.offset -= b.mark + b.mark = 0 + b.available = len(b.data) + b.err = nil +} + +// BufferedBytes returns all buffered bytes since last reset. +func (b *Buffer) BufferedBytes() []byte { + return b.data +} + +// Bytes returns all bytes not yet processed. The read counters are not advanced +// yet. For example use with fixed Buffer for simple lookahead. +// +// Note: +// The read markers are not advanced. If rest of buffer should be +// processed, call Advance immediately. +func (b *Buffer) Bytes() []byte { + return b.data[b.mark:] +} + +func (b *Buffer) bufferEndError() error { + if b.fixed { + return b.SetError(ErrUnexpectedEOB) + } else { + return b.SetError(ErrNoMoreBytes) + } +} + +// SetError marks a buffer as failed. Append and parse operations will fail with +// err. SetError returns err directly. +func (b *Buffer) SetError(err error) error { + b.err = err + return err +} + +// Collect tries to collect count bytes from the buffer and updates the read +// pointers. If the buffer is in failed state or count bytes are not available +// an error will be returned. +func (b *Buffer) Collect(count int) ([]byte, error) { + if b.err != nil { + return nil, b.err + } + + if !b.Avail(count) { + return nil, b.bufferEndError() + } + + data := b.data[b.mark : b.mark+count] + b.Advance(count) + return data, nil +} + +// CollectWithDelimiter collects count bytes and checks delim will immediately +// follow the byte sequence. Returns count bytes without delim. +// If delim is not matched ErrExpectedByteSequenceMismatch will be raised. +func (b *Buffer) CollectWithSuffix(count int, delim []byte) ([]byte, error) { + total := count + len(delim) + if b.err != nil { + return nil, b.err + } + + if !b.Avail(total) { + return nil, b.bufferEndError() + } + + end := b.mark + count + if !bytes.HasPrefix(b.data[end:], delim) { + return nil, b.SetError(ErrExpectedByteSequenceMismatch) + } + + data := b.data[b.mark : b.mark+count] + b.Advance(total) + return data, nil +} + +// Index returns offset of seq in unprocessed buffer. +// Returns -1 if seq can not be found. +func (b *Buffer) Index(seq []byte) int { + return b.IndexFrom(0, seq) +} + +// IndexFrom returns offset of seq in unprocessed buffer start at from. +// Returns -1 if seq can not be found. +func (b *Buffer) IndexFrom(from int, seq []byte) int { + if b.err != nil { + return -1 + } + + idx := bytes.Index(b.data[b.mark+from:], seq) + if idx < 0 { + return -1 + } + + return idx + from + b.mark +} + +// IndexByte returns offset of byte in unprocessed buffer. +// Returns -1 if byte not in buffer. +func (b *Buffer) IndexByte(byte byte) int { + if b.err != nil { + return -1 + } + + idx := bytes.IndexByte(b.data[b.offset:], byte) + if idx < 0 { + return -1 + } + return idx + (b.offset - b.mark) +} + +// IndexByteFrom returns offset of byte in unpressed buffer starting at off. +// Returns -1 if byte not in buffer +func (b *Buffer) IndexByteFrom(off int, byte byte) int { + if b.err != nil { + return -1 + } + + idx := bytes.IndexByte(b.data[b.offset+off:], byte) + if idx < 0 { + return -1 + } + return idx + (b.offset - b.mark) + off +} + +// CollectUntil collects all bytes until delim was found (including delim). +func (b *Buffer) CollectUntil(delim []byte) ([]byte, error) { + if b.err != nil { + return nil, b.err + } + + idx := bytes.Index(b.data[b.mark:], delim) + if idx < 0 { + return nil, b.bufferEndError() + } + + end := b.mark + idx + len(delim) + data := b.data[b.mark:end] + b.Advance(len(data)) + return data, nil +} + +// CollectUntilByte collects all bytes until delim was found (including delim). +func (b *Buffer) CollectUntilByte(delim byte) ([]byte, error) { + if b.err != nil { + return nil, b.err + } + + idx := bytes.IndexByte(b.data[b.offset:], delim) + if idx < 0 { + b.offset = b.mark + b.available + return nil, b.bufferEndError() + } + + end := b.offset + idx + 1 + data := b.data[b.mark:end] + b.Advance(len(data)) + return data, nil +} + +// CollectWhile collects all bytes until predicate returns false +func (b *Buffer) CollectWhile(pred func(byte) bool) ([]byte, error) { + if b.err != nil { + return nil, b.err + } + + data := b.data[b.offset:] + for i, byte := range data { + if !pred(byte) { + end := b.offset + i + 1 + data := b.data[b.mark:end] + b.Advance(len(data)) + return data, nil + } + } + + b.offset = b.mark + b.available + return nil, b.bufferEndError() +} + +func (b *Buffer) PeekByte() (byte, error) { + return b.PeekByteFrom(0) +} + +func (b *Buffer) PeekByteFrom(off int) (byte, error) { + if b.err != nil { + return 0, b.err + } + + if !b.Avail(off + 1) { + return 0, b.bufferEndError() + } + + return b.data[b.mark+off], nil +} diff --git a/vendor/github.com/elastic/beats/libbeat/common/string.go b/vendor/github.com/elastic/beats/libbeat/common/string.go new file mode 100644 index 0000000..acc1fea --- /dev/null +++ b/vendor/github.com/elastic/beats/libbeat/common/string.go @@ -0,0 +1,13 @@ +package common + +// NetString store the byte length of the data that follows, making it easier +// to unambiguously pass text and byte data between programs that could be +// sensitive to values that could be interpreted as delimiters or terminators +// (such as a null character). +type NetString []byte + +// MarshalText exists to implement encoding.TextMarshaller interface to +// treat []byte as raw string by other encoders/serializers (e.g. JSON) +func (n NetString) MarshalText() ([]byte, error) { + return n, nil +} diff --git a/vendor/github.com/elastic/beats/libbeat/common/tuples.go b/vendor/github.com/elastic/beats/libbeat/common/tuples.go new file mode 100644 index 0000000..cb428a7 --- /dev/null +++ b/vendor/github.com/elastic/beats/libbeat/common/tuples.go @@ -0,0 +1,135 @@ +package common + +import ( + "fmt" + "net" +) + +// In order for the IpPortTuple and the TcpTuple to be used as +// hashtable keys, they need to have a fixed size. This means the +// net.IP is problematic because it's internally represented as a slice. +// We're introducing the HashableIpPortTuple and the HashableTcpTuple +// types which are internally simple byte arrays. + +const MaxIpPortTupleRawSize = 16 + 16 + 2 + 2 + +type HashableIpPortTuple [MaxIpPortTupleRawSize]byte + +type IpPortTuple struct { + Ip_length int + Src_ip, Dst_ip net.IP + Src_port, Dst_port uint16 + + raw HashableIpPortTuple // Src_ip:Src_port:Dst_ip:Dst_port + revRaw HashableIpPortTuple // Dst_ip:Dst_port:Src_ip:Src_port +} + +func NewIpPortTuple(ip_length int, src_ip net.IP, src_port uint16, + dst_ip net.IP, dst_port uint16) IpPortTuple { + + tuple := IpPortTuple{ + Ip_length: ip_length, + Src_ip: src_ip, + Dst_ip: dst_ip, + Src_port: src_port, + Dst_port: dst_port, + } + tuple.ComputeHashebles() + + return tuple +} + +func (t *IpPortTuple) ComputeHashebles() { + copy(t.raw[0:16], t.Src_ip) + copy(t.raw[16:18], []byte{byte(t.Src_port >> 8), byte(t.Src_port)}) + copy(t.raw[18:34], t.Dst_ip) + copy(t.raw[34:36], []byte{byte(t.Dst_port >> 8), byte(t.Dst_port)}) + + copy(t.revRaw[0:16], t.Dst_ip) + copy(t.revRaw[16:18], []byte{byte(t.Dst_port >> 8), byte(t.Dst_port)}) + copy(t.revRaw[18:34], t.Src_ip) + copy(t.revRaw[34:36], []byte{byte(t.Src_port >> 8), byte(t.Src_port)}) +} + +func (t *IpPortTuple) String() string { + return fmt.Sprintf("IpPortTuple src[%s:%d] dst[%s:%d]", + t.Src_ip.String(), + t.Src_port, + t.Dst_ip.String(), + t.Dst_port) +} + +// Hashable returns a hashable value that uniquely identifies +// the IP-port tuple. +func (t *IpPortTuple) Hashable() HashableIpPortTuple { + return t.raw +} + +// Hashable returns a hashable value that uniquely identifies +// the IP-port tuple after swapping the source and destination. +func (t *IpPortTuple) RevHashable() HashableIpPortTuple { + return t.revRaw +} + +const MaxTcpTupleRawSize = 16 + 16 + 2 + 2 + 4 + +type HashableTcpTuple [MaxTcpTupleRawSize]byte + +type TcpTuple struct { + Ip_length int + Src_ip, Dst_ip net.IP + Src_port, Dst_port uint16 + Stream_id uint32 + + raw HashableTcpTuple // Src_ip:Src_port:Dst_ip:Dst_port:stream_id +} + +func TcpTupleFromIpPort(t *IpPortTuple, tcp_id uint32) TcpTuple { + tuple := TcpTuple{ + Ip_length: t.Ip_length, + Src_ip: t.Src_ip, + Dst_ip: t.Dst_ip, + Src_port: t.Src_port, + Dst_port: t.Dst_port, + Stream_id: tcp_id, + } + tuple.ComputeHashebles() + + return tuple +} + +func (t *TcpTuple) ComputeHashebles() { + copy(t.raw[0:16], t.Src_ip) + copy(t.raw[16:18], []byte{byte(t.Src_port >> 8), byte(t.Src_port)}) + copy(t.raw[18:34], t.Dst_ip) + copy(t.raw[34:36], []byte{byte(t.Dst_port >> 8), byte(t.Dst_port)}) + copy(t.raw[36:40], []byte{byte(t.Stream_id >> 24), byte(t.Stream_id >> 16), + byte(t.Stream_id >> 8), byte(t.Stream_id)}) +} + +func (t TcpTuple) String() string { + return fmt.Sprintf("TcpTuple src[%s:%d] dst[%s:%d] stream_id[%d]", + t.Src_ip.String(), + t.Src_port, + t.Dst_ip.String(), + t.Dst_port, + t.Stream_id) +} + +// Returns a pointer to the equivalent IpPortTuple. +func (t TcpTuple) IpPort() *IpPortTuple { + ipport := NewIpPortTuple(t.Ip_length, t.Src_ip, t.Src_port, + t.Dst_ip, t.Dst_port) + return &ipport +} + +// Hashable() returns a hashable value that uniquely identifies +// the TCP tuple. +func (t *TcpTuple) Hashable() HashableTcpTuple { + return t.raw +} + +// Source and destination process names, as found by the proc module. +type CmdlineTuple struct { + Src, Dst []byte +} diff --git a/vendor/github.com/elastic/beats/libbeat/logp/file_rotator.go b/vendor/github.com/elastic/beats/libbeat/logp/file_rotator.go new file mode 100644 index 0000000..caed506 --- /dev/null +++ b/vendor/github.com/elastic/beats/libbeat/logp/file_rotator.go @@ -0,0 +1,160 @@ +package logp + +import ( + "fmt" + "os" + "path/filepath" + "strconv" + "strings" +) + +const RotatorMaxFiles = 1024 +const DefaultKeepFiles = 7 +const DefaultRotateEveryBytes = 10 * 1024 * 1024 + +type FileRotator struct { + Path string + Name string + RotateEveryBytes *uint64 + KeepFiles *int + + current *os.File + current_size uint64 +} + +func (rotator *FileRotator) CreateDirectory() error { + fileinfo, err := os.Stat(rotator.Path) + if err == nil { + if !fileinfo.IsDir() { + return fmt.Errorf("%s exists but it's not a directory", rotator.Path) + } + } + + if os.IsNotExist(err) { + err = os.MkdirAll(rotator.Path, 0755) + if err != nil { + return err + } + } + + return nil +} + +func (rotator *FileRotator) CheckIfConfigSane() error { + if len(rotator.Name) == 0 { + return fmt.Errorf("File logging requires a name for the file names") + } + if rotator.KeepFiles == nil { + rotator.KeepFiles = new(int) + *rotator.KeepFiles = DefaultKeepFiles + } + if rotator.RotateEveryBytes == nil { + rotator.RotateEveryBytes = new(uint64) + *rotator.RotateEveryBytes = DefaultRotateEveryBytes + } + + if *rotator.KeepFiles < 2 || *rotator.KeepFiles >= RotatorMaxFiles { + return fmt.Errorf("The number of files to keep should be between 2 and %d", RotatorMaxFiles-1) + } + return nil +} + +func (rotator *FileRotator) WriteLine(line []byte) error { + if rotator.shouldRotate() { + err := rotator.Rotate() + if err != nil { + return err + } + } + + line = append(line, '\n') + _, err := rotator.current.Write(line) + if err != nil { + return err + } + rotator.current_size += uint64(len(line)) + + return nil +} + +func (rotator *FileRotator) shouldRotate() bool { + if rotator.current == nil { + return true + } + + if rotator.current_size >= *rotator.RotateEveryBytes { + return true + } + + return false +} + +func (rotator *FileRotator) FilePath(file_no int) string { + if file_no == 0 { + return filepath.Join(rotator.Path, rotator.Name) + } + filename := strings.Join([]string{rotator.Name, strconv.Itoa(file_no)}, ".") + return filepath.Join(rotator.Path, filename) +} + +func (rotator *FileRotator) FileExists(file_no int) bool { + file_path := rotator.FilePath(file_no) + _, err := os.Stat(file_path) + if os.IsNotExist(err) { + return false + } + return true +} + +func (rotator *FileRotator) Rotate() error { + + if rotator.current != nil { + if err := rotator.current.Close(); err != nil { + return err + } + } + + // delete any extra files, normally we shouldn't have any + for file_no := *rotator.KeepFiles; file_no < RotatorMaxFiles; file_no++ { + if rotator.FileExists(file_no) { + perr := os.Remove(rotator.FilePath(file_no)) + if perr != nil { + return perr + } + } + } + + // shift all files from last to first + for fileNo := *rotator.KeepFiles - 1; fileNo >= 0; fileNo-- { + if !rotator.FileExists(fileNo) { + // file doesn't exist, don't rotate + continue + } + file_path := rotator.FilePath(fileNo) + + if rotator.FileExists(fileNo + 1) { + // next file exists, something is strange + return fmt.Errorf("File %s exists, when rotating would overwrite it", rotator.FilePath(fileNo+1)) + } + + err := os.Rename(file_path, rotator.FilePath(fileNo+1)) + if err != nil { + return err + } + } + + // create the new file + file_path := rotator.FilePath(0) + current, err := os.Create(file_path) + if err != nil { + return err + } + rotator.current = current + rotator.current_size = 0 + + // delete the extra file, ignore errors here + file_path = rotator.FilePath(*rotator.KeepFiles) + os.Remove(file_path) + + return nil +} diff --git a/vendor/github.com/elastic/beats/libbeat/logp/log.go b/vendor/github.com/elastic/beats/libbeat/logp/log.go new file mode 100644 index 0000000..050041f --- /dev/null +++ b/vendor/github.com/elastic/beats/libbeat/logp/log.go @@ -0,0 +1,179 @@ +package logp + +import ( + "fmt" + "log" + "os" + "runtime/debug" + "time" +) + +type Priority int + +const ( + // From /usr/include/sys/syslog.h. + // These are the same on Linux, BSD, and OS X. + LOG_EMERG Priority = iota + LOG_ALERT + LOG_CRIT + LOG_ERR + LOG_WARNING + LOG_NOTICE + LOG_INFO + LOG_DEBUG +) + +type Logger struct { + toSyslog bool + toStderr bool + toFile bool + level Priority + selectors map[string]bool + debugAllSelectors bool + + logger *log.Logger + syslog [LOG_DEBUG + 1]*log.Logger + rotator *FileRotator +} + +var _log Logger + +func debugMessage(calldepth int, selector, format string, v ...interface{}) { + if _log.level >= LOG_DEBUG { + if !_log.debugAllSelectors { + selected := _log.selectors[selector] + if !selected { + return + } + } + + send(calldepth+1, LOG_DEBUG, "DBG ", format, v...) + } +} + +func send(calldepth int, level Priority, prefix string, format string, v ...interface{}) { + if _log.toSyslog { + _log.syslog[level].Output(calldepth, fmt.Sprintf(format, v...)) + } + if _log.toStderr { + _log.logger.Output(calldepth, fmt.Sprintf(prefix+format, v...)) + } + if _log.toFile { + // Creates a timestamp for the file log message and formats it + prefix = time.Now().Format(time.RFC3339) + " " + prefix + _log.rotator.WriteLine([]byte(fmt.Sprintf(prefix+format, v...))) + } +} + +func Debug(selector string, format string, v ...interface{}) { + debugMessage(3, selector, format, v...) +} + +func MakeDebug(selector string) func(string, ...interface{}) { + return func(msg string, v ...interface{}) { + debugMessage(3, selector, msg, v...) + } +} + +func IsDebug(selector string) bool { + return _log.debugAllSelectors || _log.selectors[selector] +} + +func msg(level Priority, prefix string, format string, v ...interface{}) { + if _log.level >= level { + send(4, level, prefix, format, v...) + } +} + +func Info(format string, v ...interface{}) { + msg(LOG_INFO, "INFO ", format, v...) +} + +func Warn(format string, v ...interface{}) { + msg(LOG_WARNING, "WARN ", format, v...) +} + +func Err(format string, v ...interface{}) { + msg(LOG_ERR, "ERR ", format, v...) +} + +func Critical(format string, v ...interface{}) { + msg(LOG_CRIT, "CRIT ", format, v...) +} + +// WTF prints the message at CRIT level and panics immediately with the same +// message +func WTF(format string, v ...interface{}) { + msg(LOG_CRIT, "CRIT ", format, v) + panic(fmt.Sprintf(format, v...)) +} + +func Recover(msg string) { + if r := recover(); r != nil { + Err("%s. Recovering, but please report this: %s.", msg, r) + Err("Stacktrace: %s", debug.Stack()) + } +} + +// TODO: remove toSyslog and toStderr from the init function +func LogInit(level Priority, prefix string, toSyslog bool, toStderr bool, debugSelectors []string) { + _log.toSyslog = toSyslog + _log.toStderr = toStderr + _log.level = level + + _log.selectors = make(map[string]bool) + for _, selector := range debugSelectors { + _log.selectors[selector] = true + if selector == "*" { + _log.debugAllSelectors = true + } + } + + if _log.toSyslog { + SetToSyslog(true, prefix) + } + + if _log.toStderr { + SetToStderr(true, prefix) + } +} + +func SetToStderr(toStderr bool, prefix string) { + _log.toStderr = toStderr + if _log.toStderr { + // Add timestamp + flag := log.Ldate | log.Ltime | log.Lmicroseconds | log.LUTC | log.Lshortfile + _log.logger = log.New(os.Stderr, prefix, flag) + } +} + +func SetToSyslog(toSyslog bool, prefix string) { + _log.toSyslog = toSyslog + if _log.toSyslog { + for prio := LOG_EMERG; prio <= LOG_DEBUG; prio++ { + _log.syslog[prio] = openSyslog(prio, prefix) + if _log.syslog[prio] == nil { + // syslog not available + _log.toSyslog = false + break + } + } + } +} + +func SetToFile(toFile bool, rotator *FileRotator) error { + _log.toFile = toFile + if _log.toFile { + _log.rotator = rotator + + err := rotator.CreateDirectory() + if err != nil { + return err + } + err = rotator.CheckIfConfigSane() + if err != nil { + return err + } + } + return nil +} diff --git a/vendor/github.com/elastic/beats/libbeat/logp/logp.go b/vendor/github.com/elastic/beats/libbeat/logp/logp.go new file mode 100644 index 0000000..0aee8ca --- /dev/null +++ b/vendor/github.com/elastic/beats/libbeat/logp/logp.go @@ -0,0 +1,152 @@ +package logp + +import ( + "flag" + "fmt" + "io/ioutil" + "log" + "runtime" + "strings" +) + +// cmd line flags +var verbose *bool +var toStderr *bool +var debugSelectorsStr *string + +type Logging struct { + Selectors []string + Files *FileRotator + ToSyslog *bool `yaml:"to_syslog"` + ToFiles *bool `yaml:"to_files"` + Level string +} + +func init() { + // Adds logging specific flags: -v, -e and -d. + verbose = flag.Bool("v", false, "Log at INFO level") + toStderr = flag.Bool("e", false, "Log to stderr and disable syslog/file output") + debugSelectorsStr = flag.String("d", "", "Enable certain debug selectors") +} + +// Init combines the configuration from config with the command line +// flags to initialize the Logging systems. After calling this function, +// standard output is always enabled. You can make it respect the command +// line flag with a later SetStderr call. +func Init(name string, config *Logging) error { + + logLevel, err := getLogLevel(config) + if err != nil { + return err + } + + if *verbose { + if LOG_INFO > logLevel { + logLevel = LOG_INFO + } + } + + debugSelectors := config.Selectors + if logLevel == LOG_DEBUG { + if len(debugSelectors) == 0 { + debugSelectors = []string{"*"} + } + } + if len(*debugSelectorsStr) > 0 { + debugSelectors = strings.Split(*debugSelectorsStr, ",") + logLevel = LOG_DEBUG + } + + var defaultToFiles, defaultToSyslog bool + var defaultFilePath string + if runtime.GOOS == "windows" { + // always disabled on windows + defaultToSyslog = false + defaultToFiles = true + defaultFilePath = fmt.Sprintf("C:\\ProgramData\\%s\\Logs", name) + } else { + defaultToSyslog = true + defaultToFiles = false + defaultFilePath = fmt.Sprintf("/var/log/%s", name) + } + + var toSyslog, toFiles bool + if config.ToSyslog != nil { + toSyslog = *config.ToSyslog + } else { + toSyslog = defaultToSyslog + } + if config.ToFiles != nil { + toFiles = *config.ToFiles + } else { + toFiles = defaultToFiles + } + + // toStderr disables logging to syslog/files + if *toStderr { + toSyslog = false + toFiles = false + } + + LogInit(Priority(logLevel), "", toSyslog, true, debugSelectors) + if len(debugSelectors) > 0 { + config.Selectors = debugSelectors + } + + if toFiles { + if config.Files == nil { + config.Files = &FileRotator{ + Path: defaultFilePath, + Name: name, + } + } else { + if config.Files.Path == "" { + config.Files.Path = defaultFilePath + } + + if config.Files.Name == "" { + config.Files.Name = name + } + } + + err := SetToFile(true, config.Files) + if err != nil { + return err + } + } + + if IsDebug("stdlog") { + // disable standard logging by default (this is sometimes + // used by libraries and we don't want their logs to spam ours) + log.SetOutput(ioutil.Discard) + } + + return nil +} + +func SetStderr() { + if !*toStderr { + SetToStderr(false, "") + Debug("log", "Disable stderr logging") + } +} + +func getLogLevel(config *Logging) (Priority, error) { + if config == nil || config.Level == "" { + return LOG_ERR, nil + } + + levels := map[string]Priority{ + "critical": LOG_CRIT, + "error": LOG_ERR, + "warning": LOG_WARNING, + "info": LOG_INFO, + "debug": LOG_DEBUG, + } + + level, ok := levels[strings.ToLower(config.Level)] + if !ok { + return 0, fmt.Errorf("unknown log level: %v", config.Level) + } + return level, nil +} diff --git a/vendor/github.com/elastic/beats/libbeat/logp/syslog_other.go b/vendor/github.com/elastic/beats/libbeat/logp/syslog_other.go new file mode 100644 index 0000000..b80d2a9 --- /dev/null +++ b/vendor/github.com/elastic/beats/libbeat/logp/syslog_other.go @@ -0,0 +1,9 @@ +// +build windows nacl plan9 + +package logp + +import "log" + +func openSyslog(level Priority, prefix string) *log.Logger { + return nil +} diff --git a/vendor/github.com/elastic/beats/libbeat/logp/syslog_unix.go b/vendor/github.com/elastic/beats/libbeat/logp/syslog_unix.go new file mode 100644 index 0000000..e14c6cc --- /dev/null +++ b/vendor/github.com/elastic/beats/libbeat/logp/syslog_unix.go @@ -0,0 +1,20 @@ +// +build !windows,!nacl,!plan9 + +package logp + +import ( + "fmt" + "log" + "log/syslog" +) + +func openSyslog(level Priority, prefix string) *log.Logger { + logger, err := syslog.NewLogger(syslog.Priority(level), log.Lshortfile) + if err != nil { + fmt.Println("Error opening syslog: ", err) + return nil + } + logger.SetPrefix(prefix) + + return logger +} diff --git a/vendor/github.com/elastic/beats/libbeat/outputs/console/console.go b/vendor/github.com/elastic/beats/libbeat/outputs/console/console.go new file mode 100644 index 0000000..f1f2308 --- /dev/null +++ b/vendor/github.com/elastic/beats/libbeat/outputs/console/console.go @@ -0,0 +1,81 @@ +package console + +import ( + "encoding/json" + "os" + + "github.com/elastic/beats/libbeat/common" + "github.com/elastic/beats/libbeat/logp" + "github.com/elastic/beats/libbeat/outputs" +) + +func init() { + outputs.RegisterOutputPlugin("console", plugin{}) +} + +type plugin struct{} + +func (p plugin) NewOutput( + config *outputs.MothershipConfig, + topologyExpire int, +) (outputs.Outputer, error) { + pretty := config.Pretty != nil && *config.Pretty + return newConsole(pretty), nil +} + +type console struct { + pretty bool +} + +func newConsole(pretty bool) *console { + return &console{pretty} +} + +func writeBuffer(buf []byte) error { + written := 0 + for written < len(buf) { + n, err := os.Stdout.Write(buf[written:]) + if err != nil { + return err + } + + written += n + } + return nil +} + +func (c *console) PublishEvent( + s outputs.Signaler, + opts outputs.Options, + event common.MapStr, +) error { + var jsonEvent []byte + var err error + + if c.pretty { + jsonEvent, err = json.MarshalIndent(event, "", " ") + } else { + jsonEvent, err = json.Marshal(event) + } + if err != nil { + logp.Err("Fail to convert the event to JSON: %s", err) + outputs.SignalCompleted(s) + return err + } + + if err = writeBuffer(jsonEvent); err != nil { + goto fail + } + if err = writeBuffer([]byte{'\n'}); err != nil { + goto fail + } + + outputs.SignalCompleted(s) + return nil +fail: + if opts.Guaranteed { + logp.Critical("Unable to publish events to console: %v", err) + } + outputs.SignalFailed(s, err) + return err +} diff --git a/vendor/github.com/elastic/beats/libbeat/outputs/elasticsearch/api.go b/vendor/github.com/elastic/beats/libbeat/outputs/elasticsearch/api.go new file mode 100644 index 0000000..db7c30d --- /dev/null +++ b/vendor/github.com/elastic/beats/libbeat/outputs/elasticsearch/api.go @@ -0,0 +1,172 @@ +package elasticsearch + +import "encoding/json" + +type QueryResult struct { + Ok bool `json:"ok"` + Index string `json:"_index"` + Type string `json:"_type"` + ID string `json:"_id"` + Source json.RawMessage `json:"_source"` + Version int `json:"_version"` + Found bool `json:"found"` + Exists bool `json:"exists"` + Created bool `json:"created"` + Matches []string `json:"matches"` +} + +type SearchResults struct { + Took int `json:"took"` + Shards json.RawMessage `json:"_shards"` + Hits Hits `json:"hits"` + Aggs map[string]json.RawMessage `json:"aggregations"` +} + +type Hits struct { + Total int + Hits []json.RawMessage `json:"hits"` +} + +type CountResults struct { + Count int `json:"count"` + Shards json.RawMessage `json:"_shards"` +} + +func (r QueryResult) String() string { + out, err := json.Marshal(r) + if err != nil { + return "ERROR" + } + return string(out) +} + +func readQueryResult(obj []byte) (*QueryResult, error) { + var result QueryResult + if obj == nil { + return nil, nil + } + + err := json.Unmarshal(obj, &result) + if err != nil { + return nil, err + } + return &result, err +} + +func readSearchResult(obj []byte) (*SearchResults, error) { + var result SearchResults + if obj == nil { + return nil, nil + } + + err := json.Unmarshal(obj, &result) + if err != nil { + return nil, err + } + return &result, err +} + +func readCountResult(obj []byte) (*CountResults, error) { + if obj == nil { + return nil, nil + } + + var result CountResults + err := json.Unmarshal(obj, &result) + if err != nil { + return nil, err + } + return &result, err +} + +// Index adds or updates a typed JSON document in a specified index, making it +// searchable. In case id is empty, a new id is created over a HTTP POST request. +// Otherwise, a HTTP PUT request is issued. +// Implements: http://www.elastic.co/guide/en/elasticsearch/reference/current/docs-index_.html +func (es *Connection) Index( + index, docType, id string, + params map[string]string, + body interface{}, +) (int, *QueryResult, error) { + method := "PUT" + if id == "" { + method = "POST" + } + + status, resp, err := es.apiCall(method, index, docType, id, params, body) + if err != nil { + return status, nil, err + } + result, err := readQueryResult(resp) + return status, result, err +} + +// Refresh an index. Call this after doing inserts or creating/deleting +// indexes in unit tests. +func (es *Connection) Refresh(index string) (int, *QueryResult, error) { + status, resp, err := es.apiCall("POST", index, "", "_refresh", nil, nil) + if err != nil { + return status, nil, err + } + result, err := readQueryResult(resp) + return status, result, err +} + +// CreateIndex creates a new index, optionally with settings and mappings passed in +// the body. +// Implements: https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-create-index.html +// +func (es *Connection) CreateIndex(index string, body interface{}) (int, *QueryResult, error) { + status, resp, err := es.apiCall("PUT", index, "", "", nil, body) + if err != nil { + return status, nil, err + } + result, err := readQueryResult(resp) + return status, result, err +} + +// Delete deletes a typed JSON document from a specific index based on its id. +// Implements: http://www.elastic.co/guide/en/elasticsearch/reference/current/docs-delete.html +func (es *Connection) Delete(index string, docType string, id string, params map[string]string) (int, *QueryResult, error) { + status, resp, err := es.apiCall("DELETE", index, docType, id, params, nil) + if err != nil { + return status, nil, err + } + result, err := readQueryResult(resp) + return status, result, err +} + +// A search request can be executed purely using a URI by providing request parameters. +// Implements: http://www.elastic.co/guide/en/elasticsearch/reference/current/search-uri-request.html +func (es *Connection) SearchURI(index string, docType string, params map[string]string) (int, *SearchResults, error) { + status, resp, err := es.apiCall("GET", index, docType, "_search", params, nil) + if err != nil { + return status, nil, err + } + result, err := readSearchResult(resp) + return status, result, err +} + +func (es *Connection) CountSearchURI( + index string, docType string, + params map[string]string, +) (int, *CountResults, error) { + status, resp, err := es.apiCall("GET", index, docType, "_count", params, nil) + if err != nil { + return status, nil, err + } + result, err := readCountResult(resp) + return status, result, err +} + +func (es *Connection) apiCall( + method, index, docType, id string, + params map[string]string, + body interface{}, +) (int, []byte, error) { + path, err := makePath(index, docType, id) + if err != nil { + return 0, nil, err + } + return es.request(method, path, params, body) +} diff --git a/vendor/github.com/elastic/beats/libbeat/outputs/elasticsearch/bulkapi.go b/vendor/github.com/elastic/beats/libbeat/outputs/elasticsearch/bulkapi.go new file mode 100644 index 0000000..dbf9f28 --- /dev/null +++ b/vendor/github.com/elastic/beats/libbeat/outputs/elasticsearch/bulkapi.go @@ -0,0 +1,166 @@ +package elasticsearch + +import ( + "bytes" + "encoding/json" + + "github.com/elastic/beats/libbeat/logp" +) + +// MetaBuilder creates meta data for bulk requests +type MetaBuilder func(interface{}) interface{} + +type bulkRequest struct { + es *Connection + buf bytes.Buffer + enc *json.Encoder + path string + params map[string]string +} + +type bulkMeta struct { + Index bulkMetaIndex `json:"index"` +} + +type bulkMetaIndex struct { + Index string `json:"_index"` + DocType string `json:"_type"` +} + +type BulkResult struct { + raw []byte + // Items []json.RawMessage `json:"items"` +} + +func (r *bulkRequest) Send(meta, obj interface{}) error { + var err error + + pos := r.buf.Len() + if err = r.enc.Encode(meta); err != nil { + return err + } + if err = r.enc.Encode(obj); err != nil { + r.buf.Truncate(pos) // remove meta object from buffer + } + return err +} + +func (r *bulkRequest) Flush() (int, BulkResult, error) { + if r.buf.Len() == 0 { + logp.Debug("elasticsearch", "Empty channel. Wait for more data.") + return 0, BulkResult{}, nil + } + + status, resp, err := r.es.sendBulkRequest("POST", r.path, r.params, &r.buf) + if err != nil { + return status, BulkResult{}, err + } + r.buf.Truncate(0) + + result, err := readBulkResult(resp) + return status, result, err +} + +// Bulk performs many index/delete operations in a single API call. +// Implements: http://www.elastic.co/guide/en/elasticsearch/reference/current/docs-bulk.html +func (conn *Connection) Bulk( + index, docType string, + params map[string]string, body []interface{}, +) (*QueryResult, error) { + return conn.BulkWith(index, docType, params, nil, body) +} + +// BulkWith creates a HTTP request containing a bunch of operations and send +// them to Elasticsearch. The request is retransmitted up to max_retries before +// returning an error. +func (conn *Connection) BulkWith( + index string, + docType string, + params map[string]string, + metaBuilder MetaBuilder, + body []interface{}, +) (*QueryResult, error) { + if len(body) == 0 { + logp.Debug("elasticsearch", "Empty channel. Wait for more data.") + return nil, nil + } + + path, err := makePath(index, docType, "_bulk") + if err != nil { + return nil, err + } + + buf := bulkEncode(metaBuilder, body) + if buf.Len() == 0 { + logp.Debug("elasticsearch", "Empty channel. Wait for more data.") + return nil, nil + } + + _, resp, err := conn.sendBulkRequest("POST", path, params, &buf) + if err != nil { + return nil, err + } + return readQueryResult(resp) +} + +func (conn *Connection) startBulkRequest( + index string, + docType string, + params map[string]string, +) (*bulkRequest, error) { + path, err := makePath(index, docType, "_bulk") + if err != nil { + return nil, err + } + + r := &bulkRequest{ + es: conn, + path: path, + params: params, + } + r.enc = json.NewEncoder(&r.buf) + return r, nil +} + +func (conn *Connection) sendBulkRequest( + method, path string, + params map[string]string, + buf *bytes.Buffer, +) (int, []byte, error) { + url := makeURL(conn.URL, path, params) + logp.Debug("elasticsearch", "Sending bulk request to %s", url) + + return conn.execRequest(method, url, buf) +} + +func bulkEncode(metaBuilder MetaBuilder, body []interface{}) bytes.Buffer { + var buf bytes.Buffer + enc := json.NewEncoder(&buf) + if metaBuilder == nil { + for _, obj := range body { + pos := buf.Len() + if err := enc.Encode(obj); err != nil { + debug("Failed to encode message: %s", err) + buf.Truncate(pos) + } + } + } else { + for _, obj := range body { + pos := buf.Len() + meta := metaBuilder(obj) + err := enc.Encode(meta) + if err == nil { + err = enc.Encode(obj) + } + if err != nil { + debug("Failed to encode message: %s", err) + buf.Truncate(pos) + } + } + } + return buf +} + +func readBulkResult(obj []byte) (BulkResult, error) { + return BulkResult{obj}, nil +} diff --git a/vendor/github.com/elastic/beats/libbeat/outputs/elasticsearch/client.go b/vendor/github.com/elastic/beats/libbeat/outputs/elasticsearch/client.go new file mode 100644 index 0000000..ceacc02 --- /dev/null +++ b/vendor/github.com/elastic/beats/libbeat/outputs/elasticsearch/client.go @@ -0,0 +1,514 @@ +package elasticsearch + +import ( + "bytes" + "crypto/tls" + "encoding/json" + "errors" + "expvar" + "fmt" + "io" + "io/ioutil" + "net/http" + "net/url" + "time" + + "github.com/dustin/go-humanize" + + "github.com/elastic/beats/libbeat/common" + "github.com/elastic/beats/libbeat/logp" + "github.com/elastic/beats/libbeat/outputs/mode" +) + +// Metrics that can retrieved through the expvar web interface. +var ( + ackedEvents = expvar.NewInt("libbeatEsPublishedAndAckedEvents") + eventsNotAcked = expvar.NewInt("libbeatEsPublishedButNotAckedEvents") + publishEventsCallCount = expvar.NewInt("libbeatEsPublishEventsCallCount") +) + +type Client struct { + Connection + index string + params map[string]string + + json jsonReader +} + +type Connection struct { + URL string + Username string + Password string + + http *http.Client + connected bool +} + +var ( + nameItems = []byte("items") + nameStatus = []byte("status") + nameError = []byte("error") +) + +var ( + errExpectedItemObject = errors.New("expected item response object") + errExpectedStatusCode = errors.New("expected item status code") + errUnexpectedEmptyObject = errors.New("empty object") + errExcpectedObjectEnd = errors.New("expected end of object") +) + +func NewClient( + esURL, index string, proxyURL *url.URL, tls *tls.Config, + username, password string, + params map[string]string, +) *Client { + proxy := http.ProxyFromEnvironment + if proxyURL != nil { + proxy = http.ProxyURL(proxyURL) + } + + client := &Client{ + Connection: Connection{ + URL: esURL, + Username: username, + Password: password, + http: &http.Client{ + Transport: &http.Transport{ + TLSClientConfig: tls, + Proxy: proxy, + }, + }, + }, + index: index, + params: params, + } + return client +} + +func (client *Client) Clone() *Client { + newClient := &Client{ + Connection: Connection{ + URL: client.URL, + Username: client.Username, + Password: client.Password, + http: &http.Client{ + Transport: client.http.Transport, + }, + connected: false, + }, + index: client.index, + } + return newClient +} + +// PublishEvents sends all events to elasticsearch. On error a slice with all +// events not published or confirmed to be processed by elasticsearch will be +// returned. The input slice backing memory will be reused by return the value. +func (client *Client) PublishEvents( + events []common.MapStr, +) ([]common.MapStr, error) { + + begin := time.Now() + publishEventsCallCount.Add(1) + + if !client.connected { + return events, ErrNotConnected + } + + // new request to store all events into + request, err := client.startBulkRequest("", "", client.params) + if err != nil { + logp.Err("Failed to perform any bulk index operations: %s", err) + return events, err + } + + // encode events into bulk request buffer, dropping failed elements from + // events slice + events = bulkEncodePublishRequest(request, client.index, events) + if len(events) == 0 { + return nil, nil + } + + // send bulk request + bufferSize := request.buf.Len() + _, res, err := request.Flush() + if err != nil { + logp.Err("Failed to perform any bulk index operations: %s", err) + return events, err + } + + logp.Debug("elasticsearch", "PublishEvents: %d metrics have been packed into a buffer of %s and published to elasticsearch in %v.", + len(events), + humanize.Bytes(uint64(bufferSize)), + time.Now().Sub(begin)) + + // check response for transient errors + client.json.init(res.raw) + failed_events := bulkCollectPublishFails(&client.json, events) + ackedEvents.Add(int64(len(events) - len(failed_events))) + eventsNotAcked.Add(int64(len(failed_events))) + if len(failed_events) > 0 { + return failed_events, mode.ErrTempBulkFailure + } + + return nil, nil +} + +// fillBulkRequest encodes all bulk requests and returns slice of events +// successfully added to bulk request. +func bulkEncodePublishRequest( + requ *bulkRequest, + index string, + events []common.MapStr, +) []common.MapStr { + okEvents := events[:0] + for _, event := range events { + meta := eventBulkMeta(index, event) + err := requ.Send(meta, event) + if err != nil { + logp.Err("Failed to encode event: %s", err) + continue + } + + okEvents = append(okEvents, event) + } + return okEvents +} + +func eventBulkMeta(index string, event common.MapStr) bulkMeta { + + index = getIndex(event, index) + meta := bulkMeta{ + Index: bulkMetaIndex{ + Index: index, + DocType: event["type"].(string), + }, + } + return meta +} + +// getIndex returns the full index name +// Index is either defined in the config as part of the output +// or can be overload by the event through setting index +func getIndex(event common.MapStr, index string) string { + + ts := time.Time(event["@timestamp"].(common.Time)).UTC() + + // Check for dynamic index + if _, ok := event["beat"]; ok { + beatMeta := event["beat"].(common.MapStr) + // Check if index is set dynamically + if dynamicIndex, ok := beatMeta["index"]; ok { + index = dynamicIndex.(string) + } + } + + // Append timestamp to index + index = fmt.Sprintf("%s-%d.%02d.%02d", index, + ts.Year(), ts.Month(), ts.Day()) + + return index +} + +// bulkCollectPublishFails checks per item errors returning all events +// to be tried again due to error code returned for that items. If indexing an +// event failed due to some error in the event itself (e.g. does not respect mapping), +// the event will be dropped. +func bulkCollectPublishFails( + reader *jsonReader, + events []common.MapStr, +) []common.MapStr { + if err := reader.expectDict(); err != nil { + logp.Err("Failed to parse bulk respose: expected JSON object") + return nil + } + + // find 'items' field in response + for { + kind, name, err := reader.nextFieldName() + if err != nil { + logp.Err("Failed to parse bulk response") + return nil + } + + if kind == dictEnd { + logp.Err("Failed to parse bulk response: no 'items' field in response") + return nil + } + + // found items array -> continue + if bytes.Equal(name, nameItems) { + break + } + + reader.ignoreNext() + } + + // check items field is an array + if err := reader.expectArray(); err != nil { + logp.Err("Failed to parse bulk respose: expected items array") + return nil + } + + count := len(events) + failed := events[:0] + for i := 0; i < count; i++ { + status, msg, err := itemStatus(reader) + if err != nil { + return nil + } + + if status < 300 { + continue // ok value + } + + if status < 500 && status != 429 { + // hard failure, don't collect + logp.Warn("Can not index event (status=%v): %v", status, msg) + continue + } + + logp.Info("Bulk item insert failed (i=%v, status=%v): %v", i, status, msg) + failed = append(failed, events[i]) + } + + return failed +} + +func itemStatus(reader *jsonReader) (int, []byte, error) { + // skip outer dictionary + if err := reader.expectDict(); err != nil { + return 0, nil, errExpectedItemObject + } + + // find first field in outer dictionary (e.g. 'create') + kind, _, err := reader.nextFieldName() + if err != nil { + logp.Err("Failed to parse bulk response item: %s", err) + return 0, nil, err + } + if kind == dictEnd { + err = errUnexpectedEmptyObject + logp.Err("Failed to parse bulk response item: %s", err) + return 0, nil, err + } + + // parse actual item response code and error message + status, msg, err := itemStatusInner(reader) + + // close dictionary. Expect outer dictionary to have only one element + kind, _, err = reader.step() + if err != nil { + logp.Err("Failed to parse bulk response item: %s", err) + return 0, nil, err + } + if kind != dictEnd { + err = errExcpectedObjectEnd + logp.Err("Failed to parse bulk response item: %s", err) + return 0, nil, err + } + + return status, msg, nil +} + +func itemStatusInner(reader *jsonReader) (int, []byte, error) { + if err := reader.expectDict(); err != nil { + return 0, nil, errExpectedItemObject + } + + status := -1 + var msg []byte + for { + kind, name, err := reader.nextFieldName() + if err != nil { + logp.Err("Failed to parse bulk response item: %s", err) + } + if kind == dictEnd { + break + } + + switch { + case bytes.Equal(name, nameStatus): // name == "status" + status, err = reader.nextInt() + if err != nil { + logp.Err("Failed to parse bulk reponse item: %s", err) + return 0, nil, err + } + + case bytes.Equal(name, nameError): // name == "error" + msg, err = reader.ignoreNext() // collect raw string for "error" field + if err != nil { + return 0, nil, err + } + + default: // ignore unknown fields + reader.ignoreNext() + } + } + + if status < 0 { + return 0, nil, errExpectedStatusCode + } + return status, msg, nil +} + +func (client *Client) PublishEvent(event common.MapStr) error { + if !client.connected { + return ErrNotConnected + } + + index := getIndex(event, client.index) + logp.Debug("output_elasticsearch", "Publish event: %s", event) + + // insert the events one by one + status, _, err := client.Index( + index, event["type"].(string), "", client.params, event) + if err != nil { + logp.Warn("Fail to insert a single event: %s", err) + if err == ErrJSONEncodeFailed { + // don't retry unencodable values + return nil + } + } + switch { + case status == 0: // event was not send yet + return nil + case status >= 500 || status == 429: // server error, retry + return err + case status >= 300 && status < 500: + // won't be able to index event in Elasticsearch => don't retry + return nil + } + + return nil +} + +// LoadTemplate loads a template into Elasticsearch overwriting the existing +// template if it exists. If you wish to not overwrite an existing template +// then use CheckTemplate prior to calling this method. +func (client *Client) LoadTemplate(templateName string, reader *bytes.Reader) error { + + status, _, err := client.execRequest("PUT", client.URL+"/_template/"+templateName, reader) + + if err != nil { + return fmt.Errorf("Template could not be loaded. Error: %s", err) + } + if status != 200 { + return fmt.Errorf("Template could not be loaded. Status: %v", status) + } + + logp.Info("Elasticsearch template with name '%s' loaded", templateName) + + return nil +} + +// CheckTemplate checks if a given template already exist. It returns true if +// and only if Elasticsearch returns with HTTP status code 200. +func (client *Client) CheckTemplate(templateName string) bool { + + status, _, _ := client.request("HEAD", "/_template/"+templateName, nil, nil) + + if status != 200 { + return false + } + + return true +} + +func (conn *Connection) Connect(timeout time.Duration) error { + var err error + conn.connected, err = conn.Ping(timeout) + if err != nil { + return err + } + if !conn.connected { + return ErrNotConnected + } + return nil +} + +func (conn *Connection) Ping(timeout time.Duration) (bool, error) { + debug("ES Ping(url=%v, timeout=%v)", conn.URL, timeout) + + conn.http.Timeout = timeout + status, _, err := conn.execRequest("HEAD", conn.URL, nil) + if err != nil { + debug("Ping request failed with: %v", err) + return false, err + } + + debug("Ping status code: %v", status) + return status < 300, nil +} + +func (conn *Connection) IsConnected() bool { + return conn.connected +} + +func (conn *Connection) Close() error { + conn.connected = false + return nil +} + +func (conn *Connection) request( + method, path string, + params map[string]string, + body interface{}, +) (int, []byte, error) { + url := makeURL(conn.URL, path, params) + logp.Debug("elasticsearch", "%s %s %v", method, url, body) + + var obj []byte + if body != nil { + var err error + obj, err = json.Marshal(body) + if err != nil { + return 0, nil, ErrJSONEncodeFailed + } + } + + return conn.execRequest(method, url, bytes.NewReader(obj)) +} + +func (conn *Connection) execRequest( + method, url string, + body io.Reader, +) (int, []byte, error) { + req, err := http.NewRequest(method, url, body) + if err != nil { + logp.Warn("Failed to create request", err) + return 0, nil, err + } + + req.Header.Add("Accept", "application/json") + if conn.Username != "" || conn.Password != "" { + req.SetBasicAuth(conn.Username, conn.Password) + } + + resp, err := conn.http.Do(req) + if err != nil { + conn.connected = false + return 0, nil, err + } + defer closing(resp.Body) + + status := resp.StatusCode + if status >= 300 { + conn.connected = false + return status, nil, fmt.Errorf("%v", resp.Status) + } + + obj, err := ioutil.ReadAll(resp.Body) + if err != nil { + conn.connected = false + return status, nil, err + } + return status, obj, nil +} + +func closing(c io.Closer) { + err := c.Close() + if err != nil { + logp.Warn("Close failed with: %v", err) + } +} diff --git a/vendor/github.com/elastic/beats/libbeat/outputs/elasticsearch/json_read.go b/vendor/github.com/elastic/beats/libbeat/outputs/elasticsearch/json_read.go new file mode 100644 index 0000000..3b40f1e --- /dev/null +++ b/vendor/github.com/elastic/beats/libbeat/outputs/elasticsearch/json_read.go @@ -0,0 +1,542 @@ +package elasticsearch + +import ( + "errors" + + "github.com/elastic/beats/libbeat/common/streambuf" +) + +// SAX like json parser. But instead of relying on callbacks, state machine +// returns raw item plus entity. On top of state machine additional helper methods +// like expectDict, expectArray, nextFieldName and nextInt are available for +// low-level parsing/stepping through a json document. +// +// Due to parser simply stepping through the input buffer, almost no additional +// allocations are required. +type jsonReader struct { + streambuf.Buffer + + // parser state machine + states []state // state stack for nested arrays/objects + currentState state + + // preallocate stack memory for up to 32 nested arrays/objects + statesBuf [32]state +} + +var ( + errFailing = errors.New("JSON parser failed") + errUnknownChar = errors.New("unknown character") + errQuoteMissing = errors.New("missing closing quote") + errExpectColon = errors.New("expected ':' after map key") + errUnexpectedDictClose = errors.New("unexpected '}'") + errUnexpectedArrClose = errors.New("unexpected ']'") + errExpectedDigit = errors.New("expected a digit") + errExpectedObject = errors.New("expected JSON object") + errExpectedArray = errors.New("expected JSON array") + errExpectedFieldName = errors.New("expected JSON object field name") + errExpectedInteger = errors.New("expected integer value") + errExpectedNull = errors.New("expected null value") + errExpectedFalse = errors.New("expected false value") + errExpectedTrue = errors.New("expected true value") + errExpectedArrayField = errors.New("expected ']' or ','") +) + +var ( + nullSymbol = []byte("null") + trueSymbol = []byte("true") + falseSymbol = []byte("false") +) + +type entity uint8 + +const ( + failEntity entity = iota + trueValue + falseValue + nullValue + dictStart + dictEnd + dictField + arrStart + arrEnd + stringEntity + mapKeyEntity + intEntity + doubleEntity +) + +type state uint8 + +const ( + failedState state = iota + startState + arrState + arrStateNext + dictState + dictFieldState + dictFieldStateEnd +) + +var stateNames = map[state]string{ + failedState: "failed", + startState: "start", + arrState: "array", + arrStateNext: "arrayNext", + dictState: "dict", + dictFieldState: "dictValue", + dictFieldStateEnd: "dictNext", +} + +func (s state) String() string { + if name, ok := stateNames[s]; ok { + return name + } + return "unknown" +} + +func newJSONReader(in []byte) *jsonReader { + r := &jsonReader{} + r.init(in) + return r +} + +func (r *jsonReader) init(in []byte) { + r.Buffer.Init(in, true) + r.currentState = startState + r.states = r.statesBuf[:0] +} + +var whitespace = []byte(" \t\r\n") + +func (r *jsonReader) skipWS() { + r.IgnoreSymbols(whitespace) +} + +func (r *jsonReader) pushState(next state) { + if r.currentState != failedState { + r.states = append(r.states, r.currentState) + } + r.currentState = next +} + +func (r *jsonReader) popState() { + if len(r.states) == 0 { + r.currentState = failedState + } else { + last := len(r.states) - 1 + r.currentState = r.states[last] + r.states = r.states[:last] + } +} + +func (r *jsonReader) expectDict() error { + entity, _, err := r.step() + if err != nil { + return err + } + + if entity != dictStart { + return r.SetError(errExpectedObject) + } + + return nil +} + +func (r *jsonReader) expectArray() error { + entity, _, err := r.step() + if err != nil { + return err + } + + if entity != arrStart { + return r.SetError(errExpectedArray) + } + + return nil +} + +func (r *jsonReader) nextFieldName() (entity, []byte, error) { + entity, raw, err := r.step() + if err != nil { + return entity, raw, err + } + + if entity != mapKeyEntity && entity != dictEnd { + return entity, nil, r.SetError(errExpectedFieldName) + } + + return entity, raw, err +} + +func (r *jsonReader) nextInt() (int, error) { + entity, raw, err := r.step() + if err != nil { + return 0, err + } + + if entity != intEntity { + return 0, errExpectedInteger + } + + tmp := streambuf.NewFixed(raw) + i, err := tmp.AsciiInt(false) + return int(i), err +} + +// ignore type of next element and return raw content. +func (r *jsonReader) ignoreNext() (raw []byte, err error) { + r.skipWS() + + snapshot := r.Snapshot() + before := r.Len() + + var ignoreKind func(*jsonReader, entity) error + ignoreKind = func(r *jsonReader, kind entity) error { + + for { + entity, _, err := r.step() + if err != nil { + return err + } + + switch entity { + case kind: + return nil + case arrStart: + return ignoreKind(r, arrEnd) + case dictStart: + return ignoreKind(r, dictEnd) + } + } + } + + entity, _, err := r.step() + if err != nil { + return nil, err + } + + switch entity { + case dictStart: + err = ignoreKind(r, dictEnd) + case arrStart: + err = ignoreKind(r, arrEnd) + } + if err != nil { + return nil, err + } + + after := r.Len() + r.Restore(snapshot) + + bytes, _ := r.Collect(before - after) + return bytes, nil +} + +// step continues the JSON parser state machine until next entity has been parsed. +func (r *jsonReader) step() (entity, []byte, error) { + r.skipWS() + switch r.currentState { + case failedState: + return r.stepFailing() + case startState: + return r.stepStart() + case arrState: + return r.stepArray() + case arrStateNext: + return r.stepArrayNext() + case dictState: + return r.stepDict() + case dictFieldState: + return r.stepDictValue() + case dictFieldStateEnd: + return r.stepDictValueEnd() + default: + return r.failWith(errFailing) + } +} + +func (r *jsonReader) stepFailing() (entity, []byte, error) { + return failEntity, nil, r.Err() +} + +func (r *jsonReader) stepStart() (entity, []byte, error) { + c, err := r.PeekByte() + if err != nil { + return r.failWith(err) + } + + return r.tryStepPrimitive(c) +} + +func (r *jsonReader) stepArray() (entity, []byte, error) { + return r.doStepArray(true) +} + +func (r *jsonReader) stepArrayNext() (entity, []byte, error) { + c, err := r.PeekByte() + if err != nil { + return r.failWith(errFailing) + } + + switch c { + case ']': + return r.endArray() + case ',': + r.Advance(1) + r.skipWS() + r.currentState = arrState + return r.doStepArray(false) + default: + return r.failWith(errExpectedArrayField) + } +} + +func (r *jsonReader) doStepArray(allowArrayEnd bool) (entity, []byte, error) { + c, err := r.PeekByte() + if err != nil { + return r.failWith(err) + } + + if c == ']' { + if !allowArrayEnd { + return r.failWith(errUnexpectedArrClose) + } + return r.endArray() + } + + r.currentState = arrStateNext + return r.tryStepPrimitive(c) +} + +func (r *jsonReader) stepDict() (entity, []byte, error) { + return r.doStepDict(true) +} + +func (r *jsonReader) doStepDict(allowEnd bool) (entity, []byte, error) { + c, err := r.PeekByte() + if err != nil { + return r.failWith(err) + } + + switch c { + case '}': + if !allowEnd { + return r.failWith(errUnexpectedDictClose) + } + return r.endDict() + case '"': + r.currentState = dictFieldState + return r.stepMapKey() + default: + return r.failWith(errExpectedFieldName) + } +} + +func (r *jsonReader) stepDictValue() (entity, []byte, error) { + c, err := r.PeekByte() + if err != nil { + return r.failWith(err) + } + + r.currentState = dictFieldStateEnd + return r.tryStepPrimitive(c) +} + +func (r *jsonReader) stepDictValueEnd() (entity, []byte, error) { + c, err := r.PeekByte() + if err != nil { + return r.failWith(err) + } + + switch c { + case '}': + return r.endDict() + case ',': + r.Advance(1) + r.skipWS() + r.currentState = dictState + return r.doStepDict(false) + default: + return r.failWith(errUnknownChar) + } +} + +func (r *jsonReader) tryStepPrimitive(c byte) (entity, []byte, error) { + switch c { + case '{': // start dictionary + return r.startDict() + case '[': // start array + return r.startArray() + case 'n': // null + return r.stepNull() + case 'f': // false + return r.stepFalse() + case 't': // true + return r.stepTrue() + case '"': + return r.stepString() + default: + // parse number? + if c == '-' || c == '+' || c == '.' || ('0' <= c && c <= '9') { + return r.stepNumber() + } + + err := r.Err() + if err == nil { + err = r.SetError(errUnknownChar) + } + return r.failWith(err) + } +} + +func (r *jsonReader) stepNull() (entity, []byte, error) { + return stepSymbol(r, nullValue, nullSymbol, errExpectedNull) +} + +func (r *jsonReader) stepTrue() (entity, []byte, error) { + return stepSymbol(r, trueValue, trueSymbol, errExpectedTrue) +} + +func (r *jsonReader) stepFalse() (entity, []byte, error) { + return stepSymbol(r, falseValue, falseSymbol, errExpectedFalse) +} + +func stepSymbol(r *jsonReader, e entity, symb []byte, fail error) (entity, []byte, error) { + ok, err := r.AsciiMatch(symb) + if err != nil { + return failEntity, nil, err + } + if !ok { + return failEntity, nil, fail + } + + r.Advance(len(symb)) + return e, nil, nil +} + +func (r *jsonReader) stepMapKey() (entity, []byte, error) { + entity, key, err := r.stepString() + if err != nil { + return entity, key, err + } + + r.skipWS() + c, err := r.ReadByte() + if err != nil { + return failEntity, nil, err + } + + if c != ':' { + return r.failWith(r.SetError(errExpectColon)) + } + + if err := r.Err(); err != nil { + return r.failWith(err) + } + return mapKeyEntity, key, nil +} + +func (r *jsonReader) stepString() (entity, []byte, error) { + start := 1 + for { + idxQuote := r.IndexByteFrom(start, '"') + if idxQuote == -1 { + return failEntity, nil, r.SetError(errQuoteMissing) + } + + if b, _ := r.PeekByteFrom(idxQuote - 1); b == '\\' { // escaped quote? + start = idxQuote + 1 + continue + } + + // found string end + str, err := r.Collect(idxQuote + 1) + str = str[1 : len(str)-1] + return stringEntity, str, err + } +} + +func (r *jsonReader) startDict() (entity, []byte, error) { + r.Advance(1) + r.pushState(dictState) + return dictStart, nil, nil +} + +func (r *jsonReader) endDict() (entity, []byte, error) { + r.Advance(1) + r.popState() + return dictEnd, nil, nil +} + +func (r *jsonReader) startArray() (entity, []byte, error) { + r.Advance(1) + r.pushState(arrState) + return arrStart, nil, nil +} + +func (r *jsonReader) endArray() (entity, []byte, error) { + r.Advance(1) + r.popState() + return arrEnd, nil, nil +} + +func (r *jsonReader) failWith(err error) (entity, []byte, error) { + r.currentState = failedState + return failEntity, nil, r.SetError(err) +} + +func (r *jsonReader) stepNumber() (entity, []byte, error) { + snapshot := r.Snapshot() + lenBefore := r.Len() + isDouble := false + + if err := r.Err(); err != nil { + return failEntity, nil, err + } + + // parse '+', '-' or '.' + if b, _ := r.PeekByte(); b == '-' || b == '+' { + r.Advance(1) + } + if b, _ := r.PeekByte(); b == '.' { + r.Advance(1) + isDouble = true + } + + // parse digits + buf, _ := r.CollectWhile(isDigit) + if len(buf) == 0 { + return failEntity, nil, r.SetError(errExpectedDigit) + } + + if !isDouble { + // parse optional '.' + if b, _ := r.PeekByte(); b == '.' { + r.Advance(1) + isDouble = true + + // parse optional digits + r.CollectWhile(isDigit) + } + } + + lenAfter := r.Len() + r.Restore(snapshot) + total := lenBefore - lenAfter - 1 + if total == 0 { + return failEntity, nil, r.SetError(errExpectedDigit) + } + + raw, _ := r.Collect(total) + state := intEntity + if isDouble { + state = doubleEntity + } + + return state, raw, nil +} + +func isDigit(c byte) bool { + return '0' <= c && c <= '9' +} diff --git a/vendor/github.com/elastic/beats/libbeat/outputs/elasticsearch/output.go b/vendor/github.com/elastic/beats/libbeat/outputs/elasticsearch/output.go new file mode 100644 index 0000000..df9b536 --- /dev/null +++ b/vendor/github.com/elastic/beats/libbeat/outputs/elasticsearch/output.go @@ -0,0 +1,237 @@ +package elasticsearch + +import ( + "crypto/tls" + "errors" + "net/url" + "strings" + "time" + + "bytes" + "io/ioutil" + + "github.com/elastic/beats/libbeat/common" + "github.com/elastic/beats/libbeat/logp" + "github.com/elastic/beats/libbeat/outputs" + "github.com/elastic/beats/libbeat/outputs/mode" +) + +var debug = logp.MakeDebug("elasticsearch") + +var ( + // ErrNotConnected indicates failure due to client having no valid connection + ErrNotConnected = errors.New("not connected") + + // ErrJSONEncodeFailed indicates encoding failures + ErrJSONEncodeFailed = errors.New("json encode failed") + + // ErrResponseRead indicates error parsing Elasticsearch response + ErrResponseRead = errors.New("bulk item status parse failed.") +) + +const ( + defaultMaxRetries = 3 + + defaultBulkSize = 50 + + elasticsearchDefaultTimeout = 90 * time.Second +) + +func init() { + outputs.RegisterOutputPlugin("elasticsearch", elasticsearchOutputPlugin{}) +} + +type elasticsearchOutputPlugin struct{} + +type elasticsearchOutput struct { + index string + mode mode.ConnectionMode + + topology +} + +// NewOutput instantiates a new output plugin instance publishing to elasticsearch. +func (f elasticsearchOutputPlugin) NewOutput( + config *outputs.MothershipConfig, + topologyExpire int, +) (outputs.Outputer, error) { + + // configure bulk size in config in case it is not set + if config.BulkMaxSize == nil { + bulkSize := defaultBulkSize + config.BulkMaxSize = &bulkSize + } + + output := &elasticsearchOutput{} + err := output.init(*config, topologyExpire) + if err != nil { + return nil, err + } + return output, nil +} + +func (out *elasticsearchOutput) init( + config outputs.MothershipConfig, + topologyExpire int, +) error { + tlsConfig, err := outputs.LoadTLSConfig(config.TLS) + if err != nil { + return err + } + + clients, err := mode.MakeClients(config, makeClientFactory(tlsConfig, config)) + + if err != nil { + return err + } + + timeout := elasticsearchDefaultTimeout + if config.Timeout != 0 { + timeout = time.Duration(config.Timeout) * time.Second + } + + maxRetries := defaultMaxRetries + if config.MaxRetries != nil { + maxRetries = *config.MaxRetries + } + maxAttempts := maxRetries + 1 // maximum number of send attempts (-1 = infinite) + if maxRetries < 0 { + maxAttempts = 0 + } + + var waitRetry = time.Duration(1) * time.Second + var maxWaitRetry = time.Duration(60) * time.Second + + out.clients = clients + loadBalance := config.LoadBalance == nil || *config.LoadBalance + m, err := mode.NewConnectionMode(clients, !loadBalance, + maxAttempts, waitRetry, timeout, maxWaitRetry) + if err != nil { + return err + } + + loadTemplate(config.Template, clients) + + if config.SaveTopology { + err := out.EnableTTL() + if err != nil { + logp.Err("Fail to set _ttl mapping: %s", err) + // keep trying in the background + go func() { + for { + err := out.EnableTTL() + if err == nil { + break + } + logp.Err("Fail to set _ttl mapping: %s", err) + time.Sleep(5 * time.Second) + } + }() + } + } + + out.TopologyExpire = 15000 + if topologyExpire != 0 { + out.TopologyExpire = topologyExpire * 1000 // millisec + } + + out.mode = m + out.index = config.Index + + return nil +} + +// loadTemplate checks if the index mapping template should be loaded +// In case template loading is enabled, template is written to index +func loadTemplate(config outputs.Template, clients []mode.ProtocolClient) { + // Check if template should be loaded + // Not being able to load the template will output an error but will not stop execution + if config.Name != "" && len(clients) > 0 { + + // Always takes the first client + esClient := clients[0].(*Client) + + logp.Info("Loading template enabled. Trying to load template: %v", config.Path) + + exists := esClient.CheckTemplate(config.Name) + + // Check if template already exist or should be overwritten + if !exists || config.Overwrite { + + if config.Overwrite { + logp.Info("Existing template will be overwritten, as overwrite is enabled.") + } + + // Load template from file + content, err := ioutil.ReadFile(config.Path) + if err != nil { + logp.Err("Could not load template from file path: %s; Error: %s", config.Path, err) + } else { + reader := bytes.NewReader(content) + err = esClient.LoadTemplate(config.Name, reader) + + if err != nil { + logp.Err("Could not load template: %v", err) + } + } + } else { + logp.Info("Template already exists and will not be overwritten.") + } + + } +} + +func makeClientFactory( + tls *tls.Config, + config outputs.MothershipConfig, +) func(string) (mode.ProtocolClient, error) { + return func(host string) (mode.ProtocolClient, error) { + esURL, err := getURL(config.Protocol, config.Path, host) + if err != nil { + logp.Err("Invalid host param set: %s, Error: %v", host, err) + return nil, err + } + + var proxyURL *url.URL + if config.ProxyURL != "" { + proxyURL, err = url.Parse(config.ProxyURL) + if err != nil || !strings.HasPrefix(proxyURL.Scheme, "http") { + // Proxy was bogus. Try prepending "http://" to it and + // see if that parses correctly. If not, we fall + // through and complain about the original one. + proxyURL, err = url.Parse("http://" + config.ProxyURL) + if err != nil { + return nil, err + } + } + + logp.Info("Using proxy URL: %s", proxyURL) + } + + params := config.Params + if len(params) == 0 { + params = nil + } + client := NewClient( + esURL, config.Index, proxyURL, tls, + config.Username, config.Password, + params) + return client, nil + } +} + +func (out *elasticsearchOutput) PublishEvent( + signaler outputs.Signaler, + opts outputs.Options, + event common.MapStr, +) error { + return out.mode.PublishEvent(signaler, opts, event) +} + +func (out *elasticsearchOutput) BulkPublish( + trans outputs.Signaler, + opts outputs.Options, + events []common.MapStr, +) error { + return out.mode.PublishEvents(trans, opts, events) +} diff --git a/vendor/github.com/elastic/beats/libbeat/outputs/elasticsearch/topology.go b/vendor/github.com/elastic/beats/libbeat/outputs/elasticsearch/topology.go new file mode 100644 index 0000000..7befb43 --- /dev/null +++ b/vendor/github.com/elastic/beats/libbeat/outputs/elasticsearch/topology.go @@ -0,0 +1,166 @@ +package elasticsearch + +import ( + "encoding/json" + "fmt" + "math/rand" + "strconv" + "strings" + "sync/atomic" + + "github.com/elastic/beats/libbeat/logp" + "github.com/elastic/beats/libbeat/outputs/mode" +) + +type topology struct { + clients []mode.ProtocolClient + + TopologyExpire int + TopologyMap atomic.Value // Value holds a map[string][string] + ttlEnabled bool +} + +type publishedTopology struct { + Name string + IPs string +} + +func (t *topology) randomClient() *Client { + switch len(t.clients) { + case 0: + return nil + case 1: + return t.clients[0].(*Client).Clone() + default: + return t.clients[rand.Intn(len(t.clients))].(*Client).Clone() + } +} + +// Enable using ttl as paramters in a server-ip doc type +func (t *topology) EnableTTL() error { + client := t.randomClient() + if client == nil { + return ErrNotConnected + } + + setting := map[string]interface{}{ + "server-ip": map[string]interface{}{ + "_ttl": map[string]string{"enabled": "true", "default": "15s"}, + }, + } + + // make sure the .packetbeat-topology index exists + // Ignore error here, as CreateIndex will error (400 Bad Request) if index + // already exists. If index could not be created, next api call to index will + // fail anyway. + index := ".packetbeat-topology" + _, _, _ = client.CreateIndex(index, nil) + _, _, err := client.Index(index, "server-ip", "_mapping", nil, setting) + if err != nil { + return err + } + + t.ttlEnabled = true + return nil +} + +// Get the name of a shipper by its IP address from the local topology map +func (t *topology) GetNameByIP(ip string) string { + topologyMap, ok := t.TopologyMap.Load().(map[string]string) + if ok { + name, exists := topologyMap[ip] + if exists { + return name + } + } + return "" +} + +// Each shipper publishes a list of IPs together with its name to Elasticsearch +func (t *topology) PublishIPs(name string, localAddrs []string) error { + if !t.ttlEnabled { + logp.Debug("output_elasticsearch", + "Not publishing IPs because TTL was not yet confirmed to be enabled") + return nil + } + + client := t.randomClient() + if client == nil { + return ErrNotConnected + } + + logp.Debug("output_elasticsearch", + "Publish IPs %s with expiration time %d", localAddrs, t.TopologyExpire) + + params := map[string]string{ + "ttl": fmt.Sprintf("%dms", t.TopologyExpire), + "refresh": "true", + } + _, _, err := client.Index( + ".packetbeat-topology", //index + "server-ip", //type + name, // id + params, // parameters + publishedTopology{name, strings.Join(localAddrs, ",")}, // body + ) + + if err != nil { + logp.Err("Fail to publish IP addresses: %s", err) + return err + } + + newMap, err := loadTopolgyMap(client) + if err != nil { + return err + } + t.TopologyMap.Store(newMap) + + return nil +} + +// Update the local topology map +func loadTopolgyMap(client *Client) (map[string]string, error) { + // get all shippers IPs from Elasticsearch + + index := ".packetbeat-topology" + docType := "server-ip" + + // get number of entries in index for search query to return all entries in one query + _, cntRes, err := client.CountSearchURI(index, docType, nil) + if err != nil { + logp.Err("Getting topology map fails with: %s", err) + return nil, err + } + + params := map[string]string{"size": strconv.Itoa(cntRes.Count)} + _, res, err := client.SearchURI(index, docType, params) + if err != nil { + logp.Err("Getting topology map fails with: %s", err) + return nil, err + } + + topology := make(map[string]string) + for _, obj := range res.Hits.Hits { + var result QueryResult + err = json.Unmarshal(obj, &result) + if err != nil { + logp.Err("Failed to read response: %v", err) + return nil, err + } + + var pub publishedTopology + err = json.Unmarshal(result.Source, &pub) + if err != nil { + logp.Err("json.Unmarshal fails with: %s", err) + return nil, err + } + + // add mapping + for _, addr := range strings.Split(pub.IPs, ",") { + topology[addr] = pub.Name + } + } + + logp.Debug("output_elasticsearch", "Topology map %s", topology) + return topology, nil +} diff --git a/vendor/github.com/elastic/beats/libbeat/outputs/elasticsearch/url.go b/vendor/github.com/elastic/beats/libbeat/outputs/elasticsearch/url.go new file mode 100644 index 0000000..68f760a --- /dev/null +++ b/vendor/github.com/elastic/beats/libbeat/outputs/elasticsearch/url.go @@ -0,0 +1,109 @@ +package elasticsearch + +import ( + "fmt" + "net" + "net/url" + "strings" +) + +// Creates the url based on the url configuration. +// Adds missing parts with defaults (scheme, host, port) +func getURL(defaultScheme string, defaultPath string, rawURL string) (string, error) { + + if defaultScheme == "" { + defaultScheme = "http" + } + + addr, err := url.Parse(rawURL) + if err != nil { + return "", err + } + + scheme := addr.Scheme + host := addr.Host + port := "9200" + + // sanitize parse errors if url does not contain scheme + // if parse url looks funny, prepend schema and try again: + if addr.Scheme == "" || (addr.Host == "" && addr.Path == "" && addr.Opaque != "") { + rawURL = fmt.Sprintf("%v://%v", defaultScheme, rawURL) + if tmpAddr, err := url.Parse(rawURL); err == nil { + addr = tmpAddr + scheme = addr.Scheme + host = addr.Host + } else { + // If url doesn't have a scheme, host is written into path. For example: 192.168.3.7 + scheme = defaultScheme + host = addr.Path + addr.Path = "" + } + } + + if host == "" { + host = "localhost" + } else { + // split host and optional port + if splitHost, splitPort, err := net.SplitHostPort(host); err == nil { + host = splitHost + port = splitPort + } + + // Check if ipv6 + if strings.Count(host, ":") > 1 && strings.Count(host, "]") == 0 { + host = "[" + host + "]" + } + } + + // Assign default path if not set + if addr.Path == "" { + addr.Path = defaultPath + } + + // reconstruct url + addr.Scheme = scheme + addr.Host = host + ":" + port + return addr.String(), nil +} + +func makeURL(url, path string, params map[string]string) string { + u := url + path + if len(params) > 0 { + u = u + "?" + urlEncode(params) + } + return u +} + +// Encode parameters in url +func urlEncode(params map[string]string) string { + values := url.Values{} + + for key, val := range params { + values.Add(key, string(val)) + } + return values.Encode() +} + +// Create path out of index, docType and id that is used for querying Elasticsearch +func makePath(index string, docType string, id string) (string, error) { + + var path string + if len(docType) > 0 { + if len(id) > 0 { + path = fmt.Sprintf("/%s/%s/%s", index, docType, id) + } else { + path = fmt.Sprintf("/%s/%s", index, docType) + } + } else { + if len(id) > 0 { + if len(index) > 0 { + path = fmt.Sprintf("/%s/%s", index, id) + } else { + path = fmt.Sprintf("/%s", id) + } + } else { + path = fmt.Sprintf("/%s", index) + } + } + return path, nil +} diff --git a/vendor/github.com/elastic/beats/libbeat/outputs/fileout/file.go b/vendor/github.com/elastic/beats/libbeat/outputs/fileout/file.go new file mode 100644 index 0000000..58eaeb3 --- /dev/null +++ b/vendor/github.com/elastic/beats/libbeat/outputs/fileout/file.go @@ -0,0 +1,98 @@ +package fileout + +import ( + "encoding/json" + + "github.com/elastic/beats/libbeat/common" + "github.com/elastic/beats/libbeat/logp" + "github.com/elastic/beats/libbeat/outputs" +) + +func init() { + outputs.RegisterOutputPlugin("file", FileOutputPlugin{}) +} + +type FileOutputPlugin struct{} + +func (f FileOutputPlugin) NewOutput( + config *outputs.MothershipConfig, + topology_expire int, +) (outputs.Outputer, error) { + output := &fileOutput{} + err := output.init(config, topology_expire) + if err != nil { + return nil, err + } + return output, nil +} + +type fileOutput struct { + rotator logp.FileRotator +} + +func (out *fileOutput) init(config *outputs.MothershipConfig, topology_expire int) error { + out.rotator.Path = config.Path + out.rotator.Name = config.Filename + if out.rotator.Name == "" { + out.rotator.Name = config.Index + } + logp.Info("File output base filename set to: %v", out.rotator.Name) + + // disable bulk support + configDisableInt := -1 + config.FlushInterval = &configDisableInt + config.BulkMaxSize = &configDisableInt + + rotateeverybytes := uint64(config.RotateEveryKb) * 1024 + if rotateeverybytes == 0 { + rotateeverybytes = 10 * 1024 * 1024 + } + logp.Info("Rotate every bytes set to: %v", rotateeverybytes) + out.rotator.RotateEveryBytes = &rotateeverybytes + + keepfiles := config.NumberOfFiles + if keepfiles == 0 { + keepfiles = 7 + } + logp.Info("Number of files set to: %v", keepfiles) + + out.rotator.KeepFiles = &keepfiles + + err := out.rotator.CreateDirectory() + if err != nil { + return err + } + + err = out.rotator.CheckIfConfigSane() + if err != nil { + return err + } + + return nil +} + +func (out *fileOutput) PublishEvent( + trans outputs.Signaler, + opts outputs.Options, + event common.MapStr, +) error { + jsonEvent, err := json.Marshal(event) + if err != nil { + // mark as success so event is not sent again. + outputs.SignalCompleted(trans) + + logp.Err("Fail to convert the event to JSON: %s", err) + return err + } + + err = out.rotator.WriteLine(jsonEvent) + if err != nil { + if opts.Guaranteed { + logp.Critical("Unable to write events to file: %s", err) + } else { + logp.Err("Error when writing line to file: %s", err) + } + } + outputs.Signal(trans, err) + return err +} diff --git a/vendor/github.com/elastic/beats/libbeat/outputs/kafka/client.go b/vendor/github.com/elastic/beats/libbeat/outputs/kafka/client.go new file mode 100644 index 0000000..123a749 --- /dev/null +++ b/vendor/github.com/elastic/beats/libbeat/outputs/kafka/client.go @@ -0,0 +1,188 @@ +package kafka + +import ( + "encoding/json" + "expvar" + "sync" + "sync/atomic" + "time" + + "github.com/Shopify/sarama" + + "github.com/elastic/beats/libbeat/common" + "github.com/elastic/beats/libbeat/logp" +) + +type client struct { + hosts []string + topic string + useType bool + config sarama.Config + + producer sarama.AsyncProducer + + wg sync.WaitGroup + + isConnected int32 +} + +type msgRef struct { + count int32 + err atomic.Value + batch []common.MapStr + cb func([]common.MapStr, error) +} + +var ( + ackedEvents = expvar.NewInt("libbeatKafkaPublishedAndAckedEvents") + eventsNotAcked = expvar.NewInt("libbeatKafkaPublishedButNotAckedEvents") + publishEventsCallCount = expvar.NewInt("libbeatKafkaPublishEventsCallCount") +) + +func newKafkaClient(hosts []string, topic string, useType bool, cfg *sarama.Config) (*client, error) { + c := &client{ + hosts: hosts, + useType: useType, + topic: topic, + config: *cfg, + } + return c, nil +} + +func (c *client) Connect(timeout time.Duration) error { + debugf("connect: %v", c.hosts) + + c.config.Net.DialTimeout = timeout + + // try to connect + producer, err := sarama.NewAsyncProducer(c.hosts, &c.config) + if err != nil { + logp.Err("Kafka connect fails with: %v", err) + return err + } + + c.producer = producer + + c.wg.Add(2) + go c.successWorker(producer.Successes()) + go c.errorWorker(producer.Errors()) + atomic.StoreInt32(&c.isConnected, 1) + + return nil +} + +func (c *client) Close() error { + if c.IsConnected() { + debugf("closed kafka client") + + c.producer.AsyncClose() + c.wg.Wait() + atomic.StoreInt32(&c.isConnected, 0) + c.producer = nil + } + return nil +} + +func (c *client) IsConnected() bool { + return atomic.LoadInt32(&c.isConnected) != 0 +} + +func (c *client) AsyncPublishEvent( + cb func(error), + event common.MapStr, +) error { + return c.AsyncPublishEvents(func(_ []common.MapStr, err error) { + cb(err) + }, []common.MapStr{event}) +} + +func (c *client) AsyncPublishEvents( + cb func([]common.MapStr, error), + events []common.MapStr, +) error { + publishEventsCallCount.Add(1) + debugf("publish events") + + ref := &msgRef{ + count: int32(len(events)), + batch: events, + cb: cb, + } + + ch := c.producer.Input() + + for _, event := range events { + topic := c.topic + if c.useType { + topic = event["type"].(string) + } + + jsonEvent, err := json.Marshal(event) + if err != nil { + ref.done() + continue + } + + msg := &sarama.ProducerMessage{ + Metadata: ref, + Topic: topic, + Value: sarama.ByteEncoder(jsonEvent), + } + + ch <- msg + } + + return nil +} + +func (c *client) successWorker(ch <-chan *sarama.ProducerMessage) { + defer c.wg.Done() + defer debugf("Stop kafka ack worker") + + for msg := range ch { + ref := msg.Metadata.(*msgRef) + ref.done() + } +} + +func (c *client) errorWorker(ch <-chan *sarama.ProducerError) { + defer c.wg.Done() + defer debugf("Stop kafka error handler") + + for errMsg := range ch { + msg := errMsg.Msg + ref := msg.Metadata.(*msgRef) + ref.fail(errMsg.Err) + } +} + +func (r *msgRef) done() { + r.dec() +} + +func (r *msgRef) fail(err error) { + debugf("Kafka publish failed with: %v", err) + + r.err.Store(err) + r.dec() +} + +func (r *msgRef) dec() { + i := atomic.AddInt32(&r.count, -1) + if i > 0 { + return + } + + debugf("finished kafka batch") + + var err error + v := r.err.Load() + if v != nil { + err = v.(error) + eventsNotAcked.Add(int64(len(r.batch))) + r.cb(r.batch, err) + } else { + ackedEvents.Add(int64(len(r.batch))) + r.cb(nil, nil) + } +} diff --git a/vendor/github.com/elastic/beats/libbeat/outputs/kafka/kafka.go b/vendor/github.com/elastic/beats/libbeat/outputs/kafka/kafka.go new file mode 100644 index 0000000..2561a85 --- /dev/null +++ b/vendor/github.com/elastic/beats/libbeat/outputs/kafka/kafka.go @@ -0,0 +1,223 @@ +package kafka + +import ( + "errors" + "fmt" + "strings" + "time" + + "github.com/Shopify/sarama" + + "github.com/elastic/beats/libbeat/common" + "github.com/elastic/beats/libbeat/logp" + "github.com/elastic/beats/libbeat/outputs" + "github.com/elastic/beats/libbeat/outputs/mode" +) + +var debugf = logp.MakeDebug("kafka") + +func init() { + sarama.Logger = kafkaLogger{} + + outputs.RegisterOutputPlugin("kafka", kafkaOutputPlugin{}) +} + +type kafkaOutputPlugin struct{} + +type kafka struct { + mode mode.ConnectionMode +} + +var ( + kafkaDefaultTimeout = 30 * time.Second + kafkaDefaultKeepAlive = 0 * time.Second + kafkaDefaultCompression = sarama.CompressionSnappy + kafkaDefaultClientID = "beats" + kafkaDefaultTopicsFromType = false +) + +var ( + compressionModes = map[string]sarama.CompressionCodec{ + "none": sarama.CompressionNone, + "no": sarama.CompressionNone, + "off": sarama.CompressionNone, + "gzip": sarama.CompressionGZIP, + "snappy": sarama.CompressionSnappy, + } +) + +var ( + errNoTopicSet = errors.New("No topic configured") + errNoHosts = errors.New("No hosts configured") +) + +func (p kafkaOutputPlugin) NewOutput( + config *outputs.MothershipConfig, + topologyExpire int, +) (outputs.Outputer, error) { + output := &kafka{} + err := output.init(config) + if err != nil { + return nil, err + } + return output, nil +} + +func (k *kafka) init(config *outputs.MothershipConfig) error { + debugf("initialize kafka output") + + cfg, retries, err := newKafkaConfig(config) + if err != nil { + return err + } + + hosts := config.Hosts + if len(hosts) < 1 { + logp.Err("Kafka configuration failed with: %v", errNoHosts) + return errNoHosts + } + debugf("hosts: %v", hosts) + + useType := kafkaDefaultTopicsFromType + if config.UseType != nil { + useType = *config.UseType + } + + topic := config.Topic + if topic == "" && !useType { + logp.Err("Kafka configuration failed with: %v", errNoTopicSet) + return errNoTopicSet + } + + var clients []mode.AsyncProtocolClient + worker := 1 + if config.Worker > 1 { + worker = config.Worker + } + for i := 0; i < worker; i++ { + client, err := newKafkaClient(hosts, topic, useType, cfg) + if err != nil { + logp.Err("Failed to create kafka client: %v", err) + return err + } + + clients = append(clients, client) + } + + mode, err := mode.NewAsyncConnectionMode( + clients, + false, + retries, // retry implemented by kafka client + cfg.Producer.Retry.Backoff, + cfg.Net.WriteTimeout, + 10*time.Second) + if err != nil { + logp.Err("Failed to configure kafka connection: %v", err) + return err + } + + k.mode = mode + return nil +} + +func (k *kafka) PublishEvent( + signal outputs.Signaler, + opts outputs.Options, + event common.MapStr, +) error { + return k.mode.PublishEvent(signal, opts, event) +} + +func (k *kafka) BulkPublish( + signal outputs.Signaler, + opts outputs.Options, + event []common.MapStr, +) error { + return k.mode.PublishEvents(signal, opts, event) +} + +func newKafkaConfig(config *outputs.MothershipConfig) (*sarama.Config, int, error) { + k := sarama.NewConfig() + modeRetries := 1 + + // configure network level properties + timeout := kafkaDefaultTimeout + if config.Timeout > 0 { + timeout = time.Duration(config.Timeout) * time.Second + } + + k.Net.DialTimeout = timeout + k.Net.ReadTimeout = timeout + k.Net.WriteTimeout = timeout + + if config.TLS != nil { + tls, err := outputs.LoadTLSConfig(config.TLS) + if err != nil { + return nil, modeRetries, err + } + k.Net.TLS.Enable = true + k.Net.TLS.Config = tls + } + + keepAlive := kafkaDefaultKeepAlive + if config.KeepAlive != "" { + var err error + keepAlive, err = time.ParseDuration(config.KeepAlive) + if err != nil { + return nil, modeRetries, err + } + } + k.Net.KeepAlive = keepAlive + + // TODO: configure metadata level properties + // use lib defaults + + // configure producer API properties + if config.MaxMessageBytes != nil { + k.Producer.MaxMessageBytes = *config.MaxMessageBytes + } + if config.RequiredACKs != nil { + k.Producer.RequiredAcks = sarama.RequiredAcks(*config.RequiredACKs) + } + if config.BrokerTimeout != "" { + var err error + k.Producer.Timeout, err = time.ParseDuration(config.BrokerTimeout) + if err != nil { + return nil, modeRetries, err + } + } + compressionMode := kafkaDefaultCompression + if config.Compression != "" { + mode, ok := compressionModes[strings.ToLower(config.Compression)] + if !ok { + return nil, modeRetries, fmt.Errorf("Unknown compression mode: %v", config.Compression) + } + compressionMode = mode + } + k.Producer.Compression = compressionMode + + k.Producer.Return.Successes = true // enable return channel for signaling + k.Producer.Return.Errors = true + + if config.MaxRetries != nil { + retries := *config.MaxRetries + if retries < 0 { + retries = 10 + modeRetries = -1 + } + k.Producer.Retry.Max = retries + } + + // configure client ID + clientID := kafkaDefaultClientID + if config.ClientID != "" { + clientID = config.ClientID + } + k.ClientID = clientID + + if err := k.Validate(); err != nil { + logp.Err("Invalid kafka configuration: %v", err) + return nil, modeRetries, err + } + return k, modeRetries, nil +} diff --git a/vendor/github.com/elastic/beats/libbeat/outputs/kafka/log.go b/vendor/github.com/elastic/beats/libbeat/outputs/kafka/log.go new file mode 100644 index 0000000..ef257a1 --- /dev/null +++ b/vendor/github.com/elastic/beats/libbeat/outputs/kafka/log.go @@ -0,0 +1,17 @@ +package kafka + +import "github.com/elastic/beats/libbeat/logp" + +type kafkaLogger struct{} + +func (kafkaLogger) Print(v ...interface{}) { + logp.Warn("kafka message: %v", v) +} + +func (kafkaLogger) Printf(format string, v ...interface{}) { + logp.Warn(format, v) +} + +func (kafkaLogger) Println(v ...interface{}) { + logp.Warn("kafka message: %v", v) +} diff --git a/vendor/github.com/elastic/beats/libbeat/outputs/logstash/ca_invalid_test.key b/vendor/github.com/elastic/beats/libbeat/outputs/logstash/ca_invalid_test.key new file mode 100644 index 0000000..86dbd0d --- /dev/null +++ b/vendor/github.com/elastic/beats/libbeat/outputs/logstash/ca_invalid_test.key @@ -0,0 +1,51 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIJJwIBAAKCAgEArhcGQkUS9v6aPeePxSOop/rh+Lc/IEW1NQE80lFJ6d6yFiN2 +kX0VHZsWUhsH86vjE7sDk+Uu82oNCOjc+Zq14jK0Z0ISzhdTsvryJ8paMb/Bn2bk +szEBvE57e6DKF+hJuITW6RJKASaU4FIBNkWsE16bIOgM1HZXNX+yESFc0w3OUCO7 +nNv3FBfyLS2x52sjKIZLc5RVqeC7F344OdRp6QVZzQsM1pMWsTd8Xalpj1H1aOsm +74WkHyYLthB4mV9g+arTvWBVafNDAXftFu1TmLMGm8ILduqQURxGasOPoNoEF5J4 +Rnhlp9AerB15haKdANls0X+htEy+1mnV5nsFodAsj0ZQ9ReETNkPMdHudXCrF9hh +JeBkFE3+O7059qJZH4u73opXQYFhOi/M7fpupWVmByzKkvvU8NmcCgtgtrWUlkxP +aLtoxF6JSjghuAmv9VKMLFNrHEcC9SDA8g7JcPRogGQowEOca7i9MkeKvO+BZAHR +qHHhHr/9TQ8Fym9IyR/vQZUe9ue4aNsWqsBjHhTlDKqtfMvL7/bT+h+f9+Y26CET +kfaz0WFPfwOY5jYaA6xfU6BiYJXwFHfWgV63cG+RolUIPNmV0hl2uMpk22QsTsOJ +9kIihXizh2X7aO+2ol+doxZq0jis+1pJaLtTV5/FOGa5Fx1pCys44O/No+ECAwEA +AQKCAgAnVzio3Sct/dcpShzpNee1HjLWm8J+LoKGmeL+vDPxz8t6yUTQF+4fpJ5k +q4see6dzG/3w/AeiJkMP0l+tYFLd7Qtrkjjhrc/SUHdMmqPLPkQpG31vKRH1Vd79 +zxYcVPfj5NEUFnf2zpsyHhX8B76dGfIAe6/6i0ul4VeCG4H4h9QptAl/pw2s0sR9 +hSgA3esyCzcdxVWecBSXeISIPQI6EGV8upSKIO8t2RYXrGMYajMFJK7FzfOKvnRD +DnHSZwVpJjt3Pj/PE5P+zvUbC0Kq7Tn/FNi2ZMd8LOGU2uCoPtxR312ivy5pv9RO +nNKLanYEbR30Md1++yDdH0mhLgfVa9kHSyZrlJa6cFqWlrcZwE5Zg0R3B+TLbtrA +WFZdV26u5ICbqYl3e/EhlIVJgLbmYjD88anXTSAObi1rwm6cAwd7+vM6PQkqlOGV +mUyjhvRSIpL/DTrAtUwud25yloDRCMVibxeJSkek+bbnMuf+vvVMs67MgDB2B+iN +OHLNKZZfllao/ZvPWiGjUkCIwwHLn6BkJNvNXeBwiof/sOtj56r23R0aEMU5aXvd +Ogq1lbEQZEmRLfmSoEIxC2gSQ4q8qevUQSmJp05fzQho+JjWVHZp6trSkeXIpgnS +E5YYCeGsGzkkT6CGI46R7XXvV9HzvM7RCMx7rH44V2InoZHs4QKCAQEA2gvymAGj +Rpa4p3cYAUcMD6eddPMkRpEX483ibS2ygaSzXy6uNMs7AEc5VJ4dg+uXACxita8w +rXpuNRBoPkkRIm4DiPX2y9jTTismYo4ZelyfjI05g7GhosXtlmMgQWEfL/JDlPXn +0pRBDhWXZ02Inw2AD+YMFC2hV2qqc226jIvLirHEZeO2TWJWIQWqh1nWW3bP/tdO +LyfzrZo5vxy0Ucmw0NwGXPg057XVEiaoN2XSEUNTMzz9HlPWCDkXrXfoEaEN1qFq +6f9K+UJE11sMP0cZ+AbzVw2w9YbAmz1lLiI0P51AUkLdvH99bgp46raN+xN7fZmK +6rb/VTld6b9YVQKCAQEAzGRi8Z//CP9L0ULMHGeneqnoOlMsf2FT0SOJasJbvlCK +Z0MZjJl0ukWSRNFMeE18hT+97tkg+/s9W6MkPa875ZPEMUPaIQJp47vAJm9FTdDP +T3dU/WWBsXa7oPXUNLd2AVWmjfaUye7WvR4rJR5xJKZwfqJIM9pypoOuT2YLUMlY +xQNrwYXo3LIlU/rkb3nv2rAZYxCsNvhMKdNY/j4bdXhocA7D9C745/+r2KAONecm +fDQSjLJTOL7ldOKPn6svF7eRrSVCRx80D7X06tBNGWejDib+Io/k79L+OEuo1ZEl +Z/3nnDY8qxz5yoG26jUU5Eu4j7IfG+FcHgBbykFZXQKCAQAItCFi3+3ci3ejd6WF +p4hbt50ZZfs0teX2Oemn4gMWGbTvP7XEdbhNMoqfThBvi5/jaeImzm9q/VAY3ibL +Fa+RaELL3MWVLXqBzEcj9/gcYkYcHicFkrmY/b2WGy7WbUIJb+oyr/4o8bIHFeWN +QhMKBkfuWohw5cFi8+cJ5H9lzM67Io1sY8KLJDm757X+4R8lV4DF82Izj6yyaU2U +y1iHSz27mIzIeT/jX+a5asGcNHxGJCHWEcEozL/mZCEF05t32K3su1TBMmeTu4lz +7zZ18CihNeXQu8Msicx2ZeT8CnF7eJNwtSqUs6IWGmTpOZBBTW3IfbCF3fgjNr8A +7ZphAoIBACZETToLyIX4tksxhGF1Dqgqk24IEHaw1C59xsaUKPUSwzbeGzR1rqMJ +T39O6FBFwaB49Kh5QnGq8ivr+WcLHd23sq2+lGJFv2mBx1Hq10DgbU/leaYPkR6W +qj5SiC5ugstxK8O8fNLpwo6ZzV4fuvMvrjQnUflTVs/SK5p18nxnlhUctNoApj5b +pB17BbXRUJTTD426m2OXTTsvdKP1INL3fiYsvYdEHBnjhlsCbGavJkduwGJTKL2h +D/i4SkeMlz6Lgdy28xe5wdeHK5mi8ixleOO3bTEvW5+DE1Ga6LtDd4tmwCxBA07O +F/5QFtz2nzi27JEKukRQBx0e2BCf94kCggEAaRLB2hJVjjbDf/QaXjy6+a+xUEOk +2EjbaKYLFp0GDs+0CaXBdXHh36X2vOXaT2TN08hEyL3ToirttVufKhPiG4zxDKQc +uskOG1KK5deEAiuHkjGb47J5HJcL4OwpaRDxKWihtaT6H0Dt6TawPLVViIUdEGIF +5dbOMHFch/Nz0hrr08azZf+JJ7b+40q3uCCLUleP7PA19Ye1EqVsHyX1oXhpWAWR +OT5c/DX61DT3PAZytyDmQh6G46vMMtaDXbwDbSA5rIglZgTlBoOMwR4qOzFOope4 +cBO55H8mNu/SeC36QaxJiFMeOnBo2FW3oSt0mZOb/EHlzwetGq3SO9zy5g== +-----END RSA PRIVATE KEY----- diff --git a/vendor/github.com/elastic/beats/libbeat/outputs/logstash/ca_invalid_test.pem b/vendor/github.com/elastic/beats/libbeat/outputs/logstash/ca_invalid_test.pem new file mode 100644 index 0000000..f75899d --- /dev/null +++ b/vendor/github.com/elastic/beats/libbeat/outputs/logstash/ca_invalid_test.pem @@ -0,0 +1,31 @@ +-----BEGIN CERTIFICATE----- +MIIFXTCCA0WgAwIBAgIQCYZiCOjXqDaqWrOaCNv+JDANBgkqhkiG9w0BAQ0FADAv +MQswCQYDVQQGEwJVUzEQMA4GA1UEChMHZWxhc3RpYzEOMAwGA1UECxMFYmVhdHMw +HhcNMTUxMTA0MTUwMTM0WhcNMjUxMTA0MTUwMTM0WjAvMQswCQYDVQQGEwJVUzEQ +MA4GA1UEChMHZWxhc3RpYzEOMAwGA1UECxMFYmVhdHMwggIiMA0GCSqGSIb3DQEB +AQUAA4ICDwAwggIKAoICAQCuFwZCRRL2/po954/FI6in+uH4tz8gRbU1ATzSUUnp +3rIWI3aRfRUdmxZSGwfzq+MTuwOT5S7zag0I6Nz5mrXiMrRnQhLOF1Oy+vInylox +v8GfZuSzMQG8Tnt7oMoX6Em4hNbpEkoBJpTgUgE2RawTXpsg6AzUdlc1f7IRIVzT +Dc5QI7uc2/cUF/ItLbHnayMohktzlFWp4LsXfjg51GnpBVnNCwzWkxaxN3xdqWmP +UfVo6ybvhaQfJgu2EHiZX2D5qtO9YFVp80MBd+0W7VOYswabwgt26pBRHEZqw4+g +2gQXknhGeGWn0B6sHXmFop0A2WzRf6G0TL7WadXmewWh0CyPRlD1F4RM2Q8x0e51 +cKsX2GEl4GQUTf47vTn2olkfi7veildBgWE6L8zt+m6lZWYHLMqS+9Tw2ZwKC2C2 +tZSWTE9ou2jEXolKOCG4Ca/1UowsU2scRwL1IMDyDslw9GiAZCjAQ5xruL0yR4q8 +74FkAdGoceEev/1NDwXKb0jJH+9BlR7257ho2xaqwGMeFOUMqq18y8vv9tP6H5/3 +5jboIROR9rPRYU9/A5jmNhoDrF9ToGJglfAUd9aBXrdwb5GiVQg82ZXSGXa4ymTb +ZCxOw4n2QiKFeLOHZfto77aiX52jFmrSOKz7Wklou1NXn8U4ZrkXHWkLKzjg782j +4QIDAQABo3UwczAOBgNVHQ8BAf8EBAMCAqQwHQYDVR0lBBYwFAYIKwYBBQUHAwIG +CCsGAQUFBwMBMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0OBAcEBTEyMzQ1MBAGA1Ud +IwQJMAeABTEyMzQ1MA8GA1UdEQQIMAaHBAECAwQwDQYJKoZIhvcNAQENBQADggIB +AIguXLlBE+gos9aWQ1794sQqUspsNS3kTzvXtZJPAn/egTtmYHIkELyDjUxTAPCQ +OtoTEcVRQuj1dKVva0To4IS3J7K6blDuttwcKUaQ+n/Uop45b16f+/WslZLnyGFy +qiJ6tv9hY4uXQZOoOS3NDV6ip1EPmop71bsMVyOxbXtIueT2RYbs5G0qgfKyUozD +fP7I6qzRF5lNUL+uynulk/2KmOvT61248DnT/4AwPuJZMRVQug6PBDICSBaVOpdG +1gm6w0JfCDjv6hYSoSebhdrWVl2H2T2RX5c31CDeJij1saNnL1pLBNDBon7GnlFz +rpgJRlox6zVnY9hWxA7qkBbLd0n27yXQU3JeHAsfwdYyPPTD6JeK6UYkKX+LoYan +cozuv2N/22cMUjFgB6MvaPDUBUbnq3koM+4OMJyOAFla8v8G78p6rEI4moEH68qi +BCF0KZzJCgDs8o2nWN2aoDu9h0bqOMBwxcOYgwf9ZQyav1hApdZ7OTFbZN+J4/AC +5f1Q2axOH9AuXrI8CjXbR2d3iEXRP2y0QNH59Cqrmhdghq5pxfSOB59EQjdCKRYq +7uAD12OdZp5DrCvZMlo9qzS8FdaN3xdEKiYArOe9aIx2J4gkNaPc0xh3czP/q5N6 +mhMyGAR8+xTxwCVfFXD9RqQiqgnaCLu09m4vqaWmHeTb +-----END CERTIFICATE----- diff --git a/vendor/github.com/elastic/beats/libbeat/outputs/logstash/ca_test.key b/vendor/github.com/elastic/beats/libbeat/outputs/logstash/ca_test.key new file mode 100644 index 0000000..c99ae6c --- /dev/null +++ b/vendor/github.com/elastic/beats/libbeat/outputs/logstash/ca_test.key @@ -0,0 +1,51 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIJKQIBAAKCAgEAqtICiIhf/xCLA+aaFYFvzjR10sktSDhDRS4hYNkVBxrBvYfp +n25X3BzZjemk9RmAwYrY0G00EMFJxMCd4h7OpRTmB4VdG7+WK/kD2P2or7R9o4W5 +ueOO6q9A39SqPDEi2hTYPUlxD27sGPVUJZORwqyZM85R9jcwVdTgN3U4Q1e/ifZP +yZxLNhORoC+O8w9BuJ+RQpSEWPq0VH7srf0aGNJbwrrbxd1dQMMhuJYWKZtcliok +HF9uRV2P/7tC/+CFVJuGLgMbvpHB/yuYj9Tf0/4PwSP+quWbjsDF1wGejwRipjF+ +IfCcYMLL4vrKA3RxSV5NroANC31h4MSPxN4OiOMudAOgGD8UvznV/fOol2gK9RpQ +B6T+eamrJpG3gAbSTdPVLMdbjksgzQIAH0LlF4tFztmriArKDUcN7/koiRFs60jX +7+TfrHnhZtRONAkereJjTfZ06gSkt4FAQ0AvWSYc9uS8A3jSNQv1c57XwxacbCOv +adG2+v4BV3JZoBGF8ikg12xevBSmUKQNi/5s9Lvr223wHnICYOto3P+4CAFLhICK +yG7AIvSIgdhXaOUH1LPL+oXyjKRw0BJh9LQcTk8TfQ6RzBaN6vv8zFHgeYdA4Bl4 +otyveTsDKAqN3qFloZDh/thlBDD6efWtDN1I3uGm1TAKEjdnaOgaAm0SzvECAwEA +AQKCAgEApCMp1gGcpF1EBtqFglaelThpYsJ2ZWfSk93wqrvM7cezFChNvylq+REr +pqY0IGOCCfcdwKC+H79q38jprIZHr+513hIy1l/wr44WOWH7veGjvAXZ4ZmcETuX +DbyuWyonv/+5jKJOJjNCX/UUBwtWSwZIK7R7oyeCpWboj8Ft75+YZ7urDSHGT07c +ZlxscnddgkapcJ1+0nUL5AkV6VVDx0gSbfnZBbZgTcNyWoi1AQPNImmZyz2Tmsl9 +fZB1n6Mg2pyagQnxlds+2q8MaGB3Np9wifjJU3NPVws6zw86SVhAZks2VOx7hqqG ++TJb/Jfd507bO+rFHh47d5vIPbXVpfbwngOvEwd0SLNJdtlsB3ugtLlzlqocEp9F +DUmL0VOggO5U+5NruGhEYOC88dJxZ/0IUaDRv8Em4zVDJ0DAYYcdRTFbobfvmj3b +75UB1F7AphiPTC7mthKZDaCojHJgcZUddKIFnCDi9NDIpzxgfhgC0AupabE3yuC0 +xBO3Hk8oKqWVdQH/FKEmd/uLOaQ+BIk0zW5DH2qeFI1m2mLKxYJQ/BFNk47EXpjp +Q9Ldc82EAbC5Fnt/EOWEgZXiWti10DsfXwmV0b5kyIJb5ALlko03t89HNhdH6JgM +VXZ8J8dLy0KrZ6c88IBiXq8belW+KrwIzdPQcwqGhs/3iLZElKUCggEBAMoPc9kZ +/Z2jgeGKq/amlowlHPq1xfnw5iYHWUOu/WaS017dvzYKhLbVt9SjGSmj+g1/WIrr +RQgzgt5zjdXBVYqbASd/duBBJxEtZLIUvTRosXnpyZTw+Axya7zWVi3AV+VNp79V +x86un338gonS++BwXidbpLgEPyenvL+Hp0HEqgmTwRXYVA/MJEA17E5cOld9scEz +/UEwI2m7zPOHdRddZORpIPUIfI7YggCXN3gPpJdrD5cXNcZZkxaLyqATMhXPk3dY +VCN61j+dCr70/vw+olkQsAWnPtFaH2j4+sjBG/RRtnWen/pS5j0ZwJWXdGR44Yy7 +IsOcmQM8Sx+i+0sCggEBANhrp6cMu8pnAb3/YZIhFiZmjmZYMSHMsji7KaC/hgfk +TQ6Zpsve+MHjy/Y8Rq1pMENFbc12fNSRJhDZdRpeGzCspsErxnEzSJlusb1morJM +cN9Fe7BKvUQ9f7On+jUDUBzEbGnxOQpe8ipt38GGH7a6NR+xYfidA0cXtS1wZvIc +yGcZTIFhX6Gl3psTZfKEXVWIr5RIyLQs0jTwY00N0agAk/z9vhOm3wyXHwjoDMtB +V0rtKdP1f1zvx9epCYxJXqEqiV/7i6o/bt+qsn4k5OxDqr+ocB7P3kdH6LxwJsQt +CtwlLcSkoG404EzI+C6At3J2GypueVpxdPTvPhgh3TMCggEAKo6EnMYPl2L3mPQm +8cT2UkAC0X71WoX1Qy8rCslRT4g/Amz7t7sRZpyuohdT1mRV5v/aOzAAExEeUBHQ +XqPgi1fIL3R2KhcuzjxcR/F8RAyEzKODtF3oMF7s+BHAhtRK7t2jJfZAJfS7XMKR +D8wjBotEGVAA6kzirEx0wXYlsQFluqym7x3n3oflXqy8v2hHVWQAyytS/KbR3pQS +P3xZGfmupTjLGzCVY1SQVOWEZkINLWL8Hpth1QvKoeYBYCOK2fMlIO62kd5uP2mo ++L0K8z+R2+Za3GX0Ig20Ldy6nQunApcvMaieEw/gtB+3YwpKFlsrTgOf98kEpRzO +ybP+7wKCAQEApEmk7UTXUaC8S9UP5nRDckcsFjkgov3W1QYPZb2+K0N903WEjwLm +Z5lbfcLoDD/rqUWNQwmNXXgKI4RQRwHlNh/6Pm3SqKA7nm3Pc230V9F7ZaJDcOJr +pt/gjysW3yNyr0PU4N+DY4IL53WdBDWi4X2dUj+/lZDrqg4vNR08qNJ8tvcXgqe+ +huF5iNNC8sTUbVfjoXdXFJ9pu1I4r4er/hLiRI0Cu7xTWiVmI8az35/sei5rMEIO +uygy1l21p88SjNnTiw9TSJv6uMPF18h+F3SOrAtbgahenlHSNSoV45olwlRe2AX4 +23A8TU3KSNLhb3yExsMyUBwMotrykjMyzQKCAQBAqHdDwMhyA4ePIBzFiOcJv/eD +8SwV/XWvinXZFm23d0jDzjqOg5Nzwk2lqvFjulxxSxTEFpWO7YOfuXBPiOor0brb +By6YMlzuawhUZGnDHGnr4wZCmc1AbLiVnQPy/R5PV8fK51wgArrJBTFpFZ4Ahcnj +9G7V8PBQZIMrscKxWfIPfF7YrNAclbn2+0NhX+MXU0zvfl2ATMpJzh1JMF4pFUzy +hOpORDxlRPXhgEqiPbrN5qhOcLIHYdVvEvhmXuwulOj3Li72o5SHH7ML6xCP0y0I +s1XvYciN9I9ejZJYvwug4jzUCZauWBbzpxbD9de1Ot4d9Opolcp8431DkVcn +-----END RSA PRIVATE KEY----- diff --git a/vendor/github.com/elastic/beats/libbeat/outputs/logstash/ca_test.pem b/vendor/github.com/elastic/beats/libbeat/outputs/logstash/ca_test.pem new file mode 100644 index 0000000..b6b0968 --- /dev/null +++ b/vendor/github.com/elastic/beats/libbeat/outputs/logstash/ca_test.pem @@ -0,0 +1,31 @@ +-----BEGIN CERTIFICATE----- +MIIFWTCCA0OgAwIBAgIQCzNW6Ri1mnAkXoqs/CeL2DALBgkqhkiG9w0BAQ0wLzEL +MAkGA1UEBhMCVVMxEDAOBgNVBAoTB2VsYXN0aWMxDjAMBgNVBAsTBWJlYXRzMB4X +DTE1MDkxMDIyMDkzOVoXDTI1MDkxMDIyMDkzOVowLzELMAkGA1UEBhMCVVMxEDAO +BgNVBAoTB2VsYXN0aWMxDjAMBgNVBAsTBWJlYXRzMIICIjANBgkqhkiG9w0BAQEF +AAOCAg8AMIICCgKCAgEAqtICiIhf/xCLA+aaFYFvzjR10sktSDhDRS4hYNkVBxrB +vYfpn25X3BzZjemk9RmAwYrY0G00EMFJxMCd4h7OpRTmB4VdG7+WK/kD2P2or7R9 +o4W5ueOO6q9A39SqPDEi2hTYPUlxD27sGPVUJZORwqyZM85R9jcwVdTgN3U4Q1e/ +ifZPyZxLNhORoC+O8w9BuJ+RQpSEWPq0VH7srf0aGNJbwrrbxd1dQMMhuJYWKZtc +liokHF9uRV2P/7tC/+CFVJuGLgMbvpHB/yuYj9Tf0/4PwSP+quWbjsDF1wGejwRi +pjF+IfCcYMLL4vrKA3RxSV5NroANC31h4MSPxN4OiOMudAOgGD8UvznV/fOol2gK +9RpQB6T+eamrJpG3gAbSTdPVLMdbjksgzQIAH0LlF4tFztmriArKDUcN7/koiRFs +60jX7+TfrHnhZtRONAkereJjTfZ06gSkt4FAQ0AvWSYc9uS8A3jSNQv1c57Xwxac +bCOvadG2+v4BV3JZoBGF8ikg12xevBSmUKQNi/5s9Lvr223wHnICYOto3P+4CAFL +hICKyG7AIvSIgdhXaOUH1LPL+oXyjKRw0BJh9LQcTk8TfQ6RzBaN6vv8zFHgeYdA +4Bl4otyveTsDKAqN3qFloZDh/thlBDD6efWtDN1I3uGm1TAKEjdnaOgaAm0SzvEC +AwEAAaN1MHMwDgYDVR0PAQH/BAQDAgCkMB0GA1UdJQQWMBQGCCsGAQUFBwMCBggr +BgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDgQHBAUxMjM0NTAQBgNVHSME +CTAHgAUxMjM0NTAPBgNVHREECDAGhwR/AAABMAsGCSqGSIb3DQEBDQOCAgEAaV5F +ZCNsyNVUmRMRxMDzp0qMx6PcOa9cTUaPJfmDRiDJvAbQHtyGy0FfxV8FBDoTkWw7 +uU064V+7mNIwYtYesvMgv1pamF3xfmEekO1YSJJqCDXmkcOGPutlPTcldUbLc+sz +87YrMPEQkJ3ZHdes0mnycEYsJsBoaKfcqEFoSo3VQI/0ojpNkIIPFQNnmU7Z5NNa +IY7BelEksX6gupC5GKy15vnQheBdla5S8SmsdG1osbEZWyFWMf6iZFQoxLtoIKtE +7DRZo0MGmxu2/XyWyOXBKm8aIkVtdJOLzetZSvDxvTXXv9RYrd/x0YikE5qKzpwP +PMagZgkJa3lnq9umlkSCYHaaoTUPlScVV3H0CmfpsgwKQrOwgGPVRlGW/PqVHDli +3rzX7KnBOIdyy/jKYe6deJ3oU1BAa3yt8ccQ7uYToTWA4IAVXPhI0CLmO2eexYHB +dIp7YpnSJu4wr6OOPwwTaqXG8ii2b5VtzHdpLzSZ5XCOmMKnA6SZ89KZeV94Ti/V +FmFcBu9cm+TbaqpZRDRre7nXGthUGgPTzt7teppY6nPnsqFks3D7d5DnxFA2x3G5 +424Pt+KJDOVP2zilGVoiXczelU2YrVaSC6+0FRQPl4OBNl5uJp6qm7KnvYPFbZ2Y +9jo8KeLtg7sshxm8E5kuhtpFCJCHteXQltrp9lA= +-----END CERTIFICATE----- diff --git a/vendor/github.com/elastic/beats/libbeat/outputs/logstash/logstash.go b/vendor/github.com/elastic/beats/libbeat/outputs/logstash/logstash.go new file mode 100644 index 0000000..f8904fa --- /dev/null +++ b/vendor/github.com/elastic/beats/libbeat/outputs/logstash/logstash.go @@ -0,0 +1,186 @@ +package logstash + +// logstash.go defines the logtash plugin (using lumberjack protocol) as being registered with all +// output plugins + +import ( + "crypto/tls" + "time" + + "github.com/elastic/beats/libbeat/common" + "github.com/elastic/beats/libbeat/logp" + "github.com/elastic/beats/libbeat/outputs" + "github.com/elastic/beats/libbeat/outputs/mode" +) + +var debug = logp.MakeDebug("logstash") + +func init() { + outputs.RegisterOutputPlugin("logstash", logstashOutputPlugin{}) +} + +type logstashOutputPlugin struct{} + +func (p logstashOutputPlugin) NewOutput( + config *outputs.MothershipConfig, + topologyExpire int, +) (outputs.Outputer, error) { + output := &logstash{} + err := output.init(*config, topologyExpire) + if err != nil { + return nil, err + } + return output, nil +} + +type logstash struct { + mode mode.ConnectionMode + index string +} + +const ( + logstashDefaultPort = 10200 + + logstashDefaultTimeout = 30 * time.Second + defaultSendRetries = 3 + defaultMaxWindowSize = 2048 + defaultCompressionLevel = 3 +) + +var waitRetry = time.Duration(1) * time.Second + +// NOTE: maxWaitRetry has no effect on mode, as logstash client currently does not return ErrTempBulkFailure +var maxWaitRetry = time.Duration(60) * time.Second + +func (lj *logstash) init( + config outputs.MothershipConfig, + topologyExpire int, +) error { + useTLS := (config.TLS != nil) + timeout := logstashDefaultTimeout + if config.Timeout != 0 { + timeout = time.Duration(config.Timeout) * time.Second + } + + defaultPort := logstashDefaultPort + if config.Port != 0 { + defaultPort = config.Port + } + + maxWindowSize := defaultMaxWindowSize + if config.BulkMaxSize != nil { + maxWindowSize = *config.BulkMaxSize + } + + compressLevel := defaultCompressionLevel + if config.CompressionLevel != nil { + compressLevel = *config.CompressionLevel + } + + var clients []mode.ProtocolClient + var err error + if useTLS { + var tlsConfig *tls.Config + tlsConfig, err = outputs.LoadTLSConfig(config.TLS) + if err != nil { + return err + } + + clients, err = mode.MakeClients(config, + makeClientFactory(maxWindowSize, compressLevel, timeout, + makeTLSClient(defaultPort, tlsConfig))) + } else { + clients, err = mode.MakeClients(config, + makeClientFactory(maxWindowSize, compressLevel, timeout, + makeTCPClient(defaultPort))) + } + if err != nil { + return err + } + + sendRetries := defaultSendRetries + if config.MaxRetries != nil { + sendRetries = *config.MaxRetries + } + logp.Info("Max Retries set to: %v", sendRetries) + + maxAttempts := sendRetries + 1 + if sendRetries < 0 { + maxAttempts = 0 + } + + loadBalance := config.LoadBalance != nil && *config.LoadBalance + m, err := mode.NewConnectionMode(clients, !loadBalance, + maxAttempts, waitRetry, timeout, maxWaitRetry) + if err != nil { + return err + } + + lj.mode = m + lj.index = config.Index + + return nil +} + +func makeClientFactory( + maxWindowSize int, + compressLevel int, + timeout time.Duration, + makeTransp func(string) (TransportClient, error), +) func(string) (mode.ProtocolClient, error) { + return func(host string) (mode.ProtocolClient, error) { + transp, err := makeTransp(host) + if err != nil { + return nil, err + } + return newLumberjackClient(transp, compressLevel, maxWindowSize, timeout) + } +} + +func makeTCPClient(port int) func(string) (TransportClient, error) { + return func(host string) (TransportClient, error) { + return newTCPClient(host, port) + } +} + +func makeTLSClient(port int, tls *tls.Config) func(string) (TransportClient, error) { + return func(host string) (TransportClient, error) { + return newTLSClient(host, port, tls) + } +} + +// TODO: update Outputer interface to support multiple events for batch-like +// processing (e.g. for filebeat). Batch like processing might reduce +// send/receive overhead per event for other implementors too. +func (lj *logstash) PublishEvent( + signaler outputs.Signaler, + opts outputs.Options, + event common.MapStr, +) error { + lj.addMeta(event) + return lj.mode.PublishEvent(signaler, opts, event) +} + +// BulkPublish implements the BulkOutputer interface pushing a bulk of events +// via lumberjack. +func (lj *logstash) BulkPublish( + trans outputs.Signaler, + opts outputs.Options, + events []common.MapStr, +) error { + for _, event := range events { + lj.addMeta(event) + } + return lj.mode.PublishEvents(trans, opts, events) +} + +// addMeta adapts events to be compatible with logstash forwarer messages by renaming +// the "message" field to "line". The lumberjack server in logstash will +// decode/rename the "line" field into "message". +func (lj *logstash) addMeta(event common.MapStr) { + // add metadata for indexing + event["@metadata"] = common.MapStr{ + "beat": lj.index, + "type": event["type"].(string), + } +} diff --git a/vendor/github.com/elastic/beats/libbeat/outputs/logstash/protocol.go b/vendor/github.com/elastic/beats/libbeat/outputs/logstash/protocol.go new file mode 100644 index 0000000..7b2e9cd --- /dev/null +++ b/vendor/github.com/elastic/beats/libbeat/outputs/logstash/protocol.go @@ -0,0 +1,290 @@ +package logstash + +import ( + "bytes" + "compress/zlib" + "encoding/binary" + "encoding/json" + "errors" + "fmt" + "io" + "net" + "time" + + "github.com/elastic/beats/libbeat/common" + "github.com/elastic/beats/libbeat/logp" +) + +type protocol struct { + conn net.Conn + timeout time.Duration + compressLevel int + + eventsBuffer *bytes.Buffer +} + +var ( + // ErrProtocolError is returned if an protocol error was detected in the + // conversation with lumberjack server. + ErrProtocolError = errors.New("lumberjack protocol error") + + errAllEventsEncoding = errors.New("failed to encode all events") +) + +var ( + codeVersion byte = '2' + + codeWindowSize = []byte{codeVersion, 'W'} + codeJSONDataFrame = []byte{codeVersion, 'J'} + codeCompressed = []byte{codeVersion, 'C'} +) + +func newClientProcol( + conn net.Conn, + timeout time.Duration, + compressLevel int, +) (*protocol, error) { + + // validate by creating and discarding zlib writer with configured level + if compressLevel > 0 { + tmp := bytes.NewBuffer(nil) + w, err := zlib.NewWriterLevel(tmp, compressLevel) + if err != nil { + return nil, err + } + w.Close() + } + + return &protocol{ + conn: conn, + timeout: timeout, + compressLevel: compressLevel, + eventsBuffer: bytes.NewBuffer(nil), + }, nil +} + +func (p *protocol) Close() error { + return p.conn.Close() +} + +func (p *protocol) sendEvents(events []common.MapStr) ([]common.MapStr, error) { + conn := p.conn + if len(events) == 0 { + return nil, nil + } + + debug("send events") + + // serialize all raw events into output buffer, removing all events encoding failed for + outEvents, err := p.serializeEvents(events) + count := uint32(len(outEvents)) + if count == 0 { + // encoding of all events failed. Let's stop here and report all events + // as exported so no one tries to send/encode the same events once again + // The compress/encode function already prints critical per failed encoding + // failure. + debug("no events serializable") + return nil, errAllEventsEncoding + } + + // send window size: + debug("send window size") + if err := p.sendWindowSize(count); err != nil { + return nil, err + } + + if p.compressLevel > 0 { + err = p.sendCompressed(p.eventsBuffer.Bytes()) + } else { + debug("write events") + _, err = conn.Write(p.eventsBuffer.Bytes()) + } + if err != nil { + return nil, err + } + + debug("did send %v events", count) + return outEvents, nil +} + +func (p *protocol) recvACK() (uint32, error) { + conn := p.conn + + if err := conn.SetReadDeadline(time.Now().Add(p.timeout)); err != nil { + return 0, err + } + + response := make([]byte, 6) + ackbytes := 0 + for ackbytes < 6 { + n, err := conn.Read(response[ackbytes:]) + if err != nil { + debug("read ack sequence failed with: %v", err) + return 0, err + } + ackbytes += n + } + + isACK := response[0] == codeVersion && response[1] == 'A' + if !isACK { + return 0, ErrProtocolError + } + seq := binary.BigEndian.Uint32(response[2:]) + return seq, nil +} + +// wait for ACK (accept partial ACK to reset timeout) +// reset timeout timer for every ACK received. +func (p *protocol) awaitACK(count uint32) (uint32, error) { + debug("await ack") + + var ackSeq uint32 + var err error + + // read until all acks + for ackSeq < count { + ackSeq, err = p.recvACK() + if err != nil { + debug("receive ack failed with: %v", err) + return ackSeq, err + } + } + + if ackSeq > count { + return count, fmt.Errorf( + "invalid sequence number received (seq=%v, expected=%v)", ackSeq, count) + } + return ackSeq, nil +} + +func (p *protocol) sendWindowSize(window uint32) error { + conn := p.conn + + if err := conn.SetWriteDeadline(time.Now().Add(p.timeout)); err != nil { + return err + } + if _, err := conn.Write(codeWindowSize); err != nil { + return err + } + return writeUint32(conn, window) +} + +func (p *protocol) sendCompressed(payload []byte) error { + debug("send compressed") + + conn := p.conn + + if err := conn.SetWriteDeadline(time.Now().Add(p.timeout)); err != nil { + return err + } + + debug("write compressed header") + if _, err := conn.Write(codeCompressed); err != nil { + return err + } + + if err := writeUint32(conn, uint32(len(payload))); err != nil { + return err + } + + debug("send payload") + for len(payload) > 0 { + n, err := conn.Write(payload) + payload = payload[n:] + if err != nil { + return err + } + } + + return nil +} + +func (p *protocol) serializeEvents(events []common.MapStr) ([]common.MapStr, error) { + p.eventsBuffer.Reset() + + if p.compressLevel > 0 { + w, _ := zlib.NewWriterLevel(p.eventsBuffer, p.compressLevel) + outEvents, err := p.doSerializeEvents(w, events) + if err != nil { + return nil, err + } + if err := w.Close(); err != nil { + debug("Finalizing zlib compression failed with: %s", err) + return nil, err + } + return outEvents, nil + } + + return p.doSerializeEvents(p.eventsBuffer, events) +} + +func (p *protocol) doSerializeEvents(out io.Writer, events []common.MapStr) ([]common.MapStr, error) { + var sequence uint32 + + okEvents := events + for _, event := range events { + sequence++ + err := p.serializeDataFrame(out, event, sequence) + if err != nil { + logp.Critical("failed to encode event: %v", err) + sequence-- + goto failedLoop + } + } + return okEvents, nil + +failedLoop: + // on serialization error continue serializing remaining events and collect + // serializable events only + okEvents = events[:sequence] + restEvents := events[sequence+1:] + for _, event := range restEvents { + sequence++ + err := p.serializeDataFrame(out, event, sequence) + if err != nil { + logp.Critical("failed to encode event: %v", err) + sequence-- + continue + } + okEvents = append(okEvents, event) + } + return okEvents, nil +} + +func (p *protocol) serializeDataFrame( + out io.Writer, + event common.MapStr, + seq uint32, +) error { + // Write JSON Data Frame: + // version: uint8 = '2' + // code: uint8 = 'J' + // seq: uint32 + // payloadLen (bytes): uint32 + // payload: JSON document + + jsonEvent, err := json.Marshal(event) + if err != nil { + debug("Fail to convert the event to JSON: %s", err) + return err + } + + if _, err := out.Write(codeJSONDataFrame); err != nil { // version + code + return err + } + if err := writeUint32(out, seq); err != nil { + return err + } + if err := writeUint32(out, uint32(len(jsonEvent))); err != nil { + return err + } + if _, err := out.Write(jsonEvent); err != nil { + return err + } + + return nil +} + +func writeUint32(out io.Writer, v uint32) error { + return binary.Write(out, binary.BigEndian, v) +} diff --git a/vendor/github.com/elastic/beats/libbeat/outputs/logstash/sync.go b/vendor/github.com/elastic/beats/libbeat/outputs/logstash/sync.go new file mode 100644 index 0000000..d7f4627 --- /dev/null +++ b/vendor/github.com/elastic/beats/libbeat/outputs/logstash/sync.go @@ -0,0 +1,139 @@ +package logstash + +import ( + "errors" + "expvar" + "time" + + "github.com/elastic/beats/libbeat/common" + "github.com/elastic/beats/libbeat/logp" +) + +// Metrics that can retrieved through the expvar web interface. +var ( + ackedEvents = expvar.NewInt("libbeatLogstashPublishedAndAckedEvents") + eventsNotAcked = expvar.NewInt("libbeatLogstashPublishedButNotAckedEvents") + publishEventsCallCount = expvar.NewInt("libbeatLogstashPublishEventsCallCount") +) + +// client implements the ProtocolClient interface to be used +// with different mode. The client implements slow start with low window sizes + +// window size backoff in case of long running transactions. +// +// it is suggested to use lumberjack in conjunction with roundRobinConnectionMode +// if logstash becomes unresponsive +type client struct { + TransportClient + *protocol + + win window + countTimeoutErr int +} + +const ( + minWindowSize int = 1 + defaultStartMaxWindowSize int = 10 +) + +// errors +var ( + ErrNotConnected = errors.New("lumberjack client is not connected") +) + +func newLumberjackClient( + conn TransportClient, + compressLevel int, + maxWindowSize int, + timeout time.Duration, +) (*client, error) { + p, err := newClientProcol(conn, timeout, compressLevel) + if err != nil { + return nil, err + } + + c := &client{ + TransportClient: conn, + protocol: p, + } + c.win.init(defaultStartMaxWindowSize, maxWindowSize) + return c, nil +} + +func (l *client) Connect(timeout time.Duration) error { + logp.Debug("logstash", "connect") + return l.TransportClient.Connect(timeout) +} + +func (l *client) Close() error { + logp.Debug("logstash", "close connection") + return l.TransportClient.Close() +} + +func (l *client) PublishEvent(event common.MapStr) error { + _, err := l.PublishEvents([]common.MapStr{event}) + return err +} + +// PublishEvents sends all events to logstash. On error a slice with all events +// not published or confirmed to be processed by logstash will be returned. +func (l *client) PublishEvents( + events []common.MapStr, +) ([]common.MapStr, error) { + publishEventsCallCount.Add(1) + totalNumberOfEvents := len(events) + for len(events) > 0 { + n, err := l.publishWindowed(events) + + debug("%v events out of %v events sent to logstash. Continue sending", + n, len(events)) + + events = events[n:] + if err != nil { + l.win.shrinkWindow() + _ = l.Close() + + logp.Err("Failed to publish events caused by: %v", err) + + eventsNotAcked.Add(int64(len(events))) + ackedEvents.Add(int64(totalNumberOfEvents - len(events))) + return events, err + } + } + ackedEvents.Add(int64(totalNumberOfEvents)) + return nil, nil +} + +// publishWindowed published events with current maximum window size to logstash +// returning the total number of events sent (due to window size, or acks until +// failure). +func (l *client) publishWindowed(events []common.MapStr) (int, error) { + if len(events) == 0 { + return 0, nil + } + + batchSize := len(events) + windowSize := l.win.get() + debug("Try to publish %v events to logstash with window size %v", + batchSize, windowSize) + + // prepare message payload + if batchSize > windowSize { + events = events[:windowSize] + } + + outEvents, err := l.sendEvents(events) + count := uint32(len(outEvents)) + if err != nil { + if err == errAllEventsEncoding { + return len(events), nil + } + return 0, err + } + + if seq, err := l.awaitACK(count); err != nil { + return int(seq), err + } + + l.win.tryGrowWindow(batchSize) + return len(events), nil +} diff --git a/vendor/github.com/elastic/beats/libbeat/outputs/logstash/transport.go b/vendor/github.com/elastic/beats/libbeat/outputs/logstash/transport.go new file mode 100644 index 0000000..c095a37 --- /dev/null +++ b/vendor/github.com/elastic/beats/libbeat/outputs/logstash/transport.go @@ -0,0 +1,213 @@ +package logstash + +import ( + "crypto/tls" + "fmt" + "math/rand" + "net" + "strings" + "time" + + "github.com/elastic/beats/libbeat/logp" +) + +// TransportClient interfaces adds (re-)connect support to net.Conn. +type TransportClient interface { + net.Conn + Connect(timeout time.Duration) error + IsConnected() bool +} + +type tcpClient struct { + hostport string + connected bool + conn net.Conn +} + +type tlsClient struct { + tcpClient + tls tls.Config +} + +func newTCPClient(host string, defaultPort int) (*tcpClient, error) { + return &tcpClient{hostport: fullAddress(host, defaultPort)}, nil +} + +func (c *tcpClient) Connect(timeout time.Duration) error { + if c.IsConnected() { + _ = c.Close() + } + + host, port, err := net.SplitHostPort(c.hostport) + if err != nil { + return err + } + + // TODO: address lookup copied from logstash-forwarded. Really required? + addresses, err := net.LookupHost(host) + c.conn = nil + if err != nil { + logp.Warn("DNS lookup failure \"%s\": %s", host, err) + return err + } + + // connect to random address + // Use randomization on DNS reported addresses combined with timeout and ACKs + // to spread potential load when starting up large number of beats using + // lumberjack. + // + // RFCs discussing reasons for ignoring order of DNS records: + // http://www.ietf.org/rfc/rfc3484.txt + // > is specific to locality-based address selection for multiple dns + // > records, but exists as prior art in "Choose some different ordering for + // > the dns records" done by a client + // + // https://tools.ietf.org/html/rfc1794 + // > "Clients, of course, may reorder this information" - with respect to + // > handling order of dns records in a response. address := + address := addresses[rand.Int()%len(addresses)] + addressport := net.JoinHostPort(address, port) + conn, err := net.DialTimeout("tcp", addressport, timeout) + if err != nil { + return err + } + + c.conn = conn + c.connected = true + return nil +} + +func (c *tcpClient) IsConnected() bool { + return c.connected +} + +func (c *tcpClient) Close() error { + if c.connected { + debug("closing") + c.connected = false + return c.conn.Close() + } + return nil +} + +func (c *tcpClient) Read(b []byte) (int, error) { + if !c.connected { + return 0, ErrNotConnected + } + + debug("try read: %v", len(b)) + n, err := c.conn.Read(b) + return n, c.handleError(err) +} + +func (c *tcpClient) Write(b []byte) (int, error) { + if !c.connected { + return 0, ErrNotConnected + } + + n, err := c.conn.Write(b) + return n, c.handleError(err) +} + +func (c *tcpClient) LocalAddr() net.Addr { + if !c.connected { + return nil + } + return c.conn.LocalAddr() +} + +func (c *tcpClient) RemoteAddr() net.Addr { + if !c.connected { + return nil + } + return c.conn.RemoteAddr() +} + +func (c *tcpClient) SetDeadline(t time.Time) error { + if !c.connected { + return ErrNotConnected + } + err := c.conn.SetDeadline(t) + return c.handleError(err) +} + +func (c *tcpClient) SetReadDeadline(t time.Time) error { + if !c.connected { + return ErrNotConnected + } + err := c.conn.SetReadDeadline(t) + return c.handleError(err) +} + +func (c *tcpClient) SetWriteDeadline(t time.Time) error { + if !c.connected { + return ErrNotConnected + } + err := c.conn.SetWriteDeadline(t) + return c.handleError(err) +} + +func (c *tcpClient) handleError(err error) error { + if err != nil { + debug("handle error: %v", err) + + if nerr, ok := err.(net.Error); !(ok && (nerr.Temporary() || nerr.Timeout())) { + c.Close() + } + } + return err +} + +func newTLSClient(host string, defaultPort int, tls *tls.Config) (*tlsClient, error) { + c := tlsClient{} + c.hostport = fullAddress(host, defaultPort) + c.tls = *tls + return &c, nil +} + +func (c *tlsClient) Connect(timeout time.Duration) error { + host, _, err := net.SplitHostPort(c.hostport) + if err != nil { + return err + } + + if err := c.tcpClient.Connect(timeout); err != nil { + return c.onFail(err) + } + + tlsconfig := c.tls + tlsconfig.ServerName = host + socket := tls.Client(c.conn, &tlsconfig) + if err := socket.SetDeadline(time.Now().Add(timeout)); err != nil { + _ = socket.Close() + return c.onFail(err) + } + if err := socket.Handshake(); err != nil { + _ = socket.Close() + return c.onFail(err) + } + + c.conn = socket + c.connected = true + return nil +} + +func (c *tlsClient) onFail(err error) error { + logp.Err("SSL client failed to connect with: %v", err) + c.conn = nil + c.connected = false + return err +} + +func fullAddress(host string, defaultPort int) string { + if _, _, err := net.SplitHostPort(host); err == nil { + return host + } + + idx := strings.Index(host, ":") + if idx >= 0 { + // IPv6 address detected + return fmt.Sprintf("[%v]:%v", host, defaultPort) + } + return fmt.Sprintf("%v:%v", host, defaultPort) +} diff --git a/vendor/github.com/elastic/beats/libbeat/outputs/logstash/window.go b/vendor/github.com/elastic/beats/libbeat/outputs/logstash/window.go new file mode 100644 index 0000000..4ce0928 --- /dev/null +++ b/vendor/github.com/elastic/beats/libbeat/outputs/logstash/window.go @@ -0,0 +1,77 @@ +package logstash + +import ( + "math" + "sync/atomic" +) + +type window struct { + windowSize int32 + maxOkWindowSize int // max window size sending was successful for + maxWindowSize int +} + +func (w *window) init(start, max int) { + *w = window{ + windowSize: int32(start), + maxWindowSize: max, + } +} + +func (w *window) get() int { + return int(atomic.LoadInt32(&w.windowSize)) +} + +// Increase window size by factor 1.5 until max window size +// (window size grows exponentially) +// TODO: use duration until ACK to estimate an ok max window size value +func (w *window) tryGrowWindow(batchSize int) { + windowSize := int(w.windowSize) + + if windowSize <= batchSize { + if w.maxOkWindowSize < windowSize { + debug("update max ok window size: %v < %v", + w.maxOkWindowSize, w.windowSize) + w.maxOkWindowSize = windowSize + + newWindowSize := int(math.Ceil(1.5 * float64(windowSize))) + debug("increase window size to: %v", newWindowSize) + + if windowSize <= batchSize && batchSize < newWindowSize { + debug("set to batchSize: %v", batchSize) + newWindowSize = batchSize + } + if newWindowSize > w.maxWindowSize { + debug("set to max window size: %v", w.maxWindowSize) + newWindowSize = int(w.maxWindowSize) + } + + windowSize = newWindowSize + } else if windowSize < w.maxOkWindowSize { + debug("update current window size: %v", w.windowSize) + + windowSize = int(math.Ceil(1.5 * float64(windowSize))) + if windowSize > w.maxOkWindowSize { + debug("set to max ok window size: %v", w.maxOkWindowSize) + windowSize = w.maxOkWindowSize + } + } + + atomic.StoreInt32(&w.windowSize, int32(windowSize)) + } +} + +func (w *window) shrinkWindow() { + windowSize := int(w.windowSize) + orig := windowSize + + windowSize = windowSize / 2 + if windowSize < minWindowSize { + windowSize = minWindowSize + if windowSize == orig { + return + } + } + + atomic.StoreInt32(&w.windowSize, int32(windowSize)) +} diff --git a/vendor/github.com/elastic/beats/libbeat/outputs/mode/backoff.go b/vendor/github.com/elastic/beats/libbeat/outputs/mode/backoff.go new file mode 100644 index 0000000..8f221bb --- /dev/null +++ b/vendor/github.com/elastic/beats/libbeat/outputs/mode/backoff.go @@ -0,0 +1,50 @@ +package mode + +import "time" + +type backoff struct { + duration time.Duration + done <-chan struct{} + + init time.Duration + max time.Duration +} + +func newBackoff(done <-chan struct{}, init, max time.Duration) *backoff { + return &backoff{ + duration: init, + done: done, + init: init, + max: max, + } +} + +func (b *backoff) Reset() { + b.duration = b.init +} + +func (b *backoff) Wait() bool { + + backoff := b.duration + b.duration *= 2 + if b.duration > b.max { + b.duration = b.max + } + + debug("backoff: wait for %v", b.duration) + + select { + case <-b.done: + return false + case <-time.After(backoff): + return true + } +} + +func (b *backoff) WaitOnError(err error) bool { + if err == nil { + b.Reset() + return true + } + return b.Wait() +} diff --git a/vendor/github.com/elastic/beats/libbeat/outputs/mode/balance.go b/vendor/github.com/elastic/beats/libbeat/outputs/mode/balance.go new file mode 100644 index 0000000..9847767 --- /dev/null +++ b/vendor/github.com/elastic/beats/libbeat/outputs/mode/balance.go @@ -0,0 +1,311 @@ +package mode + +import ( + "sync" + "time" + + "github.com/elastic/beats/libbeat/common" + "github.com/elastic/beats/libbeat/logp" + "github.com/elastic/beats/libbeat/outputs" +) + +// LoadBalancerMode balances the sending of events between multiple connections. +// +// The balancing algorithm is mostly pull-based, with multiple workers trying to pull +// some amount of work from a shared queue. Workers will try to get a new work item +// only if they have a working/active connection. Workers without active connection +// do not participate until a connection has been re-established. +// Due to the pull based nature the algorithm will load-balance events by random +// with workers having less latencies/turn-around times potentially getting more +// work items then other workers with higher latencies. Thusly the algorithm +// dynamically adapts to resource availability of server events are forwarded to. +// +// Workers not participating in the load-balancing will continuously try to reconnect +// to their configured endpoints. Once a new connection has been established, +// these workers will participate in in load-balancing again. +// +// If a connection becomes unavailable, the events are rescheduled for another +// connection to pick up. Rescheduling events is limited to a maximum number of +// send attempts. If events have not been send after maximum number of allowed +// attemps has been passed, they will be dropped. +// +// Distributing events to workers is subject to timeout. If no worker is available to +// pickup a message for sending, the message will be dropped internally. +type LoadBalancerMode struct { + timeout time.Duration // Send/retry timeout. Every timeout is a failed send attempt + waitRetry time.Duration // Duration to wait during re-connection attempts. + maxWaitRetry time.Duration // Maximum send/retry timeout in backoff case. + + // maximum number of configured send attempts. If set to 0, publisher will + // block until event has been successfully published. + maxAttempts int + + // waitGroup + signaling channel for handling shutdown + wg sync.WaitGroup + done chan struct{} + + // channels for forwarding work items to workers. + // The work channel is used by publisher to insert new events + // into the load balancer. The work channel is synchronous blocking until timeout + // for one worker available. + // The retries channel is used to forward failed send attempts to other workers. + // The retries channel is buffered to mitigate possible deadlocks when all + // workers become unresponsive. + work chan eventsMessage + retries chan eventsMessage +} + +type eventsMessage struct { + attemptsLeft int + signaler outputs.Signaler + events []common.MapStr + event common.MapStr +} + +// NewLoadBalancerMode create a new load balancer connection mode. +func NewLoadBalancerMode( + clients []ProtocolClient, + maxAttempts int, + waitRetry, timeout, maxWaitRetry time.Duration, +) (*LoadBalancerMode, error) { + + // maxAttempts signals infinite retry. Convert to -1, so attempts left and + // and infinite retry can be more easily distinguished by load balancer + if maxAttempts == 0 { + maxAttempts = -1 + } + + m := &LoadBalancerMode{ + timeout: timeout, + maxWaitRetry: maxWaitRetry, + waitRetry: waitRetry, + maxAttempts: maxAttempts, + + work: make(chan eventsMessage), + retries: make(chan eventsMessage, len(clients)*2), + done: make(chan struct{}), + } + m.start(clients) + + return m, nil +} + +// Close stops all workers and closes all open connections. In flight events +// are signaled as failed. +func (m *LoadBalancerMode) Close() error { + close(m.done) + m.wg.Wait() + return nil +} + +// PublishEvents forwards events to some load balancing worker. +func (m *LoadBalancerMode) PublishEvents( + signaler outputs.Signaler, + opts outputs.Options, + events []common.MapStr, +) error { + return m.publishEventsMessage(opts, + eventsMessage{signaler: signaler, events: events}) +} + +// PublishEvent forwards the event to some load balancing worker. +func (m *LoadBalancerMode) PublishEvent( + signaler outputs.Signaler, + opts outputs.Options, + event common.MapStr, +) error { + return m.publishEventsMessage(opts, + eventsMessage{signaler: signaler, event: event}) +} + +func (m *LoadBalancerMode) publishEventsMessage( + opts outputs.Options, + msg eventsMessage, +) error { + maxAttempts := m.maxAttempts + if opts.Guaranteed { + maxAttempts = -1 + } + msg.attemptsLeft = maxAttempts + + if ok := m.forwardEvent(m.work, msg); !ok { + dropping(msg) + } + return nil +} + +func (m *LoadBalancerMode) start(clients []ProtocolClient) { + var waitStart sync.WaitGroup + worker := func(client ProtocolClient) { + defer func() { + if client.IsConnected() { + _ = client.Close() + } + m.wg.Done() + }() + + waitStart.Done() + m.clientLoop(client) + } + + for _, client := range clients { + m.wg.Add(1) + waitStart.Add(1) + go worker(client) + } + waitStart.Wait() +} + +func (m *LoadBalancerMode) clientLoop(client ProtocolClient) { + debug("load balancer: start client loop") + defer debug("load balancer: stop client loop") + + backoff := newBackoff(m.done, m.waitRetry, m.maxWaitRetry) + + done := false + for !done { + if done = m.connect(client, backoff); !done { + done = m.sendLoop(client, backoff) + } + debug("close client") + client.Close() + } +} + +func (m *LoadBalancerMode) connect(client ProtocolClient, backoff *backoff) bool { + for { + debug("try to (re-)connect client") + err := client.Connect(m.timeout) + if !backoff.WaitOnError(err) { + return true + } + + if err == nil { + return false + } + } +} + +func (m *LoadBalancerMode) sendLoop(client ProtocolClient, backoff *backoff) bool { + for { + var msg eventsMessage + select { + case <-m.done: + return true + case msg = <-m.retries: // receive message from other failed worker + case msg = <-m.work: // receive message from publisher + } + + done, err := m.onMessage(backoff, client, msg) + if done || err != nil { + return done + } + } +} + +func (m *LoadBalancerMode) onMessage( + backoff *backoff, + client ProtocolClient, + msg eventsMessage, +) (bool, error) { + + done := false + if msg.event != nil { + err := client.PublishEvent(msg.event) + done = !backoff.WaitOnError(err) + if err != nil { + if msg.attemptsLeft > 0 { + msg.attemptsLeft-- + } + m.onFail(msg, err) + return done, err + } + } else { + events := msg.events + total := len(events) + + for len(events) > 0 { + var err error + + events, err = client.PublishEvents(events) + done = !backoff.WaitOnError(err) + if done && err != nil { + outputs.SignalFailed(msg.signaler, err) + return done, err + } + + if err != nil { + if msg.attemptsLeft > 0 { + msg.attemptsLeft-- + } + + // reset attempt count if subset of messages has been processed + if len(events) < total && msg.attemptsLeft >= 0 { + debug("reset fails") + msg.attemptsLeft = m.maxAttempts + } + + if err != ErrTempBulkFailure { + // retry non-published subset of events in batch + msg.events = events + m.onFail(msg, err) + return done, err + } + + if m.maxAttempts > 0 && msg.attemptsLeft == 0 { + // no more attempts left => drop + dropping(msg) + return done, err + } + + // reset total count for temporary failure loop + total = len(events) + } + } + } + + outputs.SignalCompleted(msg.signaler) + return done, nil +} + +func (m *LoadBalancerMode) onFail(msg eventsMessage, err error) { + + logp.Info("Error publishing events (retrying): %s", err) + + if !m.forwardEvent(m.retries, msg) { + dropping(msg) + } +} + +func (m *LoadBalancerMode) forwardEvent( + ch chan eventsMessage, + msg eventsMessage, +) bool { + if msg.attemptsLeft < 0 { + select { + case ch <- msg: + return true + case <-m.done: // shutdown + return false + } + } else { + for ; msg.attemptsLeft > 0; msg.attemptsLeft-- { + select { + case ch <- msg: + return true + case <-m.done: // shutdown + return false + case <-time.After(m.timeout): + } + } + } + return false +} + +// dropping is called when a message is dropped. It updates the +// relevant counters and sends a failed signal. +func dropping(msg eventsMessage) { + debug("messages dropped") + messagesDropped.Add(1) + outputs.SignalFailed(msg.signaler, nil) +} diff --git a/vendor/github.com/elastic/beats/libbeat/outputs/mode/balance_async.go b/vendor/github.com/elastic/beats/libbeat/outputs/mode/balance_async.go new file mode 100644 index 0000000..a199452 --- /dev/null +++ b/vendor/github.com/elastic/beats/libbeat/outputs/mode/balance_async.go @@ -0,0 +1,328 @@ +package mode + +import ( + "sync" + "time" + + "github.com/elastic/beats/libbeat/common" + "github.com/elastic/beats/libbeat/logp" + "github.com/elastic/beats/libbeat/outputs" +) + +// AsyncLoadBalancerMode balances the sending of events between multiple connections. +// +// The balancing algorithm is mostly pull-based, with multiple workers trying to pull +// some amount of work from a shared queue. Workers will try to get a new work item +// only if they have a working/active connection. Workers without active connection +// do not participate until a connection has been re-established. +// Due to the pull based nature the algorithm will load-balance events by random +// with workers having less latencies/turn-around times potentially getting more +// work items then other workers with higher latencies. Thusly the algorithm +// dynamically adapts to resource availability of server events are forwarded to. +// +// Workers not participating in the load-balancing will continuously try to reconnect +// to their configured endpoints. Once a new connection has been established, +// these workers will participate in in load-balancing again. +// +// If a connection becomes unavailable, the events are rescheduled for another +// connection to pick up. Rescheduling events is limited to a maximum number of +// send attempts. If events have not been send after maximum number of allowed +// attemps has been passed, they will be dropped. +// +// Like network connections, distributing events to workers is subject to +// timeout. If no worker is available to pickup a message for sending, the message +// will be dropped internally after max_retries. If mode or message requires +// guaranteed send, message is retried infinitely. +type AsyncLoadBalancerMode struct { + timeout time.Duration // Send/retry timeout. Every timeout is a failed send attempt + waitRetry time.Duration // Duration to wait during re-connection attempts. + maxWaitRetry time.Duration // Maximum send/retry timeout in backoff case. + + // maximum number of configured send attempts. If set to 0, publisher will + // block until event has been successfully published. + maxAttempts int + + // waitGroup + signaling channel for handling shutdown + wg sync.WaitGroup + done chan struct{} + + // channels for forwarding work items to workers. + // The work channel is used by publisher to insert new events + // into the load balancer. The work channel is synchronous blocking until timeout + // for one worker available. + // The retries channel is used to forward failed send attempts to other workers. + // The retries channel is buffered to mitigate possible deadlocks when all + // workers become unresponsive. + work chan eventsMessage + retries chan eventsMessage +} + +// NewAsyncLoadBalancerMode create a new load balancer connection mode. +func NewAsyncLoadBalancerMode( + clients []AsyncProtocolClient, + maxAttempts int, + waitRetry, timeout, maxWaitRetry time.Duration, +) (*AsyncLoadBalancerMode, error) { + + debug("configure maxattempts: %v", maxAttempts) + + // maxAttempts signals infinite retry. Convert to -1, so attempts left and + // and infinite retry can be more easily distinguished by load balancer + if maxAttempts == 0 { + maxAttempts = -1 + } + + m := &AsyncLoadBalancerMode{ + timeout: timeout, + maxWaitRetry: maxWaitRetry, + waitRetry: waitRetry, + maxAttempts: maxAttempts, + + work: make(chan eventsMessage), + retries: make(chan eventsMessage, len(clients)*2), + done: make(chan struct{}), + } + m.start(clients) + + return m, nil +} + +// Close stops all workers and closes all open connections. In flight events +// are signaled as failed. +func (m *AsyncLoadBalancerMode) Close() error { + close(m.done) + m.wg.Wait() + return nil +} + +// PublishEvents forwards events to some load balancing worker. +func (m *AsyncLoadBalancerMode) PublishEvents( + signaler outputs.Signaler, + opts outputs.Options, + events []common.MapStr, +) error { + return m.publishEventsMessage(opts, + eventsMessage{signaler: signaler, events: events}) +} + +// PublishEvent forwards the event to some load balancing worker. +func (m *AsyncLoadBalancerMode) PublishEvent( + signaler outputs.Signaler, + opts outputs.Options, + event common.MapStr, +) error { + return m.publishEventsMessage(opts, + eventsMessage{signaler: signaler, event: event}) +} + +func (m *AsyncLoadBalancerMode) publishEventsMessage( + opts outputs.Options, + msg eventsMessage, +) error { + maxAttempts := m.maxAttempts + if opts.Guaranteed { + debug("guaranteed flag is set") + maxAttempts = -1 + } else { + debug("guaranteed flag is not set") + } + msg.attemptsLeft = maxAttempts + debug("publish events with attempts=%v", msg.attemptsLeft) + + if ok := m.forwardEvent(m.work, msg); !ok { + dropping(msg) + } + return nil +} + +func (m *AsyncLoadBalancerMode) start(clients []AsyncProtocolClient) { + var waitStart sync.WaitGroup + worker := func(client AsyncProtocolClient) { + defer func() { + if client.IsConnected() { + _ = client.Close() + } + m.wg.Done() + }() + + waitStart.Done() + + backoff := newBackoff(m.done, m.waitRetry, m.maxWaitRetry) + for { + // reconnect loop + for !client.IsConnected() { + if err := client.Connect(m.timeout); err == nil { + break + } + + if !backoff.Wait() { // done channel closed + return + } + } + + // receive and process messages + var msg eventsMessage + select { + case <-m.done: + return + case msg = <-m.retries: // receive message from other failed worker + debug("events from retries queue") + case msg = <-m.work: // receive message from publisher + debug("events from worker worker queue") + } + + err := m.onMessage(client, msg) + if !backoff.WaitOnError(err) { // done channel closed + return + } + } + } + + for _, client := range clients { + m.wg.Add(1) + waitStart.Add(1) + go worker(client) + } + waitStart.Wait() +} + +func (m *AsyncLoadBalancerMode) onMessage( + client AsyncProtocolClient, + msg eventsMessage, +) error { + var err error + if msg.event != nil { + err = client.AsyncPublishEvent(handlePublishEventResult(m, msg), msg.event) + } else { + err = client.AsyncPublishEvents(handlePublishEventsResult(m, msg), msg.events) + } + + if err != nil { + if msg.attemptsLeft > 0 { + msg.attemptsLeft-- + } + + // asynchronously retry to insert message (if attempts left), so worker can not + // deadlock on retries channel if client puts multiple failed outstanding + // events into the pipeline + m.onFail(true, msg, err) + } + + return err +} + +func handlePublishEventResult(m *AsyncLoadBalancerMode, msg eventsMessage) func(error) { + return func(err error) { + if err != nil { + if msg.attemptsLeft > 0 { + msg.attemptsLeft-- + } + m.onFail(false, msg, err) + } else { + outputs.SignalCompleted(msg.signaler) + } + } +} + +func handlePublishEventsResult( + m *AsyncLoadBalancerMode, + msg eventsMessage, +) func([]common.MapStr, error) { + total := len(msg.events) + return func(events []common.MapStr, err error) { + debug("handlePublishEventsResult") + + if err != nil { + debug("handle publish error: %v", err) + + if msg.attemptsLeft > 0 { + msg.attemptsLeft-- + } + + // reset attempt count if subset of messages has been processed + if len(events) < total && msg.attemptsLeft >= 0 { + msg.attemptsLeft = m.maxAttempts + } + + if err != ErrTempBulkFailure { + // retry non-published subset of events in batch + msg.events = events + m.onFail(false, msg, err) + return + } + + if m.maxAttempts > 0 && msg.attemptsLeft == 0 { + // no more attempts left => drop + dropping(msg) + return + } + + // retry non-published subset of events in batch + msg.events = events + m.onFail(false, msg, err) + return + } + + // re-insert non-published events into pipeline + if len(events) != 0 { + debug("add non-published events back into pipeline: %v", len(events)) + msg.events = events + if ok := m.forwardEvent(m.retries, msg); !ok { + dropping(msg) + } + return + } + + // all events published -> signal success + debug("async bulk publish success") + outputs.SignalCompleted(msg.signaler) + } +} + +func (m *AsyncLoadBalancerMode) onFail(async bool, msg eventsMessage, err error) { + fn := func() { + logp.Info("Error publishing events (retrying): %s", err) + + if ok := m.forwardEvent(m.retries, msg); !ok { + dropping(msg) + } + } + + if async { + go fn() + } else { + fn() + } +} + +func (m *AsyncLoadBalancerMode) forwardEvent( + ch chan eventsMessage, + msg eventsMessage, +) bool { + debug("forwards msg with attempts=%v", msg.attemptsLeft) + + if msg.attemptsLeft < 0 { + select { + case ch <- msg: + debug("message forwarded") + return true + case <-m.done: // shutdown + debug("shutting down") + return false + } + } else { + for ; msg.attemptsLeft > 0; msg.attemptsLeft-- { + select { + case ch <- msg: + debug("message forwarded") + return true + case <-m.done: // shutdown + debug("shutting down") + return false + case <-time.After(m.timeout): + debug("forward timed out") + } + } + } + return false +} diff --git a/vendor/github.com/elastic/beats/libbeat/outputs/mode/failover_client.go b/vendor/github.com/elastic/beats/libbeat/outputs/mode/failover_client.go new file mode 100644 index 0000000..8857188 --- /dev/null +++ b/vendor/github.com/elastic/beats/libbeat/outputs/mode/failover_client.go @@ -0,0 +1,162 @@ +package mode + +import ( + "errors" + "math/rand" + "time" + + "github.com/elastic/beats/libbeat/common" +) + +type failOverClient struct { + conns []ProtocolClient + active int +} + +type asyncFailOverClient struct { + conns []AsyncProtocolClient + active int +} + +type clientList interface { + Active() int + Len() int + Get(i int) Connectable + Activate(i int) +} + +var ( + // ErrNoConnectionConfigured indicates no configured connections for publishing. + ErrNoConnectionConfigured = errors.New("No connection configured") + + errNoActiveConnection = errors.New("No active connection") +) + +func NewFailoverClient(clients []ProtocolClient) []ProtocolClient { + if len(clients) <= 1 { + return clients + } + return []ProtocolClient{&failOverClient{conns: clients, active: -1}} +} + +func (f *failOverClient) Active() int { return f.active } +func (f *failOverClient) Len() int { return len(f.conns) } +func (f *failOverClient) Get(i int) Connectable { return f.conns[i] } +func (f *failOverClient) Activate(i int) { f.active = i } + +func (f *failOverClient) Connect(to time.Duration) error { + return connect(f, to) +} + +func (f *failOverClient) IsConnected() bool { + return f.active >= 0 && f.conns[f.active].IsConnected() +} + +func (f *failOverClient) Close() error { + return closeActive(f) +} + +func (f *failOverClient) PublishEvents(events []common.MapStr) ([]common.MapStr, error) { + if f.active < 0 { + return events, errNoActiveConnection + } + return f.conns[f.active].PublishEvents(events) +} + +func (f *failOverClient) PublishEvent(event common.MapStr) error { + if f.active < 0 { + return errNoActiveConnection + } + return f.conns[f.active].PublishEvent(event) +} + +func NewAsyncFailoverClient(clients []AsyncProtocolClient) []AsyncProtocolClient { + if len(clients) <= 1 { + return clients + } + return []AsyncProtocolClient{ + &asyncFailOverClient{conns: clients, active: -1}, + } +} + +func (f *asyncFailOverClient) Active() int { return f.active } +func (f *asyncFailOverClient) Len() int { return len(f.conns) } +func (f *asyncFailOverClient) Get(i int) Connectable { return f.conns[i] } +func (f *asyncFailOverClient) Activate(i int) { f.active = i } + +func (f *asyncFailOverClient) Connect(to time.Duration) error { + return connect(f, to) +} + +func (f *asyncFailOverClient) IsConnected() bool { + return f.active >= 0 && f.conns[f.active].IsConnected() +} + +func (f *asyncFailOverClient) Close() error { + return closeActive(f) +} + +func (f *asyncFailOverClient) AsyncPublishEvents( + cb func([]common.MapStr, error), + events []common.MapStr, +) error { + if f.active < 0 { + return errNoActiveConnection + } + return f.conns[f.active].AsyncPublishEvents(cb, events) +} + +func (f *asyncFailOverClient) AsyncPublishEvent( + cb func(error), + event common.MapStr, +) error { + if f.active < 0 { + return errNoActiveConnection + } + return f.conns[f.active].AsyncPublishEvent(cb, event) +} + +func connect(lst clientList, to time.Duration) error { + active := lst.Active() + l := lst.Len() + next := 0 + + switch { + case l == 0: + return ErrNoConnectionConfigured + case l == 1: + next = 0 + case l == 2 && 0 <= active && active <= 1: + next = 1 - active + default: + for { + // Connect to random server to potentially spread the + // load when large number of beats with same set of sinks + // are started up at about the same time. + next = rand.Int() % l + if next != active { + break + } + } + } + + conn := lst.Get(next) + lst.Activate(next) + if conn.IsConnected() { + return nil + } + + return conn.Connect(to) +} + +func closeActive(lst clientList) error { + active := lst.Active() + if active < 0 { + return nil + } + + conn := lst.Get(active) + err := conn.Close() + lst.Activate(-1) + return err +} diff --git a/vendor/github.com/elastic/beats/libbeat/outputs/mode/mode.go b/vendor/github.com/elastic/beats/libbeat/outputs/mode/mode.go new file mode 100644 index 0000000..749bb93 --- /dev/null +++ b/vendor/github.com/elastic/beats/libbeat/outputs/mode/mode.go @@ -0,0 +1,197 @@ +// Package mode defines and implents output strategies with failover or load +// balancing modes for use by output plugins. +package mode + +import ( + "errors" + "expvar" + "time" + + "github.com/elastic/beats/libbeat/common" + "github.com/elastic/beats/libbeat/logp" + "github.com/elastic/beats/libbeat/outputs" +) + +// Metrics that can retrieved through the expvar web interface. +var ( + messagesDropped = expvar.NewInt("libbeatMessagesDropped") +) + +// ErrNoHostsConfigured indicates missing host or hosts configuration +var ErrNoHostsConfigured = errors.New("no host configuration found") + +// ConnectionMode takes care of connecting to hosts +// and potentially doing load balancing and/or failover +type ConnectionMode interface { + // Close will stop the modes it's publisher loop and close all it's + // associated clients + Close() error + + // PublishEvents will send all events (potentially asynchronous) to its + // clients. + PublishEvents(trans outputs.Signaler, opts outputs.Options, events []common.MapStr) error + + // PublishEvent will send an event to its clients. + PublishEvent(trans outputs.Signaler, opts outputs.Options, event common.MapStr) error +} + +type Connectable interface { + // Connect establishes a connection to the clients sink. + // The connection attempt shall report an error if no connection could been + // established within the given time interval. A timeout value of 0 == wait + // forever. + Connect(timeout time.Duration) error + + // Close closes the established connection. + Close() error + + // IsConnected indicates the clients connection state. If connection has + // been lost while publishing events, IsConnected must return false. As long as + // IsConnected returns false, an output plugin might try to re-establish the + // connection by calling Connect. + IsConnected() bool +} + +// ProtocolClient interface is a output plugin specific client implementation +// for encoding and publishing events. A ProtocolClient must be able to connection +// to it's sink and indicate connection failures in order to be reconnected byte +// the output plugin. +type ProtocolClient interface { + Connectable + + // PublishEvents sends events to the clients sink. On failure or timeout err + // must be set. If connection has been lost, IsConnected must return false + // in future calls. + // PublishEvents is free to publish only a subset of given events, even in + // error case. On return nextEvents contains all events not yet published. + PublishEvents(events []common.MapStr) (nextEvents []common.MapStr, err error) + + // PublishEvent sends one event to the clients sink. On failure and error is + // returned. + PublishEvent(event common.MapStr) error +} + +// AsyncProtocolClient interface is a output plugin specfic client implementation +// for asynchronous encoding and publishing events. +type AsyncProtocolClient interface { + Connectable + + AsyncPublishEvents(cb func([]common.MapStr, error), events []common.MapStr) error + + AsyncPublishEvent(cb func(error), event common.MapStr) error +} + +var ( + // ErrTempBulkFailure indicates PublishEvents fail temporary to retry. + ErrTempBulkFailure = errors.New("temporary bulk send failure") +) + +var ( + debug = logp.MakeDebug("output") +) + +func NewConnectionMode( + clients []ProtocolClient, + failover bool, + maxAttempts int, + waitRetry, timeout, maxWaitRetry time.Duration, +) (ConnectionMode, error) { + if failover { + clients = NewFailoverClient(clients) + } + + if len(clients) == 1 { + return NewSingleConnectionMode(clients[0], maxAttempts, + waitRetry, timeout, maxWaitRetry) + } + return NewLoadBalancerMode(clients, maxAttempts, + waitRetry, timeout, maxWaitRetry) +} + +func NewAsyncConnectionMode( + clients []AsyncProtocolClient, + failover bool, + maxAttempts int, + waitRetry, timeout, maxWaitRetry time.Duration, +) (ConnectionMode, error) { + if failover { + clients = NewAsyncFailoverClient(clients) + } + return NewAsyncLoadBalancerMode(clients, maxAttempts, + waitRetry, timeout, maxWaitRetry) +} + +// MakeClients will create a list from of ProtocolClient instances from +// outputer configuration host list and client factory function. +func MakeClients( + config outputs.MothershipConfig, + newClient func(string) (ProtocolClient, error), +) ([]ProtocolClient, error) { + hosts := ReadHostList(config) + if len(hosts) == 0 { + return nil, ErrNoHostsConfigured + } + + clients := make([]ProtocolClient, 0, len(hosts)) + for _, host := range hosts { + client, err := newClient(host) + if err != nil { + // on error destroy all client instance created + for _, client := range clients { + _ = client.Close() // ignore error + } + return nil, err + } + clients = append(clients, client) + } + return clients, nil +} + +func MakeAsyncClients( + config outputs.MothershipConfig, + newClient func(string) (AsyncProtocolClient, error), +) ([]AsyncProtocolClient, error) { + hosts := ReadHostList(config) + if len(hosts) == 0 { + return nil, ErrNoHostsConfigured + } + + clients := make([]AsyncProtocolClient, 0, len(hosts)) + for _, host := range hosts { + client, err := newClient(host) + if err != nil { + // on error destroy all client instance created + for _, client := range clients { + _ = client.Close() // ignore error + } + return nil, err + } + clients = append(clients, client) + } + return clients, nil +} + +func ReadHostList(config outputs.MothershipConfig) []string { + var lst []string + + // TODO: remove config.Host + if len(config.Hosts) > 0 { + lst = config.Hosts + } else if config.Host != "" { + lst = []string{config.Host} + } + + if len(lst) == 0 || config.Worker <= 1 { + return lst + } + + // duplicate entries config.Workers times + hosts := make([]string, 0, len(lst)*config.Worker) + for _, entry := range lst { + for i := 0; i < config.Worker; i++ { + hosts = append(hosts, entry) + } + } + + return hosts +} diff --git a/vendor/github.com/elastic/beats/libbeat/outputs/mode/single.go b/vendor/github.com/elastic/beats/libbeat/outputs/mode/single.go new file mode 100644 index 0000000..d10d435 --- /dev/null +++ b/vendor/github.com/elastic/beats/libbeat/outputs/mode/single.go @@ -0,0 +1,162 @@ +package mode + +import ( + "errors" + "time" + + "github.com/elastic/beats/libbeat/common" + "github.com/elastic/beats/libbeat/logp" + "github.com/elastic/beats/libbeat/outputs" +) + +// SingleConnectionMode sends all Output on one single connection. If connection is +// not available, the output plugin blocks until the connection is either available +// again or the connection mode is closed by Close. +type SingleConnectionMode struct { + conn ProtocolClient + + closed bool // mode closed flag to break publisher loop + + timeout time.Duration // connection timeout + backoff *backoff + + // maximum number of configured send attempts. If set to 0, publisher will + // block until event has been successfully published. + maxAttempts int +} + +var ( + errNeedBackoff = errors.New("need to backoff") +) + +// NewSingleConnectionMode creates a new single connection mode using exactly one +// ProtocolClient connection. +func NewSingleConnectionMode( + client ProtocolClient, + maxAttempts int, + waitRetry, timeout, maxWaitRetry time.Duration, +) (*SingleConnectionMode, error) { + s := &SingleConnectionMode{ + conn: client, + + timeout: timeout, + backoff: newBackoff(nil, waitRetry, maxWaitRetry), + maxAttempts: maxAttempts, + } + + _ = s.connect() // try to connect, but ignore errors for now + return s, nil +} + +func (s *SingleConnectionMode) connect() error { + if s.conn.IsConnected() { + return nil + } + return s.conn.Connect(s.timeout) +} + +// Close closes the underlying connection. +func (s *SingleConnectionMode) Close() error { + s.closed = true + return s.conn.Close() +} + +// PublishEvents tries to publish the events with retries if connection becomes +// unavailable. On failure PublishEvents tries to reconnect. +func (s *SingleConnectionMode) PublishEvents( + signaler outputs.Signaler, + opts outputs.Options, + events []common.MapStr, +) error { + return s.publish(signaler, opts, func() (bool, bool) { + for len(events) > 0 { + var err error + + total := len(events) + events, err = s.conn.PublishEvents(events) + if err != nil { + logp.Info("Error publishing events (retrying): %s", err) + + madeProgress := len(events) < total + return false, madeProgress + } + } + + return true, false + }) +} + +// PublishEvent forwards a single event. On failure PublishEvent tries to reconnect. +func (s *SingleConnectionMode) PublishEvent( + signaler outputs.Signaler, + opts outputs.Options, + event common.MapStr, +) error { + return s.publish(signaler, opts, func() (bool, bool) { + if err := s.conn.PublishEvent(event); err != nil { + logp.Info("Error publishing event (retrying): %s", err) + return false, false + } + return true, false + }) +} + +// publish is used to publish events using the configured protocol client. +// It provides general error handling and back off support used on failed +// send attempts. To be used by PublishEvent and PublishEvents. +// The send callback will try to progress sending traffic and returns kind of +// progress made in ok or resetFail. If ok is set to true, send finished +// processing events. If ok is false but resetFail is set, send was partially +// successful. If send was partially successful, the fail counter is reset thus up +// to maxAttempts send attempts without any progress might be executed. +func (s *SingleConnectionMode) publish( + signaler outputs.Signaler, + opts outputs.Options, + send func() (ok bool, resetFail bool), +) error { + fails := 0 + var err error + + guaranteed := opts.Guaranteed || s.maxAttempts == 0 + for !s.closed && (guaranteed || fails < s.maxAttempts) { + + ok := false + resetFail := false + + if err := s.connect(); err != nil { + logp.Info("Connecting error publishing events (retrying): %s", err) + goto sendFail + } + + ok, resetFail = send() + if !ok { + goto sendFail + } + + debug("send completed") + s.backoff.Reset() + outputs.SignalCompleted(signaler) + return nil + + sendFail: + logp.Info("send fail") + s.backoff.Wait() + + fails++ + if resetFail { + debug("reset fails") + fails = 0 + } + + if !guaranteed && (s.maxAttempts > 0 && fails == s.maxAttempts) { + // max number of attempts reached + debug("max number of attempts reached") + break + } + } + + debug("messages dropped") + messagesDropped.Add(1) + outputs.SignalFailed(signaler, err) + return nil +} diff --git a/vendor/github.com/elastic/beats/libbeat/outputs/outputs.go b/vendor/github.com/elastic/beats/libbeat/outputs/outputs.go new file mode 100644 index 0000000..2cec665 --- /dev/null +++ b/vendor/github.com/elastic/beats/libbeat/outputs/outputs.go @@ -0,0 +1,163 @@ +package outputs + +import ( + "github.com/elastic/beats/libbeat/common" + "github.com/elastic/beats/libbeat/logp" +) + +type MothershipConfig struct { + SaveTopology bool `yaml:"save_topology"` + Host string + Port int + Hosts []string + LoadBalance *bool `yaml:"loadbalance"` + Protocol string + Username string + Password string + ProxyURL string `yaml:"proxy_url"` + Index string + Path string + Template Template + Params map[string]string `yaml:"parameters"` + Db int + DbTopology int `yaml:"db_topology"` + Timeout int + ReconnectInterval int `yaml:"reconnect_interval"` + Filename string `yaml:"filename"` + RotateEveryKb int `yaml:"rotate_every_kb"` + NumberOfFiles int `yaml:"number_of_files"` + DataType string + FlushInterval *int `yaml:"flush_interval"` + BulkMaxSize *int `yaml:"bulk_max_size"` + MaxRetries *int `yaml:"max_retries"` + Pretty *bool `yaml:"pretty"` + TLS *TLSConfig + Worker int + CompressionLevel *int `yaml:"compression_level"` + KeepAlive string `yaml:"keep_alive"` + MaxMessageBytes *int `yaml:"max_message_bytes"` + RequiredACKs *int `yaml:"required_acks"` + BrokerTimeout string `yaml:"broker_timeout"` + Compression string `yaml:"compression"` + ClientID string `yaml:"client_id"` + Topic string `yaml:"topic"` + UseType *bool `yaml:"use_type"` +} + +type Template struct { + Name string + Path string + Overwrite bool +} + +type Options struct { + Guaranteed bool +} + +type Outputer interface { + // Publish event + + PublishEvent(trans Signaler, opts Options, event common.MapStr) error +} + +type TopologyOutputer interface { + // Register the agent name and its IPs to the topology map + PublishIPs(name string, localAddrs []string) error + + // Get the agent name with a specific IP from the topology map + GetNameByIP(ip string) string +} + +// BulkOutputer adds BulkPublish to publish batches of events without looping. +// Outputers still might loop on events or use more efficient bulk-apis if present. +type BulkOutputer interface { + Outputer + BulkPublish(trans Signaler, opts Options, event []common.MapStr) error +} + +type OutputBuilder interface { + // Create and initialize the output plugin + NewOutput( + config *MothershipConfig, + topologyExpire int) (Outputer, error) +} + +// Functions to be exported by a output plugin +type OutputInterface interface { + Outputer + TopologyOutputer +} + +type OutputPlugin struct { + Name string + Config MothershipConfig + Output Outputer +} + +type bulkOutputAdapter struct { + Outputer +} + +var enabledOutputPlugins = make(map[string]OutputBuilder) + +func RegisterOutputPlugin(name string, builder OutputBuilder) { + enabledOutputPlugins[name] = builder +} + +func FindOutputPlugin(name string) OutputBuilder { + return enabledOutputPlugins[name] +} + +func InitOutputs( + beatName string, + configs map[string]MothershipConfig, + topologyExpire int, +) ([]OutputPlugin, error) { + var plugins []OutputPlugin = nil + for name, plugin := range enabledOutputPlugins { + config, exists := configs[name] + if !exists { + continue + } + + if config.Index == "" { + config.Index = beatName + } + + output, err := plugin.NewOutput(&config, topologyExpire) + if err != nil { + logp.Err("failed to initialize %s plugin as output: %s", name, err) + return nil, err + } + + plugin := OutputPlugin{Name: name, Config: config, Output: output} + plugins = append(plugins, plugin) + logp.Info("Activated %s as output plugin.", name) + } + return plugins, nil +} + +// CastBulkOutputer casts out into a BulkOutputer if out implements +// the BulkOutputer interface. If out does not implement the interface an outputer +// wrapper implementing the BulkOutputer interface is returned. +func CastBulkOutputer(out Outputer) BulkOutputer { + if bo, ok := out.(BulkOutputer); ok { + return bo + } + return &bulkOutputAdapter{out} +} + +func (b *bulkOutputAdapter) BulkPublish( + signal Signaler, + opts Options, + events []common.MapStr, +) error { + signal = NewSplitSignaler(signal, len(events)) + for _, evt := range events { + err := b.PublishEvent(signal, opts, evt) + if err != nil { + return err + } + } + return nil +} diff --git a/vendor/github.com/elastic/beats/libbeat/outputs/redis/redis.go b/vendor/github.com/elastic/beats/libbeat/outputs/redis/redis.go new file mode 100644 index 0000000..c33fc13 --- /dev/null +++ b/vendor/github.com/elastic/beats/libbeat/outputs/redis/redis.go @@ -0,0 +1,336 @@ +//@deprecated: Starting with version 1.0.0-beta4 the Redis Output is deprecated as +// it's replaced by the Logstash Output that has support for Redis Output plugin. + +package redis + +import ( + "encoding/json" + "errors" + "fmt" + "strings" + "sync/atomic" + "time" + + "github.com/elastic/beats/libbeat/common" + "github.com/elastic/beats/libbeat/logp" + "github.com/elastic/beats/libbeat/outputs" + + "github.com/garyburd/redigo/redis" +) + +func init() { + + outputs.RegisterOutputPlugin("redis", RedisOutputPlugin{}) +} + +type RedisOutputPlugin struct{} + +func (f RedisOutputPlugin) NewOutput( + config *outputs.MothershipConfig, + topology_expire int, +) (outputs.Outputer, error) { + output := &redisOutput{} + err := output.Init(*config, topology_expire) + if err != nil { + return nil, err + } + return output, nil +} + +type redisDataType uint16 + +const ( + RedisListType redisDataType = iota + RedisChannelType +) + +type redisOutput struct { + Index string + Conn redis.Conn + + TopologyExpire time.Duration + ReconnectInterval time.Duration + Hostname string + Password string + Db int + DbTopology int + Timeout time.Duration + DataType redisDataType + + TopologyMap atomic.Value // Value holds a map[string][string] + connected bool +} + +type message struct { + trans outputs.Signaler + index string + msg string +} + +func (out *redisOutput) Init(config outputs.MothershipConfig, topology_expire int) error { + + logp.Warn("Redis Output is deprecated. Please use the Redis Output Plugin from Logstash instead.") + + out.Hostname = fmt.Sprintf("%s:%d", config.Host, config.Port) + + if config.Password != "" { + out.Password = config.Password + } + + if config.Db != 0 { + out.Db = config.Db + } + + out.DbTopology = 1 + if config.DbTopology != 0 { + out.DbTopology = config.DbTopology + } + + out.Timeout = 5 * time.Second + if config.Timeout != 0 { + out.Timeout = time.Duration(config.Timeout) * time.Second + } + + out.Index = config.Index + + out.ReconnectInterval = time.Duration(1) * time.Second + if config.ReconnectInterval != 0 { + out.ReconnectInterval = time.Duration(config.ReconnectInterval) * time.Second + } + logp.Info("Reconnect Interval set to: %v", out.ReconnectInterval) + + expSec := 15 + if topology_expire != 0 { + expSec = topology_expire + } + out.TopologyExpire = time.Duration(expSec) * time.Second + + switch config.DataType { + case "", "list": + out.DataType = RedisListType + case "channel": + out.DataType = RedisChannelType + default: + return errors.New("Bad Redis data type") + } + + logp.Info("[RedisOutput] Using Redis server %s", out.Hostname) + if out.Password != "" { + logp.Info("[RedisOutput] Using password to connect to Redis") + } + logp.Info("[RedisOutput] Redis connection timeout %s", out.Timeout) + logp.Info("[RedisOutput] Redis reconnect interval %s", out.ReconnectInterval) + logp.Info("[RedisOutput] Using index pattern %s", out.Index) + logp.Info("[RedisOutput] Topology expires after %s", out.TopologyExpire) + logp.Info("[RedisOutput] Using db %d for storing events", out.Db) + logp.Info("[RedisOutput] Using db %d for storing topology", out.DbTopology) + logp.Info("[RedisOutput] Using %d data type", out.DataType) + + out.Reconnect() + + return nil +} + +func (out *redisOutput) RedisConnect(db int) (redis.Conn, error) { + conn, err := redis.DialTimeout( + "tcp", + out.Hostname, + out.Timeout, out.Timeout, out.Timeout) + if err != nil { + return nil, err + } + + if len(out.Password) > 0 { + _, err = conn.Do("AUTH", out.Password) + if err != nil { + return nil, err + } + } + + _, err = conn.Do("PING") + if err != nil { + return nil, err + } + + _, err = conn.Do("SELECT", db) + if err != nil { + return nil, err + } + + return conn, nil +} + +func (out *redisOutput) Connect() error { + var err error + out.Conn, err = out.RedisConnect(out.Db) + if err != nil { + return err + } + out.connected = true + + return nil +} + +func (out *redisOutput) Close() { + _ = out.Conn.Close() +} + +func (out *redisOutput) Reconnect() { + + for { + err := out.Connect() + if err != nil { + logp.Warn("Error connecting to Redis (%s). Retrying in %s", err, out.ReconnectInterval) + time.Sleep(out.ReconnectInterval) + } else { + break + } + } +} + +func (out *redisOutput) GetNameByIP(ip string) string { + topologyMap, ok := out.TopologyMap.Load().(map[string]string) + if ok { + name, exists := topologyMap[ip] + if exists { + return name + } + } + return "" +} + +func (out *redisOutput) PublishIPs(name string, localAddrs []string) error { + logp.Debug("output_redis", "[%s] Publish the IPs %s", name, localAddrs) + + // connect to db + conn, err := out.RedisConnect(out.DbTopology) + if err != nil { + return err + } + defer func() { _ = conn.Close() }() + + _, err = conn.Do("HSET", name, "ipaddrs", strings.Join(localAddrs, ",")) + if err != nil { + logp.Err("[%s] Fail to set the IP addresses: %s", name, err) + return err + } + + _, err = conn.Do("EXPIRE", name, int(out.TopologyExpire.Seconds())) + if err != nil { + logp.Err("[%s] Fail to set the expiration time: %s", name, err) + return err + } + + out.UpdateLocalTopologyMap(conn) + + return nil +} + +func (out *redisOutput) UpdateLocalTopologyMap(conn redis.Conn) { + topologyMapTmp := make(map[string]string) + hostnames, err := redis.Strings(conn.Do("KEYS", "*")) + if err != nil { + logp.Err("Fail to get the all shippers from the topology map %s", err) + return + } + for _, hostname := range hostnames { + res, err := redis.String(conn.Do("HGET", hostname, "ipaddrs")) + if err != nil { + logp.Err("[%s] Fail to get the IPs: %s", hostname, err) + } else { + ipaddrs := strings.Split(res, ",") + for _, addr := range ipaddrs { + topologyMapTmp[addr] = hostname + } + } + } + + out.TopologyMap.Store(topologyMapTmp) + + logp.Debug("output_redis", "Topology %s", topologyMapTmp) +} + +func (out *redisOutput) PublishEvent( + signal outputs.Signaler, + opts outputs.Options, + event common.MapStr, +) error { + return out.BulkPublish(signal, opts, []common.MapStr{event}) +} + +func (out *redisOutput) BulkPublish( + signal outputs.Signaler, + opts outputs.Options, + events []common.MapStr, +) error { + if !opts.Guaranteed { + err := out.doBulkPublish(events) + outputs.Signal(signal, err) + return err + } + + for { + err := out.doBulkPublish(events) + if err == nil { + outputs.SignalCompleted(signal) + return nil + } + + // TODO: add backoff + time.Sleep(1) + } +} + +func (out *redisOutput) doBulkPublish(events []common.MapStr) error { + if !out.connected { + logp.Debug("output_redis", "Droping pkt ...") + return errors.New("Not connected") + } + + command := "RPUSH" + if out.DataType == RedisChannelType { + command = "PUBLISH" + } + + if len(events) == 1 { // single event + event := events[0] + jsonEvent, err := json.Marshal(event) + if err != nil { + logp.Err("Fail to convert the event to JSON: %s", err) + return err + } + + _, err = out.Conn.Do(command, out.Index, string(jsonEvent)) + out.onFail(err) + return err + } + + for _, event := range events { + jsonEvent, err := json.Marshal(event) + if err != nil { + logp.Err("Fail to convert the event to JSON: %s", err) + continue + } + err = out.Conn.Send(command, out.Index, string(jsonEvent)) + if err != nil { + out.onFail(err) + return err + } + } + if err := out.Conn.Flush(); err != nil { + out.onFail(err) + return err + } + _, err := out.Conn.Receive() + out.onFail(err) + return err + +} + +func (out *redisOutput) onFail(err error) { + if err != nil { + logp.Err("Fail to publish event to REDIS: %s", err) + out.connected = false + go out.Reconnect() + } +} diff --git a/vendor/github.com/elastic/beats/libbeat/outputs/signal.go b/vendor/github.com/elastic/beats/libbeat/outputs/signal.go new file mode 100644 index 0000000..e5ae661 --- /dev/null +++ b/vendor/github.com/elastic/beats/libbeat/outputs/signal.go @@ -0,0 +1,185 @@ +package outputs + +import ( + "sync/atomic" + + "github.com/elastic/beats/libbeat/logp" +) + +// Signaler signals the completion of potentially asynchronous output operation. +// Completed is called by the output plugin when all events have been sent. On +// failure or if only a subset of the data is published then Failed will be +// invoked. +type Signaler interface { + Completed() + + Failed() +} + +// ChanSignal will send outputer signals on configurable channel. +type ChanSignal struct { + ch chan bool +} + +// SyncSignal blocks waiting for a signal. +type SyncSignal struct { + ch chan bool +} + +// SplitSignal guards one output signaler from multiple calls +// by using a simple reference counting scheme. If one Signaler consumer +// reports a Failed event, the Failed event will be send to the guarded Signaler +// once the reference count becomes zero. +// +// Example use cases: +// - Push signaler to multiple outputers +// - split data to be send in smaller batches +type SplitSignal struct { + count int32 + failed bool + signaler Signaler +} + +// CompositeSignal combines multiple signalers into one Signaler forwarding an event to +// to all signalers. +type CompositeSignal struct { + signalers []Signaler +} + +// NewChanSignal create a new ChanSignal forwarding signals to a channel. +func NewChanSignal(ch chan bool) *ChanSignal { return &ChanSignal{ch} } + +// Completed sends true to the confiugred channel. +func (c *ChanSignal) Completed() { + logp.Debug("output", "send completed") + c.ch <- true +} + +// Failed sends false to the confiugred channel. +func (c *ChanSignal) Failed() { + logp.Debug("output", "send failed") + c.ch <- false +} + +// NewSyncSignal create a new SyncSignal signaler. Use Wait() method to wait for +// a signal from the publisher +func NewSyncSignal() *SyncSignal { return &SyncSignal{make(chan bool, 1)} } + +// Wait blocks waiting for a signal from the outputer. Wait return true if +// Completed was signaled and false if a Failed signal was received +func (s *SyncSignal) Wait() bool { return <-s.ch } + +// Completed sends true to the process waiting for a signal. +func (s *SyncSignal) Completed() { s.ch <- true } + +// Failed sends false to the process waiting for a signal. +func (s *SyncSignal) Failed() { s.ch <- false } + +// NewSplitSignaler creates a new SplitSignal if s is not nil. +// If s is nil, nil will be returned. The count is the number of events to be +// received before publishing the final event to the guarded Signaler. +func NewSplitSignaler( + s Signaler, + count int, +) Signaler { + if s == nil { + return nil + } + + return &SplitSignal{ + count: int32(count), + signaler: s, + } +} + +// Completed signals a Completed event to s. +func (s *SplitSignal) Completed() { + s.onEvent() +} + +// Failed signals a Failed event to s. +func (s *SplitSignal) Failed() { + s.failed = true + s.onEvent() +} + +func (s *SplitSignal) onEvent() { + res := atomic.AddInt32(&s.count, -1) + if res == 0 { + if s.failed { + s.signaler.Failed() + } else { + s.signaler.Completed() + } + } +} + +// NewCompositeSignaler creates a new composite signaler. +func NewCompositeSignaler(signalers ...Signaler) Signaler { + if len(signalers) == 0 { + return nil + } + return &CompositeSignal{signalers} +} + +// Completed sends the Completed signal to all signalers. +func (cs *CompositeSignal) Completed() { + for _, s := range cs.signalers { + if s != nil { + s.Completed() + } + } +} + +// Failed sends the Failed signal to all signalers. +func (cs *CompositeSignal) Failed() { + for _, s := range cs.signalers { + if s != nil { + s.Failed() + } + } +} + +// SignalCompleted sends the Completed event to s if s is not nil. +func SignalCompleted(s Signaler) { + if s != nil { + s.Completed() + } +} + +// SignalFailed sends the Failed event to s if s is not nil +func SignalFailed(s Signaler, err error) { + + if err != nil { + logp.Err("Error sending/writing event: %s", err) + } + + if s != nil { + s.Failed() + } +} + +// Signal will send the Completed or Failed event to s depending +// on err being set if s is not nil. +func Signal(s Signaler, err error) { + + if err != nil { + logp.Info("Failed to send event %s", err) + } + + if s != nil { + if err == nil { + s.Completed() + } else { + s.Failed() + } + } +} + +// SignalAll send the Completed or Failed event to all given signalers +// depending on err being set. +func SignalAll(signalers []Signaler, err error) { + if signalers != nil { + Signal(NewCompositeSignaler(signalers...), err) + } +} diff --git a/vendor/github.com/elastic/beats/libbeat/outputs/tls.go b/vendor/github.com/elastic/beats/libbeat/outputs/tls.go new file mode 100644 index 0000000..e818702 --- /dev/null +++ b/vendor/github.com/elastic/beats/libbeat/outputs/tls.go @@ -0,0 +1,190 @@ +package outputs + +import ( + "crypto/tls" + "crypto/x509" + "errors" + "io/ioutil" + + "github.com/elastic/beats/libbeat/logp" +) + +var ( + // ErrNotACertificate indicates a PEM file to be loaded not being a valid + // PEM file or certificate. + ErrNotACertificate = errors.New("file is not a certificate") + + // ErrCertificateNoKey indicate a configuration error with missing key file + ErrCertificateNoKey = errors.New("key file not configured") + + // ErrKeyNoCertificate indicate a configuration error with missing certificate file + ErrKeyNoCertificate = errors.New("certificate file not configured") + + // ErrInvalidTLSVersion indicates an unknown tls version string given. + ErrInvalidTLSVersion = errors.New("invalid TLS version string") + + // ErrUnknownCipherSuite indicates an unknown tls cipher suite being used + ErrUnknownCipherSuite = errors.New("unknown cypher suite") + + // ErrUnknownCurveID indicates an unknown curve id has been configured + ErrUnknownCurveID = errors.New("unknown curve id") +) + +// TLSConfig defines config file options for TLS clients. +type TLSConfig struct { + Certificate string `yaml:"certificate"` + CertificateKey string `yaml:"certificate_key"` + CAs []string `yaml:"certificate_authorities"` + Insecure bool `yaml:"insecure,omitempty"` + CipherSuites []string `yaml:"cipher_suites"` + MinVersion string `yaml:"min_version,omitempty"` + MaxVersion string `yaml:"max_version,omitempty"` + CurveTypes []string `yaml:"curve_types"` +} + +// LoadTLSConfig will load a certificate from config with all TLS based keys +// defined. If Certificate and CertificateKey are configured, client authentication +// will be configured. If no CAs are configured, the host CA will be used by go +// built-in TLS support. +func LoadTLSConfig(config *TLSConfig) (*tls.Config, error) { + if config == nil { + return nil, nil + } + + certificate := config.Certificate + key := config.CertificateKey + rootCAs := config.CAs + hasCertificate := certificate != "" + hasKey := key != "" + + var certs []tls.Certificate + switch { + case hasCertificate && !hasKey: + return nil, ErrCertificateNoKey + case !hasCertificate && hasKey: + return nil, ErrKeyNoCertificate + case hasCertificate && hasKey: + cert, err := tls.LoadX509KeyPair(certificate, key) + if err != nil { + logp.Critical("Failed loading client certificate", err) + return nil, err + } + certs = []tls.Certificate{cert} + } + + var roots *x509.CertPool + if len(rootCAs) > 0 { + roots = x509.NewCertPool() + for _, caFile := range rootCAs { + pemData, err := ioutil.ReadFile(caFile) + if err != nil { + logp.Critical("Failed reading CA certificate: %s", err) + return nil, err + } + + if ok := roots.AppendCertsFromPEM(pemData); !ok { + return nil, ErrNotACertificate + } + } + } + + minVersion, err := parseTLSVersion(config.MinVersion) + if err != nil { + return nil, err + } + if minVersion == 0 { + // require minimum TLS-1.0 if not configured + minVersion = tls.VersionTLS10 + } + + maxVersion, err := parseTLSVersion(config.MaxVersion) + if err != nil { + return nil, err + } + + cipherSuites, err := parseTLSCipherSuites(config.CipherSuites) + if err != nil { + return nil, err + } + + curveIDs, err := parseCurveTypes(config.CurveTypes) + if err != nil { + return nil, err + } + + tlsConfig := tls.Config{ + MinVersion: minVersion, + MaxVersion: maxVersion, + Certificates: certs, + RootCAs: roots, + InsecureSkipVerify: config.Insecure, + CipherSuites: cipherSuites, + CurvePreferences: curveIDs, + } + return &tlsConfig, nil +} + +func parseTLSVersion(s string) (uint16, error) { + versions := map[string]uint16{ + "": 0, + "SSL-3.0": tls.VersionSSL30, + "1.0": tls.VersionTLS10, + "1.1": tls.VersionTLS11, + "1.2": tls.VersionTLS12, + } + + id, ok := versions[s] + if !ok { + return 0, ErrInvalidTLSVersion + } + return id, nil +} + +func parseTLSCipherSuites(names []string) ([]uint16, error) { + suites := map[string]uint16{ + "RSA-RC4-128-SHA": tls.TLS_RSA_WITH_RC4_128_SHA, + "RSA-3DES-CBC3-SHA": tls.TLS_RSA_WITH_3DES_EDE_CBC_SHA, + "RSA-AES-128-CBC-SHA": tls.TLS_RSA_WITH_AES_128_CBC_SHA, + "RSA-AES-256-CBC-SHA": tls.TLS_RSA_WITH_AES_256_CBC_SHA, + "ECDHE-ECDSA-RC4-128-SHA": tls.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, + "ECDHE-ECDSA-AES-128-CBC-SHA": tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, + "ECDHE-ECDSA-AES-256-CBC-SHA": tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, + "ECDHE-RSA-RC4-128-SHA": tls.TLS_ECDHE_RSA_WITH_RC4_128_SHA, + "ECDHE-RSA-3DES-CBC3-SHA": tls.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, + "ECDHE-RSA-AES-128-CBC-SHA": tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, + "ECDHE-RSA-AES-256-CBC-SHA": tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, + "ECDHE-RSA-AES-128-GCM-SHA256": tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + "ECDHE-ECDSA-AES-128-GCM-SHA256": tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, + "ECDHE-RSA-AES-256-GCM-SHA384": tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + "ECDHE-ECDSA-AES-256-GCM-SHA384": tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, + } + + var list []uint16 + for _, name := range names { + id, ok := suites[name] + if !ok { + return nil, ErrUnknownCipherSuite + } + + list = append(list, id) + } + return list, nil +} + +func parseCurveTypes(names []string) ([]tls.CurveID, error) { + curveIDs := map[string]tls.CurveID{ + "P-256": tls.CurveP256, + "P-384": tls.CurveP384, + "P-521": tls.CurveP521, + } + + var list []tls.CurveID + for _, name := range names { + id, ok := curveIDs[name] + if !ok { + return nil, ErrUnknownCurveID + } + list = append(list, id) + } + return list, nil +} diff --git a/vendor/github.com/elastic/beats/libbeat/publisher/async.go b/vendor/github.com/elastic/beats/libbeat/publisher/async.go new file mode 100644 index 0000000..fe3f963 --- /dev/null +++ b/vendor/github.com/elastic/beats/libbeat/publisher/async.go @@ -0,0 +1,94 @@ +package publisher + +import ( + "time" + + "github.com/elastic/beats/libbeat/common" + "github.com/elastic/beats/libbeat/logp" + "github.com/elastic/beats/libbeat/outputs" +) + +type asyncPublisher struct { + outputs []worker + pub *PublisherType + ws workerSignal +} + +const ( + defaultFlushInterval = 1000 * time.Millisecond // 1s + defaultBulkSize = 2048 +) + +func newAsyncPublisher(pub *PublisherType, hwm, bulkHWM int) *asyncPublisher { + p := &asyncPublisher{pub: pub} + p.ws.Init() + + var outputs []worker + for _, out := range pub.Output { + outputs = append(outputs, asyncOutputer(&p.ws, hwm, bulkHWM, out)) + } + + p.outputs = outputs + return p +} + +// onStop will send stop signal to message batching workers +func (p *asyncPublisher) onStop() { p.ws.stop() } + +func (p *asyncPublisher) client() eventPublisher { + return p +} + +func (p *asyncPublisher) PublishEvent(ctx Context, event common.MapStr) bool { + p.send(message{context: ctx, event: event}) + return true +} + +func (p *asyncPublisher) PublishEvents(ctx Context, events []common.MapStr) bool { + p.send(message{context: ctx, events: events}) + return true +} + +func (p *asyncPublisher) send(m message) { + if p.pub.disabled { + debug("publisher disabled") + outputs.SignalCompleted(m.context.Signal) + return + } + + // m.signal is not set yet. But a async client type supporting signals might + // be implemented in the future. + // If m.Signal is nil, NewSplitSignaler will return nil -> signaler will + // only set if client did send one + if m.context.Signal != nil && len(p.outputs) > 1 { + m.context.Signal = outputs.NewSplitSignaler(m.context.Signal, len(p.outputs)) + } + for _, o := range p.outputs { + o.send(m) + } +} + +func asyncOutputer(ws *workerSignal, hwm, bulkHWM int, worker *outputWorker) worker { + config := worker.config + + flushInterval := defaultFlushInterval + if config.FlushInterval != nil { + flushInterval = time.Duration(*config.FlushInterval) * time.Millisecond + } + logp.Info("Flush Interval set to: %v", flushInterval) + + maxBulkSize := defaultBulkSize + if config.BulkMaxSize != nil { + maxBulkSize = *config.BulkMaxSize + } + logp.Info("Max Bulk Size set to: %v", maxBulkSize) + + // batching disabled + if flushInterval <= 0 || maxBulkSize <= 0 { + return worker + } + + debug("create bulk processing worker (interval=%v, bulk size=%v)", + flushInterval, maxBulkSize) + return newBulkWorker(ws, hwm, bulkHWM, worker, flushInterval, maxBulkSize) +} diff --git a/vendor/github.com/elastic/beats/libbeat/publisher/bulk.go b/vendor/github.com/elastic/beats/libbeat/publisher/bulk.go new file mode 100644 index 0000000..a10dff6 --- /dev/null +++ b/vendor/github.com/elastic/beats/libbeat/publisher/bulk.go @@ -0,0 +1,140 @@ +package publisher + +import ( + "time" + + "github.com/elastic/beats/libbeat/common" + "github.com/elastic/beats/libbeat/outputs" +) + +type bulkWorker struct { + output worker + ws *workerSignal + + queue chan message + bulkQueue chan message + guaranteed bool + flushTicker *time.Ticker + + maxBatchSize int + events []common.MapStr // batched events + pending []outputs.Signaler // pending signalers for batched events +} + +func newBulkWorker( + ws *workerSignal, hwm int, bulkHWM int, + output worker, + flushInterval time.Duration, + maxBatchSize int, +) *bulkWorker { + b := &bulkWorker{ + output: output, + ws: ws, + queue: make(chan message, hwm), + bulkQueue: make(chan message, bulkHWM), + flushTicker: time.NewTicker(flushInterval), + maxBatchSize: maxBatchSize, + events: make([]common.MapStr, 0, maxBatchSize), + pending: nil, + } + + ws.wg.Add(1) + go b.run() + return b +} + +func (b *bulkWorker) send(m message) { + if m.events == nil { + b.queue <- m + } else { + b.bulkQueue <- m + } +} + +func (b *bulkWorker) run() { + defer b.shutdown() + + for { + select { + case <-b.ws.done: + return + case m := <-b.queue: + b.onEvent(&m.context, m.event) + case m := <-b.bulkQueue: + b.onEvents(&m.context, m.events) + case <-b.flushTicker.C: + if len(b.events) > 0 { + b.publish() + } + } + } +} + +func (b *bulkWorker) onEvent(ctx *Context, event common.MapStr) { + b.events = append(b.events, event) + b.guaranteed = b.guaranteed || ctx.Guaranteed + + signal := ctx.Signal + if signal != nil { + b.pending = append(b.pending, signal) + } + + if len(b.events) == cap(b.events) { + b.publish() + } +} + +func (b *bulkWorker) onEvents(ctx *Context, events []common.MapStr) { + for len(events) > 0 { + // split up bulk to match required bulk sizes. + // If input events have been split up bufferFull will be set and + // bulk request will be published. + spaceLeft := cap(b.events) - len(b.events) + consume := len(events) + bufferFull := spaceLeft <= consume + signal := ctx.Signal + b.guaranteed = b.guaranteed || ctx.Guaranteed + if spaceLeft < consume { + consume = spaceLeft + if signal != nil { + // creating cascading signaler chain for + // subset of events being send + signal = outputs.NewSplitSignaler(signal, 2) + } + } + + // buffer events + b.events = append(b.events, events[:consume]...) + events = events[consume:] + if signal != nil { + b.pending = append(b.pending, signal) + } + + if bufferFull { + b.publish() + } + } +} + +func (b *bulkWorker) publish() { + // TODO: remember/merge and forward context options to output worker + b.output.send(message{ + context: Context{ + publishOptions: publishOptions{Guaranteed: b.guaranteed}, + Signal: outputs.NewCompositeSignaler(b.pending...), + }, + event: nil, + events: b.events, + }) + + b.pending = nil + b.guaranteed = false + b.events = make([]common.MapStr, 0, b.maxBatchSize) +} + +func (b *bulkWorker) shutdown() { + b.flushTicker.Stop() + stopQueue(b.queue) + stopQueue(b.bulkQueue) + b.ws.wg.Done() +} diff --git a/vendor/github.com/elastic/beats/libbeat/publisher/client.go b/vendor/github.com/elastic/beats/libbeat/publisher/client.go new file mode 100644 index 0000000..bf02e20 --- /dev/null +++ b/vendor/github.com/elastic/beats/libbeat/publisher/client.go @@ -0,0 +1,171 @@ +package publisher + +import ( + "expvar" + + "github.com/elastic/beats/libbeat/common" + "github.com/elastic/beats/libbeat/logp" + "github.com/elastic/beats/libbeat/outputs" +) + +// Metrics that can retrieved through the expvar web interface. +var ( + publishedEvents = expvar.NewInt("libbeatPublishedEvents") +) + +// Client is used by beats to publish new events. +type Client interface { + // PublishEvent publishes one event with given options. If Sync option is set, + // PublishEvent will block until output plugins report success or failure state + // being returned by this method. + PublishEvent(event common.MapStr, opts ...ClientOption) bool + + // PublishEvents publishes multiple events with given options. If Guaranteed + // option is set, PublishEvent will block until output plugins report + // success or failure state being returned by this method. + PublishEvents(events []common.MapStr, opts ...ClientOption) bool +} + +// ChanClient will forward all published events one by one to the given channel +type ChanClient struct { + Channel chan common.MapStr +} + +type ExtChanClient struct { + Channel chan PublishMessage +} + +type PublishMessage struct { + Context Context + Events []common.MapStr +} + +type client struct { + publisher *PublisherType + + beatMeta common.MapStr + tags []string +} + +// ClientOption allows API users to set additional options when publishing events. +type ClientOption func(option Context) Context + +// Guaranteed option will retry publishing the event, until send attempt have +// been ACKed by output plugin. +func Guaranteed(o Context) Context { + o.Guaranteed = true + return o +} + +// Sync option will block the event publisher until an event has been ACKed by +// the output plugin or failed. +func Sync(o Context) Context { + o.Sync = true + return o +} + +func Signal(signaler outputs.Signaler) ClientOption { + return func(ctx Context) Context { + if ctx.Signal == nil { + ctx.Signal = signaler + } else { + ctx.Signal = outputs.NewCompositeSignaler(ctx.Signal, signaler) + } + return ctx + } +} + +func newClient(pub *PublisherType) *client { + return &client{ + publisher: pub, + beatMeta: common.MapStr{ + "name": pub.name, + "hostname": pub.hostname, + }, + tags: pub.tags, + } +} + +func (c *client) PublishEvent(event common.MapStr, opts ...ClientOption) bool { + c.annotateEvent(event) + + ctx, client := c.getClient(opts) + publishedEvents.Add(1) + return client.PublishEvent(ctx, event) +} + +func (c *client) PublishEvents(events []common.MapStr, opts ...ClientOption) bool { + for _, event := range events { + c.annotateEvent(event) + } + + ctx, client := c.getClient(opts) + publishedEvents.Add(int64(len(events))) + return client.PublishEvents(ctx, events) +} + +func (c *client) annotateEvent(event common.MapStr) { + + // Check if index was set dynamically + if _, ok := event["beat"]; ok { + beatTemp := event["beat"].(common.MapStr) + if _, ok := beatTemp["index"]; ok { + c.beatMeta["index"] = beatTemp["index"] + } + } + + event["beat"] = c.beatMeta + if len(c.tags) > 0 { + event["tags"] = c.tags + } + + if logp.IsDebug("publish") { + PrintPublishEvent(event) + } +} + +func (c *client) getClient(opts []ClientOption) (Context, eventPublisher) { + ctx := makeContext(opts) + if ctx.Sync { + return ctx, c.publisher.syncPublisher.client() + } + return ctx, c.publisher.asyncPublisher.client() +} + +// PublishEvent will publish the event on the channel. Options will be ignored. +// Always returns true. +func (c ChanClient) PublishEvent(event common.MapStr, opts ...ClientOption) bool { + c.Channel <- event + return true +} + +// PublishEvents publishes all event on the configured channel. Options will be ignored. +// Always returns true. +func (c ChanClient) PublishEvents(events []common.MapStr, opts ...ClientOption) bool { + for _, event := range events { + c.Channel <- event + } + return true +} + +// PublishEvent will publish the event on the channel. Options will be ignored. +// Always returns true. +func (c ExtChanClient) PublishEvent(event common.MapStr, opts ...ClientOption) bool { + c.Channel <- PublishMessage{makeContext(opts), []common.MapStr{event}} + return true +} + +// PublishEvents publishes all event on the configured channel. Options will be ignored. +// Always returns true. +func (c ExtChanClient) PublishEvents(events []common.MapStr, opts ...ClientOption) bool { + c.Channel <- PublishMessage{makeContext(opts), events} + return true +} + +func makeContext(opts []ClientOption) Context { + var ctx Context + for _, opt := range opts { + ctx = opt(ctx) + } + return ctx +} diff --git a/vendor/github.com/elastic/beats/libbeat/publisher/output.go b/vendor/github.com/elastic/beats/libbeat/publisher/output.go new file mode 100644 index 0000000..da4ee34 --- /dev/null +++ b/vendor/github.com/elastic/beats/libbeat/publisher/output.go @@ -0,0 +1,94 @@ +package publisher + +import ( + "errors" + + "github.com/elastic/beats/libbeat/common" + "github.com/elastic/beats/libbeat/logp" + "github.com/elastic/beats/libbeat/outputs" +) + +type outputWorker struct { + messageWorker + out outputs.BulkOutputer + config outputs.MothershipConfig + maxBulkSize int +} + +var ( + errSendFailed = errors.New("failed send attempt") +) + +func newOutputWorker( + config outputs.MothershipConfig, + out outputs.Outputer, + ws *workerSignal, + hwm int, + bulkHWM int, +) *outputWorker { + maxBulkSize := defaultBulkSize + if config.BulkMaxSize != nil { + maxBulkSize = *config.BulkMaxSize + } + + o := &outputWorker{ + out: outputs.CastBulkOutputer(out), + config: config, + maxBulkSize: maxBulkSize, + } + o.messageWorker.init(ws, hwm, bulkHWM, o) + return o +} + +func (o *outputWorker) onStop() {} + +func (o *outputWorker) onMessage(m message) { + if m.event != nil { + o.onEvent(&m.context, m.event) + } else { + o.onBulk(&m.context, m.events) + } +} + +func (o *outputWorker) onEvent(ctx *Context, event common.MapStr) { + debug("output worker: publish single event") + o.out.PublishEvent(ctx.Signal, outputs.Options{ctx.Guaranteed}, event) +} + +func (o *outputWorker) onBulk(ctx *Context, events []common.MapStr) { + if len(events) == 0 { + debug("output worker: no events to publish") + outputs.SignalCompleted(ctx.Signal) + return + } + + if o.maxBulkSize < 0 || len(events) <= o.maxBulkSize { + o.sendBulk(ctx, events) + return + } + + // start splitting bulk request + splits := (len(events) + (o.maxBulkSize - 1)) / o.maxBulkSize + ctx.Signal = outputs.NewSplitSignaler(ctx.Signal, splits) + for len(events) > 0 { + sz := o.maxBulkSize + if sz > len(events) { + sz = len(events) + } + o.sendBulk(ctx, events[:sz]) + events = events[sz:] + } +} + +func (o *outputWorker) sendBulk( + ctx *Context, + events []common.MapStr, +) { + debug("output worker: publish %v events", len(events)) + + opts := outputs.Options{ctx.Guaranteed} + err := o.out.BulkPublish(ctx.Signal, opts, events) + if err != nil { + logp.Info("Error bulk publishing events: %s", err) + } +} diff --git a/vendor/github.com/elastic/beats/libbeat/publisher/publish.go b/vendor/github.com/elastic/beats/libbeat/publisher/publish.go new file mode 100644 index 0000000..fbef341 --- /dev/null +++ b/vendor/github.com/elastic/beats/libbeat/publisher/publish.go @@ -0,0 +1,326 @@ +package publisher + +import ( + "encoding/json" + "errors" + "flag" + "os" + "time" + + "github.com/elastic/beats/libbeat/common" + "github.com/elastic/beats/libbeat/logp" + "github.com/elastic/beats/libbeat/outputs" + "github.com/nranchev/go-libGeoIP" + + // load supported output plugins + _ "github.com/elastic/beats/libbeat/outputs/console" + _ "github.com/elastic/beats/libbeat/outputs/elasticsearch" + _ "github.com/elastic/beats/libbeat/outputs/fileout" + _ "github.com/elastic/beats/libbeat/outputs/kafka" + _ "github.com/elastic/beats/libbeat/outputs/logstash" + _ "github.com/elastic/beats/libbeat/outputs/redis" +) + +// command line flags +var publishDisabled *bool + +var debug = logp.MakeDebug("publish") + +// EventPublisher provides the interface for beats to publish events. +type eventPublisher interface { + PublishEvent(ctx Context, event common.MapStr) bool + PublishEvents(ctx Context, events []common.MapStr) bool +} + +type Context struct { + publishOptions + Signal outputs.Signaler +} + +type publishOptions struct { + Guaranteed bool + Sync bool +} + +type TransactionalEventPublisher interface { + PublishTransaction(transaction outputs.Signaler, events []common.MapStr) +} + +type PublisherType struct { + shipperName string // Shipper name as set in the configuration file + hostname string // Host name as returned by the operation system + name string // The shipperName if configured, the hostname otherwise + IpAddrs []string + tags []string + disabled bool + Index string + Output []*outputWorker + TopologyOutput outputs.TopologyOutputer + IgnoreOutgoing bool + GeoLite *libgeo.GeoIP + + RefreshTopologyTimer <-chan time.Time + + // wsOutput and wsPublisher should be used for proper shutdown of publisher + // (not implemented yet). On shutdown the publisher should be finished first + // and the outputers next, so no publisher will attempt to send messages on + // closed channels. + // Note: beat data producers must be shutdown before the publisher plugin + wsOutput workerSignal + wsPublisher workerSignal + + syncPublisher *syncPublisher + asyncPublisher *asyncPublisher + + client *client +} + +type ShipperConfig struct { + Name string + Refresh_topology_freq int + Ignore_outgoing bool + Topology_expire int + Tags []string + Geoip common.Geoip + + // internal publisher queue sizes + QueueSize *int `yaml:"queue_size"` + BulkQueueSize *int `yaml:"bulk_queue_size"` + + MaxProcs *int `yaml:"max_procs"` +} + +type Topology struct { + Name string `json:"name"` + Ip string `json:"ip"` +} + +const ( + defaultChanSize = 1000 + defaultBulkChanSize = 0 +) + +func init() { + publishDisabled = flag.Bool("N", false, "Disable actual publishing for testing") +} + +func PrintPublishEvent(event common.MapStr) { + json, err := json.MarshalIndent(event, "", " ") + if err != nil { + logp.Err("json.Marshal: %s", err) + } else { + debug("Publish: %s", string(json)) + } +} + +func (publisher *PublisherType) IsPublisherIP(ip string) bool { + for _, myip := range publisher.IpAddrs { + if myip == ip { + return true + } + } + + return false +} + +func (publisher *PublisherType) GetServerName(ip string) string { + // in case the IP is localhost, return current shipper name + islocal, err := common.IsLoopback(ip) + if err != nil { + logp.Err("Parsing IP %s fails with: %s", ip, err) + return "" + } + + if islocal { + return publisher.name + } + + // find the shipper with the desired IP + if publisher.TopologyOutput != nil { + return publisher.TopologyOutput.GetNameByIP(ip) + } + + return "" +} + +func (publisher *PublisherType) Client() Client { + return publisher.client +} + +func (publisher *PublisherType) UpdateTopologyPeriodically() { + for range publisher.RefreshTopologyTimer { + _ = publisher.PublishTopology() // ignore errors + } +} + +func (publisher *PublisherType) PublishTopology(params ...string) error { + + localAddrs := params + if len(params) == 0 { + addrs, err := common.LocalIpAddrsAsStrings(false) + if err != nil { + logp.Err("Getting local IP addresses fails with: %s", err) + return err + } + localAddrs = addrs + } + + if publisher.TopologyOutput != nil { + debug("Add topology entry for %s: %s", publisher.name, localAddrs) + + err := publisher.TopologyOutput.PublishIPs(publisher.name, localAddrs) + if err != nil { + return err + } + } + + return nil +} + +// Create new PublisherType +func New( + beatName string, + configs map[string]outputs.MothershipConfig, + shipper ShipperConfig, +) (*PublisherType, error) { + + publisher := PublisherType{} + err := publisher.init(beatName, configs, shipper) + if err != nil { + return nil, err + } + return &publisher, nil +} + +func (publisher *PublisherType) init( + beatName string, + configs map[string]outputs.MothershipConfig, + shipper ShipperConfig, +) error { + var err error + publisher.IgnoreOutgoing = shipper.Ignore_outgoing + + publisher.disabled = *publishDisabled + if publisher.disabled { + logp.Info("Dry run mode. All output types except the file based one are disabled.") + } + + hwm := defaultChanSize + if shipper.QueueSize != nil && *shipper.QueueSize > 0 { + hwm = *shipper.QueueSize + } + + bulkHWM := defaultBulkChanSize + if shipper.BulkQueueSize != nil && *shipper.BulkQueueSize >= 0 { + bulkHWM = *shipper.BulkQueueSize + } + + publisher.GeoLite = common.LoadGeoIPData(shipper.Geoip) + + publisher.wsOutput.Init() + publisher.wsPublisher.Init() + + if !publisher.disabled { + plugins, err := outputs.InitOutputs(beatName, configs, shipper.Topology_expire) + if err != nil { + return err + } + + var outputers []*outputWorker + var topoOutput outputs.TopologyOutputer + for _, plugin := range plugins { + output := plugin.Output + config := plugin.Config + + debug("Create output worker") + + outputers = append(outputers, + newOutputWorker( + config, + output, + &publisher.wsOutput, + hwm, + bulkHWM)) + + if !config.SaveTopology { + continue + } + + topo, ok := output.(outputs.TopologyOutputer) + if !ok { + logp.Err("Output type %s does not support topology logging", + plugin.Name) + return errors.New("Topology output not supported") + } + + if topoOutput != nil { + logp.Err("Multiple outputs defined to store topology. " + + "Please add save_topology = true option only for one output.") + return errors.New("Multiple outputs defined to store topology") + } + + topoOutput = topo + logp.Info("Using %s to store the topology", plugin.Name) + } + + publisher.Output = outputers + publisher.TopologyOutput = topoOutput + } + + if !publisher.disabled { + if len(publisher.Output) == 0 { + logp.Info("No outputs are defined. Please define one under the output section.") + return errors.New("No outputs are defined. Please define one under the output section.") + } + + if publisher.TopologyOutput == nil { + logp.Debug("publish", "No output is defined to store the topology. The server fields might not be filled.") + } + } + + publisher.shipperName = shipper.Name + publisher.hostname, err = os.Hostname() + if err != nil { + return err + } + if len(publisher.shipperName) > 0 { + publisher.name = publisher.shipperName + } else { + publisher.name = publisher.hostname + } + logp.Info("Publisher name: %s", publisher.name) + + publisher.tags = shipper.Tags + + //Store the publisher's IP addresses + publisher.IpAddrs, err = common.LocalIpAddrsAsStrings(false) + if err != nil { + logp.Err("Failed to get local IP addresses: %s", err) + return err + } + + if !publisher.disabled && publisher.TopologyOutput != nil { + RefreshTopologyFreq := 10 * time.Second + if shipper.Refresh_topology_freq != 0 { + RefreshTopologyFreq = time.Duration(shipper.Refresh_topology_freq) * time.Second + } + publisher.RefreshTopologyTimer = time.Tick(RefreshTopologyFreq) + logp.Info("Topology map refreshed every %s", RefreshTopologyFreq) + + // register shipper and its public IP addresses + err = publisher.PublishTopology() + if err != nil { + logp.Err("Failed to publish topology: %s", err) + return err + } + + // update topology periodically + go publisher.UpdateTopologyPeriodically() + } + + publisher.asyncPublisher = newAsyncPublisher(publisher, hwm, bulkHWM) + publisher.syncPublisher = newSyncPublisher(publisher, hwm, bulkHWM) + + publisher.client = newClient(publisher) + return nil +} diff --git a/vendor/github.com/elastic/beats/libbeat/publisher/sync.go b/vendor/github.com/elastic/beats/libbeat/publisher/sync.go new file mode 100644 index 0000000..1f0c909 --- /dev/null +++ b/vendor/github.com/elastic/beats/libbeat/publisher/sync.go @@ -0,0 +1,58 @@ +package publisher + +import ( + "github.com/elastic/beats/libbeat/common" + "github.com/elastic/beats/libbeat/outputs" +) + +type syncPublisher struct { + pub *PublisherType +} + +type syncClient func(message) bool + +func newSyncPublisher(pub *PublisherType, hwm, bulkHWM int) *syncPublisher { + return &syncPublisher{pub: pub} +} + +func (p *syncPublisher) client() eventPublisher { + return p +} + +func (p *syncPublisher) PublishEvent(ctx Context, event common.MapStr) bool { + msg := message{context: ctx, event: event} + return p.send(msg) +} + +func (p *syncPublisher) PublishEvents(ctx Context, events []common.MapStr) bool { + msg := message{context: ctx, events: events} + return p.send(msg) +} + +func (p *syncPublisher) send(m message) bool { + if p.pub.disabled { + debug("publisher disabled") + outputs.SignalCompleted(m.context.Signal) + return true + } + + signal := m.context.Signal + sync := outputs.NewSyncSignal() + if len(p.pub.Output) > 1 { + m.context.Signal = outputs.NewSplitSignaler(sync, len(p.pub.Output)) + } else { + m.context.Signal = sync + } + + for _, o := range p.pub.Output { + o.send(m) + } + + ok := sync.Wait() + if ok { + outputs.SignalCompleted(signal) + } else if signal != nil { + signal.Failed() + } + return ok +} diff --git a/vendor/github.com/elastic/beats/libbeat/publisher/worker.go b/vendor/github.com/elastic/beats/libbeat/publisher/worker.go new file mode 100644 index 0000000..1e18323 --- /dev/null +++ b/vendor/github.com/elastic/beats/libbeat/publisher/worker.go @@ -0,0 +1,110 @@ +package publisher + +import ( + "expvar" + "sync" + + "github.com/elastic/beats/libbeat/common" + "github.com/elastic/beats/libbeat/outputs" +) + +// Metrics that can retrieved through the expvar web interface. +var ( + messagesInWorkerQueues = expvar.NewInt("libbeatMessagesInWorkerQueues") +) + +type worker interface { + send(m message) +} + +type messageWorker struct { + queue chan message + bulkQueue chan message + ws *workerSignal + handler messageHandler +} + +type message struct { + context Context + event common.MapStr + events []common.MapStr +} + +type workerSignal struct { + done chan struct{} + wg sync.WaitGroup +} + +type messageHandler interface { + onMessage(m message) + onStop() +} + +func newMessageWorker(ws *workerSignal, hwm, bulkHWM int, h messageHandler) *messageWorker { + p := &messageWorker{} + p.init(ws, hwm, bulkHWM, h) + return p +} + +func (p *messageWorker) init(ws *workerSignal, hwm, bulkHWM int, h messageHandler) { + p.queue = make(chan message, hwm) + p.bulkQueue = make(chan message, bulkHWM) + p.ws = ws + p.handler = h + ws.wg.Add(1) + go p.run() +} + +func (p *messageWorker) run() { + defer p.shutdown() + for { + select { + case <-p.ws.done: + return + case m := <-p.queue: + messagesInWorkerQueues.Add(-1) + p.handler.onMessage(m) + case m := <-p.bulkQueue: + messagesInWorkerQueues.Add(-1) + p.handler.onMessage(m) + } + } +} + +func (p *messageWorker) shutdown() { + p.handler.onStop() + stopQueue(p.queue) + stopQueue(p.bulkQueue) + p.ws.wg.Done() +} + +func (p *messageWorker) send(m message) { + if m.event != nil { + p.queue <- m + } else { + p.bulkQueue <- m + } + messagesInWorkerQueues.Add(1) +} + +func (ws *workerSignal) stop() { + close(ws.done) + ws.wg.Wait() +} + +func newWorkerSignal() *workerSignal { + w := &workerSignal{} + w.Init() + return w +} + +func (ws *workerSignal) Init() { + ws.done = make(chan struct{}) +} + +func stopQueue(qu chan message) { + close(qu) + for msg := range qu { // clear queue and send fail signal + outputs.SignalFailed(msg.context.Signal, nil) + } +} diff --git a/vendor/github.com/elastic/beats/libbeat/service/service.go b/vendor/github.com/elastic/beats/libbeat/service/service.go new file mode 100644 index 0000000..f6953f9 --- /dev/null +++ b/vendor/github.com/elastic/beats/libbeat/service/service.go @@ -0,0 +1,114 @@ +package service + +import ( + "flag" + "log" + "os" + "os/signal" + "runtime" + "runtime/pprof" + "sync" + "syscall" + + "github.com/elastic/beats/libbeat/logp" + + "net/http" + _ "net/http/pprof" +) + +// HandleSignals manages OS signals that ask the service/daemon to stop. +// The stopFunction should break the loop in the Beat so that +// the service shut downs gracefully. +func HandleSignals(stopFunction func()) { + var callback sync.Once + + // On ^C or SIGTERM, gracefully stop the sniffer + sigc := make(chan os.Signal, 1) + signal.Notify(sigc, syscall.SIGINT, syscall.SIGTERM) + go func() { + <-sigc + logp.Debug("service", "Received sigterm/sigint, stopping") + callback.Do(stopFunction) + }() + + // Handle the Windows service events + go ProcessWindowsControlEvents(func() { + logp.Debug("service", "Received svc stop/shutdown request") + callback.Do(stopFunction) + }) +} + +// cmdline flags +var memprofile, cpuprofile, httpprof *string +var cpuOut *os.File + +func init() { + memprofile = flag.String("memprofile", "", "Write memory profile to this file") + cpuprofile = flag.String("cpuprofile", "", "Write cpu profile to file") + httpprof = flag.String("httpprof", "", "Start pprof http server") +} + +// WithMemProfile returns whether the beat should write the memory profile to file +func WithMemProfile() bool { + return *memprofile != "" +} + +// WithCpuProfile returns whether the beat should write the CPU profile file +func WithCpuProfile() bool { + return *cpuprofile != "" +} + +// BeforeRun takes care of necessary actions such as creating files +// before the beat should run. +func BeforeRun() { + if WithCpuProfile() { + cpuOut, err := os.Create(*cpuprofile) + if err != nil { + log.Fatal(err) + } + pprof.StartCPUProfile(cpuOut) + } + + if *httpprof != "" { + go func() { + logp.Info("start pprof endpoint") + logp.Info("finished pprof endpoint: %v", http.ListenAndServe(*httpprof, nil)) + }() + } +} + +// Cleanup handles cleaning up the runtime and OS environments. This includes +// tasks such as stopping the CPU profile if it is running. +func Cleanup() { + if WithCpuProfile() { + pprof.StopCPUProfile() + cpuOut.Close() + } + + if WithMemProfile() { + runtime.GC() + + writeHeapProfile(*memprofile) + + debugMemStats() + } +} + +func debugMemStats() { + var m runtime.MemStats + runtime.ReadMemStats(&m) + logp.Debug("mem", "Memory stats: In use: %d Total (even if freed): %d System: %d", + m.Alloc, m.TotalAlloc, m.Sys) +} + +func writeHeapProfile(filename string) { + f, err := os.Create(filename) + if err != nil { + logp.Err("Failed creating file %s: %s", filename, err) + return + } + pprof.WriteHeapProfile(f) + f.Close() + + logp.Info("Created memory profile file %s.", filename) +} diff --git a/vendor/github.com/elastic/beats/libbeat/service/service_unix.go b/vendor/github.com/elastic/beats/libbeat/service/service_unix.go new file mode 100644 index 0000000..5e80ca4 --- /dev/null +++ b/vendor/github.com/elastic/beats/libbeat/service/service_unix.go @@ -0,0 +1,7 @@ +// +build !windows + +package service + +// ProcessWindowsControlEvents is not used on non-windows platforms. +func ProcessWindowsControlEvents(stopCallback func()) { +} diff --git a/vendor/github.com/elastic/beats/libbeat/service/service_windows.go b/vendor/github.com/elastic/beats/libbeat/service/service_windows.go new file mode 100644 index 0000000..3b06786 --- /dev/null +++ b/vendor/github.com/elastic/beats/libbeat/service/service_windows.go @@ -0,0 +1,63 @@ +package service + +import ( + "os" + "time" + + "github.com/elastic/beats/libbeat/logp" + "golang.org/x/sys/windows/svc" + "golang.org/x/sys/windows/svc/debug" +) + +type beatService struct{} + +// Execute runs the beat service with the arguments and manages changes that +// occur in the environment or runtime that may affect the beat. +func (m *beatService) Execute(args []string, r <-chan svc.ChangeRequest, changes chan<- svc.Status) (ssec bool, errno uint32) { + + const cmdsAccepted = svc.AcceptStop | svc.AcceptShutdown + changes <- svc.Status{State: svc.StartPending} + changes <- svc.Status{State: svc.Running, Accepts: cmdsAccepted} + +loop: + for c := range r { + switch c.Cmd { + case svc.Interrogate: + changes <- c.CurrentStatus + // Testing deadlock from https://code.google.com/p/winsvc/issues/detail?id=4 + time.Sleep(100 * time.Millisecond) + changes <- c.CurrentStatus + case svc.Stop, svc.Shutdown: + break loop + default: + logp.Err("Unexpected control request: $%d. Ignored.", c) + } + } + changes <- svc.Status{State: svc.StopPending} + return +} + +// ProcessWindowsControlEvents on Windows machines creates a loop +// that only finishes when a Stop or Shutdown request is received. +// On non-windows platforms, the function does nothing. The +// stopCallback function is called when the Stop/Shutdown +// request is received. +func ProcessWindowsControlEvents(stopCallback func()) { + isInteractive, err := svc.IsAnInteractiveSession() + if err != nil { + logp.Err("IsAnInteractiveSession: %v", err) + return + } + logp.Debug("service", "Windows is interactive: %v", isInteractive) + + run := svc.Run + if isInteractive { + run = debug.Run + } + err = run(os.Args[0], &beatService{}) + if err != nil { + logp.Err("Error: %v", err) + } else { + stopCallback() + } +} diff --git a/vendor/github.com/garyburd/redigo/internal/commandinfo.go b/vendor/github.com/garyburd/redigo/internal/commandinfo.go new file mode 100644 index 0000000..dbc60fc --- /dev/null +++ b/vendor/github.com/garyburd/redigo/internal/commandinfo.go @@ -0,0 +1,54 @@ +// Copyright 2014 Gary Burd +// +// Licensed under the Apache License, Version 2.0 (the "License"): you may +// not use this file except in compliance with the License. You may obtain +// a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations +// under the License. + +package internal + +import ( + "strings" +) + +const ( + WatchState = 1 << iota + MultiState + SubscribeState + MonitorState +) + +type CommandInfo struct { + Set, Clear int +} + +var commandInfos = map[string]CommandInfo{ + "WATCH": {Set: WatchState}, + "UNWATCH": {Clear: WatchState}, + "MULTI": {Set: MultiState}, + "EXEC": {Clear: WatchState | MultiState}, + "DISCARD": {Clear: WatchState | MultiState}, + "PSUBSCRIBE": {Set: SubscribeState}, + "SUBSCRIBE": {Set: SubscribeState}, + "MONITOR": {Set: MonitorState}, +} + +func init() { + for n, ci := range commandInfos { + commandInfos[strings.ToLower(n)] = ci + } +} + +func LookupCommandInfo(commandName string) CommandInfo { + if ci, ok := commandInfos[commandName]; ok { + return ci + } + return commandInfos[strings.ToUpper(commandName)] +} diff --git a/vendor/github.com/garyburd/redigo/internal/redistest/testdb.go b/vendor/github.com/garyburd/redigo/internal/redistest/testdb.go new file mode 100644 index 0000000..5f955c4 --- /dev/null +++ b/vendor/github.com/garyburd/redigo/internal/redistest/testdb.go @@ -0,0 +1,65 @@ +// Copyright 2014 Gary Burd +// +// Licensed under the Apache License, Version 2.0 (the "License"): you may +// not use this file except in compliance with the License. You may obtain +// a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations +// under the License. + +// Package redistest contains utilities for writing Redigo tests. +package redistest + +import ( + "errors" + "time" + + "github.com/garyburd/redigo/redis" +) + +type testConn struct { + redis.Conn +} + +func (t testConn) Close() error { + _, err := t.Conn.Do("SELECT", "9") + if err != nil { + return nil + } + _, err = t.Conn.Do("FLUSHDB") + if err != nil { + return err + } + return t.Conn.Close() +} + +// Dial dials the local Redis server and selects database 9. To prevent +// stomping on real data, DialTestDB fails if database 9 contains data. The +// returned connection flushes database 9 on close. +func Dial() (redis.Conn, error) { + c, err := redis.DialTimeout("tcp", ":6379", 0, 1*time.Second, 1*time.Second) + if err != nil { + return nil, err + } + + _, err = c.Do("SELECT", "9") + if err != nil { + return nil, err + } + + n, err := redis.Int(c.Do("DBSIZE")) + if err != nil { + return nil, err + } + + if n != 0 { + return nil, errors.New("database #9 is not empty, test can not continue") + } + + return testConn{c}, nil +} diff --git a/vendor/github.com/garyburd/redigo/redis/conn.go b/vendor/github.com/garyburd/redigo/redis/conn.go new file mode 100644 index 0000000..ac0e971 --- /dev/null +++ b/vendor/github.com/garyburd/redigo/redis/conn.go @@ -0,0 +1,455 @@ +// Copyright 2012 Gary Burd +// +// Licensed under the Apache License, Version 2.0 (the "License"): you may +// not use this file except in compliance with the License. You may obtain +// a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations +// under the License. + +package redis + +import ( + "bufio" + "bytes" + "errors" + "fmt" + "io" + "net" + "strconv" + "sync" + "time" +) + +// conn is the low-level implementation of Conn +type conn struct { + + // Shared + mu sync.Mutex + pending int + err error + conn net.Conn + + // Read + readTimeout time.Duration + br *bufio.Reader + + // Write + writeTimeout time.Duration + bw *bufio.Writer + + // Scratch space for formatting argument length. + // '*' or '$', length, "\r\n" + lenScratch [32]byte + + // Scratch space for formatting integers and floats. + numScratch [40]byte +} + +// Dial connects to the Redis server at the given network and address. +func Dial(network, address string) (Conn, error) { + dialer := xDialer{} + return dialer.Dial(network, address) +} + +// DialTimeout acts like Dial but takes timeouts for establishing the +// connection to the server, writing a command and reading a reply. +func DialTimeout(network, address string, connectTimeout, readTimeout, writeTimeout time.Duration) (Conn, error) { + netDialer := net.Dialer{Timeout: connectTimeout} + dialer := xDialer{ + NetDial: netDialer.Dial, + ReadTimeout: readTimeout, + WriteTimeout: writeTimeout, + } + return dialer.Dial(network, address) +} + +// A Dialer specifies options for connecting to a Redis server. +type xDialer struct { + // NetDial specifies the dial function for creating TCP connections. If + // NetDial is nil, then net.Dial is used. + NetDial func(network, addr string) (net.Conn, error) + + // ReadTimeout specifies the timeout for reading a single command + // reply. If ReadTimeout is zero, then no timeout is used. + ReadTimeout time.Duration + + // WriteTimeout specifies the timeout for writing a single command. If + // WriteTimeout is zero, then no timeout is used. + WriteTimeout time.Duration +} + +// Dial connects to the Redis server at address on the named network. +func (d *xDialer) Dial(network, address string) (Conn, error) { + dial := d.NetDial + if dial == nil { + dial = net.Dial + } + netConn, err := dial(network, address) + if err != nil { + return nil, err + } + return &conn{ + conn: netConn, + bw: bufio.NewWriter(netConn), + br: bufio.NewReader(netConn), + readTimeout: d.ReadTimeout, + writeTimeout: d.WriteTimeout, + }, nil +} + +// NewConn returns a new Redigo connection for the given net connection. +func NewConn(netConn net.Conn, readTimeout, writeTimeout time.Duration) Conn { + return &conn{ + conn: netConn, + bw: bufio.NewWriter(netConn), + br: bufio.NewReader(netConn), + readTimeout: readTimeout, + writeTimeout: writeTimeout, + } +} + +func (c *conn) Close() error { + c.mu.Lock() + err := c.err + if c.err == nil { + c.err = errors.New("redigo: closed") + err = c.conn.Close() + } + c.mu.Unlock() + return err +} + +func (c *conn) fatal(err error) error { + c.mu.Lock() + if c.err == nil { + c.err = err + // Close connection to force errors on subsequent calls and to unblock + // other reader or writer. + c.conn.Close() + } + c.mu.Unlock() + return err +} + +func (c *conn) Err() error { + c.mu.Lock() + err := c.err + c.mu.Unlock() + return err +} + +func (c *conn) writeLen(prefix byte, n int) error { + c.lenScratch[len(c.lenScratch)-1] = '\n' + c.lenScratch[len(c.lenScratch)-2] = '\r' + i := len(c.lenScratch) - 3 + for { + c.lenScratch[i] = byte('0' + n%10) + i -= 1 + n = n / 10 + if n == 0 { + break + } + } + c.lenScratch[i] = prefix + _, err := c.bw.Write(c.lenScratch[i:]) + return err +} + +func (c *conn) writeString(s string) error { + c.writeLen('$', len(s)) + c.bw.WriteString(s) + _, err := c.bw.WriteString("\r\n") + return err +} + +func (c *conn) writeBytes(p []byte) error { + c.writeLen('$', len(p)) + c.bw.Write(p) + _, err := c.bw.WriteString("\r\n") + return err +} + +func (c *conn) writeInt64(n int64) error { + return c.writeBytes(strconv.AppendInt(c.numScratch[:0], n, 10)) +} + +func (c *conn) writeFloat64(n float64) error { + return c.writeBytes(strconv.AppendFloat(c.numScratch[:0], n, 'g', -1, 64)) +} + +func (c *conn) writeCommand(cmd string, args []interface{}) (err error) { + c.writeLen('*', 1+len(args)) + err = c.writeString(cmd) + for _, arg := range args { + if err != nil { + break + } + switch arg := arg.(type) { + case string: + err = c.writeString(arg) + case []byte: + err = c.writeBytes(arg) + case int: + err = c.writeInt64(int64(arg)) + case int64: + err = c.writeInt64(arg) + case float64: + err = c.writeFloat64(arg) + case bool: + if arg { + err = c.writeString("1") + } else { + err = c.writeString("0") + } + case nil: + err = c.writeString("") + default: + var buf bytes.Buffer + fmt.Fprint(&buf, arg) + err = c.writeBytes(buf.Bytes()) + } + } + return err +} + +type protocolError string + +func (pe protocolError) Error() string { + return fmt.Sprintf("redigo: %s (possible server error or unsupported concurrent read by application)", string(pe)) +} + +func (c *conn) readLine() ([]byte, error) { + p, err := c.br.ReadSlice('\n') + if err == bufio.ErrBufferFull { + return nil, protocolError("long response line") + } + if err != nil { + return nil, err + } + i := len(p) - 2 + if i < 0 || p[i] != '\r' { + return nil, protocolError("bad response line terminator") + } + return p[:i], nil +} + +// parseLen parses bulk string and array lengths. +func parseLen(p []byte) (int, error) { + if len(p) == 0 { + return -1, protocolError("malformed length") + } + + if p[0] == '-' && len(p) == 2 && p[1] == '1' { + // handle $-1 and $-1 null replies. + return -1, nil + } + + var n int + for _, b := range p { + n *= 10 + if b < '0' || b > '9' { + return -1, protocolError("illegal bytes in length") + } + n += int(b - '0') + } + + return n, nil +} + +// parseInt parses an integer reply. +func parseInt(p []byte) (interface{}, error) { + if len(p) == 0 { + return 0, protocolError("malformed integer") + } + + var negate bool + if p[0] == '-' { + negate = true + p = p[1:] + if len(p) == 0 { + return 0, protocolError("malformed integer") + } + } + + var n int64 + for _, b := range p { + n *= 10 + if b < '0' || b > '9' { + return 0, protocolError("illegal bytes in length") + } + n += int64(b - '0') + } + + if negate { + n = -n + } + return n, nil +} + +var ( + okReply interface{} = "OK" + pongReply interface{} = "PONG" +) + +func (c *conn) readReply() (interface{}, error) { + line, err := c.readLine() + if err != nil { + return nil, err + } + if len(line) == 0 { + return nil, protocolError("short response line") + } + switch line[0] { + case '+': + switch { + case len(line) == 3 && line[1] == 'O' && line[2] == 'K': + // Avoid allocation for frequent "+OK" response. + return okReply, nil + case len(line) == 5 && line[1] == 'P' && line[2] == 'O' && line[3] == 'N' && line[4] == 'G': + // Avoid allocation in PING command benchmarks :) + return pongReply, nil + default: + return string(line[1:]), nil + } + case '-': + return Error(string(line[1:])), nil + case ':': + return parseInt(line[1:]) + case '$': + n, err := parseLen(line[1:]) + if n < 0 || err != nil { + return nil, err + } + p := make([]byte, n) + _, err = io.ReadFull(c.br, p) + if err != nil { + return nil, err + } + if line, err := c.readLine(); err != nil { + return nil, err + } else if len(line) != 0 { + return nil, protocolError("bad bulk string format") + } + return p, nil + case '*': + n, err := parseLen(line[1:]) + if n < 0 || err != nil { + return nil, err + } + r := make([]interface{}, n) + for i := range r { + r[i], err = c.readReply() + if err != nil { + return nil, err + } + } + return r, nil + } + return nil, protocolError("unexpected response line") +} + +func (c *conn) Send(cmd string, args ...interface{}) error { + c.mu.Lock() + c.pending += 1 + c.mu.Unlock() + if c.writeTimeout != 0 { + c.conn.SetWriteDeadline(time.Now().Add(c.writeTimeout)) + } + if err := c.writeCommand(cmd, args); err != nil { + return c.fatal(err) + } + return nil +} + +func (c *conn) Flush() error { + if c.writeTimeout != 0 { + c.conn.SetWriteDeadline(time.Now().Add(c.writeTimeout)) + } + if err := c.bw.Flush(); err != nil { + return c.fatal(err) + } + return nil +} + +func (c *conn) Receive() (reply interface{}, err error) { + if c.readTimeout != 0 { + c.conn.SetReadDeadline(time.Now().Add(c.readTimeout)) + } + if reply, err = c.readReply(); err != nil { + return nil, c.fatal(err) + } + // When using pub/sub, the number of receives can be greater than the + // number of sends. To enable normal use of the connection after + // unsubscribing from all channels, we do not decrement pending to a + // negative value. + // + // The pending field is decremented after the reply is read to handle the + // case where Receive is called before Send. + c.mu.Lock() + if c.pending > 0 { + c.pending -= 1 + } + c.mu.Unlock() + if err, ok := reply.(Error); ok { + return nil, err + } + return +} + +func (c *conn) Do(cmd string, args ...interface{}) (interface{}, error) { + c.mu.Lock() + pending := c.pending + c.pending = 0 + c.mu.Unlock() + + if cmd == "" && pending == 0 { + return nil, nil + } + + if c.writeTimeout != 0 { + c.conn.SetWriteDeadline(time.Now().Add(c.writeTimeout)) + } + + if cmd != "" { + c.writeCommand(cmd, args) + } + + if err := c.bw.Flush(); err != nil { + return nil, c.fatal(err) + } + + if c.readTimeout != 0 { + c.conn.SetReadDeadline(time.Now().Add(c.readTimeout)) + } + + if cmd == "" { + reply := make([]interface{}, pending) + for i := range reply { + r, e := c.readReply() + if e != nil { + return nil, c.fatal(e) + } + reply[i] = r + } + return reply, nil + } + + var err error + var reply interface{} + for i := 0; i <= pending; i++ { + var e error + if reply, e = c.readReply(); e != nil { + return nil, c.fatal(e) + } + if e, ok := reply.(Error); ok && err == nil { + err = e + } + } + return reply, err +} diff --git a/vendor/github.com/garyburd/redigo/redis/doc.go b/vendor/github.com/garyburd/redigo/redis/doc.go new file mode 100644 index 0000000..1ae6f0c --- /dev/null +++ b/vendor/github.com/garyburd/redigo/redis/doc.go @@ -0,0 +1,169 @@ +// Copyright 2012 Gary Burd +// +// Licensed under the Apache License, Version 2.0 (the "License"): you may +// not use this file except in compliance with the License. You may obtain +// a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations +// under the License. + +// Package redis is a client for the Redis database. +// +// The Redigo FAQ (https://github.com/garyburd/redigo/wiki/FAQ) contains more +// documentation about this package. +// +// Connections +// +// The Conn interface is the primary interface for working with Redis. +// Applications create connections by calling the Dial, DialWithTimeout or +// NewConn functions. In the future, functions will be added for creating +// sharded and other types of connections. +// +// The application must call the connection Close method when the application +// is done with the connection. +// +// Executing Commands +// +// The Conn interface has a generic method for executing Redis commands: +// +// Do(commandName string, args ...interface{}) (reply interface{}, err error) +// +// The Redis command reference (http://redis.io/commands) lists the available +// commands. An example of using the Redis APPEND command is: +// +// n, err := conn.Do("APPEND", "key", "value") +// +// The Do method converts command arguments to binary strings for transmission +// to the server as follows: +// +// Go Type Conversion +// []byte Sent as is +// string Sent as is +// int, int64 strconv.FormatInt(v) +// float64 strconv.FormatFloat(v, 'g', -1, 64) +// bool true -> "1", false -> "0" +// nil "" +// all other types fmt.Print(v) +// +// Redis command reply types are represented using the following Go types: +// +// Redis type Go type +// error redis.Error +// integer int64 +// simple string string +// bulk string []byte or nil if value not present. +// array []interface{} or nil if value not present. +// +// Use type assertions or the reply helper functions to convert from +// interface{} to the specific Go type for the command result. +// +// Pipelining +// +// Connections support pipelining using the Send, Flush and Receive methods. +// +// Send(commandName string, args ...interface{}) error +// Flush() error +// Receive() (reply interface{}, err error) +// +// Send writes the command to the connection's output buffer. Flush flushes the +// connection's output buffer to the server. Receive reads a single reply from +// the server. The following example shows a simple pipeline. +// +// c.Send("SET", "foo", "bar") +// c.Send("GET", "foo") +// c.Flush() +// c.Receive() // reply from SET +// v, err = c.Receive() // reply from GET +// +// The Do method combines the functionality of the Send, Flush and Receive +// methods. The Do method starts by writing the command and flushing the output +// buffer. Next, the Do method receives all pending replies including the reply +// for the command just sent by Do. If any of the received replies is an error, +// then Do returns the error. If there are no errors, then Do returns the last +// reply. If the command argument to the Do method is "", then the Do method +// will flush the output buffer and receive pending replies without sending a +// command. +// +// Use the Send and Do methods to implement pipelined transactions. +// +// c.Send("MULTI") +// c.Send("INCR", "foo") +// c.Send("INCR", "bar") +// r, err := c.Do("EXEC") +// fmt.Println(r) // prints [1, 1] +// +// Concurrency +// +// Connections do not support concurrent calls to the write methods (Send, +// Flush) or concurrent calls to the read method (Receive). Connections do +// allow a concurrent reader and writer. +// +// Because the Do method combines the functionality of Send, Flush and Receive, +// the Do method cannot be called concurrently with the other methods. +// +// For full concurrent access to Redis, use the thread-safe Pool to get and +// release connections from within a goroutine. +// +// Publish and Subscribe +// +// Use the Send, Flush and Receive methods to implement Pub/Sub subscribers. +// +// c.Send("SUBSCRIBE", "example") +// c.Flush() +// for { +// reply, err := c.Receive() +// if err != nil { +// return err +// } +// // process pushed message +// } +// +// The PubSubConn type wraps a Conn with convenience methods for implementing +// subscribers. The Subscribe, PSubscribe, Unsubscribe and PUnsubscribe methods +// send and flush a subscription management command. The receive method +// converts a pushed message to convenient types for use in a type switch. +// +// psc := redis.PubSubConn{c} +// psc.Subscribe("example") +// for { +// switch v := psc.Receive().(type) { +// case redis.Message: +// fmt.Printf("%s: message: %s\n", v.Channel, v.Data) +// case redis.Subscription: +// fmt.Printf("%s: %s %d\n", v.Channel, v.Kind, v.Count) +// case error: +// return v +// } +// } +// +// Reply Helpers +// +// The Bool, Int, Bytes, String, Strings and Values functions convert a reply +// to a value of a specific type. To allow convenient wrapping of calls to the +// connection Do and Receive methods, the functions take a second argument of +// type error. If the error is non-nil, then the helper function returns the +// error. If the error is nil, the function converts the reply to the specified +// type: +// +// exists, err := redis.Bool(c.Do("EXISTS", "foo")) +// if err != nil { +// // handle error return from c.Do or type conversion error. +// } +// +// The Scan function converts elements of a array reply to Go types: +// +// var value1 int +// var value2 string +// reply, err := redis.Values(c.Do("MGET", "key1", "key2")) +// if err != nil { +// // handle error +// } +// if _, err := redis.Scan(reply, &value1, &value2); err != nil { +// // handle error +// } +package redis diff --git a/vendor/github.com/garyburd/redigo/redis/log.go b/vendor/github.com/garyburd/redigo/redis/log.go new file mode 100644 index 0000000..129b86d --- /dev/null +++ b/vendor/github.com/garyburd/redigo/redis/log.go @@ -0,0 +1,117 @@ +// Copyright 2012 Gary Burd +// +// Licensed under the Apache License, Version 2.0 (the "License"): you may +// not use this file except in compliance with the License. You may obtain +// a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations +// under the License. + +package redis + +import ( + "bytes" + "fmt" + "log" +) + +// NewLoggingConn returns a logging wrapper around a connection. +func NewLoggingConn(conn Conn, logger *log.Logger, prefix string) Conn { + if prefix != "" { + prefix = prefix + "." + } + return &loggingConn{conn, logger, prefix} +} + +type loggingConn struct { + Conn + logger *log.Logger + prefix string +} + +func (c *loggingConn) Close() error { + err := c.Conn.Close() + var buf bytes.Buffer + fmt.Fprintf(&buf, "%sClose() -> (%v)", c.prefix, err) + c.logger.Output(2, buf.String()) + return err +} + +func (c *loggingConn) printValue(buf *bytes.Buffer, v interface{}) { + const chop = 32 + switch v := v.(type) { + case []byte: + if len(v) > chop { + fmt.Fprintf(buf, "%q...", v[:chop]) + } else { + fmt.Fprintf(buf, "%q", v) + } + case string: + if len(v) > chop { + fmt.Fprintf(buf, "%q...", v[:chop]) + } else { + fmt.Fprintf(buf, "%q", v) + } + case []interface{}: + if len(v) == 0 { + buf.WriteString("[]") + } else { + sep := "[" + fin := "]" + if len(v) > chop { + v = v[:chop] + fin = "...]" + } + for _, vv := range v { + buf.WriteString(sep) + c.printValue(buf, vv) + sep = ", " + } + buf.WriteString(fin) + } + default: + fmt.Fprint(buf, v) + } +} + +func (c *loggingConn) print(method, commandName string, args []interface{}, reply interface{}, err error) { + var buf bytes.Buffer + fmt.Fprintf(&buf, "%s%s(", c.prefix, method) + if method != "Receive" { + buf.WriteString(commandName) + for _, arg := range args { + buf.WriteString(", ") + c.printValue(&buf, arg) + } + } + buf.WriteString(") -> (") + if method != "Send" { + c.printValue(&buf, reply) + buf.WriteString(", ") + } + fmt.Fprintf(&buf, "%v)", err) + c.logger.Output(3, buf.String()) +} + +func (c *loggingConn) Do(commandName string, args ...interface{}) (interface{}, error) { + reply, err := c.Conn.Do(commandName, args...) + c.print("Do", commandName, args, reply, err) + return reply, err +} + +func (c *loggingConn) Send(commandName string, args ...interface{}) error { + err := c.Conn.Send(commandName, args...) + c.print("Send", commandName, args, nil, err) + return err +} + +func (c *loggingConn) Receive() (interface{}, error) { + reply, err := c.Conn.Receive() + c.print("Receive", "", nil, reply, err) + return reply, err +} diff --git a/vendor/github.com/garyburd/redigo/redis/pool.go b/vendor/github.com/garyburd/redigo/redis/pool.go new file mode 100644 index 0000000..9daf2e3 --- /dev/null +++ b/vendor/github.com/garyburd/redigo/redis/pool.go @@ -0,0 +1,389 @@ +// Copyright 2012 Gary Burd +// +// Licensed under the Apache License, Version 2.0 (the "License"): you may +// not use this file except in compliance with the License. You may obtain +// a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations +// under the License. + +package redis + +import ( + "bytes" + "container/list" + "crypto/rand" + "crypto/sha1" + "errors" + "io" + "strconv" + "sync" + "time" + + "github.com/garyburd/redigo/internal" +) + +var nowFunc = time.Now // for testing + +// ErrPoolExhausted is returned from a pool connection method (Do, Send, +// Receive, Flush, Err) when the maximum number of database connections in the +// pool has been reached. +var ErrPoolExhausted = errors.New("redigo: connection pool exhausted") + +var ( + errPoolClosed = errors.New("redigo: connection pool closed") + errConnClosed = errors.New("redigo: connection closed") +) + +// Pool maintains a pool of connections. The application calls the Get method +// to get a connection from the pool and the connection's Close method to +// return the connection's resources to the pool. +// +// The following example shows how to use a pool in a web application. The +// application creates a pool at application startup and makes it available to +// request handlers using a global variable. +// +// func newPool(server, password string) *redis.Pool { +// return &redis.Pool{ +// MaxIdle: 3, +// IdleTimeout: 240 * time.Second, +// Dial: func () (redis.Conn, error) { +// c, err := redis.Dial("tcp", server) +// if err != nil { +// return nil, err +// } +// if _, err := c.Do("AUTH", password); err != nil { +// c.Close() +// return nil, err +// } +// return c, err +// }, +// TestOnBorrow: func(c redis.Conn, t time.Time) error { +// _, err := c.Do("PING") +// return err +// }, +// } +// } +// +// var ( +// pool *redis.Pool +// redisServer = flag.String("redisServer", ":6379", "") +// redisPassword = flag.String("redisPassword", "", "") +// ) +// +// func main() { +// flag.Parse() +// pool = newPool(*redisServer, *redisPassword) +// ... +// } +// +// A request handler gets a connection from the pool and closes the connection +// when the handler is done: +// +// func serveHome(w http.ResponseWriter, r *http.Request) { +// conn := pool.Get() +// defer conn.Close() +// .... +// } +// +type Pool struct { + + // Dial is an application supplied function for creating and configuring a + // connection + Dial func() (Conn, error) + + // TestOnBorrow is an optional application supplied function for checking + // the health of an idle connection before the connection is used again by + // the application. Argument t is the time that the connection was returned + // to the pool. If the function returns an error, then the connection is + // closed. + TestOnBorrow func(c Conn, t time.Time) error + + // Maximum number of idle connections in the pool. + MaxIdle int + + // Maximum number of connections allocated by the pool at a given time. + // When zero, there is no limit on the number of connections in the pool. + MaxActive int + + // Close connections after remaining idle for this duration. If the value + // is zero, then idle connections are not closed. Applications should set + // the timeout to a value less than the server's timeout. + IdleTimeout time.Duration + + // If Wait is true and the pool is at the MaxIdle limit, then Get() waits + // for a connection to be returned to the pool before returning. + Wait bool + + // mu protects fields defined below. + mu sync.Mutex + cond *sync.Cond + closed bool + active int + + // Stack of idleConn with most recently used at the front. + idle list.List +} + +type idleConn struct { + c Conn + t time.Time +} + +// NewPool creates a new pool. This function is deprecated. Applications should +// initialize the Pool fields directly as shown in example. +func NewPool(newFn func() (Conn, error), maxIdle int) *Pool { + return &Pool{Dial: newFn, MaxIdle: maxIdle} +} + +// Get gets a connection. The application must close the returned connection. +// This method always returns a valid connection so that applications can defer +// error handling to the first use of the connection. If there is an error +// getting an underlying connection, then the connection Err, Do, Send, Flush +// and Receive methods return that error. +func (p *Pool) Get() Conn { + c, err := p.get() + if err != nil { + return errorConnection{err} + } + return &pooledConnection{p: p, c: c} +} + +// ActiveCount returns the number of active connections in the pool. +func (p *Pool) ActiveCount() int { + p.mu.Lock() + active := p.active + p.mu.Unlock() + return active +} + +// Close releases the resources used by the pool. +func (p *Pool) Close() error { + p.mu.Lock() + idle := p.idle + p.idle.Init() + p.closed = true + p.active -= idle.Len() + if p.cond != nil { + p.cond.Broadcast() + } + p.mu.Unlock() + for e := idle.Front(); e != nil; e = e.Next() { + e.Value.(idleConn).c.Close() + } + return nil +} + +// release decrements the active count and signals waiters. The caller must +// hold p.mu during the call. +func (p *Pool) release() { + p.active -= 1 + if p.cond != nil { + p.cond.Signal() + } +} + +// get prunes stale connections and returns a connection from the idle list or +// creates a new connection. +func (p *Pool) get() (Conn, error) { + p.mu.Lock() + + // Prune stale connections. + + if timeout := p.IdleTimeout; timeout > 0 { + for i, n := 0, p.idle.Len(); i < n; i++ { + e := p.idle.Back() + if e == nil { + break + } + ic := e.Value.(idleConn) + if ic.t.Add(timeout).After(nowFunc()) { + break + } + p.idle.Remove(e) + p.release() + p.mu.Unlock() + ic.c.Close() + p.mu.Lock() + } + } + + for { + + // Get idle connection. + + for i, n := 0, p.idle.Len(); i < n; i++ { + e := p.idle.Front() + if e == nil { + break + } + ic := e.Value.(idleConn) + p.idle.Remove(e) + test := p.TestOnBorrow + p.mu.Unlock() + if test == nil || test(ic.c, ic.t) == nil { + return ic.c, nil + } + ic.c.Close() + p.mu.Lock() + p.release() + } + + // Check for pool closed before dialing a new connection. + + if p.closed { + p.mu.Unlock() + return nil, errors.New("redigo: get on closed pool") + } + + // Dial new connection if under limit. + + if p.MaxActive == 0 || p.active < p.MaxActive { + dial := p.Dial + p.active += 1 + p.mu.Unlock() + c, err := dial() + if err != nil { + p.mu.Lock() + p.release() + p.mu.Unlock() + c = nil + } + return c, err + } + + if !p.Wait { + p.mu.Unlock() + return nil, ErrPoolExhausted + } + + if p.cond == nil { + p.cond = sync.NewCond(&p.mu) + } + p.cond.Wait() + } +} + +func (p *Pool) put(c Conn, forceClose bool) error { + err := c.Err() + p.mu.Lock() + if !p.closed && err == nil && !forceClose { + p.idle.PushFront(idleConn{t: nowFunc(), c: c}) + if p.idle.Len() > p.MaxIdle { + c = p.idle.Remove(p.idle.Back()).(idleConn).c + } else { + c = nil + } + } + + if c == nil { + if p.cond != nil { + p.cond.Signal() + } + p.mu.Unlock() + return nil + } + + p.release() + p.mu.Unlock() + return c.Close() +} + +type pooledConnection struct { + p *Pool + c Conn + state int +} + +var ( + sentinel []byte + sentinelOnce sync.Once +) + +func initSentinel() { + p := make([]byte, 64) + if _, err := rand.Read(p); err == nil { + sentinel = p + } else { + h := sha1.New() + io.WriteString(h, "Oops, rand failed. Use time instead.") + io.WriteString(h, strconv.FormatInt(time.Now().UnixNano(), 10)) + sentinel = h.Sum(nil) + } +} + +func (pc *pooledConnection) Close() error { + c := pc.c + if _, ok := c.(errorConnection); ok { + return nil + } + pc.c = errorConnection{errConnClosed} + + if pc.state&internal.MultiState != 0 { + c.Send("DISCARD") + pc.state &^= (internal.MultiState | internal.WatchState) + } else if pc.state&internal.WatchState != 0 { + c.Send("UNWATCH") + pc.state &^= internal.WatchState + } + if pc.state&internal.SubscribeState != 0 { + c.Send("UNSUBSCRIBE") + c.Send("PUNSUBSCRIBE") + // To detect the end of the message stream, ask the server to echo + // a sentinel value and read until we see that value. + sentinelOnce.Do(initSentinel) + c.Send("ECHO", sentinel) + c.Flush() + for { + p, err := c.Receive() + if err != nil { + break + } + if p, ok := p.([]byte); ok && bytes.Equal(p, sentinel) { + pc.state &^= internal.SubscribeState + break + } + } + } + c.Do("") + pc.p.put(c, pc.state != 0) + return nil +} + +func (pc *pooledConnection) Err() error { + return pc.c.Err() +} + +func (pc *pooledConnection) Do(commandName string, args ...interface{}) (reply interface{}, err error) { + ci := internal.LookupCommandInfo(commandName) + pc.state = (pc.state | ci.Set) &^ ci.Clear + return pc.c.Do(commandName, args...) +} + +func (pc *pooledConnection) Send(commandName string, args ...interface{}) error { + ci := internal.LookupCommandInfo(commandName) + pc.state = (pc.state | ci.Set) &^ ci.Clear + return pc.c.Send(commandName, args...) +} + +func (pc *pooledConnection) Flush() error { + return pc.c.Flush() +} + +func (pc *pooledConnection) Receive() (reply interface{}, err error) { + return pc.c.Receive() +} + +type errorConnection struct{ err error } + +func (ec errorConnection) Do(string, ...interface{}) (interface{}, error) { return nil, ec.err } +func (ec errorConnection) Send(string, ...interface{}) error { return ec.err } +func (ec errorConnection) Err() error { return ec.err } +func (ec errorConnection) Close() error { return ec.err } +func (ec errorConnection) Flush() error { return ec.err } +func (ec errorConnection) Receive() (interface{}, error) { return nil, ec.err } diff --git a/vendor/github.com/garyburd/redigo/redis/pubsub.go b/vendor/github.com/garyburd/redigo/redis/pubsub.go new file mode 100644 index 0000000..c0ecce8 --- /dev/null +++ b/vendor/github.com/garyburd/redigo/redis/pubsub.go @@ -0,0 +1,144 @@ +// Copyright 2012 Gary Burd +// +// Licensed under the Apache License, Version 2.0 (the "License"): you may +// not use this file except in compliance with the License. You may obtain +// a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations +// under the License. + +package redis + +import "errors" + +// Subscription represents a subscribe or unsubscribe notification. +type Subscription struct { + + // Kind is "subscribe", "unsubscribe", "psubscribe" or "punsubscribe" + Kind string + + // The channel that was changed. + Channel string + + // The current number of subscriptions for connection. + Count int +} + +// Message represents a message notification. +type Message struct { + + // The originating channel. + Channel string + + // The message data. + Data []byte +} + +// PMessage represents a pmessage notification. +type PMessage struct { + + // The matched pattern. + Pattern string + + // The originating channel. + Channel string + + // The message data. + Data []byte +} + +// Pong represents a pubsub pong notification. +type Pong struct { + Data string +} + +// PubSubConn wraps a Conn with convenience methods for subscribers. +type PubSubConn struct { + Conn Conn +} + +// Close closes the connection. +func (c PubSubConn) Close() error { + return c.Conn.Close() +} + +// Subscribe subscribes the connection to the specified channels. +func (c PubSubConn) Subscribe(channel ...interface{}) error { + c.Conn.Send("SUBSCRIBE", channel...) + return c.Conn.Flush() +} + +// PSubscribe subscribes the connection to the given patterns. +func (c PubSubConn) PSubscribe(channel ...interface{}) error { + c.Conn.Send("PSUBSCRIBE", channel...) + return c.Conn.Flush() +} + +// Unsubscribe unsubscribes the connection from the given channels, or from all +// of them if none is given. +func (c PubSubConn) Unsubscribe(channel ...interface{}) error { + c.Conn.Send("UNSUBSCRIBE", channel...) + return c.Conn.Flush() +} + +// PUnsubscribe unsubscribes the connection from the given patterns, or from all +// of them if none is given. +func (c PubSubConn) PUnsubscribe(channel ...interface{}) error { + c.Conn.Send("PUNSUBSCRIBE", channel...) + return c.Conn.Flush() +} + +// Ping sends a PING to the server with the specified data. +func (c PubSubConn) Ping(data string) error { + c.Conn.Send("PING", data) + return c.Conn.Flush() +} + +// Receive returns a pushed message as a Subscription, Message, PMessage, Pong +// or error. The return value is intended to be used directly in a type switch +// as illustrated in the PubSubConn example. +func (c PubSubConn) Receive() interface{} { + reply, err := Values(c.Conn.Receive()) + if err != nil { + return err + } + + var kind string + reply, err = Scan(reply, &kind) + if err != nil { + return err + } + + switch kind { + case "message": + var m Message + if _, err := Scan(reply, &m.Channel, &m.Data); err != nil { + return err + } + return m + case "pmessage": + var pm PMessage + if _, err := Scan(reply, &pm.Pattern, &pm.Channel, &pm.Data); err != nil { + return err + } + return pm + case "subscribe", "psubscribe", "unsubscribe", "punsubscribe": + s := Subscription{Kind: kind} + if _, err := Scan(reply, &s.Channel, &s.Count); err != nil { + return err + } + return s + case "pong": + var p Pong + if _, err := Scan(reply, &p.Data); err != nil { + return err + } + return p + } + return errors.New("redigo: unknown pubsub notification") +} diff --git a/vendor/github.com/garyburd/redigo/redis/redis.go b/vendor/github.com/garyburd/redigo/redis/redis.go new file mode 100644 index 0000000..c90a48e --- /dev/null +++ b/vendor/github.com/garyburd/redigo/redis/redis.go @@ -0,0 +1,44 @@ +// Copyright 2012 Gary Burd +// +// Licensed under the Apache License, Version 2.0 (the "License"): you may +// not use this file except in compliance with the License. You may obtain +// a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations +// under the License. + +package redis + +// Error represents an error returned in a command reply. +type Error string + +func (err Error) Error() string { return string(err) } + +// Conn represents a connection to a Redis server. +type Conn interface { + // Close closes the connection. + Close() error + + // Err returns a non-nil value if the connection is broken. The returned + // value is either the first non-nil value returned from the underlying + // network connection or a protocol parsing error. Applications should + // close broken connections. + Err() error + + // Do sends a command to the server and returns the received reply. + Do(commandName string, args ...interface{}) (reply interface{}, err error) + + // Send writes the command to the client's output buffer. + Send(commandName string, args ...interface{}) error + + // Flush flushes the output buffer to the Redis server. + Flush() error + + // Receive receives a single reply from the Redis server + Receive() (reply interface{}, err error) +} diff --git a/vendor/github.com/garyburd/redigo/redis/reply.go b/vendor/github.com/garyburd/redigo/redis/reply.go new file mode 100644 index 0000000..5af29bf --- /dev/null +++ b/vendor/github.com/garyburd/redigo/redis/reply.go @@ -0,0 +1,364 @@ +// Copyright 2012 Gary Burd +// +// Licensed under the Apache License, Version 2.0 (the "License"): you may +// not use this file except in compliance with the License. You may obtain +// a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations +// under the License. + +package redis + +import ( + "errors" + "fmt" + "strconv" +) + +// ErrNil indicates that a reply value is nil. +var ErrNil = errors.New("redigo: nil returned") + +// Int is a helper that converts a command reply to an integer. If err is not +// equal to nil, then Int returns 0, err. Otherwise, Int converts the +// reply to an int as follows: +// +// Reply type Result +// integer int(reply), nil +// bulk string parsed reply, nil +// nil 0, ErrNil +// other 0, error +func Int(reply interface{}, err error) (int, error) { + if err != nil { + return 0, err + } + switch reply := reply.(type) { + case int64: + x := int(reply) + if int64(x) != reply { + return 0, strconv.ErrRange + } + return x, nil + case []byte: + n, err := strconv.ParseInt(string(reply), 10, 0) + return int(n), err + case nil: + return 0, ErrNil + case Error: + return 0, reply + } + return 0, fmt.Errorf("redigo: unexpected type for Int, got type %T", reply) +} + +// Int64 is a helper that converts a command reply to 64 bit integer. If err is +// not equal to nil, then Int returns 0, err. Otherwise, Int64 converts the +// reply to an int64 as follows: +// +// Reply type Result +// integer reply, nil +// bulk string parsed reply, nil +// nil 0, ErrNil +// other 0, error +func Int64(reply interface{}, err error) (int64, error) { + if err != nil { + return 0, err + } + switch reply := reply.(type) { + case int64: + return reply, nil + case []byte: + n, err := strconv.ParseInt(string(reply), 10, 64) + return n, err + case nil: + return 0, ErrNil + case Error: + return 0, reply + } + return 0, fmt.Errorf("redigo: unexpected type for Int64, got type %T", reply) +} + +var errNegativeInt = errors.New("redigo: unexpected value for Uint64") + +// Uint64 is a helper that converts a command reply to 64 bit integer. If err is +// not equal to nil, then Int returns 0, err. Otherwise, Int64 converts the +// reply to an int64 as follows: +// +// Reply type Result +// integer reply, nil +// bulk string parsed reply, nil +// nil 0, ErrNil +// other 0, error +func Uint64(reply interface{}, err error) (uint64, error) { + if err != nil { + return 0, err + } + switch reply := reply.(type) { + case int64: + if reply < 0 { + return 0, errNegativeInt + } + return uint64(reply), nil + case []byte: + n, err := strconv.ParseUint(string(reply), 10, 64) + return n, err + case nil: + return 0, ErrNil + case Error: + return 0, reply + } + return 0, fmt.Errorf("redigo: unexpected type for Uint64, got type %T", reply) +} + +// Float64 is a helper that converts a command reply to 64 bit float. If err is +// not equal to nil, then Float64 returns 0, err. Otherwise, Float64 converts +// the reply to an int as follows: +// +// Reply type Result +// bulk string parsed reply, nil +// nil 0, ErrNil +// other 0, error +func Float64(reply interface{}, err error) (float64, error) { + if err != nil { + return 0, err + } + switch reply := reply.(type) { + case []byte: + n, err := strconv.ParseFloat(string(reply), 64) + return n, err + case nil: + return 0, ErrNil + case Error: + return 0, reply + } + return 0, fmt.Errorf("redigo: unexpected type for Float64, got type %T", reply) +} + +// String is a helper that converts a command reply to a string. If err is not +// equal to nil, then String returns "", err. Otherwise String converts the +// reply to a string as follows: +// +// Reply type Result +// bulk string string(reply), nil +// simple string reply, nil +// nil "", ErrNil +// other "", error +func String(reply interface{}, err error) (string, error) { + if err != nil { + return "", err + } + switch reply := reply.(type) { + case []byte: + return string(reply), nil + case string: + return reply, nil + case nil: + return "", ErrNil + case Error: + return "", reply + } + return "", fmt.Errorf("redigo: unexpected type for String, got type %T", reply) +} + +// Bytes is a helper that converts a command reply to a slice of bytes. If err +// is not equal to nil, then Bytes returns nil, err. Otherwise Bytes converts +// the reply to a slice of bytes as follows: +// +// Reply type Result +// bulk string reply, nil +// simple string []byte(reply), nil +// nil nil, ErrNil +// other nil, error +func Bytes(reply interface{}, err error) ([]byte, error) { + if err != nil { + return nil, err + } + switch reply := reply.(type) { + case []byte: + return reply, nil + case string: + return []byte(reply), nil + case nil: + return nil, ErrNil + case Error: + return nil, reply + } + return nil, fmt.Errorf("redigo: unexpected type for Bytes, got type %T", reply) +} + +// Bool is a helper that converts a command reply to a boolean. If err is not +// equal to nil, then Bool returns false, err. Otherwise Bool converts the +// reply to boolean as follows: +// +// Reply type Result +// integer value != 0, nil +// bulk string strconv.ParseBool(reply) +// nil false, ErrNil +// other false, error +func Bool(reply interface{}, err error) (bool, error) { + if err != nil { + return false, err + } + switch reply := reply.(type) { + case int64: + return reply != 0, nil + case []byte: + return strconv.ParseBool(string(reply)) + case nil: + return false, ErrNil + case Error: + return false, reply + } + return false, fmt.Errorf("redigo: unexpected type for Bool, got type %T", reply) +} + +// MultiBulk is deprecated. Use Values. +func MultiBulk(reply interface{}, err error) ([]interface{}, error) { return Values(reply, err) } + +// Values is a helper that converts an array command reply to a []interface{}. +// If err is not equal to nil, then Values returns nil, err. Otherwise, Values +// converts the reply as follows: +// +// Reply type Result +// array reply, nil +// nil nil, ErrNil +// other nil, error +func Values(reply interface{}, err error) ([]interface{}, error) { + if err != nil { + return nil, err + } + switch reply := reply.(type) { + case []interface{}: + return reply, nil + case nil: + return nil, ErrNil + case Error: + return nil, reply + } + return nil, fmt.Errorf("redigo: unexpected type for Values, got type %T", reply) +} + +// Strings is a helper that converts an array command reply to a []string. If +// err is not equal to nil, then Strings returns nil, err. Nil array items are +// converted to "" in the output slice. Strings returns an error if an array +// item is not a bulk string or nil. +func Strings(reply interface{}, err error) ([]string, error) { + if err != nil { + return nil, err + } + switch reply := reply.(type) { + case []interface{}: + result := make([]string, len(reply)) + for i := range reply { + if reply[i] == nil { + continue + } + p, ok := reply[i].([]byte) + if !ok { + return nil, fmt.Errorf("redigo: unexpected element type for Strings, got type %T", reply[i]) + } + result[i] = string(p) + } + return result, nil + case nil: + return nil, ErrNil + case Error: + return nil, reply + } + return nil, fmt.Errorf("redigo: unexpected type for Strings, got type %T", reply) +} + +// Ints is a helper that converts an array command reply to a []int. If +// err is not equal to nil, then Ints returns nil, err. +func Ints(reply interface{}, err error) ([]int, error) { + var ints []int + if reply == nil { + return ints, ErrNil + } + values, err := Values(reply, err) + if err != nil { + return ints, err + } + if err := ScanSlice(values, &ints); err != nil { + return ints, err + } + return ints, nil +} + +// StringMap is a helper that converts an array of strings (alternating key, value) +// into a map[string]string. The HGETALL and CONFIG GET commands return replies in this format. +// Requires an even number of values in result. +func StringMap(result interface{}, err error) (map[string]string, error) { + values, err := Values(result, err) + if err != nil { + return nil, err + } + if len(values)%2 != 0 { + return nil, errors.New("redigo: StringMap expects even number of values result") + } + m := make(map[string]string, len(values)/2) + for i := 0; i < len(values); i += 2 { + key, okKey := values[i].([]byte) + value, okValue := values[i+1].([]byte) + if !okKey || !okValue { + return nil, errors.New("redigo: ScanMap key not a bulk string value") + } + m[string(key)] = string(value) + } + return m, nil +} + +// IntMap is a helper that converts an array of strings (alternating key, value) +// into a map[string]int. The HGETALL commands return replies in this format. +// Requires an even number of values in result. +func IntMap(result interface{}, err error) (map[string]int, error) { + values, err := Values(result, err) + if err != nil { + return nil, err + } + if len(values)%2 != 0 { + return nil, errors.New("redigo: IntMap expects even number of values result") + } + m := make(map[string]int, len(values)/2) + for i := 0; i < len(values); i += 2 { + key, ok := values[i].([]byte) + if !ok { + return nil, errors.New("redigo: ScanMap key not a bulk string value") + } + value, err := Int(values[i+1], nil) + if err != nil { + return nil, err + } + m[string(key)] = value + } + return m, nil +} + +// Int64Map is a helper that converts an array of strings (alternating key, value) +// into a map[string]int64. The HGETALL commands return replies in this format. +// Requires an even number of values in result. +func Int64Map(result interface{}, err error) (map[string]int64, error) { + values, err := Values(result, err) + if err != nil { + return nil, err + } + if len(values)%2 != 0 { + return nil, errors.New("redigo: Int64Map expects even number of values result") + } + m := make(map[string]int64, len(values)/2) + for i := 0; i < len(values); i += 2 { + key, ok := values[i].([]byte) + if !ok { + return nil, errors.New("redigo: ScanMap key not a bulk string value") + } + value, err := Int64(values[i+1], nil) + if err != nil { + return nil, err + } + m[string(key)] = value + } + return m, nil +} diff --git a/vendor/github.com/garyburd/redigo/redis/scan.go b/vendor/github.com/garyburd/redigo/redis/scan.go new file mode 100644 index 0000000..8c9cfa1 --- /dev/null +++ b/vendor/github.com/garyburd/redigo/redis/scan.go @@ -0,0 +1,513 @@ +// Copyright 2012 Gary Burd +// +// Licensed under the Apache License, Version 2.0 (the "License"): you may +// not use this file except in compliance with the License. You may obtain +// a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations +// under the License. + +package redis + +import ( + "errors" + "fmt" + "reflect" + "strconv" + "strings" + "sync" +) + +func ensureLen(d reflect.Value, n int) { + if n > d.Cap() { + d.Set(reflect.MakeSlice(d.Type(), n, n)) + } else { + d.SetLen(n) + } +} + +func cannotConvert(d reflect.Value, s interface{}) error { + return fmt.Errorf("redigo: Scan cannot convert from %s to %s", + reflect.TypeOf(s), d.Type()) +} + +func convertAssignBytes(d reflect.Value, s []byte) (err error) { + switch d.Type().Kind() { + case reflect.Float32, reflect.Float64: + var x float64 + x, err = strconv.ParseFloat(string(s), d.Type().Bits()) + d.SetFloat(x) + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + var x int64 + x, err = strconv.ParseInt(string(s), 10, d.Type().Bits()) + d.SetInt(x) + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: + var x uint64 + x, err = strconv.ParseUint(string(s), 10, d.Type().Bits()) + d.SetUint(x) + case reflect.Bool: + var x bool + x, err = strconv.ParseBool(string(s)) + d.SetBool(x) + case reflect.String: + d.SetString(string(s)) + case reflect.Slice: + if d.Type().Elem().Kind() != reflect.Uint8 { + err = cannotConvert(d, s) + } else { + d.SetBytes(s) + } + default: + err = cannotConvert(d, s) + } + return +} + +func convertAssignInt(d reflect.Value, s int64) (err error) { + switch d.Type().Kind() { + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + d.SetInt(s) + if d.Int() != s { + err = strconv.ErrRange + d.SetInt(0) + } + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: + if s < 0 { + err = strconv.ErrRange + } else { + x := uint64(s) + d.SetUint(x) + if d.Uint() != x { + err = strconv.ErrRange + d.SetUint(0) + } + } + case reflect.Bool: + d.SetBool(s != 0) + default: + err = cannotConvert(d, s) + } + return +} + +func convertAssignValue(d reflect.Value, s interface{}) (err error) { + switch s := s.(type) { + case []byte: + err = convertAssignBytes(d, s) + case int64: + err = convertAssignInt(d, s) + default: + err = cannotConvert(d, s) + } + return err +} + +func convertAssignValues(d reflect.Value, s []interface{}) error { + if d.Type().Kind() != reflect.Slice { + return cannotConvert(d, s) + } + ensureLen(d, len(s)) + for i := 0; i < len(s); i++ { + if err := convertAssignValue(d.Index(i), s[i]); err != nil { + return err + } + } + return nil +} + +func convertAssign(d interface{}, s interface{}) (err error) { + // Handle the most common destination types using type switches and + // fall back to reflection for all other types. + switch s := s.(type) { + case nil: + // ingore + case []byte: + switch d := d.(type) { + case *string: + *d = string(s) + case *int: + *d, err = strconv.Atoi(string(s)) + case *bool: + *d, err = strconv.ParseBool(string(s)) + case *[]byte: + *d = s + case *interface{}: + *d = s + case nil: + // skip value + default: + if d := reflect.ValueOf(d); d.Type().Kind() != reflect.Ptr { + err = cannotConvert(d, s) + } else { + err = convertAssignBytes(d.Elem(), s) + } + } + case int64: + switch d := d.(type) { + case *int: + x := int(s) + if int64(x) != s { + err = strconv.ErrRange + x = 0 + } + *d = x + case *bool: + *d = s != 0 + case *interface{}: + *d = s + case nil: + // skip value + default: + if d := reflect.ValueOf(d); d.Type().Kind() != reflect.Ptr { + err = cannotConvert(d, s) + } else { + err = convertAssignInt(d.Elem(), s) + } + } + case []interface{}: + switch d := d.(type) { + case *[]interface{}: + *d = s + case *interface{}: + *d = s + case nil: + // skip value + default: + if d := reflect.ValueOf(d); d.Type().Kind() != reflect.Ptr { + err = cannotConvert(d, s) + } else { + err = convertAssignValues(d.Elem(), s) + } + } + case Error: + err = s + default: + err = cannotConvert(reflect.ValueOf(d), s) + } + return +} + +// Scan copies from src to the values pointed at by dest. +// +// The values pointed at by dest must be an integer, float, boolean, string, +// []byte, interface{} or slices of these types. Scan uses the standard strconv +// package to convert bulk strings to numeric and boolean types. +// +// If a dest value is nil, then the corresponding src value is skipped. +// +// If a src element is nil, then the corresponding dest value is not modified. +// +// To enable easy use of Scan in a loop, Scan returns the slice of src +// following the copied values. +func Scan(src []interface{}, dest ...interface{}) ([]interface{}, error) { + if len(src) < len(dest) { + return nil, errors.New("redigo: Scan array short") + } + var err error + for i, d := range dest { + err = convertAssign(d, src[i]) + if err != nil { + break + } + } + return src[len(dest):], err +} + +type fieldSpec struct { + name string + index []int + //omitEmpty bool +} + +type structSpec struct { + m map[string]*fieldSpec + l []*fieldSpec +} + +func (ss *structSpec) fieldSpec(name []byte) *fieldSpec { + return ss.m[string(name)] +} + +func compileStructSpec(t reflect.Type, depth map[string]int, index []int, ss *structSpec) { + for i := 0; i < t.NumField(); i++ { + f := t.Field(i) + switch { + case f.PkgPath != "": + // Ignore unexported fields. + case f.Anonymous: + // TODO: Handle pointers. Requires change to decoder and + // protection against infinite recursion. + if f.Type.Kind() == reflect.Struct { + compileStructSpec(f.Type, depth, append(index, i), ss) + } + default: + fs := &fieldSpec{name: f.Name} + tag := f.Tag.Get("redis") + p := strings.Split(tag, ",") + if len(p) > 0 { + if p[0] == "-" { + continue + } + if len(p[0]) > 0 { + fs.name = p[0] + } + for _, s := range p[1:] { + switch s { + //case "omitempty": + // fs.omitempty = true + default: + panic(errors.New("redigo: unknown field flag " + s + " for type " + t.Name())) + } + } + } + d, found := depth[fs.name] + if !found { + d = 1 << 30 + } + switch { + case len(index) == d: + // At same depth, remove from result. + delete(ss.m, fs.name) + j := 0 + for i := 0; i < len(ss.l); i++ { + if fs.name != ss.l[i].name { + ss.l[j] = ss.l[i] + j += 1 + } + } + ss.l = ss.l[:j] + case len(index) < d: + fs.index = make([]int, len(index)+1) + copy(fs.index, index) + fs.index[len(index)] = i + depth[fs.name] = len(index) + ss.m[fs.name] = fs + ss.l = append(ss.l, fs) + } + } + } +} + +var ( + structSpecMutex sync.RWMutex + structSpecCache = make(map[reflect.Type]*structSpec) + defaultFieldSpec = &fieldSpec{} +) + +func structSpecForType(t reflect.Type) *structSpec { + + structSpecMutex.RLock() + ss, found := structSpecCache[t] + structSpecMutex.RUnlock() + if found { + return ss + } + + structSpecMutex.Lock() + defer structSpecMutex.Unlock() + ss, found = structSpecCache[t] + if found { + return ss + } + + ss = &structSpec{m: make(map[string]*fieldSpec)} + compileStructSpec(t, make(map[string]int), nil, ss) + structSpecCache[t] = ss + return ss +} + +var errScanStructValue = errors.New("redigo: ScanStruct value must be non-nil pointer to a struct") + +// ScanStruct scans alternating names and values from src to a struct. The +// HGETALL and CONFIG GET commands return replies in this format. +// +// ScanStruct uses exported field names to match values in the response. Use +// 'redis' field tag to override the name: +// +// Field int `redis:"myName"` +// +// Fields with the tag redis:"-" are ignored. +// +// Integer, float, boolean, string and []byte fields are supported. Scan uses the +// standard strconv package to convert bulk string values to numeric and +// boolean types. +// +// If a src element is nil, then the corresponding field is not modified. +func ScanStruct(src []interface{}, dest interface{}) error { + d := reflect.ValueOf(dest) + if d.Kind() != reflect.Ptr || d.IsNil() { + return errScanStructValue + } + d = d.Elem() + if d.Kind() != reflect.Struct { + return errScanStructValue + } + ss := structSpecForType(d.Type()) + + if len(src)%2 != 0 { + return errors.New("redigo: ScanStruct expects even number of values in values") + } + + for i := 0; i < len(src); i += 2 { + s := src[i+1] + if s == nil { + continue + } + name, ok := src[i].([]byte) + if !ok { + return errors.New("redigo: ScanStruct key not a bulk string value") + } + fs := ss.fieldSpec(name) + if fs == nil { + continue + } + if err := convertAssignValue(d.FieldByIndex(fs.index), s); err != nil { + return err + } + } + return nil +} + +var ( + errScanSliceValue = errors.New("redigo: ScanSlice dest must be non-nil pointer to a struct") +) + +// ScanSlice scans src to the slice pointed to by dest. The elements the dest +// slice must be integer, float, boolean, string, struct or pointer to struct +// values. +// +// Struct fields must be integer, float, boolean or string values. All struct +// fields are used unless a subset is specified using fieldNames. +func ScanSlice(src []interface{}, dest interface{}, fieldNames ...string) error { + d := reflect.ValueOf(dest) + if d.Kind() != reflect.Ptr || d.IsNil() { + return errScanSliceValue + } + d = d.Elem() + if d.Kind() != reflect.Slice { + return errScanSliceValue + } + + isPtr := false + t := d.Type().Elem() + if t.Kind() == reflect.Ptr && t.Elem().Kind() == reflect.Struct { + isPtr = true + t = t.Elem() + } + + if t.Kind() != reflect.Struct { + ensureLen(d, len(src)) + for i, s := range src { + if s == nil { + continue + } + if err := convertAssignValue(d.Index(i), s); err != nil { + return err + } + } + return nil + } + + ss := structSpecForType(t) + fss := ss.l + if len(fieldNames) > 0 { + fss = make([]*fieldSpec, len(fieldNames)) + for i, name := range fieldNames { + fss[i] = ss.m[name] + if fss[i] == nil { + return errors.New("redigo: ScanSlice bad field name " + name) + } + } + } + + if len(fss) == 0 { + return errors.New("redigo: ScanSlice no struct fields") + } + + n := len(src) / len(fss) + if n*len(fss) != len(src) { + return errors.New("redigo: ScanSlice length not a multiple of struct field count") + } + + ensureLen(d, n) + for i := 0; i < n; i++ { + d := d.Index(i) + if isPtr { + if d.IsNil() { + d.Set(reflect.New(t)) + } + d = d.Elem() + } + for j, fs := range fss { + s := src[i*len(fss)+j] + if s == nil { + continue + } + if err := convertAssignValue(d.FieldByIndex(fs.index), s); err != nil { + return err + } + } + } + return nil +} + +// Args is a helper for constructing command arguments from structured values. +type Args []interface{} + +// Add returns the result of appending value to args. +func (args Args) Add(value ...interface{}) Args { + return append(args, value...) +} + +// AddFlat returns the result of appending the flattened value of v to args. +// +// Maps are flattened by appending the alternating keys and map values to args. +// +// Slices are flattened by appending the slice elements to args. +// +// Structs are flattened by appending the alternating names and values of +// exported fields to args. If v is a nil struct pointer, then nothing is +// appended. The 'redis' field tag overrides struct field names. See ScanStruct +// for more information on the use of the 'redis' field tag. +// +// Other types are appended to args as is. +func (args Args) AddFlat(v interface{}) Args { + rv := reflect.ValueOf(v) + switch rv.Kind() { + case reflect.Struct: + args = flattenStruct(args, rv) + case reflect.Slice: + for i := 0; i < rv.Len(); i++ { + args = append(args, rv.Index(i).Interface()) + } + case reflect.Map: + for _, k := range rv.MapKeys() { + args = append(args, k.Interface(), rv.MapIndex(k).Interface()) + } + case reflect.Ptr: + if rv.Type().Elem().Kind() == reflect.Struct { + if !rv.IsNil() { + args = flattenStruct(args, rv.Elem()) + } + } else { + args = append(args, v) + } + default: + args = append(args, v) + } + return args +} + +func flattenStruct(args Args, v reflect.Value) Args { + ss := structSpecForType(v.Type()) + for _, fs := range ss.l { + fv := v.FieldByIndex(fs.index) + args = append(args, fs.name, fv.Interface()) + } + return args +} diff --git a/vendor/github.com/garyburd/redigo/redis/script.go b/vendor/github.com/garyburd/redigo/redis/script.go new file mode 100644 index 0000000..78605a9 --- /dev/null +++ b/vendor/github.com/garyburd/redigo/redis/script.go @@ -0,0 +1,86 @@ +// Copyright 2012 Gary Burd +// +// Licensed under the Apache License, Version 2.0 (the "License"): you may +// not use this file except in compliance with the License. You may obtain +// a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations +// under the License. + +package redis + +import ( + "crypto/sha1" + "encoding/hex" + "io" + "strings" +) + +// Script encapsulates the source, hash and key count for a Lua script. See +// http://redis.io/commands/eval for information on scripts in Redis. +type Script struct { + keyCount int + src string + hash string +} + +// NewScript returns a new script object. If keyCount is greater than or equal +// to zero, then the count is automatically inserted in the EVAL command +// argument list. If keyCount is less than zero, then the application supplies +// the count as the first value in the keysAndArgs argument to the Do, Send and +// SendHash methods. +func NewScript(keyCount int, src string) *Script { + h := sha1.New() + io.WriteString(h, src) + return &Script{keyCount, src, hex.EncodeToString(h.Sum(nil))} +} + +func (s *Script) args(spec string, keysAndArgs []interface{}) []interface{} { + var args []interface{} + if s.keyCount < 0 { + args = make([]interface{}, 1+len(keysAndArgs)) + args[0] = spec + copy(args[1:], keysAndArgs) + } else { + args = make([]interface{}, 2+len(keysAndArgs)) + args[0] = spec + args[1] = s.keyCount + copy(args[2:], keysAndArgs) + } + return args +} + +// Do evaluates the script. Under the covers, Do optimistically evaluates the +// script using the EVALSHA command. If the command fails because the script is +// not loaded, then Do evaluates the script using the EVAL command (thus +// causing the script to load). +func (s *Script) Do(c Conn, keysAndArgs ...interface{}) (interface{}, error) { + v, err := c.Do("EVALSHA", s.args(s.hash, keysAndArgs)...) + if e, ok := err.(Error); ok && strings.HasPrefix(string(e), "NOSCRIPT ") { + v, err = c.Do("EVAL", s.args(s.src, keysAndArgs)...) + } + return v, err +} + +// SendHash evaluates the script without waiting for the reply. The script is +// evaluated with the EVALSHA command. The application must ensure that the +// script is loaded by a previous call to Send, Do or Load methods. +func (s *Script) SendHash(c Conn, keysAndArgs ...interface{}) error { + return c.Send("EVALSHA", s.args(s.hash, keysAndArgs)...) +} + +// Send evaluates the script without waiting for the reply. +func (s *Script) Send(c Conn, keysAndArgs ...interface{}) error { + return c.Send("EVAL", s.args(s.src, keysAndArgs)...) +} + +// Load loads the script without evaluating it. +func (s *Script) Load(c Conn) error { + _, err := c.Do("SCRIPT", "LOAD", s.src) + return err +} diff --git a/vendor/github.com/golang/snappy/AUTHORS b/vendor/github.com/golang/snappy/AUTHORS new file mode 100644 index 0000000..824bf2e --- /dev/null +++ b/vendor/github.com/golang/snappy/AUTHORS @@ -0,0 +1,14 @@ +# This is the official list of Snappy-Go authors for copyright purposes. +# This file is distinct from the CONTRIBUTORS files. +# See the latter for an explanation. + +# Names should be added to this file as +# Name or Organization +# The email address is not required for organizations. + +# Please keep the list sorted. + +Damian Gryski +Google Inc. +Jan Mercl <0xjnml@gmail.com> +Sebastien Binet diff --git a/vendor/github.com/golang/snappy/CONTRIBUTORS b/vendor/github.com/golang/snappy/CONTRIBUTORS new file mode 100644 index 0000000..9f54f21 --- /dev/null +++ b/vendor/github.com/golang/snappy/CONTRIBUTORS @@ -0,0 +1,36 @@ +# This is the official list of people who can contribute +# (and typically have contributed) code to the Snappy-Go repository. +# The AUTHORS file lists the copyright holders; this file +# lists people. For example, Google employees are listed here +# but not in AUTHORS, because Google holds the copyright. +# +# The submission process automatically checks to make sure +# that people submitting code are listed in this file (by email address). +# +# Names should be added to this file only after verifying that +# the individual or the individual's organization has agreed to +# the appropriate Contributor License Agreement, found here: +# +# http://code.google.com/legal/individual-cla-v1.0.html +# http://code.google.com/legal/corporate-cla-v1.0.html +# +# The agreement for individuals can be filled out on the web. +# +# When adding J Random Contributor's name to this file, +# either J's name or J's organization's name should be +# added to the AUTHORS file, depending on whether the +# individual or corporate CLA was used. + +# Names should be added to this file like so: +# Name + +# Please keep the list sorted. + +Damian Gryski +Jan Mercl <0xjnml@gmail.com> +Kai Backman +Marc-Antoine Ruel +Nigel Tao +Rob Pike +Russ Cox +Sebastien Binet diff --git a/vendor/github.com/golang/snappy/LICENSE b/vendor/github.com/golang/snappy/LICENSE new file mode 100644 index 0000000..6050c10 --- /dev/null +++ b/vendor/github.com/golang/snappy/LICENSE @@ -0,0 +1,27 @@ +Copyright (c) 2011 The Snappy-Go Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/golang/snappy/README b/vendor/github.com/golang/snappy/README new file mode 100644 index 0000000..5074bba --- /dev/null +++ b/vendor/github.com/golang/snappy/README @@ -0,0 +1,7 @@ +The Snappy compression format in the Go programming language. + +To download and install from source: +$ go get github.com/golang/snappy + +Unless otherwise noted, the Snappy-Go source files are distributed +under the BSD-style license found in the LICENSE file. diff --git a/vendor/github.com/golang/snappy/decode.go b/vendor/github.com/golang/snappy/decode.go new file mode 100644 index 0000000..e7f1259 --- /dev/null +++ b/vendor/github.com/golang/snappy/decode.go @@ -0,0 +1,294 @@ +// Copyright 2011 The Snappy-Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package snappy + +import ( + "encoding/binary" + "errors" + "io" +) + +var ( + // ErrCorrupt reports that the input is invalid. + ErrCorrupt = errors.New("snappy: corrupt input") + // ErrTooLarge reports that the uncompressed length is too large. + ErrTooLarge = errors.New("snappy: decoded block is too large") + // ErrUnsupported reports that the input isn't supported. + ErrUnsupported = errors.New("snappy: unsupported input") +) + +// DecodedLen returns the length of the decoded block. +func DecodedLen(src []byte) (int, error) { + v, _, err := decodedLen(src) + return v, err +} + +// decodedLen returns the length of the decoded block and the number of bytes +// that the length header occupied. +func decodedLen(src []byte) (blockLen, headerLen int, err error) { + v, n := binary.Uvarint(src) + if n <= 0 || v > 0xffffffff { + return 0, 0, ErrCorrupt + } + + const wordSize = 32 << (^uint(0) >> 32 & 1) + if wordSize == 32 && v > 0x7fffffff { + return 0, 0, ErrTooLarge + } + return int(v), n, nil +} + +// Decode returns the decoded form of src. The returned slice may be a sub- +// slice of dst if dst was large enough to hold the entire decoded block. +// Otherwise, a newly allocated slice will be returned. +// It is valid to pass a nil dst. +func Decode(dst, src []byte) ([]byte, error) { + dLen, s, err := decodedLen(src) + if err != nil { + return nil, err + } + if len(dst) < dLen { + dst = make([]byte, dLen) + } + + var d, offset, length int + for s < len(src) { + switch src[s] & 0x03 { + case tagLiteral: + x := uint(src[s] >> 2) + switch { + case x < 60: + s++ + case x == 60: + s += 2 + if s > len(src) { + return nil, ErrCorrupt + } + x = uint(src[s-1]) + case x == 61: + s += 3 + if s > len(src) { + return nil, ErrCorrupt + } + x = uint(src[s-2]) | uint(src[s-1])<<8 + case x == 62: + s += 4 + if s > len(src) { + return nil, ErrCorrupt + } + x = uint(src[s-3]) | uint(src[s-2])<<8 | uint(src[s-1])<<16 + case x == 63: + s += 5 + if s > len(src) { + return nil, ErrCorrupt + } + x = uint(src[s-4]) | uint(src[s-3])<<8 | uint(src[s-2])<<16 | uint(src[s-1])<<24 + } + length = int(x + 1) + if length <= 0 { + return nil, errors.New("snappy: unsupported literal length") + } + if length > len(dst)-d || length > len(src)-s { + return nil, ErrCorrupt + } + copy(dst[d:], src[s:s+length]) + d += length + s += length + continue + + case tagCopy1: + s += 2 + if s > len(src) { + return nil, ErrCorrupt + } + length = 4 + int(src[s-2])>>2&0x7 + offset = int(src[s-2])&0xe0<<3 | int(src[s-1]) + + case tagCopy2: + s += 3 + if s > len(src) { + return nil, ErrCorrupt + } + length = 1 + int(src[s-3])>>2 + offset = int(src[s-2]) | int(src[s-1])<<8 + + case tagCopy4: + return nil, errors.New("snappy: unsupported COPY_4 tag") + } + + end := d + length + if offset > d || end > len(dst) { + return nil, ErrCorrupt + } + for ; d < end; d++ { + dst[d] = dst[d-offset] + } + } + if d != dLen { + return nil, ErrCorrupt + } + return dst[:d], nil +} + +// NewReader returns a new Reader that decompresses from r, using the framing +// format described at +// https://github.com/google/snappy/blob/master/framing_format.txt +func NewReader(r io.Reader) *Reader { + return &Reader{ + r: r, + decoded: make([]byte, maxUncompressedChunkLen), + buf: make([]byte, MaxEncodedLen(maxUncompressedChunkLen)+checksumSize), + } +} + +// Reader is an io.Reader than can read Snappy-compressed bytes. +type Reader struct { + r io.Reader + err error + decoded []byte + buf []byte + // decoded[i:j] contains decoded bytes that have not yet been passed on. + i, j int + readHeader bool +} + +// Reset discards any buffered data, resets all state, and switches the Snappy +// reader to read from r. This permits reusing a Reader rather than allocating +// a new one. +func (r *Reader) Reset(reader io.Reader) { + r.r = reader + r.err = nil + r.i = 0 + r.j = 0 + r.readHeader = false +} + +func (r *Reader) readFull(p []byte) (ok bool) { + if _, r.err = io.ReadFull(r.r, p); r.err != nil { + if r.err == io.ErrUnexpectedEOF { + r.err = ErrCorrupt + } + return false + } + return true +} + +// Read satisfies the io.Reader interface. +func (r *Reader) Read(p []byte) (int, error) { + if r.err != nil { + return 0, r.err + } + for { + if r.i < r.j { + n := copy(p, r.decoded[r.i:r.j]) + r.i += n + return n, nil + } + if !r.readFull(r.buf[:4]) { + return 0, r.err + } + chunkType := r.buf[0] + if !r.readHeader { + if chunkType != chunkTypeStreamIdentifier { + r.err = ErrCorrupt + return 0, r.err + } + r.readHeader = true + } + chunkLen := int(r.buf[1]) | int(r.buf[2])<<8 | int(r.buf[3])<<16 + if chunkLen > len(r.buf) { + r.err = ErrUnsupported + return 0, r.err + } + + // The chunk types are specified at + // https://github.com/google/snappy/blob/master/framing_format.txt + switch chunkType { + case chunkTypeCompressedData: + // Section 4.2. Compressed data (chunk type 0x00). + if chunkLen < checksumSize { + r.err = ErrCorrupt + return 0, r.err + } + buf := r.buf[:chunkLen] + if !r.readFull(buf) { + return 0, r.err + } + checksum := uint32(buf[0]) | uint32(buf[1])<<8 | uint32(buf[2])<<16 | uint32(buf[3])<<24 + buf = buf[checksumSize:] + + n, err := DecodedLen(buf) + if err != nil { + r.err = err + return 0, r.err + } + if n > len(r.decoded) { + r.err = ErrCorrupt + return 0, r.err + } + if _, err := Decode(r.decoded, buf); err != nil { + r.err = err + return 0, r.err + } + if crc(r.decoded[:n]) != checksum { + r.err = ErrCorrupt + return 0, r.err + } + r.i, r.j = 0, n + continue + + case chunkTypeUncompressedData: + // Section 4.3. Uncompressed data (chunk type 0x01). + if chunkLen < checksumSize { + r.err = ErrCorrupt + return 0, r.err + } + buf := r.buf[:checksumSize] + if !r.readFull(buf) { + return 0, r.err + } + checksum := uint32(buf[0]) | uint32(buf[1])<<8 | uint32(buf[2])<<16 | uint32(buf[3])<<24 + // Read directly into r.decoded instead of via r.buf. + n := chunkLen - checksumSize + if !r.readFull(r.decoded[:n]) { + return 0, r.err + } + if crc(r.decoded[:n]) != checksum { + r.err = ErrCorrupt + return 0, r.err + } + r.i, r.j = 0, n + continue + + case chunkTypeStreamIdentifier: + // Section 4.1. Stream identifier (chunk type 0xff). + if chunkLen != len(magicBody) { + r.err = ErrCorrupt + return 0, r.err + } + if !r.readFull(r.buf[:len(magicBody)]) { + return 0, r.err + } + for i := 0; i < len(magicBody); i++ { + if r.buf[i] != magicBody[i] { + r.err = ErrCorrupt + return 0, r.err + } + } + continue + } + + if chunkType <= 0x7f { + // Section 4.5. Reserved unskippable chunks (chunk types 0x02-0x7f). + r.err = ErrUnsupported + return 0, r.err + } + // Section 4.4 Padding (chunk type 0xfe). + // Section 4.6. Reserved skippable chunks (chunk types 0x80-0xfd). + if !r.readFull(r.buf[:chunkLen]) { + return 0, r.err + } + } +} diff --git a/vendor/github.com/golang/snappy/encode.go b/vendor/github.com/golang/snappy/encode.go new file mode 100644 index 0000000..f3b5484 --- /dev/null +++ b/vendor/github.com/golang/snappy/encode.go @@ -0,0 +1,254 @@ +// Copyright 2011 The Snappy-Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package snappy + +import ( + "encoding/binary" + "io" +) + +// We limit how far copy back-references can go, the same as the C++ code. +const maxOffset = 1 << 15 + +// emitLiteral writes a literal chunk and returns the number of bytes written. +func emitLiteral(dst, lit []byte) int { + i, n := 0, uint(len(lit)-1) + switch { + case n < 60: + dst[0] = uint8(n)<<2 | tagLiteral + i = 1 + case n < 1<<8: + dst[0] = 60<<2 | tagLiteral + dst[1] = uint8(n) + i = 2 + case n < 1<<16: + dst[0] = 61<<2 | tagLiteral + dst[1] = uint8(n) + dst[2] = uint8(n >> 8) + i = 3 + case n < 1<<24: + dst[0] = 62<<2 | tagLiteral + dst[1] = uint8(n) + dst[2] = uint8(n >> 8) + dst[3] = uint8(n >> 16) + i = 4 + case int64(n) < 1<<32: + dst[0] = 63<<2 | tagLiteral + dst[1] = uint8(n) + dst[2] = uint8(n >> 8) + dst[3] = uint8(n >> 16) + dst[4] = uint8(n >> 24) + i = 5 + default: + panic("snappy: source buffer is too long") + } + if copy(dst[i:], lit) != len(lit) { + panic("snappy: destination buffer is too short") + } + return i + len(lit) +} + +// emitCopy writes a copy chunk and returns the number of bytes written. +func emitCopy(dst []byte, offset, length int) int { + i := 0 + for length > 0 { + x := length - 4 + if 0 <= x && x < 1<<3 && offset < 1<<11 { + dst[i+0] = uint8(offset>>8)&0x07<<5 | uint8(x)<<2 | tagCopy1 + dst[i+1] = uint8(offset) + i += 2 + break + } + + x = length + if x > 1<<6 { + x = 1 << 6 + } + dst[i+0] = uint8(x-1)<<2 | tagCopy2 + dst[i+1] = uint8(offset) + dst[i+2] = uint8(offset >> 8) + i += 3 + length -= x + } + return i +} + +// Encode returns the encoded form of src. The returned slice may be a sub- +// slice of dst if dst was large enough to hold the entire encoded block. +// Otherwise, a newly allocated slice will be returned. +// It is valid to pass a nil dst. +func Encode(dst, src []byte) []byte { + if n := MaxEncodedLen(len(src)); len(dst) < n { + dst = make([]byte, n) + } + + // The block starts with the varint-encoded length of the decompressed bytes. + d := binary.PutUvarint(dst, uint64(len(src))) + + // Return early if src is short. + if len(src) <= 4 { + if len(src) != 0 { + d += emitLiteral(dst[d:], src) + } + return dst[:d] + } + + // Initialize the hash table. Its size ranges from 1<<8 to 1<<14 inclusive. + const maxTableSize = 1 << 14 + shift, tableSize := uint(32-8), 1<<8 + for tableSize < maxTableSize && tableSize < len(src) { + shift-- + tableSize *= 2 + } + var table [maxTableSize]int + + // Iterate over the source bytes. + var ( + s int // The iterator position. + t int // The last position with the same hash as s. + lit int // The start position of any pending literal bytes. + ) + for s+3 < len(src) { + // Update the hash table. + b0, b1, b2, b3 := src[s], src[s+1], src[s+2], src[s+3] + h := uint32(b0) | uint32(b1)<<8 | uint32(b2)<<16 | uint32(b3)<<24 + p := &table[(h*0x1e35a7bd)>>shift] + // We need to to store values in [-1, inf) in table. To save + // some initialization time, (re)use the table's zero value + // and shift the values against this zero: add 1 on writes, + // subtract 1 on reads. + t, *p = *p-1, s+1 + // If t is invalid or src[s:s+4] differs from src[t:t+4], accumulate a literal byte. + if t < 0 || s-t >= maxOffset || b0 != src[t] || b1 != src[t+1] || b2 != src[t+2] || b3 != src[t+3] { + s++ + continue + } + // Otherwise, we have a match. First, emit any pending literal bytes. + if lit != s { + d += emitLiteral(dst[d:], src[lit:s]) + } + // Extend the match to be as long as possible. + s0 := s + s, t = s+4, t+4 + for s < len(src) && src[s] == src[t] { + s++ + t++ + } + // Emit the copied bytes. + d += emitCopy(dst[d:], s-t, s-s0) + lit = s + } + + // Emit any final pending literal bytes and return. + if lit != len(src) { + d += emitLiteral(dst[d:], src[lit:]) + } + return dst[:d] +} + +// MaxEncodedLen returns the maximum length of a snappy block, given its +// uncompressed length. +func MaxEncodedLen(srcLen int) int { + // Compressed data can be defined as: + // compressed := item* literal* + // item := literal* copy + // + // The trailing literal sequence has a space blowup of at most 62/60 + // since a literal of length 60 needs one tag byte + one extra byte + // for length information. + // + // Item blowup is trickier to measure. Suppose the "copy" op copies + // 4 bytes of data. Because of a special check in the encoding code, + // we produce a 4-byte copy only if the offset is < 65536. Therefore + // the copy op takes 3 bytes to encode, and this type of item leads + // to at most the 62/60 blowup for representing literals. + // + // Suppose the "copy" op copies 5 bytes of data. If the offset is big + // enough, it will take 5 bytes to encode the copy op. Therefore the + // worst case here is a one-byte literal followed by a five-byte copy. + // That is, 6 bytes of input turn into 7 bytes of "compressed" data. + // + // This last factor dominates the blowup, so the final estimate is: + return 32 + srcLen + srcLen/6 +} + +// NewWriter returns a new Writer that compresses to w, using the framing +// format described at +// https://github.com/google/snappy/blob/master/framing_format.txt +func NewWriter(w io.Writer) *Writer { + return &Writer{ + w: w, + enc: make([]byte, MaxEncodedLen(maxUncompressedChunkLen)), + } +} + +// Writer is an io.Writer than can write Snappy-compressed bytes. +type Writer struct { + w io.Writer + err error + enc []byte + buf [checksumSize + chunkHeaderSize]byte + wroteHeader bool +} + +// Reset discards the writer's state and switches the Snappy writer to write to +// w. This permits reusing a Writer rather than allocating a new one. +func (w *Writer) Reset(writer io.Writer) { + w.w = writer + w.err = nil + w.wroteHeader = false +} + +// Write satisfies the io.Writer interface. +func (w *Writer) Write(p []byte) (n int, errRet error) { + if w.err != nil { + return 0, w.err + } + if !w.wroteHeader { + copy(w.enc, magicChunk) + if _, err := w.w.Write(w.enc[:len(magicChunk)]); err != nil { + w.err = err + return n, err + } + w.wroteHeader = true + } + for len(p) > 0 { + var uncompressed []byte + if len(p) > maxUncompressedChunkLen { + uncompressed, p = p[:maxUncompressedChunkLen], p[maxUncompressedChunkLen:] + } else { + uncompressed, p = p, nil + } + checksum := crc(uncompressed) + + // Compress the buffer, discarding the result if the improvement + // isn't at least 12.5%. + chunkType := uint8(chunkTypeCompressedData) + chunkBody := Encode(w.enc, uncompressed) + if len(chunkBody) >= len(uncompressed)-len(uncompressed)/8 { + chunkType, chunkBody = chunkTypeUncompressedData, uncompressed + } + + chunkLen := 4 + len(chunkBody) + w.buf[0] = chunkType + w.buf[1] = uint8(chunkLen >> 0) + w.buf[2] = uint8(chunkLen >> 8) + w.buf[3] = uint8(chunkLen >> 16) + w.buf[4] = uint8(checksum >> 0) + w.buf[5] = uint8(checksum >> 8) + w.buf[6] = uint8(checksum >> 16) + w.buf[7] = uint8(checksum >> 24) + if _, err := w.w.Write(w.buf[:]); err != nil { + w.err = err + return n, err + } + if _, err := w.w.Write(chunkBody); err != nil { + w.err = err + return n, err + } + n += len(uncompressed) + } + return n, nil +} diff --git a/vendor/github.com/golang/snappy/snappy.go b/vendor/github.com/golang/snappy/snappy.go new file mode 100644 index 0000000..e98653a --- /dev/null +++ b/vendor/github.com/golang/snappy/snappy.go @@ -0,0 +1,68 @@ +// Copyright 2011 The Snappy-Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package snappy implements the snappy block-based compression format. +// It aims for very high speeds and reasonable compression. +// +// The C++ snappy implementation is at https://github.com/google/snappy +package snappy + +import ( + "hash/crc32" +) + +/* +Each encoded block begins with the varint-encoded length of the decoded data, +followed by a sequence of chunks. Chunks begin and end on byte boundaries. The +first byte of each chunk is broken into its 2 least and 6 most significant bits +called l and m: l ranges in [0, 4) and m ranges in [0, 64). l is the chunk tag. +Zero means a literal tag. All other values mean a copy tag. + +For literal tags: + - If m < 60, the next 1 + m bytes are literal bytes. + - Otherwise, let n be the little-endian unsigned integer denoted by the next + m - 59 bytes. The next 1 + n bytes after that are literal bytes. + +For copy tags, length bytes are copied from offset bytes ago, in the style of +Lempel-Ziv compression algorithms. In particular: + - For l == 1, the offset ranges in [0, 1<<11) and the length in [4, 12). + The length is 4 + the low 3 bits of m. The high 3 bits of m form bits 8-10 + of the offset. The next byte is bits 0-7 of the offset. + - For l == 2, the offset ranges in [0, 1<<16) and the length in [1, 65). + The length is 1 + m. The offset is the little-endian unsigned integer + denoted by the next 2 bytes. + - For l == 3, this tag is a legacy format that is no longer supported. +*/ +const ( + tagLiteral = 0x00 + tagCopy1 = 0x01 + tagCopy2 = 0x02 + tagCopy4 = 0x03 +) + +const ( + checksumSize = 4 + chunkHeaderSize = 4 + magicChunk = "\xff\x06\x00\x00" + magicBody + magicBody = "sNaPpY" + // https://github.com/google/snappy/blob/master/framing_format.txt says + // that "the uncompressed data in a chunk must be no longer than 65536 bytes". + maxUncompressedChunkLen = 65536 +) + +const ( + chunkTypeCompressedData = 0x00 + chunkTypeUncompressedData = 0x01 + chunkTypePadding = 0xfe + chunkTypeStreamIdentifier = 0xff +) + +var crcTable = crc32.MakeTable(crc32.Castagnoli) + +// crc implements the checksum specified in section 3 of +// https://github.com/google/snappy/blob/master/framing_format.txt +func crc(b []byte) uint32 { + c := crc32.Update(0, crcTable, b) + return uint32(c>>15|c<<17) + 0xa282ead8 +} diff --git a/vendor/github.com/google/gopacket/.gitignore b/vendor/github.com/google/gopacket/.gitignore new file mode 100644 index 0000000..7386e2b --- /dev/null +++ b/vendor/github.com/google/gopacket/.gitignore @@ -0,0 +1,37 @@ +# 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 +layers/gen +macs/gen +pcap/pcap_tester diff --git a/vendor/github.com/google/gopacket/.travis.yml b/vendor/github.com/google/gopacket/.travis.yml new file mode 100644 index 0000000..a2feecb --- /dev/null +++ b/vendor/github.com/google/gopacket/.travis.yml @@ -0,0 +1,9 @@ +language: go +install: + - go get github.com/google/gopacket + - go get github.com/google/gopacket/layers + - go get github.com/google/gopacket/tcpassembly +script: + - go test github.com/google/gopacket + - go test github.com/google/gopacket/layers + - go test github.com/google/gopacket/tcpassembly diff --git a/vendor/github.com/google/gopacket/AUTHORS b/vendor/github.com/google/gopacket/AUTHORS new file mode 100644 index 0000000..9b3f6bf --- /dev/null +++ b/vendor/github.com/google/gopacket/AUTHORS @@ -0,0 +1,44 @@ +AUTHORS AND MAINTAINERS: + +MAIN DEVELOPERS: +Graeme Connell + +AUTHORS: +Nigel Tao +Cole Mickens +Ben Daglish +Luis Martinez +Remco Verhoef +Hiroaki Kawai +Lukas Lueg +Laurent Hausermann +Bill Green + +CONTRIBUTORS: +Attila Oláh +Vittus Mikiassen +Matthias Radestock +Matthew Sackman +Loic Prylli +Alexandre Fiori +Adrian Tam +Satoshi Matsumoto +David Stainton + +----------------------------------------------- +FORKED FROM github.com/akrennmair/gopcap +ALL THE FOLLOWING ARE FOR THAT PROJECT + +MAIN DEVELOPERS: +Andreas Krennmair + +CONTRIBUTORS: +Andrea Nall +Daniel Arndt +Dustin Sallings +Graeme Connell +Guillaume Savary +Mark Smith +Miek Gieben +Mike Bell +Trevor Strohman diff --git a/vendor/github.com/google/gopacket/CHANGELOG b/vendor/github.com/google/gopacket/CHANGELOG new file mode 100644 index 0000000..6d771b8 --- /dev/null +++ b/vendor/github.com/google/gopacket/CHANGELOG @@ -0,0 +1 @@ +See https://code.google.com/p/gopacket/wiki/ChangeLog diff --git a/vendor/github.com/google/gopacket/CONTRIBUTING.md b/vendor/github.com/google/gopacket/CONTRIBUTING.md new file mode 100644 index 0000000..1db2597 --- /dev/null +++ b/vendor/github.com/google/gopacket/CONTRIBUTING.md @@ -0,0 +1,239 @@ +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 +------------------ + +gopacket uses the Git version control system. If you want to +make a new change, you'll first have to get our code: + + go get github.com/google/gopacket + cd $GOROOT/src/pkg/github.com/google/gopacket + git checkout -b # create a new branch to work from + ... code code code ... + ./gc # Run this to do local commits, it performs a number of checks + ... code code code ... + ./gc --benchmark # Run this whenever your commit could affect performance + +Now that you're in the gopacket code directory, you can start making your initial +change. PLEASE make sure you're using a new branch to develop whatever feature +you're working on. + +Once you've got your code to a place where you're ready to have us look at it, +send an email to gopacket@googlegroups.com, detailing your change. We'll add +you as a committer, and you can upload your feature branch to github.com/google/gopacket. +From there, the other folks working on gopacket can give you code reviews with +the github.com code review functionality. + +The code review will generally be either emails or line-by-line reviews via +github.com. One or more folks might review your code. The review should +be considered "complete" when at least one of the project Owners (see +https://github.com/orgs/google/people) gives you permission to merge to +master. At that point, you can merge to master yourself, or you can have one of +the other committers/owners do it for you. + +When doing the final merge, please try to capture any interesting comments or +discussions that came up in code review. This will help future contributors be +able to find and reference those discussions later on. + +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. + + Send an email asking us to make you a committer (if you're new). + + Push your new feature branch up to github.com. + + Handle comments and requests from reviewers, pushing new commits up to + your feature branch as problems are addressed. + + Get approval from a project Owner to merge to master. + + Merge yourself, or have another Committer/Owner do it for you. + + Put interesting comments and discussions into commit comments. +* DON'T + + Push directly to master. + + Push to someone else's branch without their permission. + + Merge your own code to master without sign-off from others on the project. + + Rebase (please merge) +* OPTIONAL + + Review others' code as it comes in (politely :) + + Keep contributing! + + +Coding Style +------------ + +* Go code must be run through 'go fmt'. +* 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. diff --git a/vendor/github.com/google/gopacket/LICENSE b/vendor/github.com/google/gopacket/LICENSE new file mode 100644 index 0000000..2100d52 --- /dev/null +++ b/vendor/github.com/google/gopacket/LICENSE @@ -0,0 +1,28 @@ +Copyright (c) 2012 Google, Inc. All rights reserved. +Copyright (c) 2009-2011 Andreas Krennmair. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Andreas Krennmair, Google, nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/google/gopacket/README.md b/vendor/github.com/google/gopacket/README.md new file mode 100644 index 0000000..f71854c --- /dev/null +++ b/vendor/github.com/google/gopacket/README.md @@ -0,0 +1,10 @@ +# GoPacket + +This library provides packet decoding capabilities for Go. +See [godoc](https://godoc.org/github.com/google/gopacket) for more details. + +[![Build Status](https://travis-ci.org/google/gopacket.svg?branch=master)](https://travis-ci.org/google/gopacket) +[![GoDoc](https://godoc.org/github.com/google/gopacket?status.svg)](https://godoc.org/github.com/google/gopacket) + +Originally forked from the gopcap project written by Andreas +Krennmair (http://github.com/akrennmair/gopcap). diff --git a/vendor/github.com/google/gopacket/afpacket/afpacket.go b/vendor/github.com/google/gopacket/afpacket/afpacket.go new file mode 100644 index 0000000..2ecd4d7 --- /dev/null +++ b/vendor/github.com/google/gopacket/afpacket/afpacket.go @@ -0,0 +1,421 @@ +// 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 linux + +// Package afpacket provides Go bindings for MMap'd AF_PACKET socket reading. +package afpacket + +// Couldn't have done this without: +// http://lxr.free-electrons.com/source/Documentation/networking/packet_mmap.txt +// http://codemonkeytips.blogspot.co.uk/2011/07/asynchronous-packet-socket-reading-with.html + +import ( + "errors" + "fmt" + "github.com/google/gopacket" + "net" + "runtime" + "sync" + "time" + "unsafe" +) + +/* +#include // AF_PACKET, sockaddr_ll +#include // ETH_P_ALL +#include // socket() +#include // close() +#include // htons() +#include // mmap(), munmap() +#include // poll() +*/ +import "C" + +var pageSize = int(C.getpagesize()) +var tpacketAlignment = uint(C.TPACKET_ALIGNMENT) + +func tpacketAlign(v int) int { + return int((uint(v) + tpacketAlignment - 1) & ((^tpacketAlignment) - 1)) +} + +// Stats is a set of counters detailing the work TPacket has done so far. +type Stats struct { + // Packets is the total number of packets returned to the caller. + Packets int64 + // Polls is the number of blocking syscalls made waiting for packets. + // This should always be <= Packets, since with TPacket one syscall + // can (and often does) return many results. + Polls int64 +} + +// Get structs to store socket stats +type SocketStats C.struct_tpacket_stats +type SocketStatsV3 C.struct_tpacket_stats_v3 + +type TPacket struct { + // fd is the C file descriptor. + fd C.int + // ring points to the memory space of the ring buffer shared by tpacket and the kernel. + ring unsafe.Pointer + // opts contains read-only options for the TPacket object. + opts options + mu sync.Mutex // guards below + // offset is the offset into the ring of the current header. + offset int + // current is the current header. + current header + // pollset is used by TPacket for its poll() call. + pollset C.struct_pollfd + // shouldReleasePacket is set to true whenever we return packet data, to make sure we remember to release that data back to the kernel. + shouldReleasePacket bool + // stats is simple statistics on TPacket's run. + stats Stats + // socketStats contains stats from the socket + socketStats SocketStats + // same as socketStats, but with an extra field freeze_q_cnt + socketStatsV3 SocketStatsV3 + // tpVersion is the version of TPacket actually in use, set by setRequestedTPacketVersion. + tpVersion OptTPacketVersion + // Hackity hack hack hack. We need to return a pointer to the header with + // getTPacketHeader, and we don't want to allocate a v3wrapper every time, + // so we leave it in the TPacket object and return a pointer to it. + v3 v3wrapper +} + +// bindToInterface binds the TPacket socket to a particular named interface. +func (h *TPacket) bindToInterface(ifaceName string) error { + iface, err := net.InterfaceByName(ifaceName) + if err != nil { + return fmt.Errorf("InterfaceByName: %v", err) + } + var ll C.struct_sockaddr_ll + ll.sll_family = C.AF_PACKET + ll.sll_protocol = C.__be16(C.htons(C.ETH_P_ALL)) + ll.sll_ifindex = C.int(iface.Index) + if _, err := C.bind(h.fd, (*C.struct_sockaddr)(unsafe.Pointer(&ll)), C.socklen_t(unsafe.Sizeof(ll))); err != nil { + return fmt.Errorf("bindToInterface: %v", err) + } + return nil +} + +// setTPacketVersion asks the kernel to set TPacket to a particular version, and returns an error on failure. +func (h *TPacket) setTPacketVersion(version OptTPacketVersion) error { + val := C.int(version) + _, err := C.setsockopt(h.fd, C.SOL_PACKET, C.PACKET_VERSION, unsafe.Pointer(&val), C.socklen_t(unsafe.Sizeof(val))) + if err != nil { + return fmt.Errorf("setsockopt packet_version: %v", err) + } + return nil +} + +// setRequestedTPacketVersion tries to set TPacket to the requested version or versions. +func (h *TPacket) setRequestedTPacketVersion() error { + switch { + case (h.opts.version == TPacketVersionHighestAvailable || h.opts.version == TPacketVersion3) && h.setTPacketVersion(TPacketVersion3) == nil: + h.tpVersion = TPacketVersion3 + case (h.opts.version == TPacketVersionHighestAvailable || h.opts.version == TPacketVersion2) && h.setTPacketVersion(TPacketVersion2) == nil: + h.tpVersion = TPacketVersion2 + case (h.opts.version == TPacketVersionHighestAvailable || h.opts.version == TPacketVersion1) && h.setTPacketVersion(TPacketVersion1) == nil: + h.tpVersion = TPacketVersion1 + default: + return errors.New("no known tpacket versions work on this machine") + } + return nil +} + +// setUpRing sets up the shared-memory ring buffer between the user process and the kernel. +func (h *TPacket) setUpRing() (err error) { + totalSize := C.uint(h.opts.framesPerBlock * h.opts.numBlocks * h.opts.frameSize) + switch h.tpVersion { + case TPacketVersion1, TPacketVersion2: + var tp C.struct_tpacket_req + tp.tp_block_size = C.uint(h.opts.blockSize) + tp.tp_block_nr = C.uint(h.opts.numBlocks) + tp.tp_frame_size = C.uint(h.opts.frameSize) + tp.tp_frame_nr = C.uint(h.opts.framesPerBlock * h.opts.numBlocks) + if _, err := C.setsockopt(h.fd, C.SOL_PACKET, C.PACKET_RX_RING, unsafe.Pointer(&tp), C.socklen_t(unsafe.Sizeof(tp))); err != nil { + return fmt.Errorf("setsockopt packet_rx_ring: %v", err) + } + case TPacketVersion3: + var tp C.struct_tpacket_req3 + tp.tp_block_size = C.uint(h.opts.blockSize) + tp.tp_block_nr = C.uint(h.opts.numBlocks) + tp.tp_frame_size = C.uint(h.opts.frameSize) + tp.tp_frame_nr = C.uint(h.opts.framesPerBlock * h.opts.numBlocks) + tp.tp_retire_blk_tov = C.uint(h.opts.blockTimeout / time.Millisecond) + if _, err := C.setsockopt(h.fd, C.SOL_PACKET, C.PACKET_RX_RING, unsafe.Pointer(&tp), C.socklen_t(unsafe.Sizeof(tp))); err != nil { + return fmt.Errorf("setsockopt packet_rx_ring v3: %v", err) + } + default: + return errors.New("invalid tpVersion") + } + if h.ring, err = C.mmap(nil, C.size_t(totalSize), C.PROT_READ|C.PROT_WRITE, C.MAP_SHARED, C.int(h.fd), 0); err != nil { + return + } + if h.ring == nil { + return errors.New("no ring") + } + return nil +} + +// Close cleans up the TPacket. It should not be used after the Close call. +func (h *TPacket) Close() { + if h.fd == -1 { + return // already closed. + } + if h.ring != nil { + C.munmap(h.ring, C.size_t(h.opts.blockSize*h.opts.numBlocks)) + } + h.ring = nil + C.close(h.fd) + h.fd = -1 + runtime.SetFinalizer(h, nil) +} + +// NewTPacket returns a new TPacket object for reading packets off the wire. +// Its behavior may be modified by passing in any/all of afpacket.Opt* to this +// function. +// If this function succeeds, the user should be sure to Close the returned +// TPacket when finished with it. +func NewTPacket(opts ...interface{}) (h *TPacket, err error) { + h = &TPacket{} + if h.opts, err = parseOptions(opts...); err != nil { + return nil, err + } + fd, err := C.socket(C.AF_PACKET, C.int(h.opts.socktype), C.int(C.htons(C.ETH_P_ALL))) + if err != nil { + return nil, err + } + h.fd = fd + if h.opts.iface != "" { + if err = h.bindToInterface(h.opts.iface); err != nil { + goto errlbl + } + } + if err = h.setRequestedTPacketVersion(); err != nil { + goto errlbl + } + if err = h.setUpRing(); err != nil { + goto errlbl + } + // Clear stat counter from socket + if err = h.InitSocketStats(); err != nil { + goto errlbl + } + runtime.SetFinalizer(h, (*TPacket).Close) + return h, nil +errlbl: + h.Close() + return nil, err +} + +func (h *TPacket) releaseCurrentPacket() error { + h.current.clearStatus() + h.offset++ + h.shouldReleasePacket = false + return nil +} + +// ZeroCopyReadPacketData reads the next packet off the wire, and returns its data. +// The slice returned by ZeroCopyReadPacketData points to bytes owned by the +// TPacket. Each call to ZeroCopyReadPacketData invalidates any data previously +// returned by ZeroCopyReadPacketData. Care must be taken not to keep pointers +// to old bytes when using ZeroCopyReadPacketData... if you need to keep data past +// the next time you call ZeroCopyReadPacketData, use ReadPacketDataData, which copies +// the bytes into a new buffer for you. +// tp, _ := NewTPacket(...) +// data1, _, _ := tp.ZeroCopyReadPacketData() +// // do everything you want with data1 here, copying bytes out of it if you'd like to keep them around. +// data2, _, _ := tp.ZeroCopyReadPacketData() // invalidates bytes in data1 +func (h *TPacket) ZeroCopyReadPacketData() (data []byte, ci gopacket.CaptureInfo, err error) { + h.mu.Lock() + if h.current == nil || !h.current.next() { + if h.shouldReleasePacket { + h.releaseCurrentPacket() + } + h.current = h.getTPacketHeader() + if err = h.pollForFirstPacket(h.current); err != nil { + h.mu.Unlock() + return + } + } + data = h.current.getData() + ci.Timestamp = h.current.getTime() + ci.CaptureLength = len(data) + ci.Length = h.current.getLength() + h.stats.Packets++ + h.mu.Unlock() + return +} + +// Stats returns statistics on the packets the TPacket has seen so far. +func (h *TPacket) Stats() (Stats, error) { + h.mu.Lock() + defer h.mu.Unlock() + return h.stats, nil +} + +// Clear socket counters and return empty stats +func (h *TPacket) InitSocketStats() error { + if h.tpVersion == TPacketVersion3 { + socklen := unsafe.Sizeof(h.socketStatsV3) + var slt C.socklen_t = C.socklen_t(socklen) + _, err := C.getsockopt(h.fd, C.SOL_PACKET, C.PACKET_STATISTICS, unsafe.Pointer(&h.socketStatsV3), &slt) + if err != nil { + return err + } + h.socketStatsV3 = SocketStatsV3{} + } else { + socklen := unsafe.Sizeof(h.socketStats) + var slt C.socklen_t = C.socklen_t(socklen) + _, err := C.getsockopt(h.fd, C.SOL_PACKET, C.PACKET_STATISTICS, unsafe.Pointer(&h.socketStats), &slt) + if err != nil { + return err + } + h.socketStats = SocketStats{} + } + return nil +} + +// Saves stats from the socket to the TPacket instance +func (h *TPacket) SocketStats() (SocketStats, SocketStatsV3, error) { + h.mu.Lock() + defer h.mu.Unlock() + // We need to save the counters since asking for the stats will clear them + if h.tpVersion == TPacketVersion3 { + prevStats := h.socketStatsV3 + socklen := unsafe.Sizeof(h.socketStatsV3) + var slt C.socklen_t = C.socklen_t(socklen) + _, err := C.getsockopt(h.fd, C.SOL_PACKET, C.PACKET_STATISTICS, unsafe.Pointer(&h.socketStatsV3), &slt) + if err != nil { + return SocketStats{}, SocketStatsV3{}, err + } + + h.socketStatsV3.tp_packets += prevStats.tp_packets + h.socketStatsV3.tp_drops += prevStats.tp_drops + h.socketStatsV3.tp_freeze_q_cnt += prevStats.tp_freeze_q_cnt + + return h.socketStats, h.socketStatsV3, nil + } else { + prevStats := h.socketStats + socklen := unsafe.Sizeof(h.socketStats) + var slt C.socklen_t = C.socklen_t(socklen) + _, err := C.getsockopt(h.fd, C.SOL_PACKET, C.PACKET_STATISTICS, unsafe.Pointer(&h.socketStats), &slt) + if err != nil { + return SocketStats{}, SocketStatsV3{}, err + } + + h.socketStats.tp_packets += prevStats.tp_packets + h.socketStats.tp_drops += prevStats.tp_drops + + return h.socketStats, h.socketStatsV3, nil + + } +} + +// ReadPacketDataTo reads packet data into a user-supplied buffer. +// This function reads up to the length of the passed-in slice. +// The number of bytes read into data will be returned in ci.CaptureLength, +// which is the minimum of the size of the passed-in buffer and the size of +// the captured packet. +func (h *TPacket) ReadPacketDataTo(data []byte) (ci gopacket.CaptureInfo, err error) { + var d []byte + d, ci, err = h.ZeroCopyReadPacketData() + if err != nil { + return + } + ci.CaptureLength = copy(data, d) + return +} + +// ReadPacketData reads the next packet, copies it into a new buffer, and returns +// that buffer. Since the buffer is allocated by ReadPacketData, it is safe for long-term +// use. This implements gopacket.PacketDataSource. +func (h *TPacket) ReadPacketData() (data []byte, ci gopacket.CaptureInfo, err error) { + var d []byte + d, ci, err = h.ZeroCopyReadPacketData() + if err != nil { + return + } + data = make([]byte, len(d)) + copy(data, d) + return +} + +func (h *TPacket) getTPacketHeader() header { + switch h.tpVersion { + case TPacketVersion1: + if h.offset >= h.opts.framesPerBlock*h.opts.numBlocks { + h.offset = 0 + } + position := uintptr(h.ring) + uintptr(h.opts.frameSize*h.offset) + return (*v1header)(unsafe.Pointer(position)) + case TPacketVersion2: + if h.offset >= h.opts.framesPerBlock*h.opts.numBlocks { + h.offset = 0 + } + position := uintptr(h.ring) + uintptr(h.opts.frameSize*h.offset) + return (*v2header)(unsafe.Pointer(position)) + case TPacketVersion3: + // TPacket3 uses each block to return values, instead of each frame. Hence we need to rotate when we hit #blocks, not #frames. + if h.offset >= h.opts.numBlocks { + h.offset = 0 + } + position := uintptr(h.ring) + uintptr(h.opts.frameSize*h.offset*h.opts.framesPerBlock) + h.v3 = initV3Wrapper(unsafe.Pointer(position)) + return &h.v3 + } + panic("handle tpacket version is invalid") +} + +func (h *TPacket) pollForFirstPacket(hdr header) error { + for hdr.getStatus()&C.TP_STATUS_USER == 0 { + h.pollset.fd = h.fd + h.pollset.events = C.POLLIN + h.pollset.revents = 0 + _, err := C.poll(&h.pollset, 1, -1) + h.stats.Polls++ + if err != nil { + return err + } + } + h.shouldReleasePacket = true + return nil +} + +// FanoutType determines the type of fanout to use with a TPacket SetFanout call. +type FanoutType int + +const ( + FanoutHash FanoutType = 0 + // It appears that defrag only works with FanoutHash, see: + // http://lxr.free-electrons.com/source/net/packet/af_packet.c#L1204 + FanoutHashWithDefrag FanoutType = 0x8000 + FanoutLoadBalance FanoutType = 1 + FanoutCPU FanoutType = 2 +) + +// SetFanout activates TPacket's fanout ability. +// Use of Fanout requires creating multiple TPacket objects and the same id/type to +// a SetFanout call on each. Note that this can be done cross-process, so if two +// different processes both call SetFanout with the same type/id, they'll share +// packets between them. The same should work for multiple TPacket objects within +// the same process. +func (h *TPacket) SetFanout(t FanoutType, id uint16) error { + h.mu.Lock() + defer h.mu.Unlock() + arg := C.int(t) << 16 + arg |= C.int(id) + _, err := C.setsockopt(h.fd, C.SOL_PACKET, C.PACKET_FANOUT, unsafe.Pointer(&arg), C.socklen_t(unsafe.Sizeof(arg))) + return err +} + +// WritePacketData transmits a raw packet. +func (h *TPacket) WritePacketData(pkt []byte) error { + _, err := C.write(h.fd, unsafe.Pointer(&pkt[0]), C.size_t(len(pkt))) + return err +} diff --git a/vendor/github.com/google/gopacket/afpacket/header.go b/vendor/github.com/google/gopacket/afpacket/header.go new file mode 100644 index 0000000..c650836 --- /dev/null +++ b/vendor/github.com/google/gopacket/afpacket/header.go @@ -0,0 +1,137 @@ +// 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 linux + +package afpacket + +import ( + "reflect" + "time" + "unsafe" +) + +// #include +import "C" + +// Our model of handling all TPacket versions is a little hacky, to say the +// least. We use the header interface to handle interactions with the +// tpacket1/tpacket2 packet header AND the tpacket3 block header. The big +// difference is that tpacket3's block header implements the next() call to get +// the next packet within the block, while v1/v2 just always return false. + +type header interface { + // getStatus returns the TPacket status of the current header. + getStatus() int + // clearStatus clears the status of the current header, releasing its + // underlying data back to the kernel for future use with new packets. + // Using the header after calling clearStatus is an error. clearStatus + // should only be called after next() returns false. + clearStatus() + // getTime returns the timestamp for the current packet pointed to by + // the header. + getTime() time.Time + // getData returns the packet data pointed to by the current header. + getData() []byte + // getLength returns the total length of the packet. + getLength() int + // next moves this header to point to the next packet it contains, + // returning true on success (in which case getTime and getData will + // return values for the new packet) or false if there are no more + // packets (in which case clearStatus should be called). + next() bool +} + +type v1header C.struct_tpacket_hdr +type v2header C.struct_tpacket2_hdr + +func makeSlice(start uintptr, length int) (data []byte) { + slice := (*reflect.SliceHeader)(unsafe.Pointer(&data)) + slice.Data = start + slice.Len = length + slice.Cap = length + return +} + +func (h *v1header) getStatus() int { + return int(h.tp_status) +} +func (h *v1header) clearStatus() { + h.tp_status = 0 +} +func (h *v1header) getTime() time.Time { + return time.Unix(int64(h.tp_sec), int64(h.tp_usec)*1000) +} +func (h *v1header) getData() []byte { + return makeSlice(uintptr(unsafe.Pointer(h))+uintptr(h.tp_mac), int(h.tp_snaplen)) +} +func (h *v1header) getLength() int { + return int(h.tp_len) +} +func (h *v1header) next() bool { + return false +} +func (h *v2header) getStatus() int { + return int(h.tp_status) +} +func (h *v2header) clearStatus() { + h.tp_status = 0 +} +func (h *v2header) getTime() time.Time { + return time.Unix(int64(h.tp_sec), int64(h.tp_nsec)) +} +func (h *v2header) getData() []byte { + return makeSlice(uintptr(unsafe.Pointer(h))+uintptr(h.tp_mac), int(h.tp_snaplen)) +} +func (h *v2header) getLength() int { + return int(h.tp_len) +} +func (h *v2header) next() bool { + return false +} + +type v3wrapper struct { + block *C.struct_tpacket_block_desc + blockhdr *C.struct_tpacket_hdr_v1 + packet *C.struct_tpacket3_hdr + used C.__u32 +} + +func initV3Wrapper(block unsafe.Pointer) (w v3wrapper) { + w.block = (*C.struct_tpacket_block_desc)(block) + w.blockhdr = (*C.struct_tpacket_hdr_v1)(unsafe.Pointer(&w.block.hdr[0])) + w.packet = (*C.struct_tpacket3_hdr)(unsafe.Pointer(uintptr(block) + uintptr(w.blockhdr.offset_to_first_pkt))) + return +} +func (w *v3wrapper) getStatus() int { + return int(w.blockhdr.block_status) +} +func (w *v3wrapper) clearStatus() { + w.blockhdr.block_status = 0 +} +func (w *v3wrapper) getTime() time.Time { + return time.Unix(int64(w.packet.tp_sec), int64(w.packet.tp_nsec)) +} +func (w *v3wrapper) getData() []byte { + return makeSlice(uintptr(unsafe.Pointer(w.packet))+uintptr(w.packet.tp_mac), int(w.packet.tp_snaplen)) +} +func (w *v3wrapper) getLength() int { + return int(w.packet.tp_len) +} +func (w *v3wrapper) next() bool { + w.used++ + if w.used >= w.blockhdr.num_pkts { + return false + } + next := uintptr(unsafe.Pointer(w.packet)) + if w.packet.tp_next_offset != 0 { + next += uintptr(w.packet.tp_next_offset) + } else { + next += uintptr(tpacketAlign(int(w.packet.tp_snaplen) + int(w.packet.tp_mac))) + } + w.packet = (*C.struct_tpacket3_hdr)(unsafe.Pointer(next)) + return true +} diff --git a/vendor/github.com/google/gopacket/afpacket/options.go b/vendor/github.com/google/gopacket/afpacket/options.go new file mode 100644 index 0000000..bab9950 --- /dev/null +++ b/vendor/github.com/google/gopacket/afpacket/options.go @@ -0,0 +1,159 @@ +// 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 linux + +package afpacket + +import ( + "fmt" + "time" +) + +// #include +// #include +import "C" + +// OptTPacketVersion is the version of TPacket to use. +// It can be passed into NewTPacket. +type OptTPacketVersion int + +// String returns a string representation of the version, generally of the form V#. +func (t OptTPacketVersion) String() string { + switch t { + case TPacketVersion1: + return "V1" + case TPacketVersion2: + return "V2" + case TPacketVersion3: + return "V3" + case TPacketVersionHighestAvailable: + return "HighestAvailable" + } + return "InvalidVersion" +} + +// OptSockType is the socket type used to open the TPacket socket. +type OptSocketType int + +func (t OptSocketType) String() string { + switch t { + case SocketRaw: + return "SOCK_RAW" + case SocketDgram: + return "SOCK_DGRAM" + } + return "UnknownSocketType" +} + +const ( + // TPacketVersionHighestAvailable tells NewHandle to use the highest available version of tpacket the kernel has available. + // This is the default, should a version number not be given in NewHandle's options. + TPacketVersionHighestAvailable = OptTPacketVersion(-1) + TPacketVersion1 = OptTPacketVersion(C.TPACKET_V1) + TPacketVersion2 = OptTPacketVersion(C.TPACKET_V2) + TPacketVersion3 = OptTPacketVersion(C.TPACKET_V3) + tpacketVersionMax = TPacketVersion3 + tpacketVersionMin = -1 + // SocketRaw is the default socket type. It returns packet data + // including the link layer (ethernet headers, etc). + SocketRaw = OptSocketType(C.SOCK_RAW) + // SocketDgram strips off the link layer when reading packets, and adds + // the link layer back automatically on packet writes (coming soon...) + SocketDgram = OptSocketType(C.SOCK_DGRAM) +) + +// OptInterface is the specific interface to bind to. +// It can be passed into NewTPacket. +type OptInterface string + +// OptFrameSize is TPacket's tp_frame_size +// It can be passed into NewTPacket. +type OptFrameSize int + +// OptBlockSize is TPacket's tp_block_size +// It can be passed into NewTPacket. +type OptBlockSize int + +// OptNumBlocks is TPacket's tp_block_nr +// It can be passed into NewTPacket. +type OptNumBlocks int + +// OptBlockTimeout is TPacket v3's tp_retire_blk_tov. Note that it has only millisecond granularity, so must be >= 1 ms. +// It can be passed into NewTPacket. +type OptBlockTimeout time.Duration + +const ( + DefaultFrameSize = 4096 // Default value for OptFrameSize. + DefaultBlockSize = DefaultFrameSize * 128 // Default value for OptBlockSize. + DefaultNumBlocks = 128 // Default value for OptNumBlocks. + DefaultBlockTimeout = 64 * time.Millisecond // Default value for OptBlockTimeout. +) + +type options struct { + frameSize int + framesPerBlock int + blockSize int + numBlocks int + blockTimeout time.Duration + version OptTPacketVersion + socktype OptSocketType + iface string +} + +var defaultOpts = options{ + frameSize: DefaultFrameSize, + blockSize: DefaultBlockSize, + numBlocks: DefaultNumBlocks, + blockTimeout: DefaultBlockTimeout, + version: TPacketVersionHighestAvailable, + socktype: SocketRaw, +} + +func parseOptions(opts ...interface{}) (ret options, err error) { + ret = defaultOpts + for _, opt := range opts { + switch v := opt.(type) { + case OptFrameSize: + ret.frameSize = int(v) + case OptBlockSize: + ret.blockSize = int(v) + case OptNumBlocks: + ret.numBlocks = int(v) + case OptBlockTimeout: + ret.blockTimeout = time.Duration(v) + case OptTPacketVersion: + ret.version = v + case OptInterface: + ret.iface = string(v) + case OptSocketType: + ret.socktype = v + default: + err = fmt.Errorf("unknown type in options") + return + } + } + if err = ret.check(); err != nil { + return + } + ret.framesPerBlock = ret.blockSize / ret.frameSize + return +} +func (o options) check() error { + switch { + case o.blockSize%pageSize != 0: + return fmt.Errorf("block size %d must be divisible by page size %d", o.blockSize, pageSize) + case o.blockSize%o.frameSize != 0: + return fmt.Errorf("block size %d must be divisible by frame size %d", o.blockSize, o.frameSize) + case o.numBlocks < 1: + return fmt.Errorf("num blocks %d must be >= 1", o.numBlocks) + case o.blockTimeout < time.Millisecond: + return fmt.Errorf("block timeout %v must be > %v", o.blockTimeout, time.Millisecond) + case o.version < tpacketVersionMin || o.version > tpacketVersionMax: + return fmt.Errorf("tpacket version %v is invalid", o.version) + } + return nil +} diff --git a/vendor/github.com/google/gopacket/base.go b/vendor/github.com/google/gopacket/base.go new file mode 100644 index 0000000..462ca97 --- /dev/null +++ b/vendor/github.com/google/gopacket/base.go @@ -0,0 +1,148 @@ +// 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 } +func (p Payload) LayerContents() []byte { return []byte(p) } +func (p Payload) LayerPayload() []byte { return nil } +func (p Payload) Payload() []byte { return []byte(p) } +func (p Payload) String() string { return fmt.Sprintf("%d byte(s)", len(p)) } +func (p Payload) GoString() string { return LongBytesGoString([]byte(p)) } +func (p Payload) CanDecode() LayerClass { return LayerTypePayload } +func (p Payload) NextLayerType() LayerType { return LayerTypeZero } +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 nil + } + 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 } +func (p *Fragment) LayerContents() []byte { return []byte(*p) } +func (p *Fragment) LayerPayload() []byte { return nil } +func (p *Fragment) Payload() []byte { return []byte(*p) } +func (p *Fragment) String() string { return fmt.Sprintf("%d byte(s)", len(*p)) } +func (p *Fragment) CanDecode() LayerClass { return LayerTypeFragment } +func (p *Fragment) NextLayerType() LayerType { return LayerTypeZero } +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 nil + } + 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 +} diff --git a/vendor/github.com/google/gopacket/bsdbpf/bsd_bpf_sniffer.go b/vendor/github.com/google/gopacket/bsdbpf/bsd_bpf_sniffer.go new file mode 100644 index 0000000..6cb840c --- /dev/null +++ b/vendor/github.com/google/gopacket/bsdbpf/bsd_bpf_sniffer.go @@ -0,0 +1,214 @@ +// 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 darwin dragonfly freebsd netbsd openbsd + +package bsdbpf + +import ( + "github.com/google/gopacket" + "golang.org/x/sys/unix" + + "fmt" + "syscall" + "time" + "unsafe" +) + +const wordSize = int(unsafe.Sizeof(uintptr(0))) + +func bpfWordAlign(x int) int { + return (((x) + (wordSize - 1)) &^ (wordSize - 1)) +} + +// Options is used to configure various properties of the BPF sniffer. +// Default values are used when a nil Options pointer is passed to NewBPFSniffer. +type Options struct { + // BPFDeviceName is name of the bpf device to use for sniffing + // the network device. The default value of BPFDeviceName is empty string + // which causes the first available BPF device file /dev/bpfX to be used. + BPFDeviceName string + // ReadBufLen specifies the size of the buffer used to read packets + // off the wire such that multiple packets are buffered with each read syscall. + // Note that an individual packet larger than the buffer size is necessarily truncated. + // A larger buffer should increase performance because fewer read syscalls would be made. + // If zero is used, the system's default buffer length will be used which depending on the + // system may default to 4096 bytes which is not big enough to accomodate some link layers + // such as WLAN (802.11). + // ReadBufLen defaults to 32767... however typical BSD manual pages for BPF indicate that + // if the requested buffer size cannot be accommodated, the closest allowable size will be + // set and returned... hence our GetReadBufLen method. + ReadBufLen int + // Timeout is the length of time to wait before timing out on a read request. + // Timeout defaults to nil which means no timeout is used. + Timeout *syscall.Timeval + // Promisc is set to true for promiscuous mode ethernet sniffing. + // Promisc defaults to true. + Promisc bool + // Immediate is set to true to make our read requests return as soon as a packet becomes available. + // Otherwise, a read will block until either the kernel buffer becomes full or a timeout occurs. + // The default is true. + Immediate bool + // PreserveLinkAddr is set to false if the link level source address should be filled in automatically + // by the interface output routine. Set to true if the link level source address will be written, + // as provided, to the wire. + // The default is true. + PreserveLinkAddr bool +} + +var defaultOptions = Options{ + BPFDeviceName: "", + ReadBufLen: 32767, + Timeout: nil, + Promisc: true, + Immediate: true, + PreserveLinkAddr: true, +} + +// BPFSniffer is a struct used to track state of a BSD BPF ethernet sniffer +// such that gopacket's PacketDataSource interface is implemented. +type BPFSniffer struct { + options *Options + sniffDeviceName string + fd int + readBuffer []byte + lastReadLen int + readBytesConsumed int +} + +// NewBPFSniffer is used to create BSD-only BPF ethernet sniffer +// iface is the network interface device name that you wish to sniff +// options can set to nil in order to utilize default values for everything. +// Each field of Options also have a default setting if left unspecified by +// the user's custome Options struct. +func NewBPFSniffer(iface string, options *Options) (*BPFSniffer, error) { + var err error + enable := 1 + sniffer := BPFSniffer{ + sniffDeviceName: iface, + } + if options == nil { + sniffer.options = &defaultOptions + } else { + sniffer.options = options + } + + if sniffer.options.BPFDeviceName == "" { + sniffer.pickBpfDevice() + } + + // setup our read buffer + if sniffer.options.ReadBufLen == 0 { + sniffer.options.ReadBufLen, err = syscall.BpfBuflen(sniffer.fd) + if err != nil { + return nil, err + } + } else { + sniffer.options.ReadBufLen, err = syscall.SetBpfBuflen(sniffer.fd, sniffer.options.ReadBufLen) + if err != nil { + return nil, err + } + } + sniffer.readBuffer = make([]byte, sniffer.options.ReadBufLen) + + err = syscall.SetBpfInterface(sniffer.fd, sniffer.sniffDeviceName) + if err != nil { + return nil, err + } + + if sniffer.options.Immediate { + // turn immediate mode on. This makes the snffer non-blocking. + err = syscall.SetBpfImmediate(sniffer.fd, enable) + if err != nil { + return nil, err + } + } + + // the above call to syscall.SetBpfImmediate needs to be made + // before setting a timer otherwise the reads will block for the + // entire timer duration even if there are packets to return. + if sniffer.options.Timeout != nil { + err = syscall.SetBpfTimeout(sniffer.fd, sniffer.options.Timeout) + if err != nil { + return nil, err + } + } + + if sniffer.options.PreserveLinkAddr { + // preserves the link level source address... + // higher level protocol analyzers will not need this + err = syscall.SetBpfHeadercmpl(sniffer.fd, enable) + if err != nil { + return nil, err + } + } + + if sniffer.options.Promisc { + // forces the interface into promiscuous mode + err = syscall.SetBpfPromisc(sniffer.fd, enable) + if err != nil { + return nil, err + } + } + + return &sniffer, nil +} + +// Close is used to close the file-descriptor of the BPF device file. +func (b *BPFSniffer) Close() error { + return syscall.Close(b.fd) +} + +func (b *BPFSniffer) pickBpfDevice() { + var err error + b.options.BPFDeviceName = "" + for i := 0; i < 99; i++ { + b.options.BPFDeviceName = fmt.Sprintf("/dev/bpf%d", i) + b.fd, err = syscall.Open(b.options.BPFDeviceName, syscall.O_RDWR, 0) + if err == nil { + return + } + } + panic("failed to acquire a BPF device for read-write access") +} + +func (b *BPFSniffer) ReadPacketData() ([]byte, gopacket.CaptureInfo, error) { + var err error + if b.readBytesConsumed >= b.lastReadLen { + b.readBytesConsumed = 0 + b.readBuffer = make([]byte, b.options.ReadBufLen) + b.lastReadLen, err = syscall.Read(b.fd, b.readBuffer) + if err != nil { + b.lastReadLen = 0 + return nil, gopacket.CaptureInfo{}, err + } + } + hdr := (*unix.BpfHdr)(unsafe.Pointer(&b.readBuffer[b.readBytesConsumed])) + frameStart := b.readBytesConsumed + int(hdr.Hdrlen) + b.readBytesConsumed += bpfWordAlign(int(hdr.Hdrlen) + int(hdr.Caplen)) + + if frameStart+int(hdr.Caplen) > len(b.readBuffer) { + captureInfo := gopacket.CaptureInfo{ + Timestamp: time.Unix(int64(hdr.Tstamp.Sec), int64(hdr.Tstamp.Usec)*1000), + CaptureLength: 0, + Length: 0, + } + return nil, captureInfo, fmt.Errorf("BPF captured frame received with corrupted BpfHdr struct.") + } + + rawFrame := b.readBuffer[frameStart : frameStart+int(hdr.Caplen)] + captureInfo := gopacket.CaptureInfo{ + Timestamp: time.Unix(int64(hdr.Tstamp.Sec), int64(hdr.Tstamp.Usec)*1000), + CaptureLength: len(rawFrame), + Length: len(rawFrame), + } + return rawFrame, captureInfo, nil +} + +// GetReadBufLen returns the BPF read buffer length +func (b *BPFSniffer) GetReadBufLen() int { + return b.options.ReadBufLen +} diff --git a/vendor/github.com/google/gopacket/bytediff/bytediff.go b/vendor/github.com/google/gopacket/bytediff/bytediff.go new file mode 100644 index 0000000..63addd9 --- /dev/null +++ b/vendor/github.com/google/gopacket/bytediff/bytediff.go @@ -0,0 +1,217 @@ +// 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 bytediff provides a simple diff utility for looking at differences in byte +// slices. It's slow, clunky, and not particularly good by any measure, but +// it does provide very useful visualizations for diffs between small byte +// slices. +// +// Our diff algorithm uses a dynamic programming implementation of longest common +// substring to find matching parts of slices, then recursively calls itself on +// the prefix/suffix of that matching part for each packet. This is a Bad Idea +// (tm) for normal (especially large) input, but for packets where large portions +// repeat frequently and we expect minor changes between results, it's actually +// quite useful. +package bytediff + +import ( + "bytes" + "fmt" +) + +// OutputFormat tells a Differences.String call how to format the set of +// differences into a human-readable string. Its internals are currently +// unexported because we may want to change them drastically in the future. For +// the moment, please just use one of the provided OutputFormats that comes with +// this library. +type OutputFormat struct { + start, finish, add, remove, change, reset string +} + +var ( + // BashOutput uses bash escape sequences to color output. + BashOutput = &OutputFormat{ + reset: "\033[0m", + remove: "\033[32m", + add: "\033[31m", + change: "\033[33m", + } + // HTMLOutput uses a
 to wrap output, and s to color it.
+	// HTMLOutput is pretty experimental, so use at your own risk ;)
+	HTMLOutput = &OutputFormat{
+		start:  "
",
+		finish: "
", + reset: "
", + remove: "", + add: "", + change: "", + } +) + +// longestCommonSubstring uses a O(MN) dynamic programming approach to find the +// longest common substring in a set of slices. It returns the index in each +// slice at which the substring begins, plus the length of the commonality. +func longestCommonSubstring(strA, strB []byte) (indexA, indexB, length int) { + lenA, lenB := len(strA), len(strB) + if lenA == 0 || lenB == 0 { + return 0, 0, 0 + } + arr := make([][]int, lenA) + for i := 0; i < lenA; i++ { + arr[i] = make([]int, lenB) + } + var maxLength int + var maxA, maxB int + for a := 0; a < lenA; a++ { + for b := 0; b < lenB; b++ { + if strA[a] == strB[b] { + length := 1 + if a > 0 && b > 0 { + length = arr[a-1][b-1] + 1 + } + arr[a][b] = length + if length > maxLength { + maxLength = length + maxA = a + maxB = b + } + } + } + } + a, b := maxA, maxB + for a >= 0 && b >= 0 && strA[a] == strB[b] { + indexA = a + indexB = b + a-- + b-- + length++ + } + return +} + +func intMax(a, b int) int { + if a > b { + return a + } + return b +} + +// Difference represents a single part of the data being diffed, containing +// information about both the original and new values. +// From and To are the sets of bytes in the original and the new byte slice. +// !Replace implies From == To (no change) +// len(To) == 0 implies From is being deleted +// len(From) == 0 implies To is being inserted +// else implies From is being replaced by To +type Difference struct { + Replace bool + From, To []byte +} + +// color returns the bash color for a given difference. +func (c *OutputFormat) color(d Difference) string { + switch { + case !d.Replace: + return "" + case len(d.From) == 0: + return c.remove + case len(d.To) == 0: + return c.add + default: + return c.change + } +} + +// Diff diffs strA and strB, returning a list of differences which +// can be used to construct either the original or new string. +// +// Diff is optimized for comparing VERY SHORT slices. It's meant for comparing +// things like packets off the wire, not large files or the like. +// As such, its runtime can be catastrophic if large inputs are passed in. +// You've been warned. +func Diff(strA, strB []byte) Differences { + if len(strA) == 0 && len(strB) == 0 { + return nil + } + ia, ib, l := longestCommonSubstring(strA, strB) + if l == 0 { + return Differences{ + Difference{true, strA, strB}, + } + } + beforeA, match, afterA := strA[:ia], strA[ia:ia+l], strA[ia+l:] + beforeB, afterB := strB[:ib], strB[ib+l:] + var diffs Differences + diffs = append(diffs, Diff(beforeA, beforeB)...) + diffs = append(diffs, Difference{false, match, match}) + diffs = append(diffs, Diff(afterA, afterB)...) + return diffs +} + +// Differences is a set of differences for a given diff'd pair of byte slices. +type Differences []Difference + +// String outputs a previously diff'd set of strings, showing differences +// between them, highlighted by colors. +// +// The output format of this function is NOT guaranteed consistent, and may be +// changed at any time by the library authors. It's meant solely for human +// consumption. +func (c *OutputFormat) String(diffs Differences) string { + var buf bytes.Buffer + count := 0 + fmt.Fprintf(&buf, "%s", c.start) + fmt.Fprintf(&buf, "00000000 ") + for i := 0; i < len(diffs); i++ { + diff := diffs[i] + color := c.color(diff) + reset := "" + if color != "" { + reset = c.reset + } + fmt.Fprint(&buf, color) + for _, b := range diff.From { + fmt.Fprintf(&buf, " %02x", b) + count++ + switch count % 16 { + case 0: + fmt.Fprintf(&buf, "%v\n%08x%v ", reset, count, color) + case 8: + fmt.Fprintf(&buf, " ") + } + } + fmt.Fprint(&buf, reset) + } + fmt.Fprintf(&buf, "\n\n00000000 ") + count = 0 + for i := 0; i < len(diffs); i++ { + diff := diffs[i] + str := diff.From + if diff.Replace { + str = diff.To + } + color := c.color(diff) + reset := "" + if color != "" { + reset = c.reset + } + fmt.Fprint(&buf, color) + for _, b := range str { + fmt.Fprintf(&buf, " %02x", b) + count++ + switch count % 16 { + case 0: + fmt.Fprintf(&buf, "%v\n%08x%v ", reset, count, color) + case 8: + fmt.Fprintf(&buf, " ") + } + } + fmt.Fprint(&buf, reset) + } + fmt.Fprint(&buf, "\n") + fmt.Fprintf(&buf, "%s", c.finish) + return string(buf.Bytes()) +} diff --git a/vendor/github.com/google/gopacket/decode.go b/vendor/github.com/google/gopacket/decode.go new file mode 100644 index 0000000..dc390d6 --- /dev/null +++ b/vendor/github.com/google/gopacket/decode.go @@ -0,0 +1,146 @@ +// 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() +} + +// 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 + +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 LayerType = RegisterLayerType(0, LayerTypeMetadata{"Unknown", DecodeUnknown}) + +// LayerTypeDecodeFailure is the layer type for the default error layer. +var LayerTypeDecodeFailure LayerType = RegisterLayerType(1, LayerTypeMetadata{"DecodeFailure", 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 LayerType = RegisterLayerType(2, LayerTypeMetadata{"Payload", DecodePayload}) + +// LayerTypeFragment is the layer type for a fragment of a layer transported +// by an underlying layer that supports fragmentation. +var LayerTypeFragment LayerType = RegisterLayerType(3, LayerTypeMetadata{"Fragment", 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 } +func (d *DecodeFailure) LayerContents() []byte { return d.data } +func (d *DecodeFailure) LayerPayload() []byte { return nil } +func (d *DecodeFailure) String() string { + return "Packet decoding error: " + d.Error().Error() +} +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") +} diff --git a/vendor/github.com/google/gopacket/doc.go b/vendor/github.com/google/gopacket/doc.go new file mode 100644 index 0000000..257d9da --- /dev/null +++ b/vendor/github.com/google/gopacket/doc.go @@ -0,0 +1,365 @@ +// 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. + +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 symetric: 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, "MyLayerType", gopacket.DecodeFunc(decodeMyLayer)) + + // Implement my layer + type MyLayer struct { + StrangeHeader []byte + payload []byte + } + func (m MyLayer) LayerType() 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() { + err := parser.DecodeLayers(packetDat, &decoded) + 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. + + +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 diff --git a/vendor/github.com/google/gopacket/dumpcommand/tcpdump.go b/vendor/github.com/google/gopacket/dumpcommand/tcpdump.go new file mode 100644 index 0000000..65c74e1 --- /dev/null +++ b/vendor/github.com/google/gopacket/dumpcommand/tcpdump.go @@ -0,0 +1,117 @@ +// 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 dumpcommand implements a run function for pfdump and pcapdump +// with many similar flags/features to tcpdump. This code is split out seperate +// from data sources (pcap/pfring) so it can be used by both. +package dumpcommand + +import ( + "flag" + "fmt" + "github.com/google/gopacket" + "github.com/google/gopacket/ip4defrag" + "github.com/google/gopacket/layers" // pulls in all layers decoders + "log" + "os" + "time" +) + +var ( + print = flag.Bool("print", true, "Print out packets, if false only prints out statistics") + maxcount = flag.Int("c", -1, "Only grab this many packets, then exit") + decoder = flag.String("decoder", "Ethernet", "Name of the decoder to use") + dump = flag.Bool("X", false, "If true, dump very verbose info on each packet") + statsevery = flag.Int("stats", 1000, "Output statistics every N packets") + printErrors = flag.Bool("errors", false, "Print out packet dumps of decode errors, useful for checking decoders against live traffic") + lazy = flag.Bool("lazy", false, "If true, do lazy decoding") + defrag = flag.Bool("defrag", false, "If true, do IPv4 defrag") +) + +func Run(src gopacket.PacketDataSource) { + if !flag.Parsed() { + log.Fatalln("Run called without flags.Parse() being called") + } + var dec gopacket.Decoder + var ok bool + if dec, ok = gopacket.DecodersByLayerName[*decoder]; !ok { + log.Fatalln("No decoder named", *decoder) + } + source := gopacket.NewPacketSource(src, dec) + source.Lazy = *lazy + source.NoCopy = true + fmt.Fprintln(os.Stderr, "Starting to read packets") + count := 0 + bytes := int64(0) + start := time.Now() + errors := 0 + truncated := 0 + layertypes := map[gopacket.LayerType]int{} + defragger := ip4defrag.NewIPv4Defragmenter() + + for packet := range source.Packets() { + count++ + bytes += int64(len(packet.Data())) + + // defrag the IPv4 packet if required + if *defrag { + ip4Layer := packet.Layer(layers.LayerTypeIPv4) + if ip4Layer == nil { + continue + } + ip4 := ip4Layer.(*layers.IPv4) + l := ip4.Length + + newip4, err := defragger.DefragIPv4(ip4) + if err != nil { + log.Fatalln("Error while de-fragmenting", err) + } else if newip4 == nil { + continue // packet fragment, we don't have whole packet yet. + } + if newip4.Length != l { + fmt.Printf("Decoding re-assembled packet: %s\n", newip4.NextLayerType()) + pb, ok := packet.(gopacket.PacketBuilder) + if !ok { + panic("Not a PacketBuilder") + } + nextDecoder := newip4.NextLayerType() + nextDecoder.Decode(newip4.Payload, pb) + } + } + + if *dump { + fmt.Println(packet.Dump()) + } else if *print { + fmt.Println(packet) + } + if !*lazy || *print || *dump { // if we've already decoded all layers... + for _, layer := range packet.Layers() { + layertypes[layer.LayerType()]++ + } + if packet.Metadata().Truncated { + truncated++ + } + if errLayer := packet.ErrorLayer(); errLayer != nil { + errors++ + if *printErrors { + fmt.Println("Error:", errLayer.Error()) + fmt.Println("--- Packet ---") + fmt.Println(packet.Dump()) + } + } + } + done := *maxcount > 0 && count >= *maxcount + if count%*statsevery == 0 || done { + fmt.Fprintf(os.Stderr, "Processed %v packets (%v bytes) in %v, %v errors and %v truncated packets\n", count, bytes, time.Since(start), errors, truncated) + if len(layertypes) > 0 { + fmt.Fprintf(os.Stderr, "Layer types seen: %+v\n", layertypes) + } + } + if done { + break + } + } +} diff --git a/vendor/github.com/google/gopacket/examples/arpscan/arpscan.go b/vendor/github.com/google/gopacket/examples/arpscan/arpscan.go new file mode 100644 index 0000000..0196529 --- /dev/null +++ b/vendor/github.com/google/gopacket/examples/arpscan/arpscan.go @@ -0,0 +1,188 @@ +// 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. + +// arpscan implements ARP scanning of all interfaces' local networks using +// gopacket and its subpackages. This example shows, among other things: +// * Generating and sending packet data +// * Reading in packet data and interpreting it +// * Use of the 'pcap' subpackage for reading/writing +package main + +import ( + "bytes" + "encoding/binary" + "fmt" + "log" + "net" + "sync" + "time" + + "github.com/google/gopacket" + "github.com/google/gopacket/layers" + "github.com/google/gopacket/pcap" +) + +func main() { + // Get a list of all interfaces. + ifaces, err := net.Interfaces() + if err != nil { + panic(err) + } + + var wg sync.WaitGroup + for _, iface := range ifaces { + wg.Add(1) + // Start up a scan on each interface. + go func(iface net.Interface) { + defer wg.Done() + if err := scan(&iface); err != nil { + log.Printf("interface %v: %v", iface.Name, err) + } + }(iface) + } + // Wait for all interfaces' scans to complete. They'll try to run + // forever, but will stop on an error, so if we get past this Wait + // it means all attempts to write have failed. + wg.Wait() +} + +// scan scans an individual interface's local network for machines using ARP requests/replies. +// +// scan loops forever, sending packets out regularly. It returns an error if +// it's ever unable to write a packet. +func scan(iface *net.Interface) error { + // We just look for IPv4 addresses, so try to find if the interface has one. + var addr *net.IPNet + if addrs, err := iface.Addrs(); err != nil { + return err + } else { + for _, a := range addrs { + if ipnet, ok := a.(*net.IPNet); ok { + if ip4 := ipnet.IP.To4(); ip4 != nil { + addr = &net.IPNet{ + IP: ip4, + Mask: ipnet.Mask[len(ipnet.Mask)-4:], + } + break + } + } + } + } + // Sanity-check that the interface has a good address. + if addr == nil { + return fmt.Errorf("no good IP network found") + } else if addr.IP[0] == 127 { + return fmt.Errorf("skipping localhost") + } else if addr.Mask[0] != 0xff || addr.Mask[1] != 0xff { + return fmt.Errorf("mask means network is too large") + } + log.Printf("Using network range %v for interface %v", addr, iface.Name) + + // Open up a pcap handle for packet reads/writes. + handle, err := pcap.OpenLive(iface.Name, 65536, true, pcap.BlockForever) + if err != nil { + return err + } + defer handle.Close() + + // Start up a goroutine to read in packet data. + stop := make(chan struct{}) + go readARP(handle, iface, stop) + defer close(stop) + for { + // Write our scan packets out to the handle. + if err := writeARP(handle, iface, addr); err != nil { + log.Printf("error writing packets on %v: %v", iface.Name, err) + return err + } + // We don't know exactly how long it'll take for packets to be + // sent back to us, but 10 seconds should be more than enough + // time ;) + time.Sleep(10 * time.Second) + } +} + +// readARP watches a handle for incoming ARP responses we might care about, and prints them. +// +// readARP loops until 'stop' is closed. +func readARP(handle *pcap.Handle, iface *net.Interface, stop chan struct{}) { + src := gopacket.NewPacketSource(handle, layers.LayerTypeEthernet) + in := src.Packets() + for { + var packet gopacket.Packet + select { + case <-stop: + return + case packet = <-in: + arpLayer := packet.Layer(layers.LayerTypeARP) + if arpLayer == nil { + continue + } + arp := arpLayer.(*layers.ARP) + if arp.Operation != layers.ARPReply || bytes.Equal([]byte(iface.HardwareAddr), arp.SourceHwAddress) { + // This is a packet I sent. + continue + } + // Note: we might get some packets here that aren't responses to ones we've sent, + // if for example someone else sends US an ARP request. Doesn't much matter, though... + // all information is good information :) + log.Printf("IP %v is at %v", net.IP(arp.SourceProtAddress), net.HardwareAddr(arp.SourceHwAddress)) + } + } +} + +// writeARP writes an ARP request for each address on our local network to the +// pcap handle. +func writeARP(handle *pcap.Handle, iface *net.Interface, addr *net.IPNet) error { + // Set up all the layers' fields we can. + eth := layers.Ethernet{ + SrcMAC: iface.HardwareAddr, + DstMAC: net.HardwareAddr{0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, + EthernetType: layers.EthernetTypeARP, + } + arp := layers.ARP{ + AddrType: layers.LinkTypeEthernet, + Protocol: layers.EthernetTypeIPv4, + HwAddressSize: 6, + ProtAddressSize: 4, + Operation: layers.ARPRequest, + SourceHwAddress: []byte(iface.HardwareAddr), + SourceProtAddress: []byte(addr.IP), + DstHwAddress: []byte{0, 0, 0, 0, 0, 0}, + } + // Set up buffer and options for serialization. + buf := gopacket.NewSerializeBuffer() + opts := gopacket.SerializeOptions{ + FixLengths: true, + ComputeChecksums: true, + } + // Send one packet for every address. + for _, ip := range ips(addr) { + arp.DstProtAddress = []byte(ip) + gopacket.SerializeLayers(buf, opts, ð, &arp) + if err := handle.WritePacketData(buf.Bytes()); err != nil { + return err + } + } + return nil +} + +// ips is a simple and not very good method for getting all IPv4 addresses from a +// net.IPNet. It returns all IPs it can over the channel it sends back, closing +// the channel when done. +func ips(n *net.IPNet) (out []net.IP) { + num := binary.BigEndian.Uint32([]byte(n.IP)) + mask := binary.BigEndian.Uint32([]byte(n.Mask)) + num &= mask + for mask < 0xffffffff { + var buf [4]byte + binary.BigEndian.PutUint32(buf[:], num) + out = append(out, net.IP(buf[:])) + mask += 1 + num += 1 + } + return +} diff --git a/vendor/github.com/google/gopacket/examples/bidirectional/main.go b/vendor/github.com/google/gopacket/examples/bidirectional/main.go new file mode 100644 index 0000000..4b0b240 --- /dev/null +++ b/vendor/github.com/google/gopacket/examples/bidirectional/main.go @@ -0,0 +1,192 @@ +// 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. + +// This binary provides an example of connecting up bidirectional streams from +// the unidirectional streams provided by gopacket/tcpassembly. +package main + +import ( + "flag" + "fmt" + "github.com/google/gopacket" + "github.com/google/gopacket/examples/util" + "github.com/google/gopacket/layers" + "github.com/google/gopacket/pcap" + "github.com/google/gopacket/tcpassembly" + "log" + "time" +) + +var iface = flag.String("i", "eth0", "Interface to get packets from") +var snaplen = flag.Int("s", 16<<10, "SnapLen for pcap packet capture") +var filter = flag.String("f", "tcp", "BPF filter for pcap") +var logAllPackets = flag.Bool("v", false, "Logs every packet in great detail") + +// key is used to map bidirectional streams to each other. +type key struct { + net, transport gopacket.Flow +} + +// String prints out the key in a human-readable fashion. +func (k key) String() string { + return fmt.Sprintf("%v:%v", k.net, k.transport) +} + +// timeout is the length of time to wait befor flushing connections and +// bidirectional stream pairs. +const timeout time.Duration = time.Minute * 5 + +// myStream implements tcpassembly.Stream +type myStream struct { + bytes int64 // total bytes seen on this stream. + bidi *bidi // maps to my bidirectional twin. + done bool // if true, we've seen the last packet we're going to for this stream. +} + +// bidi stores each unidirectional side of a bidirectional stream. +// +// When a new stream comes in, if we don't have an opposite stream, a bidi is +// created with 'a' set to the new stream. If we DO have an opposite stream, +// 'b' is set to the new stream. +type bidi struct { + key key // Key of the first stream, mostly for logging. + a, b *myStream // the two bidirectional streams. + lastPacketSeen time.Time // last time we saw a packet from either stream. +} + +// myFactory implements tcpassmebly.StreamFactory +type myFactory struct { + // bidiMap maps keys to bidirectional stream pairs. + bidiMap map[key]*bidi +} + +// New handles creating a new tcpassembly.Stream. +func (f *myFactory) New(netFlow, tcpFlow gopacket.Flow) tcpassembly.Stream { + // Create a new stream. + s := &myStream{} + + // Find the bidi bidirectional struct for this stream, creating a new one if + // one doesn't already exist in the map. + k := key{netFlow, tcpFlow} + bd := f.bidiMap[k] + if bd == nil { + bd = &bidi{a: s, key: k} + log.Printf("[%v] created first side of bidirectional stream", bd.key) + // Register bidirectional with the reverse key, so the matching stream going + // the other direction will find it. + f.bidiMap[key{netFlow.Reverse(), tcpFlow.Reverse()}] = bd + } else { + log.Printf("[%v] found second side of bidirectional stream", bd.key) + bd.b = s + // Clear out the bidi we're using from the map, just in case. + delete(f.bidiMap, k) + } + s.bidi = bd + return s +} + +// emptyStream is used to finish bidi that only have one stream, in +// collectOldStreams. +var emptyStream = &myStream{done: true} + +// collectOldStreams finds any streams that haven't received a packet within +// 'timeout', and sets/finishes the 'b' stream inside them. The 'a' stream may +// still receive packets after this. +func (f *myFactory) collectOldStreams() { + cutoff := time.Now().Add(-timeout) + for k, bd := range f.bidiMap { + if bd.lastPacketSeen.Before(cutoff) { + log.Printf("[%v] timing out old stream", bd.key) + bd.b = emptyStream // stub out b with an empty stream. + delete(f.bidiMap, k) // remove it from our map. + bd.maybeFinish() // if b was the last stream we were waiting for, finish up. + } + } +} + +// Reassembled handles reassembled TCP stream data. +func (s *myStream) Reassembled(rs []tcpassembly.Reassembly) { + for _, r := range rs { + // For now, we'll simply count the bytes on each side of the TCP stream. + s.bytes += int64(len(r.Bytes)) + if r.Skip > 0 { + s.bytes += int64(r.Skip) + } + // Mark that we've received new packet data. + // We could just use time.Now, but by using r.Seen we handle the case + // where packets are being read from a file and could be very old. + if s.bidi.lastPacketSeen.After(r.Seen) { + s.bidi.lastPacketSeen = r.Seen + } + } +} + +// ReassemblyComplete marks this stream as finished. +func (s *myStream) ReassemblyComplete() { + s.done = true + s.bidi.maybeFinish() +} + +// maybeFinish will wait until both directions are complete, then print out +// stats. +func (bd *bidi) maybeFinish() { + switch { + case bd.a == nil: + log.Fatalf("[%v] a should always be non-nil, since it's set when bidis are created", bd.key) + case !bd.a.done: + log.Printf("[%v] still waiting on first stream", bd.key) + case bd.b == nil: + log.Printf("[%v] no second stream yet", bd.key) + case !bd.b.done: + log.Printf("[%v] still waiting on second stream", bd.key) + default: + log.Printf("[%v] FINISHED, bytes: %d tx, %d rx", bd.key, bd.a.bytes, bd.b.bytes) + } +} + +func main() { + defer util.Run()() + log.Printf("starting capture on interface %q", *iface) + // Set up pcap packet capture + handle, err := pcap.OpenLive(*iface, int32(*snaplen), true, pcap.BlockForever) + if err != nil { + panic(err) + } + if err := handle.SetBPFFilter(*filter); err != nil { + panic(err) + } + + // Set up assembly + streamFactory := &myFactory{bidiMap: make(map[key]*bidi)} + streamPool := tcpassembly.NewStreamPool(streamFactory) + assembler := tcpassembly.NewAssembler(streamPool) + + log.Println("reading in packets") + // Read in packets, pass to assembler. + packetSource := gopacket.NewPacketSource(handle, handle.LinkType()) + packets := packetSource.Packets() + ticker := time.Tick(timeout / 4) + for { + select { + case packet := <-packets: + if *logAllPackets { + log.Println(packet) + } + if packet.NetworkLayer() == nil || packet.TransportLayer() == nil || packet.TransportLayer().LayerType() != layers.LayerTypeTCP { + log.Println("Unusable packet") + continue + } + tcp := packet.TransportLayer().(*layers.TCP) + assembler.AssembleWithTimestamp(packet.NetworkLayer().NetworkFlow(), tcp, packet.Metadata().Timestamp) + + case <-ticker: + // Every minute, flush connections that haven't seen activity in the past minute. + log.Println("---- FLUSHING ----") + assembler.FlushOlderThan(time.Now().Add(-timeout)) + streamFactory.collectOldStreams() + } + } +} diff --git a/vendor/github.com/google/gopacket/examples/bytediff/bytediff.png b/vendor/github.com/google/gopacket/examples/bytediff/bytediff.png new file mode 100644 index 0000000..5aa3c8a Binary files /dev/null and b/vendor/github.com/google/gopacket/examples/bytediff/bytediff.png differ diff --git a/vendor/github.com/google/gopacket/examples/bytediff/main.go b/vendor/github.com/google/gopacket/examples/bytediff/main.go new file mode 100644 index 0000000..2a4c11b --- /dev/null +++ b/vendor/github.com/google/gopacket/examples/bytediff/main.go @@ -0,0 +1,96 @@ +// 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. + +// This binary shows how to display byte differences to users via the bytediff +// library. +package main + +import ( + "fmt" + "github.com/google/gopacket/bytediff" +) + +var sliceA = []byte{ + 0x00, 0x00, 0x0c, 0x9f, 0xf0, 0x20, 0xbc, 0x30, 0x5b, 0xe8, 0xd3, 0x49, + 0x08, 0x00, 0x45, 0x00, 0x01, 0xa4, 0x39, 0xdf, 0x40, 0x00, 0x40, 0x06, + 0x55, 0x5a, 0xac, 0x11, 0x51, 0x49, 0xad, 0xde, 0xfe, 0xe1, 0xc5, 0xf7, + 0x00, 0x50, 0xc5, 0x7e, 0x0e, 0x48, 0x49, 0x07, 0x42, 0x32, 0x80, 0x18, + 0x00, 0x73, 0x9a, 0x8f, 0x00, 0x00, 0x01, 0x01, 0x08, 0x0a, 0x03, 0x77, + 0x37, 0x9c, 0x42, 0x77, 0x5e, 0x3a, 0x47, 0x45, 0x54, 0x20, 0x2f, 0x20, + 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31, 0x0d, 0x0a, 0x48, 0x6f, + 0x73, 0x74, 0x3a, 0x20, 0x77, 0x77, 0x77, 0x2e, 0x66, 0x69, 0x73, 0x68, + 0x2e, 0x63, 0x6f, 0x6d, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x6b, 0x65, 0x65, 0x70, 0x2d, 0x61, + 0x6c, 0x69, 0x76, 0x65, 0x0d, 0x0a, 0x55, 0x73, 0x65, 0x72, 0x2d, 0x41, + 0x67, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x4d, 0x6f, 0x7a, 0x69, 0x6c, 0x6c, + 0x61, 0x2f, 0x35, 0x2e, 0x30, 0x20, 0x28, 0x58, 0x31, 0x31, 0x3b, 0x20, + 0x4c, 0x69, 0x6e, 0x75, 0x78, 0x20, 0x78, 0x38, 0x36, 0x5f, 0x36, 0x34, + 0x29, 0x20, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x57, 0x65, 0x62, 0x4b, 0x69, + 0x74, 0x2f, 0x35, 0x33, 0x35, 0x2e, 0x32, 0x20, 0x28, 0x4b, 0x48, 0x54, + 0x4d, 0x4c, 0x2c, 0x20, 0x6c, 0x69, 0x6b, 0x65, 0x20, 0x47, 0x65, 0x63, + 0x6b, 0x6f, 0x29, 0x20, 0x43, 0x68, 0x72, 0x6f, 0x6d, 0x65, 0x2f, 0x31, + 0x35, 0x2e, 0x30, 0x2e, 0x38, 0x37, 0x34, 0x2e, 0x31, 0x32, 0x31, 0x20, + 0x53, 0x61, 0x66, 0x61, 0x72, 0x69, 0x2f, 0x35, 0x2e, 0x31, + 0x0d, 0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x3a, 0x20, 0x74, 0x65, + 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x2c, 0x61, 0x70, 0x70, 0x6c, + 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x78, 0x68, 0x74, 0x6d, + 0x6c, 0x2b, 0x78, 0x6d, 0x6c, 0x2c, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x78, 0x6d, 0x6c, 0x3b, 0x71, 0x3d, + 0x30, 0x2e, 0x39, 0x2c, 0x2a, 0x2f, 0x2a, 0x3b, 0x71, 0x3d, 0x30, 0x2e, + 0x38, 0x0d, 0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d, 0x45, 0x6e, + 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x3a, 0x20, 0x67, 0x7a, 0x69, 0x70, + 0x2c, 0x64, 0x65, 0x66, 0x6c, 0x61, 0x74, 0x65, 0x2c, 0x73, 0x64, 0x63, + 0x68, 0x0d, 0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d, 0x4c, 0x61, + 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x3a, 0x20, 0x65, 0x6e, 0x2d, 0x55, + 0x53, 0x2c, 0x65, 0x6e, 0x3b, 0x71, 0x3d, 0x30, 0x2e, 0x38, 0x0d, 0x0a, + 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d, 0x43, 0x68, 0x61, 0x72, 0x73, + 0x65, 0x74, 0x3a, 0x20, 0x49, 0x53, 0x4f, 0x2d, 0x38, 0x38, 0x35, 0x39, + 0x2d, 0x31, 0x2c, 0x75, 0x74, 0x66, 0x2d, 0x38, 0x3b, 0x71, 0x3d, 0x30, + 0x2e, 0x37, 0x2c, 0x2a, 0x3b, 0x71, 0x3d, 0x30, 0x2e, 0x33, 0x0d, 0x0a, + 0x0d, 0x0a, +} +var sliceB = []byte{ + 0x00, 0x00, 0x0c, 0x9f, 0xf0, 0x20, 0xbc, 0x30, 0x5b, 0xe8, 0xd3, 0x49, + 0x08, 0x00, 0x45, 0x00, 0x01, 0xa4, 0x39, 0xdf, 0x40, 0x00, 0x40, 0x06, + 0x55, 0x5a, 0xac, 0x11, 0x51, 0x49, 0xad, 0xde, 0xfe, 0xe1, 0xc5, 0xf7, + 0x00, 0x50, 0xc5, 0x7e, 0x0e, 0x48, 0x49, 0x07, 0x42, 0x32, 0x80, 0x18, + 0x00, 0x73, 0x9a, 0x8f, 0x00, 0x00, 0x01, 0x01, 0x08, 0x0a, 0x03, 0x77, + 0x37, 0x9c, 0x42, 0x77, 0x5e, 0x3a, 0x47, 0x45, 0x54, 0x20, 0x2f, 0x20, + 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31, 0x0d, 0x0a, 0x48, 0x6f, + 0x73, 0x74, 0x3a, 0x20, 0x77, 0x77, 0x77, 0x2e, 0x66, 0x69, 0x73, 0x68, + 0x2e, 0x63, 0x6f, 0x6d, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, + 0x6c, 0x69, 0x76, 0x65, 0x0d, 0x0a, 0x55, 0x73, 0x65, 0x72, 0x2d, 0x41, + 0x67, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x4d, 0x6f, 0x7a, 0x69, 0x6c, 0x6c, + 0x61, 0x2f, 0x35, 0x2e, 0x30, 0x20, 0x28, 0x58, 0x31, 0x31, 0x3b, 0x20, + 0x4c, 0x69, 0x6e, 0x75, 0x78, 0x20, 0x78, 0x38, 0x36, 0x5f, 0x36, 0x34, + 0x29, 0x20, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x57, 0x65, 0x62, 0x4b, 0x69, + 0x74, 0x2f, 0x35, 0x33, 0x35, 0x2e, 0x32, 0x20, 0x28, 0x4b, 0x48, 0x54, + 0x4d, 0x4c, 0x2c, 0x20, 0x6c, 0x69, 0x6b, 0x65, 0x20, 0x47, 0x65, 0x63, + 0x6b, 0x6f, 0x29, 0x20, 0x43, 0x68, 0x72, 0x6f, 0x6d, 0x65, 0x2f, 0x31, + 0x35, 0x2e, 0x30, 0x2e, 0x38, 0x37, 0x34, 0x2e, 0x31, 0x32, 0x31, 0x20, + 0x53, 0x61, 0x66, 0x61, 0x72, 0x69, 0x2f, 0x35, 0x33, 0x35, 0x2e, 0x32, + 0x0d, 0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x3a, 0x20, 0x74, 0x65, + 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x2c, 0x61, 0x70, 0x70, 0x6c, + 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x78, 0x68, 0x74, 0x6d, + 0x6c, 0x2b, 0x78, 0x6d, 0x6c, 0x2c, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x78, 0x6d, 0x6c, 0x3b, 0x71, 0x3d, + 0x30, 0x2e, 0x39, 0x2c, 0x2a, 0x2f, 0x2a, 0x3b, 0x71, 0x3d, 0x30, 0x2e, + 0x38, 0x0d, 0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d, 0x45, 0x6e, + 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x3a, 0x20, 0x67, 0x7a, 0x69, 0x70, + 0x2c, 0x64, 0x65, 0x66, 0x6c, 0x61, 0x74, 0x65, 0x2c, 0x73, 0x64, 0x63, + 0x68, 0x0d, 0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d, 0x4c, 0x61, + 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x3a, 0x20, 0x65, 0x6e, 0x2d, 0x55, + 0x53, 0x2c, 0x65, 0x6e, 0x3b, 0x71, 0x3d, 0x30, 0x2e, 0x38, 0x0d, 0x0a, + 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d, 0x43, 0x68, 0x61, 0x72, 0x73, + 0x65, 0x74, 0x3a, 0x20, 0x49, 0x53, 0x4f, 0x2e, 0x39, 0x55, 0x35, 0x39, + 0x2d, 0x31, 0x2c, 0x75, 0x74, 0x66, 0x2d, 0x38, 0x3b, 0x71, 0x3d, 0x30, + 0x2e, 0x37, 0x2c, 0x2a, 0x3b, 0x71, 0x3d, 0x30, 0x2e, 0x33, 0x0d, 0x0a, + 0x0d, 0x0a, +} + +func main() { + fmt.Println(bytediff.BashOutput.String(bytediff.Diff(sliceA, sliceB))) +} diff --git a/vendor/github.com/google/gopacket/examples/httpassembly/main.go b/vendor/github.com/google/gopacket/examples/httpassembly/main.go new file mode 100644 index 0000000..02af21e --- /dev/null +++ b/vendor/github.com/google/gopacket/examples/httpassembly/main.go @@ -0,0 +1,127 @@ +// 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. + +// This binary provides sample code for using the gopacket TCP assembler and TCP +// stream reader. It reads packets off the wire and reconstructs HTTP requests +// it sees, logging them. +package main + +import ( + "bufio" + "flag" + "io" + "log" + "net/http" + "time" + + "github.com/google/gopacket" + "github.com/google/gopacket/examples/util" + "github.com/google/gopacket/layers" + "github.com/google/gopacket/pcap" + "github.com/google/gopacket/tcpassembly" + "github.com/google/gopacket/tcpassembly/tcpreader" +) + +var iface = flag.String("i", "eth0", "Interface to get packets from") +var fname = flag.String("r", "", "Filename to read from, overrides -i") +var snaplen = flag.Int("s", 1600, "SnapLen for pcap packet capture") +var filter = flag.String("f", "tcp and dst port 80", "BPF filter for pcap") +var logAllPackets = flag.Bool("v", false, "Logs every packet in great detail") + +// Build a simple HTTP request parser using tcpassembly.StreamFactory and tcpassembly.Stream interfaces + +// httpStreamFactory implements tcpassembly.StreamFactory +type httpStreamFactory struct{} + +// httpStream will handle the actual decoding of http requests. +type httpStream struct { + net, transport gopacket.Flow + r tcpreader.ReaderStream +} + +func (h *httpStreamFactory) New(net, transport gopacket.Flow) tcpassembly.Stream { + hstream := &httpStream{ + net: net, + transport: transport, + r: tcpreader.NewReaderStream(), + } + go hstream.run() // Important... we must guarantee that data from the reader stream is read. + + // ReaderStream implements tcpassembly.Stream, so we can return a pointer to it. + return &hstream.r +} + +func (h *httpStream) run() { + buf := bufio.NewReader(&h.r) + for { + req, err := http.ReadRequest(buf) + if err == io.EOF { + // We must read until we see an EOF... very important! + return + } else if err != nil { + log.Println("Error reading stream", h.net, h.transport, ":", err) + } else { + bodyBytes := tcpreader.DiscardBytesToEOF(req.Body) + req.Body.Close() + log.Println("Received request from stream", h.net, h.transport, ":", req, "with", bodyBytes, "bytes in request body") + } + } +} + +func main() { + defer util.Run()() + var handle *pcap.Handle + var err error + + // Set up pcap packet capture + if *fname != "" { + log.Printf("Reading from pcap dump %q", *fname) + handle, err = pcap.OpenOffline(*fname) + } else { + log.Printf("Starting capture on interface %q", *iface) + handle, err = pcap.OpenLive(*iface, int32(*snaplen), true, pcap.BlockForever) + } + if err != nil { + log.Fatal(err) + } + + if err := handle.SetBPFFilter(*filter); err != nil { + log.Fatal(err) + } + + // Set up assembly + streamFactory := &httpStreamFactory{} + streamPool := tcpassembly.NewStreamPool(streamFactory) + assembler := tcpassembly.NewAssembler(streamPool) + + log.Println("reading in packets") + // Read in packets, pass to assembler. + packetSource := gopacket.NewPacketSource(handle, handle.LinkType()) + packets := packetSource.Packets() + ticker := time.Tick(time.Minute) + for { + select { + case packet := <-packets: + // A nil packet indicates the end of a pcap file. + if packet == nil { + return + } + if *logAllPackets { + log.Println(packet) + } + if packet.NetworkLayer() == nil || packet.TransportLayer() == nil || packet.TransportLayer().LayerType() != layers.LayerTypeTCP { + log.Println("Unusable packet") + continue + } + tcp := packet.TransportLayer().(*layers.TCP) + assembler.AssembleWithTimestamp(packet.NetworkLayer().NetworkFlow(), tcp, packet.Metadata().Timestamp) + + case <-ticker: + // Every minute, flush connections that haven't seen activity in the past 2 minutes. + assembler.FlushOlderThan(time.Now().Add(time.Minute * -2)) + } + } +} diff --git a/vendor/github.com/google/gopacket/examples/pcapdump/main.go b/vendor/github.com/google/gopacket/examples/pcapdump/main.go new file mode 100644 index 0000000..9445723 --- /dev/null +++ b/vendor/github.com/google/gopacket/examples/pcapdump/main.go @@ -0,0 +1,73 @@ +// 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. + +// The pcapdump binary implements a tcpdump-like command line tool with gopacket +// using pcap as a backend data collection mechanism. +package main + +import ( + "flag" + "fmt" + "github.com/google/gopacket/dumpcommand" + "github.com/google/gopacket/examples/util" + "github.com/google/gopacket/pcap" + "log" + "os" + "strings" + "time" +) + +var iface = flag.String("i", "eth0", "Interface to read packets from") +var fname = flag.String("r", "", "Filename to read from, overrides -i") +var snaplen = flag.Int("s", 65536, "Snap length (number of bytes max to read per packet") +var tstype = flag.String("timestamp_type", "", "Type of timestamps to use") +var promisc = flag.Bool("promisc", true, "Set promiscuous mode") + +func main() { + defer util.Run()() + var handle *pcap.Handle + var err error + if *fname != "" { + if handle, err = pcap.OpenOffline(*fname); err != nil { + log.Fatal("PCAP OpenOffline error:", err) + } + } else { + // This is a little complicated because we want to allow all possible options + // for creating the packet capture handle... instead of all this you can + // just call pcap.OpenLive if you want a simple handle. + inactive, err := pcap.NewInactiveHandle(*iface) + if err != nil { + log.Fatal("could not create: %v", err) + } + defer inactive.CleanUp() + if err = inactive.SetSnapLen(*snaplen); err != nil { + log.Fatal("could not set snap length: %v", err) + } else if err = inactive.SetPromisc(*promisc); err != nil { + log.Fatal("could not set promisc mode: %v", err) + } else if err = inactive.SetTimeout(time.Second); err != nil { + log.Fatal("could not set timeout: %v", err) + } + if *tstype != "" { + if t, err := pcap.TimestampSourceFromString(*tstype); err != nil { + log.Fatalf("Supported timestamp types: %v", inactive.SupportedTimestamps()) + } else if err := inactive.SetTimestampSource(t); err != nil { + log.Fatalf("Supported timestamp types: %v", inactive.SupportedTimestamps()) + } + } + if handle, err = inactive.Activate(); err != nil { + log.Fatal("PCAP Activate error:", err) + } + defer handle.Close() + if len(flag.Args()) > 0 { + bpffilter := strings.Join(flag.Args(), " ") + fmt.Fprintf(os.Stderr, "Using BPF filter %q\n", bpffilter) + if err = handle.SetBPFFilter(bpffilter); err != nil { + log.Fatal("BPF filter error:", err) + } + } + } + dumpcommand.Run(handle) +} diff --git a/vendor/github.com/google/gopacket/examples/pcaplay/main.go b/vendor/github.com/google/gopacket/examples/pcaplay/main.go new file mode 100644 index 0000000..7172dcd --- /dev/null +++ b/vendor/github.com/google/gopacket/examples/pcaplay/main.go @@ -0,0 +1,159 @@ +// 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. + +// The pcaplay binary load an offline capture (pcap file) and replay +// it on the select interface, with an emphasis on packet timing +package main + +import ( + "flag" + "fmt" + "io" + "log" + "os" + "strings" + "time" + + "github.com/google/gopacket" + "github.com/google/gopacket/examples/util" + "github.com/google/gopacket/pcap" +) + +var iface = flag.String("i", "eth0", "Interface to write packets to") +var fname = flag.String("r", "", "Filename to read from") +var fast = flag.Bool("f", false, "Send each packets as fast as possible") + +var lastTS time.Time +var lastSend time.Time + +var start time.Time +var bytesSent int + +func writePacketDelayed(handle *pcap.Handle, buf []byte, ci gopacket.CaptureInfo) { + if ci.CaptureLength != ci.Length { + // do not write truncated packets + return + } + + intervalInCapture := ci.Timestamp.Sub(lastTS) + elapsedTime := time.Since(lastSend) + + if (intervalInCapture > elapsedTime) && !lastSend.IsZero() { + time.Sleep(intervalInCapture - elapsedTime) + } + + lastSend = time.Now() + writePacket(handle, buf) + lastTS = ci.Timestamp +} + +func writePacket(handle *pcap.Handle, buf []byte) error { + if err := handle.WritePacketData(buf); err != nil { + log.Printf("Failed to send packet: %s\n", err) + return err + } + return nil +} + +func pcapInfo(filename string) (start time.Time, end time.Time, packets int, size int) { + handleRead, err := pcap.OpenOffline(*fname) + if err != nil { + log.Fatal("PCAP OpenOffline error (handle to read packet):", err) + } + + var previousTs time.Time + var deltaTotal time.Duration + + for { + data, ci, err := handleRead.ReadPacketData() + if err != nil && err != io.EOF { + log.Fatal(err) + } else if err == io.EOF { + break + } else { + + if start.IsZero() { + start = ci.Timestamp + } + end = ci.Timestamp + packets++ + size += len(data) + + if previousTs.IsZero() { + previousTs = ci.Timestamp + } else { + deltaTotal += ci.Timestamp.Sub(previousTs) + previousTs = ci.Timestamp + } + } + } + fmt.Printf("Avg packet rate %d/s\n", packets/int(deltaTotal.Seconds())) + return start, end, packets, size +} + +func main() { + defer util.Run()() + + // Sanity checks + if *fname == "" { + log.Fatal("Need a input file") + } + + // Open PCAP file + handle potential BPF Filter + handleRead, err := pcap.OpenOffline(*fname) + if err != nil { + log.Fatal("PCAP OpenOffline error (handle to read packet):", err) + } + defer handleRead.Close() + if len(flag.Args()) > 0 { + bpffilter := strings.Join(flag.Args(), " ") + fmt.Fprintf(os.Stderr, "Using BPF filter %q\n", bpffilter) + if err = handleRead.SetBPFFilter(bpffilter); err != nil { + log.Fatal("BPF filter error:", err) + } + } + // Open up a second pcap handle for packet writes. + handleWrite, err := pcap.OpenLive(*iface, 65536, true, pcap.BlockForever) + if err != nil { + log.Fatal("PCAP OpenLive error (handle to write packet):", err) + } + defer handleWrite.Close() + + start = time.Now() + pkt := 0 + tsStart, tsEnd, packets, size := pcapInfo(*fname) + + // Loop over packets and write them + for { + data, ci, err := handleRead.ReadPacketData() + switch { + case err == io.EOF: + fmt.Printf("\nFinished in %s", time.Since(start)) + return + case err != nil: + log.Printf("Failed to read packet %d: %s\n", pkt, err) + default: + if *fast { + writePacket(handleWrite, data) + } else { + writePacketDelayed(handleWrite, data, ci) + } + + bytesSent += len(data) + duration := time.Since(start) + pkt++ + + if duration > time.Second { + rate := bytesSent / int(duration.Seconds()) + remainingTime := tsEnd.Sub(tsStart) - duration + fmt.Printf("\rrate %d kB/sec - sent %d/%d kB - %d/%d packets - remaining time %s", + rate/1000, bytesSent/1000, size/1000, + pkt, packets, remainingTime) + } + } + } + +} diff --git a/vendor/github.com/google/gopacket/examples/pfdump/main.go b/vendor/github.com/google/gopacket/examples/pfdump/main.go new file mode 100644 index 0000000..4b3ace6 --- /dev/null +++ b/vendor/github.com/google/gopacket/examples/pfdump/main.go @@ -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. + +// The pfdump binary implements a tcpdump-like command line tool with gopacket +// using pfring as a backend data collection mechanism. +package main + +import ( + "flag" + "fmt" + "github.com/google/gopacket/dumpcommand" + "github.com/google/gopacket/examples/util" + "github.com/google/gopacket/pfring" + "log" + "os" + "strings" +) + +var iface = flag.String("i", "eth0", "Interface to read packets from") +var snaplen = flag.Int("s", 65536, "Snap length (number of bytes max to read per packet") +var cluster = flag.Int("cluster", -1, "If >= 0, sets the pfring cluster to this value") +var clustertype = flag.Int("clustertype", int(pfring.ClusterPerFlow), "Cluster type") + +func main() { + defer util.Run()() + var ring *pfring.Ring + var err error + if ring, err = pfring.NewRing(*iface, uint32(*snaplen), pfring.FlagPromisc); err != nil { + log.Fatalln("pfring ring creation error:", err) + } + if len(flag.Args()) > 0 { + bpffilter := strings.Join(flag.Args(), " ") + fmt.Fprintf(os.Stderr, "Using BPF filter %q\n", bpffilter) + if err = ring.SetBPFFilter(bpffilter); err != nil { + log.Fatalln("BPF filter error:", err) + } + } + if *cluster >= 0 { + if err = ring.SetCluster(*cluster, pfring.ClusterType(*clustertype)); err != nil { + log.Fatalln("pfring SetCluster error:", err) + } + } + if err = ring.SetSocketMode(pfring.ReadOnly); err != nil { + log.Fatalln("pfring SetSocketMode error:", err) + } else if err = ring.Enable(); err != nil { + log.Fatalln("pfring Enable error:", err) + } + dumpcommand.Run(ring) +} diff --git a/vendor/github.com/google/gopacket/examples/statsassembly/main.go b/vendor/github.com/google/gopacket/examples/statsassembly/main.go new file mode 100644 index 0000000..36da011 --- /dev/null +++ b/vendor/github.com/google/gopacket/examples/statsassembly/main.go @@ -0,0 +1,211 @@ +// 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. + +// This binary provides sample code for using the gopacket TCP assembler raw, +// without the help of the tcpreader library. It watches TCP streams and +// reports statistics on completed streams. +// +// It also uses gopacket.DecodingLayerParser instead of the normal +// gopacket.PacketSource, to highlight the methods, pros, and cons of this +// approach. +package main + +import ( + "flag" + "github.com/google/gopacket" + "github.com/google/gopacket/examples/util" + "github.com/google/gopacket/layers" + "github.com/google/gopacket/pcap" + "github.com/google/gopacket/tcpassembly" + "log" + "time" +) + +var iface = flag.String("i", "eth0", "Interface to get packets from") +var snaplen = flag.Int("s", 65536, "SnapLen for pcap packet capture") +var filter = flag.String("f", "tcp", "BPF filter for pcap") +var logAllPackets = flag.Bool("v", false, "Log whenever we see a packet") +var bufferedPerConnection = flag.Int("connection_max_buffer", 0, ` +Max packets to buffer for a single connection before skipping over a gap in data +and continuing to stream the connection after the buffer. If zero or less, this +is infinite.`) +var bufferedTotal = flag.Int("total_max_buffer", 0, ` +Max packets to buffer total before skipping over gaps in connections and +continuing to stream connection data. If zero or less, this is infinite`) +var flushAfter = flag.String("flush_after", "2m", ` +Connections which have buffered packets (they've gotten packets out of order and +are waiting for old packets to fill the gaps) are flushed after they're this old +(their oldest gap is skipped). Any string parsed by time.ParseDuration is +acceptable here`) +var packetCount = flag.Int("c", -1, ` +Quit after processing this many packets, flushing all currently buffered +connections. If negative, this is infinite`) + +// simpleStreamFactory implements tcpassembly.StreamFactory +type statsStreamFactory struct{} + +// statsStream will handle the actual decoding of stats requests. +type statsStream struct { + net, transport gopacket.Flow + bytes, packets, outOfOrder, skipped int64 + start, end time.Time + sawStart, sawEnd bool +} + +// New creates a new stream. It's called whenever the assembler sees a stream +// it isn't currently following. +func (factory *statsStreamFactory) New(net, transport gopacket.Flow) tcpassembly.Stream { + log.Printf("new stream %v:%v started", net, transport) + s := &statsStream{ + net: net, + transport: transport, + start: time.Now(), + } + s.end = s.start + // ReaderStream implements tcpassembly.Stream, so we can return a pointer to it. + return s +} + +// Reassembled is called whenever new packet data is available for reading. +// Reassembly objects contain stream data IN ORDER. +func (s *statsStream) Reassembled(reassemblies []tcpassembly.Reassembly) { + for _, reassembly := range reassemblies { + if reassembly.Seen.Before(s.end) { + s.outOfOrder++ + } else { + s.end = reassembly.Seen + } + s.bytes += int64(len(reassembly.Bytes)) + s.packets += 1 + if reassembly.Skip > 0 { + s.skipped += int64(reassembly.Skip) + } + s.sawStart = s.sawStart || reassembly.Start + s.sawEnd = s.sawEnd || reassembly.End + } +} + +// ReassemblyComplete is called when the TCP assembler believes a stream has +// finished. +func (s *statsStream) ReassemblyComplete() { + diffSecs := float64(s.end.Sub(s.start)) / float64(time.Second) + log.Printf("Reassembly of stream %v:%v complete - start:%v end:%v bytes:%v packets:%v ooo:%v bps:%v pps:%v skipped:%v", + s.net, s.transport, s.start, s.end, s.bytes, s.packets, s.outOfOrder, + float64(s.bytes)/diffSecs, float64(s.packets)/diffSecs, s.skipped) +} + +func main() { + defer util.Run()() + + flushDuration, err := time.ParseDuration(*flushAfter) + if err != nil { + log.Fatal("invalid flush duration: ", *flushAfter) + } + + log.Printf("starting capture on interface %q", *iface) + // Set up pcap packet capture + handle, err := pcap.OpenLive(*iface, int32(*snaplen), true, flushDuration/2) + if err != nil { + log.Fatal("error opening pcap handle: ", err) + } + if err := handle.SetBPFFilter(*filter); err != nil { + log.Fatal("error setting BPF filter: ", err) + } + + // Set up assembly + streamFactory := &statsStreamFactory{} + streamPool := tcpassembly.NewStreamPool(streamFactory) + assembler := tcpassembly.NewAssembler(streamPool) + assembler.MaxBufferedPagesPerConnection = *bufferedPerConnection + assembler.MaxBufferedPagesTotal = *bufferedTotal + + log.Println("reading in packets") + + // We use a DecodingLayerParser here instead of a simpler PacketSource. + // This approach should be measurably faster, but is also more rigid. + // PacketSource will handle any known type of packet safely and easily, + // but DecodingLayerParser will only handle those packet types we + // specifically pass in. This trade-off can be quite useful, though, in + // high-throughput situations. + var eth layers.Ethernet + var dot1q layers.Dot1Q + var ip4 layers.IPv4 + var ip6 layers.IPv6 + var ip6extensions layers.IPv6ExtensionSkipper + var tcp layers.TCP + var payload gopacket.Payload + parser := gopacket.NewDecodingLayerParser(layers.LayerTypeEthernet, + ð, &dot1q, &ip4, &ip6, &ip6extensions, &tcp, &payload) + decoded := make([]gopacket.LayerType, 0, 4) + + nextFlush := time.Now().Add(flushDuration / 2) + + var byteCount int64 + start := time.Now() + +loop: + for ; *packetCount != 0; *packetCount-- { + // Check to see if we should flush the streams we have + // that haven't seen any new data in a while. Note we set a + // timeout on our PCAP handle, so this should happen even if we + // never see packet data. + if time.Now().After(nextFlush) { + stats, _ := handle.Stats() + log.Printf("flushing all streams that haven't seen packets in the last 2 minutes, pcap stats: %+v", stats) + assembler.FlushOlderThan(time.Now().Add(flushDuration)) + nextFlush = time.Now().Add(flushDuration / 2) + } + + // To speed things up, we're also using the ZeroCopy method for + // reading packet data. This method is faster than the normal + // ReadPacketData, but the returned bytes in 'data' are + // invalidated by any subsequent ZeroCopyReadPacketData call. + // Note that tcpassembly is entirely compatible with this packet + // reading method. This is another trade-off which might be + // appropriate for high-throughput sniffing: it avoids a packet + // copy, but its cost is much more careful handling of the + // resulting byte slice. + data, ci, err := handle.ZeroCopyReadPacketData() + + if err != nil { + log.Printf("error getting packet: %v", err) + continue + } + err = parser.DecodeLayers(data, &decoded) + if err != nil { + log.Printf("error decoding packet: %v", err) + continue + } + if *logAllPackets { + log.Printf("decoded the following layers: %v", decoded) + } + byteCount += int64(len(data)) + // Find either the IPv4 or IPv6 address to use as our network + // layer. + foundNetLayer := false + var netFlow gopacket.Flow + for _, typ := range decoded { + switch typ { + case layers.LayerTypeIPv4: + netFlow = ip4.NetworkFlow() + foundNetLayer = true + case layers.LayerTypeIPv6: + netFlow = ip6.NetworkFlow() + foundNetLayer = true + case layers.LayerTypeTCP: + if foundNetLayer { + assembler.AssembleWithTimestamp(netFlow, &tcp, ci.Timestamp) + } else { + log.Println("could not find IPv4 or IPv6 layer, inoring") + } + continue loop + } + } + log.Println("could not find TCP layer") + } + assembler.FlushAll() + log.Printf("processed %d bytes in %v", byteCount, time.Since(start)) +} diff --git a/vendor/github.com/google/gopacket/examples/synscan/main.go b/vendor/github.com/google/gopacket/examples/synscan/main.go new file mode 100644 index 0000000..bfbc631 --- /dev/null +++ b/vendor/github.com/google/gopacket/examples/synscan/main.go @@ -0,0 +1,260 @@ +// 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. + +// synscan implements a TCP syn scanner on top of pcap. +// It's more complicated than arpscan, since it has to handle sending packets +// outside the local network, requiring some routing and ARP work. +// +// Since this is just an example program, it aims for simplicity over +// performance. It doesn't handle sending packets very quickly, it scans IPs +// serially instead of in parallel, and uses gopacket.Packet instead of +// gopacket.DecodingLayerParser for packet processing. We also make use of very +// simple timeout logic with time.Since. +// +// Making it blazingly fast is left as an exercise to the reader. +package main + +import ( + "bytes" + "flag" + "fmt" + "log" + "net" + "time" + + "github.com/google/gopacket" + "github.com/google/gopacket/examples/util" + "github.com/google/gopacket/layers" + "github.com/google/gopacket/pcap" + "github.com/google/gopacket/routing" +) + +// scanner handles scanning a single IP address. +type scanner struct { + // iface is the interface to send packets on. + iface *net.Interface + // destination, gateway (if applicable), and soruce IP addresses to use. + dst, gw, src net.IP + + handle *pcap.Handle + + // opts and buf allow us to easily serialize packets in the send() + // method. + opts gopacket.SerializeOptions + buf gopacket.SerializeBuffer +} + +// newScanner creates a new scanner for a given destination IP address, using +// router to determine how to route packets to that IP. +func newScanner(ip net.IP, router routing.Router) (*scanner, error) { + s := &scanner{ + dst: ip, + opts: gopacket.SerializeOptions{ + FixLengths: true, + ComputeChecksums: true, + }, + buf: gopacket.NewSerializeBuffer(), + } + // Figure out the route to the IP. + iface, gw, src, err := router.Route(ip) + if err != nil { + return nil, err + } + log.Printf("scanning ip %v with interface %v, gateway %v, src %v", ip, iface.Name, gw, src) + s.gw, s.src, s.iface = gw, src, iface + + // Open the handle for reading/writing. + // Note we could very easily add some BPF filtering here to greatly + // decrease the number of packets we have to look at when getting back + // scan results. + handle, err := pcap.OpenLive(iface.Name, 65536, true, pcap.BlockForever) + if err != nil { + return nil, err + } + s.handle = handle + return s, nil +} + +// close cleans up the handle. +func (s *scanner) close() { + s.handle.Close() +} + +// getHwAddr is a hacky but effective way to get the destination hardware +// address for our packets. It does an ARP request for our gateway (if there is +// one) or destination IP (if no gateway is necessary), then waits for an ARP +// reply. This is pretty slow right now, since it blocks on the ARP +// request/reply. +func (s *scanner) getHwAddr() (net.HardwareAddr, error) { + start := time.Now() + arpDst := s.dst + if s.gw != nil { + arpDst = s.gw + } + // Prepare the layers to send for an ARP request. + eth := layers.Ethernet{ + SrcMAC: s.iface.HardwareAddr, + DstMAC: net.HardwareAddr{0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, + EthernetType: layers.EthernetTypeARP, + } + arp := layers.ARP{ + AddrType: layers.LinkTypeEthernet, + Protocol: layers.EthernetTypeIPv4, + HwAddressSize: 6, + ProtAddressSize: 4, + Operation: layers.ARPRequest, + SourceHwAddress: []byte(s.iface.HardwareAddr), + SourceProtAddress: []byte(s.src), + DstHwAddress: []byte{0, 0, 0, 0, 0, 0}, + DstProtAddress: []byte(arpDst), + } + // Send a single ARP request packet (we never retry a send, since this + // is just an example ;) + if err := s.send(ð, &arp); err != nil { + return nil, err + } + // Wait 3 seconds for an ARP reply. + for { + if time.Since(start) > time.Second*3 { + return nil, fmt.Errorf("timeout getting ARP reply") + } + data, _, err := s.handle.ReadPacketData() + if err == pcap.NextErrorTimeoutExpired { + continue + } else if err != nil { + return nil, err + } + packet := gopacket.NewPacket(data, layers.LayerTypeEthernet, gopacket.NoCopy) + if arpLayer := packet.Layer(layers.LayerTypeARP); arpLayer != nil { + arp := arpLayer.(*layers.ARP) + if bytes.Equal(arp.SourceProtAddress, arpDst) { + return net.HardwareAddr(arp.SourceHwAddress), nil + } + } + } +} + +// scan scans the dst IP address of this scanner. +func (s *scanner) scan() error { + // First off, get the MAC address we should be sending packets to. + hwaddr, err := s.getHwAddr() + if err != nil { + return err + } + // Construct all the network layers we need. + eth := layers.Ethernet{ + SrcMAC: s.iface.HardwareAddr, + DstMAC: hwaddr, + EthernetType: layers.EthernetTypeIPv4, + } + ip4 := layers.IPv4{ + SrcIP: s.src, + DstIP: s.dst, + Version: 4, + TTL: 64, + Protocol: layers.IPProtocolTCP, + } + tcp := layers.TCP{ + SrcPort: 54321, + DstPort: 0, // will be incremented during the scan + SYN: true, + } + tcp.SetNetworkLayerForChecksum(&ip4) + + // Create the flow we expect returning packets to have, so we can check + // against it and discard useless packets. + ipFlow := gopacket.NewFlow(layers.EndpointIPv4, s.dst, s.src) + start := time.Now() + for { + // Send one packet per loop iteration until we've sent packets + // to all of ports [1, 65535]. + if tcp.DstPort < 65535 { + start = time.Now() + tcp.DstPort++ + if err := s.send(ð, &ip4, &tcp); err != nil { + log.Printf("error sending to port %v: %v", tcp.DstPort, err) + } + } + // Time out 5 seconds after the last packet we sent. + if time.Since(start) > time.Second*5 { + log.Printf("timed out for %v, assuming we've seen all we can", s.dst) + return nil + } + + // Read in the next packet. + data, _, err := s.handle.ReadPacketData() + if err == pcap.NextErrorTimeoutExpired { + continue + } else if err != nil { + log.Printf("error reading packet: %v", err) + continue + } + + // Parse the packet. We'd use DecodingLayerParser here if we + // wanted to be really fast. + packet := gopacket.NewPacket(data, layers.LayerTypeEthernet, gopacket.NoCopy) + + // Find the packets we care about, and print out logging + // information about them. All others are ignored. + if net := packet.NetworkLayer(); net == nil { + // log.Printf("packet has no network layer") + } else if net.NetworkFlow() != ipFlow { + // log.Printf("packet does not match our ip src/dst") + } else if tcpLayer := packet.Layer(layers.LayerTypeTCP); tcpLayer == nil { + // log.Printf("packet has not tcp layer") + } else if tcp, ok := tcpLayer.(*layers.TCP); !ok { + // We panic here because this is guaranteed to never + // happen. + panic("tcp layer is not tcp layer :-/") + } else if tcp.DstPort != 54321 { + // log.Printf("dst port %v does not match", tcp.DstPort) + } else if tcp.RST { + log.Printf(" port %v closed", tcp.SrcPort) + } else if tcp.SYN && tcp.ACK { + log.Printf(" port %v open", tcp.SrcPort) + } else { + // log.Printf("ignoring useless packet") + } + } +} + +// send sends the given layers as a single packet on the network. +func (s *scanner) send(l ...gopacket.SerializableLayer) error { + if err := gopacket.SerializeLayers(s.buf, s.opts, l...); err != nil { + return err + } + return s.handle.WritePacketData(s.buf.Bytes()) +} + +func main() { + defer util.Run()() + router, err := routing.New() + if err != nil { + log.Fatal("routing error:", err) + } + for _, arg := range flag.Args() { + var ip net.IP + if ip = net.ParseIP(arg); ip == nil { + log.Printf("non-ip target: %q", arg) + continue + } else if ip = ip.To4(); ip == nil { + log.Printf("non-ipv4 target: %q", arg) + continue + } + // Note: newScanner creates and closes a pcap Handle once for + // every scan target. We could do much better, were this not an + // example ;) + s, err := newScanner(ip, router) + if err != nil { + log.Printf("unable to create scanner for %v: %v", ip, err) + continue + } + if err := s.scan(); err != nil { + log.Printf("unable to scan %v: %v", ip, err) + } + s.close() + } +} diff --git a/vendor/github.com/google/gopacket/examples/util/util.go b/vendor/github.com/google/gopacket/examples/util/util.go new file mode 100644 index 0000000..0f698fb --- /dev/null +++ b/vendor/github.com/google/gopacket/examples/util/util.go @@ -0,0 +1,40 @@ +// 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 util provides shared utilities for all gopacket examples. +package util + +import ( + "flag" + "log" + "os" + "runtime/pprof" +) + +var cpuprofile = flag.String("cpuprofile", "", "Where to write CPU profile") + +// Run starts up stuff at the beginning of a main function, and returns a +// function to defer until the function completes. It should be used like this: +// +// func main() { +// defer util.Run()() +// ... stuff ... +// } +func Run() func() { + flag.Parse() + if *cpuprofile != "" { + f, err := os.Create(*cpuprofile) + if err != nil { + log.Fatalf("could not open cpu profile file %q", *cpuprofile) + } + pprof.StartCPUProfile(f) + return func() { + pprof.StopCPUProfile() + f.Close() + } + } + return func() {} +} diff --git a/vendor/github.com/google/gopacket/flows.go b/vendor/github.com/google/gopacket/flows.go new file mode 100644 index 0000000..4622a0d --- /dev/null +++ b/vendor/github.com/google/gopacket/flows.go @@ -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 (e Endpoint) EndpointType() EndpointType { return e.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 (e Endpoint) Raw() []byte { return e.raw[:e.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 lexigraphically. +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 (e Endpoint) String() string { + if t, ok := endpointTypes[e.typ]; ok && t.Formatter != nil { + return t.Formatter(e.raw[:e.len]) + } + return fmt.Sprintf("%v:%v", e.typ, e.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 (a 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(a.src[:a.slen]) + fnvHash(a.dst[:a.dlen]) + h ^= uint64(a.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 EndpointType = RegisterEndpointType(0, EndpointTypeMetadata{"invalid", func(b []byte) string { + return fmt.Sprintf("%v", b) +}}) + +// InvalidEndpoint is a singleton Endpoint of type EndpointInvalid. +var InvalidEndpoint Endpoint = NewEndpoint(EndpointInvalid, nil) + +// InvalidFlow is a singleton Flow of type EndpointInvalid. +var InvalidFlow Flow = NewFlow(EndpointInvalid, nil, nil) diff --git a/vendor/github.com/google/gopacket/gc b/vendor/github.com/google/gopacket/gc new file mode 100644 index 0000000..6ef9f31 --- /dev/null +++ b/vendor/github.com/google/gopacket/gc @@ -0,0 +1,271 @@ +#!/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 < + +--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 + 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/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 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 + +# 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 <&1 | tee -a $COMMIT_FILE +pushd layers +go test --test.bench="$BENCH" 2>&1 | tee -a $COMMIT_FILE +popd +cat >> $COMMIT_FILE <&1 | tee -a $COMMIT_FILE +fi + + + +## Reset to last benchmark commit, run benchmarks + +git checkout $PREV + +cat >> $COMMIT_FILE <&1 | tee -a $COMMIT_FILE +pushd layers +go test --test.bench="$BENCH" 2>&1 | tee -a $COMMIT_FILE +popd +cat >> $COMMIT_FILE <&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 diff --git a/vendor/github.com/google/gopacket/ip4defrag/defrag.go b/vendor/github.com/google/gopacket/ip4defrag/defrag.go new file mode 100644 index 0000000..6c11795 --- /dev/null +++ b/vendor/github.com/google/gopacket/ip4defrag/defrag.go @@ -0,0 +1,308 @@ +// Copyright 2013 Google, Inc. All rights reserved. +// +// Package ip4defrag implements a IPv4 defragmenter +package ip4defrag + +import ( + "container/list" + "fmt" + "log" + "sync" + "time" + + "github.com/google/gopacket" + "github.com/google/gopacket/layers" +) + +// Quick and Easy to use debug code to trace +// how defrag works. +var debug debugging = false // or flip to false +type debugging bool + +func (d debugging) Printf(format string, args ...interface{}) { + if d { + log.Printf(format, args...) + } +} + +const ( + IPv4MinimumFragmentSize = 576 + IPv4MaximumSize = 65535 + IPv4MaximumFragmentOffset = 8189 + IPv4MaximumFragmentListLen = 8 +) + +// DefragIPv4 takes in an IPv4 packet with a fragment payload. +// +// It do not modify the IPv4 layer in place, 'in' remains untouched +// It returns a ready-to be used IPv4 layer. +// +// If the passed-in IPv4 layer is NOT fragmented, it will +// immediately return it without modifying the layer. +// +// If the IPv4 layer is a fragment and we don't have all +// fragments, it will return nil and store whatever internal +// information it needs to eventually defrag the packet. +// +// If the IPv4 layer is the last fragment needed to reconstruct +// the packet, a new IPv4 layer will be returned, and will be set to +// the entire defragmented packet, +// +// It use a map of all the running flows +// +// Usage example: +// +// func HandlePacket(in *layers.IPv4) err { +// defragger := ip4defrag.NewIPv4Defragmenter() +// in, err := defragger.DefragIPv4(in) +// if err != nil { +// return err +// } else if in == nil { +// return nil // packet fragment, we don't have whole packet yet. +// } +// // At this point, we know that 'in' is defragmented. +// //It may be the same 'in' passed to +// // HandlePacket, or it may not, but we don't really care :) +// ... do stuff to 'in' ... +//} +// +func (d *IPv4Defragmenter) DefragIPv4(in *layers.IPv4) (*layers.IPv4, error) { + // check if we need to defrag + if st := d.dontDefrag(in); st == true { + return in, nil + } + // perfom security checks + st, err := d.securityChecks(in) + if err != nil || st == false { + return nil, err + } + + // ok, got a fragment + debug.Printf("defrag: got in.Id=%d in.FragOffset=%d in.Flags=%d\n", + in.Id, in.FragOffset*8, in.Flags) + + // do we already has seen a flow between src/dst with that Id + ipf := newIPv4(in) + var fl *fragmentList + var exist bool + d.Lock() + fl, exist = d.ipFlows[ipf] + if !exist { + debug.Printf("defrag: creating a new flow\n") + fl = new(fragmentList) + d.ipFlows[ipf] = fl + } + d.Unlock() + // insert, and if final build it + out, err2 := fl.insert(in) + + // at last, if we hit the maximum frag list len + // without any defrag success, we just drop everything and + // raise an error + if out == nil && fl.List.Len()+1 > IPv4MaximumFragmentListLen { + d.Lock() + fl = new(fragmentList) + d.ipFlows[ipf] = fl + d.Unlock() + return nil, fmt.Errorf("defrag: Fragment List hits its maximum"+ + "size(%d), without sucess. Flushing the list", + IPv4MaximumFragmentListLen) + } + + // if we got a packet, it's a new one, and he is defragmented + if out != nil { + return out, nil + } + return nil, err2 +} + +// DiscardOlderThan forgets all packets without any activity since +// time t. It returns the number of FragmentList aka number of +// fragment packets it has discarded. +func (d *IPv4Defragmenter) DiscardOlderThan(t time.Time) int { + var nb int + d.Lock() + for k, v := range d.ipFlows { + if v.LastSeen.Before(t) { + nb = nb + 1 + delete(d.ipFlows, k) + } + } + d.Unlock() + return nb +} + +// dontDefrag returns true if the IPv4 packet do not need +// any defragmentation +func (d *IPv4Defragmenter) dontDefrag(ip *layers.IPv4) bool { + // don't defrag packet with DF flag + if ip.Flags&layers.IPv4DontFragment != 0 { + return true + } + // don't defrag not fragmented ones + if ip.Flags&layers.IPv4MoreFragments == 0 && ip.FragOffset == 0 { + return true + } + return false +} + +// securityChecks performs the needed security checks +func (d *IPv4Defragmenter) securityChecks(ip *layers.IPv4) (bool, error) { + // don't allow too big fragment offset + if ip.FragOffset > IPv4MaximumFragmentOffset { + return false, fmt.Errorf("defrag: fragment offset too big "+ + "(handcrafted? %d > %d)", ip.FragOffset, IPv4MaximumFragmentOffset) + } + fragOffset := ip.FragOffset * 8 + + // don't allow fragment that would oversize an IP packet + if fragOffset+ip.Length > IPv4MaximumSize { + return false, fmt.Errorf("defrag: fragment will overrun "+ + "(handcrafted? %d > %d)", ip.FragOffset*8+ip.Length, IPv4MaximumSize) + } + + return true, nil +} + +// fragmentList holds a container/list used to contains IP +// packets/fragments. It stores internal counters to track the +// maximum total of byte, and the current length it has received. +// It also stores a flag to know if he has seen the last packet. +type fragmentList struct { + List list.List + Highest uint16 + Current uint16 + FinalReceived bool + LastSeen time.Time +} + +// insert insert an IPv4 fragment/packet into the Fragment List +// It use the following strategy : we are inserting fragment based +// on their offset, latest first. This is sometimes called BSD-Right. +// See: http://www.sans.org/reading-room/whitepapers/detection/ip-fragment-reassembly-scapy-33969 +func (f *fragmentList) insert(in *layers.IPv4) (*layers.IPv4, error) { + // TODO: should keep a copy of *in in the list + // or not (ie the packet source is reliable) ? + fragOffset := in.FragOffset * 8 + if fragOffset >= f.Highest { + f.List.PushBack(in) + } else { + for e := f.List.Front(); e != nil; e = e.Next() { + frag, _ := e.Value.(*layers.IPv4) + if in.FragOffset <= frag.FragOffset { + debug.Printf("defrag: inserting frag %d before existing frag %d \n", + fragOffset, frag.FragOffset*8) + f.List.InsertBefore(in, e) + break + } + } + } + // packet.Metadata().Timestamp should have been better, but + // we don't have this info there... + f.LastSeen = time.Now() + + fragLength := in.Length - 20 + // After inserting the Fragment, we update the counters + if f.Highest < fragOffset+fragLength { + f.Highest = fragOffset + fragLength + } + f.Current = f.Current + fragLength + + debug.Printf("defrag: insert ListLen: %d Highest:%d Current:%d\n", + f.List.Len(), + f.Highest, f.Current) + + // Final Fragment ? + if in.Flags&layers.IPv4MoreFragments == 0 { + f.FinalReceived = true + } + // Ready to try defrag ? + if f.FinalReceived && f.Highest == f.Current { + return f.build(in) + } + return nil, nil +} + +// Build builds the final datagram, modifying ip in place. +// It puts priority to packet in the early position of the list. +// See Insert for more details. +func (f *fragmentList) build(in *layers.IPv4) (*layers.IPv4, error) { + var final []byte + var currentOffset uint16 = 0 + + debug.Printf("defrag: building the datagram \n") + for e := f.List.Front(); e != nil; e = e.Next() { + frag, _ := e.Value.(*layers.IPv4) + if frag.FragOffset*8 == currentOffset { + debug.Printf("defrag: building - adding %d\n", frag.FragOffset*8) + final = append(final, frag.Payload...) + currentOffset = currentOffset + frag.Length - 20 + } else if frag.FragOffset*8 < currentOffset { + // overlapping fragment - let's take only what we need + startAt := currentOffset - frag.FragOffset*8 + debug.Printf("defrag: building - overlapping, starting at %d\n", + startAt) + if startAt > frag.Length-20 { + return nil, fmt.Errorf("defrag: building - invalid fragment") + } + final = append(final, frag.Payload[startAt:]...) + currentOffset = currentOffset + frag.FragOffset*8 + } else { + // Houston - we have an hole ! + debug.Printf("defrag: hole found while building, " + + "stopping the defrag process\n") + return nil, fmt.Errorf("defrag: building - hole found") + } + debug.Printf("defrag: building - next is %d\n", currentOffset) + } + + // TODO recompute IP Checksum + out := &layers.IPv4{ + Version: in.Version, + IHL: in.IHL, + TOS: in.TOS, + Length: f.Highest, + Id: 0, + Flags: 0, + FragOffset: 0, + TTL: in.TTL, + Protocol: in.Protocol, + Checksum: 0, + SrcIP: in.SrcIP, + DstIP: in.DstIP, + Options: in.Options, + Padding: in.Padding, + } + out.Payload = final + + return out, nil +} + +// ipv4 is a struct to be used as a key. +type ipv4 struct { + ip4 gopacket.Flow + id uint16 +} + +// newIPv4 returns a new initialized IPv4 Flow +func newIPv4(ip *layers.IPv4) ipv4 { + return ipv4{ + ip4: ip.NetworkFlow(), + id: ip.Id, + } +} + +// IPv4Defragmenter is a struct which embedded a map of +// all fragment/packet. +type IPv4Defragmenter struct { + sync.RWMutex + ipFlows map[ipv4]*fragmentList +} + +// NewIPv4Defragmenter returns a new IPv4Defragmenter +// with an initialized map. +func NewIPv4Defragmenter() *IPv4Defragmenter { + return &IPv4Defragmenter{ + ipFlows: make(map[ipv4]*fragmentList), + } +} diff --git a/vendor/github.com/google/gopacket/layerclass.go b/vendor/github.com/google/gopacket/layerclass.go new file mode 100644 index 0000000..7e76f9c --- /dev/null +++ b/vendor/github.com/google/gopacket/layerclass.go @@ -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 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 +} + +// Make LayerType itself be a LayerClass. +func (l LayerType) Contains(a LayerType) bool { + return l == a +} + +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) +} diff --git a/vendor/github.com/google/gopacket/layers/arp.go b/vendor/github.com/google/gopacket/layers/arp.go new file mode 100644 index 0000000..60701b9 --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/arp.go @@ -0,0 +1,107 @@ +// 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" +) + +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 fmt.Errorf("mismatched hardware address sizes") + } + arp.HwAddressSize = uint8(len(arp.SourceHwAddress)) + if len(arp.SourceProtAddress) != len(arp.DstProtAddress) { + return fmt.Errorf("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) +} diff --git a/vendor/github.com/google/gopacket/layers/base.go b/vendor/github.com/google/gopacket/layers/base.go new file mode 100644 index 0000000..cd59b46 --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/base.go @@ -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 diff --git a/vendor/github.com/google/gopacket/layers/cdp.go b/vendor/github.com/google/gopacket/layers/cdp.go new file mode 100644 index 0000000..b6a53df --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/cdp.go @@ -0,0 +1,640 @@ +// 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" + "github.com/google/gopacket" + "net" +) + +// CDPTLVType is the type of each TLV value in a CiscoDiscovery packet. +type CDPTLVType uint16 + +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 +} + +type CDPCapability uint32 + +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 +} + +const ( + CDPPoEFourWire byte = 0x01 + CDPPoEPDArch byte = 0x02 + CDPPoEPDRequest byte = 0x04 + CDPPoEPSE byte = 0x08 +) + +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 +} + +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 +} + +type CDPEnergyWiseSubtype uint32 + +const ( + CDPEnergyWiseRole CDPEnergyWiseSubtype = 0x00000007 + CDPEnergyWiseDomain CDPEnergyWiseSubtype = 0x00000008 + CDPEnergyWiseName CDPEnergyWiseSubtype = 0x00000009 + CDPEnergyWiseReplyTo CDPEnergyWiseSubtype = 0x00000017 +) + +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 +) + +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 +} diff --git a/vendor/github.com/google/gopacket/layers/ctp.go b/vendor/github.com/google/gopacket/layers/ctp.go new file mode 100644 index 0000000..abe6b3e --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/ctp.go @@ -0,0 +1,108 @@ +// 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 + +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) +} diff --git a/vendor/github.com/google/gopacket/layers/dns.go b/vendor/github.com/google/gopacket/layers/dns.go new file mode 100644 index 0000000..0b9b812 --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/dns.go @@ -0,0 +1,564 @@ +// 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" + "errors" + "fmt" + "github.com/google/gopacket" + "net" +) + +type DNSClass uint16 + +const ( + DNSClassIN DNSClass = 1 // Internet + DNSClassCS DNSClass = 2 // the CSNET class (Obsolete) + DNSClassCH DNSClass = 3 // the CHAOS class + DNSClassHS DNSClass = 4 // Hesiod [Dyer 87] + DNSClassAny DNSClass = 255 // AnyClass +) + +type DNSType uint16 + +const ( + DNSTypeA DNSType = 1 // a host address + DNSTypeNS DNSType = 2 // an authoritative name server + DNSTypeMD DNSType = 3 // a mail destination (Obsolete - use MX) + DNSTypeMF DNSType = 4 // a mail forwarder (Obsolete - use MX) + DNSTypeCNAME DNSType = 5 // the canonical name for an alias + DNSTypeSOA DNSType = 6 // marks the start of a zone of authority + DNSTypeMB DNSType = 7 // a mailbox domain name (EXPERIMENTAL) + DNSTypeMG DNSType = 8 // a mail group member (EXPERIMENTAL) + DNSTypeMR DNSType = 9 // a mail rename domain name (EXPERIMENTAL) + DNSTypeNULL DNSType = 10 // a null RR (EXPERIMENTAL) + DNSTypeWKS DNSType = 11 // a well known service description + DNSTypePTR DNSType = 12 // a domain name pointer + DNSTypeHINFO DNSType = 13 // host information + DNSTypeMINFO DNSType = 14 // mailbox or mail list information + DNSTypeMX DNSType = 15 // mail exchange + DNSTypeTXT DNSType = 16 // text strings + DNSTypeAAAA DNSType = 28 // a IPv6 host address [RFC3596] + DNSTypeSRV DNSType = 33 // server discovery [RFC2782] [RFC6195] +) + +type DNSResponseCode uint8 + +const ( + DNSResponseCodeFormErr DNSResponseCode = 1 // Format Error [RFC1035] + DNSResponseCodeServFail DNSResponseCode = 2 // Server Failure [RFC1035] + DNSResponseCodeNXDomain DNSResponseCode = 3 // Non-Existent Domain [RFC1035] + DNSResponseCodeNotImp DNSResponseCode = 4 // Not Implemented [RFC1035] + DNSResponseCodeRefused DNSResponseCode = 5 // Query Refused [RFC1035] + DNSResponseCodeYXDomain DNSResponseCode = 6 // Name Exists when it should not [RFC2136] + DNSResponseCodeYXRRSet DNSResponseCode = 7 // RR Set Exists when it should not [RFC2136] + DNSResponseCodeNXRRSet DNSResponseCode = 8 // RR Set that should exist does not [RFC2136] + DNSResponseCodeNotAuth DNSResponseCode = 9 // Server Not Authoritative for zone [RFC2136] + DNSResponseCodeNotZone DNSResponseCode = 10 // Name not contained in zone [RFC2136] + DNSResponseCodeBadVers DNSResponseCode = 16 // Bad OPT Version [RFC2671] + DNSResponseCodeBadSig DNSResponseCode = 16 // TSIG Signature Failure [RFC2845] + DNSResponseCodeBadKey DNSResponseCode = 17 // Key not recognized [RFC2845] + DNSResponseCodeBadTime DNSResponseCode = 18 // Signature out of time window [RFC2845] + DNSResponseCodeBadMode DNSResponseCode = 19 // Bad TKEY Mode [RFC2930] + DNSResponseCodeBadName DNSResponseCode = 20 // Duplicate key name [RFC2930] + DNSResponseCodeBadAlg DNSResponseCode = 21 // Algorithm not supported [RFC2930] + DNSResponseCodeBadTruc DNSResponseCode = 22 // Bad Truncation [RFC4635] +) + +func (drc DNSResponseCode) String() string { + switch drc { + default: + return "Unknown" + case DNSResponseCodeFormErr: + return "Format Error" + case DNSResponseCodeServFail: + return "Server Failure " + case DNSResponseCodeNXDomain: + return "Non-Existent Domain" + case DNSResponseCodeNotImp: + return "Not Implemented" + case DNSResponseCodeRefused: + return "Query Refused" + case DNSResponseCodeYXDomain: + return "Name Exists when it should not" + case DNSResponseCodeYXRRSet: + return "RR Set Exists when it should not" + case DNSResponseCodeNXRRSet: + return "RR Set that should exist does not" + case DNSResponseCodeNotAuth: + return "Server Not Authoritative for zone" + case DNSResponseCodeNotZone: + return "Name not contained in zone" + case DNSResponseCodeBadVers: + return "Bad OPT Version" + case DNSResponseCodeBadKey: + return "Key not recognized" + case DNSResponseCodeBadTime: + return "Signature out of time window" + case DNSResponseCodeBadMode: + return "Bad TKEY Mode" + case DNSResponseCodeBadName: + return "Duplicate key name" + case DNSResponseCodeBadAlg: + return "Algorithm not supported" + case DNSResponseCodeBadTruc: + return "Bad Truncation" + } +} + +type DNSOpCode uint8 + +const ( + DNSOpCodeQuery DNSOpCode = 0 // Query [RFC1035] + DNSOpCodeIQuery DNSOpCode = 1 // Inverse Query Obsolete [RFC3425] + DNSOpCodeStatus DNSOpCode = 2 // Status [RFC1035] + DNSOpCodeNotify DNSOpCode = 4 // Notify [RFC1996] + DNSOpCodeUpdate DNSOpCode = 5 // Update [RFC2136] +) + +// DNS is specified in RFC 1034 / RFC 1035 +// +---------------------+ +// | Header | +// +---------------------+ +// | Question | the question for the name server +// +---------------------+ +// | Answer | RRs answering the question +// +---------------------+ +// | Authority | RRs pointing toward an authority +// +---------------------+ +// | Additional | RRs holding additional information +// +---------------------+ +// +// DNS Header +// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | ID | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// |QR| Opcode |AA|TC|RD|RA| Z | RCODE | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | QDCOUNT | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | ANCOUNT | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | NSCOUNT | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | ARCOUNT | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + +// DNS contains data from a single Domain Name Service packet. +type DNS struct { + BaseLayer + + // Header fields + ID uint16 + QR bool + OpCode DNSOpCode + + AA bool // Authoritative answer + TC bool // Truncated + RD bool // Recursion desired + RA bool // Recursion available + Z uint8 // Resrved for future use + + ResponseCode DNSResponseCode + QDCount uint16 // Number of questions to expect + ANCount uint16 // Number of answers to expect + NSCount uint16 // Number of authorities to expect + ARCount uint16 // Number of additional records to expect + + // Entries + Questions []DNSQuestion + Answers []DNSResourceRecord + Authorities []DNSResourceRecord + Additionals []DNSResourceRecord + + // buffer for doing name decoding. We use a single reusable buffer to avoid + // name decoding on a single object via multiple DecodeFromBytes calls + // requiring constant allocation of small byte slices. + buffer []byte +} + +// LayerType returns gopacket.LayerTypeDNS. +func (d *DNS) LayerType() gopacket.LayerType { return LayerTypeDNS } + +// decodeDNS decodes the byte slice into a DNS type. It also +// setups the application Layer in PacketBuilder. +func decodeDNS(data []byte, p gopacket.PacketBuilder) error { + d := &DNS{} + err := d.DecodeFromBytes(data, p) + if err != nil { + return err + } + p.AddLayer(d) + p.SetApplicationLayer(d) + return nil +} + +// DecodeFromBytes decodes the slice into the DNS struct. +func (d *DNS) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + d.buffer = d.buffer[:0] + + if len(data) < 12 { + df.SetTruncated() + return fmt.Errorf("DNS packet too short") + } + + // since there are no further layers, the baselayer's content is + // pointing to this layer + d.BaseLayer = BaseLayer{Contents: data[:len(data)]} + d.ID = binary.BigEndian.Uint16(data[:2]) + d.QR = data[2]&0x80 != 0 + d.OpCode = DNSOpCode(data[2]>>3) & 0x0F + d.AA = data[2]&0x04 != 0 + d.TC = data[2]&0x02 != 0 + d.RD = data[2]&0x01 != 0 + d.RA = data[3]&0x80 != 0 + d.Z = uint8(data[3]>>4) & 0x7 + d.ResponseCode = DNSResponseCode(data[3] & 0xF) + d.QDCount = binary.BigEndian.Uint16(data[4:6]) + d.ANCount = binary.BigEndian.Uint16(data[6:8]) + d.NSCount = binary.BigEndian.Uint16(data[8:10]) + d.ARCount = binary.BigEndian.Uint16(data[10:12]) + + d.Questions = d.Questions[:0] + d.Answers = d.Answers[:0] + d.Authorities = d.Authorities[:0] + d.Additionals = d.Additionals[:0] + + offset := 12 + var err error + for i := 0; i < int(d.QDCount); i++ { + var q DNSQuestion + if offset, err = q.decode(data, offset, df, &d.buffer); err != nil { + return err + } + d.Questions = append(d.Questions, q) + } + + // For some horrible reason, if we do the obvious thing in this loop: + // var r DNSResourceRecord + // if blah := r.decode(blah); err != nil { + // return err + // } + // d.Foo = append(d.Foo, r) + // the Go compiler thinks that 'r' escapes to the heap, causing a malloc for + // every Answer, Authority, and Additional. To get around this, we do + // something really silly: we append an empty resource record to our slice, + // then use the last value in the slice to call decode. Since the value is + // already in the slice, there's no WAY it can escape... on the other hand our + // code is MUCH uglier :( + for i := 0; i < int(d.ANCount); i++ { + d.Answers = append(d.Answers, DNSResourceRecord{}) + if offset, err = d.Answers[i].decode(data, offset, df, &d.buffer); err != nil { + d.Answers = d.Answers[:i] // strip off erroneous value + return err + } + } + for i := 0; i < int(d.NSCount); i++ { + d.Authorities = append(d.Authorities, DNSResourceRecord{}) + if offset, err = d.Authorities[i].decode(data, offset, df, &d.buffer); err != nil { + d.Authorities = d.Authorities[:i] // strip off erroneous value + return err + } + } + for i := 0; i < int(d.ARCount); i++ { + d.Additionals = append(d.Additionals, DNSResourceRecord{}) + if offset, err = d.Additionals[i].decode(data, offset, df, &d.buffer); err != nil { + d.Additionals = d.Additionals[:i] // strip off erroneous value + return err + } + } + + if uint16(len(d.Questions)) != d.QDCount { + return errors.New("Invalid query decoding, not the right number of questions") + } else if uint16(len(d.Answers)) != d.ANCount { + return errors.New("Invalid query decoding, not the right number of answers") + } else if uint16(len(d.Authorities)) != d.NSCount { + return errors.New("Invalid query decoding, not the right number of authorities") + } else if uint16(len(d.Additionals)) != d.ARCount { + return errors.New("Invalid query decoding, not the right number of additionals info") + } + return nil +} + +func (d *DNS) CanDecode() gopacket.LayerClass { + return LayerTypeDNS +} + +func (d *DNS) NextLayerType() gopacket.LayerType { + return gopacket.LayerTypePayload +} + +func (d *DNS) Payload() []byte { + return nil +} + +var maxRecursion = errors.New("max DNS recursion level hit") + +const maxRecursionLevel = 255 + +func decodeName(data []byte, offset int, buffer *[]byte, level int) ([]byte, int, error) { + if level > maxRecursionLevel { + return nil, 0, maxRecursion + } + start := len(*buffer) + index := offset + if data[index] == 0x00 { + return nil, index + 1, nil + } +loop: + for data[index] != 0x00 { + switch data[index] & 0xc0 { + default: + /* RFC 1035 + A domain name represented as a sequence of labels, where + each label consists of a length octet followed by that + number of octets. The domain name terminates with the + zero length octet for the null label of the root. Note + that this field may be an odd number of octets; no + padding is used. + */ + index2 := index + int(data[index]) + 1 + if index2-offset > 255 { + return nil, 0, + fmt.Errorf("dns name is too long") + } + *buffer = append(*buffer, '.') + *buffer = append(*buffer, data[index+1:index2]...) + index = index2 + + case 0xc0: + /* RFC 1035 + The pointer takes the form of a two octet sequence. + + The first two bits are ones. This allows a pointer to + be distinguished from a label, since the label must + begin with two zero bits because labels are restricted + to 63 octets or less. (The 10 and 01 combinations are + reserved for future use.) The OFFSET field specifies + an offset from the start of the message (i.e., the + first octet of the ID field in the domain header). A + zero offset specifies the first byte of the ID field, + etc. + + The compression scheme allows a domain name in a message to be + represented as either: + - a sequence of labels ending in a zero octet + - a pointer + - a sequence of labels ending with a pointer + */ + + offsetp := int(binary.BigEndian.Uint16(data[index:index+2]) & 0x3fff) + // This looks a little tricky, but actually isn't. Because of how + // decodeName is written, calling it appends the decoded name to the + // current buffer. We already have the start of the buffer, then, so + // once this call is done buffer[start:] will contain our full name. + _, _, err := decodeName(data, offsetp, buffer, level+1) + if err != nil { + return nil, 0, err + } + index++ // pointer is two bytes, so add an extra byte here. + break loop + /* EDNS, or other DNS option ? */ + case 0x40: // RFC 2673 + return nil, 0, fmt.Errorf("qname '0x40' - RFC 2673 unsupported yet (data=%x index=%d)", + data[index], index) + + case 0x80: + return nil, 0, fmt.Errorf("qname '0x80' unsupported yet (data=%x index=%d)", + data[index], index) + } + } + return (*buffer)[start+1:], index + 1, nil +} + +type DNSQuestion struct { + Name []byte + Type DNSType + Class DNSClass +} + +func (q *DNSQuestion) decode(data []byte, offset int, df gopacket.DecodeFeedback, buffer *[]byte) (int, error) { + name, endq, err := decodeName(data, offset, buffer, 1) + if err != nil { + return 0, err + } + + q.Name = name + q.Type = DNSType(binary.BigEndian.Uint16(data[endq : endq+2])) + q.Class = DNSClass(binary.BigEndian.Uint16(data[endq+2 : endq+4])) + + return endq + 4, nil +} + +// DNSResourceRecord +// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | | +// / / +// / NAME / +// | | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | TYPE | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | CLASS | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | TTL | +// | | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | RDLENGTH | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--| +// / RDATA / +// / / +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + +type DNSResourceRecord struct { + // Header + Name []byte + Type DNSType + Class DNSClass + TTL uint32 + + // RDATA Raw Values + DataLength uint16 + Data []byte + + // RDATA Decoded Values + IP net.IP + NS, CNAME, PTR []byte + TXTs [][]byte + SOA DNSSOA + SRV DNSSRV + MX DNSMX + + // Undecoded TXT for backward compatibility + TXT []byte +} + +// decode decodes the resource record, returning the total length of the record. +func (rr *DNSResourceRecord) decode(data []byte, offset int, df gopacket.DecodeFeedback, buffer *[]byte) (int, error) { + name, endq, err := decodeName(data, offset, buffer, 1) + if err != nil { + return 0, err + } + + rr.Name = name + rr.Type = DNSType(binary.BigEndian.Uint16(data[endq : endq+2])) + rr.Class = DNSClass(binary.BigEndian.Uint16(data[endq+2 : endq+4])) + rr.TTL = binary.BigEndian.Uint32(data[endq+4 : endq+8]) + rr.DataLength = binary.BigEndian.Uint16(data[endq+8 : endq+10]) + rr.Data = data[endq+10 : endq+10+int(rr.DataLength)] + + if err = rr.decodeRData(data, endq+10, buffer); err != nil { + return 0, err + } + + return endq + 10 + int(rr.DataLength), nil +} + +func (rr *DNSResourceRecord) String() string { + if (rr.Class == DNSClassIN) && ((rr.Type == DNSTypeA) || (rr.Type == DNSTypeAAAA)) { + return net.IP(rr.Data).String() + } + return "..." +} + +func decodeCharacterStrings(data []byte) ([][]byte, error) { + strings := make([][]byte, 0, 1) + end := len(data) + for index, index2 := 0, 0; index != end; index = index2 { + index2 = index + 1 + int(data[index]) // index increases by 1..256 and does not overflow + if index2 > end { + return nil, errors.New("Insufficient data for a ") + } + strings = append(strings, data[index+1:index2]) + } + return strings, nil +} + +func (rr *DNSResourceRecord) decodeRData(data []byte, offset int, buffer *[]byte) error { + switch rr.Type { + case DNSTypeA: + rr.IP = rr.Data + case DNSTypeAAAA: + rr.IP = rr.Data + case DNSTypeTXT, DNSTypeHINFO: + rr.TXT = rr.Data + txts, err := decodeCharacterStrings(rr.Data) + if err != nil { + return err + } + rr.TXTs = txts + case DNSTypeNS: + name, _, err := decodeName(data, offset, buffer, 1) + if err != nil { + return err + } + rr.NS = name + case DNSTypeCNAME: + name, _, err := decodeName(data, offset, buffer, 1) + if err != nil { + return err + } + rr.CNAME = name + case DNSTypePTR: + name, _, err := decodeName(data, offset, buffer, 1) + if err != nil { + return err + } + rr.PTR = name + case DNSTypeSOA: + name, endq, err := decodeName(data, offset, buffer, 1) + if err != nil { + return err + } + rr.SOA.MName = name + name, endq, err = decodeName(data, endq, buffer, 1) + if err != nil { + return err + } + rr.SOA.RName = name + rr.SOA.Serial = binary.BigEndian.Uint32(data[endq : endq+4]) + rr.SOA.Refresh = binary.BigEndian.Uint32(data[endq+4 : endq+8]) + rr.SOA.Retry = binary.BigEndian.Uint32(data[endq+8 : endq+12]) + rr.SOA.Expire = binary.BigEndian.Uint32(data[endq+12 : endq+16]) + rr.SOA.Minimum = binary.BigEndian.Uint32(data[endq+16 : endq+20]) + case DNSTypeMX: + rr.MX.Preference = binary.BigEndian.Uint16(data[offset : offset+2]) + name, _, err := decodeName(data, offset+2, buffer, 1) + if err != nil { + return err + } + rr.MX.Name = name + case DNSTypeSRV: + rr.SRV.Priority = binary.BigEndian.Uint16(data[offset : offset+2]) + rr.SRV.Weight = binary.BigEndian.Uint16(data[offset+2 : offset+4]) + rr.SRV.Port = binary.BigEndian.Uint16(data[offset+4 : offset+6]) + name, _, err := decodeName(data, offset+6, buffer, 1) + if err != nil { + return err + } + rr.SRV.Name = name + } + return nil +} + +type DNSSOA struct { + MName, RName []byte + Serial, Refresh, Retry, Expire, Minimum uint32 +} + +type DNSSRV struct { + Priority, Weight, Port uint16 + Name []byte +} + +type DNSMX struct { + Preference uint16 + Name []byte +} diff --git a/vendor/github.com/google/gopacket/layers/doc.go b/vendor/github.com/google/gopacket/layers/doc.go new file mode 100644 index 0000000..3c882c3 --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/doc.go @@ -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 diff --git a/vendor/github.com/google/gopacket/layers/dot11.go b/vendor/github.com/google/gopacket/layers/dot11.go new file mode 100644 index 0000000..fdf949e --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/dot11.go @@ -0,0 +1,1262 @@ +// 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. + +// See http://standards.ieee.org/findstds/standard/802.11-2012.html for info on +// all of the layers in this file. + +package layers + +import ( + "bytes" + "encoding/binary" + "fmt" + "github.com/google/gopacket" + "hash/crc32" + "net" +) + +// Dot11Flags contains the set of 8 flags in the IEEE 802.11 frame control +// header, all in one place. +type Dot11Flags uint8 + +const ( + Dot11FlagsToDS Dot11Flags = 1 << iota + Dot11FlagsFromDS + Dot11FlagsMF + Dot11FlagsRetry + Dot11FlagsPowerManagement + Dot11FlagsMD + Dot11FlagsWEP + Dot11FlagsOrder +) + +func (d Dot11Flags) ToDS() bool { + return d&Dot11FlagsToDS != 0 +} +func (d Dot11Flags) FromDS() bool { + return d&Dot11FlagsFromDS != 0 +} +func (d Dot11Flags) MF() bool { + return d&Dot11FlagsMF != 0 +} +func (d Dot11Flags) Retry() bool { + return d&Dot11FlagsRetry != 0 +} +func (d Dot11Flags) PowerManagement() bool { + return d&Dot11FlagsPowerManagement != 0 +} +func (d Dot11Flags) MD() bool { + return d&Dot11FlagsMD != 0 +} +func (d Dot11Flags) WEP() bool { + return d&Dot11FlagsWEP != 0 +} +func (d Dot11Flags) Order() bool { + return d&Dot11FlagsOrder != 0 +} + +// String provides a human readable string for Dot11Flags. +// This string is possibly subject to change over time; if you're storing this +// persistently, you should probably store the Dot11Flags value, not its string. +func (a Dot11Flags) String() string { + var out bytes.Buffer + if a.ToDS() { + out.WriteString("TO-DS,") + } + if a.FromDS() { + out.WriteString("FROM-DS,") + } + if a.MF() { + out.WriteString("MF,") + } + if a.Retry() { + out.WriteString("Retry,") + } + if a.PowerManagement() { + out.WriteString("PowerManagement,") + } + if a.MD() { + out.WriteString("MD,") + } + if a.WEP() { + out.WriteString("WEP,") + } + if a.Order() { + out.WriteString("Order,") + } + + if length := out.Len(); length > 0 { + return string(out.Bytes()[:length-1]) // strip final comma + } + return "" +} + +type Dot11Reason uint16 + +// TODO: Verify these reasons, and append more reasons if necessary. + +const ( + Dot11ReasonReserved Dot11Reason = 1 + Dot11ReasonUnspecified Dot11Reason = 2 + Dot11ReasonAuthExpired Dot11Reason = 3 + Dot11ReasonDeauthStLeaving Dot11Reason = 4 + Dot11ReasonInactivity Dot11Reason = 5 + Dot11ReasonApFull Dot11Reason = 6 + Dot11ReasonClass2FromNonAuth Dot11Reason = 7 + Dot11ReasonClass3FromNonAss Dot11Reason = 8 + Dot11ReasonDisasStLeaving Dot11Reason = 9 + Dot11ReasonStNotAuth Dot11Reason = 10 +) + +// String provides a human readable string for Dot11Reason. +// This string is possibly subject to change over time; if you're storing this +// persistently, you should probably store the Dot11Reason value, not its string. +func (a Dot11Reason) String() string { + switch a { + case Dot11ReasonReserved: + return "Reserved" + case Dot11ReasonUnspecified: + return "Unspecified" + case Dot11ReasonAuthExpired: + return "Auth. expired" + case Dot11ReasonDeauthStLeaving: + return "Deauth. st. leaving" + case Dot11ReasonInactivity: + return "Inactivity" + case Dot11ReasonApFull: + return "Ap. full" + case Dot11ReasonClass2FromNonAuth: + return "Class2 from non auth." + case Dot11ReasonClass3FromNonAss: + return "Class3 from non ass." + case Dot11ReasonDisasStLeaving: + return "Disass st. leaving" + case Dot11ReasonStNotAuth: + return "St. not auth." + default: + return "Unknown reason" + } +} + +type Dot11Status uint16 + +const ( + Dot11StatusSuccess Dot11Status = 0 + Dot11StatusFailure Dot11Status = 1 // Unspecified failure + Dot11StatusCannotSupportAllCapabilities Dot11Status = 10 // Cannot support all requested capabilities in the Capability Information field + Dot11StatusInabilityExistsAssociation Dot11Status = 11 // Reassociation denied due to inability to confirm that association exists + Dot11StatusAssociationDenied Dot11Status = 12 // Association denied due to reason outside the scope of this standard + Dot11StatusAlgorithmUnsupported Dot11Status = 13 // Responding station does not support the specified authentication algorithm + Dot11StatusOufOfExpectedSequence Dot11Status = 14 // Received an Authentication frame with authentication transaction sequence number out of expected sequence + Dot11StatusChallengeFailure Dot11Status = 15 // Authentication rejected because of challenge failure + Dot11StatusTimeout Dot11Status = 16 // Authentication rejected due to timeout waiting for next frame in sequence + Dot11StatusAPUnableToHandle Dot11Status = 17 // Association denied because AP is unable to handle additional associated stations + Dot11StatusRateUnsupported Dot11Status = 18 // Association denied due to requesting station not supporting all of the data rates in the BSSBasicRateSet parameter +) + +// String provides a human readable string for Dot11Status. +// This string is possibly subject to change over time; if you're storing this +// persistently, you should probably store the Dot11Status value, not its string. +func (a Dot11Status) String() string { + switch a { + case Dot11StatusSuccess: + return "success" + case Dot11StatusFailure: + return "failure" + case Dot11StatusCannotSupportAllCapabilities: + return "cannot-support-all-capabilities" + case Dot11StatusInabilityExistsAssociation: + return "inability-exists-association" + case Dot11StatusAssociationDenied: + return "association-denied" + case Dot11StatusAlgorithmUnsupported: + return "algorithm-unsupported" + case Dot11StatusOufOfExpectedSequence: + return "out-of-expected-sequence" + case Dot11StatusChallengeFailure: + return "challenge-failure" + case Dot11StatusTimeout: + return "timeout" + case Dot11StatusAPUnableToHandle: + return "ap-unable-to-handle" + case Dot11StatusRateUnsupported: + return "rate-unsupported" + default: + return "unknown status" + } +} + +type Dot11AckPolicy uint8 + +const ( + Dot11AckPolicyNormal Dot11AckPolicy = 0 + Dot11AckPolicyNone Dot11AckPolicy = 1 + Dot11AckPolicyNoExplicit Dot11AckPolicy = 2 + Dot11AckPolicyBlock Dot11AckPolicy = 3 +) + +// String provides a human readable string for Dot11AckPolicy. +// This string is possibly subject to change over time; if you're storing this +// persistently, you should probably store the Dot11AckPolicy value, not its string. +func (a Dot11AckPolicy) String() string { + switch a { + case Dot11AckPolicyNormal: + return "normal-ack" + case Dot11AckPolicyNone: + return "no-ack" + case Dot11AckPolicyNoExplicit: + return "no-explicit-ack" + case Dot11AckPolicyBlock: + return "block-ack" + default: + return "unknown-ack-policy" + } +} + +type Dot11Algorithm uint16 + +const ( + Dot11AlgorithmOpen Dot11Algorithm = 0 + Dot11AlgorithmSharedKey Dot11Algorithm = 1 +) + +// String provides a human readable string for Dot11Algorithm. +// This string is possibly subject to change over time; if you're storing this +// persistently, you should probably store the Dot11Algorithm value, not its string. +func (a Dot11Algorithm) String() string { + switch a { + case Dot11AlgorithmOpen: + return "open" + case Dot11AlgorithmSharedKey: + return "shared-key" + default: + return "unknown-algorithm" + } +} + +type Dot11InformationElementID uint8 + +// TODO: Verify these element ids, and append more ids if more. + +const ( + Dot11InformationElementIDSSID Dot11InformationElementID = 0 + Dot11InformationElementIDRates Dot11InformationElementID = 1 + Dot11InformationElementIDFHSet Dot11InformationElementID = 2 + Dot11InformationElementIDDSSet Dot11InformationElementID = 3 + Dot11InformationElementIDCFSet Dot11InformationElementID = 4 + Dot11InformationElementIDTIM Dot11InformationElementID = 5 + Dot11InformationElementIDIBSSSet Dot11InformationElementID = 6 + Dot11InformationElementIDChallenge Dot11InformationElementID = 16 + Dot11InformationElementIDERPInfo Dot11InformationElementID = 42 + Dot11InformationElementIDQOSCapability Dot11InformationElementID = 46 + Dot11InformationElementIDERPInfo2 Dot11InformationElementID = 47 + Dot11InformationElementIDRSNInfo Dot11InformationElementID = 48 + Dot11InformationElementIDESRates Dot11InformationElementID = 50 + Dot11InformationElementIDVendor Dot11InformationElementID = 221 + Dot11InformationElementIDReserved Dot11InformationElementID = 68 +) + +// String provides a human readable string for Dot11InformationElementID. +// This string is possibly subject to change over time; if you're storing this +// persistently, you should probably store the Dot11InformationElementID value, +// not its string. +func (a Dot11InformationElementID) String() string { + switch a { + case Dot11InformationElementIDSSID: + return "SSID" + case Dot11InformationElementIDRates: + return "Rates" + case Dot11InformationElementIDFHSet: + return "FHset" + case Dot11InformationElementIDDSSet: + return "DSset" + case Dot11InformationElementIDCFSet: + return "CFset" + case Dot11InformationElementIDTIM: + return "TIM" + case Dot11InformationElementIDIBSSSet: + return "IBSSset" + case Dot11InformationElementIDChallenge: + return "Challenge" + case Dot11InformationElementIDERPInfo: + return "ERPinfo" + case Dot11InformationElementIDQOSCapability: + return "QOS capability" + case Dot11InformationElementIDERPInfo2: + return "ERPinfo2" + case Dot11InformationElementIDRSNInfo: + return "RSNinfo" + case Dot11InformationElementIDESRates: + return "ESrates" + case Dot11InformationElementIDVendor: + return "Vendor" + case Dot11InformationElementIDReserved: + return "Reserved" + default: + return "Unknown information element id" + } +} + +// Dot11 provides an IEEE 802.11 base packet header. +// See http://standards.ieee.org/findstds/standard/802.11-2012.html +// for excrutiating detail. +type Dot11 struct { + BaseLayer + Type Dot11Type + Proto uint8 + Flags Dot11Flags + DurationID uint16 + Address1 net.HardwareAddr + Address2 net.HardwareAddr + Address3 net.HardwareAddr + Address4 net.HardwareAddr + SequenceNumber uint16 + FragmentNumber uint16 + Checksum uint32 +} + +func decodeDot11(data []byte, p gopacket.PacketBuilder) error { + d := &Dot11{} + return decodingLayerDecoder(d, data, p) +} + +func (m *Dot11) LayerType() gopacket.LayerType { return LayerTypeDot11 } +func (m *Dot11) CanDecode() gopacket.LayerClass { return LayerTypeDot11 } +func (m *Dot11) NextLayerType() gopacket.LayerType { + if m.Flags.WEP() { + return (LayerTypeDot11WEP) + } + + return m.Type.LayerType() +} + +func (m *Dot11) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + if len(data) < 10 { + df.SetTruncated() + return fmt.Errorf("Dot11 length %v too short, %v required", len(data), 10) + } + m.Type = Dot11Type((data[0])&0xFC) >> 2 + + m.Proto = uint8(data[0]) & 0x0003 + m.Flags = Dot11Flags(data[1]) + m.DurationID = binary.LittleEndian.Uint16(data[2:4]) + m.Address1 = net.HardwareAddr(data[4:10]) + + offset := 10 + + mainType := m.Type.MainType() + + switch mainType { + case Dot11TypeCtrl: + switch m.Type { + case Dot11TypeCtrlRTS, Dot11TypeCtrlPowersavePoll, Dot11TypeCtrlCFEnd, Dot11TypeCtrlCFEndAck: + if len(data) < offset+6 { + df.SetTruncated() + return fmt.Errorf("Dot11 length %v too short, %v required", len(data), offset+6) + } + m.Address2 = net.HardwareAddr(data[offset : offset+6]) + offset += 6 + } + case Dot11TypeMgmt, Dot11TypeData: + if len(data) < offset+14 { + df.SetTruncated() + return fmt.Errorf("Dot11 length %v too short, %v required", len(data), offset+14) + } + m.Address2 = net.HardwareAddr(data[offset : offset+6]) + offset += 6 + m.Address3 = net.HardwareAddr(data[offset : offset+6]) + offset += 6 + + m.SequenceNumber = (binary.LittleEndian.Uint16(data[offset:offset+2]) & 0xFFF0) >> 4 + m.FragmentNumber = (binary.LittleEndian.Uint16(data[offset:offset+2]) & 0x000F) + offset += 2 + } + + if mainType == Dot11TypeData && m.Flags.FromDS() && m.Flags.ToDS() { + if len(data) < offset+6 { + df.SetTruncated() + return fmt.Errorf("Dot11 length %v too short, %v required", len(data), offset+6) + } + m.Address4 = net.HardwareAddr(data[offset : offset+6]) + offset += 6 + } + + m.BaseLayer = BaseLayer{Contents: data[0:offset], Payload: data[offset : len(data)-4]} + m.Checksum = binary.LittleEndian.Uint32(data[len(data)-4 : len(data)]) + return nil +} + +func (m *Dot11) ChecksumValid() bool { + // only for CTRL and MGMT frames + h := crc32.NewIEEE() + h.Write(m.Contents) + h.Write(m.Payload) + return m.Checksum == h.Sum32() +} + +// Dot11Mgmt is a base for all IEEE 802.11 management layers. +type Dot11Mgmt struct { + BaseLayer +} + +func (m *Dot11Mgmt) NextLayerType() gopacket.LayerType { return gopacket.LayerTypePayload } +func (m *Dot11Mgmt) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + m.Contents = data + return nil +} + +// Dot11Ctrl is a base for all IEEE 802.11 control layers. +type Dot11Ctrl struct { + BaseLayer +} + +func (m *Dot11Ctrl) NextLayerType() gopacket.LayerType { return gopacket.LayerTypePayload } + +func (m *Dot11Ctrl) LayerType() gopacket.LayerType { return LayerTypeDot11Ctrl } +func (m *Dot11Ctrl) CanDecode() gopacket.LayerClass { return LayerTypeDot11Ctrl } +func (m *Dot11Ctrl) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + m.Contents = data + return nil +} + +func decodeDot11Ctrl(data []byte, p gopacket.PacketBuilder) error { + d := &Dot11Ctrl{} + return decodingLayerDecoder(d, data, p) +} + +// Dot11WEP contains WEP encrpted IEEE 802.11 data. +type Dot11WEP struct { + BaseLayer +} + +func (m *Dot11WEP) NextLayerType() gopacket.LayerType { return LayerTypeLLC } + +func (m *Dot11WEP) LayerType() gopacket.LayerType { return LayerTypeDot11WEP } +func (m *Dot11WEP) CanDecode() gopacket.LayerClass { return LayerTypeDot11WEP } +func (m *Dot11WEP) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + m.Contents = data + return nil +} + +func decodeDot11WEP(data []byte, p gopacket.PacketBuilder) error { + d := &Dot11WEP{} + return decodingLayerDecoder(d, data, p) +} + +// Dot11Data is a base for all IEEE 802.11 data layers. +type Dot11Data struct { + BaseLayer +} + +func (m *Dot11Data) NextLayerType() gopacket.LayerType { return LayerTypeLLC } + +func (m *Dot11Data) LayerType() gopacket.LayerType { return LayerTypeDot11Data } +func (m *Dot11Data) CanDecode() gopacket.LayerClass { return LayerTypeDot11Data } +func (m *Dot11Data) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + m.Payload = data + return nil +} + +func decodeDot11Data(data []byte, p gopacket.PacketBuilder) error { + d := &Dot11Data{} + return decodingLayerDecoder(d, data, p) +} + +type Dot11DataCFAck struct { + Dot11Data +} + +func decodeDot11DataCFAck(data []byte, p gopacket.PacketBuilder) error { + d := &Dot11DataCFAck{} + return decodingLayerDecoder(d, data, p) +} + +func (m *Dot11DataCFAck) LayerType() gopacket.LayerType { return LayerTypeDot11DataCFAck } +func (m *Dot11DataCFAck) CanDecode() gopacket.LayerClass { return LayerTypeDot11DataCFAck } +func (m *Dot11DataCFAck) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + return m.Dot11Data.DecodeFromBytes(data, df) +} + +type Dot11DataCFPoll struct { + Dot11Data +} + +func decodeDot11DataCFPoll(data []byte, p gopacket.PacketBuilder) error { + d := &Dot11DataCFPoll{} + return decodingLayerDecoder(d, data, p) +} + +func (m *Dot11DataCFPoll) LayerType() gopacket.LayerType { return LayerTypeDot11DataCFPoll } +func (m *Dot11DataCFPoll) CanDecode() gopacket.LayerClass { return LayerTypeDot11DataCFPoll } +func (m *Dot11DataCFPoll) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + return m.Dot11Data.DecodeFromBytes(data, df) +} + +type Dot11DataCFAckPoll struct { + Dot11Data +} + +func decodeDot11DataCFAckPoll(data []byte, p gopacket.PacketBuilder) error { + d := &Dot11DataCFAckPoll{} + return decodingLayerDecoder(d, data, p) +} + +func (m *Dot11DataCFAckPoll) LayerType() gopacket.LayerType { return LayerTypeDot11DataCFAckPoll } +func (m *Dot11DataCFAckPoll) CanDecode() gopacket.LayerClass { return LayerTypeDot11DataCFAckPoll } +func (m *Dot11DataCFAckPoll) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + return m.Dot11Data.DecodeFromBytes(data, df) +} + +type Dot11DataNull struct { + Dot11Data +} + +func decodeDot11DataNull(data []byte, p gopacket.PacketBuilder) error { + d := &Dot11DataNull{} + return decodingLayerDecoder(d, data, p) +} + +func (m *Dot11DataNull) LayerType() gopacket.LayerType { return LayerTypeDot11DataNull } +func (m *Dot11DataNull) CanDecode() gopacket.LayerClass { return LayerTypeDot11DataNull } +func (m *Dot11DataNull) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + return m.Dot11Data.DecodeFromBytes(data, df) +} + +type Dot11DataCFAckNoData struct { + Dot11Data +} + +func decodeDot11DataCFAckNoData(data []byte, p gopacket.PacketBuilder) error { + d := &Dot11DataCFAckNoData{} + return decodingLayerDecoder(d, data, p) +} + +func (m *Dot11DataCFAckNoData) LayerType() gopacket.LayerType { return LayerTypeDot11DataCFAckNoData } +func (m *Dot11DataCFAckNoData) CanDecode() gopacket.LayerClass { return LayerTypeDot11DataCFAckNoData } +func (m *Dot11DataCFAckNoData) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + return m.Dot11Data.DecodeFromBytes(data, df) +} + +type Dot11DataCFPollNoData struct { + Dot11Data +} + +func decodeDot11DataCFPollNoData(data []byte, p gopacket.PacketBuilder) error { + d := &Dot11DataCFPollNoData{} + return decodingLayerDecoder(d, data, p) +} + +func (m *Dot11DataCFPollNoData) LayerType() gopacket.LayerType { return LayerTypeDot11DataCFPollNoData } +func (m *Dot11DataCFPollNoData) CanDecode() gopacket.LayerClass { return LayerTypeDot11DataCFPollNoData } +func (m *Dot11DataCFPollNoData) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + return m.Dot11Data.DecodeFromBytes(data, df) +} + +type Dot11DataCFAckPollNoData struct { + Dot11Data +} + +func decodeDot11DataCFAckPollNoData(data []byte, p gopacket.PacketBuilder) error { + d := &Dot11DataCFAckPollNoData{} + return decodingLayerDecoder(d, data, p) +} + +func (m *Dot11DataCFAckPollNoData) LayerType() gopacket.LayerType { + return LayerTypeDot11DataCFAckPollNoData +} +func (m *Dot11DataCFAckPollNoData) CanDecode() gopacket.LayerClass { + return LayerTypeDot11DataCFAckPollNoData +} +func (m *Dot11DataCFAckPollNoData) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + return m.Dot11Data.DecodeFromBytes(data, df) +} + +type Dot11DataQOS struct { + Dot11Ctrl + TID uint8 /* Traffic IDentifier */ + EOSP bool /* End of service period */ + AckPolicy Dot11AckPolicy + TXOP uint8 +} + +func (m *Dot11DataQOS) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + if len(data) < 4 { + df.SetTruncated() + return fmt.Errorf("Dot11DataQOS length %v too short, %v required", len(data), 4) + } + m.TID = (uint8(data[0]) & 0x0F) + m.EOSP = (uint8(data[0]) & 0x10) == 0x10 + m.AckPolicy = Dot11AckPolicy((uint8(data[0]) & 0x60) >> 5) + m.TXOP = uint8(data[1]) + // TODO: Mesh Control bytes 2:4 + m.BaseLayer = BaseLayer{Contents: data[0:4], Payload: data[4:]} + return nil +} + +type Dot11DataQOSData struct { + Dot11DataQOS +} + +func decodeDot11DataQOSData(data []byte, p gopacket.PacketBuilder) error { + d := &Dot11DataQOSData{} + return decodingLayerDecoder(d, data, p) +} + +func (m *Dot11DataQOSData) LayerType() gopacket.LayerType { return LayerTypeDot11DataQOSData } +func (m *Dot11DataQOSData) CanDecode() gopacket.LayerClass { return LayerTypeDot11DataQOSData } + +func (m *Dot11DataQOSData) NextLayerType() gopacket.LayerType { + return LayerTypeDot11Data +} + +type Dot11DataQOSDataCFAck struct { + Dot11DataQOS +} + +func decodeDot11DataQOSDataCFAck(data []byte, p gopacket.PacketBuilder) error { + d := &Dot11DataQOSDataCFAck{} + return decodingLayerDecoder(d, data, p) +} + +func (m *Dot11DataQOSDataCFAck) LayerType() gopacket.LayerType { return LayerTypeDot11DataQOSDataCFAck } +func (m *Dot11DataQOSDataCFAck) CanDecode() gopacket.LayerClass { return LayerTypeDot11DataQOSDataCFAck } +func (m *Dot11DataQOSDataCFAck) NextLayerType() gopacket.LayerType { return LayerTypeDot11DataCFAck } + +type Dot11DataQOSDataCFPoll struct { + Dot11DataQOS +} + +func decodeDot11DataQOSDataCFPoll(data []byte, p gopacket.PacketBuilder) error { + d := &Dot11DataQOSDataCFPoll{} + return decodingLayerDecoder(d, data, p) +} + +func (m *Dot11DataQOSDataCFPoll) LayerType() gopacket.LayerType { + return LayerTypeDot11DataQOSDataCFPoll +} +func (m *Dot11DataQOSDataCFPoll) CanDecode() gopacket.LayerClass { + return LayerTypeDot11DataQOSDataCFPoll +} +func (m *Dot11DataQOSDataCFPoll) NextLayerType() gopacket.LayerType { return LayerTypeDot11DataCFPoll } + +type Dot11DataQOSDataCFAckPoll struct { + Dot11DataQOS +} + +func decodeDot11DataQOSDataCFAckPoll(data []byte, p gopacket.PacketBuilder) error { + d := &Dot11DataQOSDataCFAckPoll{} + return decodingLayerDecoder(d, data, p) +} + +func (m *Dot11DataQOSDataCFAckPoll) LayerType() gopacket.LayerType { + return LayerTypeDot11DataQOSDataCFAckPoll +} +func (m *Dot11DataQOSDataCFAckPoll) CanDecode() gopacket.LayerClass { + return LayerTypeDot11DataQOSDataCFAckPoll +} +func (m *Dot11DataQOSDataCFAckPoll) NextLayerType() gopacket.LayerType { + return LayerTypeDot11DataCFAckPoll +} + +type Dot11DataQOSNull struct { + Dot11DataQOS +} + +func decodeDot11DataQOSNull(data []byte, p gopacket.PacketBuilder) error { + d := &Dot11DataQOSNull{} + return decodingLayerDecoder(d, data, p) +} + +func (m *Dot11DataQOSNull) LayerType() gopacket.LayerType { return LayerTypeDot11DataQOSNull } +func (m *Dot11DataQOSNull) CanDecode() gopacket.LayerClass { return LayerTypeDot11DataQOSNull } +func (m *Dot11DataQOSNull) NextLayerType() gopacket.LayerType { return LayerTypeDot11DataNull } + +type Dot11DataQOSCFPollNoData struct { + Dot11DataQOS +} + +func decodeDot11DataQOSCFPollNoData(data []byte, p gopacket.PacketBuilder) error { + d := &Dot11DataQOSCFPollNoData{} + return decodingLayerDecoder(d, data, p) +} + +func (m *Dot11DataQOSCFPollNoData) LayerType() gopacket.LayerType { + return LayerTypeDot11DataQOSCFPollNoData +} +func (m *Dot11DataQOSCFPollNoData) CanDecode() gopacket.LayerClass { + return LayerTypeDot11DataQOSCFPollNoData +} +func (m *Dot11DataQOSCFPollNoData) NextLayerType() gopacket.LayerType { + return LayerTypeDot11DataCFPollNoData +} + +type Dot11DataQOSCFAckPollNoData struct { + Dot11DataQOS +} + +func decodeDot11DataQOSCFAckPollNoData(data []byte, p gopacket.PacketBuilder) error { + d := &Dot11DataQOSCFAckPollNoData{} + return decodingLayerDecoder(d, data, p) +} + +func (m *Dot11DataQOSCFAckPollNoData) LayerType() gopacket.LayerType { + return LayerTypeDot11DataQOSCFAckPollNoData +} +func (m *Dot11DataQOSCFAckPollNoData) CanDecode() gopacket.LayerClass { + return LayerTypeDot11DataQOSCFAckPollNoData +} +func (m *Dot11DataQOSCFAckPollNoData) NextLayerType() gopacket.LayerType { + return LayerTypeDot11DataCFAckPollNoData +} + +type Dot11InformationElement struct { + BaseLayer + ID Dot11InformationElementID + Length uint8 + OUI []byte + Info []byte +} + +func (m *Dot11InformationElement) LayerType() gopacket.LayerType { + return LayerTypeDot11InformationElement +} +func (m *Dot11InformationElement) CanDecode() gopacket.LayerClass { + return LayerTypeDot11InformationElement +} + +func (m *Dot11InformationElement) NextLayerType() gopacket.LayerType { + return LayerTypeDot11InformationElement +} + +func (m *Dot11InformationElement) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + if len(data) < 2 { + df.SetTruncated() + return fmt.Errorf("Dot11InformationElement length %v too short, %v required", len(data), 2) + } + m.ID = Dot11InformationElementID(data[0]) + m.Length = data[1] + offset := int(2) + + if len(data) < offset+int(m.Length) { + df.SetTruncated() + return fmt.Errorf("Dot11InformationElement length %v too short, %v required", len(data), offset+int(m.Length)) + } + if m.ID == 221 { + // Vendor extension + m.OUI = data[offset : offset+4] + m.Info = data[offset+4 : offset+int(m.Length)] + } else { + m.Info = data[offset : offset+int(m.Length)] + } + + offset += int(m.Length) + + m.BaseLayer = BaseLayer{Contents: data[:offset], Payload: data[offset:]} + return nil +} + +func (d *Dot11InformationElement) String() string { + if d.ID == 0 { + return fmt.Sprintf("802.11 Information Element (SSID: %v)", string(d.Info)) + } else if d.ID == 1 { + rates := "" + for i := 0; i < len(d.Info); i++ { + if d.Info[i]&0x80 == 0 { + rates += fmt.Sprintf("%.1f ", float32(d.Info[i])*0.5) + } else { + rates += fmt.Sprintf("%.1f* ", float32(d.Info[i]&0x7F)*0.5) + } + } + return fmt.Sprintf("802.11 Information Element (Rates: %s Mbit)", rates) + } else if d.ID == 221 { + return fmt.Sprintf("802.11 Information Element (Vendor: ID: %v, Length: %v, OUI: %X, Info: %X)", d.ID, d.Length, d.OUI, d.Info) + } else { + return fmt.Sprintf("802.11 Information Element (ID: %v, Length: %v, Info: %X)", d.ID, d.Length, d.Info) + } +} + +func (m Dot11InformationElement) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error { + length := len(m.Info) + len(m.OUI) + if buf, err := b.PrependBytes(2 + length); err != nil { + return err + } else { + buf[0] = uint8(m.ID) + buf[1] = uint8(length) + copy(buf[2:], m.OUI) + copy(buf[2+len(m.OUI):], m.Info) + } + return nil +} + +func decodeDot11InformationElement(data []byte, p gopacket.PacketBuilder) error { + d := &Dot11InformationElement{} + return decodingLayerDecoder(d, data, p) +} + +type Dot11CtrlCTS struct { + Dot11Ctrl +} + +func decodeDot11CtrlCTS(data []byte, p gopacket.PacketBuilder) error { + d := &Dot11CtrlCTS{} + return decodingLayerDecoder(d, data, p) +} + +func (m *Dot11CtrlCTS) LayerType() gopacket.LayerType { + return LayerTypeDot11CtrlCTS +} +func (m *Dot11CtrlCTS) CanDecode() gopacket.LayerClass { + return LayerTypeDot11CtrlCTS +} +func (m *Dot11CtrlCTS) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + return m.Dot11Ctrl.DecodeFromBytes(data, df) +} + +type Dot11CtrlRTS struct { + Dot11Ctrl +} + +func decodeDot11CtrlRTS(data []byte, p gopacket.PacketBuilder) error { + d := &Dot11CtrlRTS{} + return decodingLayerDecoder(d, data, p) +} + +func (m *Dot11CtrlRTS) LayerType() gopacket.LayerType { + return LayerTypeDot11CtrlRTS +} +func (m *Dot11CtrlRTS) CanDecode() gopacket.LayerClass { + return LayerTypeDot11CtrlRTS +} +func (m *Dot11CtrlRTS) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + return m.Dot11Ctrl.DecodeFromBytes(data, df) +} + +type Dot11CtrlBlockAckReq struct { + Dot11Ctrl +} + +func decodeDot11CtrlBlockAckReq(data []byte, p gopacket.PacketBuilder) error { + d := &Dot11CtrlBlockAckReq{} + return decodingLayerDecoder(d, data, p) +} + +func (m *Dot11CtrlBlockAckReq) LayerType() gopacket.LayerType { + return LayerTypeDot11CtrlBlockAckReq +} +func (m *Dot11CtrlBlockAckReq) CanDecode() gopacket.LayerClass { + return LayerTypeDot11CtrlBlockAckReq +} +func (m *Dot11CtrlBlockAckReq) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + return m.Dot11Ctrl.DecodeFromBytes(data, df) +} + +type Dot11CtrlBlockAck struct { + Dot11Ctrl +} + +func decodeDot11CtrlBlockAck(data []byte, p gopacket.PacketBuilder) error { + d := &Dot11CtrlBlockAck{} + return decodingLayerDecoder(d, data, p) +} + +func (m *Dot11CtrlBlockAck) LayerType() gopacket.LayerType { return LayerTypeDot11CtrlBlockAck } +func (m *Dot11CtrlBlockAck) CanDecode() gopacket.LayerClass { return LayerTypeDot11CtrlBlockAck } +func (m *Dot11CtrlBlockAck) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + return m.Dot11Ctrl.DecodeFromBytes(data, df) +} + +type Dot11CtrlPowersavePoll struct { + Dot11Ctrl +} + +func decodeDot11CtrlPowersavePoll(data []byte, p gopacket.PacketBuilder) error { + d := &Dot11CtrlPowersavePoll{} + return decodingLayerDecoder(d, data, p) +} + +func (m *Dot11CtrlPowersavePoll) LayerType() gopacket.LayerType { + return LayerTypeDot11CtrlPowersavePoll +} +func (m *Dot11CtrlPowersavePoll) CanDecode() gopacket.LayerClass { + return LayerTypeDot11CtrlPowersavePoll +} +func (m *Dot11CtrlPowersavePoll) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + return m.Dot11Ctrl.DecodeFromBytes(data, df) +} + +type Dot11CtrlAck struct { + Dot11Ctrl +} + +func decodeDot11CtrlAck(data []byte, p gopacket.PacketBuilder) error { + d := &Dot11CtrlAck{} + return decodingLayerDecoder(d, data, p) +} + +func (m *Dot11CtrlAck) LayerType() gopacket.LayerType { return LayerTypeDot11CtrlAck } +func (m *Dot11CtrlAck) CanDecode() gopacket.LayerClass { return LayerTypeDot11CtrlAck } +func (m *Dot11CtrlAck) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + return m.Dot11Ctrl.DecodeFromBytes(data, df) +} + +type Dot11CtrlCFEnd struct { + Dot11Ctrl +} + +func decodeDot11CtrlCFEnd(data []byte, p gopacket.PacketBuilder) error { + d := &Dot11CtrlCFEnd{} + return decodingLayerDecoder(d, data, p) +} + +func (m *Dot11CtrlCFEnd) LayerType() gopacket.LayerType { + return LayerTypeDot11CtrlCFEnd +} +func (m *Dot11CtrlCFEnd) CanDecode() gopacket.LayerClass { + return LayerTypeDot11CtrlCFEnd +} +func (m *Dot11CtrlCFEnd) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + return m.Dot11Ctrl.DecodeFromBytes(data, df) +} + +type Dot11CtrlCFEndAck struct { + Dot11Ctrl +} + +func decodeDot11CtrlCFEndAck(data []byte, p gopacket.PacketBuilder) error { + d := &Dot11CtrlCFEndAck{} + return decodingLayerDecoder(d, data, p) +} + +func (m *Dot11CtrlCFEndAck) LayerType() gopacket.LayerType { + return LayerTypeDot11CtrlCFEndAck +} +func (m *Dot11CtrlCFEndAck) CanDecode() gopacket.LayerClass { + return LayerTypeDot11CtrlCFEndAck +} +func (m *Dot11CtrlCFEndAck) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + return m.Dot11Ctrl.DecodeFromBytes(data, df) +} + +type Dot11MgmtAssociationReq struct { + Dot11Mgmt + CapabilityInfo uint16 + ListenInterval uint16 +} + +func decodeDot11MgmtAssociationReq(data []byte, p gopacket.PacketBuilder) error { + d := &Dot11MgmtAssociationReq{} + return decodingLayerDecoder(d, data, p) +} + +func (m *Dot11MgmtAssociationReq) LayerType() gopacket.LayerType { + return LayerTypeDot11MgmtAssociationReq +} +func (m *Dot11MgmtAssociationReq) CanDecode() gopacket.LayerClass { + return LayerTypeDot11MgmtAssociationReq +} +func (m *Dot11MgmtAssociationReq) NextLayerType() gopacket.LayerType { + return LayerTypeDot11InformationElement +} +func (m *Dot11MgmtAssociationReq) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + if len(data) < 4 { + df.SetTruncated() + return fmt.Errorf("Dot11MgmtAssociationReq length %v too short, %v required", len(data), 4) + } + m.CapabilityInfo = binary.LittleEndian.Uint16(data[0:2]) + m.ListenInterval = binary.LittleEndian.Uint16(data[2:4]) + m.Payload = data[4:] + return m.Dot11Mgmt.DecodeFromBytes(data, df) +} + +type Dot11MgmtAssociationResp struct { + Dot11Mgmt + CapabilityInfo uint16 + Status Dot11Status + AID uint16 +} + +func decodeDot11MgmtAssociationResp(data []byte, p gopacket.PacketBuilder) error { + d := &Dot11MgmtAssociationResp{} + return decodingLayerDecoder(d, data, p) +} + +func (m *Dot11MgmtAssociationResp) CanDecode() gopacket.LayerClass { + return LayerTypeDot11MgmtAssociationResp +} +func (m *Dot11MgmtAssociationResp) LayerType() gopacket.LayerType { + return LayerTypeDot11MgmtAssociationResp +} +func (m *Dot11MgmtAssociationResp) NextLayerType() gopacket.LayerType { + return LayerTypeDot11InformationElement +} +func (m *Dot11MgmtAssociationResp) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + if len(data) < 6 { + df.SetTruncated() + return fmt.Errorf("Dot11MgmtAssociationResp length %v too short, %v required", len(data), 6) + } + m.CapabilityInfo = binary.LittleEndian.Uint16(data[0:2]) + m.Status = Dot11Status(binary.LittleEndian.Uint16(data[2:4])) + m.AID = binary.LittleEndian.Uint16(data[4:6]) + m.Payload = data[6:] + return m.Dot11Mgmt.DecodeFromBytes(data, df) +} + +type Dot11MgmtReassociationReq struct { + Dot11Mgmt + CapabilityInfo uint16 + ListenInterval uint16 + CurrentApAddress net.HardwareAddr +} + +func decodeDot11MgmtReassociationReq(data []byte, p gopacket.PacketBuilder) error { + d := &Dot11MgmtReassociationReq{} + return decodingLayerDecoder(d, data, p) +} + +func (m *Dot11MgmtReassociationReq) LayerType() gopacket.LayerType { + return LayerTypeDot11MgmtReassociationReq +} +func (m *Dot11MgmtReassociationReq) CanDecode() gopacket.LayerClass { + return LayerTypeDot11MgmtReassociationReq +} +func (m *Dot11MgmtReassociationReq) NextLayerType() gopacket.LayerType { + return LayerTypeDot11InformationElement +} +func (m *Dot11MgmtReassociationReq) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + if len(data) < 10 { + df.SetTruncated() + return fmt.Errorf("Dot11MgmtReassociationReq length %v too short, %v required", len(data), 10) + } + m.CapabilityInfo = binary.LittleEndian.Uint16(data[0:2]) + m.ListenInterval = binary.LittleEndian.Uint16(data[2:4]) + m.CurrentApAddress = net.HardwareAddr(data[4:10]) + m.Payload = data[10:] + return m.Dot11Mgmt.DecodeFromBytes(data, df) +} + +type Dot11MgmtReassociationResp struct { + Dot11Mgmt +} + +func decodeDot11MgmtReassociationResp(data []byte, p gopacket.PacketBuilder) error { + d := &Dot11MgmtReassociationResp{} + return decodingLayerDecoder(d, data, p) +} + +func (m *Dot11MgmtReassociationResp) LayerType() gopacket.LayerType { + return LayerTypeDot11MgmtReassociationResp +} +func (m *Dot11MgmtReassociationResp) CanDecode() gopacket.LayerClass { + return LayerTypeDot11MgmtReassociationResp +} +func (m *Dot11MgmtReassociationResp) NextLayerType() gopacket.LayerType { + return LayerTypeDot11InformationElement +} + +type Dot11MgmtProbeReq struct { + Dot11Mgmt +} + +func decodeDot11MgmtProbeReq(data []byte, p gopacket.PacketBuilder) error { + d := &Dot11MgmtProbeReq{} + return decodingLayerDecoder(d, data, p) +} + +func (m *Dot11MgmtProbeReq) LayerType() gopacket.LayerType { return LayerTypeDot11MgmtProbeReq } +func (m *Dot11MgmtProbeReq) CanDecode() gopacket.LayerClass { return LayerTypeDot11MgmtProbeReq } +func (m *Dot11MgmtProbeReq) NextLayerType() gopacket.LayerType { + return LayerTypeDot11InformationElement +} + +type Dot11MgmtProbeResp struct { + Dot11Mgmt +} + +func decodeDot11MgmtProbeResp(data []byte, p gopacket.PacketBuilder) error { + d := &Dot11MgmtProbeResp{} + return decodingLayerDecoder(d, data, p) +} + +func (m *Dot11MgmtProbeResp) LayerType() gopacket.LayerType { return LayerTypeDot11MgmtProbeResp } +func (m *Dot11MgmtProbeResp) CanDecode() gopacket.LayerClass { return LayerTypeDot11MgmtProbeResp } +func (m *Dot11MgmtProbeResp) NextLayerType() gopacket.LayerType { + return LayerTypeDot11InformationElement +} + +type Dot11MgmtMeasurementPilot struct { + Dot11Mgmt +} + +func decodeDot11MgmtMeasurementPilot(data []byte, p gopacket.PacketBuilder) error { + d := &Dot11MgmtMeasurementPilot{} + return decodingLayerDecoder(d, data, p) +} + +func (m *Dot11MgmtMeasurementPilot) LayerType() gopacket.LayerType { + return LayerTypeDot11MgmtMeasurementPilot +} +func (m *Dot11MgmtMeasurementPilot) CanDecode() gopacket.LayerClass { + return LayerTypeDot11MgmtMeasurementPilot +} + +type Dot11MgmtBeacon struct { + Dot11Mgmt + Timestamp uint64 + Interval uint16 + Flags uint16 +} + +func decodeDot11MgmtBeacon(data []byte, p gopacket.PacketBuilder) error { + d := &Dot11MgmtBeacon{} + return decodingLayerDecoder(d, data, p) +} + +func (m *Dot11MgmtBeacon) LayerType() gopacket.LayerType { return LayerTypeDot11MgmtBeacon } +func (m *Dot11MgmtBeacon) CanDecode() gopacket.LayerClass { return LayerTypeDot11MgmtBeacon } +func (m *Dot11MgmtBeacon) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + if len(data) < 12 { + df.SetTruncated() + return fmt.Errorf("Dot11MgmtBeacon length %v too short, %v required", len(data), 12) + } + m.Timestamp = binary.LittleEndian.Uint64(data[0:8]) + m.Interval = binary.LittleEndian.Uint16(data[8:10]) + m.Flags = binary.LittleEndian.Uint16(data[10:12]) + m.Payload = data[12:] + return m.Dot11Mgmt.DecodeFromBytes(data, df) +} + +func (m *Dot11MgmtBeacon) NextLayerType() gopacket.LayerType { return LayerTypeDot11InformationElement } + +type Dot11MgmtATIM struct { + Dot11Mgmt +} + +func decodeDot11MgmtATIM(data []byte, p gopacket.PacketBuilder) error { + d := &Dot11MgmtATIM{} + return decodingLayerDecoder(d, data, p) +} + +func (m *Dot11MgmtATIM) LayerType() gopacket.LayerType { return LayerTypeDot11MgmtATIM } +func (m *Dot11MgmtATIM) CanDecode() gopacket.LayerClass { return LayerTypeDot11MgmtATIM } + +type Dot11MgmtDisassociation struct { + Dot11Mgmt + Reason Dot11Reason +} + +func decodeDot11MgmtDisassociation(data []byte, p gopacket.PacketBuilder) error { + d := &Dot11MgmtDisassociation{} + return decodingLayerDecoder(d, data, p) +} + +func (m *Dot11MgmtDisassociation) LayerType() gopacket.LayerType { + return LayerTypeDot11MgmtDisassociation +} +func (m *Dot11MgmtDisassociation) CanDecode() gopacket.LayerClass { + return LayerTypeDot11MgmtDisassociation +} +func (m *Dot11MgmtDisassociation) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + if len(data) < 2 { + df.SetTruncated() + return fmt.Errorf("Dot11MgmtDisassociation length %v too short, %v required", len(data), 2) + } + m.Reason = Dot11Reason(binary.LittleEndian.Uint16(data[0:2])) + return m.Dot11Mgmt.DecodeFromBytes(data, df) +} + +type Dot11MgmtAuthentication struct { + Dot11Mgmt + Algorithm Dot11Algorithm + Sequence uint16 + Status Dot11Status +} + +func decodeDot11MgmtAuthentication(data []byte, p gopacket.PacketBuilder) error { + d := &Dot11MgmtAuthentication{} + return decodingLayerDecoder(d, data, p) +} + +func (m *Dot11MgmtAuthentication) LayerType() gopacket.LayerType { + return LayerTypeDot11MgmtAuthentication +} +func (m *Dot11MgmtAuthentication) CanDecode() gopacket.LayerClass { + return LayerTypeDot11MgmtAuthentication +} +func (m *Dot11MgmtAuthentication) NextLayerType() gopacket.LayerType { + return LayerTypeDot11InformationElement +} +func (m *Dot11MgmtAuthentication) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + if len(data) < 6 { + df.SetTruncated() + return fmt.Errorf("Dot11MgmtAuthentication length %v too short, %v required", len(data), 6) + } + m.Algorithm = Dot11Algorithm(binary.LittleEndian.Uint16(data[0:2])) + m.Sequence = binary.LittleEndian.Uint16(data[2:4]) + m.Status = Dot11Status(binary.LittleEndian.Uint16(data[4:6])) + m.Payload = data[6:] + return m.Dot11Mgmt.DecodeFromBytes(data, df) +} + +type Dot11MgmtDeauthentication struct { + Dot11Mgmt + Reason Dot11Reason +} + +func decodeDot11MgmtDeauthentication(data []byte, p gopacket.PacketBuilder) error { + d := &Dot11MgmtDeauthentication{} + return decodingLayerDecoder(d, data, p) +} + +func (m *Dot11MgmtDeauthentication) LayerType() gopacket.LayerType { + return LayerTypeDot11MgmtDeauthentication +} +func (m *Dot11MgmtDeauthentication) CanDecode() gopacket.LayerClass { + return LayerTypeDot11MgmtDeauthentication +} +func (m *Dot11MgmtDeauthentication) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + if len(data) < 2 { + df.SetTruncated() + return fmt.Errorf("Dot11MgmtDeauthentication length %v too short, %v required", len(data), 2) + } + m.Reason = Dot11Reason(binary.LittleEndian.Uint16(data[0:2])) + return m.Dot11Mgmt.DecodeFromBytes(data, df) +} + +type Dot11MgmtAction struct { + Dot11Mgmt +} + +func decodeDot11MgmtAction(data []byte, p gopacket.PacketBuilder) error { + d := &Dot11MgmtAction{} + return decodingLayerDecoder(d, data, p) +} + +func (m *Dot11MgmtAction) LayerType() gopacket.LayerType { return LayerTypeDot11MgmtAction } +func (m *Dot11MgmtAction) CanDecode() gopacket.LayerClass { return LayerTypeDot11MgmtAction } + +type Dot11MgmtActionNoAck struct { + Dot11Mgmt +} + +func decodeDot11MgmtActionNoAck(data []byte, p gopacket.PacketBuilder) error { + d := &Dot11MgmtActionNoAck{} + return decodingLayerDecoder(d, data, p) +} + +func (m *Dot11MgmtActionNoAck) LayerType() gopacket.LayerType { return LayerTypeDot11MgmtActionNoAck } +func (m *Dot11MgmtActionNoAck) CanDecode() gopacket.LayerClass { return LayerTypeDot11MgmtActionNoAck } + +type Dot11MgmtArubaWLAN struct { + Dot11Mgmt +} + +func decodeDot11MgmtArubaWLAN(data []byte, p gopacket.PacketBuilder) error { + d := &Dot11MgmtArubaWLAN{} + return decodingLayerDecoder(d, data, p) +} + +func (m *Dot11MgmtArubaWLAN) LayerType() gopacket.LayerType { return LayerTypeDot11MgmtArubaWLAN } +func (m *Dot11MgmtArubaWLAN) CanDecode() gopacket.LayerClass { return LayerTypeDot11MgmtArubaWLAN } diff --git a/vendor/github.com/google/gopacket/layers/dot1q.go b/vendor/github.com/google/gopacket/layers/dot1q.go new file mode 100644 index 0000000..d8d3154 --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/dot1q.go @@ -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 |= 0x10 + } + binary.BigEndian.PutUint16(bytes, firstBytes) + binary.BigEndian.PutUint16(bytes[2:], uint16(d.Type)) + return nil +} diff --git a/vendor/github.com/google/gopacket/layers/eap.go b/vendor/github.com/google/gopacket/layers/eap.go new file mode 100644 index 0000000..250f857 --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/eap.go @@ -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) +} diff --git a/vendor/github.com/google/gopacket/layers/eapol.go b/vendor/github.com/google/gopacket/layers/eapol.go new file mode 100644 index 0000000..1200c7d --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/eapol.go @@ -0,0 +1,44 @@ +// 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" +) + +// EAPOL defines an EAP over LAN (802.1x) layer. +type EAPOL struct { + BaseLayer + Version uint8 + Type EAPOLType +} + +// 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.BaseLayer = BaseLayer{data[:2], data[2:]} + 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) +} diff --git a/vendor/github.com/google/gopacket/layers/endpoints.go b/vendor/github.com/google/gopacket/layers/endpoints.go new file mode 100644 index 0000000..a0916e1 --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/endpoints.go @@ -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" + "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{"IPv4", func(b []byte) string { + return net.IP(b).String() + }}) + EndpointIPv6 = gopacket.RegisterEndpointType(2, gopacket.EndpointTypeMetadata{"IPv6", func(b []byte) string { + return net.IP(b).String() + }}) + + EndpointMAC = gopacket.RegisterEndpointType(3, gopacket.EndpointTypeMetadata{"MAC", func(b []byte) string { + return net.HardwareAddr(b).String() + }}) + EndpointTCPPort = gopacket.RegisterEndpointType(4, gopacket.EndpointTypeMetadata{"TCP", func(b []byte) string { + return strconv.Itoa(int(binary.BigEndian.Uint16(b))) + }}) + EndpointUDPPort = gopacket.RegisterEndpointType(5, gopacket.EndpointTypeMetadata{"UDP", func(b []byte) string { + return strconv.Itoa(int(binary.BigEndian.Uint16(b))) + }}) + EndpointSCTPPort = gopacket.RegisterEndpointType(6, gopacket.EndpointTypeMetadata{"SCTP", func(b []byte) string { + return strconv.Itoa(int(binary.BigEndian.Uint16(b))) + }}) + EndpointRUDPPort = gopacket.RegisterEndpointType(7, gopacket.EndpointTypeMetadata{"RUDP", func(b []byte) string { + return strconv.Itoa(int(b[0])) + }}) + EndpointUDPLitePort = gopacket.RegisterEndpointType(8, gopacket.EndpointTypeMetadata{"UDPLite", func(b []byte) string { + return strconv.Itoa(int(binary.BigEndian.Uint16(b))) + }}) + EndpointPPP = gopacket.RegisterEndpointType(9, gopacket.EndpointTypeMetadata{"PPP", 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 { + switch len(a) { + case 4: + return gopacket.NewEndpoint(EndpointIPv4, []byte(a)) + case 16: + return gopacket.NewEndpoint(EndpointIPv6, []byte(a)) + } + 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)) +} diff --git a/vendor/github.com/google/gopacket/layers/enums.go b/vendor/github.com/google/gopacket/layers/enums.go new file mode 100644 index 0000000..0d8925e --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/enums.go @@ -0,0 +1,550 @@ +// 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" +) + +// 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 + 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 + IPProtocolIPIP IPProtocol = 94 + IPProtocolEtherIP IPProtocol = 97 + 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 + LinkTypeTokenRing LinkType = 6 + LinkTypeArcNet LinkType = 7 + LinkTypeSLIP LinkType = 8 + LinkTypePPP LinkType = 9 + LinkTypeFDDI LinkType = 10 + LinkTypeATM_RFC1483 LinkType = 100 + LinkTypeRaw LinkType = 101 + LinkTypePPP_HDLC LinkType = 50 + LinkTypePPPEthernet LinkType = 51 + LinkTypeC_HDLC LinkType = 104 + LinkTypeIEEE802_11 LinkType = 105 + LinkTypeFRelay LinkType = 107 + LinkTypeLoop LinkType = 108 + LinkTypeLinuxSLL LinkType = 113 + LinkTypeLTalk LinkType = 104 + LinkTypePFLog LinkType = 117 + LinkTypePrismHeader LinkType = 119 + LinkTypeIPOverFC LinkType = 122 + LinkTypeSunATM LinkType = 123 + LinkTypeIEEE80211Radio LinkType = 127 + LinkTypeARCNetLinux LinkType = 129 + 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 +} + +const ( + Dot11TypeMgmt Dot11Type = 0x00 + Dot11TypeCtrl Dot11Type = 0x01 + Dot11TypeData Dot11Type = 0x02 + Dot11TypeReserved Dot11Type = 0x03 + dot11TypeMask = 0x03 + + // 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 +) + +var ( + // Each of the following arrays contains mappings of how to handle enum + // values for various enum types in gopacket/layers. + // + // 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. + EthernetTypeMetadata [65536]EnumMetadata + IPProtocolMetadata [265]EnumMetadata + SCTPChunkTypeMetadata [265]EnumMetadata + PPPTypeMetadata [65536]EnumMetadata + PPPoECodeMetadata [256]EnumMetadata + LinkTypeMetadata [256]EnumMetadata + FDDIFrameControlMetadata [256]EnumMetadata + EAPOLTypeMetadata [256]EnumMetadata + ProtocolFamilyMetadata [256]EnumMetadata + Dot11TypeMetadata [256]EnumMetadata + USBTypeMetadata [256]EnumMetadata +) + +func (a EthernetType) Decode(data []byte, p gopacket.PacketBuilder) error { + return EthernetTypeMetadata[a].DecodeWith.Decode(data, p) +} +func (a EthernetType) String() string { + return EthernetTypeMetadata[a].Name +} +func (a EthernetType) LayerType() gopacket.LayerType { + return EthernetTypeMetadata[a].LayerType +} +func (a IPProtocol) Decode(data []byte, p gopacket.PacketBuilder) error { + return IPProtocolMetadata[a].DecodeWith.Decode(data, p) +} +func (a IPProtocol) String() string { + return IPProtocolMetadata[a].Name +} +func (a IPProtocol) LayerType() gopacket.LayerType { + return IPProtocolMetadata[a].LayerType +} +func (a SCTPChunkType) Decode(data []byte, p gopacket.PacketBuilder) error { + return SCTPChunkTypeMetadata[a].DecodeWith.Decode(data, p) +} +func (a SCTPChunkType) String() string { + return SCTPChunkTypeMetadata[a].Name +} +func (a PPPType) Decode(data []byte, p gopacket.PacketBuilder) error { + return PPPTypeMetadata[a].DecodeWith.Decode(data, p) +} +func (a PPPType) String() string { + return PPPTypeMetadata[a].Name +} +func (a LinkType) Decode(data []byte, p gopacket.PacketBuilder) error { + return LinkTypeMetadata[a].DecodeWith.Decode(data, p) +} +func (a LinkType) String() string { + return LinkTypeMetadata[a].Name +} +func (a PPPoECode) Decode(data []byte, p gopacket.PacketBuilder) error { + return PPPoECodeMetadata[a].DecodeWith.Decode(data, p) +} +func (a PPPoECode) String() string { + return PPPoECodeMetadata[a].Name +} +func (a FDDIFrameControl) Decode(data []byte, p gopacket.PacketBuilder) error { + return FDDIFrameControlMetadata[a].DecodeWith.Decode(data, p) +} +func (a FDDIFrameControl) String() string { + return FDDIFrameControlMetadata[a].Name +} +func (a EAPOLType) Decode(data []byte, p gopacket.PacketBuilder) error { + return EAPOLTypeMetadata[a].DecodeWith.Decode(data, p) +} +func (a EAPOLType) String() string { + return EAPOLTypeMetadata[a].Name +} +func (a EAPOLType) LayerType() gopacket.LayerType { + return EAPOLTypeMetadata[a].LayerType +} +func (a ProtocolFamily) Decode(data []byte, p gopacket.PacketBuilder) error { + return ProtocolFamilyMetadata[a].DecodeWith.Decode(data, p) +} +func (a ProtocolFamily) String() string { + return ProtocolFamilyMetadata[a].Name +} +func (a ProtocolFamily) LayerType() gopacket.LayerType { + return ProtocolFamilyMetadata[a].LayerType +} +func (a Dot11Type) Decode(data []byte, p gopacket.PacketBuilder) error { + return Dot11TypeMetadata[a].DecodeWith.Decode(data, p) +} +func (a Dot11Type) String() string { + return Dot11TypeMetadata[a].Name +} +func (a Dot11Type) LayerType() gopacket.LayerType { + return Dot11TypeMetadata[a].LayerType +} + +// 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 init() { + // Here we link up all enumerations with their respective names and decoders. + for i := 0; i < 65536; i++ { + EthernetTypeMetadata[i] = EnumMetadata{ + DecodeWith: errorFunc(fmt.Sprintf("Unable to decode ethernet type %d", i)), + Name: fmt.Sprintf("UnknownEthernetType(%d)", i), + } + PPPTypeMetadata[i] = EnumMetadata{ + DecodeWith: errorFunc(fmt.Sprintf("Unable to decode PPP type %d", i)), + Name: fmt.Sprintf("UnknownPPPType(%d)", i), + } + } + for i := 0; i < 256; i++ { + IPProtocolMetadata[i] = EnumMetadata{ + DecodeWith: errorFunc(fmt.Sprintf("Unable to decode IP protocol %d", i)), + Name: fmt.Sprintf("UnknownIPProtocol(%d)", i), + } + SCTPChunkTypeMetadata[i] = EnumMetadata{ + DecodeWith: errorFunc(fmt.Sprintf("Unable to decode SCTP chunk type %d", i)), + Name: fmt.Sprintf("UnknownSCTPChunkType(%d)", i), + } + PPPoECodeMetadata[i] = EnumMetadata{ + DecodeWith: errorFunc(fmt.Sprintf("Unable to decode PPPoE code %d", i)), + Name: fmt.Sprintf("UnknownPPPoECode(%d)", i), + } + LinkTypeMetadata[i] = EnumMetadata{ + DecodeWith: errorFunc(fmt.Sprintf("Unable to decode link type %d", i)), + Name: fmt.Sprintf("UnknownLinkType(%d)", i), + } + FDDIFrameControlMetadata[i] = EnumMetadata{ + DecodeWith: errorFunc(fmt.Sprintf("Unable to decode FDDI frame control %d", i)), + Name: fmt.Sprintf("UnknownFDDIFrameControl(%d)", i), + } + EAPOLTypeMetadata[i] = EnumMetadata{ + DecodeWith: errorFunc(fmt.Sprintf("Unable to decode EAPOL type %d", i)), + Name: fmt.Sprintf("UnknownEAPOLType(%d)", i), + } + ProtocolFamilyMetadata[i] = EnumMetadata{ + DecodeWith: errorFunc(fmt.Sprintf("Unable to decode protocol family %d", i)), + Name: fmt.Sprintf("UnknownProtocolFamily(%d)", i), + } + Dot11TypeMetadata[i] = EnumMetadata{ + DecodeWith: errorFunc(fmt.Sprintf("Unable to decode Dot11 type %d", i)), + Name: fmt.Sprintf("UnknownDot11Type(%d)", i), + } + } + + 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[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[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} + + 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[LinkTypeLoop] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeLoopback), Name: "Loop"} + LinkTypeMetadata[LinkTypeRaw] = 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} + + 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[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} + + USBTypeMetadata[USBTransportTypeInterrupt] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeUSBInterrupt), Name: "Interrupt", LayerType: LayerTypeUSBInterrupt} + USBTypeMetadata[USBTransportTypeControl] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeUSBControl), Name: "Control", LayerType: LayerTypeUSBControl} + USBTypeMetadata[USBTransportTypeBulk] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeUSBBulk), Name: "Bulk", LayerType: LayerTypeUSBBulk} +} diff --git a/vendor/github.com/google/gopacket/layers/etherip.go b/vendor/github.com/google/gopacket/layers/etherip.go new file mode 100644 index 0000000..5b7b722 --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/etherip.go @@ -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) +} diff --git a/vendor/github.com/google/gopacket/layers/ethernet.go b/vendor/github.com/google/gopacket/layers/ethernet.go new file mode 100644 index 0000000..4eebf8c --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/ethernet.go @@ -0,0 +1,122 @@ +// 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:]} + 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) +} diff --git a/vendor/github.com/google/gopacket/layers/fddi.go b/vendor/github.com/google/gopacket/layers/fddi.go new file mode 100644 index 0000000..ed9e195 --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/fddi.go @@ -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) +} diff --git a/vendor/github.com/google/gopacket/layers/gen.go b/vendor/github.com/google/gopacket/layers/gen.go new file mode 100644 index 0000000..ab7a0c0 --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/gen.go @@ -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()) +} diff --git a/vendor/github.com/google/gopacket/layers/gre.go b/vendor/github.com/google/gopacket/layers/gre.go new file mode 100644 index 0000000..733ecde --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/gre.go @@ -0,0 +1,96 @@ +// 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 bool + RecursionControl, Flags, Version uint8 + Protocol EthernetType + Checksum, Offset uint16 + Key, Seq 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.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 + } + } + g.BaseLayer = BaseLayer{data[:offset], data[offset:]} + 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) +} diff --git a/vendor/github.com/google/gopacket/layers/iana_ports.go b/vendor/github.com/google/gopacket/layers/iana_ports.go new file mode 100644 index 0000000..fbf281e --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/iana_ports.go @@ -0,0 +1,11163 @@ +// Copyright 2012 Google, Inc. All rights reserved. + +package layers + +// Created by gen.go, don't edit manually +// Generated at 2014-09-09 10:09:28.309114133 -0600 MDT +// Fetched from "http://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.xml" + +// 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{ + 1: "tcpmux", + 2: "compressnet", + 3: "compressnet", + 5: "rje", + 7: "echo", + 9: "discard", + 11: "systat", + 13: "daytime", + 17: "qotd", + 18: "msp", + 19: "chargen", + 20: "ftp-data", + 21: "ftp", + 22: "ssh", + 23: "telnet", + 25: "smtp", + 27: "nsw-fe", + 29: "msg-icp", + 31: "msg-auth", + 33: "dsp", + 37: "time", + 38: "rap", + 39: "rlp", + 41: "graphics", + 42: "name", + 43: "nicname", + 44: "mpm-flags", + 45: "mpm", + 46: "mpm-snd", + 47: "ni-ftp", + 48: "auditd", + 49: "tacacs", + 50: "re-mail-ck", + 52: "xns-time", + 53: "domain", + 54: "xns-ch", + 55: "isi-gl", + 56: "xns-auth", + 58: "xns-mail", + 61: "ni-mail", + 62: "acas", + 63: "whoispp", + 64: "covia", + 65: "tacacs-ds", + 66: "sql-net", + 67: "bootps", + 68: "bootpc", + 69: "tftp", + 70: "gopher", + 71: "netrjs-1", + 72: "netrjs-2", + 73: "netrjs-3", + 74: "netrjs-4", + 76: "deos", + 78: "vettcp", + 79: "finger", + 80: "http", + 82: "xfer", + 83: "mit-ml-dev", + 84: "ctf", + 85: "mit-ml-dev", + 86: "mfcobol", + 88: "kerberos", + 89: "su-mit-tg", + 90: "dnsix", + 91: "mit-dov", + 92: "npp", + 93: "dcp", + 94: "objcall", + 95: "supdup", + 96: "dixie", + 97: "swift-rvf", + 98: "tacnews", + 99: "metagram", + 101: "hostname", + 102: "iso-tsap", + 103: "gppitnp", + 104: "acr-nema", + 105: "cso", + 106: "3com-tsmux", + 107: "rtelnet", + 108: "snagas", + 109: "pop2", + 110: "pop3", + 111: "sunrpc", + 112: "mcidas", + 113: "ident", + 115: "sftp", + 116: "ansanotify", + 117: "uucp-path", + 118: "sqlserv", + 119: "nntp", + 120: "cfdptkt", + 121: "erpc", + 122: "smakynet", + 123: "ntp", + 124: "ansatrader", + 125: "locus-map", + 126: "nxedit", + 127: "locus-con", + 128: "gss-xlicen", + 129: "pwdgen", + 130: "cisco-fna", + 131: "cisco-tna", + 132: "cisco-sys", + 133: "statsrv", + 134: "ingres-net", + 135: "epmap", + 136: "profile", + 137: "netbios-ns", + 138: "netbios-dgm", + 139: "netbios-ssn", + 140: "emfis-data", + 141: "emfis-cntl", + 142: "bl-idm", + 143: "imap", + 144: "uma", + 145: "uaac", + 146: "iso-tp0", + 147: "iso-ip", + 148: "jargon", + 149: "aed-512", + 150: "sql-net", + 151: "hems", + 152: "bftp", + 153: "sgmp", + 154: "netsc-prod", + 155: "netsc-dev", + 156: "sqlsrv", + 157: "knet-cmp", + 158: "pcmail-srv", + 159: "nss-routing", + 160: "sgmp-traps", + 161: "snmp", + 162: "snmptrap", + 163: "cmip-man", + 164: "cmip-agent", + 165: "xns-courier", + 166: "s-net", + 167: "namp", + 168: "rsvd", + 169: "send", + 170: "print-srv", + 171: "multiplex", + 172: "cl-1", + 173: "xyplex-mux", + 174: "mailq", + 175: "vmnet", + 176: "genrad-mux", + 177: "xdmcp", + 178: "nextstep", + 179: "bgp", + 180: "ris", + 181: "unify", + 182: "audit", + 183: "ocbinder", + 184: "ocserver", + 185: "remote-kis", + 186: "kis", + 187: "aci", + 188: "mumps", + 189: "qft", + 190: "gacp", + 191: "prospero", + 192: "osu-nms", + 193: "srmp", + 194: "irc", + 195: "dn6-nlm-aud", + 196: "dn6-smm-red", + 197: "dls", + 198: "dls-mon", + 199: "smux", + 200: "src", + 201: "at-rtmp", + 202: "at-nbp", + 203: "at-3", + 204: "at-echo", + 205: "at-5", + 206: "at-zis", + 207: "at-7", + 208: "at-8", + 209: "qmtp", + 210: "z39-50", + 211: "914c-g", + 212: "anet", + 213: "ipx", + 214: "vmpwscs", + 215: "softpc", + 216: "CAIlic", + 217: "dbase", + 218: "mpp", + 219: "uarps", + 220: "imap3", + 221: "fln-spx", + 222: "rsh-spx", + 223: "cdc", + 224: "masqdialer", + 242: "direct", + 243: "sur-meas", + 244: "inbusiness", + 245: "link", + 246: "dsp3270", + 247: "subntbcst-tftp", + 248: "bhfhs", + 256: "rap", + 257: "set", + 259: "esro-gen", + 260: "openport", + 261: "nsiiops", + 262: "arcisdms", + 263: "hdap", + 264: "bgmp", + 265: "x-bone-ctl", + 266: "sst", + 267: "td-service", + 268: "td-replica", + 269: "manet", + 271: "pt-tls", + 280: "http-mgmt", + 281: "personal-link", + 282: "cableport-ax", + 283: "rescap", + 284: "corerjd", + 286: "fxp", + 287: "k-block", + 308: "novastorbakcup", + 309: "entrusttime", + 310: "bhmds", + 311: "asip-webadmin", + 312: "vslmp", + 313: "magenta-logic", + 314: "opalis-robot", + 315: "dpsi", + 316: "decauth", + 317: "zannet", + 318: "pkix-timestamp", + 319: "ptp-event", + 320: "ptp-general", + 321: "pip", + 322: "rtsps", + 323: "rpki-rtr", + 324: "rpki-rtr-tls", + 333: "texar", + 344: "pdap", + 345: "pawserv", + 346: "zserv", + 347: "fatserv", + 348: "csi-sgwp", + 349: "mftp", + 350: "matip-type-a", + 351: "matip-type-b", + 352: "dtag-ste-sb", + 353: "ndsauth", + 354: "bh611", + 355: "datex-asn", + 356: "cloanto-net-1", + 357: "bhevent", + 358: "shrinkwrap", + 359: "nsrmp", + 360: "scoi2odialog", + 361: "semantix", + 362: "srssend", + 363: "rsvp-tunnel", + 364: "aurora-cmgr", + 365: "dtk", + 366: "odmr", + 367: "mortgageware", + 368: "qbikgdp", + 369: "rpc2portmap", + 370: "codaauth2", + 371: "clearcase", + 372: "ulistproc", + 373: "legent-1", + 374: "legent-2", + 375: "hassle", + 376: "nip", + 377: "tnETOS", + 378: "dsETOS", + 379: "is99c", + 380: "is99s", + 381: "hp-collector", + 382: "hp-managed-node", + 383: "hp-alarm-mgr", + 384: "arns", + 385: "ibm-app", + 386: "asa", + 387: "aurp", + 388: "unidata-ldm", + 389: "ldap", + 390: "uis", + 391: "synotics-relay", + 392: "synotics-broker", + 393: "meta5", + 394: "embl-ndt", + 395: "netcp", + 396: "netware-ip", + 397: "mptn", + 398: "kryptolan", + 399: "iso-tsap-c2", + 400: "osb-sd", + 401: "ups", + 402: "genie", + 403: "decap", + 404: "nced", + 405: "ncld", + 406: "imsp", + 407: "timbuktu", + 408: "prm-sm", + 409: "prm-nm", + 410: "decladebug", + 411: "rmt", + 412: "synoptics-trap", + 413: "smsp", + 414: "infoseek", + 415: "bnet", + 416: "silverplatter", + 417: "onmux", + 418: "hyper-g", + 419: "ariel1", + 420: "smpte", + 421: "ariel2", + 422: "ariel3", + 423: "opc-job-start", + 424: "opc-job-track", + 425: "icad-el", + 426: "smartsdp", + 427: "svrloc", + 428: "ocs-cmu", + 429: "ocs-amu", + 430: "utmpsd", + 431: "utmpcd", + 432: "iasd", + 433: "nnsp", + 434: "mobileip-agent", + 435: "mobilip-mn", + 436: "dna-cml", + 437: "comscm", + 438: "dsfgw", + 439: "dasp", + 440: "sgcp", + 441: "decvms-sysmgt", + 442: "cvc-hostd", + 443: "https", + 444: "snpp", + 445: "microsoft-ds", + 446: "ddm-rdb", + 447: "ddm-dfm", + 448: "ddm-ssl", + 449: "as-servermap", + 450: "tserver", + 451: "sfs-smp-net", + 452: "sfs-config", + 453: "creativeserver", + 454: "contentserver", + 455: "creativepartnr", + 456: "macon-tcp", + 457: "scohelp", + 458: "appleqtc", + 459: "ampr-rcmd", + 460: "skronk", + 461: "datasurfsrv", + 462: "datasurfsrvsec", + 463: "alpes", + 464: "kpasswd", + 465: "urd", + 466: "digital-vrc", + 467: "mylex-mapd", + 468: "photuris", + 469: "rcp", + 470: "scx-proxy", + 471: "mondex", + 472: "ljk-login", + 473: "hybrid-pop", + 474: "tn-tl-w1", + 475: "tcpnethaspsrv", + 476: "tn-tl-fd1", + 477: "ss7ns", + 478: "spsc", + 479: "iafserver", + 480: "iafdbase", + 481: "ph", + 482: "bgs-nsi", + 483: "ulpnet", + 484: "integra-sme", + 485: "powerburst", + 486: "avian", + 487: "saft", + 488: "gss-http", + 489: "nest-protocol", + 490: "micom-pfs", + 491: "go-login", + 492: "ticf-1", + 493: "ticf-2", + 494: "pov-ray", + 495: "intecourier", + 496: "pim-rp-disc", + 497: "retrospect", + 498: "siam", + 499: "iso-ill", + 500: "isakmp", + 501: "stmf", + 502: "mbap", + 503: "intrinsa", + 504: "citadel", + 505: "mailbox-lm", + 506: "ohimsrv", + 507: "crs", + 508: "xvttp", + 509: "snare", + 510: "fcp", + 511: "passgo", + 512: "exec", + 513: "login", + 514: "shell", + 515: "printer", + 516: "videotex", + 517: "talk", + 518: "ntalk", + 519: "utime", + 520: "efs", + 521: "ripng", + 522: "ulp", + 523: "ibm-db2", + 524: "ncp", + 525: "timed", + 526: "tempo", + 527: "stx", + 528: "custix", + 529: "irc-serv", + 530: "courier", + 531: "conference", + 532: "netnews", + 533: "netwall", + 534: "windream", + 535: "iiop", + 536: "opalis-rdv", + 537: "nmsp", + 538: "gdomap", + 539: "apertus-ldp", + 540: "uucp", + 541: "uucp-rlogin", + 542: "commerce", + 543: "klogin", + 544: "kshell", + 545: "appleqtcsrvr", + 546: "dhcpv6-client", + 547: "dhcpv6-server", + 548: "afpovertcp", + 549: "idfp", + 550: "new-rwho", + 551: "cybercash", + 552: "devshr-nts", + 553: "pirp", + 554: "rtsp", + 555: "dsf", + 556: "remotefs", + 557: "openvms-sysipc", + 558: "sdnskmp", + 559: "teedtap", + 560: "rmonitor", + 561: "monitor", + 562: "chshell", + 563: "nntps", + 564: "9pfs", + 565: "whoami", + 566: "streettalk", + 567: "banyan-rpc", + 568: "ms-shuttle", + 569: "ms-rome", + 570: "meter", + 571: "meter", + 572: "sonar", + 573: "banyan-vip", + 574: "ftp-agent", + 575: "vemmi", + 576: "ipcd", + 577: "vnas", + 578: "ipdd", + 579: "decbsrv", + 580: "sntp-heartbeat", + 581: "bdp", + 582: "scc-security", + 583: "philips-vc", + 584: "keyserver", + 586: "password-chg", + 587: "submission", + 588: "cal", + 589: "eyelink", + 590: "tns-cml", + 591: "http-alt", + 592: "eudora-set", + 593: "http-rpc-epmap", + 594: "tpip", + 595: "cab-protocol", + 596: "smsd", + 597: "ptcnameservice", + 598: "sco-websrvrmg3", + 599: "acp", + 600: "ipcserver", + 601: "syslog-conn", + 602: "xmlrpc-beep", + 603: "idxp", + 604: "tunnel", + 605: "soap-beep", + 606: "urm", + 607: "nqs", + 608: "sift-uft", + 609: "npmp-trap", + 610: "npmp-local", + 611: "npmp-gui", + 612: "hmmp-ind", + 613: "hmmp-op", + 614: "sshell", + 615: "sco-inetmgr", + 616: "sco-sysmgr", + 617: "sco-dtmgr", + 618: "dei-icda", + 619: "compaq-evm", + 620: "sco-websrvrmgr", + 621: "escp-ip", + 622: "collaborator", + 623: "oob-ws-http", + 624: "cryptoadmin", + 625: "dec-dlm", + 626: "asia", + 627: "passgo-tivoli", + 628: "qmqp", + 629: "3com-amp3", + 630: "rda", + 631: "ipp", + 632: "bmpp", + 633: "servstat", + 634: "ginad", + 635: "rlzdbase", + 636: "ldaps", + 637: "lanserver", + 638: "mcns-sec", + 639: "msdp", + 640: "entrust-sps", + 641: "repcmd", + 642: "esro-emsdp", + 643: "sanity", + 644: "dwr", + 645: "pssc", + 646: "ldp", + 647: "dhcp-failover", + 648: "rrp", + 649: "cadview-3d", + 650: "obex", + 651: "ieee-mms", + 652: "hello-port", + 653: "repscmd", + 654: "aodv", + 655: "tinc", + 656: "spmp", + 657: "rmc", + 658: "tenfold", + 660: "mac-srvr-admin", + 661: "hap", + 662: "pftp", + 663: "purenoise", + 664: "oob-ws-https", + 665: "sun-dr", + 666: "mdqs", + 667: "disclose", + 668: "mecomm", + 669: "meregister", + 670: "vacdsm-sws", + 671: "vacdsm-app", + 672: "vpps-qua", + 673: "cimplex", + 674: "acap", + 675: "dctp", + 676: "vpps-via", + 677: "vpp", + 678: "ggf-ncp", + 679: "mrm", + 680: "entrust-aaas", + 681: "entrust-aams", + 682: "xfr", + 683: "corba-iiop", + 684: "corba-iiop-ssl", + 685: "mdc-portmapper", + 686: "hcp-wismar", + 687: "asipregistry", + 688: "realm-rusd", + 689: "nmap", + 690: "vatp", + 691: "msexch-routing", + 692: "hyperwave-isp", + 693: "connendp", + 694: "ha-cluster", + 695: "ieee-mms-ssl", + 696: "rushd", + 697: "uuidgen", + 698: "olsr", + 699: "accessnetwork", + 700: "epp", + 701: "lmp", + 702: "iris-beep", + 704: "elcsd", + 705: "agentx", + 706: "silc", + 707: "borland-dsj", + 709: "entrust-kmsh", + 710: "entrust-ash", + 711: "cisco-tdp", + 712: "tbrpf", + 713: "iris-xpc", + 714: "iris-xpcs", + 715: "iris-lwz", + 729: "netviewdm1", + 730: "netviewdm2", + 731: "netviewdm3", + 741: "netgw", + 742: "netrcs", + 744: "flexlm", + 747: "fujitsu-dev", + 748: "ris-cm", + 749: "kerberos-adm", + 750: "rfile", + 751: "pump", + 752: "qrh", + 753: "rrh", + 754: "tell", + 758: "nlogin", + 759: "con", + 760: "ns", + 761: "rxe", + 762: "quotad", + 763: "cycleserv", + 764: "omserv", + 765: "webster", + 767: "phonebook", + 769: "vid", + 770: "cadlock", + 771: "rtip", + 772: "cycleserv2", + 773: "submit", + 774: "rpasswd", + 775: "entomb", + 776: "wpages", + 777: "multiling-http", + 780: "wpgs", + 800: "mdbs-daemon", + 801: "device", + 802: "mbap-s", + 810: "fcp-udp", + 828: "itm-mcell-s", + 829: "pkix-3-ca-ra", + 830: "netconf-ssh", + 831: "netconf-beep", + 832: "netconfsoaphttp", + 833: "netconfsoapbeep", + 847: "dhcp-failover2", + 848: "gdoi", + 860: "iscsi", + 861: "owamp-control", + 862: "twamp-control", + 873: "rsync", + 886: "iclcnet-locate", + 887: "iclcnet-svinfo", + 888: "accessbuilder", + 900: "omginitialrefs", + 901: "smpnameres", + 902: "ideafarm-door", + 903: "ideafarm-panic", + 910: "kink", + 911: "xact-backup", + 912: "apex-mesh", + 913: "apex-edge", + 989: "ftps-data", + 990: "ftps", + 991: "nas", + 992: "telnets", + 993: "imaps", + 995: "pop3s", + 996: "vsinet", + 997: "maitrd", + 998: "busboy", + 999: "garcon", + 1000: "cadlock2", + 1010: "surf", + 1021: "exp1", + 1022: "exp2", + 1025: "blackjack", + 1026: "cap", + 1029: "solid-mux", + 1033: "netinfo-local", + 1034: "activesync", + 1035: "mxxrlogin", + 1036: "nsstp", + 1037: "ams", + 1038: "mtqp", + 1039: "sbl", + 1040: "netarx", + 1041: "danf-ak2", + 1042: "afrog", + 1043: "boinc-client", + 1044: "dcutility", + 1045: "fpitp", + 1046: "wfremotertm", + 1047: "neod1", + 1048: "neod2", + 1049: "td-postman", + 1050: "cma", + 1051: "optima-vnet", + 1052: "ddt", + 1053: "remote-as", + 1054: "brvread", + 1055: "ansyslmd", + 1056: "vfo", + 1057: "startron", + 1058: "nim", + 1059: "nimreg", + 1060: "polestar", + 1061: "kiosk", + 1062: "veracity", + 1063: "kyoceranetdev", + 1064: "jstel", + 1065: "syscomlan", + 1066: "fpo-fns", + 1067: "instl-boots", + 1068: "instl-bootc", + 1069: "cognex-insight", + 1070: "gmrupdateserv", + 1071: "bsquare-voip", + 1072: "cardax", + 1073: "bridgecontrol", + 1074: "warmspotMgmt", + 1075: "rdrmshc", + 1076: "dab-sti-c", + 1077: "imgames", + 1078: "avocent-proxy", + 1079: "asprovatalk", + 1080: "socks", + 1081: "pvuniwien", + 1082: "amt-esd-prot", + 1083: "ansoft-lm-1", + 1084: "ansoft-lm-2", + 1085: "webobjects", + 1086: "cplscrambler-lg", + 1087: "cplscrambler-in", + 1088: "cplscrambler-al", + 1089: "ff-annunc", + 1090: "ff-fms", + 1091: "ff-sm", + 1092: "obrpd", + 1093: "proofd", + 1094: "rootd", + 1095: "nicelink", + 1096: "cnrprotocol", + 1097: "sunclustermgr", + 1098: "rmiactivation", + 1099: "rmiregistry", + 1100: "mctp", + 1101: "pt2-discover", + 1102: "adobeserver-1", + 1103: "adobeserver-2", + 1104: "xrl", + 1105: "ftranhc", + 1106: "isoipsigport-1", + 1107: "isoipsigport-2", + 1108: "ratio-adp", + 1110: "webadmstart", + 1111: "lmsocialserver", + 1112: "icp", + 1113: "ltp-deepspace", + 1114: "mini-sql", + 1115: "ardus-trns", + 1116: "ardus-cntl", + 1117: "ardus-mtrns", + 1118: "sacred", + 1119: "bnetgame", + 1120: "bnetfile", + 1121: "rmpp", + 1122: "availant-mgr", + 1123: "murray", + 1124: "hpvmmcontrol", + 1125: "hpvmmagent", + 1126: "hpvmmdata", + 1127: "kwdb-commn", + 1128: "saphostctrl", + 1129: "saphostctrls", + 1130: "casp", + 1131: "caspssl", + 1132: "kvm-via-ip", + 1133: "dfn", + 1134: "aplx", + 1135: "omnivision", + 1136: "hhb-gateway", + 1137: "trim", + 1138: "encrypted-admin", + 1139: "evm", + 1140: "autonoc", + 1141: "mxomss", + 1142: "edtools", + 1143: "imyx", + 1144: "fuscript", + 1145: "x9-icue", + 1146: "audit-transfer", + 1147: "capioverlan", + 1148: "elfiq-repl", + 1149: "bvtsonar", + 1150: "blaze", + 1151: "unizensus", + 1152: "winpoplanmess", + 1153: "c1222-acse", + 1154: "resacommunity", + 1155: "nfa", + 1156: "iascontrol-oms", + 1157: "iascontrol", + 1158: "dbcontrol-oms", + 1159: "oracle-oms", + 1160: "olsv", + 1161: "health-polling", + 1162: "health-trap", + 1163: "sddp", + 1164: "qsm-proxy", + 1165: "qsm-gui", + 1166: "qsm-remote", + 1167: "cisco-ipsla", + 1168: "vchat", + 1169: "tripwire", + 1170: "atc-lm", + 1171: "atc-appserver", + 1172: "dnap", + 1173: "d-cinema-rrp", + 1174: "fnet-remote-ui", + 1175: "dossier", + 1176: "indigo-server", + 1177: "dkmessenger", + 1178: "sgi-storman", + 1179: "b2n", + 1180: "mc-client", + 1181: "3comnetman", + 1182: "accelenet", + 1183: "llsurfup-http", + 1184: "llsurfup-https", + 1185: "catchpole", + 1186: "mysql-cluster", + 1187: "alias", + 1188: "hp-webadmin", + 1189: "unet", + 1190: "commlinx-avl", + 1191: "gpfs", + 1192: "caids-sensor", + 1193: "fiveacross", + 1194: "openvpn", + 1195: "rsf-1", + 1196: "netmagic", + 1197: "carrius-rshell", + 1198: "cajo-discovery", + 1199: "dmidi", + 1200: "scol", + 1201: "nucleus-sand", + 1202: "caiccipc", + 1203: "ssslic-mgr", + 1204: "ssslog-mgr", + 1205: "accord-mgc", + 1206: "anthony-data", + 1207: "metasage", + 1208: "seagull-ais", + 1209: "ipcd3", + 1210: "eoss", + 1211: "groove-dpp", + 1212: "lupa", + 1213: "mpc-lifenet", + 1214: "kazaa", + 1215: "scanstat-1", + 1216: "etebac5", + 1217: "hpss-ndapi", + 1218: "aeroflight-ads", + 1219: "aeroflight-ret", + 1220: "qt-serveradmin", + 1221: "sweetware-apps", + 1222: "nerv", + 1223: "tgp", + 1224: "vpnz", + 1225: "slinkysearch", + 1226: "stgxfws", + 1227: "dns2go", + 1228: "florence", + 1229: "zented", + 1230: "periscope", + 1231: "menandmice-lpm", + 1232: "first-defense", + 1233: "univ-appserver", + 1234: "search-agent", + 1235: "mosaicsyssvc1", + 1236: "bvcontrol", + 1237: "tsdos390", + 1238: "hacl-qs", + 1239: "nmsd", + 1240: "instantia", + 1241: "nessus", + 1242: "nmasoverip", + 1243: "serialgateway", + 1244: "isbconference1", + 1245: "isbconference2", + 1246: "payrouter", + 1247: "visionpyramid", + 1248: "hermes", + 1249: "mesavistaco", + 1250: "swldy-sias", + 1251: "servergraph", + 1252: "bspne-pcc", + 1253: "q55-pcc", + 1254: "de-noc", + 1255: "de-cache-query", + 1256: "de-server", + 1257: "shockwave2", + 1258: "opennl", + 1259: "opennl-voice", + 1260: "ibm-ssd", + 1261: "mpshrsv", + 1262: "qnts-orb", + 1263: "dka", + 1264: "prat", + 1265: "dssiapi", + 1266: "dellpwrappks", + 1267: "epc", + 1268: "propel-msgsys", + 1269: "watilapp", + 1270: "opsmgr", + 1271: "excw", + 1272: "cspmlockmgr", + 1273: "emc-gateway", + 1274: "t1distproc", + 1275: "ivcollector", + 1277: "miva-mqs", + 1278: "dellwebadmin-1", + 1279: "dellwebadmin-2", + 1280: "pictrography", + 1281: "healthd", + 1282: "emperion", + 1283: "productinfo", + 1284: "iee-qfx", + 1285: "neoiface", + 1286: "netuitive", + 1287: "routematch", + 1288: "navbuddy", + 1289: "jwalkserver", + 1290: "winjaserver", + 1291: "seagulllms", + 1292: "dsdn", + 1293: "pkt-krb-ipsec", + 1294: "cmmdriver", + 1295: "ehtp", + 1296: "dproxy", + 1297: "sdproxy", + 1298: "lpcp", + 1299: "hp-sci", + 1300: "h323hostcallsc", + 1301: "ci3-software-1", + 1302: "ci3-software-2", + 1303: "sftsrv", + 1304: "boomerang", + 1305: "pe-mike", + 1306: "re-conn-proto", + 1307: "pacmand", + 1308: "odsi", + 1309: "jtag-server", + 1310: "husky", + 1311: "rxmon", + 1312: "sti-envision", + 1313: "bmc-patroldb", + 1314: "pdps", + 1315: "els", + 1316: "exbit-escp", + 1317: "vrts-ipcserver", + 1318: "krb5gatekeeper", + 1319: "amx-icsp", + 1320: "amx-axbnet", + 1321: "pip", + 1322: "novation", + 1323: "brcd", + 1324: "delta-mcp", + 1325: "dx-instrument", + 1326: "wimsic", + 1327: "ultrex", + 1328: "ewall", + 1329: "netdb-export", + 1330: "streetperfect", + 1331: "intersan", + 1332: "pcia-rxp-b", + 1333: "passwrd-policy", + 1334: "writesrv", + 1335: "digital-notary", + 1336: "ischat", + 1337: "menandmice-dns", + 1338: "wmc-log-svc", + 1339: "kjtsiteserver", + 1340: "naap", + 1341: "qubes", + 1342: "esbroker", + 1343: "re101", + 1344: "icap", + 1345: "vpjp", + 1346: "alta-ana-lm", + 1347: "bbn-mmc", + 1348: "bbn-mmx", + 1349: "sbook", + 1350: "editbench", + 1351: "equationbuilder", + 1352: "lotusnote", + 1353: "relief", + 1354: "XSIP-network", + 1355: "intuitive-edge", + 1356: "cuillamartin", + 1357: "pegboard", + 1358: "connlcli", + 1359: "ftsrv", + 1360: "mimer", + 1361: "linx", + 1362: "timeflies", + 1363: "ndm-requester", + 1364: "ndm-server", + 1365: "adapt-sna", + 1366: "netware-csp", + 1367: "dcs", + 1368: "screencast", + 1369: "gv-us", + 1370: "us-gv", + 1371: "fc-cli", + 1372: "fc-ser", + 1373: "chromagrafx", + 1374: "molly", + 1375: "bytex", + 1376: "ibm-pps", + 1377: "cichlid", + 1378: "elan", + 1379: "dbreporter", + 1380: "telesis-licman", + 1381: "apple-licman", + 1382: "udt-os", + 1383: "gwha", + 1384: "os-licman", + 1385: "atex-elmd", + 1386: "checksum", + 1387: "cadsi-lm", + 1388: "objective-dbc", + 1389: "iclpv-dm", + 1390: "iclpv-sc", + 1391: "iclpv-sas", + 1392: "iclpv-pm", + 1393: "iclpv-nls", + 1394: "iclpv-nlc", + 1395: "iclpv-wsm", + 1396: "dvl-activemail", + 1397: "audio-activmail", + 1398: "video-activmail", + 1399: "cadkey-licman", + 1400: "cadkey-tablet", + 1401: "goldleaf-licman", + 1402: "prm-sm-np", + 1403: "prm-nm-np", + 1404: "igi-lm", + 1405: "ibm-res", + 1406: "netlabs-lm", + 1407: "dbsa-lm", + 1408: "sophia-lm", + 1409: "here-lm", + 1410: "hiq", + 1411: "af", + 1412: "innosys", + 1413: "innosys-acl", + 1414: "ibm-mqseries", + 1415: "dbstar", + 1416: "novell-lu6-2", + 1417: "timbuktu-srv1", + 1418: "timbuktu-srv2", + 1419: "timbuktu-srv3", + 1420: "timbuktu-srv4", + 1421: "gandalf-lm", + 1422: "autodesk-lm", + 1423: "essbase", + 1424: "hybrid", + 1425: "zion-lm", + 1426: "sais", + 1427: "mloadd", + 1428: "informatik-lm", + 1429: "nms", + 1430: "tpdu", + 1431: "rgtp", + 1432: "blueberry-lm", + 1433: "ms-sql-s", + 1434: "ms-sql-m", + 1435: "ibm-cics", + 1436: "saism", + 1437: "tabula", + 1438: "eicon-server", + 1439: "eicon-x25", + 1440: "eicon-slp", + 1441: "cadis-1", + 1442: "cadis-2", + 1443: "ies-lm", + 1444: "marcam-lm", + 1445: "proxima-lm", + 1446: "ora-lm", + 1447: "apri-lm", + 1448: "oc-lm", + 1449: "peport", + 1450: "dwf", + 1451: "infoman", + 1452: "gtegsc-lm", + 1453: "genie-lm", + 1454: "interhdl-elmd", + 1455: "esl-lm", + 1456: "dca", + 1457: "valisys-lm", + 1458: "nrcabq-lm", + 1459: "proshare1", + 1460: "proshare2", + 1461: "ibm-wrless-lan", + 1462: "world-lm", + 1463: "nucleus", + 1464: "msl-lmd", + 1465: "pipes", + 1466: "oceansoft-lm", + 1467: "csdmbase", + 1468: "csdm", + 1469: "aal-lm", + 1470: "uaiact", + 1471: "csdmbase", + 1472: "csdm", + 1473: "openmath", + 1474: "telefinder", + 1475: "taligent-lm", + 1476: "clvm-cfg", + 1477: "ms-sna-server", + 1478: "ms-sna-base", + 1479: "dberegister", + 1480: "pacerforum", + 1481: "airs", + 1482: "miteksys-lm", + 1483: "afs", + 1484: "confluent", + 1485: "lansource", + 1486: "nms-topo-serv", + 1487: "localinfosrvr", + 1488: "docstor", + 1489: "dmdocbroker", + 1490: "insitu-conf", + 1492: "stone-design-1", + 1493: "netmap-lm", + 1494: "ica", + 1495: "cvc", + 1496: "liberty-lm", + 1497: "rfx-lm", + 1498: "sybase-sqlany", + 1499: "fhc", + 1500: "vlsi-lm", + 1501: "saiscm", + 1502: "shivadiscovery", + 1503: "imtc-mcs", + 1504: "evb-elm", + 1505: "funkproxy", + 1506: "utcd", + 1507: "symplex", + 1508: "diagmond", + 1509: "robcad-lm", + 1510: "mvx-lm", + 1511: "3l-l1", + 1512: "wins", + 1513: "fujitsu-dtc", + 1514: "fujitsu-dtcns", + 1515: "ifor-protocol", + 1516: "vpad", + 1517: "vpac", + 1518: "vpvd", + 1519: "vpvc", + 1520: "atm-zip-office", + 1521: "ncube-lm", + 1522: "ricardo-lm", + 1523: "cichild-lm", + 1524: "ingreslock", + 1525: "orasrv", + 1526: "pdap-np", + 1527: "tlisrv", + 1529: "coauthor", + 1530: "rap-service", + 1531: "rap-listen", + 1532: "miroconnect", + 1533: "virtual-places", + 1534: "micromuse-lm", + 1535: "ampr-info", + 1536: "ampr-inter", + 1537: "sdsc-lm", + 1538: "3ds-lm", + 1539: "intellistor-lm", + 1540: "rds", + 1541: "rds2", + 1542: "gridgen-elmd", + 1543: "simba-cs", + 1544: "aspeclmd", + 1545: "vistium-share", + 1546: "abbaccuray", + 1547: "laplink", + 1548: "axon-lm", + 1549: "shivahose", + 1550: "3m-image-lm", + 1551: "hecmtl-db", + 1552: "pciarray", + 1553: "sna-cs", + 1554: "caci-lm", + 1555: "livelan", + 1556: "veritas-pbx", + 1557: "arbortext-lm", + 1558: "xingmpeg", + 1559: "web2host", + 1560: "asci-val", + 1561: "facilityview", + 1562: "pconnectmgr", + 1563: "cadabra-lm", + 1564: "pay-per-view", + 1565: "winddlb", + 1566: "corelvideo", + 1567: "jlicelmd", + 1568: "tsspmap", + 1569: "ets", + 1570: "orbixd", + 1571: "rdb-dbs-disp", + 1572: "chip-lm", + 1573: "itscomm-ns", + 1574: "mvel-lm", + 1575: "oraclenames", + 1576: "moldflow-lm", + 1577: "hypercube-lm", + 1578: "jacobus-lm", + 1579: "ioc-sea-lm", + 1580: "tn-tl-r1", + 1581: "mil-2045-47001", + 1582: "msims", + 1583: "simbaexpress", + 1584: "tn-tl-fd2", + 1585: "intv", + 1586: "ibm-abtact", + 1587: "pra-elmd", + 1588: "triquest-lm", + 1589: "vqp", + 1590: "gemini-lm", + 1591: "ncpm-pm", + 1592: "commonspace", + 1593: "mainsoft-lm", + 1594: "sixtrak", + 1595: "radio", + 1596: "radio-sm", + 1597: "orbplus-iiop", + 1598: "picknfs", + 1599: "simbaservices", + 1600: "issd", + 1601: "aas", + 1602: "inspect", + 1603: "picodbc", + 1604: "icabrowser", + 1605: "slp", + 1606: "slm-api", + 1607: "stt", + 1608: "smart-lm", + 1609: "isysg-lm", + 1610: "taurus-wh", + 1611: "ill", + 1612: "netbill-trans", + 1613: "netbill-keyrep", + 1614: "netbill-cred", + 1615: "netbill-auth", + 1616: "netbill-prod", + 1617: "nimrod-agent", + 1618: "skytelnet", + 1619: "xs-openstorage", + 1620: "faxportwinport", + 1621: "softdataphone", + 1622: "ontime", + 1623: "jaleosnd", + 1624: "udp-sr-port", + 1625: "svs-omagent", + 1626: "shockwave", + 1627: "t128-gateway", + 1628: "lontalk-norm", + 1629: "lontalk-urgnt", + 1630: "oraclenet8cman", + 1631: "visitview", + 1632: "pammratc", + 1633: "pammrpc", + 1634: "loaprobe", + 1635: "edb-server1", + 1636: "isdc", + 1637: "islc", + 1638: "ismc", + 1639: "cert-initiator", + 1640: "cert-responder", + 1641: "invision", + 1642: "isis-am", + 1643: "isis-ambc", + 1644: "saiseh", + 1645: "sightline", + 1646: "sa-msg-port", + 1647: "rsap", + 1648: "concurrent-lm", + 1649: "kermit", + 1650: "nkd", + 1651: "shiva-confsrvr", + 1652: "xnmp", + 1653: "alphatech-lm", + 1654: "stargatealerts", + 1655: "dec-mbadmin", + 1656: "dec-mbadmin-h", + 1657: "fujitsu-mmpdc", + 1658: "sixnetudr", + 1659: "sg-lm", + 1660: "skip-mc-gikreq", + 1661: "netview-aix-1", + 1662: "netview-aix-2", + 1663: "netview-aix-3", + 1664: "netview-aix-4", + 1665: "netview-aix-5", + 1666: "netview-aix-6", + 1667: "netview-aix-7", + 1668: "netview-aix-8", + 1669: "netview-aix-9", + 1670: "netview-aix-10", + 1671: "netview-aix-11", + 1672: "netview-aix-12", + 1673: "proshare-mc-1", + 1674: "proshare-mc-2", + 1675: "pdp", + 1676: "netcomm1", + 1677: "groupwise", + 1678: "prolink", + 1679: "darcorp-lm", + 1680: "microcom-sbp", + 1681: "sd-elmd", + 1682: "lanyon-lantern", + 1683: "ncpm-hip", + 1684: "snaresecure", + 1685: "n2nremote", + 1686: "cvmon", + 1687: "nsjtp-ctrl", + 1688: "nsjtp-data", + 1689: "firefox", + 1690: "ng-umds", + 1691: "empire-empuma", + 1692: "sstsys-lm", + 1693: "rrirtr", + 1694: "rrimwm", + 1695: "rrilwm", + 1696: "rrifmm", + 1697: "rrisat", + 1698: "rsvp-encap-1", + 1699: "rsvp-encap-2", + 1700: "mps-raft", + 1701: "l2f", + 1702: "deskshare", + 1703: "hb-engine", + 1704: "bcs-broker", + 1705: "slingshot", + 1706: "jetform", + 1707: "vdmplay", + 1708: "gat-lmd", + 1709: "centra", + 1710: "impera", + 1711: "pptconference", + 1712: "registrar", + 1713: "conferencetalk", + 1714: "sesi-lm", + 1715: "houdini-lm", + 1716: "xmsg", + 1717: "fj-hdnet", + 1718: "h323gatedisc", + 1719: "h323gatestat", + 1720: "h323hostcall", + 1721: "caicci", + 1722: "hks-lm", + 1723: "pptp", + 1724: "csbphonemaster", + 1725: "iden-ralp", + 1726: "iberiagames", + 1727: "winddx", + 1728: "telindus", + 1729: "citynl", + 1730: "roketz", + 1731: "msiccp", + 1732: "proxim", + 1733: "siipat", + 1734: "cambertx-lm", + 1735: "privatechat", + 1736: "street-stream", + 1737: "ultimad", + 1738: "gamegen1", + 1739: "webaccess", + 1740: "encore", + 1741: "cisco-net-mgmt", + 1742: "3Com-nsd", + 1743: "cinegrfx-lm", + 1744: "ncpm-ft", + 1745: "remote-winsock", + 1746: "ftrapid-1", + 1747: "ftrapid-2", + 1748: "oracle-em1", + 1749: "aspen-services", + 1750: "sslp", + 1751: "swiftnet", + 1752: "lofr-lm", + 1753: "predatar-comms", + 1754: "oracle-em2", + 1755: "ms-streaming", + 1756: "capfast-lmd", + 1757: "cnhrp", + 1758: "tftp-mcast", + 1759: "spss-lm", + 1760: "www-ldap-gw", + 1761: "cft-0", + 1762: "cft-1", + 1763: "cft-2", + 1764: "cft-3", + 1765: "cft-4", + 1766: "cft-5", + 1767: "cft-6", + 1768: "cft-7", + 1769: "bmc-net-adm", + 1770: "bmc-net-svc", + 1771: "vaultbase", + 1772: "essweb-gw", + 1773: "kmscontrol", + 1774: "global-dtserv", + 1775: "vdab", + 1776: "femis", + 1777: "powerguardian", + 1778: "prodigy-intrnet", + 1779: "pharmasoft", + 1780: "dpkeyserv", + 1781: "answersoft-lm", + 1782: "hp-hcip", + 1784: "finle-lm", + 1785: "windlm", + 1786: "funk-logger", + 1787: "funk-license", + 1788: "psmond", + 1789: "hello", + 1790: "nmsp", + 1791: "ea1", + 1792: "ibm-dt-2", + 1793: "rsc-robot", + 1794: "cera-bcm", + 1795: "dpi-proxy", + 1796: "vocaltec-admin", + 1797: "uma", + 1798: "etp", + 1799: "netrisk", + 1800: "ansys-lm", + 1801: "msmq", + 1802: "concomp1", + 1803: "hp-hcip-gwy", + 1804: "enl", + 1805: "enl-name", + 1806: "musiconline", + 1807: "fhsp", + 1808: "oracle-vp2", + 1809: "oracle-vp1", + 1810: "jerand-lm", + 1811: "scientia-sdb", + 1812: "radius", + 1813: "radius-acct", + 1814: "tdp-suite", + 1815: "mmpft", + 1816: "harp", + 1817: "rkb-oscs", + 1818: "etftp", + 1819: "plato-lm", + 1820: "mcagent", + 1821: "donnyworld", + 1822: "es-elmd", + 1823: "unisys-lm", + 1824: "metrics-pas", + 1825: "direcpc-video", + 1826: "ardt", + 1827: "asi", + 1828: "itm-mcell-u", + 1829: "optika-emedia", + 1830: "net8-cman", + 1831: "myrtle", + 1832: "tht-treasure", + 1833: "udpradio", + 1834: "ardusuni", + 1835: "ardusmul", + 1836: "ste-smsc", + 1837: "csoft1", + 1838: "talnet", + 1839: "netopia-vo1", + 1840: "netopia-vo2", + 1841: "netopia-vo3", + 1842: "netopia-vo4", + 1843: "netopia-vo5", + 1844: "direcpc-dll", + 1845: "altalink", + 1846: "tunstall-pnc", + 1847: "slp-notify", + 1848: "fjdocdist", + 1849: "alpha-sms", + 1850: "gsi", + 1851: "ctcd", + 1852: "virtual-time", + 1853: "vids-avtp", + 1854: "buddy-draw", + 1855: "fiorano-rtrsvc", + 1856: "fiorano-msgsvc", + 1857: "datacaptor", + 1858: "privateark", + 1859: "gammafetchsvr", + 1860: "sunscalar-svc", + 1861: "lecroy-vicp", + 1862: "mysql-cm-agent", + 1863: "msnp", + 1864: "paradym-31port", + 1865: "entp", + 1866: "swrmi", + 1867: "udrive", + 1868: "viziblebrowser", + 1869: "transact", + 1870: "sunscalar-dns", + 1871: "canocentral0", + 1872: "canocentral1", + 1873: "fjmpjps", + 1874: "fjswapsnp", + 1875: "westell-stats", + 1876: "ewcappsrv", + 1877: "hp-webqosdb", + 1878: "drmsmc", + 1879: "nettgain-nms", + 1880: "vsat-control", + 1881: "ibm-mqseries2", + 1882: "ecsqdmn", + 1883: "ibm-mqisdp", + 1884: "idmaps", + 1885: "vrtstrapserver", + 1886: "leoip", + 1887: "filex-lport", + 1888: "ncconfig", + 1889: "unify-adapter", + 1890: "wilkenlistener", + 1891: "childkey-notif", + 1892: "childkey-ctrl", + 1893: "elad", + 1894: "o2server-port", + 1896: "b-novative-ls", + 1897: "metaagent", + 1898: "cymtec-port", + 1899: "mc2studios", + 1900: "ssdp", + 1901: "fjicl-tep-a", + 1902: "fjicl-tep-b", + 1903: "linkname", + 1904: "fjicl-tep-c", + 1905: "sugp", + 1906: "tpmd", + 1907: "intrastar", + 1908: "dawn", + 1909: "global-wlink", + 1910: "ultrabac", + 1911: "mtp", + 1912: "rhp-iibp", + 1913: "armadp", + 1914: "elm-momentum", + 1915: "facelink", + 1916: "persona", + 1917: "noagent", + 1918: "can-nds", + 1919: "can-dch", + 1920: "can-ferret", + 1921: "noadmin", + 1922: "tapestry", + 1923: "spice", + 1924: "xiip", + 1925: "discovery-port", + 1926: "egs", + 1927: "videte-cipc", + 1928: "emsd-port", + 1929: "bandwiz-system", + 1930: "driveappserver", + 1931: "amdsched", + 1932: "ctt-broker", + 1933: "xmapi", + 1934: "xaapi", + 1935: "macromedia-fcs", + 1936: "jetcmeserver", + 1937: "jwserver", + 1938: "jwclient", + 1939: "jvserver", + 1940: "jvclient", + 1941: "dic-aida", + 1942: "res", + 1943: "beeyond-media", + 1944: "close-combat", + 1945: "dialogic-elmd", + 1946: "tekpls", + 1947: "sentinelsrm", + 1948: "eye2eye", + 1949: "ismaeasdaqlive", + 1950: "ismaeasdaqtest", + 1951: "bcs-lmserver", + 1952: "mpnjsc", + 1953: "rapidbase", + 1954: "abr-api", + 1955: "abr-secure", + 1956: "vrtl-vmf-ds", + 1957: "unix-status", + 1958: "dxadmind", + 1959: "simp-all", + 1960: "nasmanager", + 1961: "bts-appserver", + 1962: "biap-mp", + 1963: "webmachine", + 1964: "solid-e-engine", + 1965: "tivoli-npm", + 1966: "slush", + 1967: "sns-quote", + 1968: "lipsinc", + 1969: "lipsinc1", + 1970: "netop-rc", + 1971: "netop-school", + 1972: "intersys-cache", + 1973: "dlsrap", + 1974: "drp", + 1975: "tcoflashagent", + 1976: "tcoregagent", + 1977: "tcoaddressbook", + 1978: "unisql", + 1979: "unisql-java", + 1980: "pearldoc-xact", + 1981: "p2pq", + 1982: "estamp", + 1983: "lhtp", + 1984: "bb", + 1985: "hsrp", + 1986: "licensedaemon", + 1987: "tr-rsrb-p1", + 1988: "tr-rsrb-p2", + 1989: "tr-rsrb-p3", + 1990: "stun-p1", + 1991: "stun-p2", + 1992: "stun-p3", + 1993: "snmp-tcp-port", + 1994: "stun-port", + 1995: "perf-port", + 1996: "tr-rsrb-port", + 1997: "gdp-port", + 1998: "x25-svc-port", + 1999: "tcp-id-port", + 2000: "cisco-sccp", + 2001: "dc", + 2002: "globe", + 2003: "brutus", + 2004: "mailbox", + 2005: "berknet", + 2006: "invokator", + 2007: "dectalk", + 2008: "conf", + 2009: "news", + 2010: "search", + 2011: "raid-cc", + 2012: "ttyinfo", + 2013: "raid-am", + 2014: "troff", + 2015: "cypress", + 2016: "bootserver", + 2017: "cypress-stat", + 2018: "terminaldb", + 2019: "whosockami", + 2020: "xinupageserver", + 2021: "servexec", + 2022: "down", + 2023: "xinuexpansion3", + 2024: "xinuexpansion4", + 2025: "ellpack", + 2026: "scrabble", + 2027: "shadowserver", + 2028: "submitserver", + 2029: "hsrpv6", + 2030: "device2", + 2031: "mobrien-chat", + 2032: "blackboard", + 2033: "glogger", + 2034: "scoremgr", + 2035: "imsldoc", + 2036: "e-dpnet", + 2037: "applus", + 2038: "objectmanager", + 2039: "prizma", + 2040: "lam", + 2041: "interbase", + 2042: "isis", + 2043: "isis-bcast", + 2044: "rimsl", + 2045: "cdfunc", + 2046: "sdfunc", + 2047: "dls", + 2048: "dls-monitor", + 2049: "shilp", + 2050: "av-emb-config", + 2051: "epnsdp", + 2052: "clearvisn", + 2053: "lot105-ds-upd", + 2054: "weblogin", + 2055: "iop", + 2056: "omnisky", + 2057: "rich-cp", + 2058: "newwavesearch", + 2059: "bmc-messaging", + 2060: "teleniumdaemon", + 2061: "netmount", + 2062: "icg-swp", + 2063: "icg-bridge", + 2064: "icg-iprelay", + 2065: "dlsrpn", + 2066: "aura", + 2067: "dlswpn", + 2068: "avauthsrvprtcl", + 2069: "event-port", + 2070: "ah-esp-encap", + 2071: "acp-port", + 2072: "msync", + 2073: "gxs-data-port", + 2074: "vrtl-vmf-sa", + 2075: "newlixengine", + 2076: "newlixconfig", + 2077: "tsrmagt", + 2078: "tpcsrvr", + 2079: "idware-router", + 2080: "autodesk-nlm", + 2081: "kme-trap-port", + 2082: "infowave", + 2083: "radsec", + 2084: "sunclustergeo", + 2085: "ada-cip", + 2086: "gnunet", + 2087: "eli", + 2088: "ip-blf", + 2089: "sep", + 2090: "lrp", + 2091: "prp", + 2092: "descent3", + 2093: "nbx-cc", + 2094: "nbx-au", + 2095: "nbx-ser", + 2096: "nbx-dir", + 2097: "jetformpreview", + 2098: "dialog-port", + 2099: "h2250-annex-g", + 2100: "amiganetfs", + 2101: "rtcm-sc104", + 2102: "zephyr-srv", + 2103: "zephyr-clt", + 2104: "zephyr-hm", + 2105: "minipay", + 2106: "mzap", + 2107: "bintec-admin", + 2108: "comcam", + 2109: "ergolight", + 2110: "umsp", + 2111: "dsatp", + 2112: "idonix-metanet", + 2113: "hsl-storm", + 2114: "newheights", + 2115: "kdm", + 2116: "ccowcmr", + 2117: "mentaclient", + 2118: "mentaserver", + 2119: "gsigatekeeper", + 2120: "qencp", + 2121: "scientia-ssdb", + 2122: "caupc-remote", + 2123: "gtp-control", + 2124: "elatelink", + 2125: "lockstep", + 2126: "pktcable-cops", + 2127: "index-pc-wb", + 2128: "net-steward", + 2129: "cs-live", + 2130: "xds", + 2131: "avantageb2b", + 2132: "solera-epmap", + 2133: "zymed-zpp", + 2134: "avenue", + 2135: "gris", + 2136: "appworxsrv", + 2137: "connect", + 2138: "unbind-cluster", + 2139: "ias-auth", + 2140: "ias-reg", + 2141: "ias-admind", + 2142: "tdmoip", + 2143: "lv-jc", + 2144: "lv-ffx", + 2145: "lv-pici", + 2146: "lv-not", + 2147: "lv-auth", + 2148: "veritas-ucl", + 2149: "acptsys", + 2150: "dynamic3d", + 2151: "docent", + 2152: "gtp-user", + 2153: "ctlptc", + 2154: "stdptc", + 2155: "brdptc", + 2156: "trp", + 2157: "xnds", + 2158: "touchnetplus", + 2159: "gdbremote", + 2160: "apc-2160", + 2161: "apc-2161", + 2162: "navisphere", + 2163: "navisphere-sec", + 2164: "ddns-v3", + 2165: "x-bone-api", + 2166: "iwserver", + 2167: "raw-serial", + 2168: "easy-soft-mux", + 2169: "brain", + 2170: "eyetv", + 2171: "msfw-storage", + 2172: "msfw-s-storage", + 2173: "msfw-replica", + 2174: "msfw-array", + 2175: "airsync", + 2176: "rapi", + 2177: "qwave", + 2178: "bitspeer", + 2179: "vmrdp", + 2180: "mc-gt-srv", + 2181: "eforward", + 2182: "cgn-stat", + 2183: "cgn-config", + 2184: "nvd", + 2185: "onbase-dds", + 2186: "gtaua", + 2187: "ssmc", + 2188: "radware-rpm", + 2189: "radware-rpm-s", + 2190: "tivoconnect", + 2191: "tvbus", + 2192: "asdis", + 2193: "drwcs", + 2197: "mnp-exchange", + 2198: "onehome-remote", + 2199: "onehome-help", + 2200: "ici", + 2201: "ats", + 2202: "imtc-map", + 2203: "b2-runtime", + 2204: "b2-license", + 2205: "jps", + 2206: "hpocbus", + 2207: "hpssd", + 2208: "hpiod", + 2209: "rimf-ps", + 2210: "noaaport", + 2211: "emwin", + 2212: "leecoposserver", + 2213: "kali", + 2214: "rpi", + 2215: "ipcore", + 2216: "vtu-comms", + 2217: "gotodevice", + 2218: "bounzza", + 2219: "netiq-ncap", + 2220: "netiq", + 2221: "rockwell-csp1", + 2222: "EtherNet-IP-1", + 2223: "rockwell-csp2", + 2224: "efi-mg", + 2225: "rcip-itu", + 2226: "di-drm", + 2227: "di-msg", + 2228: "ehome-ms", + 2229: "datalens", + 2230: "queueadm", + 2231: "wimaxasncp", + 2232: "ivs-video", + 2233: "infocrypt", + 2234: "directplay", + 2235: "sercomm-wlink", + 2236: "nani", + 2237: "optech-port1-lm", + 2238: "aviva-sna", + 2239: "imagequery", + 2240: "recipe", + 2241: "ivsd", + 2242: "foliocorp", + 2243: "magicom", + 2244: "nmsserver", + 2245: "hao", + 2246: "pc-mta-addrmap", + 2247: "antidotemgrsvr", + 2248: "ums", + 2249: "rfmp", + 2250: "remote-collab", + 2251: "dif-port", + 2252: "njenet-ssl", + 2253: "dtv-chan-req", + 2254: "seispoc", + 2255: "vrtp", + 2256: "pcc-mfp", + 2257: "simple-tx-rx", + 2258: "rcts", + 2260: "apc-2260", + 2261: "comotionmaster", + 2262: "comotionback", + 2263: "ecwcfg", + 2264: "apx500api-1", + 2265: "apx500api-2", + 2266: "mfserver", + 2267: "ontobroker", + 2268: "amt", + 2269: "mikey", + 2270: "starschool", + 2271: "mmcals", + 2272: "mmcal", + 2273: "mysql-im", + 2274: "pcttunnell", + 2275: "ibridge-data", + 2276: "ibridge-mgmt", + 2277: "bluectrlproxy", + 2278: "s3db", + 2279: "xmquery", + 2280: "lnvpoller", + 2281: "lnvconsole", + 2282: "lnvalarm", + 2283: "lnvstatus", + 2284: "lnvmaps", + 2285: "lnvmailmon", + 2286: "nas-metering", + 2287: "dna", + 2288: "netml", + 2289: "dict-lookup", + 2290: "sonus-logging", + 2291: "eapsp", + 2292: "mib-streaming", + 2293: "npdbgmngr", + 2294: "konshus-lm", + 2295: "advant-lm", + 2296: "theta-lm", + 2297: "d2k-datamover1", + 2298: "d2k-datamover2", + 2299: "pc-telecommute", + 2300: "cvmmon", + 2301: "cpq-wbem", + 2302: "binderysupport", + 2303: "proxy-gateway", + 2304: "attachmate-uts", + 2305: "mt-scaleserver", + 2306: "tappi-boxnet", + 2307: "pehelp", + 2308: "sdhelp", + 2309: "sdserver", + 2310: "sdclient", + 2311: "messageservice", + 2312: "wanscaler", + 2313: "iapp", + 2314: "cr-websystems", + 2315: "precise-sft", + 2316: "sent-lm", + 2317: "attachmate-g32", + 2318: "cadencecontrol", + 2319: "infolibria", + 2320: "siebel-ns", + 2321: "rdlap", + 2322: "ofsd", + 2323: "3d-nfsd", + 2324: "cosmocall", + 2325: "ansysli", + 2326: "idcp", + 2327: "xingcsm", + 2328: "netrix-sftm", + 2329: "nvd", + 2330: "tscchat", + 2331: "agentview", + 2332: "rcc-host", + 2333: "snapp", + 2334: "ace-client", + 2335: "ace-proxy", + 2336: "appleugcontrol", + 2337: "ideesrv", + 2338: "norton-lambert", + 2339: "3com-webview", + 2340: "wrs-registry", + 2341: "xiostatus", + 2342: "manage-exec", + 2343: "nati-logos", + 2344: "fcmsys", + 2345: "dbm", + 2346: "redstorm-join", + 2347: "redstorm-find", + 2348: "redstorm-info", + 2349: "redstorm-diag", + 2350: "psbserver", + 2351: "psrserver", + 2352: "pslserver", + 2353: "pspserver", + 2354: "psprserver", + 2355: "psdbserver", + 2356: "gxtelmd", + 2357: "unihub-server", + 2358: "futrix", + 2359: "flukeserver", + 2360: "nexstorindltd", + 2361: "tl1", + 2362: "digiman", + 2363: "mediacntrlnfsd", + 2364: "oi-2000", + 2365: "dbref", + 2366: "qip-login", + 2367: "service-ctrl", + 2368: "opentable", + 2370: "l3-hbmon", + 2371: "hp-rda", + 2372: "lanmessenger", + 2373: "remographlm", + 2374: "hydra", + 2375: "docker", + 2376: "docker-s", + 2379: "etcd-client", + 2380: "etcd-server", + 2381: "compaq-https", + 2382: "ms-olap3", + 2383: "ms-olap4", + 2384: "sd-request", + 2385: "sd-data", + 2386: "virtualtape", + 2387: "vsamredirector", + 2388: "mynahautostart", + 2389: "ovsessionmgr", + 2390: "rsmtp", + 2391: "3com-net-mgmt", + 2392: "tacticalauth", + 2393: "ms-olap1", + 2394: "ms-olap2", + 2395: "lan900-remote", + 2396: "wusage", + 2397: "ncl", + 2398: "orbiter", + 2399: "fmpro-fdal", + 2400: "opequus-server", + 2401: "cvspserver", + 2402: "taskmaster2000", + 2403: "taskmaster2000", + 2404: "iec-104", + 2405: "trc-netpoll", + 2406: "jediserver", + 2407: "orion", + 2408: "railgun-webaccl", + 2409: "sns-protocol", + 2410: "vrts-registry", + 2411: "netwave-ap-mgmt", + 2412: "cdn", + 2413: "orion-rmi-reg", + 2414: "beeyond", + 2415: "codima-rtp", + 2416: "rmtserver", + 2417: "composit-server", + 2418: "cas", + 2419: "attachmate-s2s", + 2420: "dslremote-mgmt", + 2421: "g-talk", + 2422: "crmsbits", + 2423: "rnrp", + 2424: "kofax-svr", + 2425: "fjitsuappmgr", + 2427: "mgcp-gateway", + 2428: "ott", + 2429: "ft-role", + 2430: "venus", + 2431: "venus-se", + 2432: "codasrv", + 2433: "codasrv-se", + 2434: "pxc-epmap", + 2435: "optilogic", + 2436: "topx", + 2437: "unicontrol", + 2438: "msp", + 2439: "sybasedbsynch", + 2440: "spearway", + 2441: "pvsw-inet", + 2442: "netangel", + 2443: "powerclientcsf", + 2444: "btpp2sectrans", + 2445: "dtn1", + 2446: "bues-service", + 2447: "ovwdb", + 2448: "hpppssvr", + 2449: "ratl", + 2450: "netadmin", + 2451: "netchat", + 2452: "snifferclient", + 2453: "madge-ltd", + 2454: "indx-dds", + 2455: "wago-io-system", + 2456: "altav-remmgt", + 2457: "rapido-ip", + 2458: "griffin", + 2459: "community", + 2460: "ms-theater", + 2461: "qadmifoper", + 2462: "qadmifevent", + 2463: "lsi-raid-mgmt", + 2464: "direcpc-si", + 2465: "lbm", + 2466: "lbf", + 2467: "high-criteria", + 2468: "qip-msgd", + 2469: "mti-tcs-comm", + 2470: "taskman-port", + 2471: "seaodbc", + 2472: "c3", + 2473: "aker-cdp", + 2474: "vitalanalysis", + 2475: "ace-server", + 2476: "ace-svr-prop", + 2477: "ssm-cvs", + 2478: "ssm-cssps", + 2479: "ssm-els", + 2480: "powerexchange", + 2481: "giop", + 2482: "giop-ssl", + 2483: "ttc", + 2484: "ttc-ssl", + 2485: "netobjects1", + 2486: "netobjects2", + 2487: "pns", + 2488: "moy-corp", + 2489: "tsilb", + 2490: "qip-qdhcp", + 2491: "conclave-cpp", + 2492: "groove", + 2493: "talarian-mqs", + 2494: "bmc-ar", + 2495: "fast-rem-serv", + 2496: "dirgis", + 2497: "quaddb", + 2498: "odn-castraq", + 2499: "unicontrol", + 2500: "rtsserv", + 2501: "rtsclient", + 2502: "kentrox-prot", + 2503: "nms-dpnss", + 2504: "wlbs", + 2505: "ppcontrol", + 2506: "jbroker", + 2507: "spock", + 2508: "jdatastore", + 2509: "fjmpss", + 2510: "fjappmgrbulk", + 2511: "metastorm", + 2512: "citrixima", + 2513: "citrixadmin", + 2514: "facsys-ntp", + 2515: "facsys-router", + 2516: "maincontrol", + 2517: "call-sig-trans", + 2518: "willy", + 2519: "globmsgsvc", + 2520: "pvsw", + 2521: "adaptecmgr", + 2522: "windb", + 2523: "qke-llc-v3", + 2524: "optiwave-lm", + 2525: "ms-v-worlds", + 2526: "ema-sent-lm", + 2527: "iqserver", + 2528: "ncr-ccl", + 2529: "utsftp", + 2530: "vrcommerce", + 2531: "ito-e-gui", + 2532: "ovtopmd", + 2533: "snifferserver", + 2534: "combox-web-acc", + 2535: "madcap", + 2536: "btpp2audctr1", + 2537: "upgrade", + 2538: "vnwk-prapi", + 2539: "vsiadmin", + 2540: "lonworks", + 2541: "lonworks2", + 2542: "udrawgraph", + 2543: "reftek", + 2544: "novell-zen", + 2545: "sis-emt", + 2546: "vytalvaultbrtp", + 2547: "vytalvaultvsmp", + 2548: "vytalvaultpipe", + 2549: "ipass", + 2550: "ads", + 2551: "isg-uda-server", + 2552: "call-logging", + 2553: "efidiningport", + 2554: "vcnet-link-v10", + 2555: "compaq-wcp", + 2556: "nicetec-nmsvc", + 2557: "nicetec-mgmt", + 2558: "pclemultimedia", + 2559: "lstp", + 2560: "labrat", + 2561: "mosaixcc", + 2562: "delibo", + 2563: "cti-redwood", + 2564: "hp-3000-telnet", + 2565: "coord-svr", + 2566: "pcs-pcw", + 2567: "clp", + 2568: "spamtrap", + 2569: "sonuscallsig", + 2570: "hs-port", + 2571: "cecsvc", + 2572: "ibp", + 2573: "trustestablish", + 2574: "blockade-bpsp", + 2575: "hl7", + 2576: "tclprodebugger", + 2577: "scipticslsrvr", + 2578: "rvs-isdn-dcp", + 2579: "mpfoncl", + 2580: "tributary", + 2581: "argis-te", + 2582: "argis-ds", + 2583: "mon", + 2584: "cyaserv", + 2585: "netx-server", + 2586: "netx-agent", + 2587: "masc", + 2588: "privilege", + 2589: "quartus-tcl", + 2590: "idotdist", + 2591: "maytagshuffle", + 2592: "netrek", + 2593: "mns-mail", + 2594: "dts", + 2595: "worldfusion1", + 2596: "worldfusion2", + 2597: "homesteadglory", + 2598: "citriximaclient", + 2599: "snapd", + 2600: "hpstgmgr", + 2601: "discp-client", + 2602: "discp-server", + 2603: "servicemeter", + 2604: "nsc-ccs", + 2605: "nsc-posa", + 2606: "netmon", + 2607: "connection", + 2608: "wag-service", + 2609: "system-monitor", + 2610: "versa-tek", + 2611: "lionhead", + 2612: "qpasa-agent", + 2613: "smntubootstrap", + 2614: "neveroffline", + 2615: "firepower", + 2616: "appswitch-emp", + 2617: "cmadmin", + 2618: "priority-e-com", + 2619: "bruce", + 2620: "lpsrecommender", + 2621: "miles-apart", + 2622: "metricadbc", + 2623: "lmdp", + 2624: "aria", + 2625: "blwnkl-port", + 2626: "gbjd816", + 2627: "moshebeeri", + 2628: "dict", + 2629: "sitaraserver", + 2630: "sitaramgmt", + 2631: "sitaradir", + 2632: "irdg-post", + 2633: "interintelli", + 2634: "pk-electronics", + 2635: "backburner", + 2636: "solve", + 2637: "imdocsvc", + 2638: "sybaseanywhere", + 2639: "aminet", + 2640: "sai-sentlm", + 2641: "hdl-srv", + 2642: "tragic", + 2643: "gte-samp", + 2644: "travsoft-ipx-t", + 2645: "novell-ipx-cmd", + 2646: "and-lm", + 2647: "syncserver", + 2648: "upsnotifyprot", + 2649: "vpsipport", + 2650: "eristwoguns", + 2651: "ebinsite", + 2652: "interpathpanel", + 2653: "sonus", + 2654: "corel-vncadmin", + 2655: "unglue", + 2656: "kana", + 2657: "sns-dispatcher", + 2658: "sns-admin", + 2659: "sns-query", + 2660: "gcmonitor", + 2661: "olhost", + 2662: "bintec-capi", + 2663: "bintec-tapi", + 2664: "patrol-mq-gm", + 2665: "patrol-mq-nm", + 2666: "extensis", + 2667: "alarm-clock-s", + 2668: "alarm-clock-c", + 2669: "toad", + 2670: "tve-announce", + 2671: "newlixreg", + 2672: "nhserver", + 2673: "firstcall42", + 2674: "ewnn", + 2675: "ttc-etap", + 2676: "simslink", + 2677: "gadgetgate1way", + 2678: "gadgetgate2way", + 2679: "syncserverssl", + 2680: "pxc-sapxom", + 2681: "mpnjsomb", + 2683: "ncdloadbalance", + 2684: "mpnjsosv", + 2685: "mpnjsocl", + 2686: "mpnjsomg", + 2687: "pq-lic-mgmt", + 2688: "md-cg-http", + 2689: "fastlynx", + 2690: "hp-nnm-data", + 2691: "itinternet", + 2692: "admins-lms", + 2694: "pwrsevent", + 2695: "vspread", + 2696: "unifyadmin", + 2697: "oce-snmp-trap", + 2698: "mck-ivpip", + 2699: "csoft-plusclnt", + 2700: "tqdata", + 2701: "sms-rcinfo", + 2702: "sms-xfer", + 2703: "sms-chat", + 2704: "sms-remctrl", + 2705: "sds-admin", + 2706: "ncdmirroring", + 2707: "emcsymapiport", + 2708: "banyan-net", + 2709: "supermon", + 2710: "sso-service", + 2711: "sso-control", + 2712: "aocp", + 2713: "raventbs", + 2714: "raventdm", + 2715: "hpstgmgr2", + 2716: "inova-ip-disco", + 2717: "pn-requester", + 2718: "pn-requester2", + 2719: "scan-change", + 2720: "wkars", + 2721: "smart-diagnose", + 2722: "proactivesrvr", + 2723: "watchdog-nt", + 2724: "qotps", + 2725: "msolap-ptp2", + 2726: "tams", + 2727: "mgcp-callagent", + 2728: "sqdr", + 2729: "tcim-control", + 2730: "nec-raidplus", + 2731: "fyre-messanger", + 2732: "g5m", + 2733: "signet-ctf", + 2734: "ccs-software", + 2735: "netiq-mc", + 2736: "radwiz-nms-srv", + 2737: "srp-feedback", + 2738: "ndl-tcp-ois-gw", + 2739: "tn-timing", + 2740: "alarm", + 2741: "tsb", + 2742: "tsb2", + 2743: "murx", + 2744: "honyaku", + 2745: "urbisnet", + 2746: "cpudpencap", + 2747: "fjippol-swrly", + 2748: "fjippol-polsvr", + 2749: "fjippol-cnsl", + 2750: "fjippol-port1", + 2751: "fjippol-port2", + 2752: "rsisysaccess", + 2753: "de-spot", + 2754: "apollo-cc", + 2755: "expresspay", + 2756: "simplement-tie", + 2757: "cnrp", + 2758: "apollo-status", + 2759: "apollo-gms", + 2760: "sabams", + 2761: "dicom-iscl", + 2762: "dicom-tls", + 2763: "desktop-dna", + 2764: "data-insurance", + 2765: "qip-audup", + 2766: "compaq-scp", + 2767: "uadtc", + 2768: "uacs", + 2769: "exce", + 2770: "veronica", + 2771: "vergencecm", + 2772: "auris", + 2773: "rbakcup1", + 2774: "rbakcup2", + 2775: "smpp", + 2776: "ridgeway1", + 2777: "ridgeway2", + 2778: "gwen-sonya", + 2779: "lbc-sync", + 2780: "lbc-control", + 2781: "whosells", + 2782: "everydayrc", + 2783: "aises", + 2784: "www-dev", + 2785: "aic-np", + 2786: "aic-oncrpc", + 2787: "piccolo", + 2788: "fryeserv", + 2789: "media-agent", + 2790: "plgproxy", + 2791: "mtport-regist", + 2792: "f5-globalsite", + 2793: "initlsmsad", + 2795: "livestats", + 2796: "ac-tech", + 2797: "esp-encap", + 2798: "tmesis-upshot", + 2799: "icon-discover", + 2800: "acc-raid", + 2801: "igcp", + 2802: "veritas-tcp1", + 2803: "btprjctrl", + 2804: "dvr-esm", + 2805: "wta-wsp-s", + 2806: "cspuni", + 2807: "cspmulti", + 2808: "j-lan-p", + 2809: "corbaloc", + 2810: "netsteward", + 2811: "gsiftp", + 2812: "atmtcp", + 2813: "llm-pass", + 2814: "llm-csv", + 2815: "lbc-measure", + 2816: "lbc-watchdog", + 2817: "nmsigport", + 2818: "rmlnk", + 2819: "fc-faultnotify", + 2820: "univision", + 2821: "vrts-at-port", + 2822: "ka0wuc", + 2823: "cqg-netlan", + 2824: "cqg-netlan-1", + 2826: "slc-systemlog", + 2827: "slc-ctrlrloops", + 2828: "itm-lm", + 2829: "silkp1", + 2830: "silkp2", + 2831: "silkp3", + 2832: "silkp4", + 2833: "glishd", + 2834: "evtp", + 2835: "evtp-data", + 2836: "catalyst", + 2837: "repliweb", + 2838: "starbot", + 2839: "nmsigport", + 2840: "l3-exprt", + 2841: "l3-ranger", + 2842: "l3-hawk", + 2843: "pdnet", + 2844: "bpcp-poll", + 2845: "bpcp-trap", + 2846: "aimpp-hello", + 2847: "aimpp-port-req", + 2848: "amt-blc-port", + 2849: "fxp", + 2850: "metaconsole", + 2851: "webemshttp", + 2852: "bears-01", + 2853: "ispipes", + 2854: "infomover", + 2855: "msrp", + 2856: "cesdinv", + 2857: "simctlp", + 2858: "ecnp", + 2859: "activememory", + 2860: "dialpad-voice1", + 2861: "dialpad-voice2", + 2862: "ttg-protocol", + 2863: "sonardata", + 2864: "astromed-main", + 2865: "pit-vpn", + 2866: "iwlistener", + 2867: "esps-portal", + 2868: "npep-messaging", + 2869: "icslap", + 2870: "daishi", + 2871: "msi-selectplay", + 2872: "radix", + 2874: "dxmessagebase1", + 2875: "dxmessagebase2", + 2876: "sps-tunnel", + 2877: "bluelance", + 2878: "aap", + 2879: "ucentric-ds", + 2880: "synapse", + 2881: "ndsp", + 2882: "ndtp", + 2883: "ndnp", + 2884: "flashmsg", + 2885: "topflow", + 2886: "responselogic", + 2887: "aironetddp", + 2888: "spcsdlobby", + 2889: "rsom", + 2890: "cspclmulti", + 2891: "cinegrfx-elmd", + 2892: "snifferdata", + 2893: "vseconnector", + 2894: "abacus-remote", + 2895: "natuslink", + 2896: "ecovisiong6-1", + 2897: "citrix-rtmp", + 2898: "appliance-cfg", + 2899: "powergemplus", + 2900: "quicksuite", + 2901: "allstorcns", + 2902: "netaspi", + 2903: "suitcase", + 2904: "m2ua", + 2905: "m3ua", + 2906: "caller9", + 2907: "webmethods-b2b", + 2908: "mao", + 2909: "funk-dialout", + 2910: "tdaccess", + 2911: "blockade", + 2912: "epicon", + 2913: "boosterware", + 2914: "gamelobby", + 2915: "tksocket", + 2916: "elvin-server", + 2917: "elvin-client", + 2918: "kastenchasepad", + 2919: "roboer", + 2920: "roboeda", + 2921: "cesdcdman", + 2922: "cesdcdtrn", + 2923: "wta-wsp-wtp-s", + 2924: "precise-vip", + 2926: "mobile-file-dl", + 2927: "unimobilectrl", + 2928: "redstone-cpss", + 2929: "amx-webadmin", + 2930: "amx-weblinx", + 2931: "circle-x", + 2932: "incp", + 2933: "4-tieropmgw", + 2934: "4-tieropmcli", + 2935: "qtp", + 2936: "otpatch", + 2937: "pnaconsult-lm", + 2938: "sm-pas-1", + 2939: "sm-pas-2", + 2940: "sm-pas-3", + 2941: "sm-pas-4", + 2942: "sm-pas-5", + 2943: "ttnrepository", + 2944: "megaco-h248", + 2945: "h248-binary", + 2946: "fjsvmpor", + 2947: "gpsd", + 2948: "wap-push", + 2949: "wap-pushsecure", + 2950: "esip", + 2951: "ottp", + 2952: "mpfwsas", + 2953: "ovalarmsrv", + 2954: "ovalarmsrv-cmd", + 2955: "csnotify", + 2956: "ovrimosdbman", + 2957: "jmact5", + 2958: "jmact6", + 2959: "rmopagt", + 2960: "dfoxserver", + 2961: "boldsoft-lm", + 2962: "iph-policy-cli", + 2963: "iph-policy-adm", + 2964: "bullant-srap", + 2965: "bullant-rap", + 2966: "idp-infotrieve", + 2967: "ssc-agent", + 2968: "enpp", + 2969: "essp", + 2970: "index-net", + 2971: "netclip", + 2972: "pmsm-webrctl", + 2973: "svnetworks", + 2974: "signal", + 2975: "fjmpcm", + 2976: "cns-srv-port", + 2977: "ttc-etap-ns", + 2978: "ttc-etap-ds", + 2979: "h263-video", + 2980: "wimd", + 2981: "mylxamport", + 2982: "iwb-whiteboard", + 2983: "netplan", + 2984: "hpidsadmin", + 2985: "hpidsagent", + 2986: "stonefalls", + 2987: "identify", + 2988: "hippad", + 2989: "zarkov", + 2990: "boscap", + 2991: "wkstn-mon", + 2992: "avenyo", + 2993: "veritas-vis1", + 2994: "veritas-vis2", + 2995: "idrs", + 2996: "vsixml", + 2997: "rebol", + 2998: "realsecure", + 2999: "remoteware-un", + 3000: "hbci", + 3001: "origo-native", + 3002: "exlm-agent", + 3003: "cgms", + 3004: "csoftragent", + 3005: "geniuslm", + 3006: "ii-admin", + 3007: "lotusmtap", + 3008: "midnight-tech", + 3009: "pxc-ntfy", + 3010: "gw", + 3011: "trusted-web", + 3012: "twsdss", + 3013: "gilatskysurfer", + 3014: "broker-service", + 3015: "nati-dstp", + 3016: "notify-srvr", + 3017: "event-listener", + 3018: "srvc-registry", + 3019: "resource-mgr", + 3020: "cifs", + 3021: "agriserver", + 3022: "csregagent", + 3023: "magicnotes", + 3024: "nds-sso", + 3025: "arepa-raft", + 3026: "agri-gateway", + 3027: "LiebDevMgmt-C", + 3028: "LiebDevMgmt-DM", + 3029: "LiebDevMgmt-A", + 3030: "arepa-cas", + 3031: "eppc", + 3032: "redwood-chat", + 3033: "pdb", + 3034: "osmosis-aeea", + 3035: "fjsv-gssagt", + 3036: "hagel-dump", + 3037: "hp-san-mgmt", + 3038: "santak-ups", + 3039: "cogitate", + 3040: "tomato-springs", + 3041: "di-traceware", + 3042: "journee", + 3043: "brp", + 3044: "epp", + 3045: "responsenet", + 3046: "di-ase", + 3047: "hlserver", + 3048: "pctrader", + 3049: "nsws", + 3050: "gds-db", + 3051: "galaxy-server", + 3052: "apc-3052", + 3053: "dsom-server", + 3054: "amt-cnf-prot", + 3055: "policyserver", + 3056: "cdl-server", + 3057: "goahead-fldup", + 3058: "videobeans", + 3059: "qsoft", + 3060: "interserver", + 3061: "cautcpd", + 3062: "ncacn-ip-tcp", + 3063: "ncadg-ip-udp", + 3064: "rprt", + 3065: "slinterbase", + 3066: "netattachsdmp", + 3067: "fjhpjp", + 3068: "ls3bcast", + 3069: "ls3", + 3070: "mgxswitch", + 3071: "csd-mgmt-port", + 3072: "csd-monitor", + 3073: "vcrp", + 3074: "xbox", + 3075: "orbix-locator", + 3076: "orbix-config", + 3077: "orbix-loc-ssl", + 3078: "orbix-cfg-ssl", + 3079: "lv-frontpanel", + 3080: "stm-pproc", + 3081: "tl1-lv", + 3082: "tl1-raw", + 3083: "tl1-telnet", + 3084: "itm-mccs", + 3085: "pcihreq", + 3086: "jdl-dbkitchen", + 3087: "asoki-sma", + 3088: "xdtp", + 3089: "ptk-alink", + 3090: "stss", + 3091: "1ci-smcs", + 3093: "rapidmq-center", + 3094: "rapidmq-reg", + 3095: "panasas", + 3096: "ndl-aps", + 3098: "umm-port", + 3099: "chmd", + 3100: "opcon-xps", + 3101: "hp-pxpib", + 3102: "slslavemon", + 3103: "autocuesmi", + 3104: "autocuelog", + 3105: "cardbox", + 3106: "cardbox-http", + 3107: "business", + 3108: "geolocate", + 3109: "personnel", + 3110: "sim-control", + 3111: "wsynch", + 3112: "ksysguard", + 3113: "cs-auth-svr", + 3114: "ccmad", + 3115: "mctet-master", + 3116: "mctet-gateway", + 3117: "mctet-jserv", + 3118: "pkagent", + 3119: "d2000kernel", + 3120: "d2000webserver", + 3121: "pcmk-remote", + 3122: "vtr-emulator", + 3123: "edix", + 3124: "beacon-port", + 3125: "a13-an", + 3127: "ctx-bridge", + 3128: "ndl-aas", + 3129: "netport-id", + 3130: "icpv2", + 3131: "netbookmark", + 3132: "ms-rule-engine", + 3133: "prism-deploy", + 3134: "ecp", + 3135: "peerbook-port", + 3136: "grubd", + 3137: "rtnt-1", + 3138: "rtnt-2", + 3139: "incognitorv", + 3140: "ariliamulti", + 3141: "vmodem", + 3142: "rdc-wh-eos", + 3143: "seaview", + 3144: "tarantella", + 3145: "csi-lfap", + 3146: "bears-02", + 3147: "rfio", + 3148: "nm-game-admin", + 3149: "nm-game-server", + 3150: "nm-asses-admin", + 3151: "nm-assessor", + 3152: "feitianrockey", + 3153: "s8-client-port", + 3154: "ccmrmi", + 3155: "jpegmpeg", + 3156: "indura", + 3157: "e3consultants", + 3158: "stvp", + 3159: "navegaweb-port", + 3160: "tip-app-server", + 3161: "doc1lm", + 3162: "sflm", + 3163: "res-sap", + 3164: "imprs", + 3165: "newgenpay", + 3166: "sossecollector", + 3167: "nowcontact", + 3168: "poweronnud", + 3169: "serverview-as", + 3170: "serverview-asn", + 3171: "serverview-gf", + 3172: "serverview-rm", + 3173: "serverview-icc", + 3174: "armi-server", + 3175: "t1-e1-over-ip", + 3176: "ars-master", + 3177: "phonex-port", + 3178: "radclientport", + 3179: "h2gf-w-2m", + 3180: "mc-brk-srv", + 3181: "bmcpatrolagent", + 3182: "bmcpatrolrnvu", + 3183: "cops-tls", + 3184: "apogeex-port", + 3185: "smpppd", + 3186: "iiw-port", + 3187: "odi-port", + 3188: "brcm-comm-port", + 3189: "pcle-infex", + 3190: "csvr-proxy", + 3191: "csvr-sslproxy", + 3192: "firemonrcc", + 3193: "spandataport", + 3194: "magbind", + 3195: "ncu-1", + 3196: "ncu-2", + 3197: "embrace-dp-s", + 3198: "embrace-dp-c", + 3199: "dmod-workspace", + 3200: "tick-port", + 3201: "cpq-tasksmart", + 3202: "intraintra", + 3203: "netwatcher-mon", + 3204: "netwatcher-db", + 3205: "isns", + 3206: "ironmail", + 3207: "vx-auth-port", + 3208: "pfu-prcallback", + 3209: "netwkpathengine", + 3210: "flamenco-proxy", + 3211: "avsecuremgmt", + 3212: "surveyinst", + 3213: "neon24x7", + 3214: "jmq-daemon-1", + 3215: "jmq-daemon-2", + 3216: "ferrari-foam", + 3217: "unite", + 3218: "smartpackets", + 3219: "wms-messenger", + 3220: "xnm-ssl", + 3221: "xnm-clear-text", + 3222: "glbp", + 3223: "digivote", + 3224: "aes-discovery", + 3225: "fcip-port", + 3226: "isi-irp", + 3227: "dwnmshttp", + 3228: "dwmsgserver", + 3229: "global-cd-port", + 3230: "sftdst-port", + 3231: "vidigo", + 3232: "mdtp", + 3233: "whisker", + 3234: "alchemy", + 3235: "mdap-port", + 3236: "apparenet-ts", + 3237: "apparenet-tps", + 3238: "apparenet-as", + 3239: "apparenet-ui", + 3240: "triomotion", + 3241: "sysorb", + 3242: "sdp-id-port", + 3243: "timelot", + 3244: "onesaf", + 3245: "vieo-fe", + 3246: "dvt-system", + 3247: "dvt-data", + 3248: "procos-lm", + 3249: "ssp", + 3250: "hicp", + 3251: "sysscanner", + 3252: "dhe", + 3253: "pda-data", + 3254: "pda-sys", + 3255: "semaphore", + 3256: "cpqrpm-agent", + 3257: "cpqrpm-server", + 3258: "ivecon-port", + 3259: "epncdp2", + 3260: "iscsi-target", + 3261: "winshadow", + 3262: "necp", + 3263: "ecolor-imager", + 3264: "ccmail", + 3265: "altav-tunnel", + 3266: "ns-cfg-server", + 3267: "ibm-dial-out", + 3268: "msft-gc", + 3269: "msft-gc-ssl", + 3270: "verismart", + 3271: "csoft-prev", + 3272: "user-manager", + 3273: "sxmp", + 3274: "ordinox-server", + 3275: "samd", + 3276: "maxim-asics", + 3277: "awg-proxy", + 3278: "lkcmserver", + 3279: "admind", + 3280: "vs-server", + 3281: "sysopt", + 3282: "datusorb", + 3283: "Apple Remote Desktop (Net Assistant)", + 3284: "4talk", + 3285: "plato", + 3286: "e-net", + 3287: "directvdata", + 3288: "cops", + 3289: "enpc", + 3290: "caps-lm", + 3291: "sah-lm", + 3292: "cart-o-rama", + 3293: "fg-fps", + 3294: "fg-gip", + 3295: "dyniplookup", + 3296: "rib-slm", + 3297: "cytel-lm", + 3298: "deskview", + 3299: "pdrncs", + 3302: "mcs-fastmail", + 3303: "opsession-clnt", + 3304: "opsession-srvr", + 3305: "odette-ftp", + 3306: "mysql", + 3307: "opsession-prxy", + 3308: "tns-server", + 3309: "tns-adv", + 3310: "dyna-access", + 3311: "mcns-tel-ret", + 3312: "appman-server", + 3313: "uorb", + 3314: "uohost", + 3315: "cdid", + 3316: "aicc-cmi", + 3317: "vsaiport", + 3318: "ssrip", + 3319: "sdt-lmd", + 3320: "officelink2000", + 3321: "vnsstr", + 3326: "sftu", + 3327: "bbars", + 3328: "egptlm", + 3329: "hp-device-disc", + 3330: "mcs-calypsoicf", + 3331: "mcs-messaging", + 3332: "mcs-mailsvr", + 3333: "dec-notes", + 3334: "directv-web", + 3335: "directv-soft", + 3336: "directv-tick", + 3337: "directv-catlg", + 3338: "anet-b", + 3339: "anet-l", + 3340: "anet-m", + 3341: "anet-h", + 3342: "webtie", + 3343: "ms-cluster-net", + 3344: "bnt-manager", + 3345: "influence", + 3346: "trnsprntproxy", + 3347: "phoenix-rpc", + 3348: "pangolin-laser", + 3349: "chevinservices", + 3350: "findviatv", + 3351: "btrieve", + 3352: "ssql", + 3353: "fatpipe", + 3354: "suitjd", + 3355: "ordinox-dbase", + 3356: "upnotifyps", + 3357: "adtech-test", + 3358: "mpsysrmsvr", + 3359: "wg-netforce", + 3360: "kv-server", + 3361: "kv-agent", + 3362: "dj-ilm", + 3363: "nati-vi-server", + 3364: "creativeserver", + 3365: "contentserver", + 3366: "creativepartnr", + 3372: "tip2", + 3373: "lavenir-lm", + 3374: "cluster-disc", + 3375: "vsnm-agent", + 3376: "cdbroker", + 3377: "cogsys-lm", + 3378: "wsicopy", + 3379: "socorfs", + 3380: "sns-channels", + 3381: "geneous", + 3382: "fujitsu-neat", + 3383: "esp-lm", + 3384: "hp-clic", + 3385: "qnxnetman", + 3386: "gprs-data", + 3387: "backroomnet", + 3388: "cbserver", + 3389: "ms-wbt-server", + 3390: "dsc", + 3391: "savant", + 3392: "efi-lm", + 3393: "d2k-tapestry1", + 3394: "d2k-tapestry2", + 3395: "dyna-lm", + 3396: "printer-agent", + 3397: "cloanto-lm", + 3398: "mercantile", + 3399: "csms", + 3400: "csms2", + 3401: "filecast", + 3402: "fxaengine-net", + 3405: "nokia-ann-ch1", + 3406: "nokia-ann-ch2", + 3407: "ldap-admin", + 3408: "BESApi", + 3409: "networklens", + 3410: "networklenss", + 3411: "biolink-auth", + 3412: "xmlblaster", + 3413: "svnet", + 3414: "wip-port", + 3415: "bcinameservice", + 3416: "commandport", + 3417: "csvr", + 3418: "rnmap", + 3419: "softaudit", + 3420: "ifcp-port", + 3421: "bmap", + 3422: "rusb-sys-port", + 3423: "xtrm", + 3424: "xtrms", + 3425: "agps-port", + 3426: "arkivio", + 3427: "websphere-snmp", + 3428: "twcss", + 3429: "gcsp", + 3430: "ssdispatch", + 3431: "ndl-als", + 3432: "osdcp", + 3433: "opnet-smp", + 3434: "opencm", + 3435: "pacom", + 3436: "gc-config", + 3437: "autocueds", + 3438: "spiral-admin", + 3439: "hri-port", + 3440: "ans-console", + 3441: "connect-client", + 3442: "connect-server", + 3443: "ov-nnm-websrv", + 3444: "denali-server", + 3445: "monp", + 3446: "3comfaxrpc", + 3447: "directnet", + 3448: "dnc-port", + 3449: "hotu-chat", + 3450: "castorproxy", + 3451: "asam", + 3452: "sabp-signal", + 3453: "pscupd", + 3454: "mira", + 3455: "prsvp", + 3456: "vat", + 3457: "vat-control", + 3458: "d3winosfi", + 3459: "integral", + 3460: "edm-manager", + 3461: "edm-stager", + 3462: "edm-std-notify", + 3463: "edm-adm-notify", + 3464: "edm-mgr-sync", + 3465: "edm-mgr-cntrl", + 3466: "workflow", + 3467: "rcst", + 3468: "ttcmremotectrl", + 3469: "pluribus", + 3470: "jt400", + 3471: "jt400-ssl", + 3472: "jaugsremotec-1", + 3473: "jaugsremotec-2", + 3474: "ttntspauto", + 3475: "genisar-port", + 3476: "nppmp", + 3477: "ecomm", + 3478: "stun", + 3479: "twrpc", + 3480: "plethora", + 3481: "cleanerliverc", + 3482: "vulture", + 3483: "slim-devices", + 3484: "gbs-stp", + 3485: "celatalk", + 3486: "ifsf-hb-port", + 3487: "ltctcp", + 3488: "fs-rh-srv", + 3489: "dtp-dia", + 3490: "colubris", + 3491: "swr-port", + 3492: "tvdumtray-port", + 3493: "nut", + 3494: "ibm3494", + 3495: "seclayer-tcp", + 3496: "seclayer-tls", + 3497: "ipether232port", + 3498: "dashpas-port", + 3499: "sccip-media", + 3500: "rtmp-port", + 3501: "isoft-p2p", + 3502: "avinstalldisc", + 3503: "lsp-ping", + 3504: "ironstorm", + 3505: "ccmcomm", + 3506: "apc-3506", + 3507: "nesh-broker", + 3508: "interactionweb", + 3509: "vt-ssl", + 3510: "xss-port", + 3511: "webmail-2", + 3512: "aztec", + 3513: "arcpd", + 3514: "must-p2p", + 3515: "must-backplane", + 3516: "smartcard-port", + 3517: "802-11-iapp", + 3518: "artifact-msg", + 3519: "nvmsgd", + 3520: "galileolog", + 3521: "mc3ss", + 3522: "nssocketport", + 3523: "odeumservlink", + 3524: "ecmport", + 3525: "eisport", + 3526: "starquiz-port", + 3527: "beserver-msg-q", + 3528: "jboss-iiop", + 3529: "jboss-iiop-ssl", + 3530: "gf", + 3531: "joltid", + 3532: "raven-rmp", + 3533: "raven-rdp", + 3534: "urld-port", + 3535: "ms-la", + 3536: "snac", + 3537: "ni-visa-remote", + 3538: "ibm-diradm", + 3539: "ibm-diradm-ssl", + 3540: "pnrp-port", + 3541: "voispeed-port", + 3542: "hacl-monitor", + 3543: "qftest-lookup", + 3544: "teredo", + 3545: "camac", + 3547: "symantec-sim", + 3548: "interworld", + 3549: "tellumat-nms", + 3550: "ssmpp", + 3551: "apcupsd", + 3552: "taserver", + 3553: "rbr-discovery", + 3554: "questnotify", + 3555: "razor", + 3556: "sky-transport", + 3557: "personalos-001", + 3558: "mcp-port", + 3559: "cctv-port", + 3560: "iniserve-port", + 3561: "bmc-onekey", + 3562: "sdbproxy", + 3563: "watcomdebug", + 3564: "esimport", + 3565: "m2pa", + 3566: "quest-data-hub", + 3567: "enc-eps", + 3568: "enc-tunnel-sec", + 3569: "mbg-ctrl", + 3570: "mccwebsvr-port", + 3571: "megardsvr-port", + 3572: "megaregsvrport", + 3573: "tag-ups-1", + 3574: "dmaf-server", + 3575: "ccm-port", + 3576: "cmc-port", + 3577: "config-port", + 3578: "data-port", + 3579: "ttat3lb", + 3580: "nati-svrloc", + 3581: "kfxaclicensing", + 3582: "press", + 3583: "canex-watch", + 3584: "u-dbap", + 3585: "emprise-lls", + 3586: "emprise-lsc", + 3587: "p2pgroup", + 3588: "sentinel", + 3589: "isomair", + 3590: "wv-csp-sms", + 3591: "gtrack-server", + 3592: "gtrack-ne", + 3593: "bpmd", + 3594: "mediaspace", + 3595: "shareapp", + 3596: "iw-mmogame", + 3597: "a14", + 3598: "a15", + 3599: "quasar-server", + 3600: "trap-daemon", + 3601: "visinet-gui", + 3602: "infiniswitchcl", + 3603: "int-rcv-cntrl", + 3604: "bmc-jmx-port", + 3605: "comcam-io", + 3606: "splitlock", + 3607: "precise-i3", + 3608: "trendchip-dcp", + 3609: "cpdi-pidas-cm", + 3610: "echonet", + 3611: "six-degrees", + 3612: "hp-dataprotect", + 3613: "alaris-disc", + 3614: "sigma-port", + 3615: "start-network", + 3616: "cd3o-protocol", + 3617: "sharp-server", + 3618: "aairnet-1", + 3619: "aairnet-2", + 3620: "ep-pcp", + 3621: "ep-nsp", + 3622: "ff-lr-port", + 3623: "haipe-discover", + 3624: "dist-upgrade", + 3625: "volley", + 3626: "bvcdaemon-port", + 3627: "jamserverport", + 3628: "ept-machine", + 3629: "escvpnet", + 3630: "cs-remote-db", + 3631: "cs-services", + 3632: "distcc", + 3633: "wacp", + 3634: "hlibmgr", + 3635: "sdo", + 3636: "servistaitsm", + 3637: "scservp", + 3638: "ehp-backup", + 3639: "xap-ha", + 3640: "netplay-port1", + 3641: "netplay-port2", + 3642: "juxml-port", + 3643: "audiojuggler", + 3644: "ssowatch", + 3645: "cyc", + 3646: "xss-srv-port", + 3647: "splitlock-gw", + 3648: "fjcp", + 3649: "nmmp", + 3650: "prismiq-plugin", + 3651: "xrpc-registry", + 3652: "vxcrnbuport", + 3653: "tsp", + 3654: "vaprtm", + 3655: "abatemgr", + 3656: "abatjss", + 3657: "immedianet-bcn", + 3658: "ps-ams", + 3659: "apple-sasl", + 3660: "can-nds-ssl", + 3661: "can-ferret-ssl", + 3662: "pserver", + 3663: "dtp", + 3664: "ups-engine", + 3665: "ent-engine", + 3666: "eserver-pap", + 3667: "infoexch", + 3668: "dell-rm-port", + 3669: "casanswmgmt", + 3670: "smile", + 3671: "efcp", + 3672: "lispworks-orb", + 3673: "mediavault-gui", + 3674: "wininstall-ipc", + 3675: "calltrax", + 3676: "va-pacbase", + 3677: "roverlog", + 3678: "ipr-dglt", + 3679: "Escale (Newton Dock)", + 3680: "npds-tracker", + 3681: "bts-x73", + 3682: "cas-mapi", + 3683: "bmc-ea", + 3684: "faxstfx-port", + 3685: "dsx-agent", + 3686: "tnmpv2", + 3687: "simple-push", + 3688: "simple-push-s", + 3689: "daap", + 3690: "svn", + 3691: "magaya-network", + 3692: "intelsync", + 3695: "bmc-data-coll", + 3696: "telnetcpcd", + 3697: "nw-license", + 3698: "sagectlpanel", + 3699: "kpn-icw", + 3700: "lrs-paging", + 3701: "netcelera", + 3702: "ws-discovery", + 3703: "adobeserver-3", + 3704: "adobeserver-4", + 3705: "adobeserver-5", + 3706: "rt-event", + 3707: "rt-event-s", + 3708: "sun-as-iiops", + 3709: "ca-idms", + 3710: "portgate-auth", + 3711: "edb-server2", + 3712: "sentinel-ent", + 3713: "tftps", + 3714: "delos-dms", + 3715: "anoto-rendezv", + 3716: "wv-csp-sms-cir", + 3717: "wv-csp-udp-cir", + 3718: "opus-services", + 3719: "itelserverport", + 3720: "ufastro-instr", + 3721: "xsync", + 3722: "xserveraid", + 3723: "sychrond", + 3724: "blizwow", + 3725: "na-er-tip", + 3726: "array-manager", + 3727: "e-mdu", + 3728: "e-woa", + 3729: "fksp-audit", + 3730: "client-ctrl", + 3731: "smap", + 3732: "m-wnn", + 3733: "multip-msg", + 3734: "synel-data", + 3735: "pwdis", + 3736: "rs-rmi", + 3737: "xpanel", + 3738: "versatalk", + 3739: "launchbird-lm", + 3740: "heartbeat", + 3741: "wysdma", + 3742: "cst-port", + 3743: "ipcs-command", + 3744: "sasg", + 3745: "gw-call-port", + 3746: "linktest", + 3747: "linktest-s", + 3748: "webdata", + 3749: "cimtrak", + 3750: "cbos-ip-port", + 3751: "gprs-cube", + 3752: "vipremoteagent", + 3753: "nattyserver", + 3754: "timestenbroker", + 3755: "sas-remote-hlp", + 3756: "canon-capt", + 3757: "grf-port", + 3758: "apw-registry", + 3759: "exapt-lmgr", + 3760: "adtempusclient", + 3761: "gsakmp", + 3762: "gbs-smp", + 3763: "xo-wave", + 3764: "mni-prot-rout", + 3765: "rtraceroute", + 3766: "sitewatch-s", + 3767: "listmgr-port", + 3768: "rblcheckd", + 3769: "haipe-otnk", + 3770: "cindycollab", + 3771: "paging-port", + 3772: "ctp", + 3773: "ctdhercules", + 3774: "zicom", + 3775: "ispmmgr", + 3776: "dvcprov-port", + 3777: "jibe-eb", + 3778: "c-h-it-port", + 3779: "cognima", + 3780: "nnp", + 3781: "abcvoice-port", + 3782: "iso-tp0s", + 3783: "bim-pem", + 3784: "bfd-control", + 3785: "bfd-echo", + 3786: "upstriggervsw", + 3787: "fintrx", + 3788: "isrp-port", + 3789: "remotedeploy", + 3790: "quickbooksrds", + 3791: "tvnetworkvideo", + 3792: "sitewatch", + 3793: "dcsoftware", + 3794: "jaus", + 3795: "myblast", + 3796: "spw-dialer", + 3797: "idps", + 3798: "minilock", + 3799: "radius-dynauth", + 3800: "pwgpsi", + 3801: "ibm-mgr", + 3802: "vhd", + 3803: "soniqsync", + 3804: "iqnet-port", + 3805: "tcpdataserver", + 3806: "wsmlb", + 3807: "spugna", + 3808: "sun-as-iiops-ca", + 3809: "apocd", + 3810: "wlanauth", + 3811: "amp", + 3812: "neto-wol-server", + 3813: "rap-ip", + 3814: "neto-dcs", + 3815: "lansurveyorxml", + 3816: "sunlps-http", + 3817: "tapeware", + 3818: "crinis-hb", + 3819: "epl-slp", + 3820: "scp", + 3821: "pmcp", + 3822: "acp-discovery", + 3823: "acp-conduit", + 3824: "acp-policy", + 3825: "ffserver", + 3826: "warmux", + 3827: "netmpi", + 3828: "neteh", + 3829: "neteh-ext", + 3830: "cernsysmgmtagt", + 3831: "dvapps", + 3832: "xxnetserver", + 3833: "aipn-auth", + 3834: "spectardata", + 3835: "spectardb", + 3836: "markem-dcp", + 3837: "mkm-discovery", + 3838: "sos", + 3839: "amx-rms", + 3840: "flirtmitmir", + 3841: "shiprush-db-svr", + 3842: "nhci", + 3843: "quest-agent", + 3844: "rnm", + 3845: "v-one-spp", + 3846: "an-pcp", + 3847: "msfw-control", + 3848: "item", + 3849: "spw-dnspreload", + 3850: "qtms-bootstrap", + 3851: "spectraport", + 3852: "sse-app-config", + 3853: "sscan", + 3854: "stryker-com", + 3855: "opentrac", + 3856: "informer", + 3857: "trap-port", + 3858: "trap-port-mom", + 3859: "nav-port", + 3860: "sasp", + 3861: "winshadow-hd", + 3862: "giga-pocket", + 3863: "asap-tcp", + 3864: "asap-tcp-tls", + 3865: "xpl", + 3866: "dzdaemon", + 3867: "dzoglserver", + 3868: "diameter", + 3869: "ovsam-mgmt", + 3870: "ovsam-d-agent", + 3871: "avocent-adsap", + 3872: "oem-agent", + 3873: "fagordnc", + 3874: "sixxsconfig", + 3875: "pnbscada", + 3876: "dl-agent", + 3877: "xmpcr-interface", + 3878: "fotogcad", + 3879: "appss-lm", + 3880: "igrs", + 3881: "idac", + 3882: "msdts1", + 3883: "vrpn", + 3884: "softrack-meter", + 3885: "topflow-ssl", + 3886: "nei-management", + 3887: "ciphire-data", + 3888: "ciphire-serv", + 3889: "dandv-tester", + 3890: "ndsconnect", + 3891: "rtc-pm-port", + 3892: "pcc-image-port", + 3893: "cgi-starapi", + 3894: "syam-agent", + 3895: "syam-smc", + 3896: "sdo-tls", + 3897: "sdo-ssh", + 3898: "senip", + 3899: "itv-control", + 3900: "udt-os", + 3901: "nimsh", + 3902: "nimaux", + 3903: "charsetmgr", + 3904: "omnilink-port", + 3905: "mupdate", + 3906: "topovista-data", + 3907: "imoguia-port", + 3908: "hppronetman", + 3909: "surfcontrolcpa", + 3910: "prnrequest", + 3911: "prnstatus", + 3912: "gbmt-stars", + 3913: "listcrt-port", + 3914: "listcrt-port-2", + 3915: "agcat", + 3916: "wysdmc", + 3917: "aftmux", + 3918: "pktcablemmcops", + 3919: "hyperip", + 3920: "exasoftport1", + 3921: "herodotus-net", + 3922: "sor-update", + 3923: "symb-sb-port", + 3924: "mpl-gprs-port", + 3925: "zmp", + 3926: "winport", + 3927: "natdataservice", + 3928: "netboot-pxe", + 3929: "smauth-port", + 3930: "syam-webserver", + 3931: "msr-plugin-port", + 3932: "dyn-site", + 3933: "plbserve-port", + 3934: "sunfm-port", + 3935: "sdp-portmapper", + 3936: "mailprox", + 3937: "dvbservdsc", + 3938: "dbcontrol-agent", + 3939: "aamp", + 3940: "xecp-node", + 3941: "homeportal-web", + 3942: "srdp", + 3943: "tig", + 3944: "sops", + 3945: "emcads", + 3946: "backupedge", + 3947: "ccp", + 3948: "apdap", + 3949: "drip", + 3950: "namemunge", + 3951: "pwgippfax", + 3952: "i3-sessionmgr", + 3953: "xmlink-connect", + 3954: "adrep", + 3955: "p2pcommunity", + 3956: "gvcp", + 3957: "mqe-broker", + 3958: "mqe-agent", + 3959: "treehopper", + 3960: "bess", + 3961: "proaxess", + 3962: "sbi-agent", + 3963: "thrp", + 3964: "sasggprs", + 3965: "ati-ip-to-ncpe", + 3966: "bflckmgr", + 3967: "ppsms", + 3968: "ianywhere-dbns", + 3969: "landmarks", + 3970: "lanrevagent", + 3971: "lanrevserver", + 3972: "iconp", + 3973: "progistics", + 3974: "citysearch", + 3975: "airshot", + 3976: "opswagent", + 3977: "opswmanager", + 3978: "secure-cfg-svr", + 3979: "smwan", + 3980: "acms", + 3981: "starfish", + 3982: "eis", + 3983: "eisp", + 3984: "mapper-nodemgr", + 3985: "mapper-mapethd", + 3986: "mapper-ws-ethd", + 3987: "centerline", + 3988: "dcs-config", + 3989: "bv-queryengine", + 3990: "bv-is", + 3991: "bv-smcsrv", + 3992: "bv-ds", + 3993: "bv-agent", + 3995: "iss-mgmt-ssl", + 3996: "abcsoftware", + 3997: "agentsease-db", + 3998: "dnx", + 3999: "nvcnet", + 4000: "terabase", + 4001: "newoak", + 4002: "pxc-spvr-ft", + 4003: "pxc-splr-ft", + 4004: "pxc-roid", + 4005: "pxc-pin", + 4006: "pxc-spvr", + 4007: "pxc-splr", + 4008: "netcheque", + 4009: "chimera-hwm", + 4010: "samsung-unidex", + 4011: "altserviceboot", + 4012: "pda-gate", + 4013: "acl-manager", + 4014: "taiclock", + 4015: "talarian-mcast1", + 4016: "talarian-mcast2", + 4017: "talarian-mcast3", + 4018: "talarian-mcast4", + 4019: "talarian-mcast5", + 4020: "trap", + 4021: "nexus-portal", + 4022: "dnox", + 4023: "esnm-zoning", + 4024: "tnp1-port", + 4025: "partimage", + 4026: "as-debug", + 4027: "bxp", + 4028: "dtserver-port", + 4029: "ip-qsig", + 4030: "jdmn-port", + 4031: "suucp", + 4032: "vrts-auth-port", + 4033: "sanavigator", + 4034: "ubxd", + 4035: "wap-push-http", + 4036: "wap-push-https", + 4037: "ravehd", + 4038: "fazzt-ptp", + 4039: "fazzt-admin", + 4040: "yo-main", + 4041: "houston", + 4042: "ldxp", + 4043: "nirp", + 4044: "ltp", + 4045: "npp", + 4046: "acp-proto", + 4047: "ctp-state", + 4049: "wafs", + 4050: "cisco-wafs", + 4051: "cppdp", + 4052: "interact", + 4053: "ccu-comm-1", + 4054: "ccu-comm-2", + 4055: "ccu-comm-3", + 4056: "lms", + 4057: "wfm", + 4058: "kingfisher", + 4059: "dlms-cosem", + 4060: "dsmeter-iatc", + 4061: "ice-location", + 4062: "ice-slocation", + 4063: "ice-router", + 4064: "ice-srouter", + 4065: "avanti-cdp", + 4066: "pmas", + 4067: "idp", + 4068: "ipfltbcst", + 4069: "minger", + 4070: "tripe", + 4071: "aibkup", + 4072: "zieto-sock", + 4073: "iRAPP", + 4074: "cequint-cityid", + 4075: "perimlan", + 4076: "seraph", + 4078: "cssp", + 4079: "santools", + 4080: "lorica-in", + 4081: "lorica-in-sec", + 4082: "lorica-out", + 4083: "lorica-out-sec", + 4085: "ezmessagesrv", + 4087: "applusservice", + 4088: "npsp", + 4089: "opencore", + 4090: "omasgport", + 4091: "ewinstaller", + 4092: "ewdgs", + 4093: "pvxpluscs", + 4094: "sysrqd", + 4095: "xtgui", + 4096: "bre", + 4097: "patrolview", + 4098: "drmsfsd", + 4099: "dpcp", + 4100: "igo-incognito", + 4101: "brlp-0", + 4102: "brlp-1", + 4103: "brlp-2", + 4104: "brlp-3", + 4105: "shofar", + 4106: "synchronite", + 4107: "j-ac", + 4108: "accel", + 4109: "izm", + 4110: "g2tag", + 4111: "xgrid", + 4112: "apple-vpns-rp", + 4113: "aipn-reg", + 4114: "jomamqmonitor", + 4115: "cds", + 4116: "smartcard-tls", + 4117: "hillrserv", + 4118: "netscript", + 4119: "assuria-slm", + 4121: "e-builder", + 4122: "fprams", + 4123: "z-wave", + 4124: "tigv2", + 4125: "opsview-envoy", + 4126: "ddrepl", + 4127: "unikeypro", + 4128: "nufw", + 4129: "nuauth", + 4130: "fronet", + 4131: "stars", + 4132: "nuts-dem", + 4133: "nuts-bootp", + 4134: "nifty-hmi", + 4135: "cl-db-attach", + 4136: "cl-db-request", + 4137: "cl-db-remote", + 4138: "nettest", + 4139: "thrtx", + 4140: "cedros-fds", + 4141: "oirtgsvc", + 4142: "oidocsvc", + 4143: "oidsr", + 4145: "vvr-control", + 4146: "tgcconnect", + 4147: "vrxpservman", + 4148: "hhb-handheld", + 4149: "agslb", + 4150: "PowerAlert-nsa", + 4151: "menandmice-noh", + 4152: "idig-mux", + 4153: "mbl-battd", + 4154: "atlinks", + 4155: "bzr", + 4156: "stat-results", + 4157: "stat-scanner", + 4158: "stat-cc", + 4159: "nss", + 4160: "jini-discovery", + 4161: "omscontact", + 4162: "omstopology", + 4163: "silverpeakpeer", + 4164: "silverpeakcomm", + 4165: "altcp", + 4166: "joost", + 4167: "ddgn", + 4168: "pslicser", + 4169: "iadt", + 4170: "d-cinema-csp", + 4171: "ml-svnet", + 4172: "pcoip", + 4174: "smcluster", + 4175: "bccp", + 4176: "tl-ipcproxy", + 4177: "wello", + 4178: "storman", + 4179: "MaxumSP", + 4180: "httpx", + 4181: "macbak", + 4182: "pcptcpservice", + 4183: "gmmp", + 4184: "universe-suite", + 4185: "wcpp", + 4186: "boxbackupstore", + 4187: "csc-proxy", + 4188: "vatata", + 4189: "pcep", + 4190: "sieve", + 4192: "azeti", + 4193: "pvxplusio", + 4199: "eims-admin", + 4300: "corelccam", + 4301: "d-data", + 4302: "d-data-control", + 4303: "srcp", + 4304: "owserver", + 4305: "batman", + 4306: "pinghgl", + 4307: "visicron-vs", + 4308: "compx-lockview", + 4309: "dserver", + 4310: "mirrtex", + 4311: "p6ssmc", + 4312: "pscl-mgt", + 4313: "perrla", + 4314: "choiceview-agt", + 4316: "choiceview-clt", + 4320: "fdt-rcatp", + 4321: "rwhois", + 4322: "trim-event", + 4323: "trim-ice", + 4324: "balour", + 4325: "geognosisman", + 4326: "geognosis", + 4327: "jaxer-web", + 4328: "jaxer-manager", + 4329: "publiqare-sync", + 4330: "dey-sapi", + 4331: "ktickets-rest", + 4333: "ahsp", + 4340: "gaia", + 4341: "lisp-data", + 4342: "lisp-cons", + 4343: "unicall", + 4344: "vinainstall", + 4345: "m4-network-as", + 4346: "elanlm", + 4347: "lansurveyor", + 4348: "itose", + 4349: "fsportmap", + 4350: "net-device", + 4351: "plcy-net-svcs", + 4352: "pjlink", + 4353: "f5-iquery", + 4354: "qsnet-trans", + 4355: "qsnet-workst", + 4356: "qsnet-assist", + 4357: "qsnet-cond", + 4358: "qsnet-nucl", + 4359: "omabcastltkm", + 4360: "matrix-vnet", + 4368: "wxbrief", + 4369: "epmd", + 4370: "elpro-tunnel", + 4371: "l2c-control", + 4372: "l2c-data", + 4373: "remctl", + 4374: "psi-ptt", + 4375: "tolteces", + 4376: "bip", + 4377: "cp-spxsvr", + 4378: "cp-spxdpy", + 4379: "ctdb", + 4389: "xandros-cms", + 4390: "wiegand", + 4391: "apwi-imserver", + 4392: "apwi-rxserver", + 4393: "apwi-rxspooler", + 4395: "omnivisionesx", + 4396: "fly", + 4400: "ds-srv", + 4401: "ds-srvr", + 4402: "ds-clnt", + 4403: "ds-user", + 4404: "ds-admin", + 4405: "ds-mail", + 4406: "ds-slp", + 4407: "nacagent", + 4408: "slscc", + 4409: "netcabinet-com", + 4410: "itwo-server", + 4411: "found", + 4425: "netrockey6", + 4426: "beacon-port-2", + 4427: "drizzle", + 4428: "omviserver", + 4429: "omviagent", + 4430: "rsqlserver", + 4431: "wspipe", + 4432: "l-acoustics", + 4433: "vop", + 4442: "saris", + 4443: "pharos", + 4444: "krb524", + 4445: "upnotifyp", + 4446: "n1-fwp", + 4447: "n1-rmgmt", + 4448: "asc-slmd", + 4449: "privatewire", + 4450: "camp", + 4451: "ctisystemmsg", + 4452: "ctiprogramload", + 4453: "nssalertmgr", + 4454: "nssagentmgr", + 4455: "prchat-user", + 4456: "prchat-server", + 4457: "prRegister", + 4458: "mcp", + 4484: "hpssmgmt", + 4485: "assyst-dr", + 4486: "icms", + 4487: "prex-tcp", + 4488: "awacs-ice", + 4500: "ipsec-nat-t", + 4535: "ehs", + 4536: "ehs-ssl", + 4537: "wssauthsvc", + 4538: "swx-gate", + 4545: "worldscores", + 4546: "sf-lm", + 4547: "lanner-lm", + 4548: "synchromesh", + 4549: "aegate", + 4550: "gds-adppiw-db", + 4551: "ieee-mih", + 4552: "menandmice-mon", + 4553: "icshostsvc", + 4554: "msfrs", + 4555: "rsip", + 4556: "dtn-bundle", + 4559: "hylafax", + 4563: "amahi-anywhere", + 4566: "kwtc", + 4567: "tram", + 4568: "bmc-reporting", + 4569: "iax", + 4570: "deploymentmap", + 4590: "rid", + 4591: "l3t-at-an", + 4593: "ipt-anri-anri", + 4594: "ias-session", + 4595: "ias-paging", + 4596: "ias-neighbor", + 4597: "a21-an-1xbs", + 4598: "a16-an-an", + 4599: "a17-an-an", + 4600: "piranha1", + 4601: "piranha2", + 4602: "mtsserver", + 4603: "menandmice-upg", + 4604: "irp", + 4658: "playsta2-app", + 4659: "playsta2-lob", + 4660: "smaclmgr", + 4661: "kar2ouche", + 4662: "oms", + 4663: "noteit", + 4664: "ems", + 4665: "contclientms", + 4666: "eportcomm", + 4667: "mmacomm", + 4668: "mmaeds", + 4669: "eportcommdata", + 4670: "light", + 4671: "acter", + 4672: "rfa", + 4673: "cxws", + 4674: "appiq-mgmt", + 4675: "dhct-status", + 4676: "dhct-alerts", + 4677: "bcs", + 4678: "traversal", + 4679: "mgesupervision", + 4680: "mgemanagement", + 4681: "parliant", + 4682: "finisar", + 4683: "spike", + 4684: "rfid-rp1", + 4685: "autopac", + 4686: "msp-os", + 4687: "nst", + 4688: "mobile-p2p", + 4689: "altovacentral", + 4690: "prelude", + 4691: "mtn", + 4692: "conspiracy", + 4700: "netxms-agent", + 4701: "netxms-mgmt", + 4702: "netxms-sync", + 4703: "npqes-test", + 4704: "assuria-ins", + 4725: "truckstar", + 4727: "fcis", + 4728: "capmux", + 4730: "gearman", + 4731: "remcap", + 4733: "resorcs", + 4737: "ipdr-sp", + 4738: "solera-lpn", + 4739: "ipfix", + 4740: "ipfixs", + 4741: "lumimgrd", + 4742: "sicct", + 4743: "openhpid", + 4744: "ifsp", + 4745: "fmp", + 4749: "profilemac", + 4750: "ssad", + 4751: "spocp", + 4752: "snap", + 4753: "simon", + 4784: "bfd-multi-ctl", + 4786: "smart-install", + 4787: "sia-ctrl-plane", + 4788: "xmcp", + 4800: "iims", + 4801: "iwec", + 4802: "ilss", + 4803: "notateit", + 4827: "htcp", + 4837: "varadero-0", + 4838: "varadero-1", + 4839: "varadero-2", + 4840: "opcua-tcp", + 4841: "quosa", + 4842: "gw-asv", + 4843: "opcua-tls", + 4844: "gw-log", + 4845: "wcr-remlib", + 4846: "contamac-icm", + 4847: "wfc", + 4848: "appserv-http", + 4849: "appserv-https", + 4850: "sun-as-nodeagt", + 4851: "derby-repli", + 4867: "unify-debug", + 4868: "phrelay", + 4869: "phrelaydbg", + 4870: "cc-tracking", + 4871: "wired", + 4876: "tritium-can", + 4877: "lmcs", + 4879: "wsdl-event", + 4880: "hislip", + 4883: "wmlserver", + 4884: "hivestor", + 4885: "abbs", + 4894: "lyskom", + 4899: "radmin-port", + 4900: "hfcs", + 4901: "flr-agent", + 4902: "magiccontrol", + 4912: "lutap", + 4913: "lutcp", + 4914: "bones", + 4915: "frcs", + 4940: "eq-office-4940", + 4941: "eq-office-4941", + 4942: "eq-office-4942", + 4949: "munin", + 4950: "sybasesrvmon", + 4951: "pwgwims", + 4952: "sagxtsds", + 4953: "dbsyncarbiter", + 4969: "ccss-qmm", + 4970: "ccss-qsm", + 4984: "webyast", + 4985: "gerhcs", + 4986: "mrip", + 4987: "smar-se-port1", + 4988: "smar-se-port2", + 4989: "parallel", + 4990: "busycal", + 4991: "vrt", + 4999: "hfcs-manager", + 5000: "commplex-main", + 5001: "commplex-link", + 5002: "rfe", + 5003: "fmpro-internal", + 5004: "avt-profile-1", + 5005: "avt-profile-2", + 5006: "wsm-server", + 5007: "wsm-server-ssl", + 5008: "synapsis-edge", + 5009: "winfs", + 5010: "telelpathstart", + 5011: "telelpathattack", + 5012: "nsp", + 5013: "fmpro-v6", + 5015: "fmwp", + 5020: "zenginkyo-1", + 5021: "zenginkyo-2", + 5022: "mice", + 5023: "htuilsrv", + 5024: "scpi-telnet", + 5025: "scpi-raw", + 5026: "strexec-d", + 5027: "strexec-s", + 5028: "qvr", + 5029: "infobright", + 5030: "surfpass", + 5032: "signacert-agent", + 5042: "asnaacceler8db", + 5043: "swxadmin", + 5044: "lxi-evntsvc", + 5045: "osp", + 5048: "texai", + 5049: "ivocalize", + 5050: "mmcc", + 5051: "ita-agent", + 5052: "ita-manager", + 5053: "rlm", + 5054: "rlm-admin", + 5055: "unot", + 5056: "intecom-ps1", + 5057: "intecom-ps2", + 5059: "sds", + 5060: "sip", + 5061: "sips", + 5062: "na-localise", + 5063: "csrpc", + 5064: "ca-1", + 5065: "ca-2", + 5066: "stanag-5066", + 5067: "authentx", + 5068: "bitforestsrv", + 5069: "i-net-2000-npr", + 5070: "vtsas", + 5071: "powerschool", + 5072: "ayiya", + 5073: "tag-pm", + 5074: "alesquery", + 5075: "pvaccess", + 5080: "onscreen", + 5081: "sdl-ets", + 5082: "qcp", + 5083: "qfp", + 5084: "llrp", + 5085: "encrypted-llrp", + 5086: "aprigo-cs", + 5087: "biotic", + 5093: "sentinel-lm", + 5094: "hart-ip", + 5099: "sentlm-srv2srv", + 5100: "socalia", + 5101: "talarian-tcp", + 5102: "oms-nonsecure", + 5103: "actifio-c2c", + 5106: "actifioudsagent", + 5111: "taep-as-svc", + 5112: "pm-cmdsvr", + 5114: "ev-services", + 5115: "autobuild", + 5117: "gradecam", + 5120: "barracuda-bbs", + 5133: "nbt-pc", + 5134: "ppactivation", + 5135: "erp-scale", + 5137: "ctsd", + 5145: "rmonitor-secure", + 5146: "social-alarm", + 5150: "atmp", + 5151: "esri-sde", + 5152: "sde-discovery", + 5153: "toruxserver", + 5154: "bzflag", + 5155: "asctrl-agent", + 5156: "rugameonline", + 5157: "mediat", + 5161: "snmpssh", + 5162: "snmpssh-trap", + 5163: "sbackup", + 5164: "vpa", + 5165: "ife-icorp", + 5166: "winpcs", + 5167: "scte104", + 5168: "scte30", + 5172: "pcoip-mgmt", + 5190: "aol", + 5191: "aol-1", + 5192: "aol-2", + 5193: "aol-3", + 5194: "cpscomm", + 5195: "ampl-lic", + 5196: "ampl-tableproxy", + 5200: "targus-getdata", + 5201: "targus-getdata1", + 5202: "targus-getdata2", + 5203: "targus-getdata3", + 5209: "nomad", + 5215: "noteza", + 5221: "3exmp", + 5222: "xmpp-client", + 5223: "hpvirtgrp", + 5224: "hpvirtctrl", + 5225: "hp-server", + 5226: "hp-status", + 5227: "perfd", + 5228: "hpvroom", + 5229: "jaxflow", + 5230: "jaxflow-data", + 5231: "crusecontrol", + 5232: "csedaemon", + 5233: "enfs", + 5234: "eenet", + 5235: "galaxy-network", + 5236: "padl2sim", + 5237: "mnet-discovery", + 5245: "downtools", + 5248: "caacws", + 5249: "caaclang2", + 5250: "soagateway", + 5251: "caevms", + 5252: "movaz-ssc", + 5253: "kpdp", + 5264: "3com-njack-1", + 5265: "3com-njack-2", + 5269: "xmpp-server", + 5270: "cartographerxmp", + 5271: "cuelink", + 5272: "pk", + 5280: "xmpp-bosh", + 5281: "undo-lm", + 5282: "transmit-port", + 5298: "presence", + 5299: "nlg-data", + 5300: "hacl-hb", + 5301: "hacl-gs", + 5302: "hacl-cfg", + 5303: "hacl-probe", + 5304: "hacl-local", + 5305: "hacl-test", + 5306: "sun-mc-grp", + 5307: "sco-aip", + 5308: "cfengine", + 5309: "jprinter", + 5310: "outlaws", + 5312: "permabit-cs", + 5313: "rrdp", + 5314: "opalis-rbt-ipc", + 5315: "hacl-poll", + 5316: "hpbladems", + 5317: "hpdevms", + 5318: "pkix-cmc", + 5320: "bsfserver-zn", + 5321: "bsfsvr-zn-ssl", + 5343: "kfserver", + 5344: "xkotodrcp", + 5349: "stuns", + 5352: "dns-llq", + 5353: "mdns", + 5354: "mdnsresponder", + 5355: "llmnr", + 5356: "ms-smlbiz", + 5357: "wsdapi", + 5358: "wsdapi-s", + 5359: "ms-alerter", + 5360: "ms-sideshow", + 5361: "ms-s-sideshow", + 5362: "serverwsd2", + 5363: "net-projection", + 5397: "stresstester", + 5398: "elektron-admin", + 5399: "securitychase", + 5400: "excerpt", + 5401: "excerpts", + 5402: "mftp", + 5403: "hpoms-ci-lstn", + 5404: "hpoms-dps-lstn", + 5405: "netsupport", + 5406: "systemics-sox", + 5407: "foresyte-clear", + 5408: "foresyte-sec", + 5409: "salient-dtasrv", + 5410: "salient-usrmgr", + 5411: "actnet", + 5412: "continuus", + 5413: "wwiotalk", + 5414: "statusd", + 5415: "ns-server", + 5416: "sns-gateway", + 5417: "sns-agent", + 5418: "mcntp", + 5419: "dj-ice", + 5420: "cylink-c", + 5421: "netsupport2", + 5422: "salient-mux", + 5423: "virtualuser", + 5424: "beyond-remote", + 5425: "br-channel", + 5426: "devbasic", + 5427: "sco-peer-tta", + 5428: "telaconsole", + 5429: "base", + 5430: "radec-corp", + 5431: "park-agent", + 5432: "postgresql", + 5433: "pyrrho", + 5434: "sgi-arrayd", + 5435: "sceanics", + 5443: "spss", + 5445: "smbdirect", + 5453: "surebox", + 5454: "apc-5454", + 5455: "apc-5455", + 5456: "apc-5456", + 5461: "silkmeter", + 5462: "ttl-publisher", + 5463: "ttlpriceproxy", + 5464: "quailnet", + 5465: "netops-broker", + 5500: "fcp-addr-srvr1", + 5501: "fcp-addr-srvr2", + 5502: "fcp-srvr-inst1", + 5503: "fcp-srvr-inst2", + 5504: "fcp-cics-gw1", + 5505: "checkoutdb", + 5506: "amc", + 5553: "sgi-eventmond", + 5554: "sgi-esphttp", + 5555: "personal-agent", + 5556: "freeciv", + 5557: "farenet", + 5566: "westec-connect", + 5567: "enc-eps-mc-sec", + 5568: "sdt", + 5569: "rdmnet-ctrl", + 5573: "sdmmp", + 5574: "lsi-bobcat", + 5575: "ora-oap", + 5579: "fdtracks", + 5580: "tmosms0", + 5581: "tmosms1", + 5582: "fac-restore", + 5583: "tmo-icon-sync", + 5584: "bis-web", + 5585: "bis-sync", + 5586: "att-mt-sms", + 5597: "ininmessaging", + 5598: "mctfeed", + 5599: "esinstall", + 5600: "esmmanager", + 5601: "esmagent", + 5602: "a1-msc", + 5603: "a1-bs", + 5604: "a3-sdunode", + 5605: "a4-sdunode", + 5618: "efr", + 5627: "ninaf", + 5628: "htrust", + 5629: "symantec-sfdb", + 5630: "precise-comm", + 5631: "pcanywheredata", + 5632: "pcanywherestat", + 5633: "beorl", + 5634: "xprtld", + 5635: "sfmsso", + 5636: "sfm-db-server", + 5637: "cssc", + 5638: "flcrs", + 5639: "ics", + 5646: "vfmobile", + 5670: "filemq", + 5671: "amqps", + 5672: "amqp", + 5673: "jms", + 5674: "hyperscsi-port", + 5675: "v5ua", + 5676: "raadmin", + 5677: "questdb2-lnchr", + 5678: "rrac", + 5679: "dccm", + 5680: "auriga-router", + 5681: "ncxcp", + 5688: "ggz", + 5689: "qmvideo", + 5693: "rbsystem", + 5696: "kmip", + 5713: "proshareaudio", + 5714: "prosharevideo", + 5715: "prosharedata", + 5716: "prosharerequest", + 5717: "prosharenotify", + 5718: "dpm", + 5719: "dpm-agent", + 5720: "ms-licensing", + 5721: "dtpt", + 5722: "msdfsr", + 5723: "omhs", + 5724: "omsdk", + 5725: "ms-ilm", + 5726: "ms-ilm-sts", + 5727: "asgenf", + 5728: "io-dist-data", + 5729: "openmail", + 5730: "unieng", + 5741: "ida-discover1", + 5742: "ida-discover2", + 5743: "watchdoc-pod", + 5744: "watchdoc", + 5745: "fcopy-server", + 5746: "fcopys-server", + 5747: "tunatic", + 5748: "tunalyzer", + 5750: "rscd", + 5755: "openmailg", + 5757: "x500ms", + 5766: "openmailns", + 5767: "s-openmail", + 5768: "openmailpxy", + 5769: "spramsca", + 5770: "spramsd", + 5771: "netagent", + 5777: "dali-port", + 5780: "vts-rpc", + 5781: "3par-evts", + 5782: "3par-mgmt", + 5783: "3par-mgmt-ssl", + 5785: "3par-rcopy", + 5793: "xtreamx", + 5813: "icmpd", + 5814: "spt-automation", + 5841: "shiprush-d-ch", + 5842: "reversion", + 5859: "wherehoo", + 5863: "ppsuitemsg", + 5868: "diameters", + 5883: "jute", + 5900: "rfb", + 5910: "cm", + 5911: "cpdlc", + 5912: "fis", + 5913: "ads-c", + 5963: "indy", + 5968: "mppolicy-v5", + 5969: "mppolicy-mgr", + 5984: "couchdb", + 5985: "wsman", + 5986: "wsmans", + 5987: "wbem-rmi", + 5988: "wbem-http", + 5989: "wbem-https", + 5990: "wbem-exp-https", + 5991: "nuxsl", + 5992: "consul-insight", + 5999: "cvsup", + 6064: "ndl-ahp-svc", + 6065: "winpharaoh", + 6066: "ewctsp", + 6068: "gsmp-ancp", + 6069: "trip", + 6070: "messageasap", + 6071: "ssdtp", + 6072: "diagnose-proc", + 6073: "directplay8", + 6074: "max", + 6075: "dpm-acm", + 6076: "msft-dpm-cert", + 6077: "iconstructsrv", + 6084: "reload-config", + 6085: "konspire2b", + 6086: "pdtp", + 6087: "ldss", + 6088: "doglms", + 6099: "raxa-mgmt", + 6100: "synchronet-db", + 6101: "synchronet-rtc", + 6102: "synchronet-upd", + 6103: "rets", + 6104: "dbdb", + 6105: "primaserver", + 6106: "mpsserver", + 6107: "etc-control", + 6108: "sercomm-scadmin", + 6109: "globecast-id", + 6110: "softcm", + 6111: "spc", + 6112: "dtspcd", + 6113: "dayliteserver", + 6114: "wrspice", + 6115: "xic", + 6116: "xtlserv", + 6117: "daylitetouch", + 6121: "spdy", + 6122: "bex-webadmin", + 6123: "backup-express", + 6124: "pnbs", + 6130: "damewaremobgtwy", + 6133: "nbt-wol", + 6140: "pulsonixnls", + 6141: "meta-corp", + 6142: "aspentec-lm", + 6143: "watershed-lm", + 6144: "statsci1-lm", + 6145: "statsci2-lm", + 6146: "lonewolf-lm", + 6147: "montage-lm", + 6148: "ricardo-lm", + 6149: "tal-pod", + 6159: "efb-aci", + 6160: "ecmp", + 6161: "patrol-ism", + 6162: "patrol-coll", + 6163: "pscribe", + 6200: "lm-x", + 6222: "radmind", + 6241: "jeol-nsdtp-1", + 6242: "jeol-nsdtp-2", + 6243: "jeol-nsdtp-3", + 6244: "jeol-nsdtp-4", + 6251: "tl1-raw-ssl", + 6252: "tl1-ssh", + 6253: "crip", + 6267: "gld", + 6268: "grid", + 6269: "grid-alt", + 6300: "bmc-grx", + 6301: "bmc-ctd-ldap", + 6306: "ufmp", + 6315: "scup", + 6316: "abb-escp", + 6317: "nav-data-cmd", + 6320: "repsvc", + 6321: "emp-server1", + 6322: "emp-server2", + 6324: "hrd-ncs", + 6325: "dt-mgmtsvc", + 6326: "dt-vra", + 6343: "sflow", + 6344: "streletz", + 6346: "gnutella-svc", + 6347: "gnutella-rtr", + 6350: "adap", + 6355: "pmcs", + 6360: "metaedit-mu", + 6370: "metaedit-se", + 6382: "metatude-mds", + 6389: "clariion-evr01", + 6390: "metaedit-ws", + 6417: "faxcomservice", + 6418: "syserverremote", + 6419: "svdrp", + 6420: "nim-vdrshell", + 6421: "nim-wan", + 6432: "pgbouncer", + 6442: "tarp", + 6443: "sun-sr-https", + 6444: "sge-qmaster", + 6445: "sge-execd", + 6446: "mysql-proxy", + 6455: "skip-cert-recv", + 6456: "skip-cert-send", + 6471: "lvision-lm", + 6480: "sun-sr-http", + 6481: "servicetags", + 6482: "ldoms-mgmt", + 6483: "SunVTS-RMI", + 6484: "sun-sr-jms", + 6485: "sun-sr-iiop", + 6486: "sun-sr-iiops", + 6487: "sun-sr-iiop-aut", + 6488: "sun-sr-jmx", + 6489: "sun-sr-admin", + 6500: "boks", + 6501: "boks-servc", + 6502: "boks-servm", + 6503: "boks-clntd", + 6505: "badm-priv", + 6506: "badm-pub", + 6507: "bdir-priv", + 6508: "bdir-pub", + 6509: "mgcs-mfp-port", + 6510: "mcer-port", + 6513: "netconf-tls", + 6514: "syslog-tls", + 6515: "elipse-rec", + 6543: "lds-distrib", + 6544: "lds-dump", + 6547: "apc-6547", + 6548: "apc-6548", + 6549: "apc-6549", + 6550: "fg-sysupdate", + 6551: "sum", + 6558: "xdsxdm", + 6566: "sane-port", + 6568: "canit-store", + 6579: "affiliate", + 6580: "parsec-master", + 6581: "parsec-peer", + 6582: "parsec-game", + 6583: "joaJewelSuite", + 6600: "mshvlm", + 6601: "mstmg-sstp", + 6602: "wsscomfrmwk", + 6619: "odette-ftps", + 6620: "kftp-data", + 6621: "kftp", + 6622: "mcftp", + 6623: "ktelnet", + 6624: "datascaler-db", + 6625: "datascaler-ctl", + 6626: "wago-service", + 6627: "nexgen", + 6628: "afesc-mc", + 6632: "mxodbc-connect", + 6640: "ovsdb", + 6653: "openflow", + 6655: "pcs-sf-ui-man", + 6656: "emgmsg", + 6670: "vocaltec-gold", + 6671: "p4p-portal", + 6672: "vision-server", + 6673: "vision-elmd", + 6678: "vfbp", + 6679: "osaut", + 6687: "clever-ctrace", + 6688: "clever-tcpip", + 6689: "tsa", + 6697: "ircs-u", + 6701: "kti-icad-srvr", + 6702: "e-design-net", + 6703: "e-design-web", + 6714: "ibprotocol", + 6715: "fibotrader-com", + 6716: "printercare-cc", + 6767: "bmc-perf-agent", + 6768: "bmc-perf-mgrd", + 6769: "adi-gxp-srvprt", + 6770: "plysrv-http", + 6771: "plysrv-https", + 6777: "ntz-tracker", + 6778: "ntz-p2p-storage", + 6785: "dgpf-exchg", + 6786: "smc-jmx", + 6787: "smc-admin", + 6788: "smc-http", + 6789: "smc-https", + 6790: "hnmp", + 6791: "hnm", + 6801: "acnet", + 6817: "pentbox-sim", + 6831: "ambit-lm", + 6841: "netmo-default", + 6842: "netmo-http", + 6850: "iccrushmore", + 6868: "acctopus-cc", + 6888: "muse", + 6901: "jetstream", + 6935: "ethoscan", + 6936: "xsmsvc", + 6946: "bioserver", + 6951: "otlp", + 6961: "jmact3", + 6962: "jmevt2", + 6963: "swismgr1", + 6964: "swismgr2", + 6965: "swistrap", + 6966: "swispol", + 6969: "acmsoda", + 6997: "MobilitySrv", + 6998: "iatp-highpri", + 6999: "iatp-normalpri", + 7000: "afs3-fileserver", + 7001: "afs3-callback", + 7002: "afs3-prserver", + 7003: "afs3-vlserver", + 7004: "afs3-kaserver", + 7005: "afs3-volser", + 7006: "afs3-errors", + 7007: "afs3-bos", + 7008: "afs3-update", + 7009: "afs3-rmtsys", + 7010: "ups-onlinet", + 7011: "talon-disc", + 7012: "talon-engine", + 7013: "microtalon-dis", + 7014: "microtalon-com", + 7015: "talon-webserver", + 7018: "fisa-svc", + 7019: "doceri-ctl", + 7020: "dpserve", + 7021: "dpserveadmin", + 7022: "ctdp", + 7023: "ct2nmcs", + 7024: "vmsvc", + 7025: "vmsvc-2", + 7030: "op-probe", + 7031: "iposplanet", + 7070: "arcp", + 7071: "iwg1", + 7073: "martalk", + 7080: "empowerid", + 7099: "lazy-ptop", + 7100: "font-service", + 7101: "elcn", + 7121: "virprot-lm", + 7128: "scenidm", + 7129: "scenccs", + 7161: "cabsm-comm", + 7162: "caistoragemgr", + 7163: "cacsambroker", + 7164: "fsr", + 7165: "doc-server", + 7166: "aruba-server", + 7167: "casrmagent", + 7168: "cnckadserver", + 7169: "ccag-pib", + 7170: "nsrp", + 7171: "drm-production", + 7172: "metalbend", + 7173: "zsecure", + 7174: "clutild", + 7200: "fodms", + 7201: "dlip", + 7227: "ramp", + 7228: "citrixupp", + 7229: "citrixuppg", + 7236: "display", + 7237: "pads", + 7262: "cnap", + 7272: "watchme-7272", + 7273: "oma-rlp", + 7274: "oma-rlp-s", + 7275: "oma-ulp", + 7276: "oma-ilp", + 7277: "oma-ilp-s", + 7278: "oma-dcdocbs", + 7279: "ctxlic", + 7280: "itactionserver1", + 7281: "itactionserver2", + 7282: "mzca-action", + 7283: "genstat", + 7365: "lcm-server", + 7391: "mindfilesys", + 7392: "mrssrendezvous", + 7393: "nfoldman", + 7394: "fse", + 7395: "winqedit", + 7397: "hexarc", + 7400: "rtps-discovery", + 7401: "rtps-dd-ut", + 7402: "rtps-dd-mt", + 7410: "ionixnetmon", + 7411: "daqstream", + 7421: "mtportmon", + 7426: "pmdmgr", + 7427: "oveadmgr", + 7428: "ovladmgr", + 7429: "opi-sock", + 7430: "xmpv7", + 7431: "pmd", + 7437: "faximum", + 7443: "oracleas-https", + 7471: "sttunnel", + 7473: "rise", + 7474: "neo4j", + 7491: "telops-lmd", + 7500: "silhouette", + 7501: "ovbus", + 7508: "adcp", + 7509: "acplt", + 7510: "ovhpas", + 7511: "pafec-lm", + 7542: "saratoga", + 7543: "atul", + 7544: "nta-ds", + 7545: "nta-us", + 7546: "cfs", + 7547: "cwmp", + 7548: "tidp", + 7549: "nls-tl", + 7560: "sncp", + 7563: "cfw", + 7566: "vsi-omega", + 7569: "dell-eql-asm", + 7570: "aries-kfinder", + 7574: "coherence", + 7588: "sun-lm", + 7624: "indi", + 7626: "simco", + 7627: "soap-http", + 7628: "zen-pawn", + 7629: "xdas", + 7630: "hawk", + 7631: "tesla-sys-msg", + 7633: "pmdfmgt", + 7648: "cuseeme", + 7672: "imqstomp", + 7673: "imqstomps", + 7674: "imqtunnels", + 7675: "imqtunnel", + 7676: "imqbrokerd", + 7677: "sun-user-https", + 7680: "pando-pub", + 7689: "collaber", + 7697: "klio", + 7700: "em7-secom", + 7707: "sync-em7", + 7708: "scinet", + 7720: "medimageportal", + 7724: "nsdeepfreezectl", + 7725: "nitrogen", + 7726: "freezexservice", + 7727: "trident-data", + 7734: "smip", + 7738: "aiagent", + 7741: "scriptview", + 7742: "msss", + 7743: "sstp-1", + 7744: "raqmon-pdu", + 7747: "prgp", + 7777: "cbt", + 7778: "interwise", + 7779: "vstat", + 7781: "accu-lmgr", + 7786: "minivend", + 7787: "popup-reminders", + 7789: "office-tools", + 7794: "q3ade", + 7797: "pnet-conn", + 7798: "pnet-enc", + 7799: "altbsdp", + 7800: "asr", + 7801: "ssp-client", + 7810: "rbt-wanopt", + 7845: "apc-7845", + 7846: "apc-7846", + 7847: "csoauth", + 7869: "mobileanalyzer", + 7870: "rbt-smc", + 7871: "mdm", + 7878: "owms", + 7880: "pss", + 7887: "ubroker", + 7900: "mevent", + 7901: "tnos-sp", + 7902: "tnos-dp", + 7903: "tnos-dps", + 7913: "qo-secure", + 7932: "t2-drm", + 7933: "t2-brm", + 7962: "generalsync", + 7967: "supercell", + 7979: "micromuse-ncps", + 7980: "quest-vista", + 7981: "sossd-collect", + 7982: "sossd-agent", + 7997: "pushns", + 7999: "irdmi2", + 8000: "irdmi", + 8001: "vcom-tunnel", + 8002: "teradataordbms", + 8003: "mcreport", + 8005: "mxi", + 8008: "http-alt", + 8019: "qbdb", + 8020: "intu-ec-svcdisc", + 8021: "intu-ec-client", + 8022: "oa-system", + 8025: "ca-audit-da", + 8026: "ca-audit-ds", + 8032: "pro-ed", + 8033: "mindprint", + 8034: "vantronix-mgmt", + 8040: "ampify", + 8042: "fs-agent", + 8043: "fs-server", + 8044: "fs-mgmt", + 8051: "rocrail", + 8052: "senomix01", + 8053: "senomix02", + 8054: "senomix03", + 8055: "senomix04", + 8056: "senomix05", + 8057: "senomix06", + 8058: "senomix07", + 8059: "senomix08", + 8066: "toad-bi-appsrvr", + 8074: "gadugadu", + 8080: "http-alt", + 8081: "sunproxyadmin", + 8082: "us-cli", + 8083: "us-srv", + 8086: "d-s-n", + 8087: "simplifymedia", + 8088: "radan-http", + 8091: "jamlink", + 8097: "sac", + 8100: "xprint-server", + 8101: "ldoms-migr", + 8102: "kz-migr", + 8115: "mtl8000-matrix", + 8116: "cp-cluster", + 8117: "purityrpc", + 8118: "privoxy", + 8121: "apollo-data", + 8122: "apollo-admin", + 8128: "paycash-online", + 8129: "paycash-wbp", + 8130: "indigo-vrmi", + 8131: "indigo-vbcp", + 8132: "dbabble", + 8148: "isdd", + 8153: "quantastor", + 8160: "patrol", + 8161: "patrol-snmp", + 8162: "lpar2rrd", + 8181: "intermapper", + 8182: "vmware-fdm", + 8183: "proremote", + 8184: "itach", + 8191: "limnerpressure", + 8192: "spytechphone", + 8194: "blp1", + 8195: "blp2", + 8199: "vvr-data", + 8200: "trivnet1", + 8201: "trivnet2", + 8204: "lm-perfworks", + 8205: "lm-instmgr", + 8206: "lm-dta", + 8207: "lm-sserver", + 8208: "lm-webwatcher", + 8230: "rexecj", + 8243: "synapse-nhttps", + 8276: "pando-sec", + 8280: "synapse-nhttp", + 8292: "blp3", + 8293: "hiperscan-id", + 8294: "blp4", + 8300: "tmi", + 8301: "amberon", + 8313: "hub-open-net", + 8320: "tnp-discover", + 8321: "tnp", + 8351: "server-find", + 8376: "cruise-enum", + 8377: "cruise-swroute", + 8378: "cruise-config", + 8379: "cruise-diags", + 8380: "cruise-update", + 8383: "m2mservices", + 8400: "cvd", + 8401: "sabarsd", + 8402: "abarsd", + 8403: "admind", + 8404: "svcloud", + 8405: "svbackup", + 8415: "dlpx-sp", + 8416: "espeech", + 8417: "espeech-rtp", + 8442: "cybro-a-bus", + 8443: "pcsync-https", + 8444: "pcsync-http", + 8445: "copy", + 8450: "npmp", + 8457: "nexentamv", + 8470: "cisco-avp", + 8471: "pim-port", + 8472: "otv", + 8473: "vp2p", + 8474: "noteshare", + 8500: "fmtp", + 8501: "cmtp-mgt", + 8502: "ftnmtp", + 8554: "rtsp-alt", + 8555: "d-fence", + 8567: "enc-tunnel", + 8600: "asterix", + 8610: "canon-mfnp", + 8611: "canon-bjnp1", + 8612: "canon-bjnp2", + 8613: "canon-bjnp3", + 8614: "canon-bjnp4", + 8615: "imink", + 8665: "monetra", + 8666: "monetra-admin", + 8675: "msi-cps-rm", + 8686: "sun-as-jmxrmi", + 8688: "openremote-ctrl", + 8699: "vnyx", + 8711: "nvc", + 8733: "ibus", + 8750: "dey-keyneg", + 8763: "mc-appserver", + 8764: "openqueue", + 8765: "ultraseek-http", + 8766: "amcs", + 8770: "dpap", + 8778: "uec", + 8786: "msgclnt", + 8787: "msgsrvr", + 8793: "acd-pm", + 8800: "sunwebadmin", + 8804: "truecm", + 8873: "dxspider", + 8880: "cddbp-alt", + 8881: "galaxy4d", + 8883: "secure-mqtt", + 8888: "ddi-tcp-1", + 8889: "ddi-tcp-2", + 8890: "ddi-tcp-3", + 8891: "ddi-tcp-4", + 8892: "ddi-tcp-5", + 8893: "ddi-tcp-6", + 8894: "ddi-tcp-7", + 8899: "ospf-lite", + 8900: "jmb-cds1", + 8901: "jmb-cds2", + 8910: "manyone-http", + 8911: "manyone-xml", + 8912: "wcbackup", + 8913: "dragonfly", + 8937: "twds", + 8953: "ub-dns-control", + 8954: "cumulus-admin", + 8989: "sunwebadmins", + 8990: "http-wmap", + 8991: "https-wmap", + 8998: "canto-roboflow", + 8999: "bctp", + 9000: "cslistener", + 9001: "etlservicemgr", + 9002: "dynamid", + 9008: "ogs-server", + 9009: "pichat", + 9010: "sdr", + 9020: "tambora", + 9021: "panagolin-ident", + 9022: "paragent", + 9023: "swa-1", + 9024: "swa-2", + 9025: "swa-3", + 9026: "swa-4", + 9050: "versiera", + 9051: "fio-cmgmt", + 9080: "glrpc", + 9083: "emc-pp-mgmtsvc", + 9084: "aurora", + 9085: "ibm-rsyscon", + 9086: "net2display", + 9087: "classic", + 9088: "sqlexec", + 9089: "sqlexec-ssl", + 9090: "websm", + 9091: "xmltec-xmlmail", + 9092: "XmlIpcRegSvc", + 9093: "copycat", + 9100: "hp-pdl-datastr", + 9101: "bacula-dir", + 9102: "bacula-fd", + 9103: "bacula-sd", + 9104: "peerwire", + 9105: "xadmin", + 9106: "astergate", + 9107: "astergatefax", + 9119: "mxit", + 9122: "grcmp", + 9123: "grcp", + 9131: "dddp", + 9160: "apani1", + 9161: "apani2", + 9162: "apani3", + 9163: "apani4", + 9164: "apani5", + 9191: "sun-as-jpda", + 9200: "wap-wsp", + 9201: "wap-wsp-wtp", + 9202: "wap-wsp-s", + 9203: "wap-wsp-wtp-s", + 9204: "wap-vcard", + 9205: "wap-vcal", + 9206: "wap-vcard-s", + 9207: "wap-vcal-s", + 9208: "rjcdb-vcards", + 9209: "almobile-system", + 9210: "oma-mlp", + 9211: "oma-mlp-s", + 9212: "serverviewdbms", + 9213: "serverstart", + 9214: "ipdcesgbs", + 9215: "insis", + 9216: "acme", + 9217: "fsc-port", + 9222: "teamcoherence", + 9255: "mon", + 9278: "pegasus", + 9279: "pegasus-ctl", + 9280: "pgps", + 9281: "swtp-port1", + 9282: "swtp-port2", + 9283: "callwaveiam", + 9284: "visd", + 9285: "n2h2server", + 9287: "cumulus", + 9292: "armtechdaemon", + 9293: "storview", + 9294: "armcenterhttp", + 9295: "armcenterhttps", + 9300: "vrace", + 9306: "sphinxql", + 9312: "sphinxapi", + 9318: "secure-ts", + 9321: "guibase", + 9343: "mpidcmgr", + 9344: "mphlpdmc", + 9346: "ctechlicensing", + 9374: "fjdmimgr", + 9380: "boxp", + 9387: "d2dconfig", + 9388: "d2ddatatrans", + 9389: "adws", + 9390: "otp", + 9396: "fjinvmgr", + 9397: "mpidcagt", + 9400: "sec-t4net-srv", + 9401: "sec-t4net-clt", + 9402: "sec-pc2fax-srv", + 9418: "git", + 9443: "tungsten-https", + 9444: "wso2esb-console", + 9445: "mindarray-ca", + 9450: "sntlkeyssrvr", + 9500: "ismserver", + 9535: "mngsuite", + 9536: "laes-bf", + 9555: "trispen-sra", + 9592: "ldgateway", + 9593: "cba8", + 9594: "msgsys", + 9595: "pds", + 9596: "mercury-disc", + 9597: "pd-admin", + 9598: "vscp", + 9599: "robix", + 9600: "micromuse-ncpw", + 9612: "streamcomm-ds", + 9614: "iadt-tls", + 9616: "erunbook-agent", + 9617: "erunbook-server", + 9618: "condor", + 9628: "odbcpathway", + 9629: "uniport", + 9630: "peoctlr", + 9631: "peocoll", + 9640: "pqsflows", + 9666: "zoomcp", + 9667: "xmms2", + 9668: "tec5-sdctp", + 9694: "client-wakeup", + 9695: "ccnx", + 9700: "board-roar", + 9747: "l5nas-parchan", + 9750: "board-voip", + 9753: "rasadv", + 9762: "tungsten-http", + 9800: "davsrc", + 9801: "sstp-2", + 9802: "davsrcs", + 9875: "sapv1", + 9876: "sd", + 9888: "cyborg-systems", + 9889: "gt-proxy", + 9898: "monkeycom", + 9900: "iua", + 9909: "domaintime", + 9911: "sype-transport", + 9925: "xybrid-cloud", + 9950: "apc-9950", + 9951: "apc-9951", + 9952: "apc-9952", + 9953: "acis", + 9954: "hinp", + 9955: "alljoyn-stm", + 9966: "odnsp", + 9978: "xybrid-rt", + 9987: "dsm-scm-target", + 9988: "nsesrvr", + 9990: "osm-appsrvr", + 9991: "osm-oev", + 9992: "palace-1", + 9993: "palace-2", + 9994: "palace-3", + 9995: "palace-4", + 9996: "palace-5", + 9997: "palace-6", + 9998: "distinct32", + 9999: "distinct", + 10000: "ndmp", + 10001: "scp-config", + 10002: "documentum", + 10003: "documentum-s", + 10004: "emcrmirccd", + 10005: "emcrmird", + 10006: "netapp-sync", + 10007: "mvs-capacity", + 10008: "octopus", + 10009: "swdtp-sv", + 10010: "rxapi", + 10050: "zabbix-agent", + 10051: "zabbix-trapper", + 10055: "qptlmd", + 10080: "amanda", + 10081: "famdc", + 10100: "itap-ddtp", + 10101: "ezmeeting-2", + 10102: "ezproxy-2", + 10103: "ezrelay", + 10104: "swdtp", + 10107: "bctp-server", + 10110: "nmea-0183", + 10113: "netiq-endpoint", + 10114: "netiq-qcheck", + 10115: "netiq-endpt", + 10116: "netiq-voipa", + 10117: "iqrm", + 10128: "bmc-perf-sd", + 10129: "bmc-gms", + 10160: "qb-db-server", + 10161: "snmptls", + 10162: "snmptls-trap", + 10200: "trisoap", + 10201: "rsms", + 10252: "apollo-relay", + 10260: "axis-wimp-port", + 10288: "blocks", + 10321: "cosir", + 10540: "MOS-lower", + 10541: "MOS-upper", + 10542: "MOS-aux", + 10543: "MOS-soap", + 10544: "MOS-soap-opt", + 10631: "printopia", + 10800: "gap", + 10805: "lpdg", + 10809: "nbd", + 10860: "helix", + 10880: "bveapi", + 10990: "rmiaux", + 11000: "irisa", + 11001: "metasys", + 11095: "weave", + 11103: "origo-sync", + 11104: "netapp-icmgmt", + 11105: "netapp-icdata", + 11106: "sgi-lk", + 11109: "sgi-dmfmgr", + 11110: "sgi-soap", + 11111: "vce", + 11112: "dicom", + 11161: "suncacao-snmp", + 11162: "suncacao-jmxmp", + 11163: "suncacao-rmi", + 11164: "suncacao-csa", + 11165: "suncacao-websvc", + 11172: "oemcacao-jmxmp", + 11173: "t5-straton", + 11174: "oemcacao-rmi", + 11175: "oemcacao-websvc", + 11201: "smsqp", + 11202: "dcsl-backup", + 11208: "wifree", + 11211: "memcache", + 11319: "imip", + 11320: "imip-channels", + 11321: "arena-server", + 11367: "atm-uhas", + 11371: "hkp", + 11489: "asgcypresstcps", + 11600: "tempest-port", + 11623: "emc-xsw-dconfig", + 11720: "h323callsigalt", + 11723: "emc-xsw-dcache", + 11751: "intrepid-ssl", + 11796: "lanschool", + 11876: "xoraya", + 11967: "sysinfo-sp", + 12000: "entextxid", + 12001: "entextnetwk", + 12002: "entexthigh", + 12003: "entextmed", + 12004: "entextlow", + 12005: "dbisamserver1", + 12006: "dbisamserver2", + 12007: "accuracer", + 12008: "accuracer-dbms", + 12010: "edbsrvr", + 12012: "vipera", + 12013: "vipera-ssl", + 12109: "rets-ssl", + 12121: "nupaper-ss", + 12168: "cawas", + 12172: "hivep", + 12300: "linogridengine", + 12302: "rads", + 12321: "warehouse-sss", + 12322: "warehouse", + 12345: "italk", + 12753: "tsaf", + 12865: "netperf", + 13160: "i-zipqd", + 13216: "bcslogc", + 13217: "rs-pias", + 13218: "emc-vcas-tcp", + 13223: "powwow-client", + 13224: "powwow-server", + 13400: "doip-data", + 13720: "bprd", + 13721: "bpdbm", + 13722: "bpjava-msvc", + 13724: "vnetd", + 13782: "bpcd", + 13783: "vopied", + 13785: "nbdb", + 13786: "nomdb", + 13818: "dsmcc-config", + 13819: "dsmcc-session", + 13820: "dsmcc-passthru", + 13821: "dsmcc-download", + 13822: "dsmcc-ccp", + 13823: "bmdss", + 13894: "ucontrol", + 13929: "dta-systems", + 13930: "medevolve", + 14000: "scotty-ft", + 14001: "sua", + 14033: "sage-best-com1", + 14034: "sage-best-com2", + 14141: "vcs-app", + 14142: "icpp", + 14145: "gcm-app", + 14149: "vrts-tdd", + 14150: "vcscmd", + 14154: "vad", + 14250: "cps", + 14414: "ca-web-update", + 14936: "hde-lcesrvr-1", + 14937: "hde-lcesrvr-2", + 15000: "hydap", + 15002: "onep-tls", + 15345: "xpilot", + 15363: "3link", + 15555: "cisco-snat", + 15660: "bex-xr", + 15740: "ptp", + 15999: "programmar", + 16000: "fmsas", + 16001: "fmsascon", + 16002: "gsms", + 16020: "jwpc", + 16021: "jwpc-bin", + 16161: "sun-sea-port", + 16162: "solaris-audit", + 16309: "etb4j", + 16310: "pduncs", + 16311: "pdefmns", + 16360: "netserialext1", + 16361: "netserialext2", + 16367: "netserialext3", + 16368: "netserialext4", + 16384: "connected", + 16619: "xoms", + 16900: "newbay-snc-mc", + 16950: "sgcip", + 16991: "intel-rci-mp", + 16992: "amt-soap-http", + 16993: "amt-soap-https", + 16994: "amt-redir-tcp", + 16995: "amt-redir-tls", + 17007: "isode-dua", + 17184: "vestasdlp", + 17185: "soundsvirtual", + 17219: "chipper", + 17220: "avtp", + 17221: "avdecc", + 17234: "integrius-stp", + 17235: "ssh-mgmt", + 17500: "db-lsp", + 17555: "ailith", + 17729: "ea", + 17754: "zep", + 17755: "zigbee-ip", + 17756: "zigbee-ips", + 17777: "sw-orion", + 18000: "biimenu", + 18104: "radpdf", + 18136: "racf", + 18181: "opsec-cvp", + 18182: "opsec-ufp", + 18183: "opsec-sam", + 18184: "opsec-lea", + 18185: "opsec-omi", + 18186: "ohsc", + 18187: "opsec-ela", + 18241: "checkpoint-rtm", + 18242: "iclid", + 18243: "clusterxl", + 18262: "gv-pf", + 18463: "ac-cluster", + 18634: "rds-ib", + 18635: "rds-ip", + 18769: "ique", + 18881: "infotos", + 18888: "apc-necmp", + 19000: "igrid", + 19007: "scintilla", + 19020: "j-link", + 19191: "opsec-uaa", + 19194: "ua-secureagent", + 19283: "keysrvr", + 19315: "keyshadow", + 19398: "mtrgtrans", + 19410: "hp-sco", + 19411: "hp-sca", + 19412: "hp-sessmon", + 19539: "fxuptp", + 19540: "sxuptp", + 19541: "jcp", + 19998: "iec-104-sec", + 19999: "dnp-sec", + 20000: "dnp", + 20001: "microsan", + 20002: "commtact-http", + 20003: "commtact-https", + 20005: "openwebnet", + 20013: "ss-idi", + 20014: "opendeploy", + 20034: "nburn-id", + 20046: "tmophl7mts", + 20048: "mountd", + 20049: "nfsrdma", + 20167: "tolfab", + 20202: "ipdtp-port", + 20222: "ipulse-ics", + 20480: "emwavemsg", + 20670: "track", + 20999: "athand-mmp", + 21000: "irtrans", + 21010: "notezilla-lan", + 21553: "rdm-tfs", + 21554: "dfserver", + 21590: "vofr-gateway", + 21800: "tvpm", + 21845: "webphone", + 21846: "netspeak-is", + 21847: "netspeak-cs", + 21848: "netspeak-acd", + 21849: "netspeak-cps", + 22000: "snapenetio", + 22001: "optocontrol", + 22002: "optohost002", + 22003: "optohost003", + 22004: "optohost004", + 22005: "optohost004", + 22125: "dcap", + 22128: "gsidcap", + 22222: "easyengine", + 22273: "wnn6", + 22305: "cis", + 22343: "cis-secure", + 22347: "wibukey", + 22350: "codemeter", + 22351: "codemeter-cmwan", + 22537: "caldsoft-backup", + 22555: "vocaltec-wconf", + 22763: "talikaserver", + 22800: "aws-brf", + 22951: "brf-gw", + 23000: "inovaport1", + 23001: "inovaport2", + 23002: "inovaport3", + 23003: "inovaport4", + 23004: "inovaport5", + 23005: "inovaport6", + 23053: "gntp", + 23333: "elxmgmt", + 23400: "novar-dbase", + 23401: "novar-alarm", + 23402: "novar-global", + 23456: "aequus", + 23457: "aequus-alt", + 23546: "areaguard-neo", + 24000: "med-ltp", + 24001: "med-fsp-rx", + 24002: "med-fsp-tx", + 24003: "med-supp", + 24004: "med-ovw", + 24005: "med-ci", + 24006: "med-net-svc", + 24242: "filesphere", + 24249: "vista-4gl", + 24321: "ild", + 24386: "intel-rci", + 24465: "tonidods", + 24554: "binkp", + 24577: "bilobit", + 24676: "canditv", + 24677: "flashfiler", + 24678: "proactivate", + 24680: "tcc-http", + 24754: "cslg", + 24922: "find", + 25000: "icl-twobase1", + 25001: "icl-twobase2", + 25002: "icl-twobase3", + 25003: "icl-twobase4", + 25004: "icl-twobase5", + 25005: "icl-twobase6", + 25006: "icl-twobase7", + 25007: "icl-twobase8", + 25008: "icl-twobase9", + 25009: "icl-twobase10", + 25576: "sauterdongle", + 25604: "idtp", + 25793: "vocaltec-hos", + 25900: "tasp-net", + 25901: "niobserver", + 25902: "nilinkanalyst", + 25903: "niprobe", + 26000: "quake", + 26133: "scscp", + 26208: "wnn6-ds", + 26260: "ezproxy", + 26261: "ezmeeting", + 26262: "k3software-svr", + 26263: "k3software-cli", + 26486: "exoline-tcp", + 26487: "exoconfig", + 26489: "exonet", + 27345: "imagepump", + 27442: "jesmsjc", + 27504: "kopek-httphead", + 27782: "ars-vista", + 27876: "astrolink", + 27999: "tw-auth-key", + 28000: "nxlmd", + 28001: "pqsp", + 28200: "voxelstorm", + 28240: "siemensgsm", + 29167: "otmp", + 29999: "bingbang", + 30000: "ndmps", + 30001: "pago-services1", + 30002: "pago-services2", + 30003: "amicon-fpsu-ra", + 30260: "kingdomsonline", + 30999: "ovobs", + 31020: "autotrac-acp", + 31400: "pace-licensed", + 31416: "xqosd", + 31457: "tetrinet", + 31620: "lm-mon", + 31685: "dsx-monitor", + 31765: "gamesmith-port", + 31948: "iceedcp-tx", + 31949: "iceedcp-rx", + 32034: "iracinghelper", + 32249: "t1distproc60", + 32483: "apm-link", + 32635: "sec-ntb-clnt", + 32636: "DMExpress", + 32767: "filenet-powsrm", + 32768: "filenet-tms", + 32769: "filenet-rpc", + 32770: "filenet-nch", + 32771: "filenet-rmi", + 32772: "filenet-pa", + 32773: "filenet-cm", + 32774: "filenet-re", + 32775: "filenet-pch", + 32776: "filenet-peior", + 32777: "filenet-obrok", + 32801: "mlsn", + 32811: "retp", + 32896: "idmgratm", + 33123: "aurora-balaena", + 33331: "diamondport", + 33333: "dgi-serv", + 33334: "speedtrace", + 33434: "traceroute", + 33656: "snip-slave", + 34249: "turbonote-2", + 34378: "p-net-local", + 34379: "p-net-remote", + 34567: "dhanalakshmi", + 34962: "profinet-rt", + 34963: "profinet-rtm", + 34964: "profinet-cm", + 34980: "ethercat", + 35000: "heathview", + 35001: "rt-viewer", + 35002: "rt-sound", + 35003: "rt-devicemapper", + 35004: "rt-classmanager", + 35005: "rt-labtracker", + 35006: "rt-helper", + 35354: "kitim", + 35355: "altova-lm", + 35356: "guttersnex", + 35357: "openstack-id", + 36001: "allpeers", + 36524: "febooti-aw", + 36602: "observium-agent", + 36865: "kastenxpipe", + 37475: "neckar", + 37483: "gdrive-sync", + 37654: "unisys-eportal", + 38000: "ivs-database", + 38001: "ivs-insertion", + 38201: "galaxy7-data", + 38202: "fairview", + 38203: "agpolicy", + 38800: "sruth", + 38865: "secrmmsafecopya", + 39681: "turbonote-1", + 40000: "safetynetp", + 40404: "sptx", + 40841: "cscp", + 40842: "csccredir", + 40843: "csccfirewall", + 41111: "fs-qos", + 41121: "tentacle", + 41794: "crestron-cip", + 41795: "crestron-ctp", + 41796: "crestron-cips", + 41797: "crestron-ctps", + 42508: "candp", + 42509: "candrp", + 42510: "caerpc", + 43000: "recvr-rc", + 43188: "reachout", + 43189: "ndm-agent-port", + 43190: "ip-provision", + 43191: "noit-transport", + 43210: "shaperai", + 43439: "eq3-update", + 43440: "ew-mgmt", + 43441: "ciscocsdb", + 44123: "z-wave-s", + 44321: "pmcd", + 44322: "pmcdproxy", + 44323: "pmwebapi", + 44444: "cognex-dataman", + 44553: "rbr-debug", + 44818: "EtherNet-IP-2", + 44900: "m3da", + 45000: "asmp", + 45001: "asmps", + 45045: "synctest", + 45054: "invision-ag", + 45678: "eba", + 45824: "dai-shell", + 45825: "qdb2service", + 45966: "ssr-servermgr", + 46998: "spremotetablet", + 46999: "mediabox", + 47000: "mbus", + 47001: "winrm", + 47557: "dbbrowse", + 47624: "directplaysrvr", + 47806: "ap", + 47808: "bacnet", + 48000: "nimcontroller", + 48001: "nimspooler", + 48002: "nimhub", + 48003: "nimgtw", + 48004: "nimbusdb", + 48005: "nimbusdbctrl", + 48049: "3gpp-cbsp", + 48050: "weandsf", + 48128: "isnetserv", + 48129: "blp5", + 48556: "com-bardac-dw", + 48619: "iqobject", + 48653: "robotraconteur", + 49000: "matahari", +} +var udpPortNames = map[UDPPort]string{ + 1: "tcpmux", + 2: "compressnet", + 3: "compressnet", + 5: "rje", + 7: "echo", + 9: "discard", + 11: "systat", + 13: "daytime", + 17: "qotd", + 18: "msp", + 19: "chargen", + 20: "ftp-data", + 21: "ftp", + 22: "ssh", + 23: "telnet", + 25: "smtp", + 27: "nsw-fe", + 29: "msg-icp", + 31: "msg-auth", + 33: "dsp", + 37: "time", + 38: "rap", + 39: "rlp", + 41: "graphics", + 42: "name", + 43: "nicname", + 44: "mpm-flags", + 45: "mpm", + 46: "mpm-snd", + 47: "ni-ftp", + 48: "auditd", + 49: "tacacs", + 50: "re-mail-ck", + 52: "xns-time", + 53: "domain", + 54: "xns-ch", + 55: "isi-gl", + 56: "xns-auth", + 58: "xns-mail", + 61: "ni-mail", + 62: "acas", + 63: "whoispp", + 64: "covia", + 65: "tacacs-ds", + 66: "sql-net", + 67: "bootps", + 68: "bootpc", + 69: "tftp", + 70: "gopher", + 71: "netrjs-1", + 72: "netrjs-2", + 73: "netrjs-3", + 74: "netrjs-4", + 76: "deos", + 78: "vettcp", + 79: "finger", + 80: "http", + 82: "xfer", + 83: "mit-ml-dev", + 84: "ctf", + 85: "mit-ml-dev", + 86: "mfcobol", + 88: "kerberos", + 89: "su-mit-tg", + 90: "dnsix", + 91: "mit-dov", + 92: "npp", + 93: "dcp", + 94: "objcall", + 95: "supdup", + 96: "dixie", + 97: "swift-rvf", + 98: "tacnews", + 99: "metagram", + 101: "hostname", + 102: "iso-tsap", + 103: "gppitnp", + 104: "acr-nema", + 105: "cso", + 106: "3com-tsmux", + 107: "rtelnet", + 108: "snagas", + 109: "pop2", + 110: "pop3", + 111: "sunrpc", + 112: "mcidas", + 113: "auth", + 115: "sftp", + 116: "ansanotify", + 117: "uucp-path", + 118: "sqlserv", + 119: "nntp", + 120: "cfdptkt", + 121: "erpc", + 122: "smakynet", + 123: "ntp", + 124: "ansatrader", + 125: "locus-map", + 126: "nxedit", + 127: "locus-con", + 128: "gss-xlicen", + 129: "pwdgen", + 130: "cisco-fna", + 131: "cisco-tna", + 132: "cisco-sys", + 133: "statsrv", + 134: "ingres-net", + 135: "epmap", + 136: "profile", + 137: "netbios-ns", + 138: "netbios-dgm", + 139: "netbios-ssn", + 140: "emfis-data", + 141: "emfis-cntl", + 142: "bl-idm", + 143: "imap", + 144: "uma", + 145: "uaac", + 146: "iso-tp0", + 147: "iso-ip", + 148: "jargon", + 149: "aed-512", + 150: "sql-net", + 151: "hems", + 152: "bftp", + 153: "sgmp", + 154: "netsc-prod", + 155: "netsc-dev", + 156: "sqlsrv", + 157: "knet-cmp", + 158: "pcmail-srv", + 159: "nss-routing", + 160: "sgmp-traps", + 161: "snmp", + 162: "snmptrap", + 163: "cmip-man", + 164: "cmip-agent", + 165: "xns-courier", + 166: "s-net", + 167: "namp", + 168: "rsvd", + 169: "send", + 170: "print-srv", + 171: "multiplex", + 172: "cl-1", + 173: "xyplex-mux", + 174: "mailq", + 175: "vmnet", + 176: "genrad-mux", + 177: "xdmcp", + 178: "nextstep", + 179: "bgp", + 180: "ris", + 181: "unify", + 182: "audit", + 183: "ocbinder", + 184: "ocserver", + 185: "remote-kis", + 186: "kis", + 187: "aci", + 188: "mumps", + 189: "qft", + 190: "gacp", + 191: "prospero", + 192: "osu-nms", + 193: "srmp", + 194: "irc", + 195: "dn6-nlm-aud", + 196: "dn6-smm-red", + 197: "dls", + 198: "dls-mon", + 199: "smux", + 200: "src", + 201: "at-rtmp", + 202: "at-nbp", + 203: "at-3", + 204: "at-echo", + 205: "at-5", + 206: "at-zis", + 207: "at-7", + 208: "at-8", + 209: "qmtp", + 210: "z39-50", + 211: "914c-g", + 212: "anet", + 213: "ipx", + 214: "vmpwscs", + 215: "softpc", + 216: "CAIlic", + 217: "dbase", + 218: "mpp", + 219: "uarps", + 220: "imap3", + 221: "fln-spx", + 222: "rsh-spx", + 223: "cdc", + 224: "masqdialer", + 242: "direct", + 243: "sur-meas", + 244: "inbusiness", + 245: "link", + 246: "dsp3270", + 247: "subntbcst-tftp", + 248: "bhfhs", + 256: "rap", + 257: "set", + 259: "esro-gen", + 260: "openport", + 261: "nsiiops", + 262: "arcisdms", + 263: "hdap", + 264: "bgmp", + 265: "x-bone-ctl", + 266: "sst", + 267: "td-service", + 268: "td-replica", + 269: "manet", + 270: "gist", + 280: "http-mgmt", + 281: "personal-link", + 282: "cableport-ax", + 283: "rescap", + 284: "corerjd", + 286: "fxp", + 287: "k-block", + 308: "novastorbakcup", + 309: "entrusttime", + 310: "bhmds", + 311: "asip-webadmin", + 312: "vslmp", + 313: "magenta-logic", + 314: "opalis-robot", + 315: "dpsi", + 316: "decauth", + 317: "zannet", + 318: "pkix-timestamp", + 319: "ptp-event", + 320: "ptp-general", + 321: "pip", + 322: "rtsps", + 333: "texar", + 344: "pdap", + 345: "pawserv", + 346: "zserv", + 347: "fatserv", + 348: "csi-sgwp", + 349: "mftp", + 350: "matip-type-a", + 351: "matip-type-b", + 352: "dtag-ste-sb", + 353: "ndsauth", + 354: "bh611", + 355: "datex-asn", + 356: "cloanto-net-1", + 357: "bhevent", + 358: "shrinkwrap", + 359: "nsrmp", + 360: "scoi2odialog", + 361: "semantix", + 362: "srssend", + 363: "rsvp-tunnel", + 364: "aurora-cmgr", + 365: "dtk", + 366: "odmr", + 367: "mortgageware", + 368: "qbikgdp", + 369: "rpc2portmap", + 370: "codaauth2", + 371: "clearcase", + 372: "ulistproc", + 373: "legent-1", + 374: "legent-2", + 375: "hassle", + 376: "nip", + 377: "tnETOS", + 378: "dsETOS", + 379: "is99c", + 380: "is99s", + 381: "hp-collector", + 382: "hp-managed-node", + 383: "hp-alarm-mgr", + 384: "arns", + 385: "ibm-app", + 386: "asa", + 387: "aurp", + 388: "unidata-ldm", + 389: "ldap", + 390: "uis", + 391: "synotics-relay", + 392: "synotics-broker", + 393: "meta5", + 394: "embl-ndt", + 395: "netcp", + 396: "netware-ip", + 397: "mptn", + 398: "kryptolan", + 399: "iso-tsap-c2", + 400: "osb-sd", + 401: "ups", + 402: "genie", + 403: "decap", + 404: "nced", + 405: "ncld", + 406: "imsp", + 407: "timbuktu", + 408: "prm-sm", + 409: "prm-nm", + 410: "decladebug", + 411: "rmt", + 412: "synoptics-trap", + 413: "smsp", + 414: "infoseek", + 415: "bnet", + 416: "silverplatter", + 417: "onmux", + 418: "hyper-g", + 419: "ariel1", + 420: "smpte", + 421: "ariel2", + 422: "ariel3", + 423: "opc-job-start", + 424: "opc-job-track", + 425: "icad-el", + 426: "smartsdp", + 427: "svrloc", + 428: "ocs-cmu", + 429: "ocs-amu", + 430: "utmpsd", + 431: "utmpcd", + 432: "iasd", + 433: "nnsp", + 434: "mobileip-agent", + 435: "mobilip-mn", + 436: "dna-cml", + 437: "comscm", + 438: "dsfgw", + 439: "dasp", + 440: "sgcp", + 441: "decvms-sysmgt", + 442: "cvc-hostd", + 443: "https", + 444: "snpp", + 445: "microsoft-ds", + 446: "ddm-rdb", + 447: "ddm-dfm", + 448: "ddm-ssl", + 449: "as-servermap", + 450: "tserver", + 451: "sfs-smp-net", + 452: "sfs-config", + 453: "creativeserver", + 454: "contentserver", + 455: "creativepartnr", + 456: "macon-udp", + 457: "scohelp", + 458: "appleqtc", + 459: "ampr-rcmd", + 460: "skronk", + 461: "datasurfsrv", + 462: "datasurfsrvsec", + 463: "alpes", + 464: "kpasswd", + 465: "igmpv3lite", + 466: "digital-vrc", + 467: "mylex-mapd", + 468: "photuris", + 469: "rcp", + 470: "scx-proxy", + 471: "mondex", + 472: "ljk-login", + 473: "hybrid-pop", + 474: "tn-tl-w2", + 475: "tcpnethaspsrv", + 476: "tn-tl-fd1", + 477: "ss7ns", + 478: "spsc", + 479: "iafserver", + 480: "iafdbase", + 481: "ph", + 482: "bgs-nsi", + 483: "ulpnet", + 484: "integra-sme", + 485: "powerburst", + 486: "avian", + 487: "saft", + 488: "gss-http", + 489: "nest-protocol", + 490: "micom-pfs", + 491: "go-login", + 492: "ticf-1", + 493: "ticf-2", + 494: "pov-ray", + 495: "intecourier", + 496: "pim-rp-disc", + 497: "retrospect", + 498: "siam", + 499: "iso-ill", + 500: "isakmp", + 501: "stmf", + 502: "mbap", + 503: "intrinsa", + 504: "citadel", + 505: "mailbox-lm", + 506: "ohimsrv", + 507: "crs", + 508: "xvttp", + 509: "snare", + 510: "fcp", + 511: "passgo", + 512: "comsat", + 513: "who", + 514: "syslog", + 515: "printer", + 516: "videotex", + 517: "talk", + 518: "ntalk", + 519: "utime", + 520: "router", + 521: "ripng", + 522: "ulp", + 523: "ibm-db2", + 524: "ncp", + 525: "timed", + 526: "tempo", + 527: "stx", + 528: "custix", + 529: "irc-serv", + 530: "courier", + 531: "conference", + 532: "netnews", + 533: "netwall", + 534: "windream", + 535: "iiop", + 536: "opalis-rdv", + 537: "nmsp", + 538: "gdomap", + 539: "apertus-ldp", + 540: "uucp", + 541: "uucp-rlogin", + 542: "commerce", + 543: "klogin", + 544: "kshell", + 545: "appleqtcsrvr", + 546: "dhcpv6-client", + 547: "dhcpv6-server", + 548: "afpovertcp", + 549: "idfp", + 550: "new-rwho", + 551: "cybercash", + 552: "devshr-nts", + 553: "pirp", + 554: "rtsp", + 555: "dsf", + 556: "remotefs", + 557: "openvms-sysipc", + 558: "sdnskmp", + 559: "teedtap", + 560: "rmonitor", + 561: "monitor", + 562: "chshell", + 563: "nntps", + 564: "9pfs", + 565: "whoami", + 566: "streettalk", + 567: "banyan-rpc", + 568: "ms-shuttle", + 569: "ms-rome", + 570: "meter", + 571: "meter", + 572: "sonar", + 573: "banyan-vip", + 574: "ftp-agent", + 575: "vemmi", + 576: "ipcd", + 577: "vnas", + 578: "ipdd", + 579: "decbsrv", + 580: "sntp-heartbeat", + 581: "bdp", + 582: "scc-security", + 583: "philips-vc", + 584: "keyserver", + 586: "password-chg", + 587: "submission", + 588: "cal", + 589: "eyelink", + 590: "tns-cml", + 591: "http-alt", + 592: "eudora-set", + 593: "http-rpc-epmap", + 594: "tpip", + 595: "cab-protocol", + 596: "smsd", + 597: "ptcnameservice", + 598: "sco-websrvrmg3", + 599: "acp", + 600: "ipcserver", + 601: "syslog-conn", + 602: "xmlrpc-beep", + 603: "idxp", + 604: "tunnel", + 605: "soap-beep", + 606: "urm", + 607: "nqs", + 608: "sift-uft", + 609: "npmp-trap", + 610: "npmp-local", + 611: "npmp-gui", + 612: "hmmp-ind", + 613: "hmmp-op", + 614: "sshell", + 615: "sco-inetmgr", + 616: "sco-sysmgr", + 617: "sco-dtmgr", + 618: "dei-icda", + 619: "compaq-evm", + 620: "sco-websrvrmgr", + 621: "escp-ip", + 622: "collaborator", + 623: "asf-rmcp", + 624: "cryptoadmin", + 625: "dec-dlm", + 626: "asia", + 627: "passgo-tivoli", + 628: "qmqp", + 629: "3com-amp3", + 630: "rda", + 631: "ipp", + 632: "bmpp", + 633: "servstat", + 634: "ginad", + 635: "rlzdbase", + 636: "ldaps", + 637: "lanserver", + 638: "mcns-sec", + 639: "msdp", + 640: "entrust-sps", + 641: "repcmd", + 642: "esro-emsdp", + 643: "sanity", + 644: "dwr", + 645: "pssc", + 646: "ldp", + 647: "dhcp-failover", + 648: "rrp", + 649: "cadview-3d", + 650: "obex", + 651: "ieee-mms", + 652: "hello-port", + 653: "repscmd", + 654: "aodv", + 655: "tinc", + 656: "spmp", + 657: "rmc", + 658: "tenfold", + 660: "mac-srvr-admin", + 661: "hap", + 662: "pftp", + 663: "purenoise", + 664: "asf-secure-rmcp", + 665: "sun-dr", + 666: "mdqs", + 667: "disclose", + 668: "mecomm", + 669: "meregister", + 670: "vacdsm-sws", + 671: "vacdsm-app", + 672: "vpps-qua", + 673: "cimplex", + 674: "acap", + 675: "dctp", + 676: "vpps-via", + 677: "vpp", + 678: "ggf-ncp", + 679: "mrm", + 680: "entrust-aaas", + 681: "entrust-aams", + 682: "xfr", + 683: "corba-iiop", + 684: "corba-iiop-ssl", + 685: "mdc-portmapper", + 686: "hcp-wismar", + 687: "asipregistry", + 688: "realm-rusd", + 689: "nmap", + 690: "vatp", + 691: "msexch-routing", + 692: "hyperwave-isp", + 693: "connendp", + 694: "ha-cluster", + 695: "ieee-mms-ssl", + 696: "rushd", + 697: "uuidgen", + 698: "olsr", + 699: "accessnetwork", + 700: "epp", + 701: "lmp", + 702: "iris-beep", + 704: "elcsd", + 705: "agentx", + 706: "silc", + 707: "borland-dsj", + 709: "entrust-kmsh", + 710: "entrust-ash", + 711: "cisco-tdp", + 712: "tbrpf", + 713: "iris-xpc", + 714: "iris-xpcs", + 715: "iris-lwz", + 716: "pana", + 729: "netviewdm1", + 730: "netviewdm2", + 731: "netviewdm3", + 741: "netgw", + 742: "netrcs", + 744: "flexlm", + 747: "fujitsu-dev", + 748: "ris-cm", + 749: "kerberos-adm", + 750: "loadav", + 751: "pump", + 752: "qrh", + 753: "rrh", + 754: "tell", + 758: "nlogin", + 759: "con", + 760: "ns", + 761: "rxe", + 762: "quotad", + 763: "cycleserv", + 764: "omserv", + 765: "webster", + 767: "phonebook", + 769: "vid", + 770: "cadlock", + 771: "rtip", + 772: "cycleserv2", + 773: "notify", + 774: "acmaint-dbd", + 775: "acmaint-transd", + 776: "wpages", + 777: "multiling-http", + 780: "wpgs", + 800: "mdbs-daemon", + 801: "device", + 802: "mbap-s", + 810: "fcp-udp", + 828: "itm-mcell-s", + 829: "pkix-3-ca-ra", + 830: "netconf-ssh", + 831: "netconf-beep", + 832: "netconfsoaphttp", + 833: "netconfsoapbeep", + 847: "dhcp-failover2", + 848: "gdoi", + 860: "iscsi", + 861: "owamp-control", + 862: "twamp-control", + 873: "rsync", + 886: "iclcnet-locate", + 887: "iclcnet-svinfo", + 888: "accessbuilder", + 900: "omginitialrefs", + 901: "smpnameres", + 902: "ideafarm-door", + 903: "ideafarm-panic", + 910: "kink", + 911: "xact-backup", + 912: "apex-mesh", + 913: "apex-edge", + 989: "ftps-data", + 990: "ftps", + 991: "nas", + 992: "telnets", + 993: "imaps", + 995: "pop3s", + 996: "vsinet", + 997: "maitrd", + 998: "puparp", + 999: "applix", + 1000: "cadlock2", + 1010: "surf", + 1021: "exp1", + 1022: "exp2", + 1025: "blackjack", + 1026: "cap", + 1027: "6a44", + 1029: "solid-mux", + 1033: "netinfo-local", + 1034: "activesync", + 1035: "mxxrlogin", + 1036: "nsstp", + 1037: "ams", + 1038: "mtqp", + 1039: "sbl", + 1040: "netarx", + 1041: "danf-ak2", + 1042: "afrog", + 1043: "boinc-client", + 1044: "dcutility", + 1045: "fpitp", + 1046: "wfremotertm", + 1047: "neod1", + 1048: "neod2", + 1049: "td-postman", + 1050: "cma", + 1051: "optima-vnet", + 1052: "ddt", + 1053: "remote-as", + 1054: "brvread", + 1055: "ansyslmd", + 1056: "vfo", + 1057: "startron", + 1058: "nim", + 1059: "nimreg", + 1060: "polestar", + 1061: "kiosk", + 1062: "veracity", + 1063: "kyoceranetdev", + 1064: "jstel", + 1065: "syscomlan", + 1066: "fpo-fns", + 1067: "instl-boots", + 1068: "instl-bootc", + 1069: "cognex-insight", + 1070: "gmrupdateserv", + 1071: "bsquare-voip", + 1072: "cardax", + 1073: "bridgecontrol", + 1074: "warmspotMgmt", + 1075: "rdrmshc", + 1076: "dab-sti-c", + 1077: "imgames", + 1078: "avocent-proxy", + 1079: "asprovatalk", + 1080: "socks", + 1081: "pvuniwien", + 1082: "amt-esd-prot", + 1083: "ansoft-lm-1", + 1084: "ansoft-lm-2", + 1085: "webobjects", + 1086: "cplscrambler-lg", + 1087: "cplscrambler-in", + 1088: "cplscrambler-al", + 1089: "ff-annunc", + 1090: "ff-fms", + 1091: "ff-sm", + 1092: "obrpd", + 1093: "proofd", + 1094: "rootd", + 1095: "nicelink", + 1096: "cnrprotocol", + 1097: "sunclustermgr", + 1098: "rmiactivation", + 1099: "rmiregistry", + 1100: "mctp", + 1101: "pt2-discover", + 1102: "adobeserver-1", + 1103: "adobeserver-2", + 1104: "xrl", + 1105: "ftranhc", + 1106: "isoipsigport-1", + 1107: "isoipsigport-2", + 1108: "ratio-adp", + 1110: "nfsd-keepalive", + 1111: "lmsocialserver", + 1112: "icp", + 1113: "ltp-deepspace", + 1114: "mini-sql", + 1115: "ardus-trns", + 1116: "ardus-cntl", + 1117: "ardus-mtrns", + 1118: "sacred", + 1119: "bnetgame", + 1120: "bnetfile", + 1121: "rmpp", + 1122: "availant-mgr", + 1123: "murray", + 1124: "hpvmmcontrol", + 1125: "hpvmmagent", + 1126: "hpvmmdata", + 1127: "kwdb-commn", + 1128: "saphostctrl", + 1129: "saphostctrls", + 1130: "casp", + 1131: "caspssl", + 1132: "kvm-via-ip", + 1133: "dfn", + 1134: "aplx", + 1135: "omnivision", + 1136: "hhb-gateway", + 1137: "trim", + 1138: "encrypted-admin", + 1139: "evm", + 1140: "autonoc", + 1141: "mxomss", + 1142: "edtools", + 1143: "imyx", + 1144: "fuscript", + 1145: "x9-icue", + 1146: "audit-transfer", + 1147: "capioverlan", + 1148: "elfiq-repl", + 1149: "bvtsonar", + 1150: "blaze", + 1151: "unizensus", + 1152: "winpoplanmess", + 1153: "c1222-acse", + 1154: "resacommunity", + 1155: "nfa", + 1156: "iascontrol-oms", + 1157: "iascontrol", + 1158: "dbcontrol-oms", + 1159: "oracle-oms", + 1160: "olsv", + 1161: "health-polling", + 1162: "health-trap", + 1163: "sddp", + 1164: "qsm-proxy", + 1165: "qsm-gui", + 1166: "qsm-remote", + 1167: "cisco-ipsla", + 1168: "vchat", + 1169: "tripwire", + 1170: "atc-lm", + 1171: "atc-appserver", + 1172: "dnap", + 1173: "d-cinema-rrp", + 1174: "fnet-remote-ui", + 1175: "dossier", + 1176: "indigo-server", + 1177: "dkmessenger", + 1178: "sgi-storman", + 1179: "b2n", + 1180: "mc-client", + 1181: "3comnetman", + 1182: "accelenet-data", + 1183: "llsurfup-http", + 1184: "llsurfup-https", + 1185: "catchpole", + 1186: "mysql-cluster", + 1187: "alias", + 1188: "hp-webadmin", + 1189: "unet", + 1190: "commlinx-avl", + 1191: "gpfs", + 1192: "caids-sensor", + 1193: "fiveacross", + 1194: "openvpn", + 1195: "rsf-1", + 1196: "netmagic", + 1197: "carrius-rshell", + 1198: "cajo-discovery", + 1199: "dmidi", + 1200: "scol", + 1201: "nucleus-sand", + 1202: "caiccipc", + 1203: "ssslic-mgr", + 1204: "ssslog-mgr", + 1205: "accord-mgc", + 1206: "anthony-data", + 1207: "metasage", + 1208: "seagull-ais", + 1209: "ipcd3", + 1210: "eoss", + 1211: "groove-dpp", + 1212: "lupa", + 1213: "mpc-lifenet", + 1214: "kazaa", + 1215: "scanstat-1", + 1216: "etebac5", + 1217: "hpss-ndapi", + 1218: "aeroflight-ads", + 1219: "aeroflight-ret", + 1220: "qt-serveradmin", + 1221: "sweetware-apps", + 1222: "nerv", + 1223: "tgp", + 1224: "vpnz", + 1225: "slinkysearch", + 1226: "stgxfws", + 1227: "dns2go", + 1228: "florence", + 1229: "zented", + 1230: "periscope", + 1231: "menandmice-lpm", + 1232: "first-defense", + 1233: "univ-appserver", + 1234: "search-agent", + 1235: "mosaicsyssvc1", + 1236: "bvcontrol", + 1237: "tsdos390", + 1238: "hacl-qs", + 1239: "nmsd", + 1240: "instantia", + 1241: "nessus", + 1242: "nmasoverip", + 1243: "serialgateway", + 1244: "isbconference1", + 1245: "isbconference2", + 1246: "payrouter", + 1247: "visionpyramid", + 1248: "hermes", + 1249: "mesavistaco", + 1250: "swldy-sias", + 1251: "servergraph", + 1252: "bspne-pcc", + 1253: "q55-pcc", + 1254: "de-noc", + 1255: "de-cache-query", + 1256: "de-server", + 1257: "shockwave2", + 1258: "opennl", + 1259: "opennl-voice", + 1260: "ibm-ssd", + 1261: "mpshrsv", + 1262: "qnts-orb", + 1263: "dka", + 1264: "prat", + 1265: "dssiapi", + 1266: "dellpwrappks", + 1267: "epc", + 1268: "propel-msgsys", + 1269: "watilapp", + 1270: "opsmgr", + 1271: "excw", + 1272: "cspmlockmgr", + 1273: "emc-gateway", + 1274: "t1distproc", + 1275: "ivcollector", + 1277: "miva-mqs", + 1278: "dellwebadmin-1", + 1279: "dellwebadmin-2", + 1280: "pictrography", + 1281: "healthd", + 1282: "emperion", + 1283: "productinfo", + 1284: "iee-qfx", + 1285: "neoiface", + 1286: "netuitive", + 1287: "routematch", + 1288: "navbuddy", + 1289: "jwalkserver", + 1290: "winjaserver", + 1291: "seagulllms", + 1292: "dsdn", + 1293: "pkt-krb-ipsec", + 1294: "cmmdriver", + 1295: "ehtp", + 1296: "dproxy", + 1297: "sdproxy", + 1298: "lpcp", + 1299: "hp-sci", + 1300: "h323hostcallsc", + 1301: "ci3-software-1", + 1302: "ci3-software-2", + 1303: "sftsrv", + 1304: "boomerang", + 1305: "pe-mike", + 1306: "re-conn-proto", + 1307: "pacmand", + 1308: "odsi", + 1309: "jtag-server", + 1310: "husky", + 1311: "rxmon", + 1312: "sti-envision", + 1313: "bmc-patroldb", + 1314: "pdps", + 1315: "els", + 1316: "exbit-escp", + 1317: "vrts-ipcserver", + 1318: "krb5gatekeeper", + 1319: "amx-icsp", + 1320: "amx-axbnet", + 1321: "pip", + 1322: "novation", + 1323: "brcd", + 1324: "delta-mcp", + 1325: "dx-instrument", + 1326: "wimsic", + 1327: "ultrex", + 1328: "ewall", + 1329: "netdb-export", + 1330: "streetperfect", + 1331: "intersan", + 1332: "pcia-rxp-b", + 1333: "passwrd-policy", + 1334: "writesrv", + 1335: "digital-notary", + 1336: "ischat", + 1337: "menandmice-dns", + 1338: "wmc-log-svc", + 1339: "kjtsiteserver", + 1340: "naap", + 1341: "qubes", + 1342: "esbroker", + 1343: "re101", + 1344: "icap", + 1345: "vpjp", + 1346: "alta-ana-lm", + 1347: "bbn-mmc", + 1348: "bbn-mmx", + 1349: "sbook", + 1350: "editbench", + 1351: "equationbuilder", + 1352: "lotusnote", + 1353: "relief", + 1354: "XSIP-network", + 1355: "intuitive-edge", + 1356: "cuillamartin", + 1357: "pegboard", + 1358: "connlcli", + 1359: "ftsrv", + 1360: "mimer", + 1361: "linx", + 1362: "timeflies", + 1363: "ndm-requester", + 1364: "ndm-server", + 1365: "adapt-sna", + 1366: "netware-csp", + 1367: "dcs", + 1368: "screencast", + 1369: "gv-us", + 1370: "us-gv", + 1371: "fc-cli", + 1372: "fc-ser", + 1373: "chromagrafx", + 1374: "molly", + 1375: "bytex", + 1376: "ibm-pps", + 1377: "cichlid", + 1378: "elan", + 1379: "dbreporter", + 1380: "telesis-licman", + 1381: "apple-licman", + 1382: "udt-os", + 1383: "gwha", + 1384: "os-licman", + 1385: "atex-elmd", + 1386: "checksum", + 1387: "cadsi-lm", + 1388: "objective-dbc", + 1389: "iclpv-dm", + 1390: "iclpv-sc", + 1391: "iclpv-sas", + 1392: "iclpv-pm", + 1393: "iclpv-nls", + 1394: "iclpv-nlc", + 1395: "iclpv-wsm", + 1396: "dvl-activemail", + 1397: "audio-activmail", + 1398: "video-activmail", + 1399: "cadkey-licman", + 1400: "cadkey-tablet", + 1401: "goldleaf-licman", + 1402: "prm-sm-np", + 1403: "prm-nm-np", + 1404: "igi-lm", + 1405: "ibm-res", + 1406: "netlabs-lm", + 1407: "dbsa-lm", + 1408: "sophia-lm", + 1409: "here-lm", + 1410: "hiq", + 1411: "af", + 1412: "innosys", + 1413: "innosys-acl", + 1414: "ibm-mqseries", + 1415: "dbstar", + 1416: "novell-lu6-2", + 1417: "timbuktu-srv1", + 1418: "timbuktu-srv2", + 1419: "timbuktu-srv3", + 1420: "timbuktu-srv4", + 1421: "gandalf-lm", + 1422: "autodesk-lm", + 1423: "essbase", + 1424: "hybrid", + 1425: "zion-lm", + 1426: "sais", + 1427: "mloadd", + 1428: "informatik-lm", + 1429: "nms", + 1430: "tpdu", + 1431: "rgtp", + 1432: "blueberry-lm", + 1433: "ms-sql-s", + 1434: "ms-sql-m", + 1435: "ibm-cics", + 1436: "saism", + 1437: "tabula", + 1438: "eicon-server", + 1439: "eicon-x25", + 1440: "eicon-slp", + 1441: "cadis-1", + 1442: "cadis-2", + 1443: "ies-lm", + 1444: "marcam-lm", + 1445: "proxima-lm", + 1446: "ora-lm", + 1447: "apri-lm", + 1448: "oc-lm", + 1449: "peport", + 1450: "dwf", + 1451: "infoman", + 1452: "gtegsc-lm", + 1453: "genie-lm", + 1454: "interhdl-elmd", + 1455: "esl-lm", + 1456: "dca", + 1457: "valisys-lm", + 1458: "nrcabq-lm", + 1459: "proshare1", + 1460: "proshare2", + 1461: "ibm-wrless-lan", + 1462: "world-lm", + 1463: "nucleus", + 1464: "msl-lmd", + 1465: "pipes", + 1466: "oceansoft-lm", + 1467: "csdmbase", + 1468: "csdm", + 1469: "aal-lm", + 1470: "uaiact", + 1471: "csdmbase", + 1472: "csdm", + 1473: "openmath", + 1474: "telefinder", + 1475: "taligent-lm", + 1476: "clvm-cfg", + 1477: "ms-sna-server", + 1478: "ms-sna-base", + 1479: "dberegister", + 1480: "pacerforum", + 1481: "airs", + 1482: "miteksys-lm", + 1483: "afs", + 1484: "confluent", + 1485: "lansource", + 1486: "nms-topo-serv", + 1487: "localinfosrvr", + 1488: "docstor", + 1489: "dmdocbroker", + 1490: "insitu-conf", + 1492: "stone-design-1", + 1493: "netmap-lm", + 1494: "ica", + 1495: "cvc", + 1496: "liberty-lm", + 1497: "rfx-lm", + 1498: "sybase-sqlany", + 1499: "fhc", + 1500: "vlsi-lm", + 1501: "saiscm", + 1502: "shivadiscovery", + 1503: "imtc-mcs", + 1504: "evb-elm", + 1505: "funkproxy", + 1506: "utcd", + 1507: "symplex", + 1508: "diagmond", + 1509: "robcad-lm", + 1510: "mvx-lm", + 1511: "3l-l1", + 1512: "wins", + 1513: "fujitsu-dtc", + 1514: "fujitsu-dtcns", + 1515: "ifor-protocol", + 1516: "vpad", + 1517: "vpac", + 1518: "vpvd", + 1519: "vpvc", + 1520: "atm-zip-office", + 1521: "ncube-lm", + 1522: "ricardo-lm", + 1523: "cichild-lm", + 1524: "ingreslock", + 1525: "orasrv", + 1526: "pdap-np", + 1527: "tlisrv", + 1529: "coauthor", + 1530: "rap-service", + 1531: "rap-listen", + 1532: "miroconnect", + 1533: "virtual-places", + 1534: "micromuse-lm", + 1535: "ampr-info", + 1536: "ampr-inter", + 1537: "sdsc-lm", + 1538: "3ds-lm", + 1539: "intellistor-lm", + 1540: "rds", + 1541: "rds2", + 1542: "gridgen-elmd", + 1543: "simba-cs", + 1544: "aspeclmd", + 1545: "vistium-share", + 1546: "abbaccuray", + 1547: "laplink", + 1548: "axon-lm", + 1549: "shivasound", + 1550: "3m-image-lm", + 1551: "hecmtl-db", + 1552: "pciarray", + 1553: "sna-cs", + 1554: "caci-lm", + 1555: "livelan", + 1556: "veritas-pbx", + 1557: "arbortext-lm", + 1558: "xingmpeg", + 1559: "web2host", + 1560: "asci-val", + 1561: "facilityview", + 1562: "pconnectmgr", + 1563: "cadabra-lm", + 1564: "pay-per-view", + 1565: "winddlb", + 1566: "corelvideo", + 1567: "jlicelmd", + 1568: "tsspmap", + 1569: "ets", + 1570: "orbixd", + 1571: "rdb-dbs-disp", + 1572: "chip-lm", + 1573: "itscomm-ns", + 1574: "mvel-lm", + 1575: "oraclenames", + 1576: "moldflow-lm", + 1577: "hypercube-lm", + 1578: "jacobus-lm", + 1579: "ioc-sea-lm", + 1580: "tn-tl-r2", + 1581: "mil-2045-47001", + 1582: "msims", + 1583: "simbaexpress", + 1584: "tn-tl-fd2", + 1585: "intv", + 1586: "ibm-abtact", + 1587: "pra-elmd", + 1588: "triquest-lm", + 1589: "vqp", + 1590: "gemini-lm", + 1591: "ncpm-pm", + 1592: "commonspace", + 1593: "mainsoft-lm", + 1594: "sixtrak", + 1595: "radio", + 1596: "radio-bc", + 1597: "orbplus-iiop", + 1598: "picknfs", + 1599: "simbaservices", + 1600: "issd", + 1601: "aas", + 1602: "inspect", + 1603: "picodbc", + 1604: "icabrowser", + 1605: "slp", + 1606: "slm-api", + 1607: "stt", + 1608: "smart-lm", + 1609: "isysg-lm", + 1610: "taurus-wh", + 1611: "ill", + 1612: "netbill-trans", + 1613: "netbill-keyrep", + 1614: "netbill-cred", + 1615: "netbill-auth", + 1616: "netbill-prod", + 1617: "nimrod-agent", + 1618: "skytelnet", + 1619: "xs-openstorage", + 1620: "faxportwinport", + 1621: "softdataphone", + 1622: "ontime", + 1623: "jaleosnd", + 1624: "udp-sr-port", + 1625: "svs-omagent", + 1626: "shockwave", + 1627: "t128-gateway", + 1628: "lontalk-norm", + 1629: "lontalk-urgnt", + 1630: "oraclenet8cman", + 1631: "visitview", + 1632: "pammratc", + 1633: "pammrpc", + 1634: "loaprobe", + 1635: "edb-server1", + 1636: "isdc", + 1637: "islc", + 1638: "ismc", + 1639: "cert-initiator", + 1640: "cert-responder", + 1641: "invision", + 1642: "isis-am", + 1643: "isis-ambc", + 1644: "saiseh", + 1645: "sightline", + 1646: "sa-msg-port", + 1647: "rsap", + 1648: "concurrent-lm", + 1649: "kermit", + 1650: "nkd", + 1651: "shiva-confsrvr", + 1652: "xnmp", + 1653: "alphatech-lm", + 1654: "stargatealerts", + 1655: "dec-mbadmin", + 1656: "dec-mbadmin-h", + 1657: "fujitsu-mmpdc", + 1658: "sixnetudr", + 1659: "sg-lm", + 1660: "skip-mc-gikreq", + 1661: "netview-aix-1", + 1662: "netview-aix-2", + 1663: "netview-aix-3", + 1664: "netview-aix-4", + 1665: "netview-aix-5", + 1666: "netview-aix-6", + 1667: "netview-aix-7", + 1668: "netview-aix-8", + 1669: "netview-aix-9", + 1670: "netview-aix-10", + 1671: "netview-aix-11", + 1672: "netview-aix-12", + 1673: "proshare-mc-1", + 1674: "proshare-mc-2", + 1675: "pdp", + 1676: "netcomm2", + 1677: "groupwise", + 1678: "prolink", + 1679: "darcorp-lm", + 1680: "microcom-sbp", + 1681: "sd-elmd", + 1682: "lanyon-lantern", + 1683: "ncpm-hip", + 1684: "snaresecure", + 1685: "n2nremote", + 1686: "cvmon", + 1687: "nsjtp-ctrl", + 1688: "nsjtp-data", + 1689: "firefox", + 1690: "ng-umds", + 1691: "empire-empuma", + 1692: "sstsys-lm", + 1693: "rrirtr", + 1694: "rrimwm", + 1695: "rrilwm", + 1696: "rrifmm", + 1697: "rrisat", + 1698: "rsvp-encap-1", + 1699: "rsvp-encap-2", + 1700: "mps-raft", + 1701: "l2f", + 1702: "deskshare", + 1703: "hb-engine", + 1704: "bcs-broker", + 1705: "slingshot", + 1706: "jetform", + 1707: "vdmplay", + 1708: "gat-lmd", + 1709: "centra", + 1710: "impera", + 1711: "pptconference", + 1712: "registrar", + 1713: "conferencetalk", + 1714: "sesi-lm", + 1715: "houdini-lm", + 1716: "xmsg", + 1717: "fj-hdnet", + 1718: "h323gatedisc", + 1719: "h323gatestat", + 1720: "h323hostcall", + 1721: "caicci", + 1722: "hks-lm", + 1723: "pptp", + 1724: "csbphonemaster", + 1725: "iden-ralp", + 1726: "iberiagames", + 1727: "winddx", + 1728: "telindus", + 1729: "citynl", + 1730: "roketz", + 1731: "msiccp", + 1732: "proxim", + 1733: "siipat", + 1734: "cambertx-lm", + 1735: "privatechat", + 1736: "street-stream", + 1737: "ultimad", + 1738: "gamegen1", + 1739: "webaccess", + 1740: "encore", + 1741: "cisco-net-mgmt", + 1742: "3Com-nsd", + 1743: "cinegrfx-lm", + 1744: "ncpm-ft", + 1745: "remote-winsock", + 1746: "ftrapid-1", + 1747: "ftrapid-2", + 1748: "oracle-em1", + 1749: "aspen-services", + 1750: "sslp", + 1751: "swiftnet", + 1752: "lofr-lm", + 1754: "oracle-em2", + 1755: "ms-streaming", + 1756: "capfast-lmd", + 1757: "cnhrp", + 1758: "tftp-mcast", + 1759: "spss-lm", + 1760: "www-ldap-gw", + 1761: "cft-0", + 1762: "cft-1", + 1763: "cft-2", + 1764: "cft-3", + 1765: "cft-4", + 1766: "cft-5", + 1767: "cft-6", + 1768: "cft-7", + 1769: "bmc-net-adm", + 1770: "bmc-net-svc", + 1771: "vaultbase", + 1772: "essweb-gw", + 1773: "kmscontrol", + 1774: "global-dtserv", + 1776: "femis", + 1777: "powerguardian", + 1778: "prodigy-intrnet", + 1779: "pharmasoft", + 1780: "dpkeyserv", + 1781: "answersoft-lm", + 1782: "hp-hcip", + 1784: "finle-lm", + 1785: "windlm", + 1786: "funk-logger", + 1787: "funk-license", + 1788: "psmond", + 1789: "hello", + 1790: "nmsp", + 1791: "ea1", + 1792: "ibm-dt-2", + 1793: "rsc-robot", + 1794: "cera-bcm", + 1795: "dpi-proxy", + 1796: "vocaltec-admin", + 1797: "uma", + 1798: "etp", + 1799: "netrisk", + 1800: "ansys-lm", + 1801: "msmq", + 1802: "concomp1", + 1803: "hp-hcip-gwy", + 1804: "enl", + 1805: "enl-name", + 1806: "musiconline", + 1807: "fhsp", + 1808: "oracle-vp2", + 1809: "oracle-vp1", + 1810: "jerand-lm", + 1811: "scientia-sdb", + 1812: "radius", + 1813: "radius-acct", + 1814: "tdp-suite", + 1815: "mmpft", + 1816: "harp", + 1817: "rkb-oscs", + 1818: "etftp", + 1819: "plato-lm", + 1820: "mcagent", + 1821: "donnyworld", + 1822: "es-elmd", + 1823: "unisys-lm", + 1824: "metrics-pas", + 1825: "direcpc-video", + 1826: "ardt", + 1827: "asi", + 1828: "itm-mcell-u", + 1829: "optika-emedia", + 1830: "net8-cman", + 1831: "myrtle", + 1832: "tht-treasure", + 1833: "udpradio", + 1834: "ardusuni", + 1835: "ardusmul", + 1836: "ste-smsc", + 1837: "csoft1", + 1838: "talnet", + 1839: "netopia-vo1", + 1840: "netopia-vo2", + 1841: "netopia-vo3", + 1842: "netopia-vo4", + 1843: "netopia-vo5", + 1844: "direcpc-dll", + 1845: "altalink", + 1846: "tunstall-pnc", + 1847: "slp-notify", + 1848: "fjdocdist", + 1849: "alpha-sms", + 1850: "gsi", + 1851: "ctcd", + 1852: "virtual-time", + 1853: "vids-avtp", + 1854: "buddy-draw", + 1855: "fiorano-rtrsvc", + 1856: "fiorano-msgsvc", + 1857: "datacaptor", + 1858: "privateark", + 1859: "gammafetchsvr", + 1860: "sunscalar-svc", + 1861: "lecroy-vicp", + 1862: "mysql-cm-agent", + 1863: "msnp", + 1864: "paradym-31port", + 1865: "entp", + 1866: "swrmi", + 1867: "udrive", + 1868: "viziblebrowser", + 1869: "transact", + 1870: "sunscalar-dns", + 1871: "canocentral0", + 1872: "canocentral1", + 1873: "fjmpjps", + 1874: "fjswapsnp", + 1875: "westell-stats", + 1876: "ewcappsrv", + 1877: "hp-webqosdb", + 1878: "drmsmc", + 1879: "nettgain-nms", + 1880: "vsat-control", + 1881: "ibm-mqseries2", + 1882: "ecsqdmn", + 1883: "ibm-mqisdp", + 1884: "idmaps", + 1885: "vrtstrapserver", + 1886: "leoip", + 1887: "filex-lport", + 1888: "ncconfig", + 1889: "unify-adapter", + 1890: "wilkenlistener", + 1891: "childkey-notif", + 1892: "childkey-ctrl", + 1893: "elad", + 1894: "o2server-port", + 1896: "b-novative-ls", + 1897: "metaagent", + 1898: "cymtec-port", + 1899: "mc2studios", + 1900: "ssdp", + 1901: "fjicl-tep-a", + 1902: "fjicl-tep-b", + 1903: "linkname", + 1904: "fjicl-tep-c", + 1905: "sugp", + 1906: "tpmd", + 1907: "intrastar", + 1908: "dawn", + 1909: "global-wlink", + 1910: "ultrabac", + 1911: "mtp", + 1912: "rhp-iibp", + 1913: "armadp", + 1914: "elm-momentum", + 1915: "facelink", + 1916: "persona", + 1917: "noagent", + 1918: "can-nds", + 1919: "can-dch", + 1920: "can-ferret", + 1921: "noadmin", + 1922: "tapestry", + 1923: "spice", + 1924: "xiip", + 1925: "discovery-port", + 1926: "egs", + 1927: "videte-cipc", + 1928: "emsd-port", + 1929: "bandwiz-system", + 1930: "driveappserver", + 1931: "amdsched", + 1932: "ctt-broker", + 1933: "xmapi", + 1934: "xaapi", + 1935: "macromedia-fcs", + 1936: "jetcmeserver", + 1937: "jwserver", + 1938: "jwclient", + 1939: "jvserver", + 1940: "jvclient", + 1941: "dic-aida", + 1942: "res", + 1943: "beeyond-media", + 1944: "close-combat", + 1945: "dialogic-elmd", + 1946: "tekpls", + 1947: "sentinelsrm", + 1948: "eye2eye", + 1949: "ismaeasdaqlive", + 1950: "ismaeasdaqtest", + 1951: "bcs-lmserver", + 1952: "mpnjsc", + 1953: "rapidbase", + 1954: "abr-api", + 1955: "abr-secure", + 1956: "vrtl-vmf-ds", + 1957: "unix-status", + 1958: "dxadmind", + 1959: "simp-all", + 1960: "nasmanager", + 1961: "bts-appserver", + 1962: "biap-mp", + 1963: "webmachine", + 1964: "solid-e-engine", + 1965: "tivoli-npm", + 1966: "slush", + 1967: "sns-quote", + 1968: "lipsinc", + 1969: "lipsinc1", + 1970: "netop-rc", + 1971: "netop-school", + 1972: "intersys-cache", + 1973: "dlsrap", + 1974: "drp", + 1975: "tcoflashagent", + 1976: "tcoregagent", + 1977: "tcoaddressbook", + 1978: "unisql", + 1979: "unisql-java", + 1980: "pearldoc-xact", + 1981: "p2pq", + 1982: "estamp", + 1983: "lhtp", + 1984: "bb", + 1985: "hsrp", + 1986: "licensedaemon", + 1987: "tr-rsrb-p1", + 1988: "tr-rsrb-p2", + 1989: "tr-rsrb-p3", + 1990: "stun-p1", + 1991: "stun-p2", + 1992: "stun-p3", + 1993: "snmp-tcp-port", + 1994: "stun-port", + 1995: "perf-port", + 1996: "tr-rsrb-port", + 1997: "gdp-port", + 1998: "x25-svc-port", + 1999: "tcp-id-port", + 2000: "cisco-sccp", + 2001: "wizard", + 2002: "globe", + 2003: "brutus", + 2004: "emce", + 2005: "oracle", + 2006: "raid-cd", + 2007: "raid-am", + 2008: "terminaldb", + 2009: "whosockami", + 2010: "pipe-server", + 2011: "servserv", + 2012: "raid-ac", + 2013: "raid-cd", + 2014: "raid-sf", + 2015: "raid-cs", + 2016: "bootserver", + 2017: "bootclient", + 2018: "rellpack", + 2019: "about", + 2020: "xinupageserver", + 2021: "xinuexpansion1", + 2022: "xinuexpansion2", + 2023: "xinuexpansion3", + 2024: "xinuexpansion4", + 2025: "xribs", + 2026: "scrabble", + 2027: "shadowserver", + 2028: "submitserver", + 2029: "hsrpv6", + 2030: "device2", + 2031: "mobrien-chat", + 2032: "blackboard", + 2033: "glogger", + 2034: "scoremgr", + 2035: "imsldoc", + 2036: "e-dpnet", + 2037: "applus", + 2038: "objectmanager", + 2039: "prizma", + 2040: "lam", + 2041: "interbase", + 2042: "isis", + 2043: "isis-bcast", + 2044: "rimsl", + 2045: "cdfunc", + 2046: "sdfunc", + 2047: "dls", + 2048: "dls-monitor", + 2049: "shilp", + 2050: "av-emb-config", + 2051: "epnsdp", + 2052: "clearvisn", + 2053: "lot105-ds-upd", + 2054: "weblogin", + 2055: "iop", + 2056: "omnisky", + 2057: "rich-cp", + 2058: "newwavesearch", + 2059: "bmc-messaging", + 2060: "teleniumdaemon", + 2061: "netmount", + 2062: "icg-swp", + 2063: "icg-bridge", + 2064: "icg-iprelay", + 2065: "dlsrpn", + 2066: "aura", + 2067: "dlswpn", + 2068: "avauthsrvprtcl", + 2069: "event-port", + 2070: "ah-esp-encap", + 2071: "acp-port", + 2072: "msync", + 2073: "gxs-data-port", + 2074: "vrtl-vmf-sa", + 2075: "newlixengine", + 2076: "newlixconfig", + 2077: "tsrmagt", + 2078: "tpcsrvr", + 2079: "idware-router", + 2080: "autodesk-nlm", + 2081: "kme-trap-port", + 2082: "infowave", + 2083: "radsec", + 2084: "sunclustergeo", + 2085: "ada-cip", + 2086: "gnunet", + 2087: "eli", + 2088: "ip-blf", + 2089: "sep", + 2090: "lrp", + 2091: "prp", + 2092: "descent3", + 2093: "nbx-cc", + 2094: "nbx-au", + 2095: "nbx-ser", + 2096: "nbx-dir", + 2097: "jetformpreview", + 2098: "dialog-port", + 2099: "h2250-annex-g", + 2100: "amiganetfs", + 2101: "rtcm-sc104", + 2102: "zephyr-srv", + 2103: "zephyr-clt", + 2104: "zephyr-hm", + 2105: "minipay", + 2106: "mzap", + 2107: "bintec-admin", + 2108: "comcam", + 2109: "ergolight", + 2110: "umsp", + 2111: "dsatp", + 2112: "idonix-metanet", + 2113: "hsl-storm", + 2114: "newheights", + 2115: "kdm", + 2116: "ccowcmr", + 2117: "mentaclient", + 2118: "mentaserver", + 2119: "gsigatekeeper", + 2120: "qencp", + 2121: "scientia-ssdb", + 2122: "caupc-remote", + 2123: "gtp-control", + 2124: "elatelink", + 2125: "lockstep", + 2126: "pktcable-cops", + 2127: "index-pc-wb", + 2128: "net-steward", + 2129: "cs-live", + 2130: "xds", + 2131: "avantageb2b", + 2132: "solera-epmap", + 2133: "zymed-zpp", + 2134: "avenue", + 2135: "gris", + 2136: "appworxsrv", + 2137: "connect", + 2138: "unbind-cluster", + 2139: "ias-auth", + 2140: "ias-reg", + 2141: "ias-admind", + 2142: "tdmoip", + 2143: "lv-jc", + 2144: "lv-ffx", + 2145: "lv-pici", + 2146: "lv-not", + 2147: "lv-auth", + 2148: "veritas-ucl", + 2149: "acptsys", + 2150: "dynamic3d", + 2151: "docent", + 2152: "gtp-user", + 2153: "ctlptc", + 2154: "stdptc", + 2155: "brdptc", + 2156: "trp", + 2157: "xnds", + 2158: "touchnetplus", + 2159: "gdbremote", + 2160: "apc-2160", + 2161: "apc-2161", + 2162: "navisphere", + 2163: "navisphere-sec", + 2164: "ddns-v3", + 2165: "x-bone-api", + 2166: "iwserver", + 2167: "raw-serial", + 2168: "easy-soft-mux", + 2169: "brain", + 2170: "eyetv", + 2171: "msfw-storage", + 2172: "msfw-s-storage", + 2173: "msfw-replica", + 2174: "msfw-array", + 2175: "airsync", + 2176: "rapi", + 2177: "qwave", + 2178: "bitspeer", + 2179: "vmrdp", + 2180: "mc-gt-srv", + 2181: "eforward", + 2182: "cgn-stat", + 2183: "cgn-config", + 2184: "nvd", + 2185: "onbase-dds", + 2186: "gtaua", + 2187: "ssmd", + 2190: "tivoconnect", + 2191: "tvbus", + 2192: "asdis", + 2193: "drwcs", + 2197: "mnp-exchange", + 2198: "onehome-remote", + 2199: "onehome-help", + 2200: "ici", + 2201: "ats", + 2202: "imtc-map", + 2203: "b2-runtime", + 2204: "b2-license", + 2205: "jps", + 2206: "hpocbus", + 2207: "hpssd", + 2208: "hpiod", + 2209: "rimf-ps", + 2210: "noaaport", + 2211: "emwin", + 2212: "leecoposserver", + 2213: "kali", + 2214: "rpi", + 2215: "ipcore", + 2216: "vtu-comms", + 2217: "gotodevice", + 2218: "bounzza", + 2219: "netiq-ncap", + 2220: "netiq", + 2221: "rockwell-csp1", + 2222: "EtherNet-IP-1", + 2223: "rockwell-csp2", + 2224: "efi-mg", + 2226: "di-drm", + 2227: "di-msg", + 2228: "ehome-ms", + 2229: "datalens", + 2230: "queueadm", + 2231: "wimaxasncp", + 2232: "ivs-video", + 2233: "infocrypt", + 2234: "directplay", + 2235: "sercomm-wlink", + 2236: "nani", + 2237: "optech-port1-lm", + 2238: "aviva-sna", + 2239: "imagequery", + 2240: "recipe", + 2241: "ivsd", + 2242: "foliocorp", + 2243: "magicom", + 2244: "nmsserver", + 2245: "hao", + 2246: "pc-mta-addrmap", + 2247: "antidotemgrsvr", + 2248: "ums", + 2249: "rfmp", + 2250: "remote-collab", + 2251: "dif-port", + 2252: "njenet-ssl", + 2253: "dtv-chan-req", + 2254: "seispoc", + 2255: "vrtp", + 2256: "pcc-mfp", + 2257: "simple-tx-rx", + 2258: "rcts", + 2260: "apc-2260", + 2261: "comotionmaster", + 2262: "comotionback", + 2263: "ecwcfg", + 2264: "apx500api-1", + 2265: "apx500api-2", + 2266: "mfserver", + 2267: "ontobroker", + 2268: "amt", + 2269: "mikey", + 2270: "starschool", + 2271: "mmcals", + 2272: "mmcal", + 2273: "mysql-im", + 2274: "pcttunnell", + 2275: "ibridge-data", + 2276: "ibridge-mgmt", + 2277: "bluectrlproxy", + 2278: "s3db", + 2279: "xmquery", + 2280: "lnvpoller", + 2281: "lnvconsole", + 2282: "lnvalarm", + 2283: "lnvstatus", + 2284: "lnvmaps", + 2285: "lnvmailmon", + 2286: "nas-metering", + 2287: "dna", + 2288: "netml", + 2289: "dict-lookup", + 2290: "sonus-logging", + 2291: "eapsp", + 2292: "mib-streaming", + 2293: "npdbgmngr", + 2294: "konshus-lm", + 2295: "advant-lm", + 2296: "theta-lm", + 2297: "d2k-datamover1", + 2298: "d2k-datamover2", + 2299: "pc-telecommute", + 2300: "cvmmon", + 2301: "cpq-wbem", + 2302: "binderysupport", + 2303: "proxy-gateway", + 2304: "attachmate-uts", + 2305: "mt-scaleserver", + 2306: "tappi-boxnet", + 2307: "pehelp", + 2308: "sdhelp", + 2309: "sdserver", + 2310: "sdclient", + 2311: "messageservice", + 2312: "wanscaler", + 2313: "iapp", + 2314: "cr-websystems", + 2315: "precise-sft", + 2316: "sent-lm", + 2317: "attachmate-g32", + 2318: "cadencecontrol", + 2319: "infolibria", + 2320: "siebel-ns", + 2321: "rdlap", + 2322: "ofsd", + 2323: "3d-nfsd", + 2324: "cosmocall", + 2325: "ansysli", + 2326: "idcp", + 2327: "xingcsm", + 2328: "netrix-sftm", + 2329: "nvd", + 2330: "tscchat", + 2331: "agentview", + 2332: "rcc-host", + 2333: "snapp", + 2334: "ace-client", + 2335: "ace-proxy", + 2336: "appleugcontrol", + 2337: "ideesrv", + 2338: "norton-lambert", + 2339: "3com-webview", + 2340: "wrs-registry", + 2341: "xiostatus", + 2342: "manage-exec", + 2343: "nati-logos", + 2344: "fcmsys", + 2345: "dbm", + 2346: "redstorm-join", + 2347: "redstorm-find", + 2348: "redstorm-info", + 2349: "redstorm-diag", + 2350: "psbserver", + 2351: "psrserver", + 2352: "pslserver", + 2353: "pspserver", + 2354: "psprserver", + 2355: "psdbserver", + 2356: "gxtelmd", + 2357: "unihub-server", + 2358: "futrix", + 2359: "flukeserver", + 2360: "nexstorindltd", + 2361: "tl1", + 2362: "digiman", + 2363: "mediacntrlnfsd", + 2364: "oi-2000", + 2365: "dbref", + 2366: "qip-login", + 2367: "service-ctrl", + 2368: "opentable", + 2370: "l3-hbmon", + 2372: "lanmessenger", + 2381: "compaq-https", + 2382: "ms-olap3", + 2383: "ms-olap4", + 2384: "sd-capacity", + 2385: "sd-data", + 2386: "virtualtape", + 2387: "vsamredirector", + 2388: "mynahautostart", + 2389: "ovsessionmgr", + 2390: "rsmtp", + 2391: "3com-net-mgmt", + 2392: "tacticalauth", + 2393: "ms-olap1", + 2394: "ms-olap2", + 2395: "lan900-remote", + 2396: "wusage", + 2397: "ncl", + 2398: "orbiter", + 2399: "fmpro-fdal", + 2400: "opequus-server", + 2401: "cvspserver", + 2402: "taskmaster2000", + 2403: "taskmaster2000", + 2404: "iec-104", + 2405: "trc-netpoll", + 2406: "jediserver", + 2407: "orion", + 2409: "sns-protocol", + 2410: "vrts-registry", + 2411: "netwave-ap-mgmt", + 2412: "cdn", + 2413: "orion-rmi-reg", + 2414: "beeyond", + 2415: "codima-rtp", + 2416: "rmtserver", + 2417: "composit-server", + 2418: "cas", + 2419: "attachmate-s2s", + 2420: "dslremote-mgmt", + 2421: "g-talk", + 2422: "crmsbits", + 2423: "rnrp", + 2424: "kofax-svr", + 2425: "fjitsuappmgr", + 2427: "mgcp-gateway", + 2428: "ott", + 2429: "ft-role", + 2430: "venus", + 2431: "venus-se", + 2432: "codasrv", + 2433: "codasrv-se", + 2434: "pxc-epmap", + 2435: "optilogic", + 2436: "topx", + 2437: "unicontrol", + 2438: "msp", + 2439: "sybasedbsynch", + 2440: "spearway", + 2441: "pvsw-inet", + 2442: "netangel", + 2443: "powerclientcsf", + 2444: "btpp2sectrans", + 2445: "dtn1", + 2446: "bues-service", + 2447: "ovwdb", + 2448: "hpppssvr", + 2449: "ratl", + 2450: "netadmin", + 2451: "netchat", + 2452: "snifferclient", + 2453: "madge-ltd", + 2454: "indx-dds", + 2455: "wago-io-system", + 2456: "altav-remmgt", + 2457: "rapido-ip", + 2458: "griffin", + 2459: "community", + 2460: "ms-theater", + 2461: "qadmifoper", + 2462: "qadmifevent", + 2463: "lsi-raid-mgmt", + 2464: "direcpc-si", + 2465: "lbm", + 2466: "lbf", + 2467: "high-criteria", + 2468: "qip-msgd", + 2469: "mti-tcs-comm", + 2470: "taskman-port", + 2471: "seaodbc", + 2472: "c3", + 2473: "aker-cdp", + 2474: "vitalanalysis", + 2475: "ace-server", + 2476: "ace-svr-prop", + 2477: "ssm-cvs", + 2478: "ssm-cssps", + 2479: "ssm-els", + 2480: "powerexchange", + 2481: "giop", + 2482: "giop-ssl", + 2483: "ttc", + 2484: "ttc-ssl", + 2485: "netobjects1", + 2486: "netobjects2", + 2487: "pns", + 2488: "moy-corp", + 2489: "tsilb", + 2490: "qip-qdhcp", + 2491: "conclave-cpp", + 2492: "groove", + 2493: "talarian-mqs", + 2494: "bmc-ar", + 2495: "fast-rem-serv", + 2496: "dirgis", + 2497: "quaddb", + 2498: "odn-castraq", + 2499: "unicontrol", + 2500: "rtsserv", + 2501: "rtsclient", + 2502: "kentrox-prot", + 2503: "nms-dpnss", + 2504: "wlbs", + 2505: "ppcontrol", + 2506: "jbroker", + 2507: "spock", + 2508: "jdatastore", + 2509: "fjmpss", + 2510: "fjappmgrbulk", + 2511: "metastorm", + 2512: "citrixima", + 2513: "citrixadmin", + 2514: "facsys-ntp", + 2515: "facsys-router", + 2516: "maincontrol", + 2517: "call-sig-trans", + 2518: "willy", + 2519: "globmsgsvc", + 2520: "pvsw", + 2521: "adaptecmgr", + 2522: "windb", + 2523: "qke-llc-v3", + 2524: "optiwave-lm", + 2525: "ms-v-worlds", + 2526: "ema-sent-lm", + 2527: "iqserver", + 2528: "ncr-ccl", + 2529: "utsftp", + 2530: "vrcommerce", + 2531: "ito-e-gui", + 2532: "ovtopmd", + 2533: "snifferserver", + 2534: "combox-web-acc", + 2535: "madcap", + 2536: "btpp2audctr1", + 2537: "upgrade", + 2538: "vnwk-prapi", + 2539: "vsiadmin", + 2540: "lonworks", + 2541: "lonworks2", + 2542: "udrawgraph", + 2543: "reftek", + 2544: "novell-zen", + 2545: "sis-emt", + 2546: "vytalvaultbrtp", + 2547: "vytalvaultvsmp", + 2548: "vytalvaultpipe", + 2549: "ipass", + 2550: "ads", + 2551: "isg-uda-server", + 2552: "call-logging", + 2553: "efidiningport", + 2554: "vcnet-link-v10", + 2555: "compaq-wcp", + 2556: "nicetec-nmsvc", + 2557: "nicetec-mgmt", + 2558: "pclemultimedia", + 2559: "lstp", + 2560: "labrat", + 2561: "mosaixcc", + 2562: "delibo", + 2563: "cti-redwood", + 2564: "hp-3000-telnet", + 2565: "coord-svr", + 2566: "pcs-pcw", + 2567: "clp", + 2568: "spamtrap", + 2569: "sonuscallsig", + 2570: "hs-port", + 2571: "cecsvc", + 2572: "ibp", + 2573: "trustestablish", + 2574: "blockade-bpsp", + 2575: "hl7", + 2576: "tclprodebugger", + 2577: "scipticslsrvr", + 2578: "rvs-isdn-dcp", + 2579: "mpfoncl", + 2580: "tributary", + 2581: "argis-te", + 2582: "argis-ds", + 2583: "mon", + 2584: "cyaserv", + 2585: "netx-server", + 2586: "netx-agent", + 2587: "masc", + 2588: "privilege", + 2589: "quartus-tcl", + 2590: "idotdist", + 2591: "maytagshuffle", + 2592: "netrek", + 2593: "mns-mail", + 2594: "dts", + 2595: "worldfusion1", + 2596: "worldfusion2", + 2597: "homesteadglory", + 2598: "citriximaclient", + 2599: "snapd", + 2600: "hpstgmgr", + 2601: "discp-client", + 2602: "discp-server", + 2603: "servicemeter", + 2604: "nsc-ccs", + 2605: "nsc-posa", + 2606: "netmon", + 2607: "connection", + 2608: "wag-service", + 2609: "system-monitor", + 2610: "versa-tek", + 2611: "lionhead", + 2612: "qpasa-agent", + 2613: "smntubootstrap", + 2614: "neveroffline", + 2615: "firepower", + 2616: "appswitch-emp", + 2617: "cmadmin", + 2618: "priority-e-com", + 2619: "bruce", + 2620: "lpsrecommender", + 2621: "miles-apart", + 2622: "metricadbc", + 2623: "lmdp", + 2624: "aria", + 2625: "blwnkl-port", + 2626: "gbjd816", + 2627: "moshebeeri", + 2628: "dict", + 2629: "sitaraserver", + 2630: "sitaramgmt", + 2631: "sitaradir", + 2632: "irdg-post", + 2633: "interintelli", + 2634: "pk-electronics", + 2635: "backburner", + 2636: "solve", + 2637: "imdocsvc", + 2638: "sybaseanywhere", + 2639: "aminet", + 2640: "sai-sentlm", + 2641: "hdl-srv", + 2642: "tragic", + 2643: "gte-samp", + 2644: "travsoft-ipx-t", + 2645: "novell-ipx-cmd", + 2646: "and-lm", + 2647: "syncserver", + 2648: "upsnotifyprot", + 2649: "vpsipport", + 2650: "eristwoguns", + 2651: "ebinsite", + 2652: "interpathpanel", + 2653: "sonus", + 2654: "corel-vncadmin", + 2655: "unglue", + 2656: "kana", + 2657: "sns-dispatcher", + 2658: "sns-admin", + 2659: "sns-query", + 2660: "gcmonitor", + 2661: "olhost", + 2662: "bintec-capi", + 2663: "bintec-tapi", + 2664: "patrol-mq-gm", + 2665: "patrol-mq-nm", + 2666: "extensis", + 2667: "alarm-clock-s", + 2668: "alarm-clock-c", + 2669: "toad", + 2670: "tve-announce", + 2671: "newlixreg", + 2672: "nhserver", + 2673: "firstcall42", + 2674: "ewnn", + 2675: "ttc-etap", + 2676: "simslink", + 2677: "gadgetgate1way", + 2678: "gadgetgate2way", + 2679: "syncserverssl", + 2680: "pxc-sapxom", + 2681: "mpnjsomb", + 2683: "ncdloadbalance", + 2684: "mpnjsosv", + 2685: "mpnjsocl", + 2686: "mpnjsomg", + 2687: "pq-lic-mgmt", + 2688: "md-cg-http", + 2689: "fastlynx", + 2690: "hp-nnm-data", + 2691: "itinternet", + 2692: "admins-lms", + 2694: "pwrsevent", + 2695: "vspread", + 2696: "unifyadmin", + 2697: "oce-snmp-trap", + 2698: "mck-ivpip", + 2699: "csoft-plusclnt", + 2700: "tqdata", + 2701: "sms-rcinfo", + 2702: "sms-xfer", + 2703: "sms-chat", + 2704: "sms-remctrl", + 2705: "sds-admin", + 2706: "ncdmirroring", + 2707: "emcsymapiport", + 2708: "banyan-net", + 2709: "supermon", + 2710: "sso-service", + 2711: "sso-control", + 2712: "aocp", + 2713: "raventbs", + 2714: "raventdm", + 2715: "hpstgmgr2", + 2716: "inova-ip-disco", + 2717: "pn-requester", + 2718: "pn-requester2", + 2719: "scan-change", + 2720: "wkars", + 2721: "smart-diagnose", + 2722: "proactivesrvr", + 2723: "watchdog-nt", + 2724: "qotps", + 2725: "msolap-ptp2", + 2726: "tams", + 2727: "mgcp-callagent", + 2728: "sqdr", + 2729: "tcim-control", + 2730: "nec-raidplus", + 2731: "fyre-messanger", + 2732: "g5m", + 2733: "signet-ctf", + 2734: "ccs-software", + 2735: "netiq-mc", + 2736: "radwiz-nms-srv", + 2737: "srp-feedback", + 2738: "ndl-tcp-ois-gw", + 2739: "tn-timing", + 2740: "alarm", + 2741: "tsb", + 2742: "tsb2", + 2743: "murx", + 2744: "honyaku", + 2745: "urbisnet", + 2746: "cpudpencap", + 2747: "fjippol-swrly", + 2748: "fjippol-polsvr", + 2749: "fjippol-cnsl", + 2750: "fjippol-port1", + 2751: "fjippol-port2", + 2752: "rsisysaccess", + 2753: "de-spot", + 2754: "apollo-cc", + 2755: "expresspay", + 2756: "simplement-tie", + 2757: "cnrp", + 2758: "apollo-status", + 2759: "apollo-gms", + 2760: "sabams", + 2761: "dicom-iscl", + 2762: "dicom-tls", + 2763: "desktop-dna", + 2764: "data-insurance", + 2765: "qip-audup", + 2766: "compaq-scp", + 2767: "uadtc", + 2768: "uacs", + 2769: "exce", + 2770: "veronica", + 2771: "vergencecm", + 2772: "auris", + 2773: "rbakcup1", + 2774: "rbakcup2", + 2775: "smpp", + 2776: "ridgeway1", + 2777: "ridgeway2", + 2778: "gwen-sonya", + 2779: "lbc-sync", + 2780: "lbc-control", + 2781: "whosells", + 2782: "everydayrc", + 2783: "aises", + 2784: "www-dev", + 2785: "aic-np", + 2786: "aic-oncrpc", + 2787: "piccolo", + 2788: "fryeserv", + 2789: "media-agent", + 2790: "plgproxy", + 2791: "mtport-regist", + 2792: "f5-globalsite", + 2793: "initlsmsad", + 2795: "livestats", + 2796: "ac-tech", + 2797: "esp-encap", + 2798: "tmesis-upshot", + 2799: "icon-discover", + 2800: "acc-raid", + 2801: "igcp", + 2802: "veritas-udp1", + 2803: "btprjctrl", + 2804: "dvr-esm", + 2805: "wta-wsp-s", + 2806: "cspuni", + 2807: "cspmulti", + 2808: "j-lan-p", + 2809: "corbaloc", + 2810: "netsteward", + 2811: "gsiftp", + 2812: "atmtcp", + 2813: "llm-pass", + 2814: "llm-csv", + 2815: "lbc-measure", + 2816: "lbc-watchdog", + 2817: "nmsigport", + 2818: "rmlnk", + 2819: "fc-faultnotify", + 2820: "univision", + 2821: "vrts-at-port", + 2822: "ka0wuc", + 2823: "cqg-netlan", + 2824: "cqg-netlan-1", + 2826: "slc-systemlog", + 2827: "slc-ctrlrloops", + 2828: "itm-lm", + 2829: "silkp1", + 2830: "silkp2", + 2831: "silkp3", + 2832: "silkp4", + 2833: "glishd", + 2834: "evtp", + 2835: "evtp-data", + 2836: "catalyst", + 2837: "repliweb", + 2838: "starbot", + 2839: "nmsigport", + 2840: "l3-exprt", + 2841: "l3-ranger", + 2842: "l3-hawk", + 2843: "pdnet", + 2844: "bpcp-poll", + 2845: "bpcp-trap", + 2846: "aimpp-hello", + 2847: "aimpp-port-req", + 2848: "amt-blc-port", + 2849: "fxp", + 2850: "metaconsole", + 2851: "webemshttp", + 2852: "bears-01", + 2853: "ispipes", + 2854: "infomover", + 2856: "cesdinv", + 2857: "simctlp", + 2858: "ecnp", + 2859: "activememory", + 2860: "dialpad-voice1", + 2861: "dialpad-voice2", + 2862: "ttg-protocol", + 2863: "sonardata", + 2864: "astromed-main", + 2865: "pit-vpn", + 2866: "iwlistener", + 2867: "esps-portal", + 2868: "npep-messaging", + 2869: "icslap", + 2870: "daishi", + 2871: "msi-selectplay", + 2872: "radix", + 2874: "dxmessagebase1", + 2875: "dxmessagebase2", + 2876: "sps-tunnel", + 2877: "bluelance", + 2878: "aap", + 2879: "ucentric-ds", + 2880: "synapse", + 2881: "ndsp", + 2882: "ndtp", + 2883: "ndnp", + 2884: "flashmsg", + 2885: "topflow", + 2886: "responselogic", + 2887: "aironetddp", + 2888: "spcsdlobby", + 2889: "rsom", + 2890: "cspclmulti", + 2891: "cinegrfx-elmd", + 2892: "snifferdata", + 2893: "vseconnector", + 2894: "abacus-remote", + 2895: "natuslink", + 2896: "ecovisiong6-1", + 2897: "citrix-rtmp", + 2898: "appliance-cfg", + 2899: "powergemplus", + 2900: "quicksuite", + 2901: "allstorcns", + 2902: "netaspi", + 2903: "suitcase", + 2904: "m2ua", + 2906: "caller9", + 2907: "webmethods-b2b", + 2908: "mao", + 2909: "funk-dialout", + 2910: "tdaccess", + 2911: "blockade", + 2912: "epicon", + 2913: "boosterware", + 2914: "gamelobby", + 2915: "tksocket", + 2916: "elvin-server", + 2917: "elvin-client", + 2918: "kastenchasepad", + 2919: "roboer", + 2920: "roboeda", + 2921: "cesdcdman", + 2922: "cesdcdtrn", + 2923: "wta-wsp-wtp-s", + 2924: "precise-vip", + 2926: "mobile-file-dl", + 2927: "unimobilectrl", + 2928: "redstone-cpss", + 2929: "amx-webadmin", + 2930: "amx-weblinx", + 2931: "circle-x", + 2932: "incp", + 2933: "4-tieropmgw", + 2934: "4-tieropmcli", + 2935: "qtp", + 2936: "otpatch", + 2937: "pnaconsult-lm", + 2938: "sm-pas-1", + 2939: "sm-pas-2", + 2940: "sm-pas-3", + 2941: "sm-pas-4", + 2942: "sm-pas-5", + 2943: "ttnrepository", + 2944: "megaco-h248", + 2945: "h248-binary", + 2946: "fjsvmpor", + 2947: "gpsd", + 2948: "wap-push", + 2949: "wap-pushsecure", + 2950: "esip", + 2951: "ottp", + 2952: "mpfwsas", + 2953: "ovalarmsrv", + 2954: "ovalarmsrv-cmd", + 2955: "csnotify", + 2956: "ovrimosdbman", + 2957: "jmact5", + 2958: "jmact6", + 2959: "rmopagt", + 2960: "dfoxserver", + 2961: "boldsoft-lm", + 2962: "iph-policy-cli", + 2963: "iph-policy-adm", + 2964: "bullant-srap", + 2965: "bullant-rap", + 2966: "idp-infotrieve", + 2967: "ssc-agent", + 2968: "enpp", + 2969: "essp", + 2970: "index-net", + 2971: "netclip", + 2972: "pmsm-webrctl", + 2973: "svnetworks", + 2974: "signal", + 2975: "fjmpcm", + 2976: "cns-srv-port", + 2977: "ttc-etap-ns", + 2978: "ttc-etap-ds", + 2979: "h263-video", + 2980: "wimd", + 2981: "mylxamport", + 2982: "iwb-whiteboard", + 2983: "netplan", + 2984: "hpidsadmin", + 2985: "hpidsagent", + 2986: "stonefalls", + 2987: "identify", + 2988: "hippad", + 2989: "zarkov", + 2990: "boscap", + 2991: "wkstn-mon", + 2992: "avenyo", + 2993: "veritas-vis1", + 2994: "veritas-vis2", + 2995: "idrs", + 2996: "vsixml", + 2997: "rebol", + 2998: "realsecure", + 2999: "remoteware-un", + 3000: "hbci", + 3002: "exlm-agent", + 3003: "cgms", + 3004: "csoftragent", + 3005: "geniuslm", + 3006: "ii-admin", + 3007: "lotusmtap", + 3008: "midnight-tech", + 3009: "pxc-ntfy", + 3010: "ping-pong", + 3011: "trusted-web", + 3012: "twsdss", + 3013: "gilatskysurfer", + 3014: "broker-service", + 3015: "nati-dstp", + 3016: "notify-srvr", + 3017: "event-listener", + 3018: "srvc-registry", + 3019: "resource-mgr", + 3020: "cifs", + 3021: "agriserver", + 3022: "csregagent", + 3023: "magicnotes", + 3024: "nds-sso", + 3025: "arepa-raft", + 3026: "agri-gateway", + 3027: "LiebDevMgmt-C", + 3028: "LiebDevMgmt-DM", + 3029: "LiebDevMgmt-A", + 3030: "arepa-cas", + 3031: "eppc", + 3032: "redwood-chat", + 3033: "pdb", + 3034: "osmosis-aeea", + 3035: "fjsv-gssagt", + 3036: "hagel-dump", + 3037: "hp-san-mgmt", + 3038: "santak-ups", + 3039: "cogitate", + 3040: "tomato-springs", + 3041: "di-traceware", + 3042: "journee", + 3043: "brp", + 3044: "epp", + 3045: "responsenet", + 3046: "di-ase", + 3047: "hlserver", + 3048: "pctrader", + 3049: "nsws", + 3050: "gds-db", + 3051: "galaxy-server", + 3052: "apc-3052", + 3053: "dsom-server", + 3054: "amt-cnf-prot", + 3055: "policyserver", + 3056: "cdl-server", + 3057: "goahead-fldup", + 3058: "videobeans", + 3059: "qsoft", + 3060: "interserver", + 3061: "cautcpd", + 3062: "ncacn-ip-tcp", + 3063: "ncadg-ip-udp", + 3064: "rprt", + 3065: "slinterbase", + 3066: "netattachsdmp", + 3067: "fjhpjp", + 3068: "ls3bcast", + 3069: "ls3", + 3070: "mgxswitch", + 3071: "csd-mgmt-port", + 3072: "csd-monitor", + 3073: "vcrp", + 3074: "xbox", + 3075: "orbix-locator", + 3076: "orbix-config", + 3077: "orbix-loc-ssl", + 3078: "orbix-cfg-ssl", + 3079: "lv-frontpanel", + 3080: "stm-pproc", + 3081: "tl1-lv", + 3082: "tl1-raw", + 3083: "tl1-telnet", + 3084: "itm-mccs", + 3085: "pcihreq", + 3086: "jdl-dbkitchen", + 3087: "asoki-sma", + 3088: "xdtp", + 3089: "ptk-alink", + 3090: "stss", + 3091: "1ci-smcs", + 3093: "rapidmq-center", + 3094: "rapidmq-reg", + 3095: "panasas", + 3096: "ndl-aps", + 3098: "umm-port", + 3099: "chmd", + 3100: "opcon-xps", + 3101: "hp-pxpib", + 3102: "slslavemon", + 3103: "autocuesmi", + 3104: "autocuetime", + 3105: "cardbox", + 3106: "cardbox-http", + 3107: "business", + 3108: "geolocate", + 3109: "personnel", + 3110: "sim-control", + 3111: "wsynch", + 3112: "ksysguard", + 3113: "cs-auth-svr", + 3114: "ccmad", + 3115: "mctet-master", + 3116: "mctet-gateway", + 3117: "mctet-jserv", + 3118: "pkagent", + 3119: "d2000kernel", + 3120: "d2000webserver", + 3122: "vtr-emulator", + 3123: "edix", + 3124: "beacon-port", + 3125: "a13-an", + 3127: "ctx-bridge", + 3128: "ndl-aas", + 3129: "netport-id", + 3130: "icpv2", + 3131: "netbookmark", + 3132: "ms-rule-engine", + 3133: "prism-deploy", + 3134: "ecp", + 3135: "peerbook-port", + 3136: "grubd", + 3137: "rtnt-1", + 3138: "rtnt-2", + 3139: "incognitorv", + 3140: "ariliamulti", + 3141: "vmodem", + 3142: "rdc-wh-eos", + 3143: "seaview", + 3144: "tarantella", + 3145: "csi-lfap", + 3146: "bears-02", + 3147: "rfio", + 3148: "nm-game-admin", + 3149: "nm-game-server", + 3150: "nm-asses-admin", + 3151: "nm-assessor", + 3152: "feitianrockey", + 3153: "s8-client-port", + 3154: "ccmrmi", + 3155: "jpegmpeg", + 3156: "indura", + 3157: "e3consultants", + 3158: "stvp", + 3159: "navegaweb-port", + 3160: "tip-app-server", + 3161: "doc1lm", + 3162: "sflm", + 3163: "res-sap", + 3164: "imprs", + 3165: "newgenpay", + 3166: "sossecollector", + 3167: "nowcontact", + 3168: "poweronnud", + 3169: "serverview-as", + 3170: "serverview-asn", + 3171: "serverview-gf", + 3172: "serverview-rm", + 3173: "serverview-icc", + 3174: "armi-server", + 3175: "t1-e1-over-ip", + 3176: "ars-master", + 3177: "phonex-port", + 3178: "radclientport", + 3179: "h2gf-w-2m", + 3180: "mc-brk-srv", + 3181: "bmcpatrolagent", + 3182: "bmcpatrolrnvu", + 3183: "cops-tls", + 3184: "apogeex-port", + 3185: "smpppd", + 3186: "iiw-port", + 3187: "odi-port", + 3188: "brcm-comm-port", + 3189: "pcle-infex", + 3190: "csvr-proxy", + 3191: "csvr-sslproxy", + 3192: "firemonrcc", + 3193: "spandataport", + 3194: "magbind", + 3195: "ncu-1", + 3196: "ncu-2", + 3197: "embrace-dp-s", + 3198: "embrace-dp-c", + 3199: "dmod-workspace", + 3200: "tick-port", + 3201: "cpq-tasksmart", + 3202: "intraintra", + 3203: "netwatcher-mon", + 3204: "netwatcher-db", + 3205: "isns", + 3206: "ironmail", + 3207: "vx-auth-port", + 3208: "pfu-prcallback", + 3209: "netwkpathengine", + 3210: "flamenco-proxy", + 3211: "avsecuremgmt", + 3212: "surveyinst", + 3213: "neon24x7", + 3214: "jmq-daemon-1", + 3215: "jmq-daemon-2", + 3216: "ferrari-foam", + 3217: "unite", + 3218: "smartpackets", + 3219: "wms-messenger", + 3220: "xnm-ssl", + 3221: "xnm-clear-text", + 3222: "glbp", + 3223: "digivote", + 3224: "aes-discovery", + 3225: "fcip-port", + 3226: "isi-irp", + 3227: "dwnmshttp", + 3228: "dwmsgserver", + 3229: "global-cd-port", + 3230: "sftdst-port", + 3231: "vidigo", + 3232: "mdtp", + 3233: "whisker", + 3234: "alchemy", + 3235: "mdap-port", + 3236: "apparenet-ts", + 3237: "apparenet-tps", + 3238: "apparenet-as", + 3239: "apparenet-ui", + 3240: "triomotion", + 3241: "sysorb", + 3242: "sdp-id-port", + 3243: "timelot", + 3244: "onesaf", + 3245: "vieo-fe", + 3246: "dvt-system", + 3247: "dvt-data", + 3248: "procos-lm", + 3249: "ssp", + 3250: "hicp", + 3251: "sysscanner", + 3252: "dhe", + 3253: "pda-data", + 3254: "pda-sys", + 3255: "semaphore", + 3256: "cpqrpm-agent", + 3257: "cpqrpm-server", + 3258: "ivecon-port", + 3259: "epncdp2", + 3260: "iscsi-target", + 3261: "winshadow", + 3262: "necp", + 3263: "ecolor-imager", + 3264: "ccmail", + 3265: "altav-tunnel", + 3266: "ns-cfg-server", + 3267: "ibm-dial-out", + 3268: "msft-gc", + 3269: "msft-gc-ssl", + 3270: "verismart", + 3271: "csoft-prev", + 3272: "user-manager", + 3273: "sxmp", + 3274: "ordinox-server", + 3275: "samd", + 3276: "maxim-asics", + 3277: "awg-proxy", + 3278: "lkcmserver", + 3279: "admind", + 3280: "vs-server", + 3281: "sysopt", + 3282: "datusorb", + 3283: "Apple Remote Desktop (Net Assistant)", + 3284: "4talk", + 3285: "plato", + 3286: "e-net", + 3287: "directvdata", + 3288: "cops", + 3289: "enpc", + 3290: "caps-lm", + 3291: "sah-lm", + 3292: "cart-o-rama", + 3293: "fg-fps", + 3294: "fg-gip", + 3295: "dyniplookup", + 3296: "rib-slm", + 3297: "cytel-lm", + 3298: "deskview", + 3299: "pdrncs", + 3302: "mcs-fastmail", + 3303: "opsession-clnt", + 3304: "opsession-srvr", + 3305: "odette-ftp", + 3306: "mysql", + 3307: "opsession-prxy", + 3308: "tns-server", + 3309: "tns-adv", + 3310: "dyna-access", + 3311: "mcns-tel-ret", + 3312: "appman-server", + 3313: "uorb", + 3314: "uohost", + 3315: "cdid", + 3316: "aicc-cmi", + 3317: "vsaiport", + 3318: "ssrip", + 3319: "sdt-lmd", + 3320: "officelink2000", + 3321: "vnsstr", + 3326: "sftu", + 3327: "bbars", + 3328: "egptlm", + 3329: "hp-device-disc", + 3330: "mcs-calypsoicf", + 3331: "mcs-messaging", + 3332: "mcs-mailsvr", + 3333: "dec-notes", + 3334: "directv-web", + 3335: "directv-soft", + 3336: "directv-tick", + 3337: "directv-catlg", + 3338: "anet-b", + 3339: "anet-l", + 3340: "anet-m", + 3341: "anet-h", + 3342: "webtie", + 3343: "ms-cluster-net", + 3344: "bnt-manager", + 3345: "influence", + 3346: "trnsprntproxy", + 3347: "phoenix-rpc", + 3348: "pangolin-laser", + 3349: "chevinservices", + 3350: "findviatv", + 3351: "btrieve", + 3352: "ssql", + 3353: "fatpipe", + 3354: "suitjd", + 3355: "ordinox-dbase", + 3356: "upnotifyps", + 3357: "adtech-test", + 3358: "mpsysrmsvr", + 3359: "wg-netforce", + 3360: "kv-server", + 3361: "kv-agent", + 3362: "dj-ilm", + 3363: "nati-vi-server", + 3364: "creativeserver", + 3365: "contentserver", + 3366: "creativepartnr", + 3372: "tip2", + 3373: "lavenir-lm", + 3374: "cluster-disc", + 3375: "vsnm-agent", + 3376: "cdbroker", + 3377: "cogsys-lm", + 3378: "wsicopy", + 3379: "socorfs", + 3380: "sns-channels", + 3381: "geneous", + 3382: "fujitsu-neat", + 3383: "esp-lm", + 3384: "hp-clic", + 3385: "qnxnetman", + 3386: "gprs-sig", + 3387: "backroomnet", + 3388: "cbserver", + 3389: "ms-wbt-server", + 3390: "dsc", + 3391: "savant", + 3392: "efi-lm", + 3393: "d2k-tapestry1", + 3394: "d2k-tapestry2", + 3395: "dyna-lm", + 3396: "printer-agent", + 3397: "cloanto-lm", + 3398: "mercantile", + 3399: "csms", + 3400: "csms2", + 3401: "filecast", + 3402: "fxaengine-net", + 3405: "nokia-ann-ch1", + 3406: "nokia-ann-ch2", + 3407: "ldap-admin", + 3408: "BESApi", + 3409: "networklens", + 3410: "networklenss", + 3411: "biolink-auth", + 3412: "xmlblaster", + 3413: "svnet", + 3414: "wip-port", + 3415: "bcinameservice", + 3416: "commandport", + 3417: "csvr", + 3418: "rnmap", + 3419: "softaudit", + 3420: "ifcp-port", + 3421: "bmap", + 3422: "rusb-sys-port", + 3423: "xtrm", + 3424: "xtrms", + 3425: "agps-port", + 3426: "arkivio", + 3427: "websphere-snmp", + 3428: "twcss", + 3429: "gcsp", + 3430: "ssdispatch", + 3431: "ndl-als", + 3432: "osdcp", + 3433: "opnet-smp", + 3434: "opencm", + 3435: "pacom", + 3436: "gc-config", + 3437: "autocueds", + 3438: "spiral-admin", + 3439: "hri-port", + 3440: "ans-console", + 3441: "connect-client", + 3442: "connect-server", + 3443: "ov-nnm-websrv", + 3444: "denali-server", + 3445: "monp", + 3446: "3comfaxrpc", + 3447: "directnet", + 3448: "dnc-port", + 3449: "hotu-chat", + 3450: "castorproxy", + 3451: "asam", + 3452: "sabp-signal", + 3453: "pscupd", + 3454: "mira", + 3455: "prsvp", + 3456: "vat", + 3457: "vat-control", + 3458: "d3winosfi", + 3459: "integral", + 3460: "edm-manager", + 3461: "edm-stager", + 3462: "edm-std-notify", + 3463: "edm-adm-notify", + 3464: "edm-mgr-sync", + 3465: "edm-mgr-cntrl", + 3466: "workflow", + 3467: "rcst", + 3468: "ttcmremotectrl", + 3469: "pluribus", + 3470: "jt400", + 3471: "jt400-ssl", + 3472: "jaugsremotec-1", + 3473: "jaugsremotec-2", + 3474: "ttntspauto", + 3475: "genisar-port", + 3476: "nppmp", + 3477: "ecomm", + 3478: "stun", + 3479: "twrpc", + 3480: "plethora", + 3481: "cleanerliverc", + 3482: "vulture", + 3483: "slim-devices", + 3484: "gbs-stp", + 3485: "celatalk", + 3486: "ifsf-hb-port", + 3487: "ltcudp", + 3488: "fs-rh-srv", + 3489: "dtp-dia", + 3490: "colubris", + 3491: "swr-port", + 3492: "tvdumtray-port", + 3493: "nut", + 3494: "ibm3494", + 3495: "seclayer-tcp", + 3496: "seclayer-tls", + 3497: "ipether232port", + 3498: "dashpas-port", + 3499: "sccip-media", + 3500: "rtmp-port", + 3501: "isoft-p2p", + 3502: "avinstalldisc", + 3503: "lsp-ping", + 3504: "ironstorm", + 3505: "ccmcomm", + 3506: "apc-3506", + 3507: "nesh-broker", + 3508: "interactionweb", + 3509: "vt-ssl", + 3510: "xss-port", + 3511: "webmail-2", + 3512: "aztec", + 3513: "arcpd", + 3514: "must-p2p", + 3515: "must-backplane", + 3516: "smartcard-port", + 3517: "802-11-iapp", + 3518: "artifact-msg", + 3519: "galileo", + 3520: "galileolog", + 3521: "mc3ss", + 3522: "nssocketport", + 3523: "odeumservlink", + 3524: "ecmport", + 3525: "eisport", + 3526: "starquiz-port", + 3527: "beserver-msg-q", + 3528: "jboss-iiop", + 3529: "jboss-iiop-ssl", + 3530: "gf", + 3531: "joltid", + 3532: "raven-rmp", + 3533: "raven-rdp", + 3534: "urld-port", + 3535: "ms-la", + 3536: "snac", + 3537: "ni-visa-remote", + 3538: "ibm-diradm", + 3539: "ibm-diradm-ssl", + 3540: "pnrp-port", + 3541: "voispeed-port", + 3542: "hacl-monitor", + 3543: "qftest-lookup", + 3544: "teredo", + 3545: "camac", + 3547: "symantec-sim", + 3548: "interworld", + 3549: "tellumat-nms", + 3550: "ssmpp", + 3551: "apcupsd", + 3552: "taserver", + 3553: "rbr-discovery", + 3554: "questnotify", + 3555: "razor", + 3556: "sky-transport", + 3557: "personalos-001", + 3558: "mcp-port", + 3559: "cctv-port", + 3560: "iniserve-port", + 3561: "bmc-onekey", + 3562: "sdbproxy", + 3563: "watcomdebug", + 3564: "esimport", + 3567: "enc-eps", + 3568: "enc-tunnel-sec", + 3569: "mbg-ctrl", + 3570: "mccwebsvr-port", + 3571: "megardsvr-port", + 3572: "megaregsvrport", + 3573: "tag-ups-1", + 3574: "dmaf-caster", + 3575: "ccm-port", + 3576: "cmc-port", + 3577: "config-port", + 3578: "data-port", + 3579: "ttat3lb", + 3580: "nati-svrloc", + 3581: "kfxaclicensing", + 3582: "press", + 3583: "canex-watch", + 3584: "u-dbap", + 3585: "emprise-lls", + 3586: "emprise-lsc", + 3587: "p2pgroup", + 3588: "sentinel", + 3589: "isomair", + 3590: "wv-csp-sms", + 3591: "gtrack-server", + 3592: "gtrack-ne", + 3593: "bpmd", + 3594: "mediaspace", + 3595: "shareapp", + 3596: "iw-mmogame", + 3597: "a14", + 3598: "a15", + 3599: "quasar-server", + 3600: "trap-daemon", + 3601: "visinet-gui", + 3602: "infiniswitchcl", + 3603: "int-rcv-cntrl", + 3604: "bmc-jmx-port", + 3605: "comcam-io", + 3606: "splitlock", + 3607: "precise-i3", + 3608: "trendchip-dcp", + 3609: "cpdi-pidas-cm", + 3610: "echonet", + 3611: "six-degrees", + 3612: "hp-dataprotect", + 3613: "alaris-disc", + 3614: "sigma-port", + 3615: "start-network", + 3616: "cd3o-protocol", + 3617: "sharp-server", + 3618: "aairnet-1", + 3619: "aairnet-2", + 3620: "ep-pcp", + 3621: "ep-nsp", + 3622: "ff-lr-port", + 3623: "haipe-discover", + 3624: "dist-upgrade", + 3625: "volley", + 3626: "bvcdaemon-port", + 3627: "jamserverport", + 3628: "ept-machine", + 3629: "escvpnet", + 3630: "cs-remote-db", + 3631: "cs-services", + 3632: "distcc", + 3633: "wacp", + 3634: "hlibmgr", + 3635: "sdo", + 3636: "servistaitsm", + 3637: "scservp", + 3638: "ehp-backup", + 3639: "xap-ha", + 3640: "netplay-port1", + 3641: "netplay-port2", + 3642: "juxml-port", + 3643: "audiojuggler", + 3644: "ssowatch", + 3645: "cyc", + 3646: "xss-srv-port", + 3647: "splitlock-gw", + 3648: "fjcp", + 3649: "nmmp", + 3650: "prismiq-plugin", + 3651: "xrpc-registry", + 3652: "vxcrnbuport", + 3653: "tsp", + 3654: "vaprtm", + 3655: "abatemgr", + 3656: "abatjss", + 3657: "immedianet-bcn", + 3658: "ps-ams", + 3659: "apple-sasl", + 3660: "can-nds-ssl", + 3661: "can-ferret-ssl", + 3662: "pserver", + 3663: "dtp", + 3664: "ups-engine", + 3665: "ent-engine", + 3666: "eserver-pap", + 3667: "infoexch", + 3668: "dell-rm-port", + 3669: "casanswmgmt", + 3670: "smile", + 3671: "efcp", + 3672: "lispworks-orb", + 3673: "mediavault-gui", + 3674: "wininstall-ipc", + 3675: "calltrax", + 3676: "va-pacbase", + 3677: "roverlog", + 3678: "ipr-dglt", + 3679: "Escale (Newton Dock)", + 3680: "npds-tracker", + 3681: "bts-x73", + 3682: "cas-mapi", + 3683: "bmc-ea", + 3684: "faxstfx-port", + 3685: "dsx-agent", + 3686: "tnmpv2", + 3687: "simple-push", + 3688: "simple-push-s", + 3689: "daap", + 3690: "svn", + 3691: "magaya-network", + 3692: "intelsync", + 3695: "bmc-data-coll", + 3696: "telnetcpcd", + 3697: "nw-license", + 3698: "sagectlpanel", + 3699: "kpn-icw", + 3700: "lrs-paging", + 3701: "netcelera", + 3702: "ws-discovery", + 3703: "adobeserver-3", + 3704: "adobeserver-4", + 3705: "adobeserver-5", + 3706: "rt-event", + 3707: "rt-event-s", + 3708: "sun-as-iiops", + 3709: "ca-idms", + 3710: "portgate-auth", + 3711: "edb-server2", + 3712: "sentinel-ent", + 3713: "tftps", + 3714: "delos-dms", + 3715: "anoto-rendezv", + 3716: "wv-csp-sms-cir", + 3717: "wv-csp-udp-cir", + 3718: "opus-services", + 3719: "itelserverport", + 3720: "ufastro-instr", + 3721: "xsync", + 3722: "xserveraid", + 3723: "sychrond", + 3724: "blizwow", + 3725: "na-er-tip", + 3726: "array-manager", + 3727: "e-mdu", + 3728: "e-woa", + 3729: "fksp-audit", + 3730: "client-ctrl", + 3731: "smap", + 3732: "m-wnn", + 3733: "multip-msg", + 3734: "synel-data", + 3735: "pwdis", + 3736: "rs-rmi", + 3738: "versatalk", + 3739: "launchbird-lm", + 3740: "heartbeat", + 3741: "wysdma", + 3742: "cst-port", + 3743: "ipcs-command", + 3744: "sasg", + 3745: "gw-call-port", + 3746: "linktest", + 3747: "linktest-s", + 3748: "webdata", + 3749: "cimtrak", + 3750: "cbos-ip-port", + 3751: "gprs-cube", + 3752: "vipremoteagent", + 3753: "nattyserver", + 3754: "timestenbroker", + 3755: "sas-remote-hlp", + 3756: "canon-capt", + 3757: "grf-port", + 3758: "apw-registry", + 3759: "exapt-lmgr", + 3760: "adtempusclient", + 3761: "gsakmp", + 3762: "gbs-smp", + 3763: "xo-wave", + 3764: "mni-prot-rout", + 3765: "rtraceroute", + 3767: "listmgr-port", + 3768: "rblcheckd", + 3769: "haipe-otnk", + 3770: "cindycollab", + 3771: "paging-port", + 3772: "ctp", + 3773: "ctdhercules", + 3774: "zicom", + 3775: "ispmmgr", + 3776: "dvcprov-port", + 3777: "jibe-eb", + 3778: "c-h-it-port", + 3779: "cognima", + 3780: "nnp", + 3781: "abcvoice-port", + 3782: "iso-tp0s", + 3783: "bim-pem", + 3784: "bfd-control", + 3785: "bfd-echo", + 3786: "upstriggervsw", + 3787: "fintrx", + 3788: "isrp-port", + 3789: "remotedeploy", + 3790: "quickbooksrds", + 3791: "tvnetworkvideo", + 3792: "sitewatch", + 3793: "dcsoftware", + 3794: "jaus", + 3795: "myblast", + 3796: "spw-dialer", + 3797: "idps", + 3798: "minilock", + 3799: "radius-dynauth", + 3800: "pwgpsi", + 3801: "ibm-mgr", + 3802: "vhd", + 3803: "soniqsync", + 3804: "iqnet-port", + 3805: "tcpdataserver", + 3806: "wsmlb", + 3807: "spugna", + 3808: "sun-as-iiops-ca", + 3809: "apocd", + 3810: "wlanauth", + 3811: "amp", + 3812: "neto-wol-server", + 3813: "rap-ip", + 3814: "neto-dcs", + 3815: "lansurveyorxml", + 3816: "sunlps-http", + 3817: "tapeware", + 3818: "crinis-hb", + 3819: "epl-slp", + 3820: "scp", + 3821: "pmcp", + 3822: "acp-discovery", + 3823: "acp-conduit", + 3824: "acp-policy", + 3825: "ffserver", + 3826: "warmux", + 3827: "netmpi", + 3828: "neteh", + 3829: "neteh-ext", + 3830: "cernsysmgmtagt", + 3831: "dvapps", + 3832: "xxnetserver", + 3833: "aipn-auth", + 3834: "spectardata", + 3835: "spectardb", + 3836: "markem-dcp", + 3837: "mkm-discovery", + 3838: "sos", + 3839: "amx-rms", + 3840: "flirtmitmir", + 3842: "nhci", + 3843: "quest-agent", + 3844: "rnm", + 3845: "v-one-spp", + 3846: "an-pcp", + 3847: "msfw-control", + 3848: "item", + 3849: "spw-dnspreload", + 3850: "qtms-bootstrap", + 3851: "spectraport", + 3852: "sse-app-config", + 3853: "sscan", + 3854: "stryker-com", + 3855: "opentrac", + 3856: "informer", + 3857: "trap-port", + 3858: "trap-port-mom", + 3859: "nav-port", + 3860: "sasp", + 3861: "winshadow-hd", + 3862: "giga-pocket", + 3863: "asap-udp", + 3865: "xpl", + 3866: "dzdaemon", + 3867: "dzoglserver", + 3869: "ovsam-mgmt", + 3870: "ovsam-d-agent", + 3871: "avocent-adsap", + 3872: "oem-agent", + 3873: "fagordnc", + 3874: "sixxsconfig", + 3875: "pnbscada", + 3876: "dl-agent", + 3877: "xmpcr-interface", + 3878: "fotogcad", + 3879: "appss-lm", + 3880: "igrs", + 3881: "idac", + 3882: "msdts1", + 3883: "vrpn", + 3884: "softrack-meter", + 3885: "topflow-ssl", + 3886: "nei-management", + 3887: "ciphire-data", + 3888: "ciphire-serv", + 3889: "dandv-tester", + 3890: "ndsconnect", + 3891: "rtc-pm-port", + 3892: "pcc-image-port", + 3893: "cgi-starapi", + 3894: "syam-agent", + 3895: "syam-smc", + 3896: "sdo-tls", + 3897: "sdo-ssh", + 3898: "senip", + 3899: "itv-control", + 3900: "udt-os", + 3901: "nimsh", + 3902: "nimaux", + 3903: "charsetmgr", + 3904: "omnilink-port", + 3905: "mupdate", + 3906: "topovista-data", + 3907: "imoguia-port", + 3908: "hppronetman", + 3909: "surfcontrolcpa", + 3910: "prnrequest", + 3911: "prnstatus", + 3912: "gbmt-stars", + 3913: "listcrt-port", + 3914: "listcrt-port-2", + 3915: "agcat", + 3916: "wysdmc", + 3917: "aftmux", + 3918: "pktcablemmcops", + 3919: "hyperip", + 3920: "exasoftport1", + 3921: "herodotus-net", + 3922: "sor-update", + 3923: "symb-sb-port", + 3924: "mpl-gprs-port", + 3925: "zmp", + 3926: "winport", + 3927: "natdataservice", + 3928: "netboot-pxe", + 3929: "smauth-port", + 3930: "syam-webserver", + 3931: "msr-plugin-port", + 3932: "dyn-site", + 3933: "plbserve-port", + 3934: "sunfm-port", + 3935: "sdp-portmapper", + 3936: "mailprox", + 3937: "dvbservdsc", + 3938: "dbcontrol-agent", + 3939: "aamp", + 3940: "xecp-node", + 3941: "homeportal-web", + 3942: "srdp", + 3943: "tig", + 3944: "sops", + 3945: "emcads", + 3946: "backupedge", + 3947: "ccp", + 3948: "apdap", + 3949: "drip", + 3950: "namemunge", + 3951: "pwgippfax", + 3952: "i3-sessionmgr", + 3953: "xmlink-connect", + 3954: "adrep", + 3955: "p2pcommunity", + 3956: "gvcp", + 3957: "mqe-broker", + 3958: "mqe-agent", + 3959: "treehopper", + 3960: "bess", + 3961: "proaxess", + 3962: "sbi-agent", + 3963: "thrp", + 3964: "sasggprs", + 3965: "ati-ip-to-ncpe", + 3966: "bflckmgr", + 3967: "ppsms", + 3968: "ianywhere-dbns", + 3969: "landmarks", + 3970: "lanrevagent", + 3971: "lanrevserver", + 3972: "iconp", + 3973: "progistics", + 3974: "citysearch", + 3975: "airshot", + 3976: "opswagent", + 3977: "opswmanager", + 3978: "secure-cfg-svr", + 3979: "smwan", + 3980: "acms", + 3981: "starfish", + 3982: "eis", + 3983: "eisp", + 3984: "mapper-nodemgr", + 3985: "mapper-mapethd", + 3986: "mapper-ws-ethd", + 3987: "centerline", + 3988: "dcs-config", + 3989: "bv-queryengine", + 3990: "bv-is", + 3991: "bv-smcsrv", + 3992: "bv-ds", + 3993: "bv-agent", + 3995: "iss-mgmt-ssl", + 3996: "abcsoftware", + 3997: "agentsease-db", + 3998: "dnx", + 3999: "nvcnet", + 4000: "terabase", + 4001: "newoak", + 4002: "pxc-spvr-ft", + 4003: "pxc-splr-ft", + 4004: "pxc-roid", + 4005: "pxc-pin", + 4006: "pxc-spvr", + 4007: "pxc-splr", + 4008: "netcheque", + 4009: "chimera-hwm", + 4010: "samsung-unidex", + 4011: "altserviceboot", + 4012: "pda-gate", + 4013: "acl-manager", + 4014: "taiclock", + 4015: "talarian-mcast1", + 4016: "talarian-mcast2", + 4017: "talarian-mcast3", + 4018: "talarian-mcast4", + 4019: "talarian-mcast5", + 4020: "trap", + 4021: "nexus-portal", + 4022: "dnox", + 4023: "esnm-zoning", + 4024: "tnp1-port", + 4025: "partimage", + 4026: "as-debug", + 4027: "bxp", + 4028: "dtserver-port", + 4029: "ip-qsig", + 4030: "jdmn-port", + 4031: "suucp", + 4032: "vrts-auth-port", + 4033: "sanavigator", + 4034: "ubxd", + 4035: "wap-push-http", + 4036: "wap-push-https", + 4037: "ravehd", + 4038: "fazzt-ptp", + 4039: "fazzt-admin", + 4040: "yo-main", + 4041: "houston", + 4042: "ldxp", + 4043: "nirp", + 4044: "ltp", + 4045: "npp", + 4046: "acp-proto", + 4047: "ctp-state", + 4049: "wafs", + 4050: "cisco-wafs", + 4051: "cppdp", + 4052: "interact", + 4053: "ccu-comm-1", + 4054: "ccu-comm-2", + 4055: "ccu-comm-3", + 4056: "lms", + 4057: "wfm", + 4058: "kingfisher", + 4059: "dlms-cosem", + 4060: "dsmeter-iatc", + 4061: "ice-location", + 4062: "ice-slocation", + 4063: "ice-router", + 4064: "ice-srouter", + 4065: "avanti-cdp", + 4066: "pmas", + 4067: "idp", + 4068: "ipfltbcst", + 4069: "minger", + 4070: "tripe", + 4071: "aibkup", + 4072: "zieto-sock", + 4073: "iRAPP", + 4074: "cequint-cityid", + 4075: "perimlan", + 4076: "seraph", + 4077: "ascomalarm", + 4079: "santools", + 4080: "lorica-in", + 4081: "lorica-in-sec", + 4082: "lorica-out", + 4083: "lorica-out-sec", + 4084: "fortisphere-vm", + 4086: "ftsync", + 4089: "opencore", + 4090: "omasgport", + 4091: "ewinstaller", + 4092: "ewdgs", + 4093: "pvxpluscs", + 4094: "sysrqd", + 4095: "xtgui", + 4096: "bre", + 4097: "patrolview", + 4098: "drmsfsd", + 4099: "dpcp", + 4100: "igo-incognito", + 4101: "brlp-0", + 4102: "brlp-1", + 4103: "brlp-2", + 4104: "brlp-3", + 4105: "shofar", + 4106: "synchronite", + 4107: "j-ac", + 4108: "accel", + 4109: "izm", + 4110: "g2tag", + 4111: "xgrid", + 4112: "apple-vpns-rp", + 4113: "aipn-reg", + 4114: "jomamqmonitor", + 4115: "cds", + 4116: "smartcard-tls", + 4117: "hillrserv", + 4118: "netscript", + 4119: "assuria-slm", + 4121: "e-builder", + 4122: "fprams", + 4123: "z-wave", + 4124: "tigv2", + 4125: "opsview-envoy", + 4126: "ddrepl", + 4127: "unikeypro", + 4128: "nufw", + 4129: "nuauth", + 4130: "fronet", + 4131: "stars", + 4132: "nuts-dem", + 4133: "nuts-bootp", + 4134: "nifty-hmi", + 4135: "cl-db-attach", + 4136: "cl-db-request", + 4137: "cl-db-remote", + 4138: "nettest", + 4139: "thrtx", + 4140: "cedros-fds", + 4141: "oirtgsvc", + 4142: "oidocsvc", + 4143: "oidsr", + 4145: "vvr-control", + 4146: "tgcconnect", + 4147: "vrxpservman", + 4148: "hhb-handheld", + 4149: "agslb", + 4150: "PowerAlert-nsa", + 4151: "menandmice-noh", + 4152: "idig-mux", + 4153: "mbl-battd", + 4154: "atlinks", + 4155: "bzr", + 4156: "stat-results", + 4157: "stat-scanner", + 4158: "stat-cc", + 4159: "nss", + 4160: "jini-discovery", + 4161: "omscontact", + 4162: "omstopology", + 4163: "silverpeakpeer", + 4164: "silverpeakcomm", + 4165: "altcp", + 4166: "joost", + 4167: "ddgn", + 4168: "pslicser", + 4169: "iadt-disc", + 4172: "pcoip", + 4173: "mma-discovery", + 4174: "sm-disc", + 4177: "wello", + 4178: "storman", + 4179: "MaxumSP", + 4180: "httpx", + 4181: "macbak", + 4182: "pcptcpservice", + 4183: "gmmp", + 4184: "universe-suite", + 4185: "wcpp", + 4188: "vatata", + 4191: "dsmipv6", + 4192: "azeti-bd", + 4199: "eims-admin", + 4300: "corelccam", + 4301: "d-data", + 4302: "d-data-control", + 4303: "srcp", + 4304: "owserver", + 4305: "batman", + 4306: "pinghgl", + 4307: "visicron-vs", + 4308: "compx-lockview", + 4309: "dserver", + 4310: "mirrtex", + 4320: "fdt-rcatp", + 4321: "rwhois", + 4322: "trim-event", + 4323: "trim-ice", + 4324: "balour", + 4325: "geognosisman", + 4326: "geognosis", + 4327: "jaxer-web", + 4328: "jaxer-manager", + 4333: "ahsp", + 4340: "gaia", + 4341: "lisp-data", + 4342: "lisp-control", + 4343: "unicall", + 4344: "vinainstall", + 4345: "m4-network-as", + 4346: "elanlm", + 4347: "lansurveyor", + 4348: "itose", + 4349: "fsportmap", + 4350: "net-device", + 4351: "plcy-net-svcs", + 4352: "pjlink", + 4353: "f5-iquery", + 4354: "qsnet-trans", + 4355: "qsnet-workst", + 4356: "qsnet-assist", + 4357: "qsnet-cond", + 4358: "qsnet-nucl", + 4359: "omabcastltkm", + 4361: "nacnl", + 4362: "afore-vdp-disc", + 4368: "wxbrief", + 4369: "epmd", + 4370: "elpro-tunnel", + 4371: "l2c-disc", + 4372: "l2c-data", + 4373: "remctl", + 4375: "tolteces", + 4376: "bip", + 4377: "cp-spxsvr", + 4378: "cp-spxdpy", + 4379: "ctdb", + 4389: "xandros-cms", + 4390: "wiegand", + 4394: "apwi-disc", + 4395: "omnivisionesx", + 4400: "ds-srv", + 4401: "ds-srvr", + 4402: "ds-clnt", + 4403: "ds-user", + 4404: "ds-admin", + 4405: "ds-mail", + 4406: "ds-slp", + 4425: "netrockey6", + 4426: "beacon-port-2", + 4430: "rsqlserver", + 4432: "l-acoustics", + 4441: "netblox", + 4442: "saris", + 4443: "pharos", + 4444: "krb524", + 4445: "upnotifyp", + 4446: "n1-fwp", + 4447: "n1-rmgmt", + 4448: "asc-slmd", + 4449: "privatewire", + 4450: "camp", + 4451: "ctisystemmsg", + 4452: "ctiprogramload", + 4453: "nssalertmgr", + 4454: "nssagentmgr", + 4455: "prchat-user", + 4456: "prchat-server", + 4457: "prRegister", + 4458: "mcp", + 4484: "hpssmgmt", + 4486: "icms", + 4488: "awacs-ice", + 4500: "ipsec-nat-t", + 4534: "armagetronad", + 4535: "ehs", + 4536: "ehs-ssl", + 4537: "wssauthsvc", + 4538: "swx-gate", + 4545: "worldscores", + 4546: "sf-lm", + 4547: "lanner-lm", + 4548: "synchromesh", + 4549: "aegate", + 4550: "gds-adppiw-db", + 4551: "ieee-mih", + 4552: "menandmice-mon", + 4554: "msfrs", + 4555: "rsip", + 4556: "dtn-bundle", + 4557: "mtcevrunqss", + 4558: "mtcevrunqman", + 4559: "hylafax", + 4566: "kwtc", + 4567: "tram", + 4568: "bmc-reporting", + 4569: "iax", + 4591: "l3t-at-an", + 4592: "hrpd-ith-at-an", + 4593: "ipt-anri-anri", + 4594: "ias-session", + 4595: "ias-paging", + 4596: "ias-neighbor", + 4597: "a21-an-1xbs", + 4598: "a16-an-an", + 4599: "a17-an-an", + 4600: "piranha1", + 4601: "piranha2", + 4658: "playsta2-app", + 4659: "playsta2-lob", + 4660: "smaclmgr", + 4661: "kar2ouche", + 4662: "oms", + 4663: "noteit", + 4664: "ems", + 4665: "contclientms", + 4666: "eportcomm", + 4667: "mmacomm", + 4668: "mmaeds", + 4669: "eportcommdata", + 4670: "light", + 4671: "acter", + 4672: "rfa", + 4673: "cxws", + 4674: "appiq-mgmt", + 4675: "dhct-status", + 4676: "dhct-alerts", + 4677: "bcs", + 4678: "traversal", + 4679: "mgesupervision", + 4680: "mgemanagement", + 4681: "parliant", + 4682: "finisar", + 4683: "spike", + 4684: "rfid-rp1", + 4685: "autopac", + 4686: "msp-os", + 4687: "nst", + 4688: "mobile-p2p", + 4689: "altovacentral", + 4690: "prelude", + 4691: "mtn", + 4692: "conspiracy", + 4700: "netxms-agent", + 4701: "netxms-mgmt", + 4702: "netxms-sync", + 4725: "truckstar", + 4726: "a26-fap-fgw", + 4727: "fcis-disc", + 4728: "capmux", + 4729: "gsmtap", + 4730: "gearman", + 4732: "ohmtrigger", + 4737: "ipdr-sp", + 4738: "solera-lpn", + 4739: "ipfix", + 4740: "ipfixs", + 4741: "lumimgrd", + 4742: "sicct-sdp", + 4743: "openhpid", + 4744: "ifsp", + 4745: "fmp", + 4747: "buschtrommel", + 4749: "profilemac", + 4750: "ssad", + 4751: "spocp", + 4752: "snap", + 4753: "simon-disc", + 4784: "bfd-multi-ctl", + 4785: "cncp", + 4789: "vxlan", + 4790: "vxlan-gpe", + 4800: "iims", + 4801: "iwec", + 4802: "ilss", + 4803: "notateit-disc", + 4804: "aja-ntv4-disc", + 4827: "htcp", + 4837: "varadero-0", + 4838: "varadero-1", + 4839: "varadero-2", + 4840: "opcua-udp", + 4841: "quosa", + 4842: "gw-asv", + 4843: "opcua-tls", + 4844: "gw-log", + 4845: "wcr-remlib", + 4846: "contamac-icm", + 4847: "wfc", + 4848: "appserv-http", + 4849: "appserv-https", + 4850: "sun-as-nodeagt", + 4851: "derby-repli", + 4867: "unify-debug", + 4868: "phrelay", + 4869: "phrelaydbg", + 4870: "cc-tracking", + 4871: "wired", + 4876: "tritium-can", + 4877: "lmcs", + 4878: "inst-discovery", + 4881: "socp-t", + 4882: "socp-c", + 4884: "hivestor", + 4885: "abbs", + 4894: "lyskom", + 4899: "radmin-port", + 4900: "hfcs", + 4914: "bones", + 4936: "an-signaling", + 4937: "atsc-mh-ssc", + 4940: "eq-office-4940", + 4941: "eq-office-4941", + 4942: "eq-office-4942", + 4949: "munin", + 4950: "sybasesrvmon", + 4951: "pwgwims", + 4952: "sagxtsds", + 4969: "ccss-qmm", + 4970: "ccss-qsm", + 4986: "mrip", + 4987: "smar-se-port1", + 4988: "smar-se-port2", + 4989: "parallel", + 4990: "busycal", + 4991: "vrt", + 4999: "hfcs-manager", + 5000: "commplex-main", + 5001: "commplex-link", + 5002: "rfe", + 5003: "fmpro-internal", + 5004: "avt-profile-1", + 5005: "avt-profile-2", + 5006: "wsm-server", + 5007: "wsm-server-ssl", + 5008: "synapsis-edge", + 5009: "winfs", + 5010: "telelpathstart", + 5011: "telelpathattack", + 5012: "nsp", + 5013: "fmpro-v6", + 5014: "onpsocket", + 5020: "zenginkyo-1", + 5021: "zenginkyo-2", + 5022: "mice", + 5023: "htuilsrv", + 5024: "scpi-telnet", + 5025: "scpi-raw", + 5026: "strexec-d", + 5027: "strexec-s", + 5029: "infobright", + 5030: "surfpass", + 5031: "dmp", + 5042: "asnaacceler8db", + 5043: "swxadmin", + 5044: "lxi-evntsvc", + 5046: "vpm-udp", + 5047: "iscape", + 5049: "ivocalize", + 5050: "mmcc", + 5051: "ita-agent", + 5052: "ita-manager", + 5053: "rlm-disc", + 5055: "unot", + 5056: "intecom-ps1", + 5057: "intecom-ps2", + 5058: "locus-disc", + 5059: "sds", + 5060: "sip", + 5061: "sips", + 5062: "na-localise", + 5064: "ca-1", + 5065: "ca-2", + 5066: "stanag-5066", + 5067: "authentx", + 5069: "i-net-2000-npr", + 5070: "vtsas", + 5071: "powerschool", + 5072: "ayiya", + 5073: "tag-pm", + 5074: "alesquery", + 5078: "pixelpusher", + 5079: "cp-spxrpts", + 5080: "onscreen", + 5081: "sdl-ets", + 5082: "qcp", + 5083: "qfp", + 5084: "llrp", + 5085: "encrypted-llrp", + 5092: "magpie", + 5093: "sentinel-lm", + 5094: "hart-ip", + 5099: "sentlm-srv2srv", + 5100: "socalia", + 5101: "talarian-udp", + 5102: "oms-nonsecure", + 5104: "tinymessage", + 5105: "hughes-ap", + 5111: "taep-as-svc", + 5112: "pm-cmdsvr", + 5116: "emb-proj-cmd", + 5120: "barracuda-bbs", + 5133: "nbt-pc", + 5136: "minotaur-sa", + 5137: "ctsd", + 5145: "rmonitor-secure", + 5150: "atmp", + 5151: "esri-sde", + 5152: "sde-discovery", + 5154: "bzflag", + 5155: "asctrl-agent", + 5164: "vpa-disc", + 5165: "ife-icorp", + 5166: "winpcs", + 5167: "scte104", + 5168: "scte30", + 5190: "aol", + 5191: "aol-1", + 5192: "aol-2", + 5193: "aol-3", + 5200: "targus-getdata", + 5201: "targus-getdata1", + 5202: "targus-getdata2", + 5203: "targus-getdata3", + 5223: "hpvirtgrp", + 5224: "hpvirtctrl", + 5225: "hp-server", + 5226: "hp-status", + 5227: "perfd", + 5234: "eenet", + 5235: "galaxy-network", + 5236: "padl2sim", + 5237: "mnet-discovery", + 5245: "downtools-disc", + 5246: "capwap-control", + 5247: "capwap-data", + 5248: "caacws", + 5249: "caaclang2", + 5250: "soagateway", + 5251: "caevms", + 5252: "movaz-ssc", + 5264: "3com-njack-1", + 5265: "3com-njack-2", + 5270: "cartographerxmp", + 5271: "cuelink-disc", + 5272: "pk", + 5282: "transmit-port", + 5298: "presence", + 5299: "nlg-data", + 5300: "hacl-hb", + 5301: "hacl-gs", + 5302: "hacl-cfg", + 5303: "hacl-probe", + 5304: "hacl-local", + 5305: "hacl-test", + 5306: "sun-mc-grp", + 5307: "sco-aip", + 5308: "cfengine", + 5309: "jprinter", + 5310: "outlaws", + 5312: "permabit-cs", + 5313: "rrdp", + 5314: "opalis-rbt-ipc", + 5315: "hacl-poll", + 5343: "kfserver", + 5344: "xkotodrcp", + 5349: "stuns", + 5350: "pcp-multicast", + 5351: "pcp", + 5352: "dns-llq", + 5353: "mdns", + 5354: "mdnsresponder", + 5355: "llmnr", + 5356: "ms-smlbiz", + 5357: "wsdapi", + 5358: "wsdapi-s", + 5359: "ms-alerter", + 5360: "ms-sideshow", + 5361: "ms-s-sideshow", + 5362: "serverwsd2", + 5363: "net-projection", + 5364: "kdnet", + 5397: "stresstester", + 5398: "elektron-admin", + 5399: "securitychase", + 5400: "excerpt", + 5401: "excerpts", + 5402: "mftp", + 5403: "hpoms-ci-lstn", + 5404: "hpoms-dps-lstn", + 5405: "netsupport", + 5406: "systemics-sox", + 5407: "foresyte-clear", + 5408: "foresyte-sec", + 5409: "salient-dtasrv", + 5410: "salient-usrmgr", + 5411: "actnet", + 5412: "continuus", + 5413: "wwiotalk", + 5414: "statusd", + 5415: "ns-server", + 5416: "sns-gateway", + 5417: "sns-agent", + 5418: "mcntp", + 5419: "dj-ice", + 5420: "cylink-c", + 5421: "netsupport2", + 5422: "salient-mux", + 5423: "virtualuser", + 5424: "beyond-remote", + 5425: "br-channel", + 5426: "devbasic", + 5427: "sco-peer-tta", + 5428: "telaconsole", + 5429: "base", + 5430: "radec-corp", + 5431: "park-agent", + 5432: "postgresql", + 5433: "pyrrho", + 5434: "sgi-arrayd", + 5435: "sceanics", + 5436: "pmip6-cntl", + 5437: "pmip6-data", + 5443: "spss", + 5453: "surebox", + 5454: "apc-5454", + 5455: "apc-5455", + 5456: "apc-5456", + 5461: "silkmeter", + 5462: "ttl-publisher", + 5463: "ttlpriceproxy", + 5464: "quailnet", + 5465: "netops-broker", + 5500: "fcp-addr-srvr1", + 5501: "fcp-addr-srvr2", + 5502: "fcp-srvr-inst1", + 5503: "fcp-srvr-inst2", + 5504: "fcp-cics-gw1", + 5505: "checkoutdb", + 5506: "amc", + 5553: "sgi-eventmond", + 5554: "sgi-esphttp", + 5555: "personal-agent", + 5556: "freeciv", + 5567: "enc-eps-mc-sec", + 5568: "sdt", + 5569: "rdmnet-device", + 5573: "sdmmp", + 5580: "tmosms0", + 5581: "tmosms1", + 5582: "fac-restore", + 5583: "tmo-icon-sync", + 5584: "bis-web", + 5585: "bis-sync", + 5597: "ininmessaging", + 5598: "mctfeed", + 5599: "esinstall", + 5600: "esmmanager", + 5601: "esmagent", + 5602: "a1-msc", + 5603: "a1-bs", + 5604: "a3-sdunode", + 5605: "a4-sdunode", + 5627: "ninaf", + 5628: "htrust", + 5629: "symantec-sfdb", + 5630: "precise-comm", + 5631: "pcanywheredata", + 5632: "pcanywherestat", + 5633: "beorl", + 5634: "xprtld", + 5670: "zre-disc", + 5671: "amqps", + 5672: "amqp", + 5673: "jms", + 5674: "hyperscsi-port", + 5675: "v5ua", + 5676: "raadmin", + 5677: "questdb2-lnchr", + 5678: "rrac", + 5679: "dccm", + 5680: "auriga-router", + 5681: "ncxcp", + 5682: "brightcore", + 5683: "coap", + 5684: "coaps", + 5687: "gog-multiplayer", + 5688: "ggz", + 5689: "qmvideo", + 5713: "proshareaudio", + 5714: "prosharevideo", + 5715: "prosharedata", + 5716: "prosharerequest", + 5717: "prosharenotify", + 5718: "dpm", + 5719: "dpm-agent", + 5720: "ms-licensing", + 5721: "dtpt", + 5722: "msdfsr", + 5723: "omhs", + 5724: "omsdk", + 5728: "io-dist-group", + 5729: "openmail", + 5730: "unieng", + 5741: "ida-discover1", + 5742: "ida-discover2", + 5743: "watchdoc-pod", + 5744: "watchdoc", + 5745: "fcopy-server", + 5746: "fcopys-server", + 5747: "tunatic", + 5748: "tunalyzer", + 5750: "rscd", + 5755: "openmailg", + 5757: "x500ms", + 5766: "openmailns", + 5767: "s-openmail", + 5768: "openmailpxy", + 5769: "spramsca", + 5770: "spramsd", + 5771: "netagent", + 5777: "dali-port", + 5781: "3par-evts", + 5782: "3par-mgmt", + 5783: "3par-mgmt-ssl", + 5784: "ibar", + 5785: "3par-rcopy", + 5786: "cisco-redu", + 5787: "waascluster", + 5793: "xtreamx", + 5794: "spdp", + 5813: "icmpd", + 5814: "spt-automation", + 5859: "wherehoo", + 5863: "ppsuitemsg", + 5900: "rfb", + 5910: "cm", + 5911: "cpdlc", + 5912: "fis", + 5913: "ads-c", + 5963: "indy", + 5968: "mppolicy-v5", + 5969: "mppolicy-mgr", + 5984: "couchdb", + 5985: "wsman", + 5986: "wsmans", + 5987: "wbem-rmi", + 5988: "wbem-http", + 5989: "wbem-https", + 5990: "wbem-exp-https", + 5991: "nuxsl", + 5992: "consul-insight", + 5999: "cvsup", + 6064: "ndl-ahp-svc", + 6065: "winpharaoh", + 6066: "ewctsp", + 6069: "trip", + 6070: "messageasap", + 6071: "ssdtp", + 6072: "diagnose-proc", + 6073: "directplay8", + 6074: "max", + 6081: "geneve", + 6082: "p25cai", + 6083: "miami-bcast", + 6085: "konspire2b", + 6086: "pdtp", + 6087: "ldss", + 6088: "doglms-notify", + 6100: "synchronet-db", + 6101: "synchronet-rtc", + 6102: "synchronet-upd", + 6103: "rets", + 6104: "dbdb", + 6105: "primaserver", + 6106: "mpsserver", + 6107: "etc-control", + 6108: "sercomm-scadmin", + 6109: "globecast-id", + 6110: "softcm", + 6111: "spc", + 6112: "dtspcd", + 6118: "tipc", + 6122: "bex-webadmin", + 6123: "backup-express", + 6124: "pnbs", + 6133: "nbt-wol", + 6140: "pulsonixnls", + 6141: "meta-corp", + 6142: "aspentec-lm", + 6143: "watershed-lm", + 6144: "statsci1-lm", + 6145: "statsci2-lm", + 6146: "lonewolf-lm", + 6147: "montage-lm", + 6148: "ricardo-lm", + 6149: "tal-pod", + 6160: "ecmp-data", + 6161: "patrol-ism", + 6162: "patrol-coll", + 6163: "pscribe", + 6200: "lm-x", + 6201: "thermo-calc", + 6222: "radmind", + 6241: "jeol-nsddp-1", + 6242: "jeol-nsddp-2", + 6243: "jeol-nsddp-3", + 6244: "jeol-nsddp-4", + 6251: "tl1-raw-ssl", + 6252: "tl1-ssh", + 6253: "crip", + 6268: "grid", + 6269: "grid-alt", + 6300: "bmc-grx", + 6301: "bmc-ctd-ldap", + 6306: "ufmp", + 6315: "scup-disc", + 6316: "abb-escp", + 6317: "nav-data", + 6320: "repsvc", + 6321: "emp-server1", + 6322: "emp-server2", + 6324: "hrd-ns-disc", + 6343: "sflow", + 6346: "gnutella-svc", + 6347: "gnutella-rtr", + 6350: "adap", + 6355: "pmcs", + 6360: "metaedit-mu", + 6363: "ndn", + 6370: "metaedit-se", + 6382: "metatude-mds", + 6389: "clariion-evr01", + 6390: "metaedit-ws", + 6417: "faxcomservice", + 6420: "nim-vdrshell", + 6421: "nim-wan", + 6443: "sun-sr-https", + 6444: "sge-qmaster", + 6445: "sge-execd", + 6446: "mysql-proxy", + 6455: "skip-cert-recv", + 6456: "skip-cert-send", + 6471: "lvision-lm", + 6480: "sun-sr-http", + 6481: "servicetags", + 6482: "ldoms-mgmt", + 6483: "SunVTS-RMI", + 6484: "sun-sr-jms", + 6485: "sun-sr-iiop", + 6486: "sun-sr-iiops", + 6487: "sun-sr-iiop-aut", + 6488: "sun-sr-jmx", + 6489: "sun-sr-admin", + 6500: "boks", + 6501: "boks-servc", + 6502: "boks-servm", + 6503: "boks-clntd", + 6505: "badm-priv", + 6506: "badm-pub", + 6507: "bdir-priv", + 6508: "bdir-pub", + 6509: "mgcs-mfp-port", + 6510: "mcer-port", + 6511: "dccp-udp", + 6514: "syslog-tls", + 6515: "elipse-rec", + 6543: "lds-distrib", + 6544: "lds-dump", + 6547: "apc-6547", + 6548: "apc-6548", + 6549: "apc-6549", + 6550: "fg-sysupdate", + 6551: "sum", + 6558: "xdsxdm", + 6566: "sane-port", + 6568: "rp-reputation", + 6579: "affiliate", + 6580: "parsec-master", + 6581: "parsec-peer", + 6582: "parsec-game", + 6583: "joaJewelSuite", + 6619: "odette-ftps", + 6620: "kftp-data", + 6621: "kftp", + 6622: "mcftp", + 6623: "ktelnet", + 6626: "wago-service", + 6627: "nexgen", + 6628: "afesc-mc", + 6633: "cisco-vpath-tun", + 6634: "mpls-pm", + 6653: "openflow", + 6657: "palcom-disc", + 6670: "vocaltec-gold", + 6671: "p4p-portal", + 6672: "vision-server", + 6673: "vision-elmd", + 6678: "vfbp-disc", + 6679: "osaut", + 6689: "tsa", + 6696: "babel", + 6701: "kti-icad-srvr", + 6702: "e-design-net", + 6703: "e-design-web", + 6714: "ibprotocol", + 6715: "fibotrader-com", + 6767: "bmc-perf-agent", + 6768: "bmc-perf-mgrd", + 6769: "adi-gxp-srvprt", + 6770: "plysrv-http", + 6771: "plysrv-https", + 6784: "bfd-lag", + 6785: "dgpf-exchg", + 6786: "smc-jmx", + 6787: "smc-admin", + 6788: "smc-http", + 6789: "smc-https", + 6790: "hnmp", + 6791: "hnm", + 6801: "acnet", + 6831: "ambit-lm", + 6841: "netmo-default", + 6842: "netmo-http", + 6850: "iccrushmore", + 6868: "acctopus-st", + 6888: "muse", + 6935: "ethoscan", + 6936: "xsmsvc", + 6946: "bioserver", + 6951: "otlp", + 6961: "jmact3", + 6962: "jmevt2", + 6963: "swismgr1", + 6964: "swismgr2", + 6965: "swistrap", + 6966: "swispol", + 6969: "acmsoda", + 6997: "MobilitySrv", + 6998: "iatp-highpri", + 6999: "iatp-normalpri", + 7000: "afs3-fileserver", + 7001: "afs3-callback", + 7002: "afs3-prserver", + 7003: "afs3-vlserver", + 7004: "afs3-kaserver", + 7005: "afs3-volser", + 7006: "afs3-errors", + 7007: "afs3-bos", + 7008: "afs3-update", + 7009: "afs3-rmtsys", + 7010: "ups-onlinet", + 7011: "talon-disc", + 7012: "talon-engine", + 7013: "microtalon-dis", + 7014: "microtalon-com", + 7015: "talon-webserver", + 7019: "doceri-view", + 7020: "dpserve", + 7021: "dpserveadmin", + 7022: "ctdp", + 7023: "ct2nmcs", + 7024: "vmsvc", + 7025: "vmsvc-2", + 7030: "op-probe", + 7040: "quest-disc", + 7070: "arcp", + 7071: "iwg1", + 7080: "empowerid", + 7095: "jdp-disc", + 7099: "lazy-ptop", + 7100: "font-service", + 7101: "elcn", + 7107: "aes-x170", + 7121: "virprot-lm", + 7128: "scenidm", + 7129: "scenccs", + 7161: "cabsm-comm", + 7162: "caistoragemgr", + 7163: "cacsambroker", + 7164: "fsr", + 7165: "doc-server", + 7166: "aruba-server", + 7169: "ccag-pib", + 7170: "nsrp", + 7171: "drm-production", + 7174: "clutild", + 7181: "janus-disc", + 7200: "fodms", + 7201: "dlip", + 7227: "ramp", + 7235: "aspcoordination", + 7262: "cnap", + 7272: "watchme-7272", + 7273: "oma-rlp", + 7274: "oma-rlp-s", + 7275: "oma-ulp", + 7276: "oma-ilp", + 7277: "oma-ilp-s", + 7278: "oma-dcdocbs", + 7279: "ctxlic", + 7280: "itactionserver1", + 7281: "itactionserver2", + 7282: "mzca-alert", + 7365: "lcm-server", + 7391: "mindfilesys", + 7392: "mrssrendezvous", + 7393: "nfoldman", + 7394: "fse", + 7395: "winqedit", + 7397: "hexarc", + 7400: "rtps-discovery", + 7401: "rtps-dd-ut", + 7402: "rtps-dd-mt", + 7410: "ionixnetmon", + 7411: "daqstream", + 7421: "mtportmon", + 7426: "pmdmgr", + 7427: "oveadmgr", + 7428: "ovladmgr", + 7429: "opi-sock", + 7430: "xmpv7", + 7431: "pmd", + 7437: "faximum", + 7443: "oracleas-https", + 7473: "rise", + 7491: "telops-lmd", + 7500: "silhouette", + 7501: "ovbus", + 7510: "ovhpas", + 7511: "pafec-lm", + 7542: "saratoga", + 7543: "atul", + 7544: "nta-ds", + 7545: "nta-us", + 7546: "cfs", + 7547: "cwmp", + 7548: "tidp", + 7549: "nls-tl", + 7550: "cloudsignaling", + 7560: "sncp", + 7566: "vsi-omega", + 7570: "aries-kfinder", + 7574: "coherence-disc", + 7588: "sun-lm", + 7624: "indi", + 7627: "soap-http", + 7628: "zen-pawn", + 7629: "xdas", + 7633: "pmdfmgt", + 7648: "cuseeme", + 7674: "imqtunnels", + 7675: "imqtunnel", + 7676: "imqbrokerd", + 7677: "sun-user-https", + 7680: "pando-pub", + 7689: "collaber", + 7697: "klio", + 7707: "sync-em7", + 7708: "scinet", + 7720: "medimageportal", + 7724: "nsdeepfreezectl", + 7725: "nitrogen", + 7726: "freezexservice", + 7727: "trident-data", + 7734: "smip", + 7738: "aiagent", + 7741: "scriptview", + 7743: "sstp-1", + 7744: "raqmon-pdu", + 7747: "prgp", + 7777: "cbt", + 7778: "interwise", + 7779: "vstat", + 7781: "accu-lmgr", + 7786: "minivend", + 7787: "popup-reminders", + 7789: "office-tools", + 7794: "q3ade", + 7797: "pnet-conn", + 7798: "pnet-enc", + 7799: "altbsdp", + 7800: "asr", + 7801: "ssp-client", + 7802: "vns-tp", + 7810: "rbt-wanopt", + 7845: "apc-7845", + 7846: "apc-7846", + 7872: "mipv6tls", + 7880: "pss", + 7887: "ubroker", + 7900: "mevent", + 7901: "tnos-sp", + 7902: "tnos-dp", + 7903: "tnos-dps", + 7913: "qo-secure", + 7932: "t2-drm", + 7933: "t2-brm", + 7962: "generalsync", + 7967: "supercell", + 7979: "micromuse-ncps", + 7980: "quest-vista", + 7982: "sossd-disc", + 7998: "usicontentpush", + 7999: "irdmi2", + 8000: "irdmi", + 8001: "vcom-tunnel", + 8002: "teradataordbms", + 8003: "mcreport", + 8005: "mxi", + 8008: "http-alt", + 8019: "qbdb", + 8020: "intu-ec-svcdisc", + 8021: "intu-ec-client", + 8022: "oa-system", + 8025: "ca-audit-da", + 8026: "ca-audit-ds", + 8032: "pro-ed", + 8033: "mindprint", + 8034: "vantronix-mgmt", + 8040: "ampify", + 8052: "senomix01", + 8053: "senomix02", + 8054: "senomix03", + 8055: "senomix04", + 8056: "senomix05", + 8057: "senomix06", + 8058: "senomix07", + 8059: "senomix08", + 8060: "aero", + 8074: "gadugadu", + 8080: "http-alt", + 8081: "sunproxyadmin", + 8082: "us-cli", + 8083: "us-srv", + 8086: "d-s-n", + 8087: "simplifymedia", + 8088: "radan-http", + 8097: "sac", + 8100: "xprint-server", + 8115: "mtl8000-matrix", + 8116: "cp-cluster", + 8118: "privoxy", + 8121: "apollo-data", + 8122: "apollo-admin", + 8128: "paycash-online", + 8129: "paycash-wbp", + 8130: "indigo-vrmi", + 8131: "indigo-vbcp", + 8132: "dbabble", + 8148: "isdd", + 8149: "eor-game", + 8160: "patrol", + 8161: "patrol-snmp", + 8182: "vmware-fdm", + 8184: "itach", + 8192: "spytechphone", + 8194: "blp1", + 8195: "blp2", + 8199: "vvr-data", + 8200: "trivnet1", + 8201: "trivnet2", + 8202: "aesop", + 8204: "lm-perfworks", + 8205: "lm-instmgr", + 8206: "lm-dta", + 8207: "lm-sserver", + 8208: "lm-webwatcher", + 8230: "rexecj", + 8243: "synapse-nhttps", + 8276: "pando-sec", + 8280: "synapse-nhttp", + 8292: "blp3", + 8294: "blp4", + 8300: "tmi", + 8301: "amberon", + 8320: "tnp-discover", + 8321: "tnp", + 8351: "server-find", + 8376: "cruise-enum", + 8377: "cruise-swroute", + 8378: "cruise-config", + 8379: "cruise-diags", + 8380: "cruise-update", + 8383: "m2mservices", + 8400: "cvd", + 8401: "sabarsd", + 8402: "abarsd", + 8403: "admind", + 8416: "espeech", + 8417: "espeech-rtp", + 8442: "cybro-a-bus", + 8443: "pcsync-https", + 8444: "pcsync-http", + 8445: "copy-disc", + 8450: "npmp", + 8472: "otv", + 8473: "vp2p", + 8474: "noteshare", + 8500: "fmtp", + 8501: "cmtp-av", + 8554: "rtsp-alt", + 8555: "d-fence", + 8567: "enc-tunnel", + 8600: "asterix", + 8609: "canon-cpp-disc", + 8610: "canon-mfnp", + 8611: "canon-bjnp1", + 8612: "canon-bjnp2", + 8613: "canon-bjnp3", + 8614: "canon-bjnp4", + 8675: "msi-cps-rm-disc", + 8686: "sun-as-jmxrmi", + 8732: "dtp-net", + 8733: "ibus", + 8763: "mc-appserver", + 8764: "openqueue", + 8765: "ultraseek-http", + 8766: "amcs", + 8770: "dpap", + 8786: "msgclnt", + 8787: "msgsrvr", + 8793: "acd-pm", + 8800: "sunwebadmin", + 8804: "truecm", + 8873: "dxspider", + 8880: "cddbp-alt", + 8883: "secure-mqtt", + 8888: "ddi-udp-1", + 8889: "ddi-udp-2", + 8890: "ddi-udp-3", + 8891: "ddi-udp-4", + 8892: "ddi-udp-5", + 8893: "ddi-udp-6", + 8894: "ddi-udp-7", + 8899: "ospf-lite", + 8900: "jmb-cds1", + 8901: "jmb-cds2", + 8910: "manyone-http", + 8911: "manyone-xml", + 8912: "wcbackup", + 8913: "dragonfly", + 8954: "cumulus-admin", + 8989: "sunwebadmins", + 8990: "http-wmap", + 8991: "https-wmap", + 8999: "bctp", + 9000: "cslistener", + 9001: "etlservicemgr", + 9002: "dynamid", + 9007: "ogs-client", + 9009: "pichat", + 9020: "tambora", + 9021: "panagolin-ident", + 9022: "paragent", + 9023: "swa-1", + 9024: "swa-2", + 9025: "swa-3", + 9026: "swa-4", + 9080: "glrpc", + 9084: "aurora", + 9085: "ibm-rsyscon", + 9086: "net2display", + 9087: "classic", + 9088: "sqlexec", + 9089: "sqlexec-ssl", + 9090: "websm", + 9091: "xmltec-xmlmail", + 9092: "XmlIpcRegSvc", + 9100: "hp-pdl-datastr", + 9101: "bacula-dir", + 9102: "bacula-fd", + 9103: "bacula-sd", + 9104: "peerwire", + 9105: "xadmin", + 9106: "astergate-disc", + 9119: "mxit", + 9131: "dddp", + 9160: "apani1", + 9161: "apani2", + 9162: "apani3", + 9163: "apani4", + 9164: "apani5", + 9191: "sun-as-jpda", + 9200: "wap-wsp", + 9201: "wap-wsp-wtp", + 9202: "wap-wsp-s", + 9203: "wap-wsp-wtp-s", + 9204: "wap-vcard", + 9205: "wap-vcal", + 9206: "wap-vcard-s", + 9207: "wap-vcal-s", + 9208: "rjcdb-vcards", + 9209: "almobile-system", + 9210: "oma-mlp", + 9211: "oma-mlp-s", + 9212: "serverviewdbms", + 9213: "serverstart", + 9214: "ipdcesgbs", + 9215: "insis", + 9216: "acme", + 9217: "fsc-port", + 9222: "teamcoherence", + 9255: "mon", + 9277: "traingpsdata", + 9278: "pegasus", + 9279: "pegasus-ctl", + 9280: "pgps", + 9281: "swtp-port1", + 9282: "swtp-port2", + 9283: "callwaveiam", + 9284: "visd", + 9285: "n2h2server", + 9286: "n2receive", + 9287: "cumulus", + 9292: "armtechdaemon", + 9293: "storview", + 9294: "armcenterhttp", + 9295: "armcenterhttps", + 9300: "vrace", + 9318: "secure-ts", + 9321: "guibase", + 9343: "mpidcmgr", + 9344: "mphlpdmc", + 9346: "ctechlicensing", + 9374: "fjdmimgr", + 9380: "boxp", + 9396: "fjinvmgr", + 9397: "mpidcagt", + 9400: "sec-t4net-srv", + 9401: "sec-t4net-clt", + 9402: "sec-pc2fax-srv", + 9418: "git", + 9443: "tungsten-https", + 9444: "wso2esb-console", + 9450: "sntlkeyssrvr", + 9500: "ismserver", + 9522: "sma-spw", + 9535: "mngsuite", + 9536: "laes-bf", + 9555: "trispen-sra", + 9592: "ldgateway", + 9593: "cba8", + 9594: "msgsys", + 9595: "pds", + 9596: "mercury-disc", + 9597: "pd-admin", + 9598: "vscp", + 9599: "robix", + 9600: "micromuse-ncpw", + 9612: "streamcomm-ds", + 9618: "condor", + 9628: "odbcpathway", + 9629: "uniport", + 9632: "mc-comm", + 9667: "xmms2", + 9668: "tec5-sdctp", + 9694: "client-wakeup", + 9695: "ccnx", + 9700: "board-roar", + 9747: "l5nas-parchan", + 9750: "board-voip", + 9753: "rasadv", + 9762: "tungsten-http", + 9800: "davsrc", + 9801: "sstp-2", + 9802: "davsrcs", + 9875: "sapv1", + 9878: "kca-service", + 9888: "cyborg-systems", + 9889: "gt-proxy", + 9898: "monkeycom", + 9899: "sctp-tunneling", + 9900: "iua", + 9901: "enrp", + 9903: "multicast-ping", + 9909: "domaintime", + 9911: "sype-transport", + 9950: "apc-9950", + 9951: "apc-9951", + 9952: "apc-9952", + 9953: "acis", + 9955: "alljoyn-mcm", + 9956: "alljoyn", + 9966: "odnsp", + 9987: "dsm-scm-target", + 9990: "osm-appsrvr", + 9991: "osm-oev", + 9992: "palace-1", + 9993: "palace-2", + 9994: "palace-3", + 9995: "palace-4", + 9996: "palace-5", + 9997: "palace-6", + 9998: "distinct32", + 9999: "distinct", + 10000: "ndmp", + 10001: "scp-config", + 10002: "documentum", + 10003: "documentum-s", + 10007: "mvs-capacity", + 10008: "octopus", + 10009: "swdtp-sv", + 10050: "zabbix-agent", + 10051: "zabbix-trapper", + 10080: "amanda", + 10081: "famdc", + 10100: "itap-ddtp", + 10101: "ezmeeting-2", + 10102: "ezproxy-2", + 10103: "ezrelay", + 10104: "swdtp", + 10107: "bctp-server", + 10110: "nmea-0183", + 10111: "nmea-onenet", + 10113: "netiq-endpoint", + 10114: "netiq-qcheck", + 10115: "netiq-endpt", + 10116: "netiq-voipa", + 10117: "iqrm", + 10128: "bmc-perf-sd", + 10160: "qb-db-server", + 10161: "snmpdtls", + 10162: "snmpdtls-trap", + 10200: "trisoap", + 10201: "rscs", + 10252: "apollo-relay", + 10260: "axis-wimp-port", + 10288: "blocks", + 10439: "bngsync", + 10500: "hip-nat-t", + 10540: "MOS-lower", + 10541: "MOS-upper", + 10542: "MOS-aux", + 10543: "MOS-soap", + 10544: "MOS-soap-opt", + 10800: "gap", + 10805: "lpdg", + 10810: "nmc-disc", + 10860: "helix", + 10880: "bveapi", + 10990: "rmiaux", + 11000: "irisa", + 11001: "metasys", + 10023: "cefd-vmp", + 11095: "weave", + 11106: "sgi-lk", + 11108: "myq-termlink", + 11111: "vce", + 11112: "dicom", + 11161: "suncacao-snmp", + 11162: "suncacao-jmxmp", + 11163: "suncacao-rmi", + 11164: "suncacao-csa", + 11165: "suncacao-websvc", + 11171: "snss", + 11201: "smsqp", + 11208: "wifree", + 11211: "memcache", + 11319: "imip", + 11320: "imip-channels", + 11321: "arena-server", + 11367: "atm-uhas", + 11371: "hkp", + 11430: "lsdp", + 11600: "tempest-port", + 11720: "h323callsigalt", + 11723: "emc-xsw-dcache", + 11751: "intrepid-ssl", + 11796: "lanschool-mpt", + 11876: "xoraya", + 11877: "x2e-disc", + 11967: "sysinfo-sp", + 12000: "entextxid", + 12001: "entextnetwk", + 12002: "entexthigh", + 12003: "entextmed", + 12004: "entextlow", + 12005: "dbisamserver1", + 12006: "dbisamserver2", + 12007: "accuracer", + 12008: "accuracer-dbms", + 12009: "ghvpn", + 12012: "vipera", + 12013: "vipera-ssl", + 12109: "rets-ssl", + 12121: "nupaper-ss", + 12168: "cawas", + 12172: "hivep", + 12300: "linogridengine", + 12321: "warehouse-sss", + 12322: "warehouse", + 12345: "italk", + 12753: "tsaf", + 13160: "i-zipqd", + 13216: "bcslogc", + 13217: "rs-pias", + 13218: "emc-vcas-udp", + 13223: "powwow-client", + 13224: "powwow-server", + 13400: "doip-disc", + 13720: "bprd", + 13721: "bpdbm", + 13722: "bpjava-msvc", + 13724: "vnetd", + 13782: "bpcd", + 13783: "vopied", + 13785: "nbdb", + 13786: "nomdb", + 13818: "dsmcc-config", + 13819: "dsmcc-session", + 13820: "dsmcc-passthru", + 13821: "dsmcc-download", + 13822: "dsmcc-ccp", + 13894: "ucontrol", + 13929: "dta-systems", + 14000: "scotty-ft", + 14001: "sua", + 14002: "scotty-disc", + 14033: "sage-best-com1", + 14034: "sage-best-com2", + 14141: "vcs-app", + 14142: "icpp", + 14145: "gcm-app", + 14149: "vrts-tdd", + 14154: "vad", + 14250: "cps", + 14414: "ca-web-update", + 14936: "hde-lcesrvr-1", + 14937: "hde-lcesrvr-2", + 15000: "hydap", + 15118: "v2g-secc", + 15345: "xpilot", + 15363: "3link", + 15555: "cisco-snat", + 15660: "bex-xr", + 15740: "ptp", + 15998: "2ping", + 16003: "alfin", + 16161: "sun-sea-port", + 16309: "etb4j", + 16310: "pduncs", + 16311: "pdefmns", + 16360: "netserialext1", + 16361: "netserialext2", + 16367: "netserialext3", + 16368: "netserialext4", + 16384: "connected", + 16666: "vtp", + 16900: "newbay-snc-mc", + 16950: "sgcip", + 16991: "intel-rci-mp", + 16992: "amt-soap-http", + 16993: "amt-soap-https", + 16994: "amt-redir-tcp", + 16995: "amt-redir-tls", + 17007: "isode-dua", + 17185: "soundsvirtual", + 17219: "chipper", + 17220: "avtp", + 17221: "avdecc", + 17222: "cpsp", + 17234: "integrius-stp", + 17235: "ssh-mgmt", + 17500: "db-lsp-disc", + 17729: "ea", + 17754: "zep", + 17755: "zigbee-ip", + 17756: "zigbee-ips", + 18000: "biimenu", + 18181: "opsec-cvp", + 18182: "opsec-ufp", + 18183: "opsec-sam", + 18184: "opsec-lea", + 18185: "opsec-omi", + 18186: "ohsc", + 18187: "opsec-ela", + 18241: "checkpoint-rtm", + 18262: "gv-pf", + 18463: "ac-cluster", + 18634: "rds-ib", + 18635: "rds-ip", + 18769: "ique", + 18881: "infotos", + 18888: "apc-necmp", + 19000: "igrid", + 19007: "scintilla", + 19191: "opsec-uaa", + 19194: "ua-secureagent", + 19283: "keysrvr", + 19315: "keyshadow", + 19398: "mtrgtrans", + 19410: "hp-sco", + 19411: "hp-sca", + 19412: "hp-sessmon", + 19539: "fxuptp", + 19540: "sxuptp", + 19541: "jcp", + 19788: "mle", + 19999: "dnp-sec", + 20000: "dnp", + 20001: "microsan", + 20002: "commtact-http", + 20003: "commtact-https", + 20005: "openwebnet", + 20012: "ss-idi-disc", + 20014: "opendeploy", + 20034: "nburn-id", + 20046: "tmophl7mts", + 20048: "mountd", + 20049: "nfsrdma", + 20167: "tolfab", + 20202: "ipdtp-port", + 20222: "ipulse-ics", + 20480: "emwavemsg", + 20670: "track", + 20999: "athand-mmp", + 21000: "irtrans", + 21554: "dfserver", + 21590: "vofr-gateway", + 21800: "tvpm", + 21845: "webphone", + 21846: "netspeak-is", + 21847: "netspeak-cs", + 21848: "netspeak-acd", + 21849: "netspeak-cps", + 22000: "snapenetio", + 22001: "optocontrol", + 22002: "optohost002", + 22003: "optohost003", + 22004: "optohost004", + 22005: "optohost004", + 22273: "wnn6", + 22305: "cis", + 22343: "cis-secure", + 22347: "wibukey", + 22350: "codemeter", + 22555: "vocaltec-phone", + 22763: "talikaserver", + 22800: "aws-brf", + 22951: "brf-gw", + 23000: "inovaport1", + 23001: "inovaport2", + 23002: "inovaport3", + 23003: "inovaport4", + 23004: "inovaport5", + 23005: "inovaport6", + 23272: "s102", + 23333: "elxmgmt", + 23400: "novar-dbase", + 23401: "novar-alarm", + 23402: "novar-global", + 24000: "med-ltp", + 24001: "med-fsp-rx", + 24002: "med-fsp-tx", + 24003: "med-supp", + 24004: "med-ovw", + 24005: "med-ci", + 24006: "med-net-svc", + 24242: "filesphere", + 24249: "vista-4gl", + 24321: "ild", + 24322: "hid", + 24386: "intel-rci", + 24465: "tonidods", + 24554: "binkp", + 24577: "bilobit-update", + 24676: "canditv", + 24677: "flashfiler", + 24678: "proactivate", + 24680: "tcc-http", + 24850: "assoc-disc", + 24922: "find", + 25000: "icl-twobase1", + 25001: "icl-twobase2", + 25002: "icl-twobase3", + 25003: "icl-twobase4", + 25004: "icl-twobase5", + 25005: "icl-twobase6", + 25006: "icl-twobase7", + 25007: "icl-twobase8", + 25008: "icl-twobase9", + 25009: "icl-twobase10", + 25793: "vocaltec-hos", + 25900: "tasp-net", + 25901: "niobserver", + 25902: "nilinkanalyst", + 25903: "niprobe", + 25954: "bf-game", + 25955: "bf-master", + 26000: "quake", + 26133: "scscp", + 26208: "wnn6-ds", + 26260: "ezproxy", + 26261: "ezmeeting", + 26262: "k3software-svr", + 26263: "k3software-cli", + 26486: "exoline-udp", + 26487: "exoconfig", + 26489: "exonet", + 27345: "imagepump", + 27442: "jesmsjc", + 27504: "kopek-httphead", + 27782: "ars-vista", + 27999: "tw-auth-key", + 28000: "nxlmd", + 28119: "a27-ran-ran", + 28200: "voxelstorm", + 28240: "siemensgsm", + 29167: "otmp", + 30001: "pago-services1", + 30002: "pago-services2", + 30003: "amicon-fpsu-ra", + 30004: "amicon-fpsu-s", + 30260: "kingdomsonline", + 30832: "samsung-disc", + 30999: "ovobs", + 31029: "yawn", + 31416: "xqosd", + 31457: "tetrinet", + 31620: "lm-mon", + 31765: "gamesmith-port", + 31948: "iceedcp-tx", + 31949: "iceedcp-rx", + 32034: "iracinghelper", + 32249: "t1distproc60", + 32483: "apm-link", + 32635: "sec-ntb-clnt", + 32636: "DMExpress", + 32767: "filenet-powsrm", + 32768: "filenet-tms", + 32769: "filenet-rpc", + 32770: "filenet-nch", + 32771: "filenet-rmi", + 32772: "filenet-pa", + 32773: "filenet-cm", + 32774: "filenet-re", + 32775: "filenet-pch", + 32776: "filenet-peior", + 32777: "filenet-obrok", + 32801: "mlsn", + 32896: "idmgratm", + 33123: "aurora-balaena", + 33331: "diamondport", + 33334: "speedtrace-disc", + 33434: "traceroute", + 33656: "snip-slave", + 34249: "turbonote-2", + 34378: "p-net-local", + 34379: "p-net-remote", + 34962: "profinet-rt", + 34963: "profinet-rtm", + 34964: "profinet-cm", + 34980: "ethercat", + 35001: "rt-viewer", + 35004: "rt-classmanager", + 35355: "altova-lm-disc", + 36001: "allpeers", + 36865: "kastenxpipe", + 37475: "neckar", + 37654: "unisys-eportal", + 38201: "galaxy7-data", + 38202: "fairview", + 38203: "agpolicy", + 39681: "turbonote-1", + 40000: "safetynetp", + 40841: "cscp", + 40842: "csccredir", + 40843: "csccfirewall", + 40853: "ortec-disc", + 41111: "fs-qos", + 41794: "crestron-cip", + 41795: "crestron-ctp", + 42508: "candp", + 42509: "candrp", + 42510: "caerpc", + 43000: "recvr-rc-disc", + 43188: "reachout", + 43189: "ndm-agent-port", + 43190: "ip-provision", + 43210: "shaperai-disc", + 43439: "eq3-config", + 43440: "ew-disc-cmd", + 43441: "ciscocsdb", + 44321: "pmcd", + 44322: "pmcdproxy", + 44544: "domiq", + 44553: "rbr-debug", + 44600: "asihpi", + 44818: "EtherNet-IP-2", + 44900: "m3da-disc", + 45000: "asmp-mon", + 45054: "invision-ag", + 45678: "eba", + 45825: "qdb2service", + 45966: "ssr-servermgr", + 46999: "mediabox", + 47000: "mbus", + 47100: "jvl-mactalk", + 47557: "dbbrowse", + 47624: "directplaysrvr", + 47806: "ap", + 47808: "bacnet", + 47809: "presonus-ucnet", + 48000: "nimcontroller", + 48001: "nimspooler", + 48002: "nimhub", + 48003: "nimgtw", + 48128: "isnetserv", + 48129: "blp5", + 48556: "com-bardac-dw", + 48619: "iqobject", + 48653: "robotraconteur", +} +var sctpPortNames = map[SCTPPort]string{ + 9: "discard", + 20: "ftp-data", + 21: "ftp", + 22: "ssh", + 80: "http", + 179: "bgp", + 443: "https", + 1021: "exp1", + 1022: "exp2", + 1167: "cisco-ipsla", + 1720: "h323hostcall", + 2049: "nfs", + 2225: "rcip-itu", + 2904: "m2ua", + 2905: "m3ua", + 2944: "megaco-h248", + 2945: "h248-binary", + 3097: "itu-bicc-stc", + 3565: "m2pa", + 3863: "asap-sctp", + 3864: "asap-sctp-tls", + 3868: "diameter", + 4333: "ahsp", + 4502: "a25-fap-fgw", + 4739: "ipfix", + 4740: "ipfixs", + 5060: "sip", + 5061: "sips", + 5090: "car", + 5091: "cxtp", + 5215: "noteza", + 5445: "smbdirect", + 5672: "amqp", + 5675: "v5ua", + 5868: "diameters", + 5910: "cm", + 5911: "cpdlc", + 5912: "fis", + 5913: "ads-c", + 6704: "frc-hp", + 6705: "frc-mp", + 6706: "frc-lp", + 6970: "conductor-mpx", + 7626: "simco", + 8471: "pim-port", + 9082: "lcs-ap", + 9084: "aurora", + 9900: "iua", + 9901: "enrp-sctp", + 9902: "enrp-sctp-tls", + 11997: "wmereceiving", + 11998: "wmedistribution", + 11999: "wmereporting", + 14001: "sua", + 20049: "nfsrdma", + 25471: "rna", + 29118: "sgsap", + 29168: "sbcap", + 29169: "iuhsctpassoc", + 36412: "s1-control", + 36422: "x2-control", + 36443: "m2ap", + 36444: "m3ap", +} diff --git a/vendor/github.com/google/gopacket/layers/icmp4.go b/vendor/github.com/google/gopacket/layers/icmp4.go new file mode 100644 index 0000000..b783822 --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/icmp4.go @@ -0,0 +1,265 @@ +// 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" + "reflect" +) + +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 fmt.Errorf("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) +} diff --git a/vendor/github.com/google/gopacket/layers/icmp6.go b/vendor/github.com/google/gopacket/layers/icmp6.go new file mode 100644 index 0000000..0547865 --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/icmp6.go @@ -0,0 +1,229 @@ +// 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" + "reflect" +) + +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 +) + +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 []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) < 8 { + df.SetTruncated() + return fmt.Errorf("ICMP layer less then 8 bytes for ICMPv6 packet") + } + i.TypeCode = CreateICMPv6TypeCode(data[0], data[1]) + i.Checksum = binary.BigEndian.Uint16(data[2:4]) + i.TypeBytes = data[4: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 *ICMPv6) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error { + if i.TypeBytes == nil { + i.TypeBytes = lotsOfZeros[:4] + } else if len(i.TypeBytes) != 4 { + return fmt.Errorf("invalid type bytes for ICMPv6 packet: %v", i.TypeBytes) + } + bytes, err := b.PrependBytes(8) + if err != nil { + return err + } + i.TypeCode.SerializeTo(bytes) + copy(bytes[4:8], i.TypeBytes) + 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 { + return gopacket.LayerTypePayload +} + +func decodeICMPv6(data []byte, p gopacket.PacketBuilder) error { + i := &ICMPv6{} + return decodingLayerDecoder(i, data, p) +} diff --git a/vendor/github.com/google/gopacket/layers/igmp.go b/vendor/github.com/google/gopacket/layers/igmp.go new file mode 100644 index 0000000..c6ab906 --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/igmp.go @@ -0,0 +1,83 @@ +// 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" + "net" + "time" +) + +type IGMPType uint8 + +// IGMP is the packet structure for IGMP messages. +type IGMP struct { + BaseLayer + Type IGMPType + MaxResponseTime time.Duration + Checksum uint16 + GroupAddress net.IP + // The following are used only by IGMPv3 + SupressRouterProcessing bool + RobustnessValue uint8 + IntervalTime time.Duration + SourceAddresses []net.IP +} + +// LayerType returns LayerTypeIGMP +func (i *IGMP) LayerType() gopacket.LayerType { return LayerTypeIGMP } + +// 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)) +} + +// DecodeFromBytes decodes the given bytes into this layer. +func (i *IGMP) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + 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]) + if i.Type == 0x11 && len(data) > 8 { + i.SupressRouterProcessing = data[8]&0x8 != 0 + i.RobustnessValue = data[8] & 0x7 + i.IntervalTime = igmpTimeDecode(data[9]) + numSources := int(binary.BigEndian.Uint16(data[10:12])) + for j := 0; j < numSources; j++ { + i.SourceAddresses = append(i.SourceAddresses, net.IP(data[12+j*4:16+j*4])) + } + } else { + i.SupressRouterProcessing = false + i.RobustnessValue = 0 + i.IntervalTime = 0 + i.SourceAddresses = nil + } + 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 +} + +func decodeIGMP(data []byte, p gopacket.PacketBuilder) error { + i := &IGMP{} + return decodingLayerDecoder(i, data, p) +} diff --git a/vendor/github.com/google/gopacket/layers/ip4.go b/vendor/github.com/google/gopacket/layers/ip4.go new file mode 100644 index 0000000..a1c9ac1 --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/ip4.go @@ -0,0 +1,286 @@ +// 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" + "net" + "strings" +) + +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) { + fmt.Errorf("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 { + // 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]) + } + ip.Checksum = ^uint16((csum >> 16) + csum) + } + binary.BigEndian.PutUint16(bytes[10:], ip.Checksum) + return nil +} + +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 { + 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] + // Set up an initial guess for contents/payload... we'll reset these soon. + ip.BaseLayer = BaseLayer{Contents: 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 fmt.Errorf("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:] + break + case 1: // 1 byte padding + opt.OptionLength = 1 + default: + opt.OptionLength = data[1] + opt.OptionData = data[2:opt.OptionLength] + } + if len(data) >= int(opt.OptionLength) { + data = data[opt.OptionLength:] + } else { + return fmt.Errorf("IP option length exceeds remaining IP header size, option type %v length %v", opt.OptionType, 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, fmt.Errorf("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 +} diff --git a/vendor/github.com/google/gopacket/layers/ip6.go b/vendor/github.com/google/gopacket/layers/ip6.go new file mode 100644 index 0000000..45eb0a2 --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/ip6.go @@ -0,0 +1,651 @@ +// 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" + "net" +) + +const ( + IPv6HopByHopOptionJumbogram = 0xC2 // RFC 2675 +) + +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 (i *IPv6) LayerType() gopacket.LayerType { return LayerTypeIPv6 } + +func (i *IPv6) NetworkFlow() gopacket.Flow { + return gopacket.NewFlow(EndpointIPv6, i.SrcIP, i.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, fmt.Errorf("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 += 1 + 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 fmt.Errorf("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 (ip6 *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(ip6) + } else if ip6.HopByHop == nil { + return fmt.Errorf("Cannot fit payload length of %d into IPv6 packet", pLen) + } else { + _, ok, err := getIPv6HopByHopJumboLength(ip6.HopByHop) + if err != nil { + return err + } + if !ok { + return fmt.Errorf("Missing jumbo length hop-by-hop option") + } + } + } + if ip6.HopByHop != nil { + if ip6.NextHeader != IPProtocolIPv6HopByHop { + // Just fix it instead of throwing an error + ip6.NextHeader = IPProtocolIPv6HopByHop + } + err = ip6.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 fmt.Errorf("Cannot fit payload into IPv6 header") + } + bytes, err := b.PrependBytes(40) + if err != nil { + return err + } + bytes[0] = (ip6.Version << 4) | (ip6.TrafficClass >> 4) + bytes[1] = (ip6.TrafficClass << 4) | uint8(ip6.FlowLabel>>16) + binary.BigEndian.PutUint16(bytes[2:], uint16(ip6.FlowLabel)) + if opts.FixLengths { + if jumbo { + ip6.Length = 0 + } else { + ip6.Length = uint16(pLen) + } + } + binary.BigEndian.PutUint16(bytes[4:], ip6.Length) + bytes[6] = byte(ip6.NextHeader) + bytes[7] = byte(ip6.HopLimit) + if err := ip6.AddressTo16(); err != nil { + return err + } + copy(bytes[8:], ip6.SrcIP) + copy(bytes[24:], ip6.DstIP) + return nil +} + +func (ip6 *IPv6) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + ip6.Version = uint8(data[0]) >> 4 + ip6.TrafficClass = uint8((binary.BigEndian.Uint16(data[0:2]) >> 4) & 0x00FF) + ip6.FlowLabel = binary.BigEndian.Uint32(data[0:4]) & 0x000FFFFF + ip6.Length = binary.BigEndian.Uint16(data[4:6]) + ip6.NextHeader = IPProtocol(data[6]) + ip6.HopLimit = data[7] + ip6.SrcIP = data[8:24] + ip6.DstIP = data[24:40] + ip6.HopByHop = nil + ip6.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 ip6.NextHeader == IPProtocolIPv6HopByHop { + err := ip6.hbh.DecodeFromBytes(ip6.Payload, df) + if err != nil { + return err + } + ip6.HopByHop = &ip6.hbh + pEnd, jumbo, err := getIPv6HopByHopJumboLength(ip6.HopByHop) + if err != nil { + return err + } + if jumbo && ip6.Length == 0 { + pEnd := int(pEnd) + if pEnd > len(ip6.Payload) { + df.SetTruncated() + pEnd = len(ip6.Payload) + } + ip6.Payload = ip6.Payload[:pEnd] + return nil + } else if jumbo && ip6.Length != 0 { + return fmt.Errorf("IPv6 has jumbo length and IPv6 length is not 0") + } else if !jumbo && ip6.Length == 0 { + return fmt.Errorf("IPv6 length 0, but HopByHop header does not have jumbogram option") + } + } + + if ip6.Length == 0 { + return fmt.Errorf("IPv6 length 0, but next header is %v, not HopByHop", ip6.NextHeader) + } else { + pEnd := int(ip6.Length) + if pEnd > len(ip6.Payload) { + df.SetTruncated() + pEnd = len(ip6.Payload) + } + ip6.Payload = ip6.Payload[:pEnd] + } + return nil +} + +func (i *IPv6) CanDecode() gopacket.LayerClass { + return LayerTypeIPv6 +} + +func (i *IPv6) NextLayerType() gopacket.LayerType { + if i.HopByHop != nil { + return i.HopByHop.NextHeader.LayerType() + } + return i.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 + } + if ip6.HopByHop != nil { + return p.NextDecoder(ip6.HopByHop.NextHeader) + } + return p.NextDecoder(ip6.NextHeader) +} + +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) (i ipv6ExtensionBase) { + i.NextHeader = IPProtocol(data[0]) + i.HeaderLength = data[1] + i.ActualLength = int(i.HeaderLength)*8 + 8 + 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 +} + +func (i *IPv6ExtensionSkipper) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + extension := decodeIPv6ExtensionBase(data) + i.BaseLayer = BaseLayer{data[:extension.ActualLength], data[extension.ActualLength:]} + i.NextHeader = extension.NextHeader + return nil +} + +func (i *IPv6ExtensionSkipper) CanDecode() gopacket.LayerClass { + return LayerClassIPv6Extension +} + +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 } + +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 fmt.Errorf("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 +} + +func (i *IPv6HopByHop) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + i.ipv6ExtensionBase = decodeIPv6ExtensionBase(data) + 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) +} + +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 { + i := &IPv6Routing{ + ipv6ExtensionBase: decodeIPv6ExtensionBase(data), + 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 { + 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 } + +func (i *IPv6Destination) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + i.ipv6ExtensionBase = decodeIPv6ExtensionBase(data) + 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 fmt.Errorf("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 fmt.Errorf("address is IPv4") + } + return fmt.Errorf("wrong length of %d bytes instead of %d", len(addr), net.IPv6len) +} + +func (ip *IPv6) AddressTo16() error { + if err := checkIPv6Address(ip.SrcIP); err != nil { + return fmt.Errorf("Invalid source IPv6 address (%s)", err) + } + if err := checkIPv6Address(ip.DstIP); err != nil { + return fmt.Errorf("Invalid destination IPv6 address (%s)", err) + } + return nil +} diff --git a/vendor/github.com/google/gopacket/layers/ipsec.go b/vendor/github.com/google/gopacket/layers/ipsec.go new file mode 100644 index 0000000..19163fa --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/ipsec.go @@ -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 +} diff --git a/vendor/github.com/google/gopacket/layers/layertypes.go b/vendor/github.com/google/gopacket/layers/layertypes.go new file mode 100644 index 0000000..5bb1421 --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/layertypes.go @@ -0,0 +1,169 @@ +// Copyright 2012 Google, gopacket.LayerTypeMetadata{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{"ARP", gopacket.DecodeFunc(decodeARP)}) + LayerTypeCiscoDiscovery = gopacket.RegisterLayerType(11, gopacket.LayerTypeMetadata{"CiscoDiscovery", gopacket.DecodeFunc(decodeCiscoDiscovery)}) + LayerTypeEthernetCTP = gopacket.RegisterLayerType(12, gopacket.LayerTypeMetadata{"EthernetCTP", gopacket.DecodeFunc(decodeEthernetCTP)}) + LayerTypeEthernetCTPForwardData = gopacket.RegisterLayerType(13, gopacket.LayerTypeMetadata{"EthernetCTPForwardData", nil}) + LayerTypeEthernetCTPReply = gopacket.RegisterLayerType(14, gopacket.LayerTypeMetadata{"EthernetCTPReply", nil}) + LayerTypeDot1Q = gopacket.RegisterLayerType(15, gopacket.LayerTypeMetadata{"Dot1Q", gopacket.DecodeFunc(decodeDot1Q)}) + LayerTypeEtherIP = gopacket.RegisterLayerType(16, gopacket.LayerTypeMetadata{"EtherIP", gopacket.DecodeFunc(decodeEtherIP)}) + LayerTypeEthernet = gopacket.RegisterLayerType(17, gopacket.LayerTypeMetadata{"Ethernet", gopacket.DecodeFunc(decodeEthernet)}) + LayerTypeGRE = gopacket.RegisterLayerType(18, gopacket.LayerTypeMetadata{"GRE", gopacket.DecodeFunc(decodeGRE)}) + LayerTypeICMPv4 = gopacket.RegisterLayerType(19, gopacket.LayerTypeMetadata{"ICMPv4", gopacket.DecodeFunc(decodeICMPv4)}) + LayerTypeIPv4 = gopacket.RegisterLayerType(20, gopacket.LayerTypeMetadata{"IPv4", gopacket.DecodeFunc(decodeIPv4)}) + LayerTypeIPv6 = gopacket.RegisterLayerType(21, gopacket.LayerTypeMetadata{"IPv6", gopacket.DecodeFunc(decodeIPv6)}) + LayerTypeLLC = gopacket.RegisterLayerType(22, gopacket.LayerTypeMetadata{"LLC", gopacket.DecodeFunc(decodeLLC)}) + LayerTypeSNAP = gopacket.RegisterLayerType(23, gopacket.LayerTypeMetadata{"SNAP", gopacket.DecodeFunc(decodeSNAP)}) + LayerTypeMPLS = gopacket.RegisterLayerType(24, gopacket.LayerTypeMetadata{"MPLS", gopacket.DecodeFunc(decodeMPLS)}) + LayerTypePPP = gopacket.RegisterLayerType(25, gopacket.LayerTypeMetadata{"PPP", gopacket.DecodeFunc(decodePPP)}) + LayerTypePPPoE = gopacket.RegisterLayerType(26, gopacket.LayerTypeMetadata{"PPPoE", gopacket.DecodeFunc(decodePPPoE)}) + LayerTypeRUDP = gopacket.RegisterLayerType(27, gopacket.LayerTypeMetadata{"RUDP", gopacket.DecodeFunc(decodeRUDP)}) + LayerTypeSCTP = gopacket.RegisterLayerType(28, gopacket.LayerTypeMetadata{"SCTP", gopacket.DecodeFunc(decodeSCTP)}) + LayerTypeSCTPUnknownChunkType = gopacket.RegisterLayerType(29, gopacket.LayerTypeMetadata{"SCTPUnknownChunkType", nil}) + LayerTypeSCTPData = gopacket.RegisterLayerType(30, gopacket.LayerTypeMetadata{"SCTPData", nil}) + LayerTypeSCTPInit = gopacket.RegisterLayerType(31, gopacket.LayerTypeMetadata{"SCTPInit", nil}) + LayerTypeSCTPSack = gopacket.RegisterLayerType(32, gopacket.LayerTypeMetadata{"SCTPSack", nil}) + LayerTypeSCTPHeartbeat = gopacket.RegisterLayerType(33, gopacket.LayerTypeMetadata{"SCTPHeartbeat", nil}) + LayerTypeSCTPError = gopacket.RegisterLayerType(34, gopacket.LayerTypeMetadata{"SCTPError", nil}) + LayerTypeSCTPShutdown = gopacket.RegisterLayerType(35, gopacket.LayerTypeMetadata{"SCTPShutdown", nil}) + LayerTypeSCTPShutdownAck = gopacket.RegisterLayerType(36, gopacket.LayerTypeMetadata{"SCTPShutdownAck", nil}) + LayerTypeSCTPCookieEcho = gopacket.RegisterLayerType(37, gopacket.LayerTypeMetadata{"SCTPCookieEcho", nil}) + LayerTypeSCTPEmptyLayer = gopacket.RegisterLayerType(38, gopacket.LayerTypeMetadata{"SCTPEmptyLayer", nil}) + LayerTypeSCTPInitAck = gopacket.RegisterLayerType(39, gopacket.LayerTypeMetadata{"SCTPInitAck", nil}) + LayerTypeSCTPHeartbeatAck = gopacket.RegisterLayerType(40, gopacket.LayerTypeMetadata{"SCTPHeartbeatAck", nil}) + LayerTypeSCTPAbort = gopacket.RegisterLayerType(41, gopacket.LayerTypeMetadata{"SCTPAbort", nil}) + LayerTypeSCTPShutdownComplete = gopacket.RegisterLayerType(42, gopacket.LayerTypeMetadata{"SCTPShutdownComplete", nil}) + LayerTypeSCTPCookieAck = gopacket.RegisterLayerType(43, gopacket.LayerTypeMetadata{"SCTPCookieAck", nil}) + LayerTypeTCP = gopacket.RegisterLayerType(44, gopacket.LayerTypeMetadata{"TCP", gopacket.DecodeFunc(decodeTCP)}) + LayerTypeUDP = gopacket.RegisterLayerType(45, gopacket.LayerTypeMetadata{"UDP", gopacket.DecodeFunc(decodeUDP)}) + LayerTypeIPv6HopByHop = gopacket.RegisterLayerType(46, gopacket.LayerTypeMetadata{"IPv6HopByHop", gopacket.DecodeFunc(decodeIPv6HopByHop)}) + LayerTypeIPv6Routing = gopacket.RegisterLayerType(47, gopacket.LayerTypeMetadata{"IPv6Routing", gopacket.DecodeFunc(decodeIPv6Routing)}) + LayerTypeIPv6Fragment = gopacket.RegisterLayerType(48, gopacket.LayerTypeMetadata{"IPv6Fragment", gopacket.DecodeFunc(decodeIPv6Fragment)}) + LayerTypeIPv6Destination = gopacket.RegisterLayerType(49, gopacket.LayerTypeMetadata{"IPv6Destination", gopacket.DecodeFunc(decodeIPv6Destination)}) + LayerTypeIPSecAH = gopacket.RegisterLayerType(50, gopacket.LayerTypeMetadata{"IPSecAH", gopacket.DecodeFunc(decodeIPSecAH)}) + LayerTypeIPSecESP = gopacket.RegisterLayerType(51, gopacket.LayerTypeMetadata{"IPSecESP", gopacket.DecodeFunc(decodeIPSecESP)}) + LayerTypeUDPLite = gopacket.RegisterLayerType(52, gopacket.LayerTypeMetadata{"UDPLite", gopacket.DecodeFunc(decodeUDPLite)}) + LayerTypeFDDI = gopacket.RegisterLayerType(53, gopacket.LayerTypeMetadata{"FDDI", gopacket.DecodeFunc(decodeFDDI)}) + LayerTypeLoopback = gopacket.RegisterLayerType(54, gopacket.LayerTypeMetadata{"Loopback", gopacket.DecodeFunc(decodeLoopback)}) + LayerTypeEAP = gopacket.RegisterLayerType(55, gopacket.LayerTypeMetadata{"EAP", gopacket.DecodeFunc(decodeEAP)}) + LayerTypeEAPOL = gopacket.RegisterLayerType(56, gopacket.LayerTypeMetadata{"EAPOL", gopacket.DecodeFunc(decodeEAPOL)}) + LayerTypeICMPv6 = gopacket.RegisterLayerType(57, gopacket.LayerTypeMetadata{"ICMPv6", gopacket.DecodeFunc(decodeICMPv6)}) + LayerTypeLinkLayerDiscovery = gopacket.RegisterLayerType(58, gopacket.LayerTypeMetadata{"LinkLayerDiscovery", gopacket.DecodeFunc(decodeLinkLayerDiscovery)}) + LayerTypeCiscoDiscoveryInfo = gopacket.RegisterLayerType(59, gopacket.LayerTypeMetadata{"CiscoDiscoveryInfo", gopacket.DecodeFunc(decodeCiscoDiscoveryInfo)}) + LayerTypeLinkLayerDiscoveryInfo = gopacket.RegisterLayerType(60, gopacket.LayerTypeMetadata{"LinkLayerDiscoveryInfo", nil}) + LayerTypeNortelDiscovery = gopacket.RegisterLayerType(61, gopacket.LayerTypeMetadata{"NortelDiscovery", gopacket.DecodeFunc(decodeNortelDiscovery)}) + LayerTypeIGMP = gopacket.RegisterLayerType(62, gopacket.LayerTypeMetadata{"IGMP", gopacket.DecodeFunc(decodeIGMP)}) + LayerTypePFLog = gopacket.RegisterLayerType(63, gopacket.LayerTypeMetadata{"PFLog", gopacket.DecodeFunc(decodePFLog)}) + LayerTypeRadioTap = gopacket.RegisterLayerType(64, gopacket.LayerTypeMetadata{"RadioTap", gopacket.DecodeFunc(decodeRadioTap)}) + LayerTypeDot11 = gopacket.RegisterLayerType(65, gopacket.LayerTypeMetadata{"Dot11", gopacket.DecodeFunc(decodeDot11)}) + LayerTypeDot11Ctrl = gopacket.RegisterLayerType(66, gopacket.LayerTypeMetadata{"Dot11Ctrl", gopacket.DecodeFunc(decodeDot11Ctrl)}) + LayerTypeDot11Data = gopacket.RegisterLayerType(67, gopacket.LayerTypeMetadata{"Dot11Data", gopacket.DecodeFunc(decodeDot11Data)}) + LayerTypeDot11DataCFAck = gopacket.RegisterLayerType(68, gopacket.LayerTypeMetadata{"Dot11DataCFAck", gopacket.DecodeFunc(decodeDot11DataCFAck)}) + LayerTypeDot11DataCFPoll = gopacket.RegisterLayerType(69, gopacket.LayerTypeMetadata{"Dot11DataCFPoll", gopacket.DecodeFunc(decodeDot11DataCFPoll)}) + LayerTypeDot11DataCFAckPoll = gopacket.RegisterLayerType(70, gopacket.LayerTypeMetadata{"Dot11DataCFAckPoll", gopacket.DecodeFunc(decodeDot11DataCFAckPoll)}) + LayerTypeDot11DataNull = gopacket.RegisterLayerType(71, gopacket.LayerTypeMetadata{"Dot11DataNull", gopacket.DecodeFunc(decodeDot11DataNull)}) + LayerTypeDot11DataCFAckNoData = gopacket.RegisterLayerType(72, gopacket.LayerTypeMetadata{"Dot11DataCFAck", gopacket.DecodeFunc(decodeDot11DataCFAck)}) + LayerTypeDot11DataCFPollNoData = gopacket.RegisterLayerType(73, gopacket.LayerTypeMetadata{"Dot11DataCFPoll", gopacket.DecodeFunc(decodeDot11DataCFPoll)}) + LayerTypeDot11DataCFAckPollNoData = gopacket.RegisterLayerType(74, gopacket.LayerTypeMetadata{"Dot11DataCFAckPoll", gopacket.DecodeFunc(decodeDot11DataCFAckPoll)}) + LayerTypeDot11DataQOSData = gopacket.RegisterLayerType(75, gopacket.LayerTypeMetadata{"Dot11DataQOSData", gopacket.DecodeFunc(decodeDot11DataQOSData)}) + LayerTypeDot11DataQOSDataCFAck = gopacket.RegisterLayerType(76, gopacket.LayerTypeMetadata{"Dot11DataQOSDataCFAck", gopacket.DecodeFunc(decodeDot11DataQOSDataCFAck)}) + LayerTypeDot11DataQOSDataCFPoll = gopacket.RegisterLayerType(77, gopacket.LayerTypeMetadata{"Dot11DataQOSDataCFPoll", gopacket.DecodeFunc(decodeDot11DataQOSDataCFPoll)}) + LayerTypeDot11DataQOSDataCFAckPoll = gopacket.RegisterLayerType(78, gopacket.LayerTypeMetadata{"Dot11DataQOSDataCFAckPoll", gopacket.DecodeFunc(decodeDot11DataQOSDataCFAckPoll)}) + LayerTypeDot11DataQOSNull = gopacket.RegisterLayerType(79, gopacket.LayerTypeMetadata{"Dot11DataQOSNull", gopacket.DecodeFunc(decodeDot11DataQOSNull)}) + LayerTypeDot11DataQOSCFPollNoData = gopacket.RegisterLayerType(80, gopacket.LayerTypeMetadata{"Dot11DataQOSCFPoll", gopacket.DecodeFunc(decodeDot11DataQOSCFPollNoData)}) + LayerTypeDot11DataQOSCFAckPollNoData = gopacket.RegisterLayerType(81, gopacket.LayerTypeMetadata{"Dot11DataQOSCFAckPoll", gopacket.DecodeFunc(decodeDot11DataQOSCFAckPollNoData)}) + LayerTypeDot11InformationElement = gopacket.RegisterLayerType(82, gopacket.LayerTypeMetadata{"Dot11InformationElement", gopacket.DecodeFunc(decodeDot11InformationElement)}) + LayerTypeDot11CtrlCTS = gopacket.RegisterLayerType(83, gopacket.LayerTypeMetadata{"Dot11CtrlCTS", gopacket.DecodeFunc(decodeDot11CtrlCTS)}) + LayerTypeDot11CtrlRTS = gopacket.RegisterLayerType(84, gopacket.LayerTypeMetadata{"Dot11CtrlRTS", gopacket.DecodeFunc(decodeDot11CtrlRTS)}) + LayerTypeDot11CtrlBlockAckReq = gopacket.RegisterLayerType(85, gopacket.LayerTypeMetadata{"Dot11CtrlBlockAckReq", gopacket.DecodeFunc(decodeDot11CtrlBlockAckReq)}) + LayerTypeDot11CtrlBlockAck = gopacket.RegisterLayerType(86, gopacket.LayerTypeMetadata{"Dot11CtrlBlockAck", gopacket.DecodeFunc(decodeDot11CtrlBlockAck)}) + LayerTypeDot11CtrlPowersavePoll = gopacket.RegisterLayerType(87, gopacket.LayerTypeMetadata{"Dot11CtrlPowersavePoll", gopacket.DecodeFunc(decodeDot11CtrlPowersavePoll)}) + LayerTypeDot11CtrlAck = gopacket.RegisterLayerType(88, gopacket.LayerTypeMetadata{"Dot11CtrlAck", gopacket.DecodeFunc(decodeDot11CtrlAck)}) + LayerTypeDot11CtrlCFEnd = gopacket.RegisterLayerType(89, gopacket.LayerTypeMetadata{"Dot11CtrlCFEnd", gopacket.DecodeFunc(decodeDot11CtrlCFEnd)}) + LayerTypeDot11CtrlCFEndAck = gopacket.RegisterLayerType(90, gopacket.LayerTypeMetadata{"Dot11CtrlCFEndAck", gopacket.DecodeFunc(decodeDot11CtrlCFEndAck)}) + LayerTypeDot11MgmtAssociationReq = gopacket.RegisterLayerType(91, gopacket.LayerTypeMetadata{"Dot11MgmtAssociationReq", gopacket.DecodeFunc(decodeDot11MgmtAssociationReq)}) + LayerTypeDot11MgmtAssociationResp = gopacket.RegisterLayerType(92, gopacket.LayerTypeMetadata{"Dot11MgmtAssociationResp", gopacket.DecodeFunc(decodeDot11MgmtAssociationResp)}) + LayerTypeDot11MgmtReassociationReq = gopacket.RegisterLayerType(93, gopacket.LayerTypeMetadata{"Dot11MgmtReassociationReq", gopacket.DecodeFunc(decodeDot11MgmtReassociationReq)}) + LayerTypeDot11MgmtReassociationResp = gopacket.RegisterLayerType(94, gopacket.LayerTypeMetadata{"Dot11MgmtReassociationResp", gopacket.DecodeFunc(decodeDot11MgmtReassociationResp)}) + LayerTypeDot11MgmtProbeReq = gopacket.RegisterLayerType(95, gopacket.LayerTypeMetadata{"Dot11MgmtProbeReq", gopacket.DecodeFunc(decodeDot11MgmtProbeReq)}) + LayerTypeDot11MgmtProbeResp = gopacket.RegisterLayerType(96, gopacket.LayerTypeMetadata{"Dot11MgmtProbeResp", gopacket.DecodeFunc(decodeDot11MgmtProbeResp)}) + LayerTypeDot11MgmtMeasurementPilot = gopacket.RegisterLayerType(97, gopacket.LayerTypeMetadata{"Dot11MgmtMeasurementPilot", gopacket.DecodeFunc(decodeDot11MgmtMeasurementPilot)}) + LayerTypeDot11MgmtBeacon = gopacket.RegisterLayerType(98, gopacket.LayerTypeMetadata{"Dot11MgmtBeacon", gopacket.DecodeFunc(decodeDot11MgmtBeacon)}) + LayerTypeDot11MgmtATIM = gopacket.RegisterLayerType(99, gopacket.LayerTypeMetadata{"Dot11MgmtATIM", gopacket.DecodeFunc(decodeDot11MgmtATIM)}) + LayerTypeDot11MgmtDisassociation = gopacket.RegisterLayerType(100, gopacket.LayerTypeMetadata{"Dot11MgmtDisassociation", gopacket.DecodeFunc(decodeDot11MgmtDisassociation)}) + LayerTypeDot11MgmtAuthentication = gopacket.RegisterLayerType(101, gopacket.LayerTypeMetadata{"Dot11MgmtAuthentication", gopacket.DecodeFunc(decodeDot11MgmtAuthentication)}) + LayerTypeDot11MgmtDeauthentication = gopacket.RegisterLayerType(102, gopacket.LayerTypeMetadata{"Dot11MgmtDeauthentication", gopacket.DecodeFunc(decodeDot11MgmtDeauthentication)}) + LayerTypeDot11MgmtAction = gopacket.RegisterLayerType(103, gopacket.LayerTypeMetadata{"Dot11MgmtAction", gopacket.DecodeFunc(decodeDot11MgmtAction)}) + LayerTypeDot11MgmtActionNoAck = gopacket.RegisterLayerType(104, gopacket.LayerTypeMetadata{"Dot11MgmtActionNoAck", gopacket.DecodeFunc(decodeDot11MgmtActionNoAck)}) + LayerTypeDot11MgmtArubaWLAN = gopacket.RegisterLayerType(105, gopacket.LayerTypeMetadata{"Dot11MgmtArubaWLAN", gopacket.DecodeFunc(decodeDot11MgmtArubaWLAN)}) + LayerTypeDot11WEP = gopacket.RegisterLayerType(106, gopacket.LayerTypeMetadata{"Dot11WEP", gopacket.DecodeFunc(decodeDot11WEP)}) + LayerTypeDNS = gopacket.RegisterLayerType(107, gopacket.LayerTypeMetadata{"DNS", gopacket.DecodeFunc(decodeDNS)}) + LayerTypeUSB = gopacket.RegisterLayerType(108, gopacket.LayerTypeMetadata{"USB", gopacket.DecodeFunc(decodeUSB)}) + LayerTypeUSBRequestBlockSetup = gopacket.RegisterLayerType(109, gopacket.LayerTypeMetadata{"USBRequestBlockSetup", gopacket.DecodeFunc(decodeUSBRequestBlockSetup)}) + LayerTypeUSBControl = gopacket.RegisterLayerType(110, gopacket.LayerTypeMetadata{"USBControl", gopacket.DecodeFunc(decodeUSBControl)}) + LayerTypeUSBInterrupt = gopacket.RegisterLayerType(111, gopacket.LayerTypeMetadata{"USBInterrupt", gopacket.DecodeFunc(decodeUSBInterrupt)}) + LayerTypeUSBBulk = gopacket.RegisterLayerType(112, gopacket.LayerTypeMetadata{"USBBulk", gopacket.DecodeFunc(decodeUSBBulk)}) + LayerTypeLinuxSLL = gopacket.RegisterLayerType(113, gopacket.LayerTypeMetadata{"Linux SLL", gopacket.DecodeFunc(decodeLinuxSLL)}) + LayerTypeSFlow = gopacket.RegisterLayerType(114, gopacket.LayerTypeMetadata{"SFlow", gopacket.DecodeFunc(decodeSFlow)}) + LayerTypePrismHeader = gopacket.RegisterLayerType(115, gopacket.LayerTypeMetadata{"Prism monitor mode header", gopacket.DecodeFunc(decodePrismHeader)}) +) + +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, + }) +) diff --git a/vendor/github.com/google/gopacket/layers/linux_sll.go b/vendor/github.com/google/gopacket/layers/linux_sll.go new file mode 100644 index 0000000..b186053 --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/linux_sll.go @@ -0,0 +1,96 @@ +// 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 +} + +// 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.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) +} diff --git a/vendor/github.com/google/gopacket/layers/llc.go b/vendor/github.com/google/gopacket/layers/llc.go new file mode 100644 index 0000000..de986f5 --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/llc.go @@ -0,0 +1,142 @@ +// 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" +) + +// 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 } + +// 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 } + +func decodeLLC(data []byte, p gopacket.PacketBuilder) error { + l := &LLC{ + DSAP: data[0] & 0xFE, + IG: data[0]&0x1 != 0, + SSAP: data[1] & 0xFE, + CR: data[1]&0x1 != 0, + Control: uint16(data[2]), + } + if l.Control&0x1 == 0 || l.Control&0x3 == 0x1 { + 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:] + } + p.AddLayer(l) + if l.DSAP == 0xAA && l.SSAP == 0xAA { + return p.NextDecoder(LayerTypeSNAP) + } + return p.NextDecoder(gopacket.DecodeUnknown) +} + +func decodeSNAP(data []byte, p gopacket.PacketBuilder) error { + s := &SNAP{ + OrganizationalCode: data[:3], + Type: EthernetType(binary.BigEndian.Uint16(data[3:5])), + BaseLayer: BaseLayer{data[:5], data[5:]}, + } + 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 ig_flag, cr_flag byte + var length int + + if l.Control&0xFF00 != 0 { + length = 4 + } else { + length = 3 + } + + if l.DSAP&0x1 != 0 { + return fmt.Errorf("DSAP value invalid, should not include IG flag bit") + } + + if l.SSAP&0x1 != 0 { + return fmt.Errorf("SSAP value invalid, should not include CR flag bit") + } + + if buf, err := b.PrependBytes(length); err != nil { + return err + } else { + ig_flag = 0 + if l.IG { + ig_flag = 0x1 + } + + cr_flag = 0 + if l.CR { + cr_flag = 0x1 + } + + buf[0] = l.DSAP + ig_flag + buf[1] = l.SSAP + cr_flag + + 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 +} diff --git a/vendor/github.com/google/gopacket/layers/lldp.go b/vendor/github.com/google/gopacket/layers/lldp.go new file mode 100644 index 0000000..cc64b44 --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/lldp.go @@ -0,0 +1,1528 @@ +// 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" +) + +// LLDPTLVType is the type of each TLV value in a LinkLayerDiscovery packet. +type LLDPTLVType byte + +const ( + LLDPTLVEnd LLDPTLVType = 0 + LLDPTLVChassisID LLDPTLVType = 1 + LLDPTLVPortID LLDPTLVType = 2 + LLDPTLVTTL LLDPTLVType = 3 + LLDPTLVPortDescription LLDPTLVType = 4 + LLDPTLVSysName LLDPTLVType = 5 + LLDPTLVSysDescription LLDPTLVType = 6 + LLDPTLVSysCapabilities LLDPTLVType = 7 + LLDPTLVMgmtAddress LLDPTLVType = 8 + LLDPTLVOrgSpecific LLDPTLVType = 127 +) + +// LinkLayerDiscoveryValue is a TLV value inside a LinkLayerDiscovery packet layer. +type LinkLayerDiscoveryValue struct { + Type LLDPTLVType + Length uint16 + Value []byte +} + +// LLDPChassisIDSubType specifies the value type for a single LLDPChassisID.ID +type LLDPChassisIDSubType byte + +// LLDP Chassis Types +const ( + LLDPChassisIDSubTypeReserved LLDPChassisIDSubType = 0 + LLDPChassisIDSubTypeChassisComp LLDPChassisIDSubType = 1 + LLDPChassisIDSubtypeIfaceAlias LLDPChassisIDSubType = 2 + LLDPChassisIDSubTypePortComp LLDPChassisIDSubType = 3 + LLDPChassisIDSubTypeMACAddr LLDPChassisIDSubType = 4 + LLDPChassisIDSubTypeNetworkAddr LLDPChassisIDSubType = 5 + LLDPChassisIDSubtypeIfaceName LLDPChassisIDSubType = 6 + LLDPChassisIDSubTypeLocal LLDPChassisIDSubType = 7 +) + +type LLDPChassisID struct { + Subtype LLDPChassisIDSubType + ID []byte +} + +// LLDPPortIDSubType specifies the value type for a single LLDPPortID.ID +type LLDPPortIDSubType byte + +// LLDP PortID types +const ( + LLDPPortIDSubtypeReserved LLDPPortIDSubType = 0 + LLDPPortIDSubtypeIfaceAlias LLDPPortIDSubType = 1 + LLDPPortIDSubtypePortComp LLDPPortIDSubType = 2 + LLDPPortIDSubtypeMACAddr LLDPPortIDSubType = 3 + LLDPPortIDSubtypeNetworkAddr LLDPPortIDSubType = 4 + LLDPPortIDSubtypeIfaceName LLDPPortIDSubType = 5 + LLDPPortIDSubtypeAgentCircuitID LLDPPortIDSubType = 6 + LLDPPortIDSubtypeLocal LLDPPortIDSubType = 7 +) + +type LLDPPortID struct { + Subtype LLDPPortIDSubType + ID []byte +} + +// LinkLayerDiscovery is a packet layer containing the LinkLayer Discovery Protocol. +// See http:http://standards.ieee.org/getieee802/download/802.1AB-2009.pdf +// ChassisID, PortID and TTL are mandatory TLV's. Other values can be decoded +// with DecodeValues() +type LinkLayerDiscovery struct { + BaseLayer + ChassisID LLDPChassisID + PortID LLDPPortID + TTL uint16 + Values []LinkLayerDiscoveryValue +} + +type IEEEOUI uint32 + +// http://standards.ieee.org/develop/regauth/oui/oui.txt +const ( + IEEEOUI8021 IEEEOUI = 0x0080c2 + IEEEOUI8023 IEEEOUI = 0x00120f + IEEEOUI80211 IEEEOUI = 0x000fac + IEEEOUI8021Qbg IEEEOUI = 0x0013BF + IEEEOUICisco2 IEEEOUI = 0x000142 + IEEEOUIMedia IEEEOUI = 0x0012bb // TR-41 + IEEEOUIProfinet IEEEOUI = 0x000ecf + IEEEOUIDCBX IEEEOUI = 0x001b21 +) + +// LLDPOrgSpecificTLV is an Organisation-specific TLV +type LLDPOrgSpecificTLV struct { + OUI IEEEOUI + SubType uint8 + Info []byte +} + +// LLDPCapabilities Types +const ( + LLDPCapsOther uint16 = 1 << 0 + LLDPCapsRepeater uint16 = 1 << 1 + LLDPCapsBridge uint16 = 1 << 2 + LLDPCapsWLANAP uint16 = 1 << 3 + LLDPCapsRouter uint16 = 1 << 4 + LLDPCapsPhone uint16 = 1 << 5 + LLDPCapsDocSis uint16 = 1 << 6 + LLDPCapsStationOnly uint16 = 1 << 7 + LLDPCapsCVLAN uint16 = 1 << 8 + LLDPCapsSVLAN uint16 = 1 << 9 + LLDPCapsTmpr uint16 = 1 << 10 +) + +// LLDPCapabilities represents the capabilities of a device +type LLDPCapabilities struct { + Other bool + Repeater bool + Bridge bool + WLANAP bool + Router bool + Phone bool + DocSis bool + StationOnly bool + CVLAN bool + SVLAN bool + TMPR bool +} + +type LLDPSysCapabilities struct { + SystemCap LLDPCapabilities + EnabledCap LLDPCapabilities +} + +type IANAAddressFamily byte + +// LLDP Management Address Subtypes +// http://www.iana.org/assignments/address-family-numbers/address-family-numbers.xml +const ( + IANAAddressFamilyReserved IANAAddressFamily = 0 + IANAAddressFamilyIPV4 IANAAddressFamily = 1 + IANAAddressFamilyIPV6 IANAAddressFamily = 2 + IANAAddressFamilyNSAP IANAAddressFamily = 3 + IANAAddressFamilyHDLC IANAAddressFamily = 4 + IANAAddressFamilyBBN1822 IANAAddressFamily = 5 + IANAAddressFamily802 IANAAddressFamily = 6 + IANAAddressFamilyE163 IANAAddressFamily = 7 + IANAAddressFamilyE164 IANAAddressFamily = 8 + IANAAddressFamilyF69 IANAAddressFamily = 9 + IANAAddressFamilyX121 IANAAddressFamily = 10 + IANAAddressFamilyIPX IANAAddressFamily = 11 + IANAAddressFamilyAtalk IANAAddressFamily = 12 + IANAAddressFamilyDecnet IANAAddressFamily = 13 + IANAAddressFamilyBanyan IANAAddressFamily = 14 + IANAAddressFamilyE164NSAP IANAAddressFamily = 15 + IANAAddressFamilyDNS IANAAddressFamily = 16 + IANAAddressFamilyDistname IANAAddressFamily = 17 + IANAAddressFamilyASNumber IANAAddressFamily = 18 + IANAAddressFamilyXTPIPV4 IANAAddressFamily = 19 + IANAAddressFamilyXTPIPV6 IANAAddressFamily = 20 + IANAAddressFamilyXTP IANAAddressFamily = 21 + IANAAddressFamilyFcWWPN IANAAddressFamily = 22 + IANAAddressFamilyFcWWNN IANAAddressFamily = 23 + IANAAddressFamilyGWID IANAAddressFamily = 24 + IANAAddressFamilyL2VPN IANAAddressFamily = 25 +) + +type LLDPInterfaceSubtype byte + +// LLDP Interface Subtypes +const ( + LLDPInterfaceSubtypeUnknown LLDPInterfaceSubtype = 1 + LLDPInterfaceSubtypeifIndex LLDPInterfaceSubtype = 2 + LLDPInterfaceSubtypeSysPort LLDPInterfaceSubtype = 3 +) + +type LLDPMgmtAddress struct { + Subtype IANAAddressFamily + Address []byte + InterfaceSubtype LLDPInterfaceSubtype + InterfaceNumber uint32 + OID string +} + +// LinkLayerDiscoveryInfo represents the decoded details for a set of LinkLayerDiscoveryValues +// Organisation-specific TLV's can be decoded using the various Decode() methods +type LinkLayerDiscoveryInfo struct { + BaseLayer + PortDescription string + SysName string + SysDescription string + SysCapabilities LLDPSysCapabilities + MgmtAddress LLDPMgmtAddress + OrgTLVs []LLDPOrgSpecificTLV // Private TLVs + Unknown []LinkLayerDiscoveryValue // undecoded TLVs +} + +/// IEEE 802.1 TLV Subtypes +const ( + LLDP8021SubtypePortVLANID uint8 = 1 + LLDP8021SubtypeProtocolVLANID uint8 = 2 + LLDP8021SubtypeVLANName uint8 = 3 + LLDP8021SubtypeProtocolIdentity uint8 = 4 + LLDP8021SubtypeVDIUsageDigest uint8 = 5 + LLDP8021SubtypeManagementVID uint8 = 6 + LLDP8021SubtypeLinkAggregation uint8 = 7 +) + +// VLAN Port Protocol ID options +const ( + LLDPProtocolVLANIDCapability byte = 1 << 1 + LLDPProtocolVLANIDStatus byte = 1 << 2 +) + +type PortProtocolVLANID struct { + Supported bool + Enabled bool + ID uint16 +} + +type VLANName struct { + ID uint16 + Name string +} + +type ProtocolIdentity []byte + +// LACP options +const ( + LLDPAggregationCapability byte = 1 << 0 + LLDPAggregationStatus byte = 1 << 1 +) + +// IEEE 802 Link Aggregation parameters +type LLDPLinkAggregation struct { + Supported bool + Enabled bool + PortID uint32 +} + +// LLDPInfo8021 represents the information carried in 802.1 Org-specific TLVs +type LLDPInfo8021 struct { + PVID uint16 + PPVIDs []PortProtocolVLANID + VLANNames []VLANName + ProtocolIdentities []ProtocolIdentity + VIDUsageDigest uint32 + ManagementVID uint16 + LinkAggregation LLDPLinkAggregation +} + +// IEEE 802.3 TLV Subtypes +const ( + LLDP8023SubtypeMACPHY uint8 = 1 + LLDP8023SubtypeMDIPower uint8 = 2 + LLDP8023SubtypeLinkAggregation uint8 = 3 + LLDP8023SubtypeMTU uint8 = 4 +) + +// MACPHY options +const ( + LLDPMACPHYCapability byte = 1 << 0 + LLDPMACPHYStatus byte = 1 << 1 +) + +// From IANA-MAU-MIB (introduced by RFC 4836) - dot3MauType +const ( + LLDPMAUTypeUnknown uint16 = 0 + LLDPMAUTypeAUI uint16 = 1 + LLDPMAUType10Base5 uint16 = 2 + LLDPMAUTypeFOIRL uint16 = 3 + LLDPMAUType10Base2 uint16 = 4 + LLDPMAUType10BaseT uint16 = 5 + LLDPMAUType10BaseFP uint16 = 6 + LLDPMAUType10BaseFB uint16 = 7 + LLDPMAUType10BaseFL uint16 = 8 + LLDPMAUType10BROAD36 uint16 = 9 + LLDPMAUType10BaseT_HD uint16 = 10 + LLDPMAUType10BaseT_FD uint16 = 11 + LLDPMAUType10BaseFL_HD uint16 = 12 + LLDPMAUType10BaseFL_FD uint16 = 13 + LLDPMAUType100BaseT4 uint16 = 14 + LLDPMAUType100BaseTX_HD uint16 = 15 + LLDPMAUType100BaseTX_FD uint16 = 16 + LLDPMAUType100BaseFX_HD uint16 = 17 + LLDPMAUType100BaseFX_FD uint16 = 18 + LLDPMAUType100BaseT2_HD uint16 = 19 + LLDPMAUType100BaseT2_FD uint16 = 20 + LLDPMAUType1000BaseX_HD uint16 = 21 + LLDPMAUType1000BaseX_FD uint16 = 22 + LLDPMAUType1000BaseLX_HD uint16 = 23 + LLDPMAUType1000BaseLX_FD uint16 = 24 + LLDPMAUType1000BaseSX_HD uint16 = 25 + LLDPMAUType1000BaseSX_FD uint16 = 26 + LLDPMAUType1000BaseCX_HD uint16 = 27 + LLDPMAUType1000BaseCX_FD uint16 = 28 + LLDPMAUType1000BaseT_HD uint16 = 29 + LLDPMAUType1000BaseT_FD uint16 = 30 + LLDPMAUType10GBaseX uint16 = 31 + LLDPMAUType10GBaseLX4 uint16 = 32 + LLDPMAUType10GBaseR uint16 = 33 + LLDPMAUType10GBaseER uint16 = 34 + LLDPMAUType10GBaseLR uint16 = 35 + LLDPMAUType10GBaseSR uint16 = 36 + LLDPMAUType10GBaseW uint16 = 37 + LLDPMAUType10GBaseEW uint16 = 38 + LLDPMAUType10GBaseLW uint16 = 39 + LLDPMAUType10GBaseSW uint16 = 40 + LLDPMAUType10GBaseCX4 uint16 = 41 + LLDPMAUType2BaseTL uint16 = 42 + LLDPMAUType10PASS_TS uint16 = 43 + LLDPMAUType100BaseBX10D uint16 = 44 + LLDPMAUType100BaseBX10U uint16 = 45 + LLDPMAUType100BaseLX10 uint16 = 46 + LLDPMAUType1000BaseBX10D uint16 = 47 + LLDPMAUType1000BaseBX10U uint16 = 48 + LLDPMAUType1000BaseLX10 uint16 = 49 + LLDPMAUType1000BasePX10D uint16 = 50 + LLDPMAUType1000BasePX10U uint16 = 51 + LLDPMAUType1000BasePX20D uint16 = 52 + LLDPMAUType1000BasePX20U uint16 = 53 + LLDPMAUType10GBaseT uint16 = 54 + LLDPMAUType10GBaseLRM uint16 = 55 + LLDPMAUType1000BaseKX uint16 = 56 + LLDPMAUType10GBaseKX4 uint16 = 57 + LLDPMAUType10GBaseKR uint16 = 58 + LLDPMAUType10_1GBasePRX_D1 uint16 = 59 + LLDPMAUType10_1GBasePRX_D2 uint16 = 60 + LLDPMAUType10_1GBasePRX_D3 uint16 = 61 + LLDPMAUType10_1GBasePRX_U1 uint16 = 62 + LLDPMAUType10_1GBasePRX_U2 uint16 = 63 + LLDPMAUType10_1GBasePRX_U3 uint16 = 64 + LLDPMAUType10GBasePR_D1 uint16 = 65 + LLDPMAUType10GBasePR_D2 uint16 = 66 + LLDPMAUType10GBasePR_D3 uint16 = 67 + LLDPMAUType10GBasePR_U1 uint16 = 68 + LLDPMAUType10GBasePR_U3 uint16 = 69 +) + +// From RFC 3636 - ifMauAutoNegCapAdvertisedBits +const ( + LLDPMAUPMDOther uint16 = 1 << 15 + LLDPMAUPMD10BaseT uint16 = 1 << 14 + LLDPMAUPMD10BaseT_FD uint16 = 1 << 13 + LLDPMAUPMD100BaseT4 uint16 = 1 << 12 + LLDPMAUPMD100BaseTX uint16 = 1 << 11 + LLDPMAUPMD100BaseTX_FD uint16 = 1 << 10 + LLDPMAUPMD100BaseT2 uint16 = 1 << 9 + LLDPMAUPMD100BaseT2_FD uint16 = 1 << 8 + LLDPMAUPMDFDXPAUSE uint16 = 1 << 7 + LLDPMAUPMDFDXAPAUSE uint16 = 1 << 6 + LLDPMAUPMDFDXSPAUSE uint16 = 1 << 5 + LLDPMAUPMDFDXBPAUSE uint16 = 1 << 4 + LLDPMAUPMD1000BaseX uint16 = 1 << 3 + LLDPMAUPMD1000BaseX_FD uint16 = 1 << 2 + LLDPMAUPMD1000BaseT uint16 = 1 << 1 + LLDPMAUPMD1000BaseT_FD uint16 = 1 << 0 +) + +// Inverted ifMauAutoNegCapAdvertisedBits if required +// (Some manufacturers misinterpreted the spec - +// see https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=1455) +const ( + LLDPMAUPMDOtherInv uint16 = 1 << 0 + LLDPMAUPMD10BaseTInv uint16 = 1 << 1 + LLDPMAUPMD10BaseT_FDInv uint16 = 1 << 2 + LLDPMAUPMD100BaseT4Inv uint16 = 1 << 3 + LLDPMAUPMD100BaseTXInv uint16 = 1 << 4 + LLDPMAUPMD100BaseTX_FDInv uint16 = 1 << 5 + LLDPMAUPMD100BaseT2Inv uint16 = 1 << 6 + LLDPMAUPMD100BaseT2_FDInv uint16 = 1 << 7 + LLDPMAUPMDFDXPAUSEInv uint16 = 1 << 8 + LLDPMAUPMDFDXAPAUSEInv uint16 = 1 << 9 + LLDPMAUPMDFDXSPAUSEInv uint16 = 1 << 10 + LLDPMAUPMDFDXBPAUSEInv uint16 = 1 << 11 + LLDPMAUPMD1000BaseXInv uint16 = 1 << 12 + LLDPMAUPMD1000BaseX_FDInv uint16 = 1 << 13 + LLDPMAUPMD1000BaseTInv uint16 = 1 << 14 + LLDPMAUPMD1000BaseT_FDInv uint16 = 1 << 15 +) + +type LLDPMACPHYConfigStatus struct { + AutoNegSupported bool + AutoNegEnabled bool + AutoNegCapability uint16 + MAUType uint16 +} + +// MDI Power options +const ( + LLDPMDIPowerPortClass byte = 1 << 0 + LLDPMDIPowerCapability byte = 1 << 1 + LLDPMDIPowerStatus byte = 1 << 2 + LLDPMDIPowerPairsAbility byte = 1 << 3 +) + +type LLDPPowerType byte + +type LLDPPowerSource byte + +type LLDPPowerPriority byte + +const ( + LLDPPowerPriorityUnknown LLDPPowerPriority = 0 + LLDPPowerPriorityMedium LLDPPowerPriority = 1 + LLDPPowerPriorityHigh LLDPPowerPriority = 2 + LLDPPowerPriorityLow LLDPPowerPriority = 3 +) + +type LLDPPowerViaMDI8023 struct { + PortClassPSE bool // false = PD + PSESupported bool + PSEEnabled bool + PSEPairsAbility bool + PSEPowerPair uint8 + PSEClass uint8 + Type LLDPPowerType + Source LLDPPowerSource + Priority LLDPPowerPriority + Requested uint16 // 1-510 Watts + Allocated uint16 // 1-510 Watts +} + +// LLDPInfo8023 represents the information carried in 802.3 Org-specific TLVs +type LLDPInfo8023 struct { + MACPHYConfigStatus LLDPMACPHYConfigStatus + PowerViaMDI LLDPPowerViaMDI8023 + LinkAggregation LLDPLinkAggregation + MTU uint16 +} + +// IEEE 802.1Qbg TLV Subtypes +const ( + LLDP8021QbgEVB uint8 = 0 + LLDP8021QbgCDCP uint8 = 1 + LLDP8021QbgVDP uint8 = 2 + LLDP8021QbgEVB22 uint8 = 13 +) + +// LLDPEVBCapabilities Types +const ( + LLDPEVBCapsSTD uint16 = 1 << 7 + LLDPEVBCapsRR uint16 = 1 << 6 + LLDPEVBCapsRTE uint16 = 1 << 2 + LLDPEVBCapsECP uint16 = 1 << 1 + LLDPEVBCapsVDP uint16 = 1 << 0 +) + +// LLDPEVBCapabilities represents the EVB capabilities of a device +type LLDPEVBCapabilities struct { + StandardBridging bool + ReflectiveRelay bool + RetransmissionTimerExponent bool + EdgeControlProtocol bool + VSIDiscoveryProtocol bool +} + +type LLDPEVBSettings struct { + Supported LLDPEVBCapabilities + Enabled LLDPEVBCapabilities + SupportedVSIs uint16 + ConfiguredVSIs uint16 + RTEExponent uint8 +} + +// LLDPInfo8021Qbg represents the information carried in 802.1Qbg Org-specific TLVs +type LLDPInfo8021Qbg struct { + EVBSettings LLDPEVBSettings +} + +type LLDPMediaSubtype uint8 + +// Media TLV Subtypes +const ( + LLDPMediaTypeCapabilities LLDPMediaSubtype = 1 + LLDPMediaTypeNetwork LLDPMediaSubtype = 2 + LLDPMediaTypeLocation LLDPMediaSubtype = 3 + LLDPMediaTypePower LLDPMediaSubtype = 4 + LLDPMediaTypeHardware LLDPMediaSubtype = 5 + LLDPMediaTypeFirmware LLDPMediaSubtype = 6 + LLDPMediaTypeSoftware LLDPMediaSubtype = 7 + LLDPMediaTypeSerial LLDPMediaSubtype = 8 + LLDPMediaTypeManufacturer LLDPMediaSubtype = 9 + LLDPMediaTypeModel LLDPMediaSubtype = 10 + LLDPMediaTypeAssetID LLDPMediaSubtype = 11 +) + +type LLDPMediaClass uint8 + +// Media Class Values +const ( + LLDPMediaClassUndefined LLDPMediaClass = 0 + LLDPMediaClassEndpointI LLDPMediaClass = 1 + LLDPMediaClassEndpointII LLDPMediaClass = 2 + LLDPMediaClassEndpointIII LLDPMediaClass = 3 + LLDPMediaClassNetwork LLDPMediaClass = 4 +) + +// LLDPMediaCapabilities Types +const ( + LLDPMediaCapsLLDP uint16 = 1 << 0 + LLDPMediaCapsNetwork uint16 = 1 << 1 + LLDPMediaCapsLocation uint16 = 1 << 2 + LLDPMediaCapsPowerPSE uint16 = 1 << 3 + LLDPMediaCapsPowerPD uint16 = 1 << 4 + LLDPMediaCapsInventory uint16 = 1 << 5 +) + +// LLDPMediaCapabilities represents the LLDP Media capabilities of a device +type LLDPMediaCapabilities struct { + Capabilities bool + NetworkPolicy bool + Location bool + PowerPSE bool + PowerPD bool + Inventory bool + Class LLDPMediaClass +} + +type LLDPApplicationType uint8 + +const ( + LLDPAppTypeReserved LLDPApplicationType = 0 + LLDPAppTypeVoice LLDPApplicationType = 1 + LLDPappTypeVoiceSignaling LLDPApplicationType = 2 + LLDPappTypeGuestVoice LLDPApplicationType = 3 + LLDPappTypeGuestVoiceSignaling LLDPApplicationType = 4 + LLDPappTypeSoftphoneVoice LLDPApplicationType = 5 + LLDPappTypeVideoConferencing LLDPApplicationType = 6 + LLDPappTypeStreamingVideo LLDPApplicationType = 7 + LLDPappTypeVideoSignaling LLDPApplicationType = 8 +) + +type LLDPNetworkPolicy struct { + ApplicationType LLDPApplicationType + Defined bool + Tagged bool + VLANId uint16 + L2Priority uint16 + DSCPValue uint8 +} + +type LLDPLocationFormat uint8 + +const ( + LLDPLocationFormatInvalid LLDPLocationFormat = 0 + LLDPLocationFormatCoordinate LLDPLocationFormat = 1 + LLDPLocationFormatAddress LLDPLocationFormat = 2 + LLDPLocationFormatECS LLDPLocationFormat = 3 +) + +type LLDPLocationAddressWhat uint8 + +const ( + LLDPLocationAddressWhatDHCP LLDPLocationAddressWhat = 0 + LLDPLocationAddressWhatNetwork LLDPLocationAddressWhat = 1 + LLDPLocationAddressWhatClient LLDPLocationAddressWhat = 2 +) + +type LLDPLocationAddressType uint8 + +const ( + LLDPLocationAddressTypeLanguage LLDPLocationAddressType = 0 + LLDPLocationAddressTypeNational LLDPLocationAddressType = 1 + LLDPLocationAddressTypeCounty LLDPLocationAddressType = 2 + LLDPLocationAddressTypeCity LLDPLocationAddressType = 3 + LLDPLocationAddressTypeCityDivision LLDPLocationAddressType = 4 + LLDPLocationAddressTypeNeighborhood LLDPLocationAddressType = 5 + LLDPLocationAddressTypeStreet LLDPLocationAddressType = 6 + LLDPLocationAddressTypeLeadingStreet LLDPLocationAddressType = 16 + LLDPLocationAddressTypeTrailingStreet LLDPLocationAddressType = 17 + LLDPLocationAddressTypeStreetSuffix LLDPLocationAddressType = 18 + LLDPLocationAddressTypeHouseNum LLDPLocationAddressType = 19 + LLDPLocationAddressTypeHouseSuffix LLDPLocationAddressType = 20 + LLDPLocationAddressTypeLandmark LLDPLocationAddressType = 21 + LLDPLocationAddressTypeAdditional LLDPLocationAddressType = 22 + LLDPLocationAddressTypeName LLDPLocationAddressType = 23 + LLDPLocationAddressTypePostal LLDPLocationAddressType = 24 + LLDPLocationAddressTypeBuilding LLDPLocationAddressType = 25 + LLDPLocationAddressTypeUnit LLDPLocationAddressType = 26 + LLDPLocationAddressTypeFloor LLDPLocationAddressType = 27 + LLDPLocationAddressTypeRoom LLDPLocationAddressType = 28 + LLDPLocationAddressTypePlace LLDPLocationAddressType = 29 + LLDPLocationAddressTypeScript LLDPLocationAddressType = 128 +) + +type LLDPLocationCoordinate struct { + LatitudeResolution uint8 + Latitude uint64 + LongitudeResolution uint8 + Longitude uint64 + AltitudeType uint8 + AltitudeResolution uint16 + Altitude uint32 + Datum uint8 +} + +type LLDPLocationAddressLine struct { + Type LLDPLocationAddressType + Value string +} + +type LLDPLocationAddress struct { + What LLDPLocationAddressWhat + CountryCode string + AddressLines []LLDPLocationAddressLine +} + +type LLDPLocationECS struct { + ELIN string +} + +// LLDP represents a physical location. +// Only one of the embedded types will contain values, depending on Format. +type LLDPLocation struct { + Format LLDPLocationFormat + Coordinate LLDPLocationCoordinate + Address LLDPLocationAddress + ECS LLDPLocationECS +} + +type LLDPPowerViaMDI struct { + Type LLDPPowerType + Source LLDPPowerSource + Priority LLDPPowerPriority + Value uint16 +} + +// LLDPInfoMedia represents the information carried in TR-41 Org-specific TLVs +type LLDPInfoMedia struct { + MediaCapabilities LLDPMediaCapabilities + NetworkPolicy LLDPNetworkPolicy + Location LLDPLocation + PowerViaMDI LLDPPowerViaMDI + HardwareRevision string + FirmwareRevision string + SoftwareRevision string + SerialNumber string + Manufacturer string + Model string + AssetID string +} + +type LLDPCisco2Subtype uint8 + +// Cisco2 TLV Subtypes +const ( + LLDPCisco2PowerViaMDI LLDPCisco2Subtype = 1 +) + +const ( + LLDPCiscoPSESupport uint8 = 1 << 0 + LLDPCiscoArchShared uint8 = 1 << 1 + LLDPCiscoPDSparePair uint8 = 1 << 2 + LLDPCiscoPSESparePair uint8 = 1 << 3 +) + +// LLDPInfoCisco2 represents the information carried in Cisco Org-specific TLVs +type LLDPInfoCisco2 struct { + PSEFourWirePoESupported bool + PDSparePairArchitectureShared bool + PDRequestSparePairPoEOn bool + PSESparePairPoEOn bool +} + +// Profinet Subtypes +type LLDPProfinetSubtype uint8 + +const ( + LLDPProfinetPNIODelay LLDPProfinetSubtype = 1 + LLDPProfinetPNIOPortStatus LLDPProfinetSubtype = 2 + LLDPProfinetPNIOMRPPortStatus LLDPProfinetSubtype = 4 + LLDPProfinetPNIOChassisMAC LLDPProfinetSubtype = 5 + LLDPProfinetPNIOPTCPStatus LLDPProfinetSubtype = 6 +) + +type LLDPPNIODelay struct { + RXLocal uint32 + RXRemote uint32 + TXLocal uint32 + TXRemote uint32 + CableLocal uint32 +} + +type LLDPPNIOPortStatus struct { + Class2 uint16 + Class3 uint16 +} + +type LLDPPNIOMRPPortStatus struct { + UUID []byte + Status uint16 +} + +type LLDPPNIOPTCPStatus struct { + MasterAddress []byte + SubdomainUUID []byte + IRDataUUID []byte + PeriodValid bool + PeriodLength uint32 + RedPeriodValid bool + RedPeriodBegin uint32 + OrangePeriodValid bool + OrangePeriodBegin uint32 + GreenPeriodValid bool + GreenPeriodBegin uint32 +} + +// LLDPInfoProfinet represents the information carried in Profinet Org-specific TLVs +type LLDPInfoProfinet struct { + PNIODelay LLDPPNIODelay + PNIOPortStatus LLDPPNIOPortStatus + PNIOMRPPortStatus LLDPPNIOMRPPortStatus + ChassisMAC []byte + PNIOPTCPStatus LLDPPNIOPTCPStatus +} + +// LayerType returns gopacket.LayerTypeLinkLayerDiscovery. +func (c *LinkLayerDiscovery) LayerType() gopacket.LayerType { + return LayerTypeLinkLayerDiscovery +} + +func decodeLinkLayerDiscovery(data []byte, p gopacket.PacketBuilder) error { + var vals []LinkLayerDiscoveryValue + vData := data[0:] + for len(vData) > 0 { + nbit := vData[0] & 0x01 + t := LLDPTLVType(vData[0] >> 1) + val := LinkLayerDiscoveryValue{Type: t, Length: uint16(nbit<<8 + vData[1])} + if val.Length > 0 { + val.Value = vData[2 : val.Length+2] + } + vals = append(vals, val) + if t == LLDPTLVEnd { + break + } + if len(vData) < int(2+val.Length) { + return fmt.Errorf("Malformed LinkLayerDiscovery Header") + } + vData = vData[2+val.Length:] + } + if len(vals) < 4 { + return fmt.Errorf("Missing mandatory LinkLayerDiscovery TLV") + } + c := &LinkLayerDiscovery{} + gotEnd := false + for _, v := range vals { + switch v.Type { + case LLDPTLVEnd: + gotEnd = true + case LLDPTLVChassisID: + if len(v.Value) < 2 { + return fmt.Errorf("Malformed LinkLayerDiscovery ChassisID TLV") + } + c.ChassisID.Subtype = LLDPChassisIDSubType(v.Value[0]) + c.ChassisID.ID = v.Value[1:] + case LLDPTLVPortID: + if len(v.Value) < 2 { + return fmt.Errorf("Malformed LinkLayerDiscovery PortID TLV") + } + c.PortID.Subtype = LLDPPortIDSubType(v.Value[0]) + c.PortID.ID = v.Value[1:] + case LLDPTLVTTL: + if len(v.Value) < 2 { + return fmt.Errorf("Malformed LinkLayerDiscovery TTL TLV") + } + c.TTL = binary.BigEndian.Uint16(v.Value[0:2]) + default: + c.Values = append(c.Values, v) + } + } + if c.ChassisID.Subtype == 0 || c.PortID.Subtype == 0 || !gotEnd { + return fmt.Errorf("Missing mandatory LinkLayerDiscovery TLV") + } + c.Contents = data + p.AddLayer(c) + + info := &LinkLayerDiscoveryInfo{} + p.AddLayer(info) + for _, v := range c.Values { + switch v.Type { + case LLDPTLVPortDescription: + info.PortDescription = string(v.Value) + case LLDPTLVSysName: + info.SysName = string(v.Value) + case LLDPTLVSysDescription: + info.SysDescription = string(v.Value) + case LLDPTLVSysCapabilities: + if err := checkLLDPTLVLen(v, 4); err != nil { + return err + } + info.SysCapabilities.SystemCap = getCapabilities(binary.BigEndian.Uint16(v.Value[0:2])) + info.SysCapabilities.EnabledCap = getCapabilities(binary.BigEndian.Uint16(v.Value[2:4])) + case LLDPTLVMgmtAddress: + if err := checkLLDPTLVLen(v, 9); err != nil { + return err + } + mlen := v.Value[0] + if err := checkLLDPTLVLen(v, int(mlen+7)); err != nil { + return err + } + info.MgmtAddress.Subtype = IANAAddressFamily(v.Value[1]) + info.MgmtAddress.Address = v.Value[2 : mlen+1] + info.MgmtAddress.InterfaceSubtype = LLDPInterfaceSubtype(v.Value[mlen+1]) + info.MgmtAddress.InterfaceNumber = binary.BigEndian.Uint32(v.Value[mlen+2 : mlen+6]) + olen := v.Value[mlen+6] + if err := checkLLDPTLVLen(v, int(mlen+6+olen)); err != nil { + return err + } + info.MgmtAddress.OID = string(v.Value[mlen+9 : mlen+9+olen]) + case LLDPTLVOrgSpecific: + if err := checkLLDPTLVLen(v, 4); err != nil { + return err + } + info.OrgTLVs = append(info.OrgTLVs, LLDPOrgSpecificTLV{IEEEOUI(binary.BigEndian.Uint32(append([]byte{byte(0)}, v.Value[0:3]...))), uint8(v.Value[3]), v.Value[4:]}) + } + } + return nil +} + +func (l *LinkLayerDiscoveryInfo) Decode8021() (info LLDPInfo8021, err error) { + for _, o := range l.OrgTLVs { + if o.OUI != IEEEOUI8021 { + continue + } + switch o.SubType { + case LLDP8021SubtypePortVLANID: + if err = checkLLDPOrgSpecificLen(o, 2); err != nil { + return + } + info.PVID = binary.BigEndian.Uint16(o.Info[0:2]) + case LLDP8021SubtypeProtocolVLANID: + if err = checkLLDPOrgSpecificLen(o, 3); err != nil { + return + } + sup := (o.Info[0]&LLDPProtocolVLANIDCapability > 0) + en := (o.Info[0]&LLDPProtocolVLANIDStatus > 0) + id := binary.BigEndian.Uint16(o.Info[1:3]) + info.PPVIDs = append(info.PPVIDs, PortProtocolVLANID{sup, en, id}) + case LLDP8021SubtypeVLANName: + if err = checkLLDPOrgSpecificLen(o, 2); err != nil { + return + } + id := binary.BigEndian.Uint16(o.Info[0:2]) + info.VLANNames = append(info.VLANNames, VLANName{id, string(o.Info[3:])}) + case LLDP8021SubtypeProtocolIdentity: + if err = checkLLDPOrgSpecificLen(o, 1); err != nil { + return + } + l := int(o.Info[0]) + if l > 0 { + info.ProtocolIdentities = append(info.ProtocolIdentities, o.Info[1:1+l]) + } + case LLDP8021SubtypeVDIUsageDigest: + if err = checkLLDPOrgSpecificLen(o, 4); err != nil { + return + } + info.VIDUsageDigest = binary.BigEndian.Uint32(o.Info[0:4]) + case LLDP8021SubtypeManagementVID: + if err = checkLLDPOrgSpecificLen(o, 2); err != nil { + return + } + info.ManagementVID = binary.BigEndian.Uint16(o.Info[0:2]) + case LLDP8021SubtypeLinkAggregation: + if err = checkLLDPOrgSpecificLen(o, 5); err != nil { + return + } + sup := (o.Info[0]&LLDPAggregationCapability > 0) + en := (o.Info[0]&LLDPAggregationStatus > 0) + info.LinkAggregation = LLDPLinkAggregation{sup, en, binary.BigEndian.Uint32(o.Info[1:5])} + } + } + return +} + +func (l *LinkLayerDiscoveryInfo) Decode8023() (info LLDPInfo8023, err error) { + for _, o := range l.OrgTLVs { + if o.OUI != IEEEOUI8023 { + continue + } + switch o.SubType { + case LLDP8023SubtypeMACPHY: + if err = checkLLDPOrgSpecificLen(o, 5); err != nil { + return + } + sup := (o.Info[0]&LLDPMACPHYCapability > 0) + en := (o.Info[0]&LLDPMACPHYStatus > 0) + ca := binary.BigEndian.Uint16(o.Info[1:3]) + mau := binary.BigEndian.Uint16(o.Info[3:5]) + info.MACPHYConfigStatus = LLDPMACPHYConfigStatus{sup, en, ca, mau} + case LLDP8023SubtypeMDIPower: + if err = checkLLDPOrgSpecificLen(o, 3); err != nil { + return + } + info.PowerViaMDI.PortClassPSE = (o.Info[0]&LLDPMDIPowerPortClass > 0) + info.PowerViaMDI.PSESupported = (o.Info[0]&LLDPMDIPowerCapability > 0) + info.PowerViaMDI.PSEEnabled = (o.Info[0]&LLDPMDIPowerStatus > 0) + info.PowerViaMDI.PSEPairsAbility = (o.Info[0]&LLDPMDIPowerPairsAbility > 0) + info.PowerViaMDI.PSEPowerPair = uint8(o.Info[1]) + info.PowerViaMDI.PSEClass = uint8(o.Info[2]) + if len(o.Info) >= 7 { + info.PowerViaMDI.Type = LLDPPowerType((o.Info[3] & 0xc0) >> 6) + info.PowerViaMDI.Source = LLDPPowerSource((o.Info[3] & 0x30) >> 4) + if info.PowerViaMDI.Type == 1 || info.PowerViaMDI.Type == 3 { + info.PowerViaMDI.Source += 128 // For Stringify purposes + } + info.PowerViaMDI.Priority = LLDPPowerPriority(o.Info[3] & 0x0f) + info.PowerViaMDI.Requested = binary.BigEndian.Uint16(o.Info[4:6]) + info.PowerViaMDI.Allocated = binary.BigEndian.Uint16(o.Info[6:8]) + } + case LLDP8023SubtypeLinkAggregation: + if err = checkLLDPOrgSpecificLen(o, 5); err != nil { + return + } + sup := (o.Info[0]&LLDPAggregationCapability > 0) + en := (o.Info[0]&LLDPAggregationStatus > 0) + info.LinkAggregation = LLDPLinkAggregation{sup, en, binary.BigEndian.Uint32(o.Info[1:5])} + case LLDP8023SubtypeMTU: + if err = checkLLDPOrgSpecificLen(o, 2); err != nil { + return + } + info.MTU = binary.BigEndian.Uint16(o.Info[0:2]) + } + } + return +} + +func (l *LinkLayerDiscoveryInfo) Decode8021Qbg() (info LLDPInfo8021Qbg, err error) { + for _, o := range l.OrgTLVs { + if o.OUI != IEEEOUI8021Qbg { + continue + } + switch o.SubType { + case LLDP8021QbgEVB: + if err = checkLLDPOrgSpecificLen(o, 9); err != nil { + return + } + info.EVBSettings.Supported = getEVBCapabilities(binary.BigEndian.Uint16(o.Info[0:2])) + info.EVBSettings.Enabled = getEVBCapabilities(binary.BigEndian.Uint16(o.Info[2:4])) + info.EVBSettings.SupportedVSIs = binary.BigEndian.Uint16(o.Info[4:6]) + info.EVBSettings.ConfiguredVSIs = binary.BigEndian.Uint16(o.Info[6:8]) + info.EVBSettings.RTEExponent = uint8(o.Info[8]) + } + } + return +} + +func (l *LinkLayerDiscoveryInfo) DecodeMedia() (info LLDPInfoMedia, err error) { + for _, o := range l.OrgTLVs { + if o.OUI != IEEEOUIMedia { + continue + } + switch LLDPMediaSubtype(o.SubType) { + case LLDPMediaTypeCapabilities: + if err = checkLLDPOrgSpecificLen(o, 3); err != nil { + return + } + b := binary.BigEndian.Uint16(o.Info[0:2]) + info.MediaCapabilities.Capabilities = (b & LLDPMediaCapsLLDP) > 0 + info.MediaCapabilities.NetworkPolicy = (b & LLDPMediaCapsNetwork) > 0 + info.MediaCapabilities.Location = (b & LLDPMediaCapsLocation) > 0 + info.MediaCapabilities.PowerPSE = (b & LLDPMediaCapsPowerPSE) > 0 + info.MediaCapabilities.PowerPD = (b & LLDPMediaCapsPowerPD) > 0 + info.MediaCapabilities.Inventory = (b & LLDPMediaCapsInventory) > 0 + info.MediaCapabilities.Class = LLDPMediaClass(o.Info[2]) + case LLDPMediaTypeNetwork: + if err = checkLLDPOrgSpecificLen(o, 4); err != nil { + return + } + info.NetworkPolicy.ApplicationType = LLDPApplicationType(o.Info[0]) + b := binary.BigEndian.Uint16(o.Info[1:3]) + info.NetworkPolicy.Defined = (b & 0x8000) == 0 + info.NetworkPolicy.Tagged = (b & 0x4000) > 0 + info.NetworkPolicy.VLANId = (b & 0x1ffe) >> 1 + b = binary.BigEndian.Uint16(o.Info[2:4]) + info.NetworkPolicy.L2Priority = (b & 0x01c0) >> 6 + info.NetworkPolicy.DSCPValue = uint8(o.Info[3] & 0x3f) + case LLDPMediaTypeLocation: + if err = checkLLDPOrgSpecificLen(o, 1); err != nil { + return + } + info.Location.Format = LLDPLocationFormat(o.Info[0]) + o.Info = o.Info[1:] + switch info.Location.Format { + case LLDPLocationFormatCoordinate: + if err = checkLLDPOrgSpecificLen(o, 16); err != nil { + return + } + info.Location.Coordinate.LatitudeResolution = uint8(o.Info[0]&0xfc) >> 2 + b := binary.BigEndian.Uint64(o.Info[0:8]) + info.Location.Coordinate.Latitude = (b & 0x03ffffffff000000) >> 24 + info.Location.Coordinate.LongitudeResolution = uint8(o.Info[5]&0xfc) >> 2 + b = binary.BigEndian.Uint64(o.Info[5:13]) + info.Location.Coordinate.Longitude = (b & 0x03ffffffff000000) >> 24 + info.Location.Coordinate.AltitudeType = uint8((o.Info[10] & 0x30) >> 4) + b1 := binary.BigEndian.Uint16(o.Info[10:12]) + info.Location.Coordinate.AltitudeResolution = (b1 & 0xfc0) >> 6 + b2 := binary.BigEndian.Uint32(o.Info[11:15]) + info.Location.Coordinate.Altitude = b2 & 0x3fffffff + info.Location.Coordinate.Datum = uint8(o.Info[15]) + case LLDPLocationFormatAddress: + if err = checkLLDPOrgSpecificLen(o, 3); err != nil { + return + } + //ll := uint8(o.Info[0]) + info.Location.Address.What = LLDPLocationAddressWhat(o.Info[1]) + info.Location.Address.CountryCode = string(o.Info[2:4]) + data := o.Info[4:] + for len(data) > 1 { + aType := LLDPLocationAddressType(data[0]) + aLen := int(data[1]) + if len(data) >= aLen+2 { + info.Location.Address.AddressLines = append(info.Location.Address.AddressLines, LLDPLocationAddressLine{aType, string(data[2 : aLen+2])}) + data = data[aLen+2:] + } else { + break + } + } + case LLDPLocationFormatECS: + info.Location.ECS.ELIN = string(o.Info) + } + case LLDPMediaTypePower: + if err = checkLLDPOrgSpecificLen(o, 3); err != nil { + return + } + info.PowerViaMDI.Type = LLDPPowerType((o.Info[0] & 0xc0) >> 6) + info.PowerViaMDI.Source = LLDPPowerSource((o.Info[0] & 0x30) >> 4) + if info.PowerViaMDI.Type == 1 || info.PowerViaMDI.Type == 3 { + info.PowerViaMDI.Source += 128 // For Stringify purposes + } + info.PowerViaMDI.Priority = LLDPPowerPriority(o.Info[0] & 0x0f) + info.PowerViaMDI.Value = binary.BigEndian.Uint16(o.Info[1:3]) * 100 // 0 to 102.3 w, 0.1W increments + case LLDPMediaTypeHardware: + info.HardwareRevision = string(o.Info) + case LLDPMediaTypeFirmware: + info.FirmwareRevision = string(o.Info) + case LLDPMediaTypeSoftware: + info.SoftwareRevision = string(o.Info) + case LLDPMediaTypeSerial: + info.SerialNumber = string(o.Info) + case LLDPMediaTypeManufacturer: + info.Manufacturer = string(o.Info) + case LLDPMediaTypeModel: + info.Model = string(o.Info) + case LLDPMediaTypeAssetID: + info.AssetID = string(o.Info) + } + } + return +} + +func (l *LinkLayerDiscoveryInfo) DecodeCisco2() (info LLDPInfoCisco2, err error) { + for _, o := range l.OrgTLVs { + if o.OUI != IEEEOUICisco2 { + continue + } + switch LLDPCisco2Subtype(o.SubType) { + case LLDPCisco2PowerViaMDI: + if err = checkLLDPOrgSpecificLen(o, 1); err != nil { + return + } + info.PSEFourWirePoESupported = (o.Info[0] & LLDPCiscoPSESupport) > 0 + info.PDSparePairArchitectureShared = (o.Info[0] & LLDPCiscoArchShared) > 0 + info.PDRequestSparePairPoEOn = (o.Info[0] & LLDPCiscoPDSparePair) > 0 + info.PSESparePairPoEOn = (o.Info[0] & LLDPCiscoPSESparePair) > 0 + } + } + return +} + +func (l *LinkLayerDiscoveryInfo) DecodeProfinet() (info LLDPInfoProfinet, err error) { + for _, o := range l.OrgTLVs { + if o.OUI != IEEEOUIProfinet { + continue + } + switch LLDPProfinetSubtype(o.SubType) { + case LLDPProfinetPNIODelay: + if err = checkLLDPOrgSpecificLen(o, 20); err != nil { + return + } + info.PNIODelay.RXLocal = binary.BigEndian.Uint32(o.Info[0:4]) + info.PNIODelay.RXRemote = binary.BigEndian.Uint32(o.Info[4:8]) + info.PNIODelay.TXLocal = binary.BigEndian.Uint32(o.Info[8:12]) + info.PNIODelay.TXRemote = binary.BigEndian.Uint32(o.Info[12:16]) + info.PNIODelay.CableLocal = binary.BigEndian.Uint32(o.Info[16:20]) + case LLDPProfinetPNIOPortStatus: + if err = checkLLDPOrgSpecificLen(o, 4); err != nil { + return + } + info.PNIOPortStatus.Class2 = binary.BigEndian.Uint16(o.Info[0:2]) + info.PNIOPortStatus.Class3 = binary.BigEndian.Uint16(o.Info[2:4]) + case LLDPProfinetPNIOMRPPortStatus: + if err = checkLLDPOrgSpecificLen(o, 18); err != nil { + return + } + info.PNIOMRPPortStatus.UUID = o.Info[0:16] + info.PNIOMRPPortStatus.Status = binary.BigEndian.Uint16(o.Info[16:18]) + case LLDPProfinetPNIOChassisMAC: + if err = checkLLDPOrgSpecificLen(o, 6); err != nil { + return + } + info.ChassisMAC = o.Info[0:6] + case LLDPProfinetPNIOPTCPStatus: + if err = checkLLDPOrgSpecificLen(o, 54); err != nil { + return + } + info.PNIOPTCPStatus.MasterAddress = o.Info[0:6] + info.PNIOPTCPStatus.SubdomainUUID = o.Info[6:22] + info.PNIOPTCPStatus.IRDataUUID = o.Info[22:38] + b := binary.BigEndian.Uint32(o.Info[38:42]) + info.PNIOPTCPStatus.PeriodValid = (b & 0x80000000) > 0 + info.PNIOPTCPStatus.PeriodLength = b & 0x7fffffff + b = binary.BigEndian.Uint32(o.Info[42:46]) + info.PNIOPTCPStatus.RedPeriodValid = (b & 0x80000000) > 0 + info.PNIOPTCPStatus.RedPeriodBegin = b & 0x7fffffff + b = binary.BigEndian.Uint32(o.Info[46:50]) + info.PNIOPTCPStatus.OrangePeriodValid = (b & 0x80000000) > 0 + info.PNIOPTCPStatus.OrangePeriodBegin = b & 0x7fffffff + b = binary.BigEndian.Uint32(o.Info[50:54]) + info.PNIOPTCPStatus.GreenPeriodValid = (b & 0x80000000) > 0 + info.PNIOPTCPStatus.GreenPeriodBegin = b & 0x7fffffff + } + } + return +} + +// LayerType returns gopacket.LayerTypeLinkLayerDiscoveryInfo. +func (c *LinkLayerDiscoveryInfo) LayerType() gopacket.LayerType { + return LayerTypeLinkLayerDiscoveryInfo +} + +func getCapabilities(v uint16) (c LLDPCapabilities) { + c.Other = (v&LLDPCapsOther > 0) + c.Repeater = (v&LLDPCapsRepeater > 0) + c.Bridge = (v&LLDPCapsBridge > 0) + c.WLANAP = (v&LLDPCapsWLANAP > 0) + c.Router = (v&LLDPCapsRouter > 0) + c.Phone = (v&LLDPCapsPhone > 0) + c.DocSis = (v&LLDPCapsDocSis > 0) + c.StationOnly = (v&LLDPCapsStationOnly > 0) + c.CVLAN = (v&LLDPCapsCVLAN > 0) + c.SVLAN = (v&LLDPCapsSVLAN > 0) + c.TMPR = (v&LLDPCapsTmpr > 0) + return +} + +func getEVBCapabilities(v uint16) (c LLDPEVBCapabilities) { + c.StandardBridging = (v & LLDPEVBCapsSTD) > 0 + c.StandardBridging = (v & LLDPEVBCapsSTD) > 0 + c.ReflectiveRelay = (v & LLDPEVBCapsRR) > 0 + c.RetransmissionTimerExponent = (v & LLDPEVBCapsRTE) > 0 + c.EdgeControlProtocol = (v & LLDPEVBCapsECP) > 0 + c.VSIDiscoveryProtocol = (v & LLDPEVBCapsVDP) > 0 + return +} + +func (t LLDPTLVType) String() (s string) { + switch t { + case LLDPTLVEnd: + s = "TLV End" + case LLDPTLVChassisID: + s = "Chassis ID" + case LLDPTLVPortID: + s = "Port ID" + case LLDPTLVTTL: + s = "TTL" + case LLDPTLVPortDescription: + s = "Port Description" + case LLDPTLVSysName: + s = "System Name" + case LLDPTLVSysDescription: + s = "System Description" + case LLDPTLVSysCapabilities: + s = "System Capabilities" + case LLDPTLVMgmtAddress: + s = "Management Address" + case LLDPTLVOrgSpecific: + s = "Organisation Specific" + default: + s = "Unknown" + } + return +} + +func (t LLDPChassisIDSubType) String() (s string) { + switch t { + case LLDPChassisIDSubTypeReserved: + s = "Reserved" + case LLDPChassisIDSubTypeChassisComp: + s = "Chassis Component" + case LLDPChassisIDSubtypeIfaceAlias: + s = "Interface Alias" + case LLDPChassisIDSubTypePortComp: + s = "Port Component" + case LLDPChassisIDSubTypeMACAddr: + s = "MAC Address" + case LLDPChassisIDSubTypeNetworkAddr: + s = "Network Address" + case LLDPChassisIDSubtypeIfaceName: + s = "Interface Name" + case LLDPChassisIDSubTypeLocal: + s = "Local" + default: + s = "Unknown" + } + return +} + +func (t LLDPPortIDSubType) String() (s string) { + switch t { + case LLDPPortIDSubtypeReserved: + s = "Reserved" + case LLDPPortIDSubtypeIfaceAlias: + s = "Interface Alias" + case LLDPPortIDSubtypePortComp: + s = "Port Component" + case LLDPPortIDSubtypeMACAddr: + s = "MAC Address" + case LLDPPortIDSubtypeNetworkAddr: + s = "Network Address" + case LLDPPortIDSubtypeIfaceName: + s = "Interface Name" + case LLDPPortIDSubtypeAgentCircuitID: + s = "Agent Circuit ID" + case LLDPPortIDSubtypeLocal: + s = "Local" + default: + s = "Unknown" + } + return +} + +func (t IANAAddressFamily) String() (s string) { + switch t { + case IANAAddressFamilyReserved: + s = "Reserved" + case IANAAddressFamilyIPV4: + s = "IPv4" + case IANAAddressFamilyIPV6: + s = "IPv6" + case IANAAddressFamilyNSAP: + s = "NSAP" + case IANAAddressFamilyHDLC: + s = "HDLC" + case IANAAddressFamilyBBN1822: + s = "BBN 1822" + case IANAAddressFamily802: + s = "802 media plus Ethernet 'canonical format'" + case IANAAddressFamilyE163: + s = "E.163" + case IANAAddressFamilyE164: + s = "E.164 (SMDS, Frame Relay, ATM)" + case IANAAddressFamilyF69: + s = "F.69 (Telex)" + case IANAAddressFamilyX121: + s = "X.121, X.25, Frame Relay" + case IANAAddressFamilyIPX: + s = "IPX" + case IANAAddressFamilyAtalk: + s = "Appletalk" + case IANAAddressFamilyDecnet: + s = "Decnet IV" + case IANAAddressFamilyBanyan: + s = "Banyan Vines" + case IANAAddressFamilyE164NSAP: + s = "E.164 with NSAP format subaddress" + case IANAAddressFamilyDNS: + s = "DNS" + case IANAAddressFamilyDistname: + s = "Distinguished Name" + case IANAAddressFamilyASNumber: + s = "AS Number" + case IANAAddressFamilyXTPIPV4: + s = "XTP over IP version 4" + case IANAAddressFamilyXTPIPV6: + s = "XTP over IP version 6" + case IANAAddressFamilyXTP: + s = "XTP native mode XTP" + case IANAAddressFamilyFcWWPN: + s = "Fibre Channel World-Wide Port Name" + case IANAAddressFamilyFcWWNN: + s = "Fibre Channel World-Wide Node Name" + case IANAAddressFamilyGWID: + s = "GWID" + case IANAAddressFamilyL2VPN: + s = "AFI for Layer 2 VPN" + default: + s = "Unknown" + } + return +} + +func (t LLDPInterfaceSubtype) String() (s string) { + switch t { + case LLDPInterfaceSubtypeUnknown: + s = "Unknown" + case LLDPInterfaceSubtypeifIndex: + s = "IfIndex" + case LLDPInterfaceSubtypeSysPort: + s = "System Port Number" + default: + s = "Unknown" + } + return +} + +func (t LLDPPowerType) String() (s string) { + switch t { + case 0: + s = "Type 2 PSE Device" + case 1: + s = "Type 2 PD Device" + case 2: + s = "Type 1 PSE Device" + case 3: + s = "Type 1 PD Device" + default: + s = "Unknown" + } + return +} + +func (t LLDPPowerSource) String() (s string) { + switch t { + // PD Device + case 0: + s = "Unknown" + case 1: + s = "PSE" + case 2: + s = "Local" + case 3: + s = "PSE and Local" + // PSE Device (Actual value + 128) + case 128: + s = "Unknown" + case 129: + s = "Primary Power Source" + case 130: + s = "Backup Power Source" + default: + s = "Unknown" + } + return +} + +func (t LLDPPowerPriority) String() (s string) { + switch t { + case 0: + s = "Unknown" + case 1: + s = "Critical" + case 2: + s = "High" + case 3: + s = "Low" + default: + s = "Unknown" + } + return +} + +func (t LLDPMediaSubtype) String() (s string) { + switch t { + case LLDPMediaTypeCapabilities: + s = "Media Capabilities " + case LLDPMediaTypeNetwork: + s = "Network Policy" + case LLDPMediaTypeLocation: + s = "Location Identification" + case LLDPMediaTypePower: + s = "Extended Power-via-MDI" + case LLDPMediaTypeHardware: + s = "Hardware Revision" + case LLDPMediaTypeFirmware: + s = "Firmware Revision" + case LLDPMediaTypeSoftware: + s = "Software Revision" + case LLDPMediaTypeSerial: + s = "Serial Number" + case LLDPMediaTypeManufacturer: + s = "Manufacturer" + case LLDPMediaTypeModel: + s = "Model" + case LLDPMediaTypeAssetID: + s = "Asset ID" + default: + s = "Unknown" + } + return +} + +func (t LLDPMediaClass) String() (s string) { + switch t { + case LLDPMediaClassUndefined: + s = "Undefined" + case LLDPMediaClassEndpointI: + s = "Endpoint Class I" + case LLDPMediaClassEndpointII: + s = "Endpoint Class II" + case LLDPMediaClassEndpointIII: + s = "Endpoint Class III" + case LLDPMediaClassNetwork: + s = "Network connectivity " + default: + s = "Unknown" + } + return +} + +func (t LLDPApplicationType) String() (s string) { + switch t { + case LLDPAppTypeReserved: + s = "Reserved" + case LLDPAppTypeVoice: + s = "Voice" + case LLDPappTypeVoiceSignaling: + s = "Voice Signaling" + case LLDPappTypeGuestVoice: + s = "Guest Voice" + case LLDPappTypeGuestVoiceSignaling: + s = "Guest Voice Signaling" + case LLDPappTypeSoftphoneVoice: + s = "Softphone Voice" + case LLDPappTypeVideoConferencing: + s = "Video Conferencing" + case LLDPappTypeStreamingVideo: + s = "Streaming Video" + case LLDPappTypeVideoSignaling: + s = "Video Signaling" + default: + s = "Unknown" + } + return +} + +func (t LLDPLocationFormat) String() (s string) { + switch t { + case LLDPLocationFormatInvalid: + s = "Invalid" + case LLDPLocationFormatCoordinate: + s = "Coordinate-based LCI" + case LLDPLocationFormatAddress: + s = "Address-based LCO" + case LLDPLocationFormatECS: + s = "ECS ELIN" + default: + s = "Unknown" + } + return +} + +func (t LLDPLocationAddressType) String() (s string) { + switch t { + case LLDPLocationAddressTypeLanguage: + s = "Language" + case LLDPLocationAddressTypeNational: + s = "National subdivisions (province, state, etc)" + case LLDPLocationAddressTypeCounty: + s = "County, parish, district" + case LLDPLocationAddressTypeCity: + s = "City, township" + case LLDPLocationAddressTypeCityDivision: + s = "City division, borough, ward" + case LLDPLocationAddressTypeNeighborhood: + s = "Neighborhood, block" + case LLDPLocationAddressTypeStreet: + s = "Street" + case LLDPLocationAddressTypeLeadingStreet: + s = "Leading street direction" + case LLDPLocationAddressTypeTrailingStreet: + s = "Trailing street suffix" + case LLDPLocationAddressTypeStreetSuffix: + s = "Street suffix" + case LLDPLocationAddressTypeHouseNum: + s = "House number" + case LLDPLocationAddressTypeHouseSuffix: + s = "House number suffix" + case LLDPLocationAddressTypeLandmark: + s = "Landmark or vanity address" + case LLDPLocationAddressTypeAdditional: + s = "Additional location information" + case LLDPLocationAddressTypeName: + s = "Name" + case LLDPLocationAddressTypePostal: + s = "Postal/ZIP code" + case LLDPLocationAddressTypeBuilding: + s = "Building" + case LLDPLocationAddressTypeUnit: + s = "Unit" + case LLDPLocationAddressTypeFloor: + s = "Floor" + case LLDPLocationAddressTypeRoom: + s = "Room number" + case LLDPLocationAddressTypePlace: + s = "Place type" + case LLDPLocationAddressTypeScript: + s = "Script" + default: + s = "Unknown" + } + return +} + +func checkLLDPTLVLen(v LinkLayerDiscoveryValue, l int) (err error) { + if len(v.Value) < l { + err = fmt.Errorf("Invalid TLV %v length %d (wanted mimimum %v", v.Type, len(v.Value), l) + } + return +} + +func checkLLDPOrgSpecificLen(o LLDPOrgSpecificTLV, l int) (err error) { + if len(o.Info) < l { + err = fmt.Errorf("Invalid Org Specific TLV %v length %d (wanted minimum %v)", o.SubType, len(o.Info), l) + } + return +} diff --git a/vendor/github.com/google/gopacket/layers/loopback.go b/vendor/github.com/google/gopacket/layers/loopback.go new file mode 100644 index 0000000..27848e4 --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/loopback.go @@ -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" + "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 fmt.Errorf("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() +} + +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) +} diff --git a/vendor/github.com/google/gopacket/layers/mpls.go b/vendor/github.com/google/gopacket/layers/mpls.go new file mode 100644 index 0000000..83079a0 --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/mpls.go @@ -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 +} diff --git a/vendor/github.com/google/gopacket/layers/ndp.go b/vendor/github.com/google/gopacket/layers/ndp.go new file mode 100644 index 0000000..f7ca1b2 --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/ndp.go @@ -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 +} diff --git a/vendor/github.com/google/gopacket/layers/pflog.go b/vendor/github.com/google/gopacket/layers/pflog.go new file mode 100644 index 0000000..853882f --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/pflog.go @@ -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) +} diff --git a/vendor/github.com/google/gopacket/layers/ports.go b/vendor/github.com/google/gopacket/layers/ports.go new file mode 100644 index 0000000..6b06ec6 --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/ports.go @@ -0,0 +1,102 @@ +// 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)) +} + +// 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 use some well-known port such as 53 for DNS. +// +// Returns gopacket.LayerTypePayload for unknown/unsupported port numbers. +func (a UDPPort) LayerType() gopacket.LayerType { + switch a { + case 53: + return LayerTypeDNS + case 6343: + return LayerTypeSFlow + default: + return gopacket.LayerTypePayload + } +} + +// 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)) +} diff --git a/vendor/github.com/google/gopacket/layers/ppp.go b/vendor/github.com/google/gopacket/layers/ppp.go new file mode 100644 index 0000000..1d2e7b8 --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/ppp.go @@ -0,0 +1,74 @@ +// 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 +} + +// 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{} + if data[0]&0x1 == 0 { + if data[1]&0x1 == 0 { + return errors.New("PPP has invalid type") + } + ppp.PPPType = PPPType(binary.BigEndian.Uint16(data[:2])) + ppp.Contents = data[:2] + ppp.Payload = data[2:] + } else { + ppp.PPPType = PPPType(data[0]) + ppp.Contents = data[:1] + ppp.Payload = data[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) + } + return nil +} diff --git a/vendor/github.com/google/gopacket/layers/pppoe.go b/vendor/github.com/google/gopacket/layers/pppoe.go new file mode 100644 index 0000000..14cd63a --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/pppoe.go @@ -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 +} diff --git a/vendor/github.com/google/gopacket/layers/prism.go b/vendor/github.com/google/gopacket/layers/prism.go new file mode 100644 index 0000000..e1711e7 --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/prism.go @@ -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 } diff --git a/vendor/github.com/google/gopacket/layers/radiotap.go b/vendor/github.com/google/gopacket/layers/radiotap.go new file mode 100644 index 0000000..b6daf48 --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/radiotap.go @@ -0,0 +1,874 @@ +// 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 ( + "bytes" + "encoding/binary" + "fmt" + "github.com/google/gopacket" + "hash/crc32" + "strings" +) + +// align calculates the number of bytes needed to align with the width +// on the offset, returning the number of bytes we need to skip to +// align to the offset (width). +func align(offset uint16, width uint16) uint16 { + return ((((offset) + ((width) - 1)) & (^((width) - 1))) - offset) +} + +type RadioTapPresent uint32 + +const ( + RadioTapPresentTSFT RadioTapPresent = 1 << iota + RadioTapPresentFlags + RadioTapPresentRate + RadioTapPresentChannel + RadioTapPresentFHSS + RadioTapPresentDBMAntennaSignal + RadioTapPresentDBMAntennaNoise + RadioTapPresentLockQuality + RadioTapPresentTxAttenuation + RadioTapPresentDBTxAttenuation + RadioTapPresentDBMTxPower + RadioTapPresentAntenna + RadioTapPresentDBAntennaSignal + RadioTapPresentDBAntennaNoise + RadioTapPresentRxFlags + RadioTapPresentTxFlags + RadioTapPresentRtsRetries + RadioTapPresentDataRetries + _ + RadioTapPresentMCS + RadioTapPresentAMPDUStatus + RadioTapPresentVHT + RadioTapPresentEXT RadioTapPresent = 1 << 31 +) + +func (r RadioTapPresent) TSFT() bool { + return r&RadioTapPresentTSFT != 0 +} +func (r RadioTapPresent) Flags() bool { + return r&RadioTapPresentFlags != 0 +} +func (r RadioTapPresent) Rate() bool { + return r&RadioTapPresentRate != 0 +} +func (r RadioTapPresent) Channel() bool { + return r&RadioTapPresentChannel != 0 +} +func (r RadioTapPresent) FHSS() bool { + return r&RadioTapPresentFHSS != 0 +} +func (r RadioTapPresent) DBMAntennaSignal() bool { + return r&RadioTapPresentDBMAntennaSignal != 0 +} +func (r RadioTapPresent) DBMAntennaNoise() bool { + return r&RadioTapPresentDBMAntennaNoise != 0 +} +func (r RadioTapPresent) LockQuality() bool { + return r&RadioTapPresentLockQuality != 0 +} +func (r RadioTapPresent) TxAttenuation() bool { + return r&RadioTapPresentTxAttenuation != 0 +} +func (r RadioTapPresent) DBTxAttenuation() bool { + return r&RadioTapPresentDBTxAttenuation != 0 +} +func (r RadioTapPresent) DBMTxPower() bool { + return r&RadioTapPresentDBMTxPower != 0 +} +func (r RadioTapPresent) Antenna() bool { + return r&RadioTapPresentAntenna != 0 +} +func (r RadioTapPresent) DBAntennaSignal() bool { + return r&RadioTapPresentDBAntennaSignal != 0 +} +func (r RadioTapPresent) DBAntennaNoise() bool { + return r&RadioTapPresentDBAntennaNoise != 0 +} +func (r RadioTapPresent) RxFlags() bool { + return r&RadioTapPresentRxFlags != 0 +} +func (r RadioTapPresent) TxFlags() bool { + return r&RadioTapPresentTxFlags != 0 +} +func (r RadioTapPresent) RtsRetries() bool { + return r&RadioTapPresentRtsRetries != 0 +} +func (r RadioTapPresent) DataRetries() bool { + return r&RadioTapPresentDataRetries != 0 +} +func (r RadioTapPresent) MCS() bool { + return r&RadioTapPresentMCS != 0 +} +func (r RadioTapPresent) AMPDUStatus() bool { + return r&RadioTapPresentAMPDUStatus != 0 +} +func (r RadioTapPresent) VHT() bool { + return r&RadioTapPresentVHT != 0 +} +func (r RadioTapPresent) EXT() bool { + return r&RadioTapPresentEXT != 0 +} + +type RadioTapChannelFlags uint16 + +const ( + RadioTapChannelFlagsTurbo RadioTapChannelFlags = 0x0010 // Turbo channel + RadioTapChannelFlagsCCK RadioTapChannelFlags = 0x0020 // CCK channel + RadioTapChannelFlagsOFDM RadioTapChannelFlags = 0x0040 // OFDM channel + RadioTapChannelFlagsGhz2 RadioTapChannelFlags = 0x0080 // 2 GHz spectrum channel. + RadioTapChannelFlagsGhz5 RadioTapChannelFlags = 0x0100 // 5 GHz spectrum channel + RadioTapChannelFlagsPassive RadioTapChannelFlags = 0x0200 // Only passive scan allowed + RadioTapChannelFlagsDynamic RadioTapChannelFlags = 0x0400 // Dynamic CCK-OFDM channel + RadioTapChannelFlagsGFSK RadioTapChannelFlags = 0x0800 // GFSK channel (FHSS PHY) +) + +func (r RadioTapChannelFlags) Turbo() bool { + return r&RadioTapChannelFlagsTurbo != 0 +} +func (r RadioTapChannelFlags) CCK() bool { + return r&RadioTapChannelFlagsCCK != 0 +} +func (r RadioTapChannelFlags) OFDM() bool { + return r&RadioTapChannelFlagsOFDM != 0 +} +func (r RadioTapChannelFlags) Ghz2() bool { + return r&RadioTapChannelFlagsGhz2 != 0 +} +func (r RadioTapChannelFlags) Ghz5() bool { + return r&RadioTapChannelFlagsGhz5 != 0 +} +func (r RadioTapChannelFlags) Passive() bool { + return r&RadioTapChannelFlagsPassive != 0 +} +func (r RadioTapChannelFlags) Dynamic() bool { + return r&RadioTapChannelFlagsDynamic != 0 +} +func (r RadioTapChannelFlags) GFSK() bool { + return r&RadioTapChannelFlagsGFSK != 0 +} + +// String provides a human readable string for RadioTapChannelFlags. +// This string is possibly subject to change over time; if you're storing this +// persistently, you should probably store the RadioTapChannelFlags value, not its string. +func (a RadioTapChannelFlags) String() string { + var out bytes.Buffer + if a.Turbo() { + out.WriteString("Turbo,") + } + if a.CCK() { + out.WriteString("CCK,") + } + if a.OFDM() { + out.WriteString("OFDM,") + } + if a.Ghz2() { + out.WriteString("Ghz2,") + } + if a.Ghz5() { + out.WriteString("Ghz5,") + } + if a.Passive() { + out.WriteString("Passive,") + } + if a.Dynamic() { + out.WriteString("Dynamic,") + } + if a.GFSK() { + out.WriteString("GFSK,") + } + + if length := out.Len(); length > 0 { + return string(out.Bytes()[:length-1]) // strip final comma + } + return "" +} + +type RadioTapFlags uint8 + +const ( + RadioTapFlagsCFP RadioTapFlags = 1 << iota // sent/received during CFP + RadioTapFlagsShortPreamble // sent/received * with short * preamble + RadioTapFlagsWEP // sent/received * with WEP encryption + RadioTapFlagsFrag // sent/received * with fragmentation + RadioTapFlagsFCS // frame includes FCS + RadioTapFlagsDatapad // frame has padding between * 802.11 header and payload * (to 32-bit boundary) + RadioTapFlagsBadFCS // does not pass FCS check + RadioTapFlagsShortGI // HT short GI +) + +func (r RadioTapFlags) CFP() bool { + return r&RadioTapFlagsCFP != 0 +} +func (r RadioTapFlags) ShortPreamble() bool { + return r&RadioTapFlagsShortPreamble != 0 +} +func (r RadioTapFlags) WEP() bool { + return r&RadioTapFlagsWEP != 0 +} +func (r RadioTapFlags) Frag() bool { + return r&RadioTapFlagsFrag != 0 +} +func (r RadioTapFlags) FCS() bool { + return r&RadioTapFlagsFCS != 0 +} +func (r RadioTapFlags) Datapad() bool { + return r&RadioTapFlagsDatapad != 0 +} +func (r RadioTapFlags) BadFCS() bool { + return r&RadioTapFlagsBadFCS != 0 +} +func (r RadioTapFlags) ShortGI() bool { + return r&RadioTapFlagsShortGI != 0 +} + +// String provides a human readable string for RadioTapFlags. +// This string is possibly subject to change over time; if you're storing this +// persistently, you should probably store the RadioTapFlags value, not its string. +func (a RadioTapFlags) String() string { + var out bytes.Buffer + if a.CFP() { + out.WriteString("CFP,") + } + if a.ShortPreamble() { + out.WriteString("SHORT-PREAMBLE,") + } + if a.WEP() { + out.WriteString("WEP,") + } + if a.Frag() { + out.WriteString("FRAG,") + } + if a.FCS() { + out.WriteString("FCS,") + } + if a.Datapad() { + out.WriteString("DATAPAD,") + } + if a.ShortGI() { + out.WriteString("SHORT-GI,") + } + + if length := out.Len(); length > 0 { + return string(out.Bytes()[:length-1]) // strip final comma + } + return "" +} + +type RadioTapRate uint8 + +func (a RadioTapRate) String() string { + return fmt.Sprintf("%v Mb/s", 0.5*float32(a)) +} + +type RadioTapChannelFrequency uint16 + +func (a RadioTapChannelFrequency) String() string { + return fmt.Sprintf("%d MHz", a) +} + +type RadioTapRxFlags uint16 + +const ( + RadioTapRxFlagsBadPlcp RadioTapRxFlags = 0x0002 +) + +func (self RadioTapRxFlags) BadPlcp() bool { + return self&RadioTapRxFlagsBadPlcp != 0 +} + +func (self RadioTapRxFlags) String() string { + if self.BadPlcp() { + return "BADPLCP" + } + return "" +} + +type RadioTapTxFlags uint16 + +const ( + RadioTapTxFlagsFail RadioTapTxFlags = 1 << iota + RadioTapTxFlagsCTS + RadioTapTxFlagsRTS + RadioTapTxFlagsNoACK +) + +func (self RadioTapTxFlags) Fail() bool { return self&RadioTapTxFlagsFail != 0 } +func (self RadioTapTxFlags) CTS() bool { return self&RadioTapTxFlagsCTS != 0 } +func (self RadioTapTxFlags) RTS() bool { return self&RadioTapTxFlagsRTS != 0 } +func (self RadioTapTxFlags) NoACK() bool { return self&RadioTapTxFlagsNoACK != 0 } + +func (self RadioTapTxFlags) String() string { + var tokens []string + if self.Fail() { + tokens = append(tokens, "Fail") + } + if self.CTS() { + tokens = append(tokens, "CTS") + } + if self.RTS() { + tokens = append(tokens, "RTS") + } + if self.NoACK() { + tokens = append(tokens, "NoACK") + } + return strings.Join(tokens, ",") +} + +type RadioTapMCS struct { + Known RadioTapMCSKnown + Flags RadioTapMCSFlags + MCS uint8 +} + +func (self RadioTapMCS) String() string { + var tokens []string + if self.Known.Bandwidth() { + token := "?" + switch self.Flags.Bandwidth() { + case 0: + token = "20" + case 1: + token = "40" + case 2: + token = "40(20L)" + case 3: + token = "40(20U)" + } + tokens = append(tokens, token) + } + if self.Known.MCSIndex() { + tokens = append(tokens, fmt.Sprintf("MCSIndex#%d", self.MCS)) + } + if self.Known.GuardInterval() { + if self.Flags.ShortGI() { + tokens = append(tokens, fmt.Sprintf("shortGI")) + } else { + tokens = append(tokens, fmt.Sprintf("longGI")) + } + } + if self.Known.HTFormat() { + if self.Flags.Greenfield() { + tokens = append(tokens, fmt.Sprintf("HT-greenfield")) + } else { + tokens = append(tokens, fmt.Sprintf("HT-mixed")) + } + } + if self.Known.FECType() { + if self.Flags.FECLDPC() { + tokens = append(tokens, fmt.Sprintf("LDPC")) + } else { + tokens = append(tokens, fmt.Sprintf("BCC")) + } + } + if self.Known.STBC() { + tokens = append(tokens, fmt.Sprintf("STBC#%d", self.Flags.STBC())) + } + if self.Known.NESS() { + num := 0 + if self.Known.NESS1() { + num |= 0x02 + } + if self.Flags.NESS0() { + num |= 0x01 + } + tokens = append(tokens, fmt.Sprintf("num-of-ESS#%d", num)) + } + return strings.Join(tokens, ",") +} + +type RadioTapMCSKnown uint8 + +const ( + RadioTapMCSKnownBandwidth RadioTapMCSKnown = 1 << iota + RadioTapMCSKnownMCSIndex + RadioTapMCSKnownGuardInterval + RadioTapMCSKnownHTFormat + RadioTapMCSKnownFECType + RadioTapMCSKnownSTBC + RadioTapMCSKnownNESS + RadioTapMCSKnownNESS1 +) + +func (self RadioTapMCSKnown) Bandwidth() bool { return self&RadioTapMCSKnownBandwidth != 0 } +func (self RadioTapMCSKnown) MCSIndex() bool { return self&RadioTapMCSKnownMCSIndex != 0 } +func (self RadioTapMCSKnown) GuardInterval() bool { return self&RadioTapMCSKnownGuardInterval != 0 } +func (self RadioTapMCSKnown) HTFormat() bool { return self&RadioTapMCSKnownHTFormat != 0 } +func (self RadioTapMCSKnown) FECType() bool { return self&RadioTapMCSKnownFECType != 0 } +func (self RadioTapMCSKnown) STBC() bool { return self&RadioTapMCSKnownSTBC != 0 } +func (self RadioTapMCSKnown) NESS() bool { return self&RadioTapMCSKnownNESS != 0 } +func (self RadioTapMCSKnown) NESS1() bool { return self&RadioTapMCSKnownNESS1 != 0 } + +type RadioTapMCSFlags uint8 + +const ( + RadioTapMCSFlagsBandwidthMask RadioTapMCSFlags = 0x03 + RadioTapMCSFlagsShortGI = 0x04 + RadioTapMCSFlagsGreenfield = 0x08 + RadioTapMCSFlagsFECLDPC = 0x10 + RadioTapMCSFlagsSTBCMask = 0x60 + RadioTapMCSFlagsNESS0 = 0x80 +) + +func (self RadioTapMCSFlags) Bandwidth() int { + return int(self & RadioTapMCSFlagsBandwidthMask) +} +func (self RadioTapMCSFlags) ShortGI() bool { return self&RadioTapMCSFlagsShortGI != 0 } +func (self RadioTapMCSFlags) Greenfield() bool { return self&RadioTapMCSFlagsGreenfield != 0 } +func (self RadioTapMCSFlags) FECLDPC() bool { return self&RadioTapMCSFlagsFECLDPC != 0 } +func (self RadioTapMCSFlags) STBC() int { + return int(self&RadioTapMCSFlagsSTBCMask) >> 5 +} +func (self RadioTapMCSFlags) NESS0() bool { return self&RadioTapMCSFlagsNESS0 != 0 } + +type RadioTapAMPDUStatus struct { + Reference uint32 + Flags RadioTapAMPDUStatusFlags + CRC uint8 +} + +func (self RadioTapAMPDUStatus) String() string { + tokens := []string{ + fmt.Sprintf("ref#%x", self.Reference), + } + if self.Flags.ReportZerolen() && self.Flags.IsZerolen() { + tokens = append(tokens, fmt.Sprintf("zero-length")) + } + if self.Flags.LastKnown() && self.Flags.IsLast() { + tokens = append(tokens, "last") + } + if self.Flags.DelimCRCErr() { + tokens = append(tokens, "delimiter CRC error") + } + if self.Flags.DelimCRCKnown() { + tokens = append(tokens, fmt.Sprintf("delimiter-CRC=%02x", self.CRC)) + } + return strings.Join(tokens, ",") +} + +type RadioTapAMPDUStatusFlags uint16 + +const ( + RadioTapAMPDUStatusFlagsReportZerolen RadioTapAMPDUStatusFlags = 1 << iota + RadioTapAMPDUIsZerolen + RadioTapAMPDULastKnown + RadioTapAMPDUIsLast + RadioTapAMPDUDelimCRCErr + RadioTapAMPDUDelimCRCKnown +) + +func (self RadioTapAMPDUStatusFlags) ReportZerolen() bool { + return self&RadioTapAMPDUStatusFlagsReportZerolen != 0 +} +func (self RadioTapAMPDUStatusFlags) IsZerolen() bool { return self&RadioTapAMPDUIsZerolen != 0 } +func (self RadioTapAMPDUStatusFlags) LastKnown() bool { return self&RadioTapAMPDULastKnown != 0 } +func (self RadioTapAMPDUStatusFlags) IsLast() bool { return self&RadioTapAMPDUIsLast != 0 } +func (self RadioTapAMPDUStatusFlags) DelimCRCErr() bool { return self&RadioTapAMPDUDelimCRCErr != 0 } +func (self RadioTapAMPDUStatusFlags) DelimCRCKnown() bool { return self&RadioTapAMPDUDelimCRCKnown != 0 } + +type RadioTapVHT struct { + Known RadioTapVHTKnown + Flags RadioTapVHTFlags + Bandwidth uint8 + MCSNSS [4]RadioTapVHTMCSNSS + Coding uint8 + GroupId uint8 + PartialAID uint16 +} + +func (self RadioTapVHT) String() string { + var tokens []string + if self.Known.STBC() { + if self.Flags.STBC() { + tokens = append(tokens, "STBC") + } else { + tokens = append(tokens, "no STBC") + } + } + if self.Known.TXOPPSNotAllowed() { + if self.Flags.TXOPPSNotAllowed() { + tokens = append(tokens, "TXOP doze not allowed") + } else { + tokens = append(tokens, "TXOP doze allowed") + } + } + if self.Known.GI() { + if self.Flags.SGI() { + tokens = append(tokens, "short GI") + } else { + tokens = append(tokens, "long GI") + } + } + if self.Known.SGINSYMDisambiguation() { + if self.Flags.SGINSYMMod() { + tokens = append(tokens, "NSYM mod 10=9") + } else { + tokens = append(tokens, "NSYM mod 10!=9 or no short GI") + } + } + if self.Known.LDPCExtraOFDMSymbol() { + if self.Flags.LDPCExtraOFDMSymbol() { + tokens = append(tokens, "LDPC extra OFDM symbols") + } else { + tokens = append(tokens, "no LDPC extra OFDM symbols") + } + } + if self.Known.Beamformed() { + if self.Flags.Beamformed() { + tokens = append(tokens, "beamformed") + } else { + tokens = append(tokens, "no beamformed") + } + } + if self.Known.Bandwidth() { + token := "?" + switch self.Bandwidth & 0x1f { + case 0: + token = "20" + case 1: + token = "40" + case 2: + token = "40(20L)" + case 3: + token = "40(20U)" + case 4: + token = "80" + case 5: + token = "80(40L)" + case 6: + token = "80(40U)" + case 7: + token = "80(20LL)" + case 8: + token = "80(20LU)" + case 9: + token = "80(20UL)" + case 10: + token = "80(20UU)" + case 11: + token = "160" + case 12: + token = "160(80L)" + case 13: + token = "160(80U)" + case 14: + token = "160(40LL)" + case 15: + token = "160(40LU)" + case 16: + token = "160(40UL)" + case 17: + token = "160(40UU)" + case 18: + token = "160(20LLL)" + case 19: + token = "160(20LLU)" + case 20: + token = "160(20LUL)" + case 21: + token = "160(20LUU)" + case 22: + token = "160(20ULL)" + case 23: + token = "160(20ULU)" + case 24: + token = "160(20UUL)" + case 25: + token = "160(20UUU)" + } + tokens = append(tokens, token) + } + for i, MCSNSS := range self.MCSNSS { + if MCSNSS.Present() { + fec := "?" + switch self.Coding & (1 << uint8(i)) { + case 0: + fec = "BCC" + case 1: + fec = "LDPC" + } + tokens = append(tokens, fmt.Sprintf("user%d(%s,%s)", i, MCSNSS.String(), fec)) + } + } + if self.Known.GroupId() { + tokens = append(tokens, + fmt.Sprintf("group=%d", self.GroupId)) + } + if self.Known.PartialAID() { + tokens = append(tokens, + fmt.Sprintf("partial-AID=%d", self.PartialAID)) + } + return strings.Join(tokens, ",") +} + +type RadioTapVHTKnown uint16 + +const ( + RadioTapVHTKnownSTBC RadioTapVHTKnown = 1 << iota + RadioTapVHTKnownTXOPPSNotAllowed + RadioTapVHTKnownGI + RadioTapVHTKnownSGINSYMDisambiguation + RadioTapVHTKnownLDPCExtraOFDMSymbol + RadioTapVHTKnownBeamformed + RadioTapVHTKnownBandwidth + RadioTapVHTKnownGroupId + RadioTapVHTKnownPartialAID +) + +func (self RadioTapVHTKnown) STBC() bool { return self&RadioTapVHTKnownSTBC != 0 } +func (self RadioTapVHTKnown) TXOPPSNotAllowed() bool { + return self&RadioTapVHTKnownTXOPPSNotAllowed != 0 +} +func (self RadioTapVHTKnown) GI() bool { return self&RadioTapVHTKnownGI != 0 } +func (self RadioTapVHTKnown) SGINSYMDisambiguation() bool { + return self&RadioTapVHTKnownSGINSYMDisambiguation != 0 +} +func (self RadioTapVHTKnown) LDPCExtraOFDMSymbol() bool { + return self&RadioTapVHTKnownLDPCExtraOFDMSymbol != 0 +} +func (self RadioTapVHTKnown) Beamformed() bool { return self&RadioTapVHTKnownBeamformed != 0 } +func (self RadioTapVHTKnown) Bandwidth() bool { return self&RadioTapVHTKnownBandwidth != 0 } +func (self RadioTapVHTKnown) GroupId() bool { return self&RadioTapVHTKnownGroupId != 0 } +func (self RadioTapVHTKnown) PartialAID() bool { return self&RadioTapVHTKnownPartialAID != 0 } + +type RadioTapVHTFlags uint8 + +const ( + RadioTapVHTFlagsSTBC RadioTapVHTFlags = 1 << iota + RadioTapVHTFlagsTXOPPSNotAllowed + RadioTapVHTFlagsSGI + RadioTapVHTFlagsSGINSYMMod + RadioTapVHTFlagsLDPCExtraOFDMSymbol + RadioTapVHTFlagsBeamformed +) + +func (self RadioTapVHTFlags) STBC() bool { return self&RadioTapVHTFlagsSTBC != 0 } +func (self RadioTapVHTFlags) TXOPPSNotAllowed() bool { + return self&RadioTapVHTFlagsTXOPPSNotAllowed != 0 +} +func (self RadioTapVHTFlags) SGI() bool { return self&RadioTapVHTFlagsSGI != 0 } +func (self RadioTapVHTFlags) SGINSYMMod() bool { return self&RadioTapVHTFlagsSGINSYMMod != 0 } +func (self RadioTapVHTFlags) LDPCExtraOFDMSymbol() bool { + return self&RadioTapVHTFlagsLDPCExtraOFDMSymbol != 0 +} +func (self RadioTapVHTFlags) Beamformed() bool { return self&RadioTapVHTFlagsBeamformed != 0 } + +type RadioTapVHTMCSNSS uint8 + +func (self RadioTapVHTMCSNSS) Present() bool { + return self&0x0F != 0 +} + +func (self RadioTapVHTMCSNSS) String() string { + return fmt.Sprintf("NSS#%dMCS#%d", uint32(self&0xf), uint32(self>>4)) +} + +func decodeRadioTap(data []byte, p gopacket.PacketBuilder) error { + d := &RadioTap{} + // TODO: Should we set LinkLayer here? And implement LinkFlow + return decodingLayerDecoder(d, data, p) +} + +type RadioTap struct { + BaseLayer + + // Version 0. Only increases for drastic changes, introduction of compatible new fields does not count. + Version uint8 + // Length of the whole header in bytes, including it_version, it_pad, it_len, and data fields. + Length uint16 + // Present is a bitmap telling which fields are present. Set bit 31 (0x80000000) to extend the bitmap by another 32 bits. Additional extensions are made by setting bit 31. + Present RadioTapPresent + // TSFT: value in microseconds of the MAC's 64-bit 802.11 Time Synchronization Function timer when the first bit of the MPDU arrived at the MAC. For received frames, only. + TSFT uint64 + Flags RadioTapFlags + // Rate Tx/Rx data rate + Rate RadioTapRate + // ChannelFrequency Tx/Rx frequency in MHz, followed by flags + ChannelFrequency RadioTapChannelFrequency + ChannelFlags RadioTapChannelFlags + // FHSS For frequency-hopping radios, the hop set (first byte) and pattern (second byte). + FHSS uint16 + // DBMAntennaSignal RF signal power at the antenna, decibel difference from one milliwatt. + DBMAntennaSignal int8 + // DBMAntennaNoise RF noise power at the antenna, decibel difference from one milliwatt. + DBMAntennaNoise int8 + // LockQuality Quality of Barker code lock. Unitless. Monotonically nondecreasing with "better" lock strength. Called "Signal Quality" in datasheets. + LockQuality uint16 + // TxAttenuation Transmit power expressed as unitless distance from max power set at factory calibration. 0 is max power. Monotonically nondecreasing with lower power levels. + TxAttenuation uint16 + // DBTxAttenuation Transmit power expressed as decibel distance from max power set at factory calibration. 0 is max power. Monotonically nondecreasing with lower power levels. + DBTxAttenuation uint16 + // DBMTxPower Transmit power expressed as dBm (decibels from a 1 milliwatt reference). This is the absolute power level measured at the antenna port. + DBMTxPower int8 + // Antenna Unitless indication of the Rx/Tx antenna for this packet. The first antenna is antenna 0. + Antenna uint8 + // DBAntennaSignal RF signal power at the antenna, decibel difference from an arbitrary, fixed reference. + DBAntennaSignal uint8 + // DBAntennaNoise RF noise power at the antenna, decibel difference from an arbitrary, fixed reference point. + DBAntennaNoise uint8 + // + RxFlags RadioTapRxFlags + TxFlags RadioTapTxFlags + RtsRetries uint8 + DataRetries uint8 + MCS RadioTapMCS + AMPDUStatus RadioTapAMPDUStatus + VHT RadioTapVHT +} + +func (m *RadioTap) LayerType() gopacket.LayerType { return LayerTypeRadioTap } + +func (m *RadioTap) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + m.Version = uint8(data[0]) + m.Length = binary.LittleEndian.Uint16(data[2:4]) + m.Present = RadioTapPresent(binary.LittleEndian.Uint32(data[4:8])) + + offset := uint16(4) + + for (binary.LittleEndian.Uint32(data[offset:offset+4]) & 0x80000000) != 0 { + // This parser only handles standard radiotap namespace, + // and expects all fields are packed in the first it_present. + // Extended bitmap will be just ignored. + offset += 4 + } + offset += 4 // skip the bitmap + + if m.Present.TSFT() { + offset += align(offset, 8) + m.TSFT = binary.LittleEndian.Uint64(data[offset : offset+8]) + offset += 8 + } + if m.Present.Flags() { + m.Flags = RadioTapFlags(data[offset]) + offset++ + } + if m.Present.Rate() { + m.Rate = RadioTapRate(data[offset]) + offset++ + } + if m.Present.Channel() { + offset += align(offset, 2) + m.ChannelFrequency = RadioTapChannelFrequency(binary.LittleEndian.Uint16(data[offset : offset+2])) + offset += 2 + m.ChannelFlags = RadioTapChannelFlags(binary.LittleEndian.Uint16(data[offset : offset+2])) + offset += 2 + } + if m.Present.FHSS() { + m.FHSS = binary.LittleEndian.Uint16(data[offset : offset+2]) + offset += 2 + } + if m.Present.DBMAntennaSignal() { + m.DBMAntennaSignal = int8(data[offset]) + offset++ + } + if m.Present.DBMAntennaNoise() { + m.DBMAntennaNoise = int8(data[offset]) + offset++ + } + if m.Present.LockQuality() { + offset += align(offset, 2) + m.LockQuality = binary.LittleEndian.Uint16(data[offset : offset+2]) + offset += 2 + } + if m.Present.TxAttenuation() { + offset += align(offset, 2) + m.TxAttenuation = binary.LittleEndian.Uint16(data[offset : offset+2]) + offset += 2 + } + if m.Present.DBTxAttenuation() { + offset += align(offset, 2) + m.DBTxAttenuation = binary.LittleEndian.Uint16(data[offset : offset+2]) + offset += 2 + } + if m.Present.DBMTxPower() { + m.DBMTxPower = int8(data[offset]) + offset++ + } + if m.Present.Antenna() { + m.Antenna = uint8(data[offset]) + offset++ + } + if m.Present.DBAntennaSignal() { + m.DBAntennaSignal = uint8(data[offset]) + offset++ + } + if m.Present.DBAntennaNoise() { + m.DBAntennaNoise = uint8(data[offset]) + offset++ + } + if m.Present.RxFlags() { + offset += align(offset, 2) + m.RxFlags = RadioTapRxFlags(binary.LittleEndian.Uint16(data[offset:])) + offset += 2 + } + if m.Present.TxFlags() { + offset += align(offset, 2) + m.TxFlags = RadioTapTxFlags(binary.LittleEndian.Uint16(data[offset:])) + offset += 2 + } + if m.Present.RtsRetries() { + m.RtsRetries = uint8(data[offset]) + offset++ + } + if m.Present.DataRetries() { + m.DataRetries = uint8(data[offset]) + offset++ + } + if m.Present.MCS() { + m.MCS = RadioTapMCS{ + RadioTapMCSKnown(data[offset]), + RadioTapMCSFlags(data[offset+1]), + uint8(data[offset+2]), + } + offset += 3 + } + if m.Present.AMPDUStatus() { + offset += align(offset, 4) + m.AMPDUStatus = RadioTapAMPDUStatus{ + Reference: binary.LittleEndian.Uint32(data[offset:]), + Flags: RadioTapAMPDUStatusFlags(binary.LittleEndian.Uint16(data[offset+4:])), + CRC: uint8(data[offset+6]), + } + offset += 8 + } + if m.Present.VHT() { + offset += align(offset, 2) + m.VHT = RadioTapVHT{ + Known: RadioTapVHTKnown(binary.LittleEndian.Uint16(data[offset:])), + Flags: RadioTapVHTFlags(data[offset+2]), + Bandwidth: uint8(data[offset+3]), + MCSNSS: [4]RadioTapVHTMCSNSS{ + RadioTapVHTMCSNSS(data[offset+4]), + RadioTapVHTMCSNSS(data[offset+5]), + RadioTapVHTMCSNSS(data[offset+6]), + RadioTapVHTMCSNSS(data[offset+7]), + }, + Coding: uint8(data[offset+8]), + GroupId: uint8(data[offset+9]), + PartialAID: binary.LittleEndian.Uint16(data[offset+10:]), + } + offset += 12 + } + + payload := data[m.Length:] + if !m.Flags.FCS() { // Dot11.DecodeFromBytes() expects FCS present + fcs := make([]byte, 4) + h := crc32.NewIEEE() + h.Write(payload) + binary.LittleEndian.PutUint32(fcs, h.Sum32()) + payload = append(payload, fcs...) + } + m.BaseLayer = BaseLayer{Contents: data[:m.Length], Payload: payload} + + return nil +} + +func (m *RadioTap) CanDecode() gopacket.LayerClass { return LayerTypeRadioTap } +func (m *RadioTap) NextLayerType() gopacket.LayerType { return LayerTypeDot11 } diff --git a/vendor/github.com/google/gopacket/layers/rudp.go b/vendor/github.com/google/gopacket/layers/rudp.go new file mode 100644 index 0000000..8435129 --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/rudp.go @@ -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)}) +} diff --git a/vendor/github.com/google/gopacket/layers/sctp.go b/vendor/github.com/google/gopacket/layers/sctp.go new file mode 100644 index 0000000..3767549 --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/sctp.go @@ -0,0 +1,608 @@ +// 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" + "hash/crc32" +) + +// 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{ + SrcPort: SCTPPort(binary.BigEndian.Uint16(data[:2])), + sPort: data[:2], + DstPort: SCTPPort(binary.BigEndian.Uint16(data[2:4])), + dPort: data[2:4], + VerificationTag: binary.BigEndian.Uint32(data[4:8]), + Checksum: binary.BigEndian.Uint32(data[8:12]), + BaseLayer: BaseLayer{data[:12], data[12:]}, + } + p.AddLayer(sctp) + p.SetTransportLayer(sctp) + 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 +} + +// 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 { + length := binary.BigEndian.Uint16(data[2:4]) + actual := roundUpToNearest4(int(length)) + return SCTPChunk{ + Type: SCTPChunkType(data[0]), + Flags: data[1], + Length: length, + ActualLength: actual, + BaseLayer: BaseLayer{data[:actual], data[actual:]}, + } +} + +// 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 { + sc := &SCTPUnknownChunkType{SCTPChunk: decodeSCTPChunk(data)} + 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 uint32 + PayloadData []byte +} + +// LayerType returns gopacket.LayerTypeSCTPData. +func (s *SCTPData) LayerType() gopacket.LayerType { return LayerTypeSCTPData } + +// Payload returns the data payload of the SCTP data chunk. +func (s *SCTPData) Payload() []byte { + return s.PayloadData +} + +func decodeSCTPData(data []byte, p gopacket.PacketBuilder) error { + sc := &SCTPData{ + SCTPChunk: decodeSCTPChunk(data), + 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: binary.BigEndian.Uint32(data[12:16]), + } + // Length is the length in bytes of the data, INCLUDING the 16-byte header. + sc.PayloadData = data[16:sc.Length] + p.AddLayer(sc) + p.SetApplicationLayer(sc) + return p.NextDecoder(gopacket.DecodeFunc(decodeWithSCTPChunkTypePrefix)) +} + +// SerializeTo is for gopacket.SerializableLayer. +func (sc SCTPData) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error { + length := 16 + len(sc.PayloadData) + bytes, err := b.PrependBytes(roundUpToNearest4(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)) + 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], sc.PayloadProtocol) + copy(bytes[16:], sc.PayloadData) + 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 { + sc := &SCTPInit{ + SCTPChunk: decodeSCTPChunk(data), + 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 { + sc := &SCTPSack{ + SCTPChunk: decodeSCTPChunk(data), + 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 { + sc := &SCTPHeartbeat{ + SCTPChunk: decodeSCTPChunk(data), + } + 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 similarot decodeSCTPHeartbeat ;) + sc := &SCTPError{ + SCTPChunk: decodeSCTPChunk(data), + } + 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 { + sc := &SCTPShutdown{ + SCTPChunk: decodeSCTPChunk(data), + 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 { + sc := &SCTPShutdownAck{ + SCTPChunk: decodeSCTPChunk(data), + } + 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 { + sc := &SCTPCookieEcho{ + SCTPChunk: decodeSCTPChunk(data), + } + 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 { + sc := &SCTPEmptyLayer{ + SCTPChunk: decodeSCTPChunk(data), + } + 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 +} diff --git a/vendor/github.com/google/gopacket/layers/sflow.go b/vendor/github.com/google/gopacket/layers/sflow.go new file mode 100644 index 0000000..a8f138c --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/sflow.go @@ -0,0 +1,1627 @@ +// 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. + +/* +This layer decodes SFlow version 5 datagrams. + +The specification can be found here: http://sflow.org/sflow_version_5.txt + +Additional developer information about sflow can be found at: +http://sflow.org/developers/specifications.php + +And SFlow in general: +http://sflow.org/index.php + +Two forms of sample data are defined: compact and expanded. The +Specification has this to say: + + Compact and expand forms of counter and flow samples are defined. + An agent must not mix compact/expanded encodings. If an agent + will never use ifIndex numbers >= 2^24 then it must use compact + encodings for all interfaces. Otherwise the expanded formats must + be used for all interfaces. + +This decoder only supports the compact form, because that is the only +one for which data was avaialble. + +The datagram is composed of one or more samples of type flow or counter, +and each sample is composed of one or more records describing the sample. +A sample is a single instance of sampled inforamtion, and each record in +the sample gives additional / supplimentary information about the sample. + +The following sample record types are supported: + + Raw Packet Header + opaque = flow_data; enterprise = 0; format = 1 + + Extended Switch Data + opaque = flow_data; enterprise = 0; format = 1001 + + Extended Router Data + opaque = flow_data; enterprise = 0; format = 1002 + + Extended Gateway Data + opaque = flow_data; enterprise = 0; format = 1003 + + Extended User Data + opaque = flow_data; enterprise = 0; format = 1004 + + Extended URL Data + opaque = flow_data; enterprise = 0; format = 1005 + +The following types of counter records are supported: + + Generic Interface Counters - see RFC 2233 + opaque = counter_data; enterprise = 0; format = 1 + + Ethernet Interface Counters - see RFC 2358 + opaque = counter_data; enterprise = 0; format = 2 + +SFlow is encoded using XDR (RFC4506). There are a few places +where the standard 4-byte fields are partitioned into two +bitfields of different lengths. I'm not sure why the designers +chose to pack together two values like this in some places, and +in others they use the entire 4-byte value to store a number that +will never be more than a few bits. In any case, there are a couple +of types defined to handle the decoding of these bitfields, and +that's why they're there. */ + +package layers + +import ( + "encoding/binary" + "fmt" + "github.com/google/gopacket" + "net" +) + +// SFlowRecord holds both flow sample records and counter sample records. +// A Record is the structure that actually holds the sampled data +// and / or counters. +type SFlowRecord interface { +} + +// SFlowDataSource encodes a 2-bit SFlowSourceFormat in its most significant +// 2 bits, and an SFlowSourceValue in its least significant 30 bits. +// These types and values define the meaning of the inteface information +// presented in the sample metadata. +type SFlowDataSource int32 + +func (sdc SFlowDataSource) decode() (SFlowSourceFormat, SFlowSourceValue) { + leftField := sdc >> 30 + rightField := uint32(0x3FFFFFFF) & uint32(sdc) + return SFlowSourceFormat(leftField), SFlowSourceValue(rightField) +} + +type SFlowSourceFormat uint32 + +type SFlowSourceValue uint32 + +const ( + SFlowTypeSingleInterface SFlowSourceFormat = 0 + SFlowTypePacketDiscarded SFlowSourceFormat = 1 + SFlowTypeMultipleDestinations SFlowSourceFormat = 2 +) + +func (sdf SFlowSourceFormat) String() string { + switch sdf { + case SFlowTypeSingleInterface: + return "Single Interface" + case SFlowTypePacketDiscarded: + return "Packet Discarded" + case SFlowTypeMultipleDestinations: + return "Multiple Destinations" + default: + return "UNKNOWN" + } +} + +func decodeSFlow(data []byte, p gopacket.PacketBuilder) error { + s := &SFlowDatagram{} + err := s.DecodeFromBytes(data, p) + if err != nil { + return err + } + p.AddLayer(s) + p.SetApplicationLayer(s) + return nil +} + +// SFlowDatagram is the outermost container which holds some basic information +// about the reporting agent, and holds at least one sample record +type SFlowDatagram struct { + BaseLayer + + DatagramVersion uint32 + AgentAddress net.IP + SubAgentID uint32 + SequenceNumber uint32 + AgentUptime uint32 + SampleCount uint32 + FlowSamples []SFlowFlowSample + CounterSamples []SFlowCounterSample +} + +// An SFlow datagram's outer container has the following +// structure: + +// 0 15 31 +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | int sFlow version (2|4|5) | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | int IP version of the Agent (1=v4|2=v6) | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// / Agent IP address (v4=4byte|v6=16byte) / +// / / +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | int sub agent id | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | int datagram sequence number | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | int switch uptime in ms | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | int n samples in datagram | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// / n samples / +// / / +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + +// SFlowDataFormat encodes the EnterpriseID in the most +// significant 12 bits, and the SampleType in the least significant +// 20 bits. +type SFlowDataFormat uint32 + +func (sdf SFlowDataFormat) decode() (SFlowEnterpriseID, SFlowSampleType) { + leftField := sdf >> 12 + rightField := uint32(0xFFF) & uint32(sdf) + return SFlowEnterpriseID(leftField), SFlowSampleType(rightField) +} + +// SFlowEnterpriseID is used to differentiate between the +// official SFlow standard, and other, vendor-specific +// types of flow data. (Similiar to SNMP's enterprise MIB +// OIDs) Only the office SFlow Enterprise ID is decoded +// here. +type SFlowEnterpriseID uint32 + +const ( + SFlowStandard SFlowEnterpriseID = 0 +) + +func (eid SFlowEnterpriseID) String() string { + switch eid { + case SFlowStandard: + return "Standard SFlow" + default: + return "" + } +} + +func (eid SFlowEnterpriseID) GetType() SFlowEnterpriseID { + return SFlowStandard +} + +// SFlowSampleType specifies the type of sample. Only flow samples +// and counter samples are supported +type SFlowSampleType uint32 + +const ( + SFlowTypeFlowSample SFlowSampleType = 1 + SFlowTypeCounterSample SFlowSampleType = 2 + SFlowTypeExpandedFlowSample SFlowSampleType = 3 + SFlowTypeExpandedCounterSample SFlowSampleType = 4 +) + +func (st SFlowSampleType) GetType() SFlowSampleType { + switch st { + case SFlowTypeFlowSample: + return SFlowTypeFlowSample + case SFlowTypeCounterSample: + return SFlowTypeCounterSample + case SFlowTypeExpandedFlowSample: + return SFlowTypeExpandedFlowSample + case SFlowTypeExpandedCounterSample: + return SFlowTypeExpandedCounterSample + default: + panic("Invalid Sample Type") + } +} + +func (st SFlowSampleType) String() string { + switch st { + case SFlowTypeFlowSample: + return "Flow Sample" + case SFlowTypeCounterSample: + return "Counter Sample" + case SFlowTypeExpandedFlowSample: + return "Expanded Flow Sample" + case SFlowTypeExpandedCounterSample: + return "Expanded Counter Sample" + default: + return "" + } +} + +func (s *SFlowDatagram) LayerType() gopacket.LayerType { return LayerTypeSFlow } + +func (d *SFlowDatagram) Payload() []byte { return nil } + +func (d *SFlowDatagram) CanDecode() gopacket.LayerClass { return LayerTypeSFlow } + +func (d *SFlowDatagram) NextLayerType() gopacket.LayerType { return gopacket.LayerTypePayload } + +// SFlowIPType determines what form the IP address being decoded will +// take. This is an XDR union type allowing for both IPv4 and IPv6 +type SFlowIPType uint32 + +const ( + SFlowIPv4 SFlowIPType = 1 + SFlowIPv6 SFlowIPType = 2 +) + +func (s SFlowIPType) String() string { + switch s { + case SFlowIPv4: + return "IPv4" + case SFlowIPv6: + return "IPv6" + default: + return "" + } +} + +func (s SFlowIPType) Length() int { + switch s { + case SFlowIPv4: + return 4 + case SFlowIPv6: + return 16 + default: + return 0 + } +} + +func (s *SFlowDatagram) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { + var agentAddressType SFlowIPType + + data, s.DatagramVersion = data[4:], binary.BigEndian.Uint32(data[:4]) + data, agentAddressType = data[4:], SFlowIPType(binary.BigEndian.Uint32(data[:4])) + data, s.AgentAddress = data[agentAddressType.Length():], data[:agentAddressType.Length()] + data, s.SubAgentID = data[4:], binary.BigEndian.Uint32(data[:4]) + data, s.SequenceNumber = data[4:], binary.BigEndian.Uint32(data[:4]) + data, s.AgentUptime = data[4:], binary.BigEndian.Uint32(data[:4]) + data, s.SampleCount = data[4:], binary.BigEndian.Uint32(data[:4]) + + if s.SampleCount < 1 { + return fmt.Errorf("SFlow Datagram has invalid sample length: %d", s.SampleCount) + } + for i := uint32(0); i < s.SampleCount; i++ { + sdf := SFlowDataFormat(binary.BigEndian.Uint32(data[:4])) + _, sampleType := sdf.decode() + switch sampleType { + case SFlowTypeFlowSample: + if flowSample, err := decodeFlowSample(&data); err == nil { + s.FlowSamples = append(s.FlowSamples, flowSample) + } else { + return err + } + case SFlowTypeCounterSample: + if counterSample, err := decodeCounterSample(&data); err == nil { + s.CounterSamples = append(s.CounterSamples, counterSample) + } else { + return err + } + case SFlowTypeExpandedFlowSample: + // TODO + return fmt.Errorf("Unsupported SFlow sample type TypeExpandedFlowSample") + case SFlowTypeExpandedCounterSample: + // TODO + return fmt.Errorf("Unsupported SFlow sample type TypeExpandedCounterSample") + default: + return fmt.Errorf("Unsupported SFlow sample type %d", sampleType) + } + } + return nil +} + +// SFlowFlowSample represents a sampled packet and contains +// one or more records describing the packet +type SFlowFlowSample struct { + EnterpriseID SFlowEnterpriseID + Format SFlowSampleType + SampleLength uint32 + SequenceNumber uint32 + SourceIDClass SFlowSourceFormat + SourceIDIndex SFlowSourceValue + SamplingRate uint32 + SamplePool uint32 + Dropped uint32 + InputInterface uint32 + OutputInterface uint32 + RecordCount uint32 + Records []SFlowRecord +} + +// Flow samples have the following structure. Note +// the bit fields to encode the Enterprise ID and the +// Flow record format: + +// 0 15 31 +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | 20 bit Interprise (0) |12 bit format | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | sample length | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | int sample sequence number | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// |id type | src id index value | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | int sampling rate | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | int sample pool | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | int drops | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | int input ifIndex | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | int output ifIndex | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | int number of records | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// / flow records / +// / / +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + +type SFlowFlowDataFormat uint32 + +func (fdf SFlowFlowDataFormat) decode() (SFlowEnterpriseID, SFlowFlowRecordType) { + leftField := fdf >> 12 + rightField := uint32(0xFFF) & uint32(fdf) + return SFlowEnterpriseID(leftField), SFlowFlowRecordType(rightField) +} + +func (fs SFlowFlowSample) GetRecords() []SFlowRecord { + return fs.Records +} + +func (fs SFlowFlowSample) GetType() SFlowSampleType { + return SFlowTypeFlowSample +} + +func skipRecord(data *[]byte) { + recordLength := int(binary.BigEndian.Uint32((*data)[4:])) + *data = (*data)[(recordLength+((4-recordLength)%4))+8:] +} + +func decodeFlowSample(data *[]byte) (SFlowFlowSample, error) { + s := SFlowFlowSample{} + var sdf SFlowDataFormat + *data, sdf = (*data)[4:], SFlowDataFormat(binary.BigEndian.Uint32((*data)[:4])) + var sdc SFlowDataSource + + s.EnterpriseID, s.Format = sdf.decode() + *data, s.SampleLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, s.SequenceNumber = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, sdc = (*data)[4:], SFlowDataSource(binary.BigEndian.Uint32((*data)[:4])) + s.SourceIDClass, s.SourceIDIndex = sdc.decode() + *data, s.SamplingRate = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, s.SamplePool = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, s.Dropped = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, s.InputInterface = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, s.OutputInterface = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, s.RecordCount = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + + for i := uint32(0); i < s.RecordCount; i++ { + rdf := SFlowFlowDataFormat(binary.BigEndian.Uint32((*data)[:4])) + _, flowRecordType := rdf.decode() + + switch flowRecordType { + case SFlowTypeRawPacketFlow: + if record, err := decodeRawPacketFlowRecord(data); err == nil { + s.Records = append(s.Records, record) + } else { + return s, err + } + case SFlowTypeExtendedUserFlow: + if record, err := decodeExtendedUserFlow(data); err == nil { + s.Records = append(s.Records, record) + } else { + return s, err + } + case SFlowTypeExtendedUrlFlow: + if record, err := decodeExtendedURLRecord(data); err == nil { + s.Records = append(s.Records, record) + } else { + return s, err + } + case SFlowTypeExtendedSwitchFlow: + if record, err := decodeExtendedSwitchFlowRecord(data); err == nil { + s.Records = append(s.Records, record) + } else { + return s, err + } + case SFlowTypeExtendedRouterFlow: + if record, err := decodeExtendedRouterFlowRecord(data); err == nil { + s.Records = append(s.Records, record) + } else { + return s, err + } + case SFlowTypeExtendedGatewayFlow: + if record, err := decodeExtendedGatewayFlowRecord(data); err == nil { + s.Records = append(s.Records, record) + } else { + return s, err + } + case SFlowTypeEthernetFrameFlow: + // TODO + skipRecord(data) + return s, fmt.Errorf("skipping TypeEthernetFrameFlow") + case SFlowTypeIpv4Flow: + // TODO + skipRecord(data) + return s, fmt.Errorf("skipping TypeIpv4Flow") + case SFlowTypeIpv6Flow: + // TODO + skipRecord(data) + return s, fmt.Errorf("skipping TypeIpv6Flow") + case SFlowTypeExtendedMlpsFlow: + // TODO + skipRecord(data) + return s, fmt.Errorf("skipping TypeExtendedMlpsFlow") + case SFlowTypeExtendedNatFlow: + // TODO + skipRecord(data) + return s, fmt.Errorf("skipping TypeExtendedNatFlow") + case SFlowTypeExtendedMlpsTunnelFlow: + // TODO + skipRecord(data) + return s, fmt.Errorf("skipping TypeExtendedMlpsTunnelFlow") + case SFlowTypeExtendedMlpsVcFlow: + // TODO + skipRecord(data) + return s, fmt.Errorf("skipping TypeExtendedMlpsVcFlow") + case SFlowTypeExtendedMlpsFecFlow: + // TODO + skipRecord(data) + return s, fmt.Errorf("skipping TypeExtendedMlpsFecFlow") + case SFlowTypeExtendedMlpsLvpFecFlow: + // TODO + skipRecord(data) + return s, fmt.Errorf("skipping TypeExtendedMlpsLvpFecFlow") + case SFlowTypeExtendedVlanFlow: + // TODO + skipRecord(data) + return s, fmt.Errorf("skipping TypeExtendedVlanFlow") + default: + return s, fmt.Errorf("Unsupported flow record type: %d", flowRecordType) + } + } + return s, nil +} + +// Counter samples report information about various counter +// objects. Typically these are items like IfInOctets, or +// CPU / Memory stats, etc. SFlow will report these at regular +// intervals as configured on the agent. If one were sufficiently +// industrious, this could be used to replace the typical +// SNMP polling used for such things. +type SFlowCounterSample struct { + EnterpriseID SFlowEnterpriseID + Format SFlowSampleType + SampleLength uint32 + SequenceNumber uint32 + SourceIDClass SFlowSourceFormat + SourceIDIndex SFlowSourceValue + RecordCount uint32 + Records []SFlowRecord +} + +// Counter samples have the following structure: + +// 0 15 31 +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | int sample sequence number | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// |id type | src id index value | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | int number of records | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// / counter records / +// / / +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + +type SFlowCounterDataFormat uint32 + +func (cdf SFlowCounterDataFormat) decode() (SFlowEnterpriseID, SFlowCounterRecordType) { + leftField := cdf >> 12 + rightField := uint32(0xFFF) & uint32(cdf) + return SFlowEnterpriseID(leftField), SFlowCounterRecordType(rightField) +} + +// GetRecords will return a slice of interface types +// representing records. A type switch can be used to +// get at the underlying SFlowCounterRecordType. +func (cs SFlowCounterSample) GetRecords() []SFlowRecord { + return cs.Records +} + +// GetType will report the type of sample. Only the +// compact form of counter samples is supported +func (cs SFlowCounterSample) GetType() SFlowSampleType { + return SFlowTypeCounterSample +} + +type SFlowCounterRecordType uint32 + +const ( + SFlowTypeGenericInterfaceCounters SFlowCounterRecordType = 1 + SFlowTypeEthernetInterfaceCounters SFlowCounterRecordType = 2 + SFlowTypeTokenRingInterfaceCounters SFlowCounterRecordType = 3 + SFlowType100BaseVGInterfaceCounters SFlowCounterRecordType = 4 + SFlowTypeVLANCounters SFlowCounterRecordType = 5 + SFlowTypeProcessorCounters SFlowCounterRecordType = 1001 +) + +func (cr SFlowCounterRecordType) String() string { + switch cr { + case SFlowTypeGenericInterfaceCounters: + return "Generic Interface Counters" + case SFlowTypeEthernetInterfaceCounters: + return "Ethernet Interface Counters" + case SFlowTypeTokenRingInterfaceCounters: + return "Token Ring Interface Counters" + case SFlowType100BaseVGInterfaceCounters: + return "100BaseVG Interface Counters" + case SFlowTypeVLANCounters: + return "VLAN Counters" + case SFlowTypeProcessorCounters: + return "Processor Counters" + default: + return "" + + } +} + +func decodeCounterSample(data *[]byte) (SFlowCounterSample, error) { + s := SFlowCounterSample{} + var sdc SFlowDataSource + var sdf SFlowDataFormat + + *data, sdf = (*data)[4:], SFlowDataFormat(binary.BigEndian.Uint32((*data)[:4])) + s.EnterpriseID, s.Format = sdf.decode() + *data, s.SampleLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, s.SequenceNumber = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, sdc = (*data)[4:], SFlowDataSource(binary.BigEndian.Uint32((*data)[:4])) + s.SourceIDClass, s.SourceIDIndex = sdc.decode() + *data, s.RecordCount = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + + for i := uint32(0); i < s.RecordCount; i++ { + cdf := SFlowCounterDataFormat(binary.BigEndian.Uint32((*data)[:4])) + _, counterRecordType := cdf.decode() + switch counterRecordType { + case SFlowTypeGenericInterfaceCounters: + if record, err := decodeGenericInterfaceCounters(data); err == nil { + s.Records = append(s.Records, record) + } else { + return s, err + } + case SFlowTypeEthernetInterfaceCounters: + if record, err := decodeEthernetCounters(data); err == nil { + s.Records = append(s.Records, record) + } else { + return s, err + } + case SFlowTypeTokenRingInterfaceCounters: + skipRecord(data) + return s, fmt.Errorf("skipping TypeTokenRingInterfaceCounters") + case SFlowType100BaseVGInterfaceCounters: + skipRecord(data) + return s, fmt.Errorf("skipping Type100BaseVGInterfaceCounters") + case SFlowTypeVLANCounters: + skipRecord(data) + return s, fmt.Errorf("skipping TypeVLANCounters") + case SFlowTypeProcessorCounters: + skipRecord(data) + return s, fmt.Errorf("skipping TypeProcessorCounters") + default: + return s, fmt.Errorf("Invalid counter record type: %d", counterRecordType) + } + } + return s, nil +} + +// SFlowBaseFlowRecord holds the fields common to all records +// of type SFlowFlowRecordType +type SFlowBaseFlowRecord struct { + EnterpriseID SFlowEnterpriseID + Format SFlowFlowRecordType + FlowDataLength uint32 +} + +func (bfr SFlowBaseFlowRecord) GetType() SFlowFlowRecordType { + return bfr.Format +} + +// SFlowFlowRecordType denotes what kind of Flow Record is +// represented. See RFC 3176 +type SFlowFlowRecordType uint32 + +const ( + SFlowTypeRawPacketFlow SFlowFlowRecordType = 1 + SFlowTypeEthernetFrameFlow SFlowFlowRecordType = 2 + SFlowTypeIpv4Flow SFlowFlowRecordType = 3 + SFlowTypeIpv6Flow SFlowFlowRecordType = 4 + SFlowTypeExtendedSwitchFlow SFlowFlowRecordType = 1001 + SFlowTypeExtendedRouterFlow SFlowFlowRecordType = 1002 + SFlowTypeExtendedGatewayFlow SFlowFlowRecordType = 1003 + SFlowTypeExtendedUserFlow SFlowFlowRecordType = 1004 + SFlowTypeExtendedUrlFlow SFlowFlowRecordType = 1005 + SFlowTypeExtendedMlpsFlow SFlowFlowRecordType = 1006 + SFlowTypeExtendedNatFlow SFlowFlowRecordType = 1007 + SFlowTypeExtendedMlpsTunnelFlow SFlowFlowRecordType = 1008 + SFlowTypeExtendedMlpsVcFlow SFlowFlowRecordType = 1009 + SFlowTypeExtendedMlpsFecFlow SFlowFlowRecordType = 1010 + SFlowTypeExtendedMlpsLvpFecFlow SFlowFlowRecordType = 1011 + SFlowTypeExtendedVlanFlow SFlowFlowRecordType = 1012 +) + +func (rt SFlowFlowRecordType) String() string { + switch rt { + case SFlowTypeRawPacketFlow: + return "Raw Packet Flow Record" + case SFlowTypeEthernetFrameFlow: + return "Ethernet Frame Flow Record" + case SFlowTypeIpv4Flow: + return "IPv4 Flow Record" + case SFlowTypeIpv6Flow: + return "IPv6 Flow Record" + case SFlowTypeExtendedSwitchFlow: + return "Extended Switch Flow Record" + case SFlowTypeExtendedRouterFlow: + return "Extended Router Flow Record" + case SFlowTypeExtendedGatewayFlow: + return "Extended Gateway Flow Record" + case SFlowTypeExtendedUserFlow: + return "Extended User Flow Record" + case SFlowTypeExtendedUrlFlow: + return "Extended URL Flow Record" + case SFlowTypeExtendedMlpsFlow: + return "Extended MPLS Flow Record" + case SFlowTypeExtendedNatFlow: + return "Extended NAT Flow Record" + case SFlowTypeExtendedMlpsTunnelFlow: + return "Extended MPLS Tunnel Flow Record" + case SFlowTypeExtendedMlpsVcFlow: + return "Extended MPLS VC Flow Record" + case SFlowTypeExtendedMlpsFecFlow: + return "Extended MPLS FEC Flow Record" + case SFlowTypeExtendedMlpsLvpFecFlow: + return "Extended MPLS LVP FEC Flow Record" + case SFlowTypeExtendedVlanFlow: + return "Extended VLAN Flow Record" + default: + return "" + } +} + +// SFlowRawPacketFlowRecords hold information about a sampled +// packet grabbed as it transited the agent. This is +// perhaps the most useful and interesting record type, +// as it holds the headers of the sampled packet and +// can be used to build up a complete picture of the +// traffic patterns on a network. +// +// The raw packet header is sent back into gopacket for +// decoding, and the resulting gopackt.Packet is stored +// in the Header member +type SFlowRawPacketFlowRecord struct { + SFlowBaseFlowRecord + HeaderProtocol SFlowRawHeaderProtocol + FrameLength uint32 + PayloadRemoved uint32 + HeaderLength uint32 + Header gopacket.Packet +} + +// Raw packet record types have the following structure: + +// 0 15 31 +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | 20 bit Interprise (0) |12 bit format | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | record length | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | Header Protocol | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | Frame Length | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | Payload Removed | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | Header Length | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// \ Header \ +// \ \ +// \ \ +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + +type SFlowRawHeaderProtocol uint32 + +const ( + SFlowProtoEthernet SFlowRawHeaderProtocol = 1 + SFlowProtoISO88024 SFlowRawHeaderProtocol = 2 + SFlowProtoISO88025 SFlowRawHeaderProtocol = 3 + SFlowProtoFDDI SFlowRawHeaderProtocol = 4 + SFlowProtoFrameRelay SFlowRawHeaderProtocol = 5 + SFlowProtoX25 SFlowRawHeaderProtocol = 6 + SFlowProtoPPP SFlowRawHeaderProtocol = 7 + SFlowProtoSMDS SFlowRawHeaderProtocol = 8 + SFlowProtoAAL5 SFlowRawHeaderProtocol = 9 + SFlowProtoAAL5_IP SFlowRawHeaderProtocol = 10 /* e.g. Cisco AAL5 mux */ + SFlowProtoIPv4 SFlowRawHeaderProtocol = 11 + SFlowProtoIPv6 SFlowRawHeaderProtocol = 12 + SFlowProtoMPLS SFlowRawHeaderProtocol = 13 + SFlowProtoPOS SFlowRawHeaderProtocol = 14 /* RFC 1662, 2615 */ +) + +func (sfhp SFlowRawHeaderProtocol) String() string { + switch sfhp { + case SFlowProtoEthernet: + return "ETHERNET-ISO88023" + case SFlowProtoISO88024: + return "ISO88024-TOKENBUS" + case SFlowProtoISO88025: + return "ISO88025-TOKENRING" + case SFlowProtoFDDI: + return "FDDI" + case SFlowProtoFrameRelay: + return "FRAME-RELAY" + case SFlowProtoX25: + return "X25" + case SFlowProtoPPP: + return "PPP" + case SFlowProtoSMDS: + return "SMDS" + case SFlowProtoAAL5: + return "AAL5" + case SFlowProtoAAL5_IP: + return "AAL5-IP" + case SFlowProtoIPv4: + return "IPv4" + case SFlowProtoIPv6: + return "IPv6" + case SFlowProtoMPLS: + return "MPLS" + case SFlowProtoPOS: + return "POS" + } + return "UNKNOWN" +} + +func decodeRawPacketFlowRecord(data *[]byte) (SFlowRawPacketFlowRecord, error) { + rec := SFlowRawPacketFlowRecord{} + header := []byte{} + var fdf SFlowFlowDataFormat + + *data, fdf = (*data)[4:], SFlowFlowDataFormat(binary.BigEndian.Uint32((*data)[:4])) + rec.EnterpriseID, rec.Format = fdf.decode() + *data, rec.FlowDataLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, rec.HeaderProtocol = (*data)[4:], SFlowRawHeaderProtocol(binary.BigEndian.Uint32((*data)[:4])) + *data, rec.FrameLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, rec.PayloadRemoved = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, rec.HeaderLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + headerLenWithPadding := int(rec.HeaderLength + ((4 - rec.HeaderLength) % 4)) + *data, header = (*data)[headerLenWithPadding:], (*data)[:headerLenWithPadding] + rec.Header = gopacket.NewPacket(header, LayerTypeEthernet, gopacket.Default) + return rec, nil +} + +// SFlowExtendedSwitchFlowRecord give additional information +// about the sampled packet if it's available. It's mainly +// useful for getting at the incoming and outgoing VLANs +// An agent may or may not provide this information. +type SFlowExtendedSwitchFlowRecord struct { + SFlowBaseFlowRecord + IncomingVLAN uint32 + IncomingVLANPriority uint32 + OutgoingVLAN uint32 + OutgoingVLANPriority uint32 +} + +// Extended switch records have the following structure: + +// 0 15 31 +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | 20 bit Interprise (0) |12 bit format | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | record length | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | Incoming VLAN | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | Incoming VLAN Priority | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | Outgoing VLAN | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | Outgoing VLAN Priority | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + +func decodeExtendedSwitchFlowRecord(data *[]byte) (SFlowExtendedSwitchFlowRecord, error) { + es := SFlowExtendedSwitchFlowRecord{} + var fdf SFlowFlowDataFormat + + *data, fdf = (*data)[4:], SFlowFlowDataFormat(binary.BigEndian.Uint32((*data)[:4])) + es.EnterpriseID, es.Format = fdf.decode() + *data, es.FlowDataLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, es.IncomingVLAN = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, es.IncomingVLANPriority = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, es.OutgoingVLAN = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, es.OutgoingVLANPriority = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + return es, nil +} + +// SFlowExtendedRouterFlowRecord gives additional information +// about the layer 3 routing information used to forward +// the packet +type SFlowExtendedRouterFlowRecord struct { + SFlowBaseFlowRecord + NextHop net.IP + NextHopSourceMask uint32 + NextHopDestinationMask uint32 +} + +// Extended router records have the following structure: + +// 0 15 31 +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | 20 bit Interprise (0) |12 bit format | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | record length | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | Next Hop | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | Next Hop Source Mask | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | Next Hop Destination Mask | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + +func decodeExtendedRouterFlowRecord(data *[]byte) (SFlowExtendedRouterFlowRecord, error) { + er := SFlowExtendedRouterFlowRecord{} + var fdf SFlowFlowDataFormat + var erat SFlowIPType + + *data, fdf = (*data)[4:], SFlowFlowDataFormat(binary.BigEndian.Uint32((*data)[:4])) + er.EnterpriseID, er.Format = fdf.decode() + *data, er.FlowDataLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, erat = (*data)[4:], SFlowIPType(binary.BigEndian.Uint32((*data)[:4])) + *data, er.NextHop = (*data)[erat.Length():], (*data)[:erat.Length()] + *data, er.NextHopSourceMask = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, er.NextHopDestinationMask = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + return er, nil +} + +// SFlowExtendedGatewayFlowRecord describes information treasured by +// nework engineers everywhere: AS path information listing which +// BGP peer sent the packet, and various other BGP related info. +// This information is vital because it gives a picture of how much +// traffic is being sent from / received by various BGP peers. + +// Extended gatway records have the following structure: + +// 0 15 31 +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | 20 bit Interprise (0) |12 bit format | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | record length | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | Next Hop | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | AS | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | Source AS | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | Peer AS | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | AS Path Count | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// / AS Path / Sequence / +// / / +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// / Communities / +// / / +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | Local Pref | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + +// AS Path / Sequence: + +// 0 15 31 +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | AS Source Type (Path=1 / Sequence=2) | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | Path / Sequence length | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// / Path / Sequence Members / +// / / +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + +// Communities: + +// 0 15 31 +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | communitiy length | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// / communitiy Members / +// / / +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + +type SFlowExtendedGatewayFlowRecord struct { + SFlowBaseFlowRecord + NextHop net.IP + AS uint32 + SourceAS uint32 + PeerAS uint32 + ASPathCount uint32 + ASPath []SFlowASDestination + Communities []uint32 + LocalPref uint32 +} + +type SFlowASPathType uint32 + +const ( + SFlowASSet SFlowASPathType = 1 + SFlowASSequence SFlowASPathType = 2 +) + +func (apt SFlowASPathType) String() string { + switch apt { + case SFlowASSet: + return "AS Set" + case SFlowASSequence: + return "AS Sequence" + default: + return "" + } +} + +type SFlowASDestination struct { + Type SFlowASPathType + Count uint32 + Members []uint32 +} + +func (asd SFlowASDestination) String() string { + switch asd.Type { + case SFlowASSet: + return fmt.Sprint("AS Set:", asd.Members) + case SFlowASSequence: + return fmt.Sprint("AS Sequence:", asd.Members) + default: + return "" + } +} + +func (ad *SFlowASDestination) decodePath(data *[]byte) { + *data, ad.Type = (*data)[4:], SFlowASPathType(binary.BigEndian.Uint32((*data)[:4])) + *data, ad.Count = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + ad.Members = make([]uint32, ad.Count) + for i := uint32(0); i < ad.Count; i++ { + var member uint32 + *data, member = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + ad.Members[i] = member + } +} + +func decodeExtendedGatewayFlowRecord(data *[]byte) (SFlowExtendedGatewayFlowRecord, error) { + eg := SFlowExtendedGatewayFlowRecord{} + var fdf SFlowFlowDataFormat + var extendedGatewayAddressType SFlowIPType + var communitiesLength uint32 + var community uint32 + + *data, fdf = (*data)[4:], SFlowFlowDataFormat(binary.BigEndian.Uint32((*data)[:4])) + eg.EnterpriseID, eg.Format = fdf.decode() + *data, eg.FlowDataLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, extendedGatewayAddressType = (*data)[4:], SFlowIPType(binary.BigEndian.Uint32((*data)[:4])) + *data, eg.NextHop = (*data)[extendedGatewayAddressType.Length():], (*data)[:extendedGatewayAddressType.Length()] + *data, eg.AS = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, eg.SourceAS = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, eg.PeerAS = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, eg.ASPathCount = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + for i := uint32(0); i < eg.ASPathCount; i++ { + asPath := SFlowASDestination{} + asPath.decodePath(data) + eg.ASPath = append(eg.ASPath, asPath) + } + *data, communitiesLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + eg.Communities = make([]uint32, communitiesLength) + for j := uint32(0); j < communitiesLength; j++ { + *data, community = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + eg.Communities[j] = community + } + *data, eg.LocalPref = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + return eg, nil +} + +// ************************************************** +// Extended URL Flow Record +// ************************************************** + +// 0 15 31 +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | 20 bit Interprise (0) |12 bit format | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | record length | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | direction | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | URL | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | Host | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + +type SFlowURLDirection uint32 + +const ( + SFlowURLsrc SFlowURLDirection = 1 + SFlowURLdst SFlowURLDirection = 2 +) + +func (urld SFlowURLDirection) String() string { + switch urld { + case SFlowURLsrc: + return "Source address is the server" + case SFlowURLdst: + return "Destination address is the server" + default: + return "" + } +} + +type SFlowExtendedURLRecord struct { + SFlowBaseFlowRecord + Direction SFlowURLDirection + URL string + Host string +} + +func decodeExtendedURLRecord(data *[]byte) (SFlowExtendedURLRecord, error) { + eur := SFlowExtendedURLRecord{} + var fdf SFlowFlowDataFormat + var urlLen uint32 + var urlLenWithPad int + var hostLen uint32 + var hostLenWithPad int + var urlBytes []byte + var hostBytes []byte + + *data, fdf = (*data)[4:], SFlowFlowDataFormat(binary.BigEndian.Uint32((*data)[:4])) + eur.EnterpriseID, eur.Format = fdf.decode() + *data, eur.FlowDataLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, eur.Direction = (*data)[4:], SFlowURLDirection(binary.BigEndian.Uint32((*data)[:4])) + *data, urlLen = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + urlLenWithPad = int(urlLen + ((4 - urlLen) % 4)) + *data, urlBytes = (*data)[urlLenWithPad:], (*data)[:urlLenWithPad] + eur.URL = string(urlBytes[:urlLen]) + *data, hostLen = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + hostLenWithPad = int(hostLen + ((4 - hostLen) % 4)) + *data, hostBytes = (*data)[hostLenWithPad:], (*data)[:hostLenWithPad] + eur.Host = string(hostBytes[:hostLen]) + return eur, nil +} + +// ************************************************** +// Extended User Flow Record +// ************************************************** + +// 0 15 31 +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | 20 bit Interprise (0) |12 bit format | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | record length | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | Source Character Set | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | Source User Id | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | Destination Character Set | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | Destination User ID | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + +type SFlowExtendedUserFlow struct { + SFlowBaseFlowRecord + SourceCharSet SFlowCharSet + SourceUserID string + DestinationCharSet SFlowCharSet + DestinationUserID string +} + +type SFlowCharSet uint32 + +const ( + SFlowCSunknown SFlowCharSet = 2 + SFlowCSASCII SFlowCharSet = 3 + SFlowCSISOLatin1 SFlowCharSet = 4 + SFlowCSISOLatin2 SFlowCharSet = 5 + SFlowCSISOLatin3 SFlowCharSet = 6 + SFlowCSISOLatin4 SFlowCharSet = 7 + SFlowCSISOLatinCyrillic SFlowCharSet = 8 + SFlowCSISOLatinArabic SFlowCharSet = 9 + SFlowCSISOLatinGreek SFlowCharSet = 10 + SFlowCSISOLatinHebrew SFlowCharSet = 11 + SFlowCSISOLatin5 SFlowCharSet = 12 + SFlowCSISOLatin6 SFlowCharSet = 13 + SFlowCSISOTextComm SFlowCharSet = 14 + SFlowCSHalfWidthKatakana SFlowCharSet = 15 + SFlowCSJISEncoding SFlowCharSet = 16 + SFlowCSShiftJIS SFlowCharSet = 17 + SFlowCSEUCPkdFmtJapanese SFlowCharSet = 18 + SFlowCSEUCFixWidJapanese SFlowCharSet = 19 + SFlowCSISO4UnitedKingdom SFlowCharSet = 20 + SFlowCSISO11SwedishForNames SFlowCharSet = 21 + SFlowCSISO15Italian SFlowCharSet = 22 + SFlowCSISO17Spanish SFlowCharSet = 23 + SFlowCSISO21German SFlowCharSet = 24 + SFlowCSISO60DanishNorwegian SFlowCharSet = 25 + SFlowCSISO69French SFlowCharSet = 26 + SFlowCSISO10646UTF1 SFlowCharSet = 27 + SFlowCSISO646basic1983 SFlowCharSet = 28 + SFlowCSINVARIANT SFlowCharSet = 29 + SFlowCSISO2IntlRefVersion SFlowCharSet = 30 + SFlowCSNATSSEFI SFlowCharSet = 31 + SFlowCSNATSSEFIADD SFlowCharSet = 32 + SFlowCSNATSDANO SFlowCharSet = 33 + SFlowCSNATSDANOADD SFlowCharSet = 34 + SFlowCSISO10Swedish SFlowCharSet = 35 + SFlowCSKSC56011987 SFlowCharSet = 36 + SFlowCSISO2022KR SFlowCharSet = 37 + SFlowCSEUCKR SFlowCharSet = 38 + SFlowCSISO2022JP SFlowCharSet = 39 + SFlowCSISO2022JP2 SFlowCharSet = 40 + SFlowCSISO13JISC6220jp SFlowCharSet = 41 + SFlowCSISO14JISC6220ro SFlowCharSet = 42 + SFlowCSISO16Portuguese SFlowCharSet = 43 + SFlowCSISO18Greek7Old SFlowCharSet = 44 + SFlowCSISO19LatinGreek SFlowCharSet = 45 + SFlowCSISO25French SFlowCharSet = 46 + SFlowCSISO27LatinGreek1 SFlowCharSet = 47 + SFlowCSISO5427Cyrillic SFlowCharSet = 48 + SFlowCSISO42JISC62261978 SFlowCharSet = 49 + SFlowCSISO47BSViewdata SFlowCharSet = 50 + SFlowCSISO49INIS SFlowCharSet = 51 + SFlowCSISO50INIS8 SFlowCharSet = 52 + SFlowCSISO51INISCyrillic SFlowCharSet = 53 + SFlowCSISO54271981 SFlowCharSet = 54 + SFlowCSISO5428Greek SFlowCharSet = 55 + SFlowCSISO57GB1988 SFlowCharSet = 56 + SFlowCSISO58GB231280 SFlowCharSet = 57 + SFlowCSISO61Norwegian2 SFlowCharSet = 58 + SFlowCSISO70VideotexSupp1 SFlowCharSet = 59 + SFlowCSISO84Portuguese2 SFlowCharSet = 60 + SFlowCSISO85Spanish2 SFlowCharSet = 61 + SFlowCSISO86Hungarian SFlowCharSet = 62 + SFlowCSISO87JISX0208 SFlowCharSet = 63 + SFlowCSISO88Greek7 SFlowCharSet = 64 + SFlowCSISO89ASMO449 SFlowCharSet = 65 + SFlowCSISO90 SFlowCharSet = 66 + SFlowCSISO91JISC62291984a SFlowCharSet = 67 + SFlowCSISO92JISC62991984b SFlowCharSet = 68 + SFlowCSISO93JIS62291984badd SFlowCharSet = 69 + SFlowCSISO94JIS62291984hand SFlowCharSet = 70 + SFlowCSISO95JIS62291984handadd SFlowCharSet = 71 + SFlowCSISO96JISC62291984kana SFlowCharSet = 72 + SFlowCSISO2033 SFlowCharSet = 73 + SFlowCSISO99NAPLPS SFlowCharSet = 74 + SFlowCSISO102T617bit SFlowCharSet = 75 + SFlowCSISO103T618bit SFlowCharSet = 76 + SFlowCSISO111ECMACyrillic SFlowCharSet = 77 + SFlowCSa71 SFlowCharSet = 78 + SFlowCSa72 SFlowCharSet = 79 + SFlowCSISO123CSAZ24341985gr SFlowCharSet = 80 + SFlowCSISO88596E SFlowCharSet = 81 + SFlowCSISO88596I SFlowCharSet = 82 + SFlowCSISO128T101G2 SFlowCharSet = 83 + SFlowCSISO88598E SFlowCharSet = 84 + SFlowCSISO88598I SFlowCharSet = 85 + SFlowCSISO139CSN369103 SFlowCharSet = 86 + SFlowCSISO141JUSIB1002 SFlowCharSet = 87 + SFlowCSISO143IECP271 SFlowCharSet = 88 + SFlowCSISO146Serbian SFlowCharSet = 89 + SFlowCSISO147Macedonian SFlowCharSet = 90 + SFlowCSISO150 SFlowCharSet = 91 + SFlowCSISO151Cuba SFlowCharSet = 92 + SFlowCSISO6937Add SFlowCharSet = 93 + SFlowCSISO153GOST1976874 SFlowCharSet = 94 + SFlowCSISO8859Supp SFlowCharSet = 95 + SFlowCSISO10367Box SFlowCharSet = 96 + SFlowCSISO158Lap SFlowCharSet = 97 + SFlowCSISO159JISX02121990 SFlowCharSet = 98 + SFlowCSISO646Danish SFlowCharSet = 99 + SFlowCSUSDK SFlowCharSet = 100 + SFlowCSDKUS SFlowCharSet = 101 + SFlowCSKSC5636 SFlowCharSet = 102 + SFlowCSUnicode11UTF7 SFlowCharSet = 103 + SFlowCSISO2022CN SFlowCharSet = 104 + SFlowCSISO2022CNEXT SFlowCharSet = 105 + SFlowCSUTF8 SFlowCharSet = 106 + SFlowCSISO885913 SFlowCharSet = 109 + SFlowCSISO885914 SFlowCharSet = 110 + SFlowCSISO885915 SFlowCharSet = 111 + SFlowCSISO885916 SFlowCharSet = 112 + SFlowCSGBK SFlowCharSet = 113 + SFlowCSGB18030 SFlowCharSet = 114 + SFlowCSOSDEBCDICDF0415 SFlowCharSet = 115 + SFlowCSOSDEBCDICDF03IRV SFlowCharSet = 116 + SFlowCSOSDEBCDICDF041 SFlowCharSet = 117 + SFlowCSISO115481 SFlowCharSet = 118 + SFlowCSKZ1048 SFlowCharSet = 119 + SFlowCSUnicode SFlowCharSet = 1000 + SFlowCSUCS4 SFlowCharSet = 1001 + SFlowCSUnicodeASCII SFlowCharSet = 1002 + SFlowCSUnicodeLatin1 SFlowCharSet = 1003 + SFlowCSUnicodeJapanese SFlowCharSet = 1004 + SFlowCSUnicodeIBM1261 SFlowCharSet = 1005 + SFlowCSUnicodeIBM1268 SFlowCharSet = 1006 + SFlowCSUnicodeIBM1276 SFlowCharSet = 1007 + SFlowCSUnicodeIBM1264 SFlowCharSet = 1008 + SFlowCSUnicodeIBM1265 SFlowCharSet = 1009 + SFlowCSUnicode11 SFlowCharSet = 1010 + SFlowCSSCSU SFlowCharSet = 1011 + SFlowCSUTF7 SFlowCharSet = 1012 + SFlowCSUTF16BE SFlowCharSet = 1013 + SFlowCSUTF16LE SFlowCharSet = 1014 + SFlowCSUTF16 SFlowCharSet = 1015 + SFlowCSCESU8 SFlowCharSet = 1016 + SFlowCSUTF32 SFlowCharSet = 1017 + SFlowCSUTF32BE SFlowCharSet = 1018 + SFlowCSUTF32LE SFlowCharSet = 1019 + SFlowCSBOCU1 SFlowCharSet = 1020 + SFlowCSWindows30Latin1 SFlowCharSet = 2000 + SFlowCSWindows31Latin1 SFlowCharSet = 2001 + SFlowCSWindows31Latin2 SFlowCharSet = 2002 + SFlowCSWindows31Latin5 SFlowCharSet = 2003 + SFlowCSHPRoman8 SFlowCharSet = 2004 + SFlowCSAdobeStandardEncoding SFlowCharSet = 2005 + SFlowCSVenturaUS SFlowCharSet = 2006 + SFlowCSVenturaInternational SFlowCharSet = 2007 + SFlowCSDECMCS SFlowCharSet = 2008 + SFlowCSPC850Multilingual SFlowCharSet = 2009 + SFlowCSPCp852 SFlowCharSet = 2010 + SFlowCSPC8CodePage437 SFlowCharSet = 2011 + SFlowCSPC8DanishNorwegian SFlowCharSet = 2012 + SFlowCSPC862LatinHebrew SFlowCharSet = 2013 + SFlowCSPC8Turkish SFlowCharSet = 2014 + SFlowCSIBMSymbols SFlowCharSet = 2015 + SFlowCSIBMThai SFlowCharSet = 2016 + SFlowCSHPLegal SFlowCharSet = 2017 + SFlowCSHPPiFont SFlowCharSet = 2018 + SFlowCSHPMath8 SFlowCharSet = 2019 + SFlowCSHPPSMath SFlowCharSet = 2020 + SFlowCSHPDesktop SFlowCharSet = 2021 + SFlowCSVenturaMath SFlowCharSet = 2022 + SFlowCSMicrosoftPublishing SFlowCharSet = 2023 + SFlowCSWindows31J SFlowCharSet = 2024 + SFlowCSGB2312 SFlowCharSet = 2025 + SFlowCSBig5 SFlowCharSet = 2026 + SFlowCSMacintosh SFlowCharSet = 2027 + SFlowCSIBM037 SFlowCharSet = 2028 + SFlowCSIBM038 SFlowCharSet = 2029 + SFlowCSIBM273 SFlowCharSet = 2030 + SFlowCSIBM274 SFlowCharSet = 2031 + SFlowCSIBM275 SFlowCharSet = 2032 + SFlowCSIBM277 SFlowCharSet = 2033 + SFlowCSIBM278 SFlowCharSet = 2034 + SFlowCSIBM280 SFlowCharSet = 2035 + SFlowCSIBM281 SFlowCharSet = 2036 + SFlowCSIBM284 SFlowCharSet = 2037 + SFlowCSIBM285 SFlowCharSet = 2038 + SFlowCSIBM290 SFlowCharSet = 2039 + SFlowCSIBM297 SFlowCharSet = 2040 + SFlowCSIBM420 SFlowCharSet = 2041 + SFlowCSIBM423 SFlowCharSet = 2042 + SFlowCSIBM424 SFlowCharSet = 2043 + SFlowCSIBM500 SFlowCharSet = 2044 + SFlowCSIBM851 SFlowCharSet = 2045 + SFlowCSIBM855 SFlowCharSet = 2046 + SFlowCSIBM857 SFlowCharSet = 2047 + SFlowCSIBM860 SFlowCharSet = 2048 + SFlowCSIBM861 SFlowCharSet = 2049 + SFlowCSIBM863 SFlowCharSet = 2050 + SFlowCSIBM864 SFlowCharSet = 2051 + SFlowCSIBM865 SFlowCharSet = 2052 + SFlowCSIBM868 SFlowCharSet = 2053 + SFlowCSIBM869 SFlowCharSet = 2054 + SFlowCSIBM870 SFlowCharSet = 2055 + SFlowCSIBM871 SFlowCharSet = 2056 + SFlowCSIBM880 SFlowCharSet = 2057 + SFlowCSIBM891 SFlowCharSet = 2058 + SFlowCSIBM903 SFlowCharSet = 2059 + SFlowCSIBBM904 SFlowCharSet = 2060 + SFlowCSIBM905 SFlowCharSet = 2061 + SFlowCSIBM918 SFlowCharSet = 2062 + SFlowCSIBM1026 SFlowCharSet = 2063 + SFlowCSIBMEBCDICATDE SFlowCharSet = 2064 + SFlowCSEBCDICATDEA SFlowCharSet = 2065 + SFlowCSEBCDICCAFR SFlowCharSet = 2066 + SFlowCSEBCDICDKNO SFlowCharSet = 2067 + SFlowCSEBCDICDKNOA SFlowCharSet = 2068 + SFlowCSEBCDICFISE SFlowCharSet = 2069 + SFlowCSEBCDICFISEA SFlowCharSet = 2070 + SFlowCSEBCDICFR SFlowCharSet = 2071 + SFlowCSEBCDICIT SFlowCharSet = 2072 + SFlowCSEBCDICPT SFlowCharSet = 2073 + SFlowCSEBCDICES SFlowCharSet = 2074 + SFlowCSEBCDICESA SFlowCharSet = 2075 + SFlowCSEBCDICESS SFlowCharSet = 2076 + SFlowCSEBCDICUK SFlowCharSet = 2077 + SFlowCSEBCDICUS SFlowCharSet = 2078 + SFlowCSUnknown8BiT SFlowCharSet = 2079 + SFlowCSMnemonic SFlowCharSet = 2080 + SFlowCSMnem SFlowCharSet = 2081 + SFlowCSVISCII SFlowCharSet = 2082 + SFlowCSVIQR SFlowCharSet = 2083 + SFlowCSKOI8R SFlowCharSet = 2084 + SFlowCSHZGB2312 SFlowCharSet = 2085 + SFlowCSIBM866 SFlowCharSet = 2086 + SFlowCSPC775Baltic SFlowCharSet = 2087 + SFlowCSKOI8U SFlowCharSet = 2088 + SFlowCSIBM00858 SFlowCharSet = 2089 + SFlowCSIBM00924 SFlowCharSet = 2090 + SFlowCSIBM01140 SFlowCharSet = 2091 + SFlowCSIBM01141 SFlowCharSet = 2092 + SFlowCSIBM01142 SFlowCharSet = 2093 + SFlowCSIBM01143 SFlowCharSet = 2094 + SFlowCSIBM01144 SFlowCharSet = 2095 + SFlowCSIBM01145 SFlowCharSet = 2096 + SFlowCSIBM01146 SFlowCharSet = 2097 + SFlowCSIBM01147 SFlowCharSet = 2098 + SFlowCSIBM01148 SFlowCharSet = 2099 + SFlowCSIBM01149 SFlowCharSet = 2100 + SFlowCSBig5HKSCS SFlowCharSet = 2101 + SFlowCSIBM1047 SFlowCharSet = 2102 + SFlowCSPTCP154 SFlowCharSet = 2103 + SFlowCSAmiga1251 SFlowCharSet = 2104 + SFlowCSKOI7switched SFlowCharSet = 2105 + SFlowCSBRF SFlowCharSet = 2106 + SFlowCSTSCII SFlowCharSet = 2107 + SFlowCSCP51932 SFlowCharSet = 2108 + SFlowCSWindows874 SFlowCharSet = 2109 + SFlowCSWindows1250 SFlowCharSet = 2250 + SFlowCSWindows1251 SFlowCharSet = 2251 + SFlowCSWindows1252 SFlowCharSet = 2252 + SFlowCSWindows1253 SFlowCharSet = 2253 + SFlowCSWindows1254 SFlowCharSet = 2254 + SFlowCSWindows1255 SFlowCharSet = 2255 + SFlowCSWindows1256 SFlowCharSet = 2256 + SFlowCSWindows1257 SFlowCharSet = 2257 + SFlowCSWindows1258 SFlowCharSet = 2258 + SFlowCSTIS620 SFlowCharSet = 2259 + SFlowCS50220 SFlowCharSet = 2260 + SFlowCSreserved SFlowCharSet = 3000 +) + +func decodeExtendedUserFlow(data *[]byte) (SFlowExtendedUserFlow, error) { + eu := SFlowExtendedUserFlow{} + var fdf SFlowFlowDataFormat + var srcUserLen uint32 + var srcUserLenWithPad int + var srcUserBytes []byte + var dstUserLen uint32 + var dstUserLenWithPad int + var dstUserBytes []byte + + *data, fdf = (*data)[4:], SFlowFlowDataFormat(binary.BigEndian.Uint32((*data)[:4])) + eu.EnterpriseID, eu.Format = fdf.decode() + *data, eu.FlowDataLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, eu.SourceCharSet = (*data)[4:], SFlowCharSet(binary.BigEndian.Uint32((*data)[:4])) + *data, srcUserLen = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + srcUserLenWithPad = int(srcUserLen + ((4 - srcUserLen) % 4)) + *data, srcUserBytes = (*data)[srcUserLenWithPad:], (*data)[:srcUserLenWithPad] + eu.SourceUserID = string(srcUserBytes[:srcUserLen]) + *data, eu.DestinationCharSet = (*data)[4:], SFlowCharSet(binary.BigEndian.Uint32((*data)[:4])) + *data, dstUserLen = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + dstUserLenWithPad = int(dstUserLen + ((4 - dstUserLen) % 4)) + *data, dstUserBytes = (*data)[dstUserLenWithPad:], (*data)[:dstUserLenWithPad] + eu.DestinationUserID = string(dstUserBytes[:dstUserLen]) + return eu, nil +} + +// ************************************************** +// Counter Record +// ************************************************** + +// 0 15 31 +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | 20 bit Interprise (0) |12 bit format | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | counter length | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// / counter data / +// / / +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + +type SFlowBaseCounterRecord struct { + EnterpriseID SFlowEnterpriseID + Format SFlowCounterRecordType + FlowDataLength uint32 +} + +func (bcr SFlowBaseCounterRecord) GetType() SFlowCounterRecordType { + switch bcr.Format { + case SFlowTypeGenericInterfaceCounters: + return SFlowTypeGenericInterfaceCounters + case SFlowTypeEthernetInterfaceCounters: + return SFlowTypeEthernetInterfaceCounters + case SFlowTypeTokenRingInterfaceCounters: + return SFlowTypeTokenRingInterfaceCounters + case SFlowType100BaseVGInterfaceCounters: + return SFlowType100BaseVGInterfaceCounters + case SFlowTypeVLANCounters: + return SFlowTypeVLANCounters + case SFlowTypeProcessorCounters: + return SFlowTypeProcessorCounters + + } + unrecognized := fmt.Sprint("Unrecognized counter record type:", bcr.Format) + panic(unrecognized) +} + +// ************************************************** +// Counter Record +// ************************************************** + +// 0 15 31 +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | 20 bit Interprise (0) |12 bit format | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | counter length | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | IfIndex | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | IfType | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | IfSpeed | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | IfDirection | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | IfStatus | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | IFInOctets | +// | | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | IfInUcastPkts | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | IfInMulticastPkts | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | IfInBroadcastPkts | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | IfInDiscards | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | InInErrors | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | IfInUnknownProtos | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | IfOutOctets | +// | | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | IfOutUcastPkts | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | IfOutMulticastPkts | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | IfOutBroadcastPkts | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | IfOutDiscards | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | IfOUtErrors | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | IfPromiscouousMode | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + +type SFlowGenericInterfaceCounters struct { + SFlowBaseCounterRecord + IfIndex uint32 + IfType uint32 + IfSpeed uint64 + IfDirection uint32 + IfStatus uint32 + IfInOctets uint64 + IfInUcastPkts uint32 + IfInMulticastPkts uint32 + IfInBroadcastPkts uint32 + IfInDiscards uint32 + IfInErrors uint32 + IfInUnknownProtos uint32 + IfOutOctets uint64 + IfOutUcastPkts uint32 + IfOutMulticastPkts uint32 + IfOutBroadcastPkts uint32 + IfOutDiscards uint32 + IfOutErrors uint32 + IfPromiscuousMode uint32 +} + +func decodeGenericInterfaceCounters(data *[]byte) (SFlowGenericInterfaceCounters, error) { + gic := SFlowGenericInterfaceCounters{} + var cdf SFlowCounterDataFormat + + *data, cdf = (*data)[4:], SFlowCounterDataFormat(binary.BigEndian.Uint32((*data)[:4])) + gic.EnterpriseID, gic.Format = cdf.decode() + *data, gic.FlowDataLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, gic.IfIndex = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, gic.IfType = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, gic.IfSpeed = (*data)[8:], binary.BigEndian.Uint64((*data)[:8]) + *data, gic.IfDirection = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, gic.IfStatus = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, gic.IfInOctets = (*data)[8:], binary.BigEndian.Uint64((*data)[:8]) + *data, gic.IfInUcastPkts = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, gic.IfInMulticastPkts = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, gic.IfInBroadcastPkts = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, gic.IfInDiscards = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, gic.IfInErrors = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, gic.IfInUnknownProtos = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, gic.IfOutOctets = (*data)[8:], binary.BigEndian.Uint64((*data)[:8]) + *data, gic.IfOutUcastPkts = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, gic.IfOutMulticastPkts = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, gic.IfOutBroadcastPkts = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, gic.IfOutDiscards = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, gic.IfOutErrors = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, gic.IfPromiscuousMode = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + return gic, nil +} + +// ************************************************** +// Counter Record +// ************************************************** + +// 0 15 31 +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | 20 bit Interprise (0) |12 bit format | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// | counter length | +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +// / counter data / +// / / +// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + +type SFlowEthernetCounters struct { + SFlowBaseCounterRecord + AlignmentErrors uint32 + FCSErrors uint32 + SingleCollisionFrames uint32 + MultipleCollisionFrames uint32 + SQETestErrors uint32 + DeferredTransmissions uint32 + LateCollisions uint32 + ExcessiveCollisions uint32 + InternalMacTransmitErrors uint32 + CarrierSenseErrors uint32 + FrameTooLongs uint32 + InternalMacReceiveErrors uint32 + SymbolErrors uint32 +} + +func decodeEthernetCounters(data *[]byte) (SFlowEthernetCounters, error) { + ec := SFlowEthernetCounters{} + var cdf SFlowCounterDataFormat + + *data, cdf = (*data)[4:], SFlowCounterDataFormat(binary.BigEndian.Uint32((*data)[:4])) + ec.EnterpriseID, ec.Format = cdf.decode() + *data, ec.FlowDataLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, ec.AlignmentErrors = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, ec.FCSErrors = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, ec.SingleCollisionFrames = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, ec.MultipleCollisionFrames = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, ec.SQETestErrors = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, ec.DeferredTransmissions = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, ec.LateCollisions = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, ec.ExcessiveCollisions = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, ec.InternalMacTransmitErrors = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, ec.CarrierSenseErrors = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, ec.FrameTooLongs = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, ec.InternalMacReceiveErrors = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + *data, ec.SymbolErrors = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) + return ec, nil +} diff --git a/vendor/github.com/google/gopacket/layers/tcp.go b/vendor/github.com/google/gopacket/layers/tcp.go new file mode 100644 index 0000000..5f0fda1 --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/tcp.go @@ -0,0 +1,232 @@ +// 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" +) + +// 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 +} + +type TCPOption struct { + OptionType uint8 + OptionLength uint8 + OptionData []byte +} + +func (t TCPOption) String() string { + switch t.OptionType { + case 1: + return "NOP" + case 8: + if len(t.OptionData) == 8 { + return fmt.Sprintf("TSOPT:%v/%v", + binary.BigEndian.Uint32(t.OptionData[:4]), + binary.BigEndian.Uint32(t.OptionData[4:8])) + } + } + return fmt.Sprintf("TCPOption(%v:%v)", t.OptionType, t.OptionData) +} + +// 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 { + t.Padding = lotsOfZeros[:optionLength%4] + 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] = 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 += int(o.OptionLength) + } + } + 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) 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 { + 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]) + tcp.Options = tcp.opts[: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 { + if tcp.Options == nil { + // Pre-allocate to avoid allocating a slice. + tcp.Options = tcp.opts[:0] + } + tcp.Options = append(tcp.Options, TCPOption{OptionType: data[0]}) + opt := &tcp.Options[len(tcp.Options)-1] + switch opt.OptionType { + case 0: // End of options + opt.OptionLength = 1 + tcp.Padding = data[1:] + break + case 1: // 1 byte padding + opt.OptionLength = 1 + default: + 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) { + 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 { + return gopacket.LayerTypePayload +} + +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 + } + return p.NextDecoder(gopacket.LayerTypePayload) +} + +func (t *TCP) TransportFlow() gopacket.Flow { + return gopacket.NewFlow(EndpointTCPPort, t.sPort, t.dPort) +} diff --git a/vendor/github.com/google/gopacket/layers/tcpip.go b/vendor/github.com/google/gopacket/layers/tcpip.go new file mode 100644 index 0000000..b5185d2 --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/tcpip.go @@ -0,0 +1,102 @@ +// Copyright 2012 Google, Inc. All rights reserved. +// Copyright 2009-2011 Andreas Krennmair. All rights reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. + +package layers + +import ( + "fmt" + "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 + (csum >> 16)) +} + +// 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, fmt.Errorf("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 +} diff --git a/vendor/github.com/google/gopacket/layers/test_creator.py b/vendor/github.com/google/gopacket/layers/test_creator.py new file mode 100644 index 0000000..c92d276 --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/test_creator.py @@ -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() diff --git a/vendor/github.com/google/gopacket/layers/udp.go b/vendor/github.com/google/gopacket/layers/udp.go new file mode 100644 index 0000000..20f8c50 --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/udp.go @@ -0,0 +1,120 @@ +// 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 { + 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) +} diff --git a/vendor/github.com/google/gopacket/layers/udplite.go b/vendor/github.com/google/gopacket/layers/udplite.go new file mode 100644 index 0000000..7d84c51 --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/udplite.go @@ -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) +} diff --git a/vendor/github.com/google/gopacket/layers/usb.go b/vendor/github.com/google/gopacket/layers/usb.go new file mode 100644 index 0000000..d4f483c --- /dev/null +++ b/vendor/github.com/google/gopacket/layers/usb.go @@ -0,0 +1,308 @@ +// 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. +) + +func (a USBTransportType) LayerType() gopacket.LayerType { + return USBTypeMetadata[a].LayerType +} + +func (a USBTransportType) String() string { + switch a { + case USBTransportTypeTransferIn: + return "Transfer In" + case USBTransportTypeIsochronous: + return "Isochronous" + case USBTransportTypeInterrupt: + return "Interrupt" + case USBTransportTypeControl: + return "Control" + case USBTransportTypeBulk: + return "Bulk" + default: + return "Unknown transport type" + } +} + +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) +} diff --git a/vendor/github.com/google/gopacket/layertype.go b/vendor/github.com/google/gopacket/layertype.go new file mode 100644 index 0000000..31810c3 --- /dev/null +++ b/vendor/github.com/google/gopacket/layertype.go @@ -0,0 +1,101 @@ +// 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") + } + ltMeta[num] = layerTypeMetadata{ + inUse: true, + LayerTypeMetadata: meta, + } + } else { + if ltMetaMap[LayerType(num)].inUse { + panic("Layer type already exists") + } + 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 +} diff --git a/vendor/github.com/google/gopacket/macs/doc.go b/vendor/github.com/google/gopacket/macs/doc.go new file mode 100644 index 0000000..c0d32a8 --- /dev/null +++ b/vendor/github.com/google/gopacket/macs/doc.go @@ -0,0 +1,12 @@ +// 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 macs provides an in-memory mapping of all valid Ethernet MAC address +// prefixes to their associated organization. +// +// The ValidMACPrefixMap map maps 3-byte prefixes to organization strings. It +// can be updated using 'go run gen.go' in this directory. +package macs diff --git a/vendor/github.com/google/gopacket/macs/gen.go b/vendor/github.com/google/gopacket/macs/gen.go new file mode 100644 index 0000000..97776e0 --- /dev/null +++ b/vendor/github.com/google/gopacket/macs/gen.go @@ -0,0 +1,78 @@ +// 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 the list of known MAC +// prefixes from IEEE and writes them out to a go file which is compiled +// into gopacket. It should be run as follows: +// +// go run gen.go | gofmt > valid_mac_prefixes.go +package main + +import ( + "bufio" + "encoding/hex" + "flag" + "fmt" + "io" + "net/http" + "os" + "regexp" + "time" +) + +const header = `// 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 macs + +// Created by gen.go, don't edit manually +// Generated at %s +// Fetched from %q + +// ValidMACPrefixMap maps a valid MAC address prefix to the name of the +// organization that owns the rights to use it. We map it to a hidden +// variable so it won't show up in godoc, since it's a very large map. +var ValidMACPrefixMap map[[3]byte]string= validMACPrefixMap +var validMACPrefixMap = map[[3]byte]string{ +` + +var url = flag.String("url", "http://standards.ieee.org/develop/regauth/oui/oui.txt", "URL to fetch MACs from") + +func main() { + fmt.Fprintf(os.Stderr, "Fetching MACs from %q\n", *url) + resp, err := http.Get(*url) + if err != nil { + panic(err) + } + defer resp.Body.Close() + buffered := bufio.NewReader(resp.Body) + finder := regexp.MustCompile(`^\s*([0-9A-F]{6})\s+\(base 16\)\s+(.*)`) + fmt.Fprintln(os.Stderr, "Starting write to standard output") + fmt.Printf(header, time.Now(), *url) + for { + line, err := buffered.ReadString('\n') + if err == io.EOF { + break + } else if err != nil { + panic(err) + } + if matches := finder.FindStringSubmatch(line); matches != nil { + bytes := make([]byte, 3) + hex.Decode(bytes, []byte(matches[1])) + company := matches[2] + if company == "" { + company = "PRIVATE" + } + fmt.Printf("\t[3]byte{%d, %d, %d}: %q,\n", bytes[0], bytes[1], bytes[2], company) + } + } + fmt.Println("}") +} diff --git a/vendor/github.com/google/gopacket/macs/valid_mac_prefixes.go b/vendor/github.com/google/gopacket/macs/valid_mac_prefixes.go new file mode 100644 index 0000000..4afee40 --- /dev/null +++ b/vendor/github.com/google/gopacket/macs/valid_mac_prefixes.go @@ -0,0 +1,19791 @@ +// 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 macs + +// Created by gen.go, don't edit manually +// Generated at 2014-09-09 10:01:58.097553511 -0600 MDT +// Fetched from "http://standards.ieee.org/develop/regauth/oui/oui.txt" + +// ValidMACPrefixMap maps a valid MAC address prefix to the name of the +// organization that owns the rights to use it. We map it to a hidden +// variable so it won't show up in godoc, since it's a very large map. +var ValidMACPrefixMap map[[3]byte]string = validMACPrefixMap +var validMACPrefixMap = map[[3]byte]string{ + [3]byte{0, 0, 0}: "XEROX CORPORATION", + [3]byte{0, 0, 1}: "XEROX CORPORATION", + [3]byte{0, 0, 2}: "XEROX CORPORATION", + [3]byte{0, 0, 3}: "XEROX CORPORATION", + [3]byte{0, 0, 4}: "XEROX CORPORATION", + [3]byte{0, 0, 5}: "XEROX CORPORATION", + [3]byte{0, 0, 6}: "XEROX CORPORATION", + [3]byte{0, 0, 7}: "XEROX CORPORATION", + [3]byte{0, 0, 8}: "XEROX CORPORATION", + [3]byte{0, 0, 9}: "XEROX CORPORATION", + [3]byte{0, 0, 10}: "OMRON TATEISI ELECTRONICS CO.", + [3]byte{0, 0, 11}: "MATRIX CORPORATION", + [3]byte{0, 0, 12}: "CISCO SYSTEMS, INC.", + [3]byte{0, 0, 13}: "FIBRONICS LTD.", + [3]byte{0, 0, 14}: "FUJITSU LIMITED", + [3]byte{0, 0, 15}: "NEXT, INC.", + [3]byte{0, 0, 16}: "SYTEK INC.", + [3]byte{0, 0, 17}: "NORMEREL SYSTEMES", + [3]byte{0, 0, 18}: "INFORMATION TECHNOLOGY LIMITED", + [3]byte{0, 0, 19}: "CAMEX", + [3]byte{0, 0, 20}: "NETRONIX", + [3]byte{0, 0, 21}: "DATAPOINT CORPORATION", + [3]byte{0, 0, 22}: "DU PONT PIXEL SYSTEMS .", + [3]byte{0, 0, 23}: "Oracle", + [3]byte{0, 0, 24}: "WEBSTER COMPUTER CORPORATION", + [3]byte{0, 0, 25}: "APPLIED DYNAMICS INTERNATIONAL", + [3]byte{0, 0, 26}: "ADVANCED MICRO DEVICES", + [3]byte{0, 0, 27}: "NOVELL INC.", + [3]byte{0, 0, 28}: "BELL TECHNOLOGIES", + [3]byte{0, 0, 29}: "CABLETRON SYSTEMS, INC.", + [3]byte{0, 0, 30}: "TELSIST INDUSTRIA ELECTRONICA", + [3]byte{0, 0, 31}: "Telco Systems, Inc.", + [3]byte{0, 0, 32}: "DATAINDUSTRIER DIAB AB", + [3]byte{0, 0, 33}: "SUREMAN COMP. & COMMUN. CORP.", + [3]byte{0, 0, 34}: "VISUAL TECHNOLOGY INC.", + [3]byte{0, 0, 35}: "ABB INDUSTRIAL SYSTEMS AB", + [3]byte{0, 0, 36}: "CONNECT AS", + [3]byte{0, 0, 37}: "RAMTEK CORP.", + [3]byte{0, 0, 38}: "SHA-KEN CO., LTD.", + [3]byte{0, 0, 39}: "JAPAN RADIO COMPANY", + [3]byte{0, 0, 40}: "PRODIGY SYSTEMS CORPORATION", + [3]byte{0, 0, 41}: "IMC NETWORKS CORP.", + [3]byte{0, 0, 42}: "TRW - SEDD/INP", + [3]byte{0, 0, 43}: "CRISP AUTOMATION, INC", + [3]byte{0, 0, 44}: "AUTOTOTE LIMITED", + [3]byte{0, 0, 45}: "CHROMATICS INC", + [3]byte{0, 0, 46}: "SOCIETE EVIRA", + [3]byte{0, 0, 47}: "TIMEPLEX INC.", + [3]byte{0, 0, 48}: "VG LABORATORY SYSTEMS LTD", + [3]byte{0, 0, 49}: "QPSX COMMUNICATIONS PTY LTD", + [3]byte{0, 0, 50}: "Marconi plc", + [3]byte{0, 0, 51}: "EGAN MACHINERY COMPANY", + [3]byte{0, 0, 52}: "NETWORK RESOURCES CORPORATION", + [3]byte{0, 0, 53}: "SPECTRAGRAPHICS CORPORATION", + [3]byte{0, 0, 54}: "ATARI CORPORATION", + [3]byte{0, 0, 55}: "OXFORD METRICS LIMITED", + [3]byte{0, 0, 56}: "CSS LABS", + [3]byte{0, 0, 57}: "TOSHIBA CORPORATION", + [3]byte{0, 0, 58}: "CHYRON CORPORATION", + [3]byte{0, 0, 59}: "i Controls, Inc.", + [3]byte{0, 0, 60}: "AUSPEX SYSTEMS INC.", + [3]byte{0, 0, 61}: "UNISYS", + [3]byte{0, 0, 62}: "SIMPACT", + [3]byte{0, 0, 63}: "SYNTREX, INC.", + [3]byte{0, 0, 64}: "APPLICON, INC.", + [3]byte{0, 0, 65}: "ICE CORPORATION", + [3]byte{0, 0, 66}: "METIER MANAGEMENT SYSTEMS LTD.", + [3]byte{0, 0, 67}: "MICRO TECHNOLOGY", + [3]byte{0, 0, 68}: "CASTELLE CORPORATION", + [3]byte{0, 0, 69}: "FORD AEROSPACE & COMM. CORP.", + [3]byte{0, 0, 70}: "OLIVETTI NORTH AMERICA", + [3]byte{0, 0, 71}: "NICOLET INSTRUMENTS CORP.", + [3]byte{0, 0, 72}: "SEIKO EPSON CORPORATION", + [3]byte{0, 0, 73}: "APRICOT COMPUTERS, LTD", + [3]byte{0, 0, 74}: "ADC CODENOLL TECHNOLOGY CORP.", + [3]byte{0, 0, 75}: "ICL DATA OY", + [3]byte{0, 0, 76}: "NEC CORPORATION", + [3]byte{0, 0, 77}: "DCI CORPORATION", + [3]byte{0, 0, 78}: "AMPEX CORPORATION", + [3]byte{0, 0, 79}: "LOGICRAFT, INC.", + [3]byte{0, 0, 80}: "RADISYS CORPORATION", + [3]byte{0, 0, 81}: "HOB ELECTRONIC GMBH & CO. KG", + [3]byte{0, 0, 82}: "Intrusion.com, Inc.", + [3]byte{0, 0, 83}: "COMPUCORP", + [3]byte{0, 0, 84}: "Schnieder Electric", + [3]byte{0, 0, 85}: "COMMISSARIAT A L`ENERGIE ATOM.", + [3]byte{0, 0, 86}: "DR. B. STRUCK", + [3]byte{0, 0, 87}: "SCITEX CORPORATION LTD.", + [3]byte{0, 0, 88}: "RACORE COMPUTER PRODUCTS INC.", + [3]byte{0, 0, 89}: "HELLIGE GMBH", + [3]byte{0, 0, 90}: "SysKonnect GmbH", + [3]byte{0, 0, 91}: "ELTEC ELEKTRONIK AG", + [3]byte{0, 0, 92}: "TELEMATICS INTERNATIONAL INC.", + [3]byte{0, 0, 93}: "CS TELECOM", + [3]byte{0, 0, 94}: "ICANN, IANA Department", + [3]byte{0, 0, 95}: "SUMITOMO ELECTRIC IND., LTD.", + [3]byte{0, 0, 96}: "KONTRON ELEKTRONIK GMBH", + [3]byte{0, 0, 97}: "GATEWAY COMMUNICATIONS", + [3]byte{0, 0, 98}: "BULL HN INFORMATION SYSTEMS", + [3]byte{0, 0, 99}: "BARCO CONTROL ROOMS GMBH", + [3]byte{0, 0, 100}: "Yokogawa Electric Corporation", + [3]byte{0, 0, 101}: "Network General Corporation", + [3]byte{0, 0, 102}: "TALARIS SYSTEMS, INC.", + [3]byte{0, 0, 103}: "SOFT * RITE, INC.", + [3]byte{0, 0, 104}: "ROSEMOUNT CONTROLS", + [3]byte{0, 0, 105}: "CONCORD COMMUNICATIONS INC", + [3]byte{0, 0, 106}: "COMPUTER CONSOLES INC.", + [3]byte{0, 0, 107}: "SILICON GRAPHICS INC./MIPS", + [3]byte{0, 0, 108}: "PRIVATE", + [3]byte{0, 0, 109}: "CRAY COMMUNICATIONS, LTD.", + [3]byte{0, 0, 110}: "ARTISOFT, INC.", + [3]byte{0, 0, 111}: "Madge Ltd.", + [3]byte{0, 0, 112}: "HCL LIMITED", + [3]byte{0, 0, 113}: "ADRA SYSTEMS INC.", + [3]byte{0, 0, 114}: "MINIWARE TECHNOLOGY", + [3]byte{0, 0, 115}: "SIECOR CORPORATION", + [3]byte{0, 0, 116}: "RICOH COMPANY LTD.", + [3]byte{0, 0, 117}: "Nortel Networks", + [3]byte{0, 0, 118}: "ABEKAS VIDEO SYSTEM", + [3]byte{0, 0, 119}: "INTERPHASE CORPORATION", + [3]byte{0, 0, 120}: "LABTAM LIMITED", + [3]byte{0, 0, 121}: "NETWORTH INCORPORATED", + [3]byte{0, 0, 122}: "DANA COMPUTER INC.", + [3]byte{0, 0, 123}: "RESEARCH MACHINES", + [3]byte{0, 0, 124}: "AMPERE INCORPORATED", + [3]byte{0, 0, 125}: "Oracle Corporation", + [3]byte{0, 0, 126}: "CLUSTRIX CORPORATION", + [3]byte{0, 0, 127}: "LINOTYPE-HELL AG", + [3]byte{0, 0, 128}: "CRAY COMMUNICATIONS A/S", + [3]byte{0, 0, 129}: "BAY NETWORKS", + [3]byte{0, 0, 130}: "LECTRA SYSTEMES SA", + [3]byte{0, 0, 131}: "TADPOLE TECHNOLOGY PLC", + [3]byte{0, 0, 132}: "SUPERNET", + [3]byte{0, 0, 133}: "CANON INC.", + [3]byte{0, 0, 134}: "MEGAHERTZ CORPORATION", + [3]byte{0, 0, 135}: "HITACHI, LTD.", + [3]byte{0, 0, 136}: "Brocade Communications Systems, Inc.", + [3]byte{0, 0, 137}: "CAYMAN SYSTEMS INC.", + [3]byte{0, 0, 138}: "DATAHOUSE INFORMATION SYSTEMS", + [3]byte{0, 0, 139}: "INFOTRON", + [3]byte{0, 0, 140}: "Alloy Computer Products (Australia) Pty Ltd", + [3]byte{0, 0, 141}: "Cryptek Inc.", + [3]byte{0, 0, 142}: "SOLBOURNE COMPUTER, INC.", + [3]byte{0, 0, 143}: "Raytheon", + [3]byte{0, 0, 144}: "MICROCOM", + [3]byte{0, 0, 145}: "ANRITSU CORPORATION", + [3]byte{0, 0, 146}: "COGENT DATA TECHNOLOGIES", + [3]byte{0, 0, 147}: "PROTEON INC.", + [3]byte{0, 0, 148}: "ASANTE TECHNOLOGIES", + [3]byte{0, 0, 149}: "SONY TEKTRONIX CORP.", + [3]byte{0, 0, 150}: "MARCONI ELECTRONICS LTD.", + [3]byte{0, 0, 151}: "EMC Corporation", + [3]byte{0, 0, 152}: "CROSSCOMM CORPORATION", + [3]byte{0, 0, 153}: "MTX, INC.", + [3]byte{0, 0, 154}: "RC COMPUTER A/S", + [3]byte{0, 0, 155}: "INFORMATION INTERNATIONAL, INC", + [3]byte{0, 0, 156}: "ROLM MIL-SPEC COMPUTERS", + [3]byte{0, 0, 157}: "LOCUS COMPUTING CORPORATION", + [3]byte{0, 0, 158}: "MARLI S.A.", + [3]byte{0, 0, 159}: "AMERISTAR TECHNOLOGIES INC.", + [3]byte{0, 0, 160}: "SANYO Electric Co., Ltd.", + [3]byte{0, 0, 161}: "MARQUETTE ELECTRIC CO.", + [3]byte{0, 0, 162}: "BAY NETWORKS", + [3]byte{0, 0, 163}: "NETWORK APPLICATION TECHNOLOGY", + [3]byte{0, 0, 164}: "ACORN COMPUTERS LIMITED", + [3]byte{0, 0, 165}: "Tattile SRL", + [3]byte{0, 0, 166}: "NETWORK GENERAL CORPORATION", + [3]byte{0, 0, 167}: "NETWORK COMPUTING DEVICES INC.", + [3]byte{0, 0, 168}: "STRATUS COMPUTER INC.", + [3]byte{0, 0, 169}: "NETWORK SYSTEMS CORP.", + [3]byte{0, 0, 170}: "XEROX CORPORATION", + [3]byte{0, 0, 171}: "LOGIC MODELING CORPORATION", + [3]byte{0, 0, 172}: "CONWARE COMPUTER CONSULTING", + [3]byte{0, 0, 173}: "BRUKER INSTRUMENTS INC.", + [3]byte{0, 0, 174}: "DASSAULT ELECTRONIQUE", + [3]byte{0, 0, 175}: "NUCLEAR DATA INSTRUMENTATION", + [3]byte{0, 0, 176}: "RND-RAD NETWORK DEVICES", + [3]byte{0, 0, 177}: "ALPHA MICROSYSTEMS INC.", + [3]byte{0, 0, 178}: "TELEVIDEO SYSTEMS, INC.", + [3]byte{0, 0, 179}: "CIMLINC INCORPORATED", + [3]byte{0, 0, 180}: "EDIMAX COMPUTER COMPANY", + [3]byte{0, 0, 181}: "DATABILITY SOFTWARE SYS. INC.", + [3]byte{0, 0, 182}: "MICRO-MATIC RESEARCH", + [3]byte{0, 0, 183}: "DOVE COMPUTER CORPORATION", + [3]byte{0, 0, 184}: "SEIKOSHA CO., LTD.", + [3]byte{0, 0, 185}: "MCDONNELL DOUGLAS COMPUTER SYS", + [3]byte{0, 0, 186}: "SIIG, INC.", + [3]byte{0, 0, 187}: "TRI-DATA", + [3]byte{0, 0, 188}: "Rockwell Automation", + [3]byte{0, 0, 189}: "MITSUBISHI CABLE COMPANY", + [3]byte{0, 0, 190}: "THE NTI GROUP", + [3]byte{0, 0, 191}: "SYMMETRIC COMPUTER SYSTEMS", + [3]byte{0, 0, 192}: "WESTERN DIGITAL CORPORATION", + [3]byte{0, 0, 193}: "Madge Ltd.", + [3]byte{0, 0, 194}: "INFORMATION PRESENTATION TECH.", + [3]byte{0, 0, 195}: "HARRIS CORP COMPUTER SYS DIV", + [3]byte{0, 0, 196}: "WATERS DIV. OF MILLIPORE", + [3]byte{0, 0, 197}: "FARALLON COMPUTING/NETOPIA", + [3]byte{0, 0, 198}: "EON SYSTEMS", + [3]byte{0, 0, 199}: "ARIX CORPORATION", + [3]byte{0, 0, 200}: "ALTOS COMPUTER SYSTEMS", + [3]byte{0, 0, 201}: "Emulex Corporation", + [3]byte{0, 0, 202}: "ARRIS International", + [3]byte{0, 0, 203}: "COMPU-SHACK ELECTRONIC GMBH", + [3]byte{0, 0, 204}: "DENSAN CO., LTD.", + [3]byte{0, 0, 205}: "Allied Telesis Labs Ltd", + [3]byte{0, 0, 206}: "MEGADATA CORP.", + [3]byte{0, 0, 207}: "HAYES MICROCOMPUTER PRODUCTS", + [3]byte{0, 0, 208}: "DEVELCON ELECTRONICS LTD.", + [3]byte{0, 0, 209}: "ADAPTEC INCORPORATED", + [3]byte{0, 0, 210}: "SBE, INC.", + [3]byte{0, 0, 211}: "WANG LABORATORIES INC.", + [3]byte{0, 0, 212}: "PURE DATA LTD.", + [3]byte{0, 0, 213}: "MICROGNOSIS INTERNATIONAL", + [3]byte{0, 0, 214}: "PUNCH LINE HOLDING", + [3]byte{0, 0, 215}: "DARTMOUTH COLLEGE", + [3]byte{0, 0, 216}: "NOVELL, INC.", + [3]byte{0, 0, 217}: "NIPPON TELEGRAPH & TELEPHONE", + [3]byte{0, 0, 218}: "ATEX", + [3]byte{0, 0, 219}: "British Telecommunications plc", + [3]byte{0, 0, 220}: "HAYES MICROCOMPUTER PRODUCTS", + [3]byte{0, 0, 221}: "TCL INCORPORATED", + [3]byte{0, 0, 222}: "CETIA", + [3]byte{0, 0, 223}: "BELL & HOWELL PUB SYS DIV", + [3]byte{0, 0, 224}: "QUADRAM CORP.", + [3]byte{0, 0, 225}: "GRID SYSTEMS", + [3]byte{0, 0, 226}: "ACER TECHNOLOGIES CORP.", + [3]byte{0, 0, 227}: "INTEGRATED MICRO PRODUCTS LTD", + [3]byte{0, 0, 228}: "IN2 GROUPE INTERTECHNIQUE", + [3]byte{0, 0, 229}: "SIGMEX LTD.", + [3]byte{0, 0, 230}: "APTOR PRODUITS DE COMM INDUST", + [3]byte{0, 0, 231}: "STAR GATE TECHNOLOGIES", + [3]byte{0, 0, 232}: "ACCTON TECHNOLOGY CORP.", + [3]byte{0, 0, 233}: "ISICAD, INC.", + [3]byte{0, 0, 234}: "UPNOD AB", + [3]byte{0, 0, 235}: "MATSUSHITA COMM. IND. CO. LTD.", + [3]byte{0, 0, 236}: "MICROPROCESS", + [3]byte{0, 0, 237}: "APRIL", + [3]byte{0, 0, 238}: "NETWORK DESIGNERS, LTD.", + [3]byte{0, 0, 239}: "KTI", + [3]byte{0, 0, 240}: "SAMSUNG ELECTRONICS CO., LTD.", + [3]byte{0, 0, 241}: "MAGNA COMPUTER CORPORATION", + [3]byte{0, 0, 242}: "SPIDER COMMUNICATIONS", + [3]byte{0, 0, 243}: "GANDALF DATA LIMITED", + [3]byte{0, 0, 244}: "Allied Telesis", + [3]byte{0, 0, 245}: "DIAMOND SALES LIMITED", + [3]byte{0, 0, 246}: "APPLIED MICROSYSTEMS CORP.", + [3]byte{0, 0, 247}: "YOUTH KEEP ENTERPRISE CO LTD", + [3]byte{0, 0, 248}: "DIGITAL EQUIPMENT CORPORATION", + [3]byte{0, 0, 249}: "QUOTRON SYSTEMS INC.", + [3]byte{0, 0, 250}: "MICROSAGE COMPUTER SYSTEMS INC", + [3]byte{0, 0, 251}: "RECHNER ZUR KOMMUNIKATION", + [3]byte{0, 0, 252}: "MEIKO", + [3]byte{0, 0, 253}: "HIGH LEVEL HARDWARE", + [3]byte{0, 0, 254}: "ANNAPOLIS MICRO SYSTEMS", + [3]byte{0, 0, 255}: "CAMTEC ELECTRONICS LTD.", + [3]byte{0, 1, 0}: "EQUIP'TRANS", + [3]byte{0, 1, 1}: "PRIVATE", + [3]byte{0, 1, 2}: "3COM CORPORATION", + [3]byte{0, 1, 3}: "3COM CORPORATION", + [3]byte{0, 1, 4}: "DVICO Co., Ltd.", + [3]byte{0, 1, 5}: "Beckhoff Automation GmbH", + [3]byte{0, 1, 6}: "Tews Datentechnik GmbH", + [3]byte{0, 1, 7}: "Leiser GmbH", + [3]byte{0, 1, 8}: "AVLAB Technology, Inc.", + [3]byte{0, 1, 9}: "Nagano Japan Radio Co., Ltd.", + [3]byte{0, 1, 10}: "CIS TECHNOLOGY INC.", + [3]byte{0, 1, 11}: "Space CyberLink, Inc.", + [3]byte{0, 1, 12}: "System Talks Inc.", + [3]byte{0, 1, 13}: "CORECO, INC.", + [3]byte{0, 1, 14}: "Bri-Link Technologies Co., Ltd", + [3]byte{0, 1, 15}: "Brocade Communications Systems, Inc.", + [3]byte{0, 1, 16}: "Gotham Networks", + [3]byte{0, 1, 17}: "iDigm Inc.", + [3]byte{0, 1, 18}: "Shark Multimedia Inc.", + [3]byte{0, 1, 19}: "OLYMPUS CORPORATION", + [3]byte{0, 1, 20}: "KANDA TSUSHIN KOGYO CO., LTD.", + [3]byte{0, 1, 21}: "EXTRATECH CORPORATION", + [3]byte{0, 1, 22}: "Netspect Technologies, Inc.", + [3]byte{0, 1, 23}: "CANAL +", + [3]byte{0, 1, 24}: "EZ Digital Co., Ltd.", + [3]byte{0, 1, 25}: "RTUnet (Australia)", + [3]byte{0, 1, 26}: "Hoffmann und Burmeister GbR", + [3]byte{0, 1, 27}: "Unizone Technologies, Inc.", + [3]byte{0, 1, 28}: "Universal Talkware Corporation", + [3]byte{0, 1, 29}: "Centillium Communications", + [3]byte{0, 1, 30}: "Precidia Technologies, Inc.", + [3]byte{0, 1, 31}: "RC Networks, Inc.", + [3]byte{0, 1, 32}: "OSCILLOQUARTZ S.A.", + [3]byte{0, 1, 33}: "Watchguard Technologies, Inc.", + [3]byte{0, 1, 34}: "Trend Communications, Ltd.", + [3]byte{0, 1, 35}: "DIGITAL ELECTRONICS CORP.", + [3]byte{0, 1, 36}: "Acer Incorporated", + [3]byte{0, 1, 37}: "YAESU MUSEN CO., LTD.", + [3]byte{0, 1, 38}: "PAC Labs", + [3]byte{0, 1, 39}: "OPEN Networks Pty Ltd", + [3]byte{0, 1, 40}: "EnjoyWeb, Inc.", + [3]byte{0, 1, 41}: "DFI Inc.", + [3]byte{0, 1, 42}: "Telematica Sistems Inteligente", + [3]byte{0, 1, 43}: "TELENET Co., Ltd.", + [3]byte{0, 1, 44}: "Aravox Technologies, Inc.", + [3]byte{0, 1, 45}: "Komodo Technology", + [3]byte{0, 1, 46}: "PC Partner Ltd.", + [3]byte{0, 1, 47}: "Twinhead International Corp", + [3]byte{0, 1, 48}: "Extreme Networks", + [3]byte{0, 1, 49}: "Bosch Security Systems, Inc.", + [3]byte{0, 1, 50}: "Dranetz - BMI", + [3]byte{0, 1, 51}: "KYOWA Electronic Instruments C", + [3]byte{0, 1, 52}: "Selectron Systems AG", + [3]byte{0, 1, 53}: "KDC Corp.", + [3]byte{0, 1, 54}: "CyberTAN Technology, Inc.", + [3]byte{0, 1, 55}: "IT Farm Corporation", + [3]byte{0, 1, 56}: "XAVi Technologies Corp.", + [3]byte{0, 1, 57}: "Point Multimedia Systems", + [3]byte{0, 1, 58}: "SHELCAD COMMUNICATIONS, LTD.", + [3]byte{0, 1, 59}: "BNA SYSTEMS", + [3]byte{0, 1, 60}: "TIW SYSTEMS", + [3]byte{0, 1, 61}: "RiscStation Ltd.", + [3]byte{0, 1, 62}: "Ascom Tateco AB", + [3]byte{0, 1, 63}: "Neighbor World Co., Ltd.", + [3]byte{0, 1, 64}: "Sendtek Corporation", + [3]byte{0, 1, 65}: "CABLE PRINT", + [3]byte{0, 1, 66}: "CISCO SYSTEMS, INC.", + [3]byte{0, 1, 67}: "CISCO SYSTEMS, INC.", + [3]byte{0, 1, 68}: "EMC Corporation", + [3]byte{0, 1, 69}: "WINSYSTEMS, INC.", + [3]byte{0, 1, 70}: "Tesco Controls, Inc.", + [3]byte{0, 1, 71}: "Zhone Technologies", + [3]byte{0, 1, 72}: "X-traWeb Inc.", + [3]byte{0, 1, 73}: "T.D.T. Transfer Data Test GmbH", + [3]byte{0, 1, 74}: "Sony Corporation", + [3]byte{0, 1, 75}: "Ennovate Networks, Inc.", + [3]byte{0, 1, 76}: "Berkeley Process Control", + [3]byte{0, 1, 77}: "Shin Kin Enterprises Co., Ltd", + [3]byte{0, 1, 78}: "WIN Enterprises, Inc.", + [3]byte{0, 1, 79}: "ADTRAN INC", + [3]byte{0, 1, 80}: "GILAT COMMUNICATIONS, LTD.", + [3]byte{0, 1, 81}: "Ensemble Communications", + [3]byte{0, 1, 82}: "CHROMATEK INC.", + [3]byte{0, 1, 83}: "ARCHTEK TELECOM CORPORATION", + [3]byte{0, 1, 84}: "G3M Corporation", + [3]byte{0, 1, 85}: "Promise Technology, Inc.", + [3]byte{0, 1, 86}: "FIREWIREDIRECT.COM, INC.", + [3]byte{0, 1, 87}: "SYSWAVE CO., LTD", + [3]byte{0, 1, 88}: "Electro Industries/Gauge Tech", + [3]byte{0, 1, 89}: "S1 Corporation", + [3]byte{0, 1, 90}: "Digital Video Broadcasting", + [3]byte{0, 1, 91}: "ITALTEL S.p.A/RF-UP-I", + [3]byte{0, 1, 92}: "CADANT INC.", + [3]byte{0, 1, 93}: "Oracle Corporation", + [3]byte{0, 1, 94}: "BEST TECHNOLOGY CO., LTD.", + [3]byte{0, 1, 95}: "DIGITAL DESIGN GmbH", + [3]byte{0, 1, 96}: "ELMEX Co., LTD.", + [3]byte{0, 1, 97}: "Meta Machine Technology", + [3]byte{0, 1, 98}: "Cygnet Technologies, Inc.", + [3]byte{0, 1, 99}: "CISCO SYSTEMS, INC.", + [3]byte{0, 1, 100}: "CISCO SYSTEMS, INC.", + [3]byte{0, 1, 101}: "AirSwitch Corporation", + [3]byte{0, 1, 102}: "TC GROUP A/S", + [3]byte{0, 1, 103}: "HIOKI E.E. CORPORATION", + [3]byte{0, 1, 104}: "VITANA CORPORATION", + [3]byte{0, 1, 105}: "Celestix Networks Pte Ltd.", + [3]byte{0, 1, 106}: "ALITEC", + [3]byte{0, 1, 107}: "LightChip, Inc.", + [3]byte{0, 1, 108}: "FOXCONN", + [3]byte{0, 1, 109}: "CarrierComm Inc.", + [3]byte{0, 1, 110}: "Conklin Corporation", + [3]byte{0, 1, 111}: "Inkel Corp.", + [3]byte{0, 1, 112}: "ESE Embedded System Engineer'g", + [3]byte{0, 1, 113}: "Allied Data Technologies", + [3]byte{0, 1, 114}: "TechnoLand Co., LTD.", + [3]byte{0, 1, 115}: "AMCC", + [3]byte{0, 1, 116}: "CyberOptics Corporation", + [3]byte{0, 1, 117}: "Radiant Communications Corp.", + [3]byte{0, 1, 118}: "Orient Silver Enterprises", + [3]byte{0, 1, 119}: "EDSL", + [3]byte{0, 1, 120}: "MARGI Systems, Inc.", + [3]byte{0, 1, 121}: "WIRELESS TECHNOLOGY, INC.", + [3]byte{0, 1, 122}: "Chengdu Maipu Electric Industrial Co., Ltd.", + [3]byte{0, 1, 123}: "Heidelberger Druckmaschinen AG", + [3]byte{0, 1, 124}: "AG-E GmbH", + [3]byte{0, 1, 125}: "ThermoQuest", + [3]byte{0, 1, 126}: "ADTEK System Science Co., Ltd.", + [3]byte{0, 1, 127}: "Experience Music Project", + [3]byte{0, 1, 128}: "AOpen, Inc.", + [3]byte{0, 1, 129}: "Nortel Networks", + [3]byte{0, 1, 130}: "DICA TECHNOLOGIES AG", + [3]byte{0, 1, 131}: "ANITE TELECOMS", + [3]byte{0, 1, 132}: "SIEB & MEYER AG", + [3]byte{0, 1, 133}: "Hitachi Aloka Medical, Ltd.", + [3]byte{0, 1, 134}: "Uwe Disch", + [3]byte{0, 1, 135}: "I2SE GmbH", + [3]byte{0, 1, 136}: "LXCO Technologies ag", + [3]byte{0, 1, 137}: "Refraction Technology, Inc.", + [3]byte{0, 1, 138}: "ROI COMPUTER AG", + [3]byte{0, 1, 139}: "NetLinks Co., Ltd.", + [3]byte{0, 1, 140}: "Mega Vision", + [3]byte{0, 1, 141}: "AudeSi Technologies", + [3]byte{0, 1, 142}: "Logitec Corporation", + [3]byte{0, 1, 143}: "Kenetec, Inc.", + [3]byte{0, 1, 144}: "SMK-M", + [3]byte{0, 1, 145}: "SYRED Data Systems", + [3]byte{0, 1, 146}: "Texas Digital Systems", + [3]byte{0, 1, 147}: "Hanbyul Telecom Co., Ltd.", + [3]byte{0, 1, 148}: "Capital Equipment Corporation", + [3]byte{0, 1, 149}: "Sena Technologies, Inc.", + [3]byte{0, 1, 150}: "CISCO SYSTEMS, INC.", + [3]byte{0, 1, 151}: "CISCO SYSTEMS, INC.", + [3]byte{0, 1, 152}: "Darim Vision", + [3]byte{0, 1, 153}: "HeiSei Electronics", + [3]byte{0, 1, 154}: "LEUNIG GmbH", + [3]byte{0, 1, 155}: "Kyoto Microcomputer Co., Ltd.", + [3]byte{0, 1, 156}: "JDS Uniphase Inc.", + [3]byte{0, 1, 157}: "E-Control Systems, Inc.", + [3]byte{0, 1, 158}: "ESS Technology, Inc.", + [3]byte{0, 1, 159}: "ReadyNet", + [3]byte{0, 1, 160}: "Infinilink Corporation", + [3]byte{0, 1, 161}: "Mag-Tek, Inc.", + [3]byte{0, 1, 162}: "Logical Co., Ltd.", + [3]byte{0, 1, 163}: "GENESYS LOGIC, INC.", + [3]byte{0, 1, 164}: "Microlink Corporation", + [3]byte{0, 1, 165}: "Nextcomm, Inc.", + [3]byte{0, 1, 166}: "Scientific-Atlanta Arcodan A/S", + [3]byte{0, 1, 167}: "UNEX TECHNOLOGY CORPORATION", + [3]byte{0, 1, 168}: "Welltech Computer Co., Ltd.", + [3]byte{0, 1, 169}: "BMW AG", + [3]byte{0, 1, 170}: "Airspan Communications, Ltd.", + [3]byte{0, 1, 171}: "Main Street Networks", + [3]byte{0, 1, 172}: "Sitara Networks, Inc.", + [3]byte{0, 1, 173}: "Coach Master International d.b.a. CMI Worldwide, Inc.", + [3]byte{0, 1, 174}: "Trex Enterprises", + [3]byte{0, 1, 175}: "Artesyn Embedded Technologies", + [3]byte{0, 1, 176}: "Fulltek Technology Co., Ltd.", + [3]byte{0, 1, 177}: "General Bandwidth", + [3]byte{0, 1, 178}: "Digital Processing Systems, Inc.", + [3]byte{0, 1, 179}: "Precision Electronic Manufacturing", + [3]byte{0, 1, 180}: "Wayport, Inc.", + [3]byte{0, 1, 181}: "Turin Networks, Inc.", + [3]byte{0, 1, 182}: "SAEJIN T&M Co., Ltd.", + [3]byte{0, 1, 183}: "Centos, Inc.", + [3]byte{0, 1, 184}: "Netsensity, Inc.", + [3]byte{0, 1, 185}: "SKF Condition Monitoring", + [3]byte{0, 1, 186}: "IC-Net, Inc.", + [3]byte{0, 1, 187}: "Frequentis", + [3]byte{0, 1, 188}: "Brains Corporation", + [3]byte{0, 1, 189}: "Peterson Electro-Musical Products, Inc.", + [3]byte{0, 1, 190}: "Gigalink Co., Ltd.", + [3]byte{0, 1, 191}: "Teleforce Co., Ltd.", + [3]byte{0, 1, 192}: "CompuLab, Ltd.", + [3]byte{0, 1, 193}: "Vitesse Semiconductor Corporation", + [3]byte{0, 1, 194}: "ARK Research Corp.", + [3]byte{0, 1, 195}: "Acromag, Inc.", + [3]byte{0, 1, 196}: "NeoWave, Inc.", + [3]byte{0, 1, 197}: "Simpler Networks", + [3]byte{0, 1, 198}: "Quarry Technologies", + [3]byte{0, 1, 199}: "CISCO SYSTEMS, INC.", + [3]byte{0, 1, 200}: "THOMAS CONRAD CORP.", + [3]byte{0, 1, 200}: "CONRAD CORP.", + [3]byte{0, 1, 201}: "CISCO SYSTEMS, INC.", + [3]byte{0, 1, 202}: "Geocast Network Systems, Inc.", + [3]byte{0, 1, 203}: "EVR", + [3]byte{0, 1, 204}: "Japan Total Design Communication Co., Ltd.", + [3]byte{0, 1, 205}: "ARtem", + [3]byte{0, 1, 206}: "Custom Micro Products, Ltd.", + [3]byte{0, 1, 207}: "Alpha Data Parallel Systems, Ltd.", + [3]byte{0, 1, 208}: "VitalPoint, Inc.", + [3]byte{0, 1, 209}: "CoNet Communications, Inc.", + [3]byte{0, 1, 210}: "inXtron, Inc.", + [3]byte{0, 1, 211}: "PAXCOMM, Inc.", + [3]byte{0, 1, 212}: "Leisure Time, Inc.", + [3]byte{0, 1, 213}: "HAEDONG INFO & COMM CO., LTD", + [3]byte{0, 1, 214}: "manroland AG", + [3]byte{0, 1, 215}: "F5 Networks, Inc.", + [3]byte{0, 1, 216}: "Teltronics, Inc.", + [3]byte{0, 1, 217}: "Sigma, Inc.", + [3]byte{0, 1, 218}: "WINCOMM Corporation", + [3]byte{0, 1, 219}: "Freecom Technologies GmbH", + [3]byte{0, 1, 220}: "Activetelco", + [3]byte{0, 1, 221}: "Avail Networks", + [3]byte{0, 1, 222}: "Trango Systems, Inc.", + [3]byte{0, 1, 223}: "ISDN Communications, Ltd.", + [3]byte{0, 1, 224}: "Fast Systems, Inc.", + [3]byte{0, 1, 225}: "Kinpo Electronics, Inc.", + [3]byte{0, 1, 226}: "Ando Electric Corporation", + [3]byte{0, 1, 227}: "Siemens AG", + [3]byte{0, 1, 228}: "Sitera, Inc.", + [3]byte{0, 1, 229}: "Supernet, Inc.", + [3]byte{0, 1, 230}: "Hewlett-Packard Company", + [3]byte{0, 1, 231}: "Hewlett-Packard Company", + [3]byte{0, 1, 232}: "Force10 Networks, Inc.", + [3]byte{0, 1, 233}: "Litton Marine Systems B.V.", + [3]byte{0, 1, 234}: "Cirilium Corp.", + [3]byte{0, 1, 235}: "C-COM Corporation", + [3]byte{0, 1, 236}: "Ericsson Group", + [3]byte{0, 1, 237}: "SETA Corp.", + [3]byte{0, 1, 238}: "Comtrol Europe, Ltd.", + [3]byte{0, 1, 239}: "Camtel Technology Corp.", + [3]byte{0, 1, 240}: "Tridium, Inc.", + [3]byte{0, 1, 241}: "Innovative Concepts, Inc.", + [3]byte{0, 1, 242}: "Mark of the Unicorn, Inc.", + [3]byte{0, 1, 243}: "QPS, Inc.", + [3]byte{0, 1, 244}: "Enterasys Networks", + [3]byte{0, 1, 245}: "ERIM S.A.", + [3]byte{0, 1, 246}: "Association of Musical Electronics Industry", + [3]byte{0, 1, 247}: "Image Display Systems, Inc.", + [3]byte{0, 1, 248}: "Texio Technology Corporation", + [3]byte{0, 1, 249}: "TeraGlobal Communications Corp.", + [3]byte{0, 1, 250}: "HOROSCAS", + [3]byte{0, 1, 251}: "DoTop Technology, Inc.", + [3]byte{0, 1, 252}: "Keyence Corporation", + [3]byte{0, 1, 253}: "Digital Voice Systems, Inc.", + [3]byte{0, 1, 254}: "DIGITAL EQUIPMENT CORPORATION", + [3]byte{0, 1, 255}: "Data Direct Networks, Inc.", + [3]byte{0, 2, 0}: "Net & Sys Co., Ltd.", + [3]byte{0, 2, 1}: "IFM Electronic gmbh", + [3]byte{0, 2, 2}: "Amino Communications, Ltd.", + [3]byte{0, 2, 3}: "Woonsang Telecom, Inc.", + [3]byte{0, 2, 4}: "Bodmann Industries Elektronik GmbH", + [3]byte{0, 2, 5}: "Hitachi Denshi, Ltd.", + [3]byte{0, 2, 6}: "Telital R&D Denmark A/S", + [3]byte{0, 2, 7}: "VisionGlobal Network Corp.", + [3]byte{0, 2, 8}: "Unify Networks, Inc.", + [3]byte{0, 2, 9}: "Shenzhen SED Information Technology Co., Ltd.", + [3]byte{0, 2, 10}: "Gefran Spa", + [3]byte{0, 2, 11}: "Native Networks, Inc.", + [3]byte{0, 2, 12}: "Metro-Optix", + [3]byte{0, 2, 13}: "Micronpc.com", + [3]byte{0, 2, 14}: "ECI Telecom, Ltd", + [3]byte{0, 2, 15}: "AATR", + [3]byte{0, 2, 16}: "Fenecom", + [3]byte{0, 2, 17}: "Nature Worldwide Technology Corp.", + [3]byte{0, 2, 18}: "SierraCom", + [3]byte{0, 2, 19}: "S.D.E.L.", + [3]byte{0, 2, 20}: "DTVRO", + [3]byte{0, 2, 21}: "Cotas Computer Technology A/B", + [3]byte{0, 2, 22}: "CISCO SYSTEMS, INC.", + [3]byte{0, 2, 23}: "CISCO SYSTEMS, INC.", + [3]byte{0, 2, 24}: "Advanced Scientific Corp", + [3]byte{0, 2, 25}: "Paralon Technologies", + [3]byte{0, 2, 26}: "Zuma Networks", + [3]byte{0, 2, 27}: "Kollmorgen-Servotronix", + [3]byte{0, 2, 28}: "Network Elements, Inc.", + [3]byte{0, 2, 29}: "Data General Communication Ltd.", + [3]byte{0, 2, 30}: "SIMTEL S.R.L.", + [3]byte{0, 2, 31}: "Aculab PLC", + [3]byte{0, 2, 32}: "CANON FINETECH INC.", + [3]byte{0, 2, 33}: "DSP Application, Ltd.", + [3]byte{0, 2, 34}: "Chromisys, Inc.", + [3]byte{0, 2, 35}: "ClickTV", + [3]byte{0, 2, 36}: "C-COR", + [3]byte{0, 2, 37}: "One Stop Systems", + [3]byte{0, 2, 38}: "XESystems, Inc.", + [3]byte{0, 2, 39}: "ESD Electronic System Design GmbH", + [3]byte{0, 2, 40}: "Necsom, Ltd.", + [3]byte{0, 2, 41}: "Adtec Corporation", + [3]byte{0, 2, 42}: "Asound Electronic", + [3]byte{0, 2, 43}: "SAXA, Inc.", + [3]byte{0, 2, 44}: "ABB Bomem, Inc.", + [3]byte{0, 2, 45}: "Agere Systems", + [3]byte{0, 2, 46}: "TEAC Corp. R& D", + [3]byte{0, 2, 47}: "P-Cube, Ltd.", + [3]byte{0, 2, 48}: "Intersoft Electronics", + [3]byte{0, 2, 49}: "Ingersoll-Rand", + [3]byte{0, 2, 50}: "Avision, Inc.", + [3]byte{0, 2, 51}: "Mantra Communications, Inc.", + [3]byte{0, 2, 52}: "Imperial Technology, Inc.", + [3]byte{0, 2, 53}: "Paragon Networks International", + [3]byte{0, 2, 54}: "INIT GmbH", + [3]byte{0, 2, 55}: "Cosmo Research Corp.", + [3]byte{0, 2, 56}: "Serome Technology, Inc.", + [3]byte{0, 2, 57}: "Visicom", + [3]byte{0, 2, 58}: "ZSK Stickmaschinen GmbH", + [3]byte{0, 2, 59}: "Ericsson", + [3]byte{0, 2, 60}: "Creative Technology, Ltd.", + [3]byte{0, 2, 61}: "Cisco Systems, Inc.", + [3]byte{0, 2, 62}: "Selta Telematica S.p.a", + [3]byte{0, 2, 63}: "Compal Electronics, Inc.", + [3]byte{0, 2, 64}: "Seedek Co., Ltd.", + [3]byte{0, 2, 65}: "Amer.com", + [3]byte{0, 2, 66}: "Videoframe Systems", + [3]byte{0, 2, 67}: "Raysis Co., Ltd.", + [3]byte{0, 2, 68}: "SURECOM Technology Co.", + [3]byte{0, 2, 69}: "Lampus Co, Ltd.", + [3]byte{0, 2, 70}: "All-Win Tech Co., Ltd.", + [3]byte{0, 2, 71}: "Great Dragon Information Technology (Group) Co., Ltd.", + [3]byte{0, 2, 72}: "Pilz GmbH & Co.", + [3]byte{0, 2, 73}: "Aviv Infocom Co, Ltd.", + [3]byte{0, 2, 74}: "CISCO SYSTEMS, INC.", + [3]byte{0, 2, 75}: "CISCO SYSTEMS, INC.", + [3]byte{0, 2, 76}: "SiByte, Inc.", + [3]byte{0, 2, 77}: "Mannesman Dematic Colby Pty. Ltd.", + [3]byte{0, 2, 78}: "Datacard Group", + [3]byte{0, 2, 79}: "IPM Datacom S.R.L.", + [3]byte{0, 2, 80}: "Geyser Networks, Inc.", + [3]byte{0, 2, 81}: "Soma Networks, Inc.", + [3]byte{0, 2, 82}: "Carrier Corporation", + [3]byte{0, 2, 83}: "Televideo, Inc.", + [3]byte{0, 2, 84}: "WorldGate", + [3]byte{0, 2, 85}: "IBM Corp", + [3]byte{0, 2, 86}: "Alpha Processor, Inc.", + [3]byte{0, 2, 87}: "Microcom Corp.", + [3]byte{0, 2, 88}: "Flying Packets Communications", + [3]byte{0, 2, 89}: "Tsann Kuen China (Shanghai)Enterprise Co., Ltd. IT Group", + [3]byte{0, 2, 90}: "Catena Networks", + [3]byte{0, 2, 91}: "Cambridge Silicon Radio", + [3]byte{0, 2, 92}: "SCI Systems (Kunshan) Co., Ltd.", + [3]byte{0, 2, 93}: "Calix Networks", + [3]byte{0, 2, 94}: "High Technology Ltd", + [3]byte{0, 2, 95}: "Nortel Networks", + [3]byte{0, 2, 96}: "Accordion Networks, Inc.", + [3]byte{0, 2, 97}: "Tilgin AB", + [3]byte{0, 2, 98}: "Soyo Group Soyo Com Tech Co., Ltd", + [3]byte{0, 2, 99}: "UPS Manufacturing SRL", + [3]byte{0, 2, 100}: "AudioRamp.com", + [3]byte{0, 2, 101}: "Virditech Co. Ltd.", + [3]byte{0, 2, 102}: "Thermalogic Corporation", + [3]byte{0, 2, 103}: "NODE RUNNER, INC.", + [3]byte{0, 2, 104}: "Harris Government Communications", + [3]byte{0, 2, 105}: "Nadatel Co., Ltd", + [3]byte{0, 2, 106}: "Cocess Telecom Co., Ltd.", + [3]byte{0, 2, 107}: "BCM Computers Co., Ltd.", + [3]byte{0, 2, 108}: "Philips CFT", + [3]byte{0, 2, 109}: "Adept Telecom", + [3]byte{0, 2, 110}: "NeGeN Access, Inc.", + [3]byte{0, 2, 111}: "Senao International Co., Ltd.", + [3]byte{0, 2, 112}: "Crewave Co., Ltd.", + [3]byte{0, 2, 113}: "Zhone Technologies", + [3]byte{0, 2, 114}: "CC&C Technologies, Inc.", + [3]byte{0, 2, 115}: "Coriolis Networks", + [3]byte{0, 2, 116}: "Tommy Technologies Corp.", + [3]byte{0, 2, 117}: "SMART Technologies, Inc.", + [3]byte{0, 2, 118}: "Primax Electronics Ltd.", + [3]byte{0, 2, 119}: "Cash Systemes Industrie", + [3]byte{0, 2, 120}: "Samsung Electro-Mechanics Co., Ltd.", + [3]byte{0, 2, 121}: "Control Applications, Ltd.", + [3]byte{0, 2, 122}: "IOI Technology Corporation", + [3]byte{0, 2, 123}: "Amplify Net, Inc.", + [3]byte{0, 2, 124}: "Trilithic, Inc.", + [3]byte{0, 2, 125}: "CISCO SYSTEMS, INC.", + [3]byte{0, 2, 126}: "CISCO SYSTEMS, INC.", + [3]byte{0, 2, 127}: "ask-technologies.com", + [3]byte{0, 2, 128}: "Mu Net, Inc.", + [3]byte{0, 2, 129}: "Madge Ltd.", + [3]byte{0, 2, 130}: "ViaClix, Inc.", + [3]byte{0, 2, 131}: "Spectrum Controls, Inc.", + [3]byte{0, 2, 132}: "AREVA T&D", + [3]byte{0, 2, 133}: "Riverstone Networks", + [3]byte{0, 2, 134}: "Occam Networks", + [3]byte{0, 2, 135}: "Adapcom", + [3]byte{0, 2, 136}: "GLOBAL VILLAGE COMMUNICATION", + [3]byte{0, 2, 137}: "DNE Technologies", + [3]byte{0, 2, 138}: "Ambit Microsystems Corporation", + [3]byte{0, 2, 139}: "VDSL Systems OY", + [3]byte{0, 2, 140}: "Micrel-Synergy Semiconductor", + [3]byte{0, 2, 141}: "Movita Technologies, Inc.", + [3]byte{0, 2, 142}: "Rapid 5 Networks, Inc.", + [3]byte{0, 2, 143}: "Globetek, Inc.", + [3]byte{0, 2, 144}: "Woorigisool, Inc.", + [3]byte{0, 2, 145}: "Open Network Co., Ltd.", + [3]byte{0, 2, 146}: "Logic Innovations, Inc.", + [3]byte{0, 2, 147}: "Solid Data Systems", + [3]byte{0, 2, 148}: "Tokyo Sokushin Co., Ltd.", + [3]byte{0, 2, 149}: "IP.Access Limited", + [3]byte{0, 2, 150}: "Lectron Co,. Ltd.", + [3]byte{0, 2, 151}: "C-COR.net", + [3]byte{0, 2, 152}: "Broadframe Corporation", + [3]byte{0, 2, 153}: "Apex, Inc.", + [3]byte{0, 2, 154}: "Storage Apps", + [3]byte{0, 2, 155}: "Kreatel Communications AB", + [3]byte{0, 2, 156}: "3COM", + [3]byte{0, 2, 157}: "Merix Corp.", + [3]byte{0, 2, 158}: "Information Equipment Co., Ltd.", + [3]byte{0, 2, 159}: "L-3 Communication Aviation Recorders", + [3]byte{0, 2, 160}: "Flatstack Ltd.", + [3]byte{0, 2, 161}: "World Wide Packets", + [3]byte{0, 2, 162}: "Hilscher GmbH", + [3]byte{0, 2, 163}: "ABB Switzerland Ltd, Power Systems", + [3]byte{0, 2, 164}: "AddPac Technology Co., Ltd.", + [3]byte{0, 2, 165}: "Hewlett-Packard Company", + [3]byte{0, 2, 166}: "Effinet Systems Co., Ltd.", + [3]byte{0, 2, 167}: "Vivace Networks", + [3]byte{0, 2, 168}: "Air Link Technology", + [3]byte{0, 2, 169}: "RACOM, s.r.o.", + [3]byte{0, 2, 170}: "PLcom Co., Ltd.", + [3]byte{0, 2, 171}: "CTC Union Technologies Co., Ltd.", + [3]byte{0, 2, 172}: "3PAR data", + [3]byte{0, 2, 173}: "HOYA Corporation", + [3]byte{0, 2, 174}: "Scannex Electronics Ltd.", + [3]byte{0, 2, 175}: "TeleCruz Technology, Inc.", + [3]byte{0, 2, 176}: "Hokubu Communication & Industrial Co., Ltd.", + [3]byte{0, 2, 177}: "Anritsu, Ltd.", + [3]byte{0, 2, 178}: "Cablevision", + [3]byte{0, 2, 179}: "Intel Corporation", + [3]byte{0, 2, 180}: "DAPHNE", + [3]byte{0, 2, 181}: "Avnet, Inc.", + [3]byte{0, 2, 182}: "Acrosser Technology Co., Ltd.", + [3]byte{0, 2, 183}: "Watanabe Electric Industry Co., Ltd.", + [3]byte{0, 2, 184}: "WHI KONSULT AB", + [3]byte{0, 2, 185}: "CISCO SYSTEMS, INC.", + [3]byte{0, 2, 186}: "CISCO SYSTEMS, INC.", + [3]byte{0, 2, 187}: "Continuous Computing Corp", + [3]byte{0, 2, 188}: "LVL 7 Systems, Inc.", + [3]byte{0, 2, 189}: "Bionet Co., Ltd.", + [3]byte{0, 2, 190}: "Totsu Engineering, Inc.", + [3]byte{0, 2, 191}: "dotRocket, Inc.", + [3]byte{0, 2, 192}: "Bencent Tzeng Industry Co., Ltd.", + [3]byte{0, 2, 193}: "Innovative Electronic Designs, Inc.", + [3]byte{0, 2, 194}: "Net Vision Telecom", + [3]byte{0, 2, 195}: "Arelnet Ltd.", + [3]byte{0, 2, 196}: "Vector International BVBA", + [3]byte{0, 2, 197}: "Evertz Microsystems Ltd.", + [3]byte{0, 2, 198}: "Data Track Technology PLC", + [3]byte{0, 2, 199}: "ALPS ELECTRIC Co., Ltd.", + [3]byte{0, 2, 200}: "Technocom Communications Technology (pte) Ltd", + [3]byte{0, 2, 201}: "Mellanox Technologies", + [3]byte{0, 2, 202}: "EndPoints, Inc.", + [3]byte{0, 2, 203}: "TriState Ltd.", + [3]byte{0, 2, 204}: "M.C.C.I", + [3]byte{0, 2, 205}: "TeleDream, Inc.", + [3]byte{0, 2, 206}: "FoxJet, Inc.", + [3]byte{0, 2, 207}: "ZyGate Communications, Inc.", + [3]byte{0, 2, 208}: "Comdial Corporation", + [3]byte{0, 2, 209}: "Vivotek, Inc.", + [3]byte{0, 2, 210}: "Workstation AG", + [3]byte{0, 2, 211}: "NetBotz, Inc.", + [3]byte{0, 2, 212}: "PDA Peripherals, Inc.", + [3]byte{0, 2, 213}: "ACR", + [3]byte{0, 2, 214}: "NICE Systems", + [3]byte{0, 2, 215}: "EMPEG Ltd", + [3]byte{0, 2, 216}: "BRECIS Communications Corporation", + [3]byte{0, 2, 217}: "Reliable Controls", + [3]byte{0, 2, 218}: "ExiO Communications, Inc.", + [3]byte{0, 2, 219}: "NETSEC", + [3]byte{0, 2, 220}: "Fujitsu General Limited", + [3]byte{0, 2, 221}: "Bromax Communications, Ltd.", + [3]byte{0, 2, 222}: "Astrodesign, Inc.", + [3]byte{0, 2, 223}: "Net Com Systems, Inc.", + [3]byte{0, 2, 224}: "ETAS GmbH", + [3]byte{0, 2, 225}: "Integrated Network Corporation", + [3]byte{0, 2, 226}: "NDC Infared Engineering", + [3]byte{0, 2, 227}: "LITE-ON Communications, Inc.", + [3]byte{0, 2, 228}: "JC HYUN Systems, Inc.", + [3]byte{0, 2, 229}: "Timeware Ltd.", + [3]byte{0, 2, 230}: "Gould Instrument Systems, Inc.", + [3]byte{0, 2, 231}: "CAB GmbH & Co KG", + [3]byte{0, 2, 232}: "E.D.&A.", + [3]byte{0, 2, 233}: "CS Systemes De Securite - C3S", + [3]byte{0, 2, 234}: "Focus Enhancements", + [3]byte{0, 2, 235}: "Pico Communications", + [3]byte{0, 2, 236}: "Maschoff Design Engineering", + [3]byte{0, 2, 237}: "DXO Telecom Co., Ltd.", + [3]byte{0, 2, 238}: "Nokia Danmark A/S", + [3]byte{0, 2, 239}: "CCC Network Systems Group Ltd.", + [3]byte{0, 2, 240}: "AME Optimedia Technology Co., Ltd.", + [3]byte{0, 2, 241}: "Pinetron Co., Ltd.", + [3]byte{0, 2, 242}: "eDevice, Inc.", + [3]byte{0, 2, 243}: "Media Serve Co., Ltd.", + [3]byte{0, 2, 244}: "PCTEL, Inc.", + [3]byte{0, 2, 245}: "VIVE Synergies, Inc.", + [3]byte{0, 2, 246}: "Equipe Communications", + [3]byte{0, 2, 247}: "ARM", + [3]byte{0, 2, 248}: "SEAKR Engineering, Inc.", + [3]byte{0, 2, 249}: "MIMOS Berhad", + [3]byte{0, 2, 250}: "DX Antenna Co., Ltd.", + [3]byte{0, 2, 251}: "Baumuller Aulugen-Systemtechnik GmbH", + [3]byte{0, 2, 252}: "CISCO SYSTEMS, INC.", + [3]byte{0, 2, 253}: "CISCO SYSTEMS, INC.", + [3]byte{0, 2, 254}: "Viditec, Inc.", + [3]byte{0, 2, 255}: "Handan BroadInfoCom", + [3]byte{0, 3, 0}: "Barracuda Networks, Inc.", + [3]byte{0, 3, 1}: "EXFO", + [3]byte{0, 3, 2}: "Charles Industries, Ltd.", + [3]byte{0, 3, 3}: "JAMA Electronics Co., Ltd.", + [3]byte{0, 3, 4}: "Pacific Broadband Communications", + [3]byte{0, 3, 5}: "MSC Vertriebs GmbH", + [3]byte{0, 3, 6}: "Fusion In Tech Co., Ltd.", + [3]byte{0, 3, 7}: "Secure Works, Inc.", + [3]byte{0, 3, 8}: "AM Communications, Inc.", + [3]byte{0, 3, 9}: "Texcel Technology PLC", + [3]byte{0, 3, 10}: "Argus Technologies", + [3]byte{0, 3, 11}: "Hunter Technology, Inc.", + [3]byte{0, 3, 12}: "Telesoft Technologies Ltd.", + [3]byte{0, 3, 13}: "Uniwill Computer Corp.", + [3]byte{0, 3, 14}: "Core Communications Co., Ltd.", + [3]byte{0, 3, 15}: "Digital China (Shanghai) Networks Ltd.", + [3]byte{0, 3, 16}: "E-Globaledge Corporation", + [3]byte{0, 3, 17}: "Micro Technology Co., Ltd.", + [3]byte{0, 3, 18}: "TR-Systemtechnik GmbH", + [3]byte{0, 3, 19}: "Access Media SPA", + [3]byte{0, 3, 20}: "Teleware Network Systems", + [3]byte{0, 3, 21}: "Cidco Incorporated", + [3]byte{0, 3, 22}: "Nobell Communications, Inc.", + [3]byte{0, 3, 23}: "Merlin Systems, Inc.", + [3]byte{0, 3, 24}: "Cyras Systems, Inc.", + [3]byte{0, 3, 25}: "Infineon AG", + [3]byte{0, 3, 26}: "Beijing Broad Telecom Ltd., China", + [3]byte{0, 3, 27}: "Cellvision Systems, Inc.", + [3]byte{0, 3, 28}: "Svenska Hardvarufabriken AB", + [3]byte{0, 3, 29}: "Taiwan Commate Computer, Inc.", + [3]byte{0, 3, 30}: "Optranet, Inc.", + [3]byte{0, 3, 31}: "Condev Ltd.", + [3]byte{0, 3, 32}: "Xpeed, Inc.", + [3]byte{0, 3, 33}: "Reco Research Co., Ltd.", + [3]byte{0, 3, 34}: "IDIS Co., Ltd.", + [3]byte{0, 3, 35}: "Cornet Technology, Inc.", + [3]byte{0, 3, 36}: "SANYO Consumer Electronics Co., Ltd.", + [3]byte{0, 3, 37}: "Arima Computer Corp.", + [3]byte{0, 3, 38}: "Iwasaki Information Systems Co., Ltd.", + [3]byte{0, 3, 39}: "ACT'L", + [3]byte{0, 3, 40}: "Mace Group, Inc.", + [3]byte{0, 3, 41}: "F3, Inc.", + [3]byte{0, 3, 42}: "UniData Communication Systems, Inc.", + [3]byte{0, 3, 43}: "GAI Datenfunksysteme GmbH", + [3]byte{0, 3, 44}: "ABB Switzerland Ltd", + [3]byte{0, 3, 45}: "IBASE Technology, Inc.", + [3]byte{0, 3, 46}: "Scope Information Management, Ltd.", + [3]byte{0, 3, 47}: "Global Sun Technology, Inc.", + [3]byte{0, 3, 48}: "Imagenics, Co., Ltd.", + [3]byte{0, 3, 49}: "CISCO SYSTEMS, INC.", + [3]byte{0, 3, 50}: "CISCO SYSTEMS, INC.", + [3]byte{0, 3, 51}: "Digitel Co., Ltd.", + [3]byte{0, 3, 52}: "Newport Electronics", + [3]byte{0, 3, 53}: "Mirae Technology", + [3]byte{0, 3, 54}: "Zetes Technologies", + [3]byte{0, 3, 55}: "Vaone, Inc.", + [3]byte{0, 3, 56}: "Oak Technology", + [3]byte{0, 3, 57}: "Eurologic Systems, Ltd.", + [3]byte{0, 3, 58}: "Silicon Wave, Inc.", + [3]byte{0, 3, 59}: "TAMI Tech Co., Ltd.", + [3]byte{0, 3, 60}: "Daiden Co., Ltd.", + [3]byte{0, 3, 61}: "ILSHin Lab", + [3]byte{0, 3, 62}: "Tateyama System Laboratory Co., Ltd.", + [3]byte{0, 3, 63}: "BigBand Networks, Ltd.", + [3]byte{0, 3, 64}: "Floware Wireless Systems, Ltd.", + [3]byte{0, 3, 65}: "Axon Digital Design", + [3]byte{0, 3, 66}: "Nortel Networks", + [3]byte{0, 3, 67}: "Martin Professional A/S", + [3]byte{0, 3, 68}: "Tietech.Co., Ltd.", + [3]byte{0, 3, 69}: "Routrek Networks Corporation", + [3]byte{0, 3, 70}: "Hitachi Kokusai Electric, Inc.", + [3]byte{0, 3, 71}: "Intel Corporation", + [3]byte{0, 3, 72}: "Norscan Instruments, Ltd.", + [3]byte{0, 3, 73}: "Vidicode Datacommunicatie B.V.", + [3]byte{0, 3, 74}: "RIAS Corporation", + [3]byte{0, 3, 75}: "Nortel Networks", + [3]byte{0, 3, 76}: "Shanghai DigiVision Technology Co., Ltd.", + [3]byte{0, 3, 77}: "Chiaro Networks, Ltd.", + [3]byte{0, 3, 78}: "Pos Data Company, Ltd.", + [3]byte{0, 3, 79}: "Sur-Gard Security", + [3]byte{0, 3, 80}: "BTICINO SPA", + [3]byte{0, 3, 81}: "Diebold, Inc.", + [3]byte{0, 3, 82}: "Colubris Networks", + [3]byte{0, 3, 83}: "Mitac, Inc.", + [3]byte{0, 3, 84}: "Fiber Logic Communications", + [3]byte{0, 3, 85}: "TeraBeam Internet Systems", + [3]byte{0, 3, 86}: "Wincor Nixdorf International GmbH", + [3]byte{0, 3, 87}: "Intervoice-Brite, Inc.", + [3]byte{0, 3, 88}: "Hanyang Digitech Co., Ltd.", + [3]byte{0, 3, 89}: "DigitalSis", + [3]byte{0, 3, 90}: "Photron Limited", + [3]byte{0, 3, 91}: "BridgeWave Communications", + [3]byte{0, 3, 92}: "Saint Song Corp.", + [3]byte{0, 3, 93}: "Bosung Hi-Net Co., Ltd.", + [3]byte{0, 3, 94}: "Metropolitan Area Networks, Inc.", + [3]byte{0, 3, 95}: "Prüftechnik Condition Monitoring GmbH & Co. KG", + [3]byte{0, 3, 96}: "PAC Interactive Technology, Inc.", + [3]byte{0, 3, 97}: "Widcomm, Inc.", + [3]byte{0, 3, 98}: "Vodtel Communications, Inc.", + [3]byte{0, 3, 99}: "Miraesys Co., Ltd.", + [3]byte{0, 3, 100}: "Scenix Semiconductor, Inc.", + [3]byte{0, 3, 101}: "Kira Information & Communications, Ltd.", + [3]byte{0, 3, 102}: "ASM Pacific Technology", + [3]byte{0, 3, 103}: "Jasmine Networks, Inc.", + [3]byte{0, 3, 104}: "Embedone Co., Ltd.", + [3]byte{0, 3, 105}: "Nippon Antenna Co., Ltd.", + [3]byte{0, 3, 106}: "Mainnet, Ltd.", + [3]byte{0, 3, 107}: "CISCO SYSTEMS, INC.", + [3]byte{0, 3, 108}: "CISCO SYSTEMS, INC.", + [3]byte{0, 3, 109}: "Runtop, Inc.", + [3]byte{0, 3, 110}: "Nicon Systems (Pty) Limited", + [3]byte{0, 3, 111}: "Telsey SPA", + [3]byte{0, 3, 112}: "NXTV, Inc.", + [3]byte{0, 3, 113}: "Acomz Networks Corp.", + [3]byte{0, 3, 114}: "ULAN", + [3]byte{0, 3, 115}: "Aselsan A.S", + [3]byte{0, 3, 116}: "Control Microsystems", + [3]byte{0, 3, 117}: "NetMedia, Inc.", + [3]byte{0, 3, 118}: "Graphtec Technology, Inc.", + [3]byte{0, 3, 119}: "Gigabit Wireless", + [3]byte{0, 3, 120}: "HUMAX Co., Ltd.", + [3]byte{0, 3, 121}: "Proscend Communications, Inc.", + [3]byte{0, 3, 122}: "Taiyo Yuden Co., Ltd.", + [3]byte{0, 3, 123}: "IDEC IZUMI Corporation", + [3]byte{0, 3, 124}: "Coax Media", + [3]byte{0, 3, 125}: "Stellcom", + [3]byte{0, 3, 126}: "PORTech Communications, Inc.", + [3]byte{0, 3, 127}: "Atheros Communications, Inc.", + [3]byte{0, 3, 128}: "SSH Communications Security Corp.", + [3]byte{0, 3, 129}: "Ingenico International", + [3]byte{0, 3, 130}: "A-One Co., Ltd.", + [3]byte{0, 3, 131}: "Metera Networks, Inc.", + [3]byte{0, 3, 132}: "AETA", + [3]byte{0, 3, 133}: "Actelis Networks, Inc.", + [3]byte{0, 3, 134}: "Ho Net, Inc.", + [3]byte{0, 3, 135}: "Blaze Network Products", + [3]byte{0, 3, 136}: "Fastfame Technology Co., Ltd.", + [3]byte{0, 3, 137}: "Plantronics", + [3]byte{0, 3, 138}: "America Online, Inc.", + [3]byte{0, 3, 139}: "PLUS-ONE I&T, Inc.", + [3]byte{0, 3, 140}: "Total Impact", + [3]byte{0, 3, 141}: "PCS Revenue Control Systems, Inc.", + [3]byte{0, 3, 142}: "Atoga Systems, Inc.", + [3]byte{0, 3, 143}: "Weinschel Corporation", + [3]byte{0, 3, 144}: "Digital Video Communications, Inc.", + [3]byte{0, 3, 145}: "Advanced Digital Broadcast, Ltd.", + [3]byte{0, 3, 146}: "Hyundai Teletek Co., Ltd.", + [3]byte{0, 3, 147}: "Apple", + [3]byte{0, 3, 148}: "Connect One", + [3]byte{0, 3, 149}: "California Amplifier", + [3]byte{0, 3, 150}: "EZ Cast Co., Ltd.", + [3]byte{0, 3, 151}: "Watchfront Limited", + [3]byte{0, 3, 152}: "WISI", + [3]byte{0, 3, 153}: "Dongju Informations & Communications Co., Ltd.", + [3]byte{0, 3, 154}: "SiConnect", + [3]byte{0, 3, 155}: "NetChip Technology, Inc.", + [3]byte{0, 3, 156}: "OptiMight Communications, Inc.", + [3]byte{0, 3, 157}: "Qisda Corporation", + [3]byte{0, 3, 158}: "Tera System Co., Ltd.", + [3]byte{0, 3, 159}: "CISCO SYSTEMS, INC.", + [3]byte{0, 3, 160}: "CISCO SYSTEMS, INC.", + [3]byte{0, 3, 161}: "HIPER Information & Communication, Inc.", + [3]byte{0, 3, 162}: "Catapult Communications", + [3]byte{0, 3, 163}: "MAVIX, Ltd.", + [3]byte{0, 3, 164}: "Imation Corp.", + [3]byte{0, 3, 165}: "Medea Corporation", + [3]byte{0, 3, 166}: "Traxit Technology, Inc.", + [3]byte{0, 3, 167}: "Unixtar Technology, Inc.", + [3]byte{0, 3, 168}: "IDOT Computers, Inc.", + [3]byte{0, 3, 169}: "AXCENT Media AG", + [3]byte{0, 3, 170}: "Watlow", + [3]byte{0, 3, 171}: "Bridge Information Systems", + [3]byte{0, 3, 172}: "Fronius Schweissmaschinen", + [3]byte{0, 3, 173}: "Emerson Energy Systems AB", + [3]byte{0, 3, 174}: "Allied Advanced Manufacturing Pte, Ltd.", + [3]byte{0, 3, 175}: "Paragea Communications", + [3]byte{0, 3, 176}: "Xsense Technology Corp.", + [3]byte{0, 3, 177}: "Hospira Inc.", + [3]byte{0, 3, 178}: "Radware", + [3]byte{0, 3, 179}: "IA Link Systems Co., Ltd.", + [3]byte{0, 3, 180}: "Macrotek International Corp.", + [3]byte{0, 3, 181}: "Entra Technology Co.", + [3]byte{0, 3, 182}: "QSI Corporation", + [3]byte{0, 3, 183}: "ZACCESS Systems", + [3]byte{0, 3, 184}: "NetKit Solutions, LLC", + [3]byte{0, 3, 185}: "Hualong Telecom Co., Ltd.", + [3]byte{0, 3, 186}: "Oracle Corporation", + [3]byte{0, 3, 187}: "Signal Communications Limited", + [3]byte{0, 3, 188}: "COT GmbH", + [3]byte{0, 3, 189}: "OmniCluster Technologies, Inc.", + [3]byte{0, 3, 190}: "Netility", + [3]byte{0, 3, 191}: "Centerpoint Broadband Technologies, Inc.", + [3]byte{0, 3, 192}: "RFTNC Co., Ltd.", + [3]byte{0, 3, 193}: "Packet Dynamics Ltd", + [3]byte{0, 3, 194}: "Solphone K.K.", + [3]byte{0, 3, 195}: "Micronik Multimedia", + [3]byte{0, 3, 196}: "Tomra Systems ASA", + [3]byte{0, 3, 197}: "Mobotix AG", + [3]byte{0, 3, 198}: "ICUE Systems, Inc.", + [3]byte{0, 3, 199}: "hopf Elektronik GmbH", + [3]byte{0, 3, 200}: "CML Emergency Services", + [3]byte{0, 3, 201}: "TECOM Co., Ltd.", + [3]byte{0, 3, 202}: "MTS Systems Corp.", + [3]byte{0, 3, 203}: "Nippon Systems Development Co., Ltd.", + [3]byte{0, 3, 204}: "Momentum Computer, Inc.", + [3]byte{0, 3, 205}: "Clovertech, Inc.", + [3]byte{0, 3, 206}: "ETEN Technologies, Inc.", + [3]byte{0, 3, 207}: "Muxcom, Inc.", + [3]byte{0, 3, 208}: "KOANKEISO Co., Ltd.", + [3]byte{0, 3, 209}: "Takaya Corporation", + [3]byte{0, 3, 210}: "Crossbeam Systems, Inc.", + [3]byte{0, 3, 211}: "Internet Energy Systems, Inc.", + [3]byte{0, 3, 212}: "Alloptic, Inc.", + [3]byte{0, 3, 213}: "Advanced Communications Co., Ltd.", + [3]byte{0, 3, 214}: "RADVision, Ltd.", + [3]byte{0, 3, 215}: "NextNet Wireless, Inc.", + [3]byte{0, 3, 216}: "iMPath Networks, Inc.", + [3]byte{0, 3, 217}: "Secheron SA", + [3]byte{0, 3, 218}: "Takamisawa Cybernetics Co., Ltd.", + [3]byte{0, 3, 219}: "Apogee Electronics Corp.", + [3]byte{0, 3, 220}: "Lexar Media, Inc.", + [3]byte{0, 3, 221}: "Comark Corp.", + [3]byte{0, 3, 222}: "OTC Wireless", + [3]byte{0, 3, 223}: "Desana Systems", + [3]byte{0, 3, 224}: "ARRIS Group, Inc.", + [3]byte{0, 3, 225}: "Winmate Communication, Inc.", + [3]byte{0, 3, 226}: "Comspace Corporation", + [3]byte{0, 3, 227}: "CISCO SYSTEMS, INC.", + [3]byte{0, 3, 228}: "CISCO SYSTEMS, INC.", + [3]byte{0, 3, 229}: "Hermstedt SG", + [3]byte{0, 3, 230}: "Entone, Inc.", + [3]byte{0, 3, 231}: "Logostek Co. Ltd.", + [3]byte{0, 3, 232}: "Wavelength Digital Limited", + [3]byte{0, 3, 233}: "Akara Canada, Inc.", + [3]byte{0, 3, 234}: "Mega System Technologies, Inc.", + [3]byte{0, 3, 235}: "Atrica", + [3]byte{0, 3, 236}: "ICG Research, Inc.", + [3]byte{0, 3, 237}: "Shinkawa Electric Co., Ltd.", + [3]byte{0, 3, 238}: "MKNet Corporation", + [3]byte{0, 3, 239}: "Oneline AG", + [3]byte{0, 3, 240}: "Redfern Broadband Networks", + [3]byte{0, 3, 241}: "Cicada Semiconductor, Inc.", + [3]byte{0, 3, 242}: "Seneca Networks", + [3]byte{0, 3, 243}: "Dazzle Multimedia, Inc.", + [3]byte{0, 3, 244}: "NetBurner", + [3]byte{0, 3, 245}: "Chip2Chip", + [3]byte{0, 3, 246}: "Allegro Networks, Inc.", + [3]byte{0, 3, 247}: "Plast-Control GmbH", + [3]byte{0, 3, 248}: "SanCastle Technologies, Inc.", + [3]byte{0, 3, 249}: "Pleiades Communications, Inc.", + [3]byte{0, 3, 250}: "TiMetra Networks", + [3]byte{0, 3, 251}: "ENEGATE Co.,Ltd.", + [3]byte{0, 3, 252}: "Intertex Data AB", + [3]byte{0, 3, 253}: "CISCO SYSTEMS, INC.", + [3]byte{0, 3, 254}: "CISCO SYSTEMS, INC.", + [3]byte{0, 3, 255}: "Microsoft Corporation", + [3]byte{0, 4, 0}: "LEXMARK INTERNATIONAL, INC.", + [3]byte{0, 4, 1}: "Osaki Electric Co., Ltd.", + [3]byte{0, 4, 2}: "Nexsan Technologies, Ltd.", + [3]byte{0, 4, 3}: "Nexsi Corporation", + [3]byte{0, 4, 4}: "Makino Milling Machine Co., Ltd.", + [3]byte{0, 4, 5}: "ACN Technologies", + [3]byte{0, 4, 6}: "Fa. Metabox AG", + [3]byte{0, 4, 7}: "Topcon Positioning Systems, Inc.", + [3]byte{0, 4, 8}: "Sanko Electronics Co., Ltd.", + [3]byte{0, 4, 9}: "Cratos Networks", + [3]byte{0, 4, 10}: "Sage Systems", + [3]byte{0, 4, 11}: "3com Europe Ltd.", + [3]byte{0, 4, 12}: "Kanno Works, Ltd.", + [3]byte{0, 4, 13}: "Avaya, Inc.", + [3]byte{0, 4, 14}: "AVM GmbH", + [3]byte{0, 4, 15}: "Asus Network Technologies, Inc.", + [3]byte{0, 4, 16}: "Spinnaker Networks, Inc.", + [3]byte{0, 4, 17}: "Inkra Networks, Inc.", + [3]byte{0, 4, 18}: "WaveSmith Networks, Inc.", + [3]byte{0, 4, 19}: "SNOM Technology AG", + [3]byte{0, 4, 20}: "Umezawa Musen Denki Co., Ltd.", + [3]byte{0, 4, 21}: "Rasteme Systems Co., Ltd.", + [3]byte{0, 4, 22}: "Parks S/A Comunicacoes Digitais", + [3]byte{0, 4, 23}: "ELAU AG", + [3]byte{0, 4, 24}: "Teltronic S.A.U.", + [3]byte{0, 4, 25}: "Fibercycle Networks, Inc.", + [3]byte{0, 4, 26}: "Ines Test and Measurement GmbH & CoKG", + [3]byte{0, 4, 27}: "Bridgeworks Ltd.", + [3]byte{0, 4, 28}: "ipDialog, Inc.", + [3]byte{0, 4, 29}: "Corega of America", + [3]byte{0, 4, 30}: "Shikoku Instrumentation Co., Ltd.", + [3]byte{0, 4, 31}: "Sony Computer Entertainment, Inc.", + [3]byte{0, 4, 32}: "Slim Devices, Inc.", + [3]byte{0, 4, 33}: "Ocular Networks", + [3]byte{0, 4, 34}: "Gordon Kapes, Inc.", + [3]byte{0, 4, 35}: "Intel Corporation", + [3]byte{0, 4, 36}: "TMC s.r.l.", + [3]byte{0, 4, 37}: "Atmel Corporation", + [3]byte{0, 4, 38}: "Autosys", + [3]byte{0, 4, 39}: "CISCO SYSTEMS, INC.", + [3]byte{0, 4, 40}: "CISCO SYSTEMS, INC.", + [3]byte{0, 4, 41}: "Pixord Corporation", + [3]byte{0, 4, 42}: "Wireless Networks, Inc.", + [3]byte{0, 4, 43}: "IT Access Co., Ltd.", + [3]byte{0, 4, 44}: "Minet, Inc.", + [3]byte{0, 4, 45}: "Sarian Systems, Ltd.", + [3]byte{0, 4, 46}: "Netous Technologies, Ltd.", + [3]byte{0, 4, 47}: "International Communications Products, Inc.", + [3]byte{0, 4, 48}: "Netgem", + [3]byte{0, 4, 49}: "GlobalStreams, Inc.", + [3]byte{0, 4, 50}: "Voyetra Turtle Beach, Inc.", + [3]byte{0, 4, 51}: "Cyberboard A/S", + [3]byte{0, 4, 52}: "Accelent Systems, Inc.", + [3]byte{0, 4, 53}: "Comptek International, Inc.", + [3]byte{0, 4, 54}: "ELANsat Technologies, Inc.", + [3]byte{0, 4, 55}: "Powin Information Technology, Inc.", + [3]byte{0, 4, 56}: "Nortel Networks", + [3]byte{0, 4, 57}: "Rosco Entertainment Technology, Inc.", + [3]byte{0, 4, 58}: "Intelligent Telecommunications, Inc.", + [3]byte{0, 4, 59}: "Lava Computer Mfg., Inc.", + [3]byte{0, 4, 60}: "SONOS Co., Ltd.", + [3]byte{0, 4, 61}: "INDEL AG", + [3]byte{0, 4, 62}: "Telencomm", + [3]byte{0, 4, 63}: "ESTeem Wireless Modems, Inc", + [3]byte{0, 4, 64}: "cyberPIXIE, Inc.", + [3]byte{0, 4, 65}: "Half Dome Systems, Inc.", + [3]byte{0, 4, 66}: "NACT", + [3]byte{0, 4, 67}: "Agilent Technologies, Inc.", + [3]byte{0, 4, 68}: "Western Multiplex Corporation", + [3]byte{0, 4, 69}: "LMS Skalar Instruments GmbH", + [3]byte{0, 4, 70}: "CYZENTECH Co., Ltd.", + [3]byte{0, 4, 71}: "Acrowave Systems Co., Ltd.", + [3]byte{0, 4, 72}: "Polaroid Corporation", + [3]byte{0, 4, 73}: "Mapletree Networks", + [3]byte{0, 4, 74}: "iPolicy Networks, Inc.", + [3]byte{0, 4, 75}: "NVIDIA", + [3]byte{0, 4, 76}: "JENOPTIK", + [3]byte{0, 4, 77}: "CISCO SYSTEMS, INC.", + [3]byte{0, 4, 78}: "CISCO SYSTEMS, INC.", + [3]byte{0, 4, 79}: "Leukhardt Systemelektronik GmbH", + [3]byte{0, 4, 80}: "DMD Computers SRL", + [3]byte{0, 4, 81}: "Medrad, Inc.", + [3]byte{0, 4, 82}: "RocketLogix, Inc.", + [3]byte{0, 4, 83}: "YottaYotta, Inc.", + [3]byte{0, 4, 84}: "Quadriga UK", + [3]byte{0, 4, 85}: "ANTARA.net", + [3]byte{0, 4, 86}: "Cambium Networks Limited", + [3]byte{0, 4, 87}: "Universal Access Technology, Inc.", + [3]byte{0, 4, 88}: "Fusion X Co., Ltd.", + [3]byte{0, 4, 89}: "Veristar Corporation", + [3]byte{0, 4, 90}: "The Linksys Group, Inc.", + [3]byte{0, 4, 91}: "Techsan Electronics Co., Ltd.", + [3]byte{0, 4, 92}: "Mobiwave Pte Ltd", + [3]byte{0, 4, 93}: "BEKA Elektronik", + [3]byte{0, 4, 94}: "PolyTrax Information Technology AG", + [3]byte{0, 4, 95}: "Avalue Technology, Inc.", + [3]byte{0, 4, 96}: "Knilink Technology, Inc.", + [3]byte{0, 4, 97}: "EPOX Computer Co., Ltd.", + [3]byte{0, 4, 98}: "DAKOS Data & Communication Co., Ltd.", + [3]byte{0, 4, 99}: "Bosch Security Systems", + [3]byte{0, 4, 100}: "Pulse-Link Inc", + [3]byte{0, 4, 101}: "i.s.t isdn-support technik GmbH", + [3]byte{0, 4, 102}: "ARMITEL Co.", + [3]byte{0, 4, 103}: "Wuhan Research Institute of MII", + [3]byte{0, 4, 104}: "Vivity, Inc.", + [3]byte{0, 4, 105}: "Innocom, Inc.", + [3]byte{0, 4, 106}: "Navini Networks", + [3]byte{0, 4, 107}: "Palm Wireless, Inc.", + [3]byte{0, 4, 108}: "Cyber Technology Co., Ltd.", + [3]byte{0, 4, 109}: "CISCO SYSTEMS, INC.", + [3]byte{0, 4, 110}: "CISCO SYSTEMS, INC.", + [3]byte{0, 4, 111}: "Digitel S/A Industria Eletronica", + [3]byte{0, 4, 112}: "ipUnplugged AB", + [3]byte{0, 4, 113}: "IPrad", + [3]byte{0, 4, 114}: "Telelynx, Inc.", + [3]byte{0, 4, 115}: "Photonex Corporation", + [3]byte{0, 4, 116}: "LEGRAND", + [3]byte{0, 4, 117}: "3 Com Corporation", + [3]byte{0, 4, 118}: "3 Com Corporation", + [3]byte{0, 4, 119}: "Scalant Systems, Inc.", + [3]byte{0, 4, 120}: "G. Star Technology Corporation", + [3]byte{0, 4, 121}: "Radius Co., Ltd.", + [3]byte{0, 4, 122}: "AXXESSIT ASA", + [3]byte{0, 4, 123}: "Schlumberger", + [3]byte{0, 4, 124}: "Skidata AG", + [3]byte{0, 4, 125}: "Pelco", + [3]byte{0, 4, 126}: "Siqura B.V.", + [3]byte{0, 4, 127}: "Chr. Mayr GmbH & Co. KG", + [3]byte{0, 4, 128}: "Brocade Communications Systems, Inc", + [3]byte{0, 4, 129}: "Econolite Control Products, Inc.", + [3]byte{0, 4, 130}: "Medialogic Corp.", + [3]byte{0, 4, 131}: "Deltron Technology, Inc.", + [3]byte{0, 4, 132}: "Amann GmbH", + [3]byte{0, 4, 133}: "PicoLight", + [3]byte{0, 4, 134}: "ITTC, University of Kansas", + [3]byte{0, 4, 135}: "Cogency Semiconductor, Inc.", + [3]byte{0, 4, 136}: "Eurotherm Controls", + [3]byte{0, 4, 137}: "YAFO Networks, Inc.", + [3]byte{0, 4, 138}: "Temia Vertriebs GmbH", + [3]byte{0, 4, 139}: "Poscon Corporation", + [3]byte{0, 4, 140}: "Nayna Networks, Inc.", + [3]byte{0, 4, 141}: "Tone Commander Systems, Inc.", + [3]byte{0, 4, 142}: "Ohm Tech Labs, Inc.", + [3]byte{0, 4, 143}: "TD Systems Corporation", + [3]byte{0, 4, 144}: "Optical Access", + [3]byte{0, 4, 145}: "Technovision, Inc.", + [3]byte{0, 4, 146}: "Hive Internet, Ltd.", + [3]byte{0, 4, 147}: "Tsinghua Unisplendour Co., Ltd.", + [3]byte{0, 4, 148}: "Breezecom, Ltd.", + [3]byte{0, 4, 149}: "Tejas Networks India Limited", + [3]byte{0, 4, 150}: "Extreme Networks", + [3]byte{0, 4, 151}: "MacroSystem Digital Video AG", + [3]byte{0, 4, 152}: "Mahi Networks", + [3]byte{0, 4, 153}: "Chino Corporation", + [3]byte{0, 4, 154}: "CISCO SYSTEMS, INC.", + [3]byte{0, 4, 155}: "CISCO SYSTEMS, INC.", + [3]byte{0, 4, 156}: "Surgient Networks, Inc.", + [3]byte{0, 4, 157}: "Ipanema Technologies", + [3]byte{0, 4, 158}: "Wirelink Co., Ltd.", + [3]byte{0, 4, 159}: "Freescale Semiconductor", + [3]byte{0, 4, 160}: "Verity Instruments, Inc.", + [3]byte{0, 4, 161}: "Pathway Connectivity", + [3]byte{0, 4, 162}: "L.S.I. Japan Co., Ltd.", + [3]byte{0, 4, 163}: "Microchip Technology, Inc.", + [3]byte{0, 4, 164}: "NetEnabled, Inc.", + [3]byte{0, 4, 165}: "Barco Projection Systems NV", + [3]byte{0, 4, 166}: "SAF Tehnika Ltd.", + [3]byte{0, 4, 167}: "FabiaTech Corporation", + [3]byte{0, 4, 168}: "Broadmax Technologies, Inc.", + [3]byte{0, 4, 169}: "SandStream Technologies, Inc.", + [3]byte{0, 4, 170}: "Jetstream Communications", + [3]byte{0, 4, 171}: "Comverse Network Systems, Inc.", + [3]byte{0, 4, 172}: "IBM Corp", + [3]byte{0, 4, 173}: "Malibu Networks", + [3]byte{0, 4, 174}: "Sullair Corporation", + [3]byte{0, 4, 175}: "Digital Fountain, Inc.", + [3]byte{0, 4, 176}: "ELESIGN Co., Ltd.", + [3]byte{0, 4, 177}: "Signal Technology, Inc.", + [3]byte{0, 4, 178}: "ESSEGI SRL", + [3]byte{0, 4, 179}: "Videotek, Inc.", + [3]byte{0, 4, 180}: "CIAC", + [3]byte{0, 4, 181}: "Equitrac Corporation", + [3]byte{0, 4, 182}: "Stratex Networks, Inc.", + [3]byte{0, 4, 183}: "AMB i.t. Holding", + [3]byte{0, 4, 184}: "Kumahira Co., Ltd.", + [3]byte{0, 4, 185}: "S.I. Soubou, Inc.", + [3]byte{0, 4, 186}: "KDD Media Will Corporation", + [3]byte{0, 4, 187}: "Bardac Corporation", + [3]byte{0, 4, 188}: "Giantec, Inc.", + [3]byte{0, 4, 189}: "ARRIS Group, Inc.", + [3]byte{0, 4, 190}: "OptXCon, Inc.", + [3]byte{0, 4, 191}: "VersaLogic Corp.", + [3]byte{0, 4, 192}: "CISCO SYSTEMS, INC.", + [3]byte{0, 4, 193}: "CISCO SYSTEMS, INC.", + [3]byte{0, 4, 194}: "Magnipix, Inc.", + [3]byte{0, 4, 195}: "CASTOR Informatique", + [3]byte{0, 4, 196}: "Allen & Heath Limited", + [3]byte{0, 4, 197}: "ASE Technologies, USA", + [3]byte{0, 4, 198}: "Yamaha Motor Co., Ltd.", + [3]byte{0, 4, 199}: "NetMount", + [3]byte{0, 4, 200}: "LIBA Maschinenfabrik GmbH", + [3]byte{0, 4, 201}: "Micro Electron Co., Ltd.", + [3]byte{0, 4, 202}: "FreeMs Corp.", + [3]byte{0, 4, 203}: "Tdsoft Communication, Ltd.", + [3]byte{0, 4, 204}: "Peek Traffic B.V.", + [3]byte{0, 4, 205}: "Extenway Solutions Inc", + [3]byte{0, 4, 206}: "Patria Ailon", + [3]byte{0, 4, 207}: "Seagate Technology", + [3]byte{0, 4, 208}: "Softlink s.r.o.", + [3]byte{0, 4, 209}: "Drew Technologies, Inc.", + [3]byte{0, 4, 210}: "Adcon Telemetry GmbH", + [3]byte{0, 4, 211}: "Toyokeiki Co., Ltd.", + [3]byte{0, 4, 212}: "Proview Electronics Co., Ltd.", + [3]byte{0, 4, 213}: "Hitachi Information & Communication Engineering, Ltd.", + [3]byte{0, 4, 214}: "Takagi Industrial Co., Ltd.", + [3]byte{0, 4, 215}: "Omitec Instrumentation Ltd.", + [3]byte{0, 4, 216}: "IPWireless, Inc.", + [3]byte{0, 4, 217}: "Titan Electronics, Inc.", + [3]byte{0, 4, 218}: "Relax Technology, Inc.", + [3]byte{0, 4, 219}: "Tellus Group Corp.", + [3]byte{0, 4, 220}: "Nortel Networks", + [3]byte{0, 4, 221}: "CISCO SYSTEMS, INC.", + [3]byte{0, 4, 222}: "CISCO SYSTEMS, INC.", + [3]byte{0, 4, 223}: "Teracom Telematica Ltda.", + [3]byte{0, 4, 224}: "Procket Networks", + [3]byte{0, 4, 225}: "Infinior Microsystems", + [3]byte{0, 4, 226}: "SMC Networks, Inc.", + [3]byte{0, 4, 227}: "Accton Technology Corp.", + [3]byte{0, 4, 228}: "Daeryung Ind., Inc.", + [3]byte{0, 4, 229}: "Glonet Systems, Inc.", + [3]byte{0, 4, 230}: "Banyan Network Private Limited", + [3]byte{0, 4, 231}: "Lightpointe Communications, Inc", + [3]byte{0, 4, 232}: "IER, Inc.", + [3]byte{0, 4, 233}: "Infiniswitch Corporation", + [3]byte{0, 4, 234}: "Hewlett-Packard Company", + [3]byte{0, 4, 235}: "Paxonet Communications, Inc.", + [3]byte{0, 4, 236}: "Memobox SA", + [3]byte{0, 4, 237}: "Billion Electric Co., Ltd.", + [3]byte{0, 4, 238}: "Lincoln Electric Company", + [3]byte{0, 4, 239}: "Polestar Corp.", + [3]byte{0, 4, 240}: "International Computers, Ltd", + [3]byte{0, 4, 241}: "WhereNet", + [3]byte{0, 4, 242}: "Polycom", + [3]byte{0, 4, 243}: "FS FORTH-SYSTEME GmbH", + [3]byte{0, 4, 244}: "Infinite Electronics Inc.", + [3]byte{0, 4, 245}: "SnowShore Networks, Inc.", + [3]byte{0, 4, 246}: "Amphus", + [3]byte{0, 4, 247}: "Omega Band, Inc.", + [3]byte{0, 4, 248}: "QUALICABLE TV Industria E Com., Ltda", + [3]byte{0, 4, 249}: "Xtera Communications, Inc.", + [3]byte{0, 4, 250}: "NBS Technologies Inc.", + [3]byte{0, 4, 251}: "Commtech, Inc.", + [3]byte{0, 4, 252}: "Stratus Computer (DE), Inc.", + [3]byte{0, 4, 253}: "Japan Control Engineering Co., Ltd.", + [3]byte{0, 4, 254}: "Pelago Networks", + [3]byte{0, 4, 255}: "Acronet Co., Ltd.", + [3]byte{0, 5, 0}: "CISCO SYSTEMS, INC.", + [3]byte{0, 5, 1}: "CISCO SYSTEMS, INC.", + [3]byte{0, 5, 2}: "Apple", + [3]byte{0, 5, 3}: "ICONAG", + [3]byte{0, 5, 4}: "Naray Information & Communication Enterprise", + [3]byte{0, 5, 5}: "Systems Integration Solutions, Inc.", + [3]byte{0, 5, 6}: "Reddo Networks AB", + [3]byte{0, 5, 7}: "Fine Appliance Corp.", + [3]byte{0, 5, 8}: "Inetcam, Inc.", + [3]byte{0, 5, 9}: "AVOC Nishimura Ltd.", + [3]byte{0, 5, 10}: "ICS Spa", + [3]byte{0, 5, 11}: "SICOM Systems, Inc.", + [3]byte{0, 5, 12}: "Network Photonics, Inc.", + [3]byte{0, 5, 13}: "Midstream Technologies, Inc.", + [3]byte{0, 5, 14}: "3ware, Inc.", + [3]byte{0, 5, 15}: "Tanaka S/S Ltd.", + [3]byte{0, 5, 16}: "Infinite Shanghai Communication Terminals Ltd.", + [3]byte{0, 5, 17}: "Complementary Technologies Ltd", + [3]byte{0, 5, 18}: "MeshNetworks, Inc.", + [3]byte{0, 5, 19}: "VTLinx Multimedia Systems, Inc.", + [3]byte{0, 5, 20}: "KDT Systems Co., Ltd.", + [3]byte{0, 5, 21}: "Nuark Co., Ltd.", + [3]byte{0, 5, 22}: "SMART Modular Technologies", + [3]byte{0, 5, 23}: "Shellcomm, Inc.", + [3]byte{0, 5, 24}: "Jupiters Technology", + [3]byte{0, 5, 25}: "Siemens Building Technologies AG,", + [3]byte{0, 5, 26}: "3Com Europe Ltd.", + [3]byte{0, 5, 27}: "Magic Control Technology Corporation", + [3]byte{0, 5, 28}: "Xnet Technology Corp.", + [3]byte{0, 5, 29}: "Airocon, Inc.", + [3]byte{0, 5, 30}: "Brocade Communications Systems, Inc.", + [3]byte{0, 5, 31}: "Taijin Media Co., Ltd.", + [3]byte{0, 5, 32}: "Smartronix, Inc.", + [3]byte{0, 5, 33}: "Control Microsystems", + [3]byte{0, 5, 34}: "LEA*D Corporation, Inc.", + [3]byte{0, 5, 35}: "AVL List GmbH", + [3]byte{0, 5, 36}: "BTL System (HK) Limited", + [3]byte{0, 5, 37}: "Puretek Industrial Co., Ltd.", + [3]byte{0, 5, 38}: "IPAS GmbH", + [3]byte{0, 5, 39}: "SJ Tek Co. Ltd", + [3]byte{0, 5, 40}: "New Focus, Inc.", + [3]byte{0, 5, 41}: "Shanghai Broadan Communication Technology Co., Ltd", + [3]byte{0, 5, 42}: "Ikegami Tsushinki Co., Ltd.", + [3]byte{0, 5, 43}: "HORIBA, Ltd.", + [3]byte{0, 5, 44}: "Supreme Magic Corporation", + [3]byte{0, 5, 45}: "Zoltrix International Limited", + [3]byte{0, 5, 46}: "Cinta Networks", + [3]byte{0, 5, 47}: "Leviton Network Solutions", + [3]byte{0, 5, 48}: "Andiamo Systems, Inc.", + [3]byte{0, 5, 49}: "CISCO SYSTEMS, INC.", + [3]byte{0, 5, 50}: "CISCO SYSTEMS, INC.", + [3]byte{0, 5, 51}: "Brocade Communications Systems, Inc.", + [3]byte{0, 5, 52}: "Northstar Engineering Ltd.", + [3]byte{0, 5, 53}: "Chip PC Ltd.", + [3]byte{0, 5, 54}: "Danam Communications, Inc.", + [3]byte{0, 5, 55}: "Nets Technology Co., Ltd.", + [3]byte{0, 5, 56}: "Merilus, Inc.", + [3]byte{0, 5, 57}: "A Brand New World in Sweden AB", + [3]byte{0, 5, 58}: "Willowglen Services Pte Ltd", + [3]byte{0, 5, 59}: "Harbour Networks Ltd., Co. Beijing", + [3]byte{0, 5, 60}: "Xircom", + [3]byte{0, 5, 61}: "Agere Systems", + [3]byte{0, 5, 62}: "KID Systeme GmbH", + [3]byte{0, 5, 63}: "VisionTek, Inc.", + [3]byte{0, 5, 64}: "FAST Corporation", + [3]byte{0, 5, 65}: "Advanced Systems Co., Ltd.", + [3]byte{0, 5, 66}: "Otari, Inc.", + [3]byte{0, 5, 67}: "IQ Wireless GmbH", + [3]byte{0, 5, 68}: "Valley Technologies, Inc.", + [3]byte{0, 5, 69}: "Internet Photonics", + [3]byte{0, 5, 70}: "KDDI Network & Solultions Inc.", + [3]byte{0, 5, 71}: "Starent Networks", + [3]byte{0, 5, 72}: "Disco Corporation", + [3]byte{0, 5, 73}: "Salira Optical Network Systems", + [3]byte{0, 5, 74}: "Ario Data Networks, Inc.", + [3]byte{0, 5, 75}: "Eaton Automation AG", + [3]byte{0, 5, 76}: "RF Innovations Pty Ltd", + [3]byte{0, 5, 77}: "Brans Technologies, Inc.", + [3]byte{0, 5, 78}: "Philips", + [3]byte{0, 5, 79}: "PRIVATE", + [3]byte{0, 5, 80}: "Vcomms Connect Limited", + [3]byte{0, 5, 81}: "F & S Elektronik Systeme GmbH", + [3]byte{0, 5, 82}: "Xycotec Computer GmbH", + [3]byte{0, 5, 83}: "DVC Company, Inc.", + [3]byte{0, 5, 84}: "Rangestar Wireless", + [3]byte{0, 5, 85}: "Japan Cash Machine Co., Ltd.", + [3]byte{0, 5, 86}: "360 Systems", + [3]byte{0, 5, 87}: "Agile TV Corporation", + [3]byte{0, 5, 88}: "Synchronous, Inc.", + [3]byte{0, 5, 89}: "Intracom S.A.", + [3]byte{0, 5, 90}: "Power Dsine Ltd.", + [3]byte{0, 5, 91}: "Charles Industries, Ltd.", + [3]byte{0, 5, 92}: "Kowa Company, Ltd.", + [3]byte{0, 5, 93}: "D-Link Systems, Inc.", + [3]byte{0, 5, 94}: "CISCO SYSTEMS, INC.", + [3]byte{0, 5, 95}: "CISCO SYSTEMS, INC.", + [3]byte{0, 5, 96}: "LEADER COMM.CO., LTD", + [3]byte{0, 5, 97}: "nac Image Technology, Inc.", + [3]byte{0, 5, 98}: "Digital View Limited", + [3]byte{0, 5, 99}: "J-Works, Inc.", + [3]byte{0, 5, 100}: "Tsinghua Bitway Co., Ltd.", + [3]byte{0, 5, 101}: "Tailyn Communication Company Ltd.", + [3]byte{0, 5, 102}: "Secui.com Corporation", + [3]byte{0, 5, 103}: "Etymonic Design, Inc.", + [3]byte{0, 5, 104}: "Piltofish Networks AB", + [3]byte{0, 5, 105}: "VMware, Inc.", + [3]byte{0, 5, 106}: "Heuft Systemtechnik GmbH", + [3]byte{0, 5, 107}: "C.P. Technology Co., Ltd.", + [3]byte{0, 5, 108}: "Hung Chang Co., Ltd.", + [3]byte{0, 5, 109}: "Pacific Corporation", + [3]byte{0, 5, 110}: "National Enhance Technology, Inc.", + [3]byte{0, 5, 111}: "Innomedia Technologies Pvt. Ltd.", + [3]byte{0, 5, 112}: "Baydel Ltd.", + [3]byte{0, 5, 113}: "Seiwa Electronics Co.", + [3]byte{0, 5, 114}: "Deonet Co., Ltd.", + [3]byte{0, 5, 115}: "CISCO SYSTEMS, INC.", + [3]byte{0, 5, 116}: "CISCO SYSTEMS, INC.", + [3]byte{0, 5, 117}: "CDS-Electronics BV", + [3]byte{0, 5, 118}: "NSM Technology Ltd.", + [3]byte{0, 5, 119}: "SM Information & Communication", + [3]byte{0, 5, 120}: "PRIVATE", + [3]byte{0, 5, 121}: "Universal Control Solution Corp.", + [3]byte{0, 5, 122}: "Overture Networks", + [3]byte{0, 5, 123}: "Chung Nam Electronic Co., Ltd.", + [3]byte{0, 5, 124}: "RCO Security AB", + [3]byte{0, 5, 125}: "Sun Communications, Inc.", + [3]byte{0, 5, 126}: "Eckelmann Steuerungstechnik GmbH", + [3]byte{0, 5, 127}: "Acqis Technology", + [3]byte{0, 5, 128}: "FibroLAN Ltd.", + [3]byte{0, 5, 129}: "Snell", + [3]byte{0, 5, 130}: "ClearCube Technology", + [3]byte{0, 5, 131}: "ImageCom Limited", + [3]byte{0, 5, 132}: "AbsoluteValue Systems, Inc.", + [3]byte{0, 5, 133}: "Juniper Networks, Inc.", + [3]byte{0, 5, 134}: "Lucent Technologies", + [3]byte{0, 5, 135}: "Locus, Incorporated", + [3]byte{0, 5, 136}: "Sensoria Corp.", + [3]byte{0, 5, 137}: "National Datacomputer", + [3]byte{0, 5, 138}: "Netcom Co., Ltd.", + [3]byte{0, 5, 139}: "IPmental, Inc.", + [3]byte{0, 5, 140}: "Opentech Inc.", + [3]byte{0, 5, 141}: "Lynx Photonic Networks, Inc.", + [3]byte{0, 5, 142}: "Flextronics International GmbH & Co. Nfg. KG", + [3]byte{0, 5, 143}: "CLCsoft co.", + [3]byte{0, 5, 144}: "Swissvoice Ltd.", + [3]byte{0, 5, 145}: "Active Silicon Ltd", + [3]byte{0, 5, 146}: "Pultek Corp.", + [3]byte{0, 5, 147}: "Grammar Engine Inc.", + [3]byte{0, 5, 148}: "IXXAT Automation GmbH", + [3]byte{0, 5, 149}: "Alesis Corporation", + [3]byte{0, 5, 150}: "Genotech Co., Ltd.", + [3]byte{0, 5, 151}: "Eagle Traffic Control Systems", + [3]byte{0, 5, 152}: "CRONOS S.r.l.", + [3]byte{0, 5, 153}: "DRS Test and Energy Management or DRS-TEM", + [3]byte{0, 5, 154}: "CISCO SYSTEMS, INC.", + [3]byte{0, 5, 155}: "CISCO SYSTEMS, INC.", + [3]byte{0, 5, 156}: "Kleinknecht GmbH, Ing. Büro", + [3]byte{0, 5, 157}: "Daniel Computing Systems, Inc.", + [3]byte{0, 5, 158}: "Zinwell Corporation", + [3]byte{0, 5, 159}: "Yotta Networks, Inc.", + [3]byte{0, 5, 160}: "MOBILINE Kft.", + [3]byte{0, 5, 161}: "Zenocom", + [3]byte{0, 5, 162}: "CELOX Networks", + [3]byte{0, 5, 163}: "QEI, Inc.", + [3]byte{0, 5, 164}: "Lucid Voice Ltd.", + [3]byte{0, 5, 165}: "KOTT", + [3]byte{0, 5, 166}: "Extron Electronics", + [3]byte{0, 5, 167}: "Hyperchip, Inc.", + [3]byte{0, 5, 168}: "WYLE ELECTRONICS", + [3]byte{0, 5, 169}: "Princeton Networks, Inc.", + [3]byte{0, 5, 170}: "Moore Industries International Inc.", + [3]byte{0, 5, 171}: "Cyber Fone, Inc.", + [3]byte{0, 5, 172}: "Northern Digital, Inc.", + [3]byte{0, 5, 173}: "Topspin Communications, Inc.", + [3]byte{0, 5, 174}: "Mediaport USA", + [3]byte{0, 5, 175}: "InnoScan Computing A/S", + [3]byte{0, 5, 176}: "Korea Computer Technology Co., Ltd.", + [3]byte{0, 5, 177}: "ASB Technology BV", + [3]byte{0, 5, 178}: "Medison Co., Ltd.", + [3]byte{0, 5, 179}: "Asahi-Engineering Co., Ltd.", + [3]byte{0, 5, 180}: "Aceex Corporation", + [3]byte{0, 5, 181}: "Broadcom Technologies", + [3]byte{0, 5, 182}: "INSYS Microelectronics GmbH", + [3]byte{0, 5, 183}: "Arbor Technology Corp.", + [3]byte{0, 5, 184}: "Electronic Design Associates, Inc.", + [3]byte{0, 5, 185}: "Airvana, Inc.", + [3]byte{0, 5, 186}: "Area Netwoeks, Inc.", + [3]byte{0, 5, 187}: "Myspace AB", + [3]byte{0, 5, 188}: "Resource Data Management Ltd", + [3]byte{0, 5, 189}: "ROAX BV", + [3]byte{0, 5, 190}: "Kongsberg Seatex AS", + [3]byte{0, 5, 191}: "JustEzy Technology, Inc.", + [3]byte{0, 5, 192}: "Digital Network Alacarte Co., Ltd.", + [3]byte{0, 5, 193}: "A-Kyung Motion, Inc.", + [3]byte{0, 5, 194}: "Soronti, Inc.", + [3]byte{0, 5, 195}: "Pacific Instruments, Inc.", + [3]byte{0, 5, 196}: "Telect, Inc.", + [3]byte{0, 5, 197}: "Flaga HF", + [3]byte{0, 5, 198}: "Triz Communications", + [3]byte{0, 5, 199}: "I/F-COM A/S", + [3]byte{0, 5, 200}: "VERYTECH", + [3]byte{0, 5, 201}: "LG Innotek Co., Ltd.", + [3]byte{0, 5, 202}: "Hitron Technology, Inc.", + [3]byte{0, 5, 203}: "ROIS Technologies, Inc.", + [3]byte{0, 5, 204}: "Sumtel Communications, Inc.", + [3]byte{0, 5, 205}: "Denon, Ltd.", + [3]byte{0, 5, 206}: "Prolink Microsystems Corporation", + [3]byte{0, 5, 207}: "Thunder River Technologies, Inc.", + [3]byte{0, 5, 208}: "Solinet Systems", + [3]byte{0, 5, 209}: "Metavector Technologies", + [3]byte{0, 5, 210}: "DAP Technologies", + [3]byte{0, 5, 211}: "eProduction Solutions, Inc.", + [3]byte{0, 5, 212}: "FutureSmart Networks, Inc.", + [3]byte{0, 5, 213}: "Speedcom Wireless", + [3]byte{0, 5, 214}: "L-3 Linkabit", + [3]byte{0, 5, 215}: "Vista Imaging, Inc.", + [3]byte{0, 5, 216}: "Arescom, Inc.", + [3]byte{0, 5, 217}: "Techno Valley, Inc.", + [3]byte{0, 5, 218}: "Apex Automationstechnik", + [3]byte{0, 5, 219}: "PSI Nentec GmbH", + [3]byte{0, 5, 220}: "CISCO SYSTEMS, INC.", + [3]byte{0, 5, 221}: "CISCO SYSTEMS, INC.", + [3]byte{0, 5, 222}: "Gi Fone Korea, Inc.", + [3]byte{0, 5, 223}: "Electronic Innovation, Inc.", + [3]byte{0, 5, 224}: "Empirix Corp.", + [3]byte{0, 5, 225}: "Trellis Photonics, Ltd.", + [3]byte{0, 5, 226}: "Creativ Network Technologies", + [3]byte{0, 5, 227}: "LightSand Communications, Inc.", + [3]byte{0, 5, 228}: "Red Lion Controls Inc.", + [3]byte{0, 5, 229}: "Renishaw PLC", + [3]byte{0, 5, 230}: "Egenera, Inc.", + [3]byte{0, 5, 231}: "Netrake an AudioCodes Company", + [3]byte{0, 5, 232}: "TurboWave, Inc.", + [3]byte{0, 5, 233}: "Unicess Network, Inc.", + [3]byte{0, 5, 234}: "Rednix", + [3]byte{0, 5, 235}: "Blue Ridge Networks, Inc.", + [3]byte{0, 5, 236}: "Mosaic Systems Inc.", + [3]byte{0, 5, 237}: "Technikum Joanneum GmbH", + [3]byte{0, 5, 238}: "Siemens AB, Infrastructure & Cities, Building Technologies Division, IC BT SSP SP BA PR", + [3]byte{0, 5, 239}: "ADOIR Digital Technology", + [3]byte{0, 5, 240}: "SATEC", + [3]byte{0, 5, 241}: "Vrcom, Inc.", + [3]byte{0, 5, 242}: "Power R, Inc.", + [3]byte{0, 5, 243}: "Webyn", + [3]byte{0, 5, 244}: "System Base Co., Ltd.", + [3]byte{0, 5, 245}: "Geospace Technologies", + [3]byte{0, 5, 246}: "Young Chang Co. Ltd.", + [3]byte{0, 5, 247}: "Analog Devices, Inc.", + [3]byte{0, 5, 248}: "Real Time Access, Inc.", + [3]byte{0, 5, 249}: "TOA Corporation", + [3]byte{0, 5, 250}: "IPOptical, Inc.", + [3]byte{0, 5, 251}: "ShareGate, Inc.", + [3]byte{0, 5, 252}: "Schenck Pegasus Corp.", + [3]byte{0, 5, 253}: "PacketLight Networks Ltd.", + [3]byte{0, 5, 254}: "Traficon N.V.", + [3]byte{0, 5, 255}: "SNS Solutions, Inc.", + [3]byte{0, 6, 0}: "Toshiba Teli Corporation", + [3]byte{0, 6, 1}: "Otanikeiki Co., Ltd.", + [3]byte{0, 6, 2}: "Cirkitech Electronics Co.", + [3]byte{0, 6, 3}: "Baker Hughes Inc.", + [3]byte{0, 6, 4}: "@Track Communications, Inc.", + [3]byte{0, 6, 5}: "Inncom International, Inc.", + [3]byte{0, 6, 6}: "RapidWAN, Inc.", + [3]byte{0, 6, 7}: "Omni Directional Control Technology Inc.", + [3]byte{0, 6, 8}: "At-Sky SAS", + [3]byte{0, 6, 9}: "Crossport Systems", + [3]byte{0, 6, 10}: "Blue2space", + [3]byte{0, 6, 11}: "Artesyn Embedded Technologies", + [3]byte{0, 6, 12}: "Melco Industries, Inc.", + [3]byte{0, 6, 13}: "Wave7 Optics", + [3]byte{0, 6, 14}: "IGYS Systems, Inc.", + [3]byte{0, 6, 15}: "Narad Networks Inc", + [3]byte{0, 6, 16}: "Abeona Networks Inc", + [3]byte{0, 6, 17}: "Zeus Wireless, Inc.", + [3]byte{0, 6, 18}: "Accusys, Inc.", + [3]byte{0, 6, 19}: "Kawasaki Microelectronics Incorporated", + [3]byte{0, 6, 20}: "Prism Holdings", + [3]byte{0, 6, 21}: "Kimoto Electric Co., Ltd.", + [3]byte{0, 6, 22}: "Tel Net Co., Ltd.", + [3]byte{0, 6, 23}: "Redswitch Inc.", + [3]byte{0, 6, 24}: "DigiPower Manufacturing Inc.", + [3]byte{0, 6, 25}: "Connection Technology Systems", + [3]byte{0, 6, 26}: "Zetari Inc.", + [3]byte{0, 6, 27}: "Notebook Development Lab. Lenovo Japan Ltd.", + [3]byte{0, 6, 28}: "Hoshino Metal Industries, Ltd.", + [3]byte{0, 6, 29}: "MIP Telecom, Inc.", + [3]byte{0, 6, 30}: "Maxan Systems", + [3]byte{0, 6, 31}: "Vision Components GmbH", + [3]byte{0, 6, 32}: "Serial System Ltd.", + [3]byte{0, 6, 33}: "Hinox, Co., Ltd.", + [3]byte{0, 6, 34}: "Chung Fu Chen Yeh Enterprise Corp.", + [3]byte{0, 6, 35}: "MGE UPS Systems France", + [3]byte{0, 6, 36}: "Gentner Communications Corp.", + [3]byte{0, 6, 37}: "The Linksys Group, Inc.", + [3]byte{0, 6, 38}: "MWE GmbH", + [3]byte{0, 6, 39}: "Uniwide Technologies, Inc.", + [3]byte{0, 6, 40}: "CISCO SYSTEMS, INC.", + [3]byte{0, 6, 41}: "IBM Corp", + [3]byte{0, 6, 42}: "CISCO SYSTEMS, INC.", + [3]byte{0, 6, 43}: "INTRASERVER TECHNOLOGY", + [3]byte{0, 6, 44}: "Bivio Networks", + [3]byte{0, 6, 45}: "TouchStar Technologies, L.L.C.", + [3]byte{0, 6, 46}: "Aristos Logic Corp.", + [3]byte{0, 6, 47}: "Pivotech Systems Inc.", + [3]byte{0, 6, 48}: "Adtranz Sweden", + [3]byte{0, 6, 49}: "Calix", + [3]byte{0, 6, 50}: "Mesco Engineering GmbH", + [3]byte{0, 6, 51}: "Cross Match Technologies GmbH", + [3]byte{0, 6, 52}: "GTE Airfone Inc.", + [3]byte{0, 6, 53}: "PacketAir Networks, Inc.", + [3]byte{0, 6, 54}: "Jedai Broadband Networks", + [3]byte{0, 6, 55}: "Toptrend-Meta Information (ShenZhen) Inc.", + [3]byte{0, 6, 56}: "Sungjin C&C Co., Ltd.", + [3]byte{0, 6, 57}: "Newtec", + [3]byte{0, 6, 58}: "Dura Micro, Inc.", + [3]byte{0, 6, 59}: "Arcturus Networks Inc.", + [3]byte{0, 6, 60}: "Intrinsyc Software International Inc.", + [3]byte{0, 6, 61}: "Microwave Data Systems Inc.", + [3]byte{0, 6, 62}: "Opthos Inc.", + [3]byte{0, 6, 63}: "Everex Communications Inc.", + [3]byte{0, 6, 64}: "White Rock Networks", + [3]byte{0, 6, 65}: "ITCN", + [3]byte{0, 6, 66}: "Genetel Systems Inc.", + [3]byte{0, 6, 67}: "SONO Computer Co., Ltd.", + [3]byte{0, 6, 68}: "Neix,Inc", + [3]byte{0, 6, 69}: "Meisei Electric Co. Ltd.", + [3]byte{0, 6, 70}: "ShenZhen XunBao Network Technology Co Ltd", + [3]byte{0, 6, 71}: "Etrali S.A.", + [3]byte{0, 6, 72}: "Seedsware, Inc.", + [3]byte{0, 6, 73}: "3M Deutschland GmbH", + [3]byte{0, 6, 74}: "Honeywell Co., Ltd. (KOREA)", + [3]byte{0, 6, 75}: "Alexon Co., Ltd.", + [3]byte{0, 6, 76}: "Invicta Networks, Inc.", + [3]byte{0, 6, 77}: "Sencore", + [3]byte{0, 6, 78}: "Broad Net Technology Inc.", + [3]byte{0, 6, 79}: "PRO-NETS Technology Corporation", + [3]byte{0, 6, 80}: "Tiburon Networks, Inc.", + [3]byte{0, 6, 81}: "Aspen Networks Inc.", + [3]byte{0, 6, 82}: "CISCO SYSTEMS, INC.", + [3]byte{0, 6, 83}: "CISCO SYSTEMS, INC.", + [3]byte{0, 6, 84}: "Winpresa Building Automation Technologies GmbH", + [3]byte{0, 6, 85}: "Yipee, Inc.", + [3]byte{0, 6, 86}: "Tactel AB", + [3]byte{0, 6, 87}: "Market Central, Inc.", + [3]byte{0, 6, 88}: "Helmut Fischer GmbH Institut für Elektronik und Messtechnik", + [3]byte{0, 6, 89}: "EAL (Apeldoorn) B.V.", + [3]byte{0, 6, 90}: "Strix Systems", + [3]byte{0, 6, 91}: "Dell Computer Corp.", + [3]byte{0, 6, 92}: "Malachite Technologies, Inc.", + [3]byte{0, 6, 93}: "Heidelberg Web Systems", + [3]byte{0, 6, 94}: "Photuris, Inc.", + [3]byte{0, 6, 95}: "ECI Telecom - NGTS Ltd.", + [3]byte{0, 6, 96}: "NADEX Co., Ltd.", + [3]byte{0, 6, 97}: "NIA Home Technologies Corp.", + [3]byte{0, 6, 98}: "MBM Technology Ltd.", + [3]byte{0, 6, 99}: "Human Technology Co., Ltd.", + [3]byte{0, 6, 100}: "Fostex Corporation", + [3]byte{0, 6, 101}: "Sunny Giken, Inc.", + [3]byte{0, 6, 102}: "Roving Networks", + [3]byte{0, 6, 103}: "Tripp Lite", + [3]byte{0, 6, 104}: "Vicon Industries Inc.", + [3]byte{0, 6, 105}: "Datasound Laboratories Ltd", + [3]byte{0, 6, 106}: "InfiniCon Systems, Inc.", + [3]byte{0, 6, 107}: "Sysmex Corporation", + [3]byte{0, 6, 108}: "Robinson Corporation", + [3]byte{0, 6, 109}: "Compuprint S.P.A.", + [3]byte{0, 6, 110}: "Delta Electronics, Inc.", + [3]byte{0, 6, 111}: "Korea Data Systems", + [3]byte{0, 6, 112}: "Upponetti Oy", + [3]byte{0, 6, 113}: "Softing AG", + [3]byte{0, 6, 114}: "Netezza", + [3]byte{0, 6, 115}: "TKH Security Solutions USA", + [3]byte{0, 6, 116}: "Spectrum Control, Inc.", + [3]byte{0, 6, 117}: "Banderacom, Inc.", + [3]byte{0, 6, 118}: "Novra Technologies Inc.", + [3]byte{0, 6, 119}: "SICK AG", + [3]byte{0, 6, 120}: "Marantz Brand Company", + [3]byte{0, 6, 121}: "Konami Corporation", + [3]byte{0, 6, 122}: "JMP Systems", + [3]byte{0, 6, 123}: "Toplink C&C Corporation", + [3]byte{0, 6, 124}: "CISCO SYSTEMS, INC.", + [3]byte{0, 6, 125}: "Takasago Ltd.", + [3]byte{0, 6, 126}: "WinCom Systems, Inc.", + [3]byte{0, 6, 127}: "Digeo, Inc.", + [3]byte{0, 6, 128}: "Card Access, Inc.", + [3]byte{0, 6, 129}: "Goepel Electronic GmbH", + [3]byte{0, 6, 130}: "Convedia", + [3]byte{0, 6, 131}: "Bravara Communications, Inc.", + [3]byte{0, 6, 132}: "Biacore AB", + [3]byte{0, 6, 133}: "NetNearU Corporation", + [3]byte{0, 6, 134}: "ZARDCOM Co., Ltd.", + [3]byte{0, 6, 135}: "Omnitron Systems Technology, Inc.", + [3]byte{0, 6, 136}: "Telways Communication Co., Ltd.", + [3]byte{0, 6, 137}: "yLez Technologies Pte Ltd", + [3]byte{0, 6, 138}: "NeuronNet Co. Ltd. R&D Center", + [3]byte{0, 6, 139}: "AirRunner Technologies, Inc.", + [3]byte{0, 6, 140}: "3Com Corporation", + [3]byte{0, 6, 141}: "SEPATON, Inc.", + [3]byte{0, 6, 142}: "HID Corporation", + [3]byte{0, 6, 143}: "Telemonitor, Inc.", + [3]byte{0, 6, 144}: "Euracom Communication GmbH", + [3]byte{0, 6, 145}: "PT Inovacao", + [3]byte{0, 6, 146}: "Intruvert Networks, Inc.", + [3]byte{0, 6, 147}: "Flexus Computer Technology, Inc.", + [3]byte{0, 6, 148}: "Mobillian Corporation", + [3]byte{0, 6, 149}: "Ensure Technologies, Inc.", + [3]byte{0, 6, 150}: "Advent Networks", + [3]byte{0, 6, 151}: "R & D Center", + [3]byte{0, 6, 152}: "egnite GmbH", + [3]byte{0, 6, 153}: "Vida Design Co.", + [3]byte{0, 6, 154}: "e & Tel", + [3]byte{0, 6, 155}: "AVT Audio Video Technologies GmbH", + [3]byte{0, 6, 156}: "Transmode Systems AB", + [3]byte{0, 6, 157}: "Petards Ltd", + [3]byte{0, 6, 158}: "UNIQA, Inc.", + [3]byte{0, 6, 159}: "Kuokoa Networks", + [3]byte{0, 6, 160}: "Mx Imaging", + [3]byte{0, 6, 161}: "Celsian Technologies, Inc.", + [3]byte{0, 6, 162}: "Microtune, Inc.", + [3]byte{0, 6, 163}: "Bitran Corporation", + [3]byte{0, 6, 164}: "INNOWELL Corp.", + [3]byte{0, 6, 165}: "PINON Corp.", + [3]byte{0, 6, 166}: "Artistic Licence Engineering Ltd", + [3]byte{0, 6, 167}: "Primarion", + [3]byte{0, 6, 168}: "KC Technology, Inc.", + [3]byte{0, 6, 169}: "Universal Instruments Corp.", + [3]byte{0, 6, 170}: "VT Miltope", + [3]byte{0, 6, 171}: "W-Link Systems, Inc.", + [3]byte{0, 6, 172}: "Intersoft Co.", + [3]byte{0, 6, 173}: "KB Electronics Ltd.", + [3]byte{0, 6, 174}: "Himachal Futuristic Communications Ltd", + [3]byte{0, 6, 175}: "Xalted Networks", + [3]byte{0, 6, 176}: "Comtech EF Data Corp.", + [3]byte{0, 6, 177}: "Sonicwall", + [3]byte{0, 6, 178}: "Linxtek Co.", + [3]byte{0, 6, 179}: "Diagraph Corporation", + [3]byte{0, 6, 180}: "Vorne Industries, Inc.", + [3]byte{0, 6, 181}: "Source Photonics, Inc.", + [3]byte{0, 6, 182}: "Nir-Or Israel Ltd.", + [3]byte{0, 6, 183}: "TELEM GmbH", + [3]byte{0, 6, 184}: "Bandspeed Pty Ltd", + [3]byte{0, 6, 185}: "A5TEK Corp.", + [3]byte{0, 6, 186}: "Westwave Communications", + [3]byte{0, 6, 187}: "ATI Technologies Inc.", + [3]byte{0, 6, 188}: "Macrolink, Inc.", + [3]byte{0, 6, 189}: "BNTECHNOLOGY Co., Ltd.", + [3]byte{0, 6, 190}: "Baumer Optronic GmbH", + [3]byte{0, 6, 191}: "Accella Technologies Co., Ltd.", + [3]byte{0, 6, 192}: "United Internetworks, Inc.", + [3]byte{0, 6, 193}: "CISCO SYSTEMS, INC.", + [3]byte{0, 6, 194}: "Smartmatic Corporation", + [3]byte{0, 6, 195}: "Schindler Elevator Ltd.", + [3]byte{0, 6, 196}: "Piolink Inc.", + [3]byte{0, 6, 197}: "INNOVI Technologies Limited", + [3]byte{0, 6, 198}: "lesswire AG", + [3]byte{0, 6, 199}: "RFNET Technologies Pte Ltd (S)", + [3]byte{0, 6, 200}: "Sumitomo Metal Micro Devices, Inc.", + [3]byte{0, 6, 201}: "Technical Marketing Research, Inc.", + [3]byte{0, 6, 202}: "American Computer & Digital Components, Inc. (ACDC)", + [3]byte{0, 6, 203}: "Jotron Electronics A/S", + [3]byte{0, 6, 204}: "JMI Electronics Co., Ltd.", + [3]byte{0, 6, 205}: "Leaf Imaging Ltd.", + [3]byte{0, 6, 206}: "DATENO", + [3]byte{0, 6, 207}: "Thales Avionics In-Flight Systems, LLC", + [3]byte{0, 6, 208}: "Elgar Electronics Corp.", + [3]byte{0, 6, 209}: "Tahoe Networks, Inc.", + [3]byte{0, 6, 210}: "Tundra Semiconductor Corp.", + [3]byte{0, 6, 211}: "Alpha Telecom, Inc. U.S.A.", + [3]byte{0, 6, 212}: "Interactive Objects, Inc.", + [3]byte{0, 6, 213}: "Diamond Systems Corp.", + [3]byte{0, 6, 214}: "CISCO SYSTEMS, INC.", + [3]byte{0, 6, 215}: "CISCO SYSTEMS, INC.", + [3]byte{0, 6, 216}: "Maple Optical Systems", + [3]byte{0, 6, 217}: "IPM-Net S.p.A.", + [3]byte{0, 6, 218}: "ITRAN Communications Ltd.", + [3]byte{0, 6, 219}: "ICHIPS Co., Ltd.", + [3]byte{0, 6, 220}: "Syabas Technology (Amquest)", + [3]byte{0, 6, 221}: "AT & T Laboratories - Cambridge Ltd", + [3]byte{0, 6, 222}: "Flash Technology", + [3]byte{0, 6, 223}: "AIDONIC Corporation", + [3]byte{0, 6, 224}: "MAT Co., Ltd.", + [3]byte{0, 6, 225}: "Techno Trade s.a", + [3]byte{0, 6, 226}: "Ceemax Technology Co., Ltd.", + [3]byte{0, 6, 227}: "Quantitative Imaging Corporation", + [3]byte{0, 6, 228}: "Citel Technologies Ltd.", + [3]byte{0, 6, 229}: "Fujian Newland Computer Ltd. Co.", + [3]byte{0, 6, 230}: "DongYang Telecom Co., Ltd.", + [3]byte{0, 6, 231}: "Bit Blitz Communications Inc.", + [3]byte{0, 6, 232}: "Optical Network Testing, Inc.", + [3]byte{0, 6, 233}: "Intime Corp.", + [3]byte{0, 6, 234}: "ELZET80 Mikrocomputer GmbH&Co. KG", + [3]byte{0, 6, 235}: "Global Data", + [3]byte{0, 6, 236}: "Harris Corporation", + [3]byte{0, 6, 237}: "Inara Networks", + [3]byte{0, 6, 238}: "Shenyang Neu-era Information & Technology Stock Co., Ltd", + [3]byte{0, 6, 239}: "Maxxan Systems, Inc.", + [3]byte{0, 6, 240}: "Digeo, Inc.", + [3]byte{0, 6, 241}: "Optillion", + [3]byte{0, 6, 242}: "Platys Communications", + [3]byte{0, 6, 243}: "AcceLight Networks", + [3]byte{0, 6, 244}: "Prime Electronics & Satellitics Inc.", + [3]byte{0, 6, 245}: "ALPS Co,. Ltd.", + [3]byte{0, 6, 246}: "CISCO SYSTEMS, INC.", + [3]byte{0, 6, 247}: "ALPS Co,. Ltd.", + [3]byte{0, 6, 248}: "The Boeing Company", + [3]byte{0, 6, 249}: "Mitsui Zosen Systems Research Inc.", + [3]byte{0, 6, 250}: "IP SQUARE Co, Ltd.", + [3]byte{0, 6, 251}: "Hitachi Printing Solutions, Ltd.", + [3]byte{0, 6, 252}: "Fnet Co., Ltd.", + [3]byte{0, 6, 253}: "Comjet Information Systems Corp.", + [3]byte{0, 6, 254}: "Ambrado, Inc", + [3]byte{0, 6, 255}: "Sheba Systems Co., Ltd.", + [3]byte{0, 7, 0}: "Zettamedia Korea", + [3]byte{0, 7, 1}: "RACAL-DATACOM", + [3]byte{0, 7, 2}: "Varian Medical Systems", + [3]byte{0, 7, 3}: "CSEE Transport", + [3]byte{0, 7, 4}: "ALPS Co,. Ltd.", + [3]byte{0, 7, 5}: "Endress & Hauser GmbH & Co", + [3]byte{0, 7, 6}: "Sanritz Corporation", + [3]byte{0, 7, 7}: "Interalia Inc.", + [3]byte{0, 7, 8}: "Bitrage Inc.", + [3]byte{0, 7, 9}: "Westerstrand Urfabrik AB", + [3]byte{0, 7, 10}: "Unicom Automation Co., Ltd.", + [3]byte{0, 7, 11}: "Novabase SGPS, SA", + [3]byte{0, 7, 12}: "SVA-Intrusion.com Co. Ltd.", + [3]byte{0, 7, 13}: "CISCO SYSTEMS, INC.", + [3]byte{0, 7, 14}: "CISCO SYSTEMS, INC.", + [3]byte{0, 7, 15}: "Fujant, Inc.", + [3]byte{0, 7, 16}: "Adax, Inc.", + [3]byte{0, 7, 17}: "Acterna", + [3]byte{0, 7, 18}: "JAL Information Technology", + [3]byte{0, 7, 19}: "IP One, Inc.", + [3]byte{0, 7, 20}: "Brightcom", + [3]byte{0, 7, 21}: "General Research of Electronics, Inc.", + [3]byte{0, 7, 22}: "J & S Marine Ltd.", + [3]byte{0, 7, 23}: "Wieland Electric GmbH", + [3]byte{0, 7, 24}: "iCanTek Co., Ltd.", + [3]byte{0, 7, 25}: "Mobiis Co., Ltd.", + [3]byte{0, 7, 26}: "Finedigital Inc.", + [3]byte{0, 7, 27}: "CDVI Americas Ltd", + [3]byte{0, 7, 28}: "AT&T Fixed Wireless Services", + [3]byte{0, 7, 29}: "Satelsa Sistemas Y Aplicaciones De Telecomunicaciones, S.A.", + [3]byte{0, 7, 30}: "Tri-M Engineering / Nupak Dev. Corp.", + [3]byte{0, 7, 31}: "European Systems Integration", + [3]byte{0, 7, 32}: "Trutzschler GmbH & Co. KG", + [3]byte{0, 7, 33}: "Formac Elektronik GmbH", + [3]byte{0, 7, 34}: "The Nielsen Company", + [3]byte{0, 7, 35}: "ELCON Systemtechnik GmbH", + [3]byte{0, 7, 36}: "Telemax Co., Ltd.", + [3]byte{0, 7, 37}: "Bematech International Corp.", + [3]byte{0, 7, 38}: "Shenzhen Gongjin Electronics Co., Ltd.", + [3]byte{0, 7, 39}: "Zi Corporation (HK) Ltd.", + [3]byte{0, 7, 40}: "Neo Telecom", + [3]byte{0, 7, 41}: "Kistler Instrumente AG", + [3]byte{0, 7, 42}: "Innovance Networks", + [3]byte{0, 7, 43}: "Jung Myung Telecom Co., Ltd.", + [3]byte{0, 7, 44}: "Fabricom", + [3]byte{0, 7, 45}: "CNSystems", + [3]byte{0, 7, 46}: "North Node AB", + [3]byte{0, 7, 47}: "Intransa, Inc.", + [3]byte{0, 7, 48}: "Hutchison OPTEL Telecom Technology Co., Ltd.", + [3]byte{0, 7, 49}: "Ophir-Spiricon LLC", + [3]byte{0, 7, 50}: "AAEON Technology Inc.", + [3]byte{0, 7, 51}: "DANCONTROL Engineering", + [3]byte{0, 7, 52}: "ONStor, Inc.", + [3]byte{0, 7, 53}: "Flarion Technologies, Inc.", + [3]byte{0, 7, 54}: "Data Video Technologies Co., Ltd.", + [3]byte{0, 7, 55}: "Soriya Co. Ltd.", + [3]byte{0, 7, 56}: "Young Technology Co., Ltd.", + [3]byte{0, 7, 57}: "Scotty Group Austria Gmbh", + [3]byte{0, 7, 58}: "Inventel Systemes", + [3]byte{0, 7, 59}: "Tenovis GmbH & Co KG", + [3]byte{0, 7, 60}: "Telecom Design", + [3]byte{0, 7, 61}: "Nanjing Postel Telecommunications Co., Ltd.", + [3]byte{0, 7, 62}: "China Great-Wall Computer Shenzhen Co., Ltd.", + [3]byte{0, 7, 63}: "Woojyun Systec Co., Ltd.", + [3]byte{0, 7, 64}: "Buffalo Inc.", + [3]byte{0, 7, 65}: "Sierra Automated Systems", + [3]byte{0, 7, 66}: "Current Technologies, LLC", + [3]byte{0, 7, 67}: "Chelsio Communications", + [3]byte{0, 7, 68}: "Unico, Inc.", + [3]byte{0, 7, 69}: "Radlan Computer Communications Ltd.", + [3]byte{0, 7, 70}: "TURCK, Inc.", + [3]byte{0, 7, 71}: "Mecalc", + [3]byte{0, 7, 72}: "The Imaging Source Europe", + [3]byte{0, 7, 73}: "CENiX Inc.", + [3]byte{0, 7, 74}: "Carl Valentin GmbH", + [3]byte{0, 7, 75}: "Daihen Corporation", + [3]byte{0, 7, 76}: "Beicom Inc.", + [3]byte{0, 7, 77}: "Zebra Technologies Corp.", + [3]byte{0, 7, 78}: "IPFRONT Inc", + [3]byte{0, 7, 79}: "CISCO SYSTEMS, INC.", + [3]byte{0, 7, 80}: "CISCO SYSTEMS, INC.", + [3]byte{0, 7, 81}: "m-u-t AG", + [3]byte{0, 7, 82}: "Rhythm Watch Co., Ltd.", + [3]byte{0, 7, 83}: "Beijing Qxcomm Technology Co., Ltd.", + [3]byte{0, 7, 84}: "Xyterra Computing, Inc.", + [3]byte{0, 7, 85}: "Lafon", + [3]byte{0, 7, 86}: "Juyoung Telecom", + [3]byte{0, 7, 87}: "Topcall International AG", + [3]byte{0, 7, 88}: "Dragonwave", + [3]byte{0, 7, 89}: "Boris Manufacturing Corp.", + [3]byte{0, 7, 90}: "Air Products and Chemicals, Inc.", + [3]byte{0, 7, 91}: "Gibson Guitars", + [3]byte{0, 7, 92}: "Eastman Kodak Company", + [3]byte{0, 7, 93}: "Celleritas Inc.", + [3]byte{0, 7, 94}: "Ametek Power Instruments", + [3]byte{0, 7, 95}: "VCS Video Communication Systems AG", + [3]byte{0, 7, 96}: "TOMIS Information & Telecom Corp.", + [3]byte{0, 7, 97}: "Logitech Europe SA", + [3]byte{0, 7, 98}: "Group Sense Limited", + [3]byte{0, 7, 99}: "Sunniwell Cyber Tech. Co., Ltd.", + [3]byte{0, 7, 100}: "YoungWoo Telecom Co. Ltd.", + [3]byte{0, 7, 101}: "Jade Quantum Technologies, Inc.", + [3]byte{0, 7, 102}: "Chou Chin Industrial Co., Ltd.", + [3]byte{0, 7, 103}: "Yuxing Electronics Company Limited", + [3]byte{0, 7, 104}: "Danfoss A/S", + [3]byte{0, 7, 105}: "Italiana Macchi SpA", + [3]byte{0, 7, 106}: "NEXTEYE Co., Ltd.", + [3]byte{0, 7, 107}: "Stralfors AB", + [3]byte{0, 7, 108}: "Daehanet, Inc.", + [3]byte{0, 7, 109}: "Flexlight Networks", + [3]byte{0, 7, 110}: "Sinetica Corporation Limited", + [3]byte{0, 7, 111}: "Synoptics Limited", + [3]byte{0, 7, 112}: "Ubiquoss Inc", + [3]byte{0, 7, 113}: "Embedded System Corporation", + [3]byte{0, 7, 114}: "Alcatel Shanghai Bell Co., Ltd.", + [3]byte{0, 7, 115}: "Ascom Powerline Communications Ltd.", + [3]byte{0, 7, 116}: "GuangZhou Thinker Technology Co. Ltd.", + [3]byte{0, 7, 117}: "Valence Semiconductor, Inc.", + [3]byte{0, 7, 118}: "Federal APD", + [3]byte{0, 7, 119}: "Motah Ltd.", + [3]byte{0, 7, 120}: "GERSTEL GmbH & Co. KG", + [3]byte{0, 7, 121}: "Sungil Telecom Co., Ltd.", + [3]byte{0, 7, 122}: "Infoware System Co., Ltd.", + [3]byte{0, 7, 123}: "Millimetrix Broadband Networks", + [3]byte{0, 7, 124}: "Westermo Teleindustri AB", + [3]byte{0, 7, 125}: "CISCO SYSTEMS, INC.", + [3]byte{0, 7, 126}: "Elrest GmbH", + [3]byte{0, 7, 127}: "J Communications Co., Ltd.", + [3]byte{0, 7, 128}: "Bluegiga Technologies OY", + [3]byte{0, 7, 129}: "Itron Inc.", + [3]byte{0, 7, 130}: "Oracle Corporation", + [3]byte{0, 7, 131}: "SynCom Network, Inc.", + [3]byte{0, 7, 132}: "CISCO SYSTEMS, INC.", + [3]byte{0, 7, 133}: "CISCO SYSTEMS, INC.", + [3]byte{0, 7, 134}: "Wireless Networks Inc.", + [3]byte{0, 7, 135}: "Idea System Co., Ltd.", + [3]byte{0, 7, 136}: "Clipcomm, Inc.", + [3]byte{0, 7, 137}: "DONGWON SYSTEMS", + [3]byte{0, 7, 138}: "Mentor Data System Inc.", + [3]byte{0, 7, 139}: "Wegener Communications, Inc.", + [3]byte{0, 7, 140}: "Elektronikspecialisten i Borlange AB", + [3]byte{0, 7, 141}: "NetEngines Ltd.", + [3]byte{0, 7, 142}: "Garz & Friche GmbH", + [3]byte{0, 7, 143}: "Emkay Innovative Products", + [3]byte{0, 7, 144}: "Tri-M Technologies (s) Limited", + [3]byte{0, 7, 145}: "International Data Communications, Inc.", + [3]byte{0, 7, 146}: "Sütron Electronic GmbH", + [3]byte{0, 7, 147}: "Shin Satellite Public Company Limited", + [3]byte{0, 7, 148}: "Simple Devices, Inc.", + [3]byte{0, 7, 149}: "Elitegroup Computer System Co. (ECS)", + [3]byte{0, 7, 150}: "LSI Systems, Inc.", + [3]byte{0, 7, 151}: "Netpower Co., Ltd.", + [3]byte{0, 7, 152}: "Selea SRL", + [3]byte{0, 7, 153}: "Tipping Point Technologies, Inc.", + [3]byte{0, 7, 154}: "Verint Systems Inc", + [3]byte{0, 7, 155}: "Aurora Networks", + [3]byte{0, 7, 156}: "Golden Electronics Technology Co., Ltd.", + [3]byte{0, 7, 157}: "Musashi Co., Ltd.", + [3]byte{0, 7, 158}: "Ilinx Co., Ltd.", + [3]byte{0, 7, 159}: "Action Digital Inc.", + [3]byte{0, 7, 160}: "e-Watch Inc.", + [3]byte{0, 7, 161}: "VIASYS Healthcare GmbH", + [3]byte{0, 7, 162}: "Opteon Corporation", + [3]byte{0, 7, 163}: "Ositis Software, Inc.", + [3]byte{0, 7, 164}: "GN Netcom Ltd.", + [3]byte{0, 7, 165}: "Y.D.K Co. Ltd.", + [3]byte{0, 7, 166}: "Home Automation, Inc.", + [3]byte{0, 7, 167}: "A-Z Inc.", + [3]byte{0, 7, 168}: "Haier Group Technologies Ltd.", + [3]byte{0, 7, 169}: "Novasonics", + [3]byte{0, 7, 170}: "Quantum Data Inc.", + [3]byte{0, 7, 171}: "Samsung Electronics Co.,Ltd", + [3]byte{0, 7, 172}: "Eolring", + [3]byte{0, 7, 173}: "Pentacon GmbH Foto-und Feinwerktechnik", + [3]byte{0, 7, 174}: "Britestream Networks, Inc.", + [3]byte{0, 7, 175}: "N-TRON Corporation", + [3]byte{0, 7, 176}: "Office Details, Inc.", + [3]byte{0, 7, 177}: "Equator Technologies", + [3]byte{0, 7, 178}: "Transaccess S.A.", + [3]byte{0, 7, 179}: "CISCO SYSTEMS, INC.", + [3]byte{0, 7, 180}: "CISCO SYSTEMS, INC.", + [3]byte{0, 7, 181}: "Any One Wireless Ltd.", + [3]byte{0, 7, 182}: "Telecom Technology Ltd.", + [3]byte{0, 7, 183}: "Samurai Ind. Prods Eletronicos Ltda", + [3]byte{0, 7, 184}: "Corvalent Corporation", + [3]byte{0, 7, 185}: "Ginganet Corporation", + [3]byte{0, 7, 186}: "UTStarcom, Inc.", + [3]byte{0, 7, 187}: "Candera Inc.", + [3]byte{0, 7, 188}: "Identix Inc.", + [3]byte{0, 7, 189}: "Radionet Ltd.", + [3]byte{0, 7, 190}: "DataLogic SpA", + [3]byte{0, 7, 191}: "Armillaire Technologies, Inc.", + [3]byte{0, 7, 192}: "NetZerver Inc.", + [3]byte{0, 7, 193}: "Overture Networks, Inc.", + [3]byte{0, 7, 194}: "Netsys Telecom", + [3]byte{0, 7, 195}: "Thomson", + [3]byte{0, 7, 196}: "JEAN Co. Ltd.", + [3]byte{0, 7, 197}: "Gcom, Inc.", + [3]byte{0, 7, 198}: "VDS Vosskuhler GmbH", + [3]byte{0, 7, 199}: "Synectics Systems Limited", + [3]byte{0, 7, 200}: "Brain21, Inc.", + [3]byte{0, 7, 201}: "Technol Seven Co., Ltd.", + [3]byte{0, 7, 202}: "Creatix Polymedia Ges Fur Kommunikaitonssysteme", + [3]byte{0, 7, 203}: "Freebox SA", + [3]byte{0, 7, 204}: "Kaba Benzing GmbH", + [3]byte{0, 7, 205}: "Kumoh Electronic Co, Ltd", + [3]byte{0, 7, 206}: "Cabletime Limited", + [3]byte{0, 7, 207}: "Anoto AB", + [3]byte{0, 7, 208}: "Automat Engenharia de Automação Ltda.", + [3]byte{0, 7, 209}: "Spectrum Signal Processing Inc.", + [3]byte{0, 7, 210}: "Logopak Systeme GmbH & Co. KG", + [3]byte{0, 7, 211}: "SPGPrints B.V.", + [3]byte{0, 7, 212}: "Zhejiang Yutong Network Communication Co Ltd.", + [3]byte{0, 7, 213}: "3e Technologies Int;., Inc.", + [3]byte{0, 7, 214}: "Commil Ltd.", + [3]byte{0, 7, 215}: "Caporis Networks AG", + [3]byte{0, 7, 216}: "Hitron Systems Inc.", + [3]byte{0, 7, 217}: "Splicecom", + [3]byte{0, 7, 218}: "Neuro Telecom Co., Ltd.", + [3]byte{0, 7, 219}: "Kirana Networks, Inc.", + [3]byte{0, 7, 220}: "Atek Co, Ltd.", + [3]byte{0, 7, 221}: "Cradle Technologies", + [3]byte{0, 7, 222}: "eCopilt AB", + [3]byte{0, 7, 223}: "Vbrick Systems Inc.", + [3]byte{0, 7, 224}: "Palm Inc.", + [3]byte{0, 7, 225}: "WIS Communications Co. Ltd.", + [3]byte{0, 7, 226}: "Bitworks, Inc.", + [3]byte{0, 7, 227}: "Navcom Technology, Inc.", + [3]byte{0, 7, 228}: "SoftRadio Co., Ltd.", + [3]byte{0, 7, 229}: "Coup Corporation", + [3]byte{0, 7, 230}: "edgeflow Canada Inc.", + [3]byte{0, 7, 231}: "FreeWave Technologies", + [3]byte{0, 7, 232}: "EdgeWave", + [3]byte{0, 7, 233}: "Intel Corporation", + [3]byte{0, 7, 234}: "Massana, Inc.", + [3]byte{0, 7, 235}: "CISCO SYSTEMS, INC.", + [3]byte{0, 7, 236}: "CISCO SYSTEMS, INC.", + [3]byte{0, 7, 237}: "Altera Corporation", + [3]byte{0, 7, 238}: "telco Informationssysteme GmbH", + [3]byte{0, 7, 239}: "Lockheed Martin Tactical Systems", + [3]byte{0, 7, 240}: "LogiSync LLC", + [3]byte{0, 7, 241}: "TeraBurst Networks Inc.", + [3]byte{0, 7, 242}: "IOA Corporation", + [3]byte{0, 7, 243}: "Thinkengine Networks", + [3]byte{0, 7, 244}: "Eletex Co., Ltd.", + [3]byte{0, 7, 245}: "Bridgeco Co AG", + [3]byte{0, 7, 246}: "Qqest Software Systems", + [3]byte{0, 7, 247}: "Galtronics", + [3]byte{0, 7, 248}: "ITDevices, Inc.", + [3]byte{0, 7, 249}: "Sensaphone", + [3]byte{0, 7, 250}: "ITT Co., Ltd.", + [3]byte{0, 7, 251}: "Giga Stream UMTS Technologies GmbH", + [3]byte{0, 7, 252}: "Adept Systems Inc.", + [3]byte{0, 7, 253}: "LANergy Ltd.", + [3]byte{0, 7, 254}: "Rigaku Corporation", + [3]byte{0, 7, 255}: "Gluon Networks", + [3]byte{0, 8, 0}: "MULTITECH SYSTEMS, INC.", + [3]byte{0, 8, 1}: "HighSpeed Surfing Inc.", + [3]byte{0, 8, 2}: "Hewlett-Packard Company", + [3]byte{0, 8, 3}: "Cos Tron", + [3]byte{0, 8, 4}: "ICA Inc.", + [3]byte{0, 8, 5}: "Techno-Holon Corporation", + [3]byte{0, 8, 6}: "Raonet Systems, Inc.", + [3]byte{0, 8, 7}: "Access Devices Limited", + [3]byte{0, 8, 8}: "PPT Vision, Inc.", + [3]byte{0, 8, 9}: "Systemonic AG", + [3]byte{0, 8, 10}: "Espera-Werke GmbH", + [3]byte{0, 8, 11}: "Birka BPA Informationssystem AB", + [3]byte{0, 8, 12}: "VDA Elettronica spa", + [3]byte{0, 8, 13}: "Toshiba", + [3]byte{0, 8, 14}: "ARRIS Group, Inc.", + [3]byte{0, 8, 15}: "Proximion Fiber Optics AB", + [3]byte{0, 8, 16}: "Key Technology, Inc.", + [3]byte{0, 8, 17}: "VOIX Corporation", + [3]byte{0, 8, 18}: "GM-2 Corporation", + [3]byte{0, 8, 19}: "Diskbank, Inc.", + [3]byte{0, 8, 20}: "TIL Technologies", + [3]byte{0, 8, 21}: "CATS Co., Ltd.", + [3]byte{0, 8, 22}: "Bluelon ApS", + [3]byte{0, 8, 23}: "EmergeCore Networks LLC", + [3]byte{0, 8, 24}: "Pixelworks, Inc.", + [3]byte{0, 8, 25}: "Banksys", + [3]byte{0, 8, 26}: "Sanrad Intelligence Storage Communications (2000) Ltd.", + [3]byte{0, 8, 27}: "Windigo Systems", + [3]byte{0, 8, 28}: "@pos.com", + [3]byte{0, 8, 29}: "Ipsil, Incorporated", + [3]byte{0, 8, 30}: "Repeatit AB", + [3]byte{0, 8, 31}: "Pou Yuen Tech Corp. Ltd.", + [3]byte{0, 8, 32}: "CISCO SYSTEMS, INC.", + [3]byte{0, 8, 33}: "CISCO SYSTEMS, INC.", + [3]byte{0, 8, 34}: "InPro Comm", + [3]byte{0, 8, 35}: "Texa Corp.", + [3]byte{0, 8, 36}: "Nuance Document Imaging", + [3]byte{0, 8, 37}: "Acme Packet", + [3]byte{0, 8, 38}: "Colorado Med Tech", + [3]byte{0, 8, 39}: "ADB Broadband Italia", + [3]byte{0, 8, 40}: "Koei Engineering Ltd.", + [3]byte{0, 8, 41}: "Aval Nagasaki Corporation", + [3]byte{0, 8, 42}: "Powerwallz Network Security", + [3]byte{0, 8, 43}: "Wooksung Electronics, Inc.", + [3]byte{0, 8, 44}: "Homag AG", + [3]byte{0, 8, 45}: "Indus Teqsite Private Limited", + [3]byte{0, 8, 46}: "Multitone Electronics PLC", + [3]byte{0, 8, 47}: "CISCO SYSTEMS, INC.", + [3]byte{0, 8, 48}: "CISCO SYSTEMS, INC.", + [3]byte{0, 8, 49}: "CISCO SYSTEMS, INC.", + [3]byte{0, 8, 50}: "Cisco", + [3]byte{0, 8, 78}: "DivergeNet, Inc.", + [3]byte{0, 8, 79}: "Qualstar Corporation", + [3]byte{0, 8, 80}: "Arizona Instrument Corp.", + [3]byte{0, 8, 81}: "Canadian Bank Note Company, Ltd.", + [3]byte{0, 8, 82}: "Davolink Co. Inc.", + [3]byte{0, 8, 83}: "Schleicher GmbH & Co. Relaiswerke KG", + [3]byte{0, 8, 84}: "Netronix, Inc.", + [3]byte{0, 8, 85}: "NASA-Goddard Space Flight Center", + [3]byte{0, 8, 86}: "Gamatronic Electronic Industries Ltd.", + [3]byte{0, 8, 87}: "Polaris Networks, Inc.", + [3]byte{0, 8, 88}: "Novatechnology Inc.", + [3]byte{0, 8, 89}: "ShenZhen Unitone Electronics Co., Ltd.", + [3]byte{0, 8, 90}: "IntiGate Inc.", + [3]byte{0, 8, 91}: "Hanbit Electronics Co., Ltd.", + [3]byte{0, 8, 92}: "Shanghai Dare Technologies Co. Ltd.", + [3]byte{0, 8, 93}: "Aastra", + [3]byte{0, 8, 94}: "PCO AG", + [3]byte{0, 8, 95}: "Picanol N.V.", + [3]byte{0, 8, 96}: "LodgeNet Entertainment Corp.", + [3]byte{0, 8, 97}: "SoftEnergy Co., Ltd.", + [3]byte{0, 8, 98}: "NEC Eluminant Technologies, Inc.", + [3]byte{0, 8, 99}: "Entrisphere Inc.", + [3]byte{0, 8, 100}: "Fasy S.p.A.", + [3]byte{0, 8, 101}: "JASCOM CO., LTD", + [3]byte{0, 8, 102}: "DSX Access Systems, Inc.", + [3]byte{0, 8, 103}: "Uptime Devices", + [3]byte{0, 8, 104}: "PurOptix", + [3]byte{0, 8, 105}: "Command-e Technology Co.,Ltd.", + [3]byte{0, 8, 106}: "Securiton Gmbh", + [3]byte{0, 8, 107}: "MIPSYS", + [3]byte{0, 8, 108}: "Plasmon LMS", + [3]byte{0, 8, 109}: "Missouri FreeNet", + [3]byte{0, 8, 110}: "Hyglo AB", + [3]byte{0, 8, 111}: "Resources Computer Network Ltd.", + [3]byte{0, 8, 112}: "Rasvia Systems, Inc.", + [3]byte{0, 8, 113}: "NORTHDATA Co., Ltd.", + [3]byte{0, 8, 114}: "Sorenson Communications", + [3]byte{0, 8, 115}: "DapTechnology B.V.", + [3]byte{0, 8, 116}: "Dell Computer Corp.", + [3]byte{0, 8, 117}: "Acorp Electronics Corp.", + [3]byte{0, 8, 118}: "SDSystem", + [3]byte{0, 8, 119}: "Liebert-Hiross Spa", + [3]byte{0, 8, 120}: "Benchmark Storage Innovations", + [3]byte{0, 8, 121}: "CEM Corporation", + [3]byte{0, 8, 122}: "Wipotec GmbH", + [3]byte{0, 8, 123}: "RTX Telecom A/S", + [3]byte{0, 8, 124}: "CISCO SYSTEMS, INC.", + [3]byte{0, 8, 125}: "CISCO SYSTEMS, INC.", + [3]byte{0, 8, 126}: "Bon Electro-Telecom Inc.", + [3]byte{0, 8, 127}: "SPAUN electronic GmbH & Co. KG", + [3]byte{0, 8, 128}: "BroadTel Canada Communications inc.", + [3]byte{0, 8, 129}: "DIGITAL HANDS CO.,LTD.", + [3]byte{0, 8, 130}: "SIGMA CORPORATION", + [3]byte{0, 8, 131}: "Hewlett-Packard Company", + [3]byte{0, 8, 132}: "Index Braille AB", + [3]byte{0, 8, 133}: "EMS Dr. Thomas Wünsche", + [3]byte{0, 8, 134}: "Hansung Teliann, Inc.", + [3]byte{0, 8, 135}: "Maschinenfabrik Reinhausen GmbH", + [3]byte{0, 8, 136}: "OULLIM Information Technology Inc,.", + [3]byte{0, 8, 137}: "Echostar Technologies Corp", + [3]byte{0, 8, 138}: "Minds@Work", + [3]byte{0, 8, 139}: "Tropic Networks Inc.", + [3]byte{0, 8, 140}: "Quanta Network Systems Inc.", + [3]byte{0, 8, 141}: "Sigma-Links Inc.", + [3]byte{0, 8, 142}: "Nihon Computer Co., Ltd.", + [3]byte{0, 8, 143}: "ADVANCED DIGITAL TECHNOLOGY", + [3]byte{0, 8, 144}: "AVILINKS SA", + [3]byte{0, 8, 145}: "Lyan Inc.", + [3]byte{0, 8, 146}: "EM Solutions", + [3]byte{0, 8, 147}: "LE INFORMATION COMMUNICATION INC.", + [3]byte{0, 8, 148}: "InnoVISION Multimedia Ltd.", + [3]byte{0, 8, 149}: "DIRC Technologie GmbH & Co.KG", + [3]byte{0, 8, 150}: "Printronix, Inc.", + [3]byte{0, 8, 151}: "Quake Technologies", + [3]byte{0, 8, 152}: "Gigabit Optics Corporation", + [3]byte{0, 8, 153}: "Netbind, Inc.", + [3]byte{0, 8, 154}: "Alcatel Microelectronics", + [3]byte{0, 8, 155}: "ICP Electronics Inc.", + [3]byte{0, 8, 156}: "Elecs Industry Co., Ltd.", + [3]byte{0, 8, 157}: "UHD-Elektronik", + [3]byte{0, 8, 158}: "Beijing Enter-Net co.LTD", + [3]byte{0, 8, 159}: "EFM Networks", + [3]byte{0, 8, 160}: "Stotz Feinmesstechnik GmbH", + [3]byte{0, 8, 161}: "CNet Technology Inc.", + [3]byte{0, 8, 162}: "ADI Engineering, Inc.", + [3]byte{0, 8, 163}: "CISCO SYSTEMS, INC.", + [3]byte{0, 8, 164}: "CISCO SYSTEMS, INC.", + [3]byte{0, 8, 165}: "Peninsula Systems Inc.", + [3]byte{0, 8, 166}: "Multiware & Image Co., Ltd.", + [3]byte{0, 8, 167}: "iLogic Inc.", + [3]byte{0, 8, 168}: "Systec Co., Ltd.", + [3]byte{0, 8, 169}: "SangSang Technology, Inc.", + [3]byte{0, 8, 170}: "KARAM", + [3]byte{0, 8, 171}: "EnerLinx.com, Inc.", + [3]byte{0, 8, 172}: "Eltromat GmbH", + [3]byte{0, 8, 173}: "Toyo-Linx Co., Ltd.", + [3]byte{0, 8, 174}: "PacketFront Network Products AB", + [3]byte{0, 8, 175}: "Novatec Corporation", + [3]byte{0, 8, 176}: "BKtel communications GmbH", + [3]byte{0, 8, 177}: "ProQuent Systems", + [3]byte{0, 8, 178}: "SHENZHEN COMPASS TECHNOLOGY DEVELOPMENT CO.,LTD", + [3]byte{0, 8, 179}: "Fastwel", + [3]byte{0, 8, 180}: "SYSPOL", + [3]byte{0, 8, 181}: "TAI GUEN ENTERPRISE CO., LTD", + [3]byte{0, 8, 182}: "RouteFree, Inc.", + [3]byte{0, 8, 183}: "HIT Incorporated", + [3]byte{0, 8, 184}: "E.F. Johnson", + [3]byte{0, 8, 185}: "KAON MEDIA Co., Ltd.", + [3]byte{0, 8, 186}: "Erskine Systems Ltd", + [3]byte{0, 8, 187}: "NetExcell", + [3]byte{0, 8, 188}: "Ilevo AB", + [3]byte{0, 8, 189}: "TEPG-US", + [3]byte{0, 8, 190}: "XENPAK MSA Group", + [3]byte{0, 8, 191}: "Aptus Elektronik AB", + [3]byte{0, 8, 192}: "ASA SYSTEMS", + [3]byte{0, 8, 193}: "Avistar Communications Corporation", + [3]byte{0, 8, 194}: "CISCO SYSTEMS, INC.", + [3]byte{0, 8, 195}: "Contex A/S", + [3]byte{0, 8, 196}: "Hikari Co.,Ltd.", + [3]byte{0, 8, 197}: "Liontech Co., Ltd.", + [3]byte{0, 8, 198}: "Philips Consumer Communications", + [3]byte{0, 8, 199}: "Hewlett-Packard Company", + [3]byte{0, 8, 200}: "Soneticom, Inc.", + [3]byte{0, 8, 201}: "TechniSat Digital GmbH", + [3]byte{0, 8, 202}: "TwinHan Technology Co.,Ltd", + [3]byte{0, 8, 203}: "Zeta Broadband Inc.", + [3]byte{0, 8, 204}: "Remotec, Inc.", + [3]byte{0, 8, 205}: "With-Net Inc", + [3]byte{0, 8, 206}: "IPMobileNet Inc.", + [3]byte{0, 8, 207}: "Nippon Koei Power Systems Co., Ltd.", + [3]byte{0, 8, 208}: "Musashi Engineering Co., LTD.", + [3]byte{0, 8, 209}: "KAREL INC.", + [3]byte{0, 8, 210}: "ZOOM Networks Inc.", + [3]byte{0, 8, 211}: "Hercules Technologies S.A.S.", + [3]byte{0, 8, 212}: "IneoQuest Technologies, Inc", + [3]byte{0, 8, 213}: "Vanguard Networks Solutions, LLC", + [3]byte{0, 8, 214}: "HASSNET Inc.", + [3]byte{0, 8, 215}: "HOW CORPORATION", + [3]byte{0, 8, 216}: "Dowkey Microwave", + [3]byte{0, 8, 217}: "Mitadenshi Co.,LTD", + [3]byte{0, 8, 218}: "SofaWare Technologies Ltd.", + [3]byte{0, 8, 219}: "Corrigent Systems", + [3]byte{0, 8, 220}: "Wiznet", + [3]byte{0, 8, 221}: "Telena Communications, Inc.", + [3]byte{0, 8, 222}: "3UP Systems", + [3]byte{0, 8, 223}: "Alistel Inc.", + [3]byte{0, 8, 224}: "ATO Technology Ltd.", + [3]byte{0, 8, 225}: "Barix AG", + [3]byte{0, 8, 226}: "CISCO SYSTEMS, INC.", + [3]byte{0, 8, 227}: "CISCO SYSTEMS, INC.", + [3]byte{0, 8, 228}: "Envenergy Inc", + [3]byte{0, 8, 229}: "IDK Corporation", + [3]byte{0, 8, 230}: "Littlefeet", + [3]byte{0, 8, 231}: "SHI ControlSystems,Ltd.", + [3]byte{0, 8, 232}: "Excel Master Ltd.", + [3]byte{0, 8, 233}: "NextGig", + [3]byte{0, 8, 234}: "Motion Control Engineering, Inc", + [3]byte{0, 8, 235}: "ROMWin Co.,Ltd.", + [3]byte{0, 8, 236}: "Optical Zonu Corporation", + [3]byte{0, 8, 237}: "ST&T Instrument Corp.", + [3]byte{0, 8, 238}: "Logic Product Development", + [3]byte{0, 8, 239}: "DIBAL,S.A.", + [3]byte{0, 8, 240}: "Next Generation Systems, Inc.", + [3]byte{0, 8, 241}: "Voltaire", + [3]byte{0, 8, 242}: "C&S Technology", + [3]byte{0, 8, 243}: "WANY", + [3]byte{0, 8, 244}: "Bluetake Technology Co., Ltd.", + [3]byte{0, 8, 245}: "YESTECHNOLOGY Co.,Ltd.", + [3]byte{0, 8, 246}: "Sumitomo Electric System Solutions Co., Ltd.", + [3]byte{0, 8, 247}: "Hitachi Ltd, Semiconductor & Integrated Circuits Gr", + [3]byte{0, 8, 248}: "UTC CCS", + [3]byte{0, 8, 249}: "Artesyn Embedded Technologies", + [3]byte{0, 8, 250}: "Karl E.Brinkmann GmbH", + [3]byte{0, 8, 251}: "SonoSite, Inc.", + [3]byte{0, 8, 252}: "Gigaphoton Inc.", + [3]byte{0, 8, 253}: "BlueKorea Co., Ltd.", + [3]byte{0, 8, 254}: "UNIK C&C Co.,Ltd.", + [3]byte{0, 8, 255}: "Trilogy Communications Ltd", + [3]byte{0, 9, 0}: "TMT", + [3]byte{0, 9, 1}: "Shenzhen Shixuntong Information & Technoligy Co", + [3]byte{0, 9, 2}: "Redline Communications Inc.", + [3]byte{0, 9, 3}: "Panasas, Inc", + [3]byte{0, 9, 4}: "MONDIAL electronic", + [3]byte{0, 9, 5}: "iTEC Technologies Ltd.", + [3]byte{0, 9, 6}: "Esteem Networks", + [3]byte{0, 9, 7}: "Chrysalis Development", + [3]byte{0, 9, 8}: "VTech Technology Corp.", + [3]byte{0, 9, 9}: "Telenor Connect A/S", + [3]byte{0, 9, 10}: "SnedFar Technology Co., Ltd.", + [3]byte{0, 9, 11}: "MTL Instruments PLC", + [3]byte{0, 9, 12}: "Mayekawa Mfg. Co. Ltd.", + [3]byte{0, 9, 13}: "LEADER ELECTRONICS CORP.", + [3]byte{0, 9, 14}: "Helix Technology Inc.", + [3]byte{0, 9, 15}: "Fortinet Inc.", + [3]byte{0, 9, 16}: "Simple Access Inc.", + [3]byte{0, 9, 17}: "CISCO SYSTEMS, INC.", + [3]byte{0, 9, 18}: "CISCO SYSTEMS, INC.", + [3]byte{0, 9, 19}: "SystemK Corporation", + [3]byte{0, 9, 20}: "COMPUTROLS INC.", + [3]byte{0, 9, 21}: "CAS Corp.", + [3]byte{0, 9, 22}: "Listman Home Technologies, Inc.", + [3]byte{0, 9, 23}: "WEM Technology Inc", + [3]byte{0, 9, 24}: "SAMSUNG TECHWIN CO.,LTD", + [3]byte{0, 9, 25}: "MDS Gateways", + [3]byte{0, 9, 26}: "Macat Optics & Electronics Co., Ltd.", + [3]byte{0, 9, 27}: "Digital Generation Inc.", + [3]byte{0, 9, 28}: "CacheVision, Inc", + [3]byte{0, 9, 29}: "Proteam Computer Corporation", + [3]byte{0, 9, 30}: "Firstech Technology Corp.", + [3]byte{0, 9, 31}: "A&D Co., Ltd.", + [3]byte{0, 9, 32}: "EpoX COMPUTER CO.,LTD.", + [3]byte{0, 9, 33}: "Planmeca Oy", + [3]byte{0, 9, 34}: "TST Biometrics GmbH", + [3]byte{0, 9, 35}: "Heaman System Co., Ltd", + [3]byte{0, 9, 36}: "Telebau GmbH", + [3]byte{0, 9, 37}: "VSN Systemen BV", + [3]byte{0, 9, 38}: "YODA COMMUNICATIONS, INC.", + [3]byte{0, 9, 39}: "TOYOKEIKI CO.,LTD.", + [3]byte{0, 9, 40}: "Telecore", + [3]byte{0, 9, 41}: "Sanyo Industries (UK) Limited", + [3]byte{0, 9, 42}: "MYTECS Co.,Ltd.", + [3]byte{0, 9, 43}: "iQstor Networks, Inc.", + [3]byte{0, 9, 44}: "Hitpoint Inc.", + [3]byte{0, 9, 45}: "HTC Corporation", + [3]byte{0, 9, 46}: "B&Tech System Inc.", + [3]byte{0, 9, 47}: "Akom Technology Corporation", + [3]byte{0, 9, 48}: "AeroConcierge Inc.", + [3]byte{0, 9, 49}: "Future Internet, Inc.", + [3]byte{0, 9, 50}: "Omnilux", + [3]byte{0, 9, 51}: "Ophit Co.Ltd.", + [3]byte{0, 9, 52}: "Dream-Multimedia-Tv GmbH", + [3]byte{0, 9, 53}: "Sandvine Incorporated", + [3]byte{0, 9, 54}: "Ipetronik GmbH & Co. KG", + [3]byte{0, 9, 55}: "Inventec Appliance Corp", + [3]byte{0, 9, 56}: "Allot Communications", + [3]byte{0, 9, 57}: "ShibaSoku Co.,Ltd.", + [3]byte{0, 9, 58}: "Molex Fiber Optics", + [3]byte{0, 9, 59}: "HYUNDAI NETWORKS INC.", + [3]byte{0, 9, 60}: "Jacques Technologies P/L", + [3]byte{0, 9, 61}: "Newisys,Inc.", + [3]byte{0, 9, 62}: "C&I Technologies", + [3]byte{0, 9, 63}: "Double-Win Enterpirse CO., LTD", + [3]byte{0, 9, 64}: "AGFEO GmbH & Co. KG", + [3]byte{0, 9, 65}: "Allied Telesis K.K.", + [3]byte{0, 9, 66}: "Wireless Technologies, Inc", + [3]byte{0, 9, 67}: "CISCO SYSTEMS, INC.", + [3]byte{0, 9, 68}: "CISCO SYSTEMS, INC.", + [3]byte{0, 9, 69}: "Palmmicro Communications Inc", + [3]byte{0, 9, 70}: "Cluster Labs GmbH", + [3]byte{0, 9, 71}: "Aztek, Inc.", + [3]byte{0, 9, 72}: "Vista Control Systems, Corp.", + [3]byte{0, 9, 73}: "Glyph Technologies Inc.", + [3]byte{0, 9, 74}: "Homenet Communications", + [3]byte{0, 9, 75}: "FillFactory NV", + [3]byte{0, 9, 76}: "Communication Weaver Co.,Ltd.", + [3]byte{0, 9, 77}: "Braintree Communications Pty Ltd", + [3]byte{0, 9, 78}: "BARTECH SYSTEMS INTERNATIONAL, INC", + [3]byte{0, 9, 79}: "elmegt GmbH & Co. KG", + [3]byte{0, 9, 80}: "Independent Storage Corporation", + [3]byte{0, 9, 81}: "Apogee Imaging Systems", + [3]byte{0, 9, 82}: "Auerswald GmbH & Co. KG", + [3]byte{0, 9, 83}: "Linkage System Integration Co.Ltd.", + [3]byte{0, 9, 84}: "AMiT spol. s. r. o.", + [3]byte{0, 9, 85}: "Young Generation International Corp.", + [3]byte{0, 9, 86}: "Network Systems Group, Ltd. (NSG)", + [3]byte{0, 9, 87}: "Supercaller, Inc.", + [3]byte{0, 9, 88}: "INTELNET S.A.", + [3]byte{0, 9, 89}: "Sitecsoft", + [3]byte{0, 9, 90}: "RACEWOOD TECHNOLOGY", + [3]byte{0, 9, 91}: "Netgear, Inc.", + [3]byte{0, 9, 92}: "Philips Medical Systems - Cardiac and Monitoring Systems (CM", + [3]byte{0, 9, 93}: "Dialogue Technology Corp.", + [3]byte{0, 9, 94}: "Masstech Group Inc.", + [3]byte{0, 9, 95}: "Telebyte, Inc.", + [3]byte{0, 9, 96}: "YOZAN Inc.", + [3]byte{0, 9, 97}: "Switchgear and Instrumentation Ltd", + [3]byte{0, 9, 98}: "Sonitor Technologies AS", + [3]byte{0, 9, 99}: "Dominion Lasercom Inc.", + [3]byte{0, 9, 100}: "Hi-Techniques, Inc.", + [3]byte{0, 9, 101}: "HyunJu Computer Co., Ltd.", + [3]byte{0, 9, 102}: "Thales Navigation", + [3]byte{0, 9, 103}: "Tachyon, Inc", + [3]byte{0, 9, 104}: "TECHNOVENTURE, INC.", + [3]byte{0, 9, 105}: "Meret Optical Communications", + [3]byte{0, 9, 106}: "Cloverleaf Communications Inc.", + [3]byte{0, 9, 107}: "IBM Corp", + [3]byte{0, 9, 108}: "Imedia Semiconductor Corp.", + [3]byte{0, 9, 109}: "Powernet Technologies Corp.", + [3]byte{0, 9, 110}: "GIANT ELECTRONICS LTD.", + [3]byte{0, 9, 111}: "Beijing Zhongqing Elegant Tech. Corp.,Limited", + [3]byte{0, 9, 112}: "Vibration Research Corporation", + [3]byte{0, 9, 113}: "Time Management, Inc.", + [3]byte{0, 9, 114}: "Securebase,Inc", + [3]byte{0, 9, 115}: "Lenten Technology Co., Ltd.", + [3]byte{0, 9, 116}: "Innopia Technologies, Inc.", + [3]byte{0, 9, 117}: "fSONA Communications Corporation", + [3]byte{0, 9, 118}: "Datasoft ISDN Systems GmbH", + [3]byte{0, 9, 119}: "Brunner Elektronik AG", + [3]byte{0, 9, 120}: "AIJI System Co., Ltd.", + [3]byte{0, 9, 121}: "Advanced Television Systems Committee, Inc.", + [3]byte{0, 9, 122}: "Louis Design Labs.", + [3]byte{0, 9, 123}: "CISCO SYSTEMS, INC.", + [3]byte{0, 9, 124}: "CISCO SYSTEMS, INC.", + [3]byte{0, 9, 125}: "SecWell Networks Oy", + [3]byte{0, 9, 126}: "IMI TECHNOLOGY CO., LTD", + [3]byte{0, 9, 127}: "Vsecure 2000 LTD.", + [3]byte{0, 9, 128}: "Power Zenith Inc.", + [3]byte{0, 9, 129}: "Newport Networks", + [3]byte{0, 9, 130}: "Loewe Opta GmbH", + [3]byte{0, 9, 131}: "GlobalTop Technology, Inc.", + [3]byte{0, 9, 132}: "MyCasa Network Inc.", + [3]byte{0, 9, 133}: "Auto Telecom Company", + [3]byte{0, 9, 134}: "Metalink LTD.", + [3]byte{0, 9, 135}: "NISHI NIPPON ELECTRIC WIRE & CABLE CO.,LTD.", + [3]byte{0, 9, 136}: "Nudian Electron Co., Ltd.", + [3]byte{0, 9, 137}: "VividLogic Inc.", + [3]byte{0, 9, 138}: "EqualLogic Inc", + [3]byte{0, 9, 139}: "Entropic Communications, Inc.", + [3]byte{0, 9, 140}: "Option Wireless Sweden", + [3]byte{0, 9, 141}: "Velocity Semiconductor", + [3]byte{0, 9, 142}: "ipcas GmbH", + [3]byte{0, 9, 143}: "Cetacean Networks", + [3]byte{0, 9, 144}: "ACKSYS Communications & systems", + [3]byte{0, 9, 145}: "GE Fanuc Automation Manufacturing, Inc.", + [3]byte{0, 9, 146}: "InterEpoch Technology,INC.", + [3]byte{0, 9, 147}: "Visteon Corporation", + [3]byte{0, 9, 148}: "Cronyx Engineering", + [3]byte{0, 9, 149}: "Castle Technology Ltd", + [3]byte{0, 9, 150}: "RDI", + [3]byte{0, 9, 151}: "Nortel Networks", + [3]byte{0, 9, 152}: "Capinfo Company Limited", + [3]byte{0, 9, 153}: "CP GEORGES RENAULT", + [3]byte{0, 9, 154}: "ELMO COMPANY, LIMITED", + [3]byte{0, 9, 155}: "Western Telematic Inc.", + [3]byte{0, 9, 156}: "Naval Research Laboratory", + [3]byte{0, 9, 157}: "Haliplex Communications", + [3]byte{0, 9, 158}: "Testech, Inc.", + [3]byte{0, 9, 159}: "VIDEX INC.", + [3]byte{0, 9, 160}: "Microtechno Corporation", + [3]byte{0, 9, 161}: "Telewise Communications, Inc.", + [3]byte{0, 9, 162}: "Interface Co., Ltd.", + [3]byte{0, 9, 163}: "Leadfly Techologies Corp. Ltd.", + [3]byte{0, 9, 164}: "HARTEC Corporation", + [3]byte{0, 9, 165}: "HANSUNG ELETRONIC INDUSTRIES DEVELOPMENT CO., LTD", + [3]byte{0, 9, 166}: "Ignis Optics, Inc.", + [3]byte{0, 9, 167}: "Bang & Olufsen A/S", + [3]byte{0, 9, 168}: "Eastmode Pte Ltd", + [3]byte{0, 9, 169}: "Ikanos Communications", + [3]byte{0, 9, 170}: "Data Comm for Business, Inc.", + [3]byte{0, 9, 171}: "Netcontrol Oy", + [3]byte{0, 9, 172}: "LANVOICE", + [3]byte{0, 9, 173}: "HYUNDAI SYSCOMM, INC.", + [3]byte{0, 9, 174}: "OKANO ELECTRIC CO.,LTD", + [3]byte{0, 9, 175}: "e-generis", + [3]byte{0, 9, 176}: "Onkyo Corporation", + [3]byte{0, 9, 177}: "Kanematsu Electronics, Ltd.", + [3]byte{0, 9, 178}: "L&F Inc.", + [3]byte{0, 9, 179}: "MCM Systems Ltd", + [3]byte{0, 9, 180}: "KISAN TELECOM CO., LTD.", + [3]byte{0, 9, 181}: "3J Tech. Co., Ltd.", + [3]byte{0, 9, 182}: "CISCO SYSTEMS, INC.", + [3]byte{0, 9, 183}: "CISCO SYSTEMS, INC.", + [3]byte{0, 9, 184}: "Entise Systems", + [3]byte{0, 9, 185}: "Action Imaging Solutions", + [3]byte{0, 9, 186}: "MAKU Informationstechik GmbH", + [3]byte{0, 9, 187}: "MathStar, Inc.", + [3]byte{0, 9, 188}: "Digital Safety Technologies, Inc", + [3]byte{0, 9, 189}: "Epygi Technologies, Ltd.", + [3]byte{0, 9, 190}: "Mamiya-OP Co.,Ltd.", + [3]byte{0, 9, 191}: "Nintendo Co., Ltd.", + [3]byte{0, 9, 192}: "6WIND", + [3]byte{0, 9, 193}: "PROCES-DATA A/S", + [3]byte{0, 9, 194}: "Onity, Inc.", + [3]byte{0, 9, 195}: "NETAS", + [3]byte{0, 9, 196}: "Medicore Co., Ltd", + [3]byte{0, 9, 197}: "KINGENE Technology Corporation", + [3]byte{0, 9, 198}: "Visionics Corporation", + [3]byte{0, 9, 199}: "Movistec", + [3]byte{0, 9, 200}: "SINAGAWA TSUSHIN KEISOU SERVICE", + [3]byte{0, 9, 201}: "BlueWINC Co., Ltd.", + [3]byte{0, 9, 202}: "iMaxNetworks(Shenzhen)Limited.", + [3]byte{0, 9, 203}: "HBrain", + [3]byte{0, 9, 204}: "Moog GmbH", + [3]byte{0, 9, 205}: "HUDSON SOFT CO.,LTD.", + [3]byte{0, 9, 206}: "SpaceBridge Semiconductor Corp.", + [3]byte{0, 9, 207}: "iAd GmbH", + [3]byte{0, 9, 208}: "Solacom Technologies Inc.", + [3]byte{0, 9, 209}: "SERANOA NETWORKS INC", + [3]byte{0, 9, 210}: "Mai Logic Inc.", + [3]byte{0, 9, 211}: "Western DataCom Co., Inc.", + [3]byte{0, 9, 212}: "Transtech Networks", + [3]byte{0, 9, 213}: "Signal Communication, Inc.", + [3]byte{0, 9, 214}: "KNC One GmbH", + [3]byte{0, 9, 215}: "DC Security Products", + [3]byte{0, 9, 216}: "Fält Communications AB", + [3]byte{0, 9, 217}: "Neoscale Systems, Inc", + [3]byte{0, 9, 218}: "Control Module Inc.", + [3]byte{0, 9, 219}: "eSpace", + [3]byte{0, 9, 220}: "Galaxis Technology AG", + [3]byte{0, 9, 221}: "Mavin Technology Inc.", + [3]byte{0, 9, 222}: "Samjin Information & Communications Co., Ltd.", + [3]byte{0, 9, 223}: "Vestel Komunikasyon Sanayi ve Ticaret A.S.", + [3]byte{0, 9, 224}: "XEMICS S.A.", + [3]byte{0, 9, 225}: "Gemtek Technology Co., Ltd.", + [3]byte{0, 9, 226}: "Sinbon Electronics Co., Ltd.", + [3]byte{0, 9, 227}: "Angel Iglesias S.A.", + [3]byte{0, 9, 228}: "K Tech Infosystem Inc.", + [3]byte{0, 9, 229}: "Hottinger Baldwin Messtechnik GmbH", + [3]byte{0, 9, 230}: "Cyber Switching Inc.", + [3]byte{0, 9, 231}: "ADC Techonology", + [3]byte{0, 9, 232}: "CISCO SYSTEMS, INC.", + [3]byte{0, 9, 233}: "CISCO SYSTEMS, INC.", + [3]byte{0, 9, 234}: "YEM Inc.", + [3]byte{0, 9, 235}: "HuMANDATA LTD.", + [3]byte{0, 9, 236}: "Daktronics, Inc.", + [3]byte{0, 9, 237}: "CipherOptics", + [3]byte{0, 9, 238}: "MEIKYO ELECTRIC CO.,LTD", + [3]byte{0, 9, 239}: "Vocera Communications", + [3]byte{0, 9, 240}: "Shimizu Technology Inc.", + [3]byte{0, 9, 241}: "Yamaki Electric Corporation", + [3]byte{0, 9, 242}: "Cohu, Inc., Electronics Division", + [3]byte{0, 9, 243}: "WELL Communication Corp.", + [3]byte{0, 9, 244}: "Alcon Laboratories, Inc.", + [3]byte{0, 9, 245}: "Emerson Network Power Co.,Ltd", + [3]byte{0, 9, 246}: "Shenzhen Eastern Digital Tech Ltd.", + [3]byte{0, 9, 247}: "SED, a division of Calian", + [3]byte{0, 9, 248}: "UNIMO TECHNOLOGY CO., LTD.", + [3]byte{0, 9, 249}: "ART JAPAN CO., LTD.", + [3]byte{0, 9, 251}: "Philips Patient Monitoring", + [3]byte{0, 9, 252}: "IPFLEX Inc.", + [3]byte{0, 9, 253}: "Ubinetics Limited", + [3]byte{0, 9, 254}: "Daisy Technologies, Inc.", + [3]byte{0, 9, 255}: "X.net 2000 GmbH", + [3]byte{0, 10, 0}: "Mediatek Corp.", + [3]byte{0, 10, 1}: "SOHOware, Inc.", + [3]byte{0, 10, 2}: "ANNSO CO., LTD.", + [3]byte{0, 10, 3}: "ENDESA SERVICIOS, S.L.", + [3]byte{0, 10, 4}: "3Com Ltd", + [3]byte{0, 10, 5}: "Widax Corp.", + [3]byte{0, 10, 6}: "Teledex LLC", + [3]byte{0, 10, 7}: "WebWayOne Ltd", + [3]byte{0, 10, 8}: "ALPINE ELECTRONICS, INC.", + [3]byte{0, 10, 9}: "TaraCom Integrated Products, Inc.", + [3]byte{0, 10, 10}: "SUNIX Co., Ltd.", + [3]byte{0, 10, 11}: "Sealevel Systems, Inc.", + [3]byte{0, 10, 12}: "Scientific Research Corporation", + [3]byte{0, 10, 13}: "FCI Deutschland GmbH", + [3]byte{0, 10, 14}: "Invivo Research Inc.", + [3]byte{0, 10, 15}: "Ilryung Telesys, Inc", + [3]byte{0, 10, 16}: "FAST media integrations AG", + [3]byte{0, 10, 17}: "ExPet Technologies, Inc", + [3]byte{0, 10, 18}: "Azylex Technology, Inc", + [3]byte{0, 10, 19}: "Honeywell Video Systems", + [3]byte{0, 10, 20}: "TECO a.s.", + [3]byte{0, 10, 21}: "Silicon Data, Inc", + [3]byte{0, 10, 22}: "Lassen Research", + [3]byte{0, 10, 23}: "NESTAR COMMUNICATIONS, INC", + [3]byte{0, 10, 24}: "Vichel Inc.", + [3]byte{0, 10, 25}: "Valere Power, Inc.", + [3]byte{0, 10, 26}: "Imerge Ltd", + [3]byte{0, 10, 27}: "Stream Labs", + [3]byte{0, 10, 28}: "Bridge Information Co., Ltd.", + [3]byte{0, 10, 29}: "Optical Communications Products Inc.", + [3]byte{0, 10, 30}: "Red-M Products Limited", + [3]byte{0, 10, 31}: "ART WARE Telecommunication Co., Ltd.", + [3]byte{0, 10, 32}: "SVA Networks, Inc.", + [3]byte{0, 10, 33}: "Integra Telecom Co. Ltd", + [3]byte{0, 10, 34}: "Amperion Inc", + [3]byte{0, 10, 35}: "Parama Networks Inc", + [3]byte{0, 10, 36}: "Octave Communications", + [3]byte{0, 10, 37}: "CERAGON NETWORKS", + [3]byte{0, 10, 38}: "CEIA S.p.A.", + [3]byte{0, 10, 39}: "Apple", + [3]byte{0, 10, 40}: "Motorola", + [3]byte{0, 10, 41}: "Pan Dacom Networking AG", + [3]byte{0, 10, 42}: "QSI Systems Inc.", + [3]byte{0, 10, 43}: "Etherstuff", + [3]byte{0, 10, 44}: "Active Tchnology Corporation", + [3]byte{0, 10, 45}: "Cabot Communications Limited", + [3]byte{0, 10, 46}: "MAPLE NETWORKS CO., LTD", + [3]byte{0, 10, 47}: "Artnix Inc.", + [3]byte{0, 10, 48}: "Visteon Corporation", + [3]byte{0, 10, 49}: "HCV Consulting", + [3]byte{0, 10, 50}: "Xsido Corporation", + [3]byte{0, 10, 51}: "Emulex Corporation", + [3]byte{0, 10, 52}: "Identicard Systems Incorporated", + [3]byte{0, 10, 53}: "Xilinx", + [3]byte{0, 10, 54}: "Synelec Telecom Multimedia", + [3]byte{0, 10, 55}: "Procera Networks, Inc.", + [3]byte{0, 10, 56}: "Apani Networks", + [3]byte{0, 10, 57}: "LoPA Information Technology", + [3]byte{0, 10, 58}: "J-THREE INTERNATIONAL Holding Co., Ltd.", + [3]byte{0, 10, 59}: "GCT Semiconductor, Inc", + [3]byte{0, 10, 60}: "Enerpoint Ltd.", + [3]byte{0, 10, 61}: "Elo Sistemas Eletronicos S.A.", + [3]byte{0, 10, 62}: "EADS Telecom", + [3]byte{0, 10, 63}: "Data East Corporation", + [3]byte{0, 10, 64}: "Crown Audio -- Harmanm International", + [3]byte{0, 10, 65}: "CISCO SYSTEMS, INC.", + [3]byte{0, 10, 66}: "CISCO SYSTEMS, INC.", + [3]byte{0, 10, 67}: "Chunghwa Telecom Co., Ltd.", + [3]byte{0, 10, 68}: "Avery Dennison Deutschland GmbH", + [3]byte{0, 10, 69}: "Audio-Technica Corp.", + [3]byte{0, 10, 70}: "ARO WELDING TECHNOLOGIES SAS", + [3]byte{0, 10, 71}: "Allied Vision Technologies", + [3]byte{0, 10, 72}: "Albatron Technology", + [3]byte{0, 10, 73}: "F5 Networks, Inc.", + [3]byte{0, 10, 74}: "Targa Systems Ltd.", + [3]byte{0, 10, 75}: "DataPower Technology, Inc.", + [3]byte{0, 10, 76}: "Molecular Devices Corporation", + [3]byte{0, 10, 77}: "Noritz Corporation", + [3]byte{0, 10, 78}: "UNITEK Electronics INC.", + [3]byte{0, 10, 79}: "Brain Boxes Limited", + [3]byte{0, 10, 80}: "REMOTEK CORPORATION", + [3]byte{0, 10, 81}: "GyroSignal Technology Co., Ltd.", + [3]byte{0, 10, 82}: "AsiaRF Ltd.", + [3]byte{0, 10, 83}: "Intronics, Incorporated", + [3]byte{0, 10, 84}: "Laguna Hills, Inc.", + [3]byte{0, 10, 85}: "MARKEM Corporation", + [3]byte{0, 10, 86}: "HITACHI Maxell Ltd.", + [3]byte{0, 10, 87}: "Hewlett-Packard Company - Standards", + [3]byte{0, 10, 88}: "Freyer & Siegel Elektronik GmbH & Co. KG", + [3]byte{0, 10, 89}: "HW server", + [3]byte{0, 10, 90}: "GreenNET Technologies Co.,Ltd.", + [3]byte{0, 10, 91}: "Power-One as", + [3]byte{0, 10, 92}: "Carel s.p.a.", + [3]byte{0, 10, 93}: "FingerTec Worldwide Sdn Bhd", + [3]byte{0, 10, 94}: "3COM Corporation", + [3]byte{0, 10, 95}: "almedio inc.", + [3]byte{0, 10, 96}: "Autostar Technology Pte Ltd", + [3]byte{0, 10, 97}: "Cellinx Systems Inc.", + [3]byte{0, 10, 98}: "Crinis Networks, Inc.", + [3]byte{0, 10, 99}: "DHD GmbH", + [3]byte{0, 10, 100}: "Eracom Technologies", + [3]byte{0, 10, 101}: "GentechMedia.co.,ltd.", + [3]byte{0, 10, 102}: "MITSUBISHI ELECTRIC SYSTEM & SERVICE CO.,LTD.", + [3]byte{0, 10, 103}: "OngCorp", + [3]byte{0, 10, 104}: "SolarFlare Communications, Inc.", + [3]byte{0, 10, 105}: "SUNNY bell Technology Co., Ltd.", + [3]byte{0, 10, 106}: "SVM Microwaves s.r.o.", + [3]byte{0, 10, 107}: "Tadiran Telecom Business Systems LTD", + [3]byte{0, 10, 108}: "Walchem Corporation", + [3]byte{0, 10, 109}: "EKS Elektronikservice GmbH", + [3]byte{0, 10, 110}: "Harmonic, Inc", + [3]byte{0, 10, 111}: "ZyFLEX Technologies Inc", + [3]byte{0, 10, 112}: "MPLS Forum", + [3]byte{0, 10, 113}: "Avrio Technologies, Inc", + [3]byte{0, 10, 114}: "STEC, INC.", + [3]byte{0, 10, 115}: "Scientific Atlanta", + [3]byte{0, 10, 116}: "Manticom Networks Inc.", + [3]byte{0, 10, 117}: "Caterpillar, Inc", + [3]byte{0, 10, 118}: "Beida Jade Bird Huaguang Technology Co.,Ltd", + [3]byte{0, 10, 119}: "Bluewire Technologies LLC", + [3]byte{0, 10, 120}: "OLITEC", + [3]byte{0, 10, 121}: "corega K.K", + [3]byte{0, 10, 122}: "Kyoritsu Electric Co., Ltd.", + [3]byte{0, 10, 123}: "Cornelius Consult", + [3]byte{0, 10, 124}: "Tecton Ltd", + [3]byte{0, 10, 125}: "Valo, Inc.", + [3]byte{0, 10, 126}: "The Advantage Group", + [3]byte{0, 10, 127}: "Teradon Industries, Inc", + [3]byte{0, 10, 128}: "Telkonet Inc.", + [3]byte{0, 10, 129}: "TEIMA Audiotex S.L.", + [3]byte{0, 10, 130}: "TATSUTA SYSTEM ELECTRONICS CO.,LTD.", + [3]byte{0, 10, 131}: "SALTO SYSTEMS S.L.", + [3]byte{0, 10, 132}: "Rainsun Enterprise Co., Ltd.", + [3]byte{0, 10, 133}: "PLAT'C2,Inc", + [3]byte{0, 10, 134}: "Lenze", + [3]byte{0, 10, 135}: "Integrated Micromachines Inc.", + [3]byte{0, 10, 136}: "InCypher S.A.", + [3]byte{0, 10, 137}: "Creval Systems, Inc.", + [3]byte{0, 10, 138}: "CISCO SYSTEMS, INC.", + [3]byte{0, 10, 139}: "CISCO SYSTEMS, INC.", + [3]byte{0, 10, 140}: "Guardware Systems Ltd.", + [3]byte{0, 10, 141}: "EUROTHERM LIMITED", + [3]byte{0, 10, 142}: "Invacom Ltd", + [3]byte{0, 10, 143}: "Aska International Inc.", + [3]byte{0, 10, 144}: "Bayside Interactive, Inc.", + [3]byte{0, 10, 145}: "HemoCue AB", + [3]byte{0, 10, 146}: "Presonus Corporation", + [3]byte{0, 10, 147}: "W2 Networks, Inc.", + [3]byte{0, 10, 148}: "ShangHai cellink CO., LTD", + [3]byte{0, 10, 149}: "Apple", + [3]byte{0, 10, 150}: "MEWTEL TECHNOLOGY INC.", + [3]byte{0, 10, 151}: "SONICblue, Inc.", + [3]byte{0, 10, 152}: "M+F Gwinner GmbH & Co", + [3]byte{0, 10, 153}: "Calamp Wireless Networks Inc", + [3]byte{0, 10, 154}: "Aiptek International Inc", + [3]byte{0, 10, 155}: "TB Group Inc", + [3]byte{0, 10, 156}: "Server Technology, Inc.", + [3]byte{0, 10, 157}: "King Young Technology Co. Ltd.", + [3]byte{0, 10, 158}: "BroadWeb Corportation", + [3]byte{0, 10, 159}: "Pannaway Technologies, Inc.", + [3]byte{0, 10, 160}: "Cedar Point Communications", + [3]byte{0, 10, 161}: "V V S Limited", + [3]byte{0, 10, 162}: "SYSTEK INC.", + [3]byte{0, 10, 163}: "SHIMAFUJI ELECTRIC CO.,LTD.", + [3]byte{0, 10, 164}: "SHANGHAI SURVEILLANCE TECHNOLOGY CO,LTD", + [3]byte{0, 10, 165}: "MAXLINK INDUSTRIES LIMITED", + [3]byte{0, 10, 166}: "Hochiki Corporation", + [3]byte{0, 10, 167}: "FEI Electron Optics", + [3]byte{0, 10, 168}: "ePipe Pty. Ltd.", + [3]byte{0, 10, 169}: "Brooks Automation GmbH", + [3]byte{0, 10, 170}: "AltiGen Communications Inc.", + [3]byte{0, 10, 171}: "Toyota Technical Development Corporation", + [3]byte{0, 10, 172}: "TerraTec Electronic GmbH", + [3]byte{0, 10, 173}: "Stargames Corporation", + [3]byte{0, 10, 174}: "Rosemount Process Analytical", + [3]byte{0, 10, 175}: "Pipal Systems", + [3]byte{0, 10, 176}: "LOYTEC electronics GmbH", + [3]byte{0, 10, 177}: "GENETEC Corporation", + [3]byte{0, 10, 178}: "Fresnel Wireless Systems", + [3]byte{0, 10, 179}: "Fa. GIRA", + [3]byte{0, 10, 180}: "ETIC Telecommunications", + [3]byte{0, 10, 181}: "Digital Electronic Network", + [3]byte{0, 10, 182}: "COMPUNETIX, INC", + [3]byte{0, 10, 183}: "CISCO SYSTEMS, INC.", + [3]byte{0, 10, 184}: "CISCO SYSTEMS, INC.", + [3]byte{0, 10, 185}: "Astera Technologies Corp.", + [3]byte{0, 10, 186}: "Arcon Technology Limited", + [3]byte{0, 10, 187}: "Taiwan Secom Co,. Ltd", + [3]byte{0, 10, 188}: "Seabridge Ltd.", + [3]byte{0, 10, 189}: "Rupprecht & Patashnick Co.", + [3]byte{0, 10, 190}: "OPNET Technologies CO., LTD.", + [3]byte{0, 10, 191}: "HIROTA SS", + [3]byte{0, 10, 192}: "Fuyoh Video Industry CO., LTD.", + [3]byte{0, 10, 193}: "Futuretel", + [3]byte{0, 10, 194}: "FiberHome Telecommunication Technologies CO.,LTD", + [3]byte{0, 10, 195}: "eM Technics Co., Ltd.", + [3]byte{0, 10, 196}: "Daewoo Teletech Co., Ltd", + [3]byte{0, 10, 197}: "Color Kinetics", + [3]byte{0, 10, 198}: "Overture Networks.", + [3]byte{0, 10, 199}: "Unication Group", + [3]byte{0, 10, 200}: "ZPSYS CO.,LTD. (Planning&Management)", + [3]byte{0, 10, 201}: "Zambeel Inc", + [3]byte{0, 10, 202}: "YOKOYAMA SHOKAI CO.,Ltd.", + [3]byte{0, 10, 203}: "XPAK MSA Group", + [3]byte{0, 10, 204}: "Winnow Networks, Inc.", + [3]byte{0, 10, 205}: "Sunrich Technology Limited", + [3]byte{0, 10, 206}: "RADIANTECH, INC.", + [3]byte{0, 10, 207}: "PROVIDEO Multimedia Co. Ltd.", + [3]byte{0, 10, 208}: "Niigata Develoment Center, F.I.T. Co., Ltd.", + [3]byte{0, 10, 209}: "MWS", + [3]byte{0, 10, 210}: "JEPICO Corporation", + [3]byte{0, 10, 211}: "INITECH Co., Ltd", + [3]byte{0, 10, 212}: "CoreBell Systems Inc.", + [3]byte{0, 10, 213}: "Brainchild Electronic Co., Ltd.", + [3]byte{0, 10, 214}: "BeamReach Networks", + [3]byte{0, 10, 215}: "Origin ELECTRIC CO.,LTD.", + [3]byte{0, 10, 216}: "IPCserv Technology Corp.", + [3]byte{0, 10, 217}: "Sony Ericsson Mobile Communications AB", + [3]byte{0, 10, 218}: "Vindicator Technologies", + [3]byte{0, 10, 219}: "SkyPilot Network, Inc", + [3]byte{0, 10, 220}: "RuggedCom Inc.", + [3]byte{0, 10, 221}: "Allworx Corp.", + [3]byte{0, 10, 222}: "Happy Communication Co., Ltd.", + [3]byte{0, 10, 223}: "Gennum Corporation", + [3]byte{0, 10, 224}: "Fujitsu Softek", + [3]byte{0, 10, 225}: "EG Technology", + [3]byte{0, 10, 226}: "Binatone Electronics International, Ltd", + [3]byte{0, 10, 227}: "YANG MEI TECHNOLOGY CO., LTD", + [3]byte{0, 10, 228}: "Wistron Corp.", + [3]byte{0, 10, 229}: "ScottCare Corporation", + [3]byte{0, 10, 230}: "Elitegroup Computer System Co. (ECS)", + [3]byte{0, 10, 231}: "ELIOP S.A.", + [3]byte{0, 10, 232}: "Cathay Roxus Information Technology Co. LTD", + [3]byte{0, 10, 233}: "AirVast Technology Inc.", + [3]byte{0, 10, 234}: "ADAM ELEKTRONIK LTD. ŞTI", + [3]byte{0, 10, 235}: "Shenzhen Tp-Link Technology Co; Ltd.", + [3]byte{0, 10, 236}: "Koatsu Gas Kogyo Co., Ltd.", + [3]byte{0, 10, 237}: "HARTING Systems GmbH & Co KG", + [3]byte{0, 10, 238}: "GCD Hard- & Software GmbH", + [3]byte{0, 10, 239}: "OTRUM ASA", + [3]byte{0, 10, 240}: "SHIN-OH ELECTRONICS CO., LTD. R&D", + [3]byte{0, 10, 241}: "Clarity Design, Inc.", + [3]byte{0, 10, 242}: "NeoAxiom Corp.", + [3]byte{0, 10, 243}: "CISCO SYSTEMS, INC.", + [3]byte{0, 10, 244}: "CISCO SYSTEMS, INC.", + [3]byte{0, 10, 245}: "Airgo Networks, Inc.", + [3]byte{0, 10, 246}: "Emerson Climate Technologies Retail Solutions, Inc.", + [3]byte{0, 10, 247}: "Broadcom Corp.", + [3]byte{0, 10, 248}: "American Telecare Inc.", + [3]byte{0, 10, 249}: "HiConnect, Inc.", + [3]byte{0, 10, 250}: "Traverse Technologies Australia", + [3]byte{0, 10, 251}: "Ambri Limited", + [3]byte{0, 10, 252}: "Core Tec Communications, LLC", + [3]byte{0, 10, 253}: "Viking Electronic Services", + [3]byte{0, 10, 254}: "NovaPal Ltd", + [3]byte{0, 10, 255}: "Kilchherr Elektronik AG", + [3]byte{0, 11, 0}: "FUJIAN START COMPUTER EQUIPMENT CO.,LTD", + [3]byte{0, 11, 1}: "DAIICHI ELECTRONICS CO., LTD.", + [3]byte{0, 11, 2}: "Dallmeier electronic", + [3]byte{0, 11, 3}: "Taekwang Industrial Co., Ltd", + [3]byte{0, 11, 4}: "Volktek Corporation", + [3]byte{0, 11, 5}: "Pacific Broadband Networks", + [3]byte{0, 11, 6}: "ARRIS Group, Inc.", + [3]byte{0, 11, 7}: "Voxpath Networks", + [3]byte{0, 11, 8}: "Pillar Data Systems", + [3]byte{0, 11, 9}: "Ifoundry Systems Singapore", + [3]byte{0, 11, 10}: "dBm Optics", + [3]byte{0, 11, 11}: "Corrent Corporation", + [3]byte{0, 11, 12}: "Agile Systems Inc.", + [3]byte{0, 11, 13}: "Air2U, Inc.", + [3]byte{0, 11, 14}: "Trapeze Networks", + [3]byte{0, 11, 15}: "Bosch Rexroth", + [3]byte{0, 11, 16}: "11wave Technonlogy Co.,Ltd", + [3]byte{0, 11, 17}: "HIMEJI ABC TRADING CO.,LTD.", + [3]byte{0, 11, 18}: "NURI Telecom Co., Ltd.", + [3]byte{0, 11, 19}: "ZETRON INC", + [3]byte{0, 11, 20}: "ViewSonic Corporation", + [3]byte{0, 11, 21}: "Platypus Technology", + [3]byte{0, 11, 22}: "Communication Machinery Corporation", + [3]byte{0, 11, 23}: "MKS Instruments", + [3]byte{0, 11, 24}: "PRIVATE", + [3]byte{0, 11, 25}: "Vernier Networks, Inc.", + [3]byte{0, 11, 26}: "Industrial Defender, Inc.", + [3]byte{0, 11, 27}: "Systronix, Inc.", + [3]byte{0, 11, 28}: "SIBCO bv", + [3]byte{0, 11, 29}: "LayerZero Power Systems, Inc.", + [3]byte{0, 11, 30}: "KAPPA opto-electronics GmbH", + [3]byte{0, 11, 31}: "I CON Computer Co.", + [3]byte{0, 11, 32}: "Hirata corporation", + [3]byte{0, 11, 33}: "G-Star Communications Inc.", + [3]byte{0, 11, 34}: "Environmental Systems and Services", + [3]byte{0, 11, 35}: "Siemens Subscriber Networks", + [3]byte{0, 11, 36}: "AirLogic", + [3]byte{0, 11, 37}: "Aeluros", + [3]byte{0, 11, 38}: "Wetek Corporation", + [3]byte{0, 11, 39}: "Scion Corporation", + [3]byte{0, 11, 40}: "Quatech Inc.", + [3]byte{0, 11, 41}: "LS(LG) Industrial Systems co.,Ltd", + [3]byte{0, 11, 42}: "HOWTEL Co., Ltd.", + [3]byte{0, 11, 43}: "HOSTNET CORPORATION", + [3]byte{0, 11, 44}: "Eiki Industrial Co. Ltd.", + [3]byte{0, 11, 45}: "Danfoss Inc.", + [3]byte{0, 11, 46}: "Cal-Comp Electronics (Thailand) Public Company Limited Taipe", + [3]byte{0, 11, 47}: "bplan GmbH", + [3]byte{0, 11, 48}: "Beijing Gongye Science & Technology Co.,Ltd", + [3]byte{0, 11, 49}: "Yantai ZhiYang Scientific and technology industry CO., LTD", + [3]byte{0, 11, 50}: "VORMETRIC, INC.", + [3]byte{0, 11, 51}: "Vivato Technologies", + [3]byte{0, 11, 52}: "ShangHai Broadband Technologies CO.LTD", + [3]byte{0, 11, 53}: "Quad Bit System co., Ltd.", + [3]byte{0, 11, 54}: "Productivity Systems, Inc.", + [3]byte{0, 11, 55}: "MANUFACTURE DES MONTRES ROLEX SA", + [3]byte{0, 11, 56}: "Knürr GmbH", + [3]byte{0, 11, 57}: "Keisoku Giken Co.,Ltd.", + [3]byte{0, 11, 58}: "QuStream Corporation", + [3]byte{0, 11, 59}: "devolo AG", + [3]byte{0, 11, 60}: "Cygnal Integrated Products, Inc.", + [3]byte{0, 11, 61}: "CONTAL OK Ltd.", + [3]byte{0, 11, 62}: "BittWare, Inc", + [3]byte{0, 11, 63}: "Anthology Solutions Inc.", + [3]byte{0, 11, 64}: "Oclaro", + [3]byte{0, 11, 65}: "Ing. Büro Dr. Beutlhauser", + [3]byte{0, 11, 66}: "commax Co., Ltd.", + [3]byte{0, 11, 67}: "Microscan Systems, Inc.", + [3]byte{0, 11, 68}: "Concord IDea Corp.", + [3]byte{0, 11, 69}: "CISCO SYSTEMS, INC.", + [3]byte{0, 11, 70}: "CISCO SYSTEMS, INC.", + [3]byte{0, 11, 71}: "Advanced Energy", + [3]byte{0, 11, 72}: "sofrel", + [3]byte{0, 11, 73}: "RF-Link System Inc.", + [3]byte{0, 11, 74}: "Visimetrics (UK) Ltd", + [3]byte{0, 11, 75}: "VISIOWAVE SA", + [3]byte{0, 11, 76}: "Clarion (M) Sdn Bhd", + [3]byte{0, 11, 77}: "Emuzed", + [3]byte{0, 11, 78}: "VertexRSI, General Dynamics SatCOM Technologies, Inc.", + [3]byte{0, 11, 79}: "Verifone, INC.", + [3]byte{0, 11, 80}: "Oxygnet", + [3]byte{0, 11, 81}: "Micetek International Inc.", + [3]byte{0, 11, 82}: "JOYMAX ELECTRONICS CO. LTD.", + [3]byte{0, 11, 83}: "INITIUM Co., Ltd.", + [3]byte{0, 11, 84}: "BiTMICRO Networks, Inc.", + [3]byte{0, 11, 85}: "ADInstruments", + [3]byte{0, 11, 86}: "Cybernetics", + [3]byte{0, 11, 87}: "Silicon Laboratories", + [3]byte{0, 11, 88}: "Astronautics C.A LTD", + [3]byte{0, 11, 89}: "ScriptPro, LLC", + [3]byte{0, 11, 90}: "HyperEdge", + [3]byte{0, 11, 91}: "Rincon Research Corporation", + [3]byte{0, 11, 92}: "Newtech Co.,Ltd", + [3]byte{0, 11, 93}: "FUJITSU LIMITED", + [3]byte{0, 11, 94}: "Audio Engineering Society Inc.", + [3]byte{0, 11, 95}: "CISCO SYSTEMS, INC.", + [3]byte{0, 11, 96}: "CISCO SYSTEMS, INC.", + [3]byte{0, 11, 97}: "Friedrich Lütze GmbH & Co. KG", + [3]byte{0, 11, 98}: "ib-mohnen KG", + [3]byte{0, 11, 99}: "Kaleidescape", + [3]byte{0, 11, 100}: "Kieback & Peter GmbH & Co KG", + [3]byte{0, 11, 101}: "Sy.A.C. srl", + [3]byte{0, 11, 102}: "Teralink Communications", + [3]byte{0, 11, 103}: "Topview Technology Corporation", + [3]byte{0, 11, 104}: "Addvalue Communications Pte Ltd", + [3]byte{0, 11, 105}: "Franke Finland Oy", + [3]byte{0, 11, 106}: "Asiarock Incorporation", + [3]byte{0, 11, 107}: "Wistron Neweb Corp.", + [3]byte{0, 11, 108}: "Sychip Inc.", + [3]byte{0, 11, 109}: "SOLECTRON JAPAN NAKANIIDA", + [3]byte{0, 11, 110}: "Neff Instrument Corp.", + [3]byte{0, 11, 111}: "Media Streaming Networks Inc", + [3]byte{0, 11, 112}: "Load Technology, Inc.", + [3]byte{0, 11, 113}: "Litchfield Communications Inc.", + [3]byte{0, 11, 114}: "Lawo AG", + [3]byte{0, 11, 115}: "Kodeos Communications", + [3]byte{0, 11, 116}: "Kingwave Technology Co., Ltd.", + [3]byte{0, 11, 117}: "Iosoft Ltd.", + [3]byte{0, 11, 118}: "ET&T Technology Co. Ltd.", + [3]byte{0, 11, 119}: "Cogent Systems, Inc.", + [3]byte{0, 11, 120}: "TAIFATECH INC.", + [3]byte{0, 11, 121}: "X-COM, Inc.", + [3]byte{0, 11, 122}: "L-3 Linkabit", + [3]byte{0, 11, 123}: "Test-Um Inc.", + [3]byte{0, 11, 124}: "Telex Communications", + [3]byte{0, 11, 125}: "SOLOMON EXTREME INTERNATIONAL LTD.", + [3]byte{0, 11, 126}: "SAGINOMIYA Seisakusho Inc.", + [3]byte{0, 11, 127}: "Align Engineering LLC", + [3]byte{0, 11, 128}: "Lycium Networks", + [3]byte{0, 11, 129}: "Kaparel Corporation", + [3]byte{0, 11, 130}: "Grandstream Networks, Inc.", + [3]byte{0, 11, 131}: "DATAWATT B.V.", + [3]byte{0, 11, 132}: "BODET", + [3]byte{0, 11, 133}: "CISCO SYSTEMS, INC.", + [3]byte{0, 11, 134}: "Aruba Networks", + [3]byte{0, 11, 135}: "American Reliance Inc.", + [3]byte{0, 11, 136}: "Vidisco ltd.", + [3]byte{0, 11, 137}: "Top Global Technology, Ltd.", + [3]byte{0, 11, 138}: "MITEQ Inc.", + [3]byte{0, 11, 139}: "KERAJET, S.A.", + [3]byte{0, 11, 140}: "Flextronics", + [3]byte{0, 11, 141}: "Avvio Networks", + [3]byte{0, 11, 142}: "Ascent Corporation", + [3]byte{0, 11, 143}: "AKITA ELECTRONICS SYSTEMS CO.,LTD.", + [3]byte{0, 11, 144}: "ADVA Optical Networking Ltd.", + [3]byte{0, 11, 145}: "Aglaia Gesellschaft für Bildverarbeitung und Kommunikation mbH", + [3]byte{0, 11, 146}: "Ascom Danmark A/S", + [3]byte{0, 11, 147}: "Ritter Elektronik", + [3]byte{0, 11, 148}: "Digital Monitoring Products, Inc.", + [3]byte{0, 11, 149}: "eBet Gaming Systems Pty Ltd", + [3]byte{0, 11, 150}: "Innotrac Diagnostics Oy", + [3]byte{0, 11, 151}: "Matsushita Electric Industrial Co.,Ltd.", + [3]byte{0, 11, 152}: "NiceTechVision", + [3]byte{0, 11, 153}: "SensAble Technologies, Inc.", + [3]byte{0, 11, 154}: "Shanghai Ulink Telecom Equipment Co. Ltd.", + [3]byte{0, 11, 155}: "Sirius System Co, Ltd.", + [3]byte{0, 11, 156}: "TriBeam Technologies, Inc.", + [3]byte{0, 11, 157}: "TwinMOS Technologies Inc.", + [3]byte{0, 11, 158}: "Yasing Technology Corp.", + [3]byte{0, 11, 159}: "Neue ELSA GmbH", + [3]byte{0, 11, 160}: "T&L Information Inc.", + [3]byte{0, 11, 161}: "SYSCOM Ltd.", + [3]byte{0, 11, 162}: "Sumitomo Electric Networks, Inc", + [3]byte{0, 11, 163}: "Siemens AG, I&S", + [3]byte{0, 11, 164}: "Shiron Satellite Communications Ltd. (1996)", + [3]byte{0, 11, 165}: "Quasar Cipta Mandiri, PT", + [3]byte{0, 11, 166}: "Miyakawa Electric Works Ltd.", + [3]byte{0, 11, 167}: "Maranti Networks", + [3]byte{0, 11, 168}: "HANBACK ELECTRONICS CO., LTD.", + [3]byte{0, 11, 169}: "CloudShield Technologies, Inc.", + [3]byte{0, 11, 170}: "Aiphone co.,Ltd", + [3]byte{0, 11, 171}: "Advantech Technology (CHINA) Co., Ltd.", + [3]byte{0, 11, 172}: "3Com Ltd", + [3]byte{0, 11, 173}: "PC-PoS Inc.", + [3]byte{0, 11, 174}: "Vitals System Inc.", + [3]byte{0, 11, 175}: "WOOJU COMMUNICATIONS Co,.Ltd", + [3]byte{0, 11, 176}: "Sysnet Telematica srl", + [3]byte{0, 11, 177}: "Super Star Technology Co., Ltd.", + [3]byte{0, 11, 178}: "SMALLBIG TECHNOLOGY", + [3]byte{0, 11, 179}: "RiT technologies Ltd.", + [3]byte{0, 11, 180}: "RDC Semiconductor Inc.,", + [3]byte{0, 11, 181}: "nStor Technologies, Inc.", + [3]byte{0, 11, 182}: "Metalligence Technology Corp.", + [3]byte{0, 11, 183}: "Micro Systems Co.,Ltd.", + [3]byte{0, 11, 184}: "Kihoku Electronic Co.", + [3]byte{0, 11, 185}: "Imsys AB", + [3]byte{0, 11, 186}: "Harmonic, Inc", + [3]byte{0, 11, 187}: "Etin Systems Co., Ltd", + [3]byte{0, 11, 188}: "En Garde Systems, Inc.", + [3]byte{0, 11, 189}: "Connexionz Limited", + [3]byte{0, 11, 190}: "CISCO SYSTEMS, INC.", + [3]byte{0, 11, 191}: "CISCO SYSTEMS, INC.", + [3]byte{0, 11, 192}: "China IWNComm Co., Ltd.", + [3]byte{0, 11, 193}: "Bay Microsystems, Inc.", + [3]byte{0, 11, 194}: "Corinex Communication Corp.", + [3]byte{0, 11, 195}: "Multiplex, Inc.", + [3]byte{0, 11, 196}: "BIOTRONIK GmbH & Co", + [3]byte{0, 11, 197}: "SMC Networks, Inc.", + [3]byte{0, 11, 198}: "ISAC, Inc.", + [3]byte{0, 11, 199}: "ICET S.p.A.", + [3]byte{0, 11, 200}: "AirFlow Networks", + [3]byte{0, 11, 201}: "Electroline Equipment", + [3]byte{0, 11, 202}: "DATAVAN International Corporation", + [3]byte{0, 11, 203}: "Fagor Automation , S. Coop", + [3]byte{0, 11, 204}: "JUSAN, S.A.", + [3]byte{0, 11, 205}: "Hewlett-Packard Company", + [3]byte{0, 11, 206}: "Free2move AB", + [3]byte{0, 11, 207}: "AGFA NDT INC.", + [3]byte{0, 11, 208}: "XiMeta Technology Americas Inc.", + [3]byte{0, 11, 209}: "Aeronix, Inc.", + [3]byte{0, 11, 210}: "Remopro Technology Inc.", + [3]byte{0, 11, 211}: "cd3o", + [3]byte{0, 11, 212}: "Beijing Wise Technology & Science Development Co.Ltd", + [3]byte{0, 11, 213}: "Nvergence, Inc.", + [3]byte{0, 11, 214}: "Paxton Access Ltd", + [3]byte{0, 11, 215}: "DORMA Time + Access GmbH", + [3]byte{0, 11, 216}: "Industrial Scientific Corp.", + [3]byte{0, 11, 217}: "General Hydrogen", + [3]byte{0, 11, 218}: "EyeCross Co.,Inc.", + [3]byte{0, 11, 219}: "Dell Inc", + [3]byte{0, 11, 220}: "AKCP", + [3]byte{0, 11, 221}: "TOHOKU RICOH Co., LTD.", + [3]byte{0, 11, 222}: "TELDIX GmbH", + [3]byte{0, 11, 223}: "Shenzhen RouterD Networks Limited", + [3]byte{0, 11, 224}: "SercoNet Ltd.", + [3]byte{0, 11, 225}: "Nokia NET Product Operations", + [3]byte{0, 11, 226}: "Lumenera Corporation", + [3]byte{0, 11, 227}: "Key Stream Co., Ltd.", + [3]byte{0, 11, 228}: "Hosiden Corporation", + [3]byte{0, 11, 229}: "HIMS International Corporation", + [3]byte{0, 11, 230}: "Datel Electronics", + [3]byte{0, 11, 231}: "COMFLUX TECHNOLOGY INC.", + [3]byte{0, 11, 232}: "AOIP", + [3]byte{0, 11, 233}: "Actel Corporation", + [3]byte{0, 11, 234}: "Zultys Technologies", + [3]byte{0, 11, 235}: "Systegra AG", + [3]byte{0, 11, 236}: "NIPPON ELECTRIC INSTRUMENT, INC.", + [3]byte{0, 11, 237}: "ELM Inc.", + [3]byte{0, 11, 238}: "inc.jet, Incorporated", + [3]byte{0, 11, 239}: "Code Corporation", + [3]byte{0, 11, 240}: "MoTEX Products Co., Ltd.", + [3]byte{0, 11, 241}: "LAP Laser Applikations", + [3]byte{0, 11, 242}: "Chih-Kan Technology Co., Ltd.", + [3]byte{0, 11, 243}: "BAE SYSTEMS", + [3]byte{0, 11, 244}: "PRIVATE", + [3]byte{0, 11, 245}: "Shanghai Sibo Telecom Technology Co.,Ltd", + [3]byte{0, 11, 246}: "Nitgen Co., Ltd", + [3]byte{0, 11, 247}: "NIDEK CO.,LTD", + [3]byte{0, 11, 248}: "Infinera", + [3]byte{0, 11, 249}: "Gemstone communications, Inc.", + [3]byte{0, 11, 250}: "EXEMYS SRL", + [3]byte{0, 11, 251}: "D-NET International Corporation", + [3]byte{0, 11, 252}: "CISCO SYSTEMS, INC.", + [3]byte{0, 11, 253}: "CISCO SYSTEMS, INC.", + [3]byte{0, 11, 254}: "CASTEL Broadband Limited", + [3]byte{0, 11, 255}: "Berkeley Camera Engineering", + [3]byte{0, 12, 0}: "BEB Industrie-Elektronik AG", + [3]byte{0, 12, 1}: "Abatron AG", + [3]byte{0, 12, 2}: "ABB Oy", + [3]byte{0, 12, 3}: "HDMI Licensing, LLC", + [3]byte{0, 12, 4}: "Tecnova", + [3]byte{0, 12, 5}: "RPA Reserch Co., Ltd.", + [3]byte{0, 12, 6}: "Nixvue Systems Pte Ltd", + [3]byte{0, 12, 7}: "Iftest AG", + [3]byte{0, 12, 8}: "HUMEX Technologies Corp.", + [3]byte{0, 12, 9}: "Hitachi IE Systems Co., Ltd", + [3]byte{0, 12, 10}: "Guangdong Province Electronic Technology Research Institute", + [3]byte{0, 12, 11}: "Broadbus Technologies", + [3]byte{0, 12, 12}: "APPRO TECHNOLOGY INC.", + [3]byte{0, 12, 13}: "Communications & Power Industries / Satcom Division", + [3]byte{0, 12, 14}: "XtremeSpectrum, Inc.", + [3]byte{0, 12, 15}: "Techno-One Co., Ltd", + [3]byte{0, 12, 16}: "PNI Corporation", + [3]byte{0, 12, 17}: "NIPPON DEMPA CO.,LTD.", + [3]byte{0, 12, 18}: "Micro-Optronic-Messtechnik GmbH", + [3]byte{0, 12, 19}: "MediaQ", + [3]byte{0, 12, 20}: "Diagnostic Instruments, Inc.", + [3]byte{0, 12, 21}: "CyberPower Systems, Inc.", + [3]byte{0, 12, 22}: "Concorde Microsystems Inc.", + [3]byte{0, 12, 23}: "AJA Video Systems Inc", + [3]byte{0, 12, 24}: "Zenisu Keisoku Inc.", + [3]byte{0, 12, 25}: "Telio Communications GmbH", + [3]byte{0, 12, 26}: "Quest Technical Solutions Inc.", + [3]byte{0, 12, 27}: "ORACOM Co, Ltd.", + [3]byte{0, 12, 28}: "MicroWeb Co., Ltd.", + [3]byte{0, 12, 29}: "Mettler & Fuchs AG", + [3]byte{0, 12, 30}: "Global Cache", + [3]byte{0, 12, 31}: "Glimmerglass Networks", + [3]byte{0, 12, 32}: "Fi WIn, Inc.", + [3]byte{0, 12, 33}: "Faculty of Science and Technology, Keio University", + [3]byte{0, 12, 34}: "Double D Electronics Ltd", + [3]byte{0, 12, 35}: "Beijing Lanchuan Tech. Co., Ltd.", + [3]byte{0, 12, 36}: "ANATOR", + [3]byte{0, 12, 37}: "Allied Telesis Labs, Inc.", + [3]byte{0, 12, 38}: "Weintek Labs. Inc.", + [3]byte{0, 12, 39}: "Sammy Corporation", + [3]byte{0, 12, 40}: "RIFATRON", + [3]byte{0, 12, 41}: "VMware, Inc.", + [3]byte{0, 12, 42}: "OCTTEL Communication Co., Ltd.", + [3]byte{0, 12, 43}: "ELIAS Technology, Inc.", + [3]byte{0, 12, 44}: "Enwiser Inc.", + [3]byte{0, 12, 45}: "FullWave Technology Co., Ltd.", + [3]byte{0, 12, 46}: "Openet information technology(shenzhen) Co., Ltd.", + [3]byte{0, 12, 47}: "SeorimTechnology Co.,Ltd.", + [3]byte{0, 12, 48}: "CISCO SYSTEMS, INC.", + [3]byte{0, 12, 49}: "CISCO SYSTEMS, INC.", + [3]byte{0, 12, 50}: "Avionic Design Development GmbH", + [3]byte{0, 12, 51}: "Compucase Enterprise Co. Ltd.", + [3]byte{0, 12, 52}: "Vixen Co., Ltd.", + [3]byte{0, 12, 53}: "KaVo Dental GmbH & Co. KG", + [3]byte{0, 12, 54}: "SHARP TAKAYA ELECTRONICS INDUSTRY CO.,LTD.", + [3]byte{0, 12, 55}: "Geomation, Inc.", + [3]byte{0, 12, 56}: "TelcoBridges Inc.", + [3]byte{0, 12, 57}: "Sentinel Wireless Inc.", + [3]byte{0, 12, 58}: "Oxance", + [3]byte{0, 12, 59}: "Orion Electric Co., Ltd.", + [3]byte{0, 12, 60}: "MediaChorus, Inc.", + [3]byte{0, 12, 61}: "Glsystech Co., Ltd.", + [3]byte{0, 12, 62}: "Crest Audio", + [3]byte{0, 12, 63}: "Cogent Defence & Security Networks,", + [3]byte{0, 12, 64}: "Altech Controls", + [3]byte{0, 12, 65}: "Cisco-Linksys", + [3]byte{0, 12, 66}: "Routerboard.com", + [3]byte{0, 12, 67}: "Ralink Technology, Corp.", + [3]byte{0, 12, 68}: "Automated Interfaces, Inc.", + [3]byte{0, 12, 69}: "Animation Technologies Inc.", + [3]byte{0, 12, 70}: "Allied Telesyn Inc.", + [3]byte{0, 12, 71}: "SK Teletech(R&D Planning Team)", + [3]byte{0, 12, 72}: "QoStek Corporation", + [3]byte{0, 12, 73}: "Dangaard Telecom RTC Division A/S", + [3]byte{0, 12, 74}: "Cygnus Microsystems (P) Limited", + [3]byte{0, 12, 75}: "Cheops Elektronik", + [3]byte{0, 12, 76}: "Arcor AG&Co.", + [3]byte{0, 12, 77}: "Curtiss-Wright Controls Avionics & Electronics", + [3]byte{0, 12, 78}: "Winbest Technology CO,LT", + [3]byte{0, 12, 79}: "UDTech Japan Corporation", + [3]byte{0, 12, 80}: "Seagate Technology", + [3]byte{0, 12, 81}: "Scientific Technologies Inc.", + [3]byte{0, 12, 82}: "Roll Systems Inc.", + [3]byte{0, 12, 83}: "PRIVATE", + [3]byte{0, 12, 84}: "Pedestal Networks, Inc", + [3]byte{0, 12, 85}: "Microlink Communications Inc.", + [3]byte{0, 12, 86}: "Megatel Computer (1986) Corp.", + [3]byte{0, 12, 87}: "MACKIE Engineering Services Belgium BVBA", + [3]byte{0, 12, 88}: "M&S Systems", + [3]byte{0, 12, 89}: "Indyme Electronics, Inc.", + [3]byte{0, 12, 90}: "IBSmm Embedded Electronics Consulting", + [3]byte{0, 12, 91}: "HANWANG TECHNOLOGY CO.,LTD", + [3]byte{0, 12, 92}: "GTN Systems B.V.", + [3]byte{0, 12, 93}: "CHIC TECHNOLOGY (CHINA) CORP.", + [3]byte{0, 12, 94}: "Calypso Medical", + [3]byte{0, 12, 95}: "Avtec, Inc.", + [3]byte{0, 12, 96}: "ACM Systems", + [3]byte{0, 12, 97}: "AC Tech corporation DBA Advanced Digital", + [3]byte{0, 12, 98}: "ABB AB, Cewe-Control", + [3]byte{0, 12, 99}: "Zenith Electronics Corporation", + [3]byte{0, 12, 100}: "X2 MSA Group", + [3]byte{0, 12, 101}: "Sunin Telecom", + [3]byte{0, 12, 102}: "Pronto Networks Inc", + [3]byte{0, 12, 103}: "OYO ELECTRIC CO.,LTD", + [3]byte{0, 12, 104}: "SigmaTel, Inc.", + [3]byte{0, 12, 105}: "National Radio Astronomy Observatory", + [3]byte{0, 12, 106}: "MBARI", + [3]byte{0, 12, 107}: "Kurz Industrie-Elektronik GmbH", + [3]byte{0, 12, 108}: "Elgato Systems LLC", + [3]byte{0, 12, 109}: "Edwards Ltd.", + [3]byte{0, 12, 110}: "ASUSTEK COMPUTER INC.", + [3]byte{0, 12, 111}: "Amtek system co.,LTD.", + [3]byte{0, 12, 112}: "ACC GmbH", + [3]byte{0, 12, 113}: "Wybron, Inc", + [3]byte{0, 12, 114}: "Tempearl Industrial Co., Ltd.", + [3]byte{0, 12, 115}: "TELSON ELECTRONICS CO., LTD", + [3]byte{0, 12, 116}: "RIVERTEC CORPORATION", + [3]byte{0, 12, 117}: "Oriental integrated electronics. LTD", + [3]byte{0, 12, 118}: "MICRO-STAR INTERNATIONAL CO., LTD.", + [3]byte{0, 12, 119}: "Life Racing Ltd", + [3]byte{0, 12, 120}: "In-Tech Electronics Limited", + [3]byte{0, 12, 121}: "Extel Communications P/L", + [3]byte{0, 12, 122}: "DaTARIUS Technologies GmbH", + [3]byte{0, 12, 123}: "ALPHA PROJECT Co.,Ltd.", + [3]byte{0, 12, 124}: "Internet Information Image Inc.", + [3]byte{0, 12, 125}: "TEIKOKU ELECTRIC MFG. CO., LTD", + [3]byte{0, 12, 126}: "Tellium Incorporated", + [3]byte{0, 12, 127}: "synertronixx GmbH", + [3]byte{0, 12, 128}: "Opelcomm Inc.", + [3]byte{0, 12, 129}: "Schneider Electric (Australia)", + [3]byte{0, 12, 130}: "NETWORK TECHNOLOGIES INC", + [3]byte{0, 12, 131}: "Logical Solutions", + [3]byte{0, 12, 132}: "Eazix, Inc.", + [3]byte{0, 12, 133}: "CISCO SYSTEMS, INC.", + [3]byte{0, 12, 134}: "CISCO SYSTEMS, INC.", + [3]byte{0, 12, 135}: "AMD", + [3]byte{0, 12, 136}: "Apache Micro Peripherals, Inc.", + [3]byte{0, 12, 137}: "AC Electric Vehicles, Ltd.", + [3]byte{0, 12, 138}: "Bose Corporation", + [3]byte{0, 12, 139}: "Connect Tech Inc", + [3]byte{0, 12, 140}: "KODICOM CO.,LTD.", + [3]byte{0, 12, 141}: "MATRIX VISION GmbH", + [3]byte{0, 12, 142}: "Mentor Engineering Inc", + [3]byte{0, 12, 143}: "Nergal s.r.l.", + [3]byte{0, 12, 144}: "Octasic Inc.", + [3]byte{0, 12, 145}: "Riverhead Networks Inc.", + [3]byte{0, 12, 146}: "WolfVision Gmbh", + [3]byte{0, 12, 147}: "Xeline Co., Ltd.", + [3]byte{0, 12, 148}: "United Electronic Industries, Inc. (EUI)", + [3]byte{0, 12, 149}: "PrimeNet", + [3]byte{0, 12, 150}: "OQO, Inc.", + [3]byte{0, 12, 151}: "NV ADB TTV Technologies SA", + [3]byte{0, 12, 152}: "LETEK Communications Inc.", + [3]byte{0, 12, 153}: "HITEL LINK Co.,Ltd", + [3]byte{0, 12, 154}: "Hitech Electronics Corp.", + [3]byte{0, 12, 155}: "EE Solutions, Inc", + [3]byte{0, 12, 156}: "Chongho information & communications", + [3]byte{0, 12, 157}: "UbeeAirWalk, Inc.", + [3]byte{0, 12, 158}: "MemoryLink Corp.", + [3]byte{0, 12, 159}: "NKE Corporation", + [3]byte{0, 12, 160}: "StorCase Technology, Inc.", + [3]byte{0, 12, 161}: "SIGMACOM Co., LTD.", + [3]byte{0, 12, 162}: "Harmonic Video Network", + [3]byte{0, 12, 163}: "Rancho Technology, Inc.", + [3]byte{0, 12, 164}: "Prompttec Product Management GmbH", + [3]byte{0, 12, 165}: "Naman NZ LTd", + [3]byte{0, 12, 166}: "Mintera Corporation", + [3]byte{0, 12, 167}: "Metro (Suzhou) Technologies Co., Ltd.", + [3]byte{0, 12, 168}: "Garuda Networks Corporation", + [3]byte{0, 12, 169}: "Ebtron Inc.", + [3]byte{0, 12, 170}: "Cubic Transportation Systems Inc", + [3]byte{0, 12, 171}: "COMMEND International", + [3]byte{0, 12, 172}: "Citizen Watch Co., Ltd.", + [3]byte{0, 12, 173}: "BTU International", + [3]byte{0, 12, 174}: "Ailocom Oy", + [3]byte{0, 12, 175}: "TRI TERM CO.,LTD.", + [3]byte{0, 12, 176}: "Star Semiconductor Corporation", + [3]byte{0, 12, 177}: "Salland Engineering (Europe) BV", + [3]byte{0, 12, 178}: "UNION co., ltd.", + [3]byte{0, 12, 179}: "ROUND Co.,Ltd.", + [3]byte{0, 12, 180}: "AutoCell Laboratories, Inc.", + [3]byte{0, 12, 181}: "Premier Technolgies, Inc", + [3]byte{0, 12, 182}: "NANJING SEU MOBILE & INTERNET TECHNOLOGY CO.,LTD", + [3]byte{0, 12, 183}: "Nanjing Huazhuo Electronics Co., Ltd.", + [3]byte{0, 12, 184}: "MEDION AG", + [3]byte{0, 12, 185}: "LEA", + [3]byte{0, 12, 186}: "Jamex, Inc.", + [3]byte{0, 12, 187}: "ISKRAEMECO", + [3]byte{0, 12, 188}: "Iscutum", + [3]byte{0, 12, 189}: "Interface Masters, Inc", + [3]byte{0, 12, 190}: "Innominate Security Technologies AG", + [3]byte{0, 12, 191}: "Holy Stone Ent. Co., Ltd.", + [3]byte{0, 12, 192}: "Genera Oy", + [3]byte{0, 12, 193}: "Cooper Industries Inc.", + [3]byte{0, 12, 194}: "ControlNet (India) Private Limited", + [3]byte{0, 12, 195}: "BeWAN systems", + [3]byte{0, 12, 196}: "Tiptel AG", + [3]byte{0, 12, 197}: "Nextlink Co., Ltd.", + [3]byte{0, 12, 198}: "Ka-Ro electronics GmbH", + [3]byte{0, 12, 199}: "Intelligent Computer Solutions Inc.", + [3]byte{0, 12, 200}: "Xytronix Research & Design, Inc.", + [3]byte{0, 12, 201}: "ILWOO DATA & TECHNOLOGY CO.,LTD", + [3]byte{0, 12, 202}: "HGST a Western Digital Company", + [3]byte{0, 12, 203}: "Design Combus Ltd", + [3]byte{0, 12, 204}: "Aeroscout Ltd.", + [3]byte{0, 12, 205}: "IEC - TC57", + [3]byte{0, 12, 206}: "CISCO SYSTEMS, INC.", + [3]byte{0, 12, 207}: "CISCO SYSTEMS, INC.", + [3]byte{0, 12, 208}: "Symetrix", + [3]byte{0, 12, 209}: "SFOM Technology Corp.", + [3]byte{0, 12, 210}: "Schaffner EMV AG", + [3]byte{0, 12, 211}: "Prettl Elektronik Radeberg GmbH", + [3]byte{0, 12, 212}: "Positron Public Safety Systems inc.", + [3]byte{0, 12, 213}: "Passave Inc.", + [3]byte{0, 12, 214}: "PARTNER TECH", + [3]byte{0, 12, 215}: "Nallatech Ltd", + [3]byte{0, 12, 216}: "M. K. Juchheim GmbH & Co", + [3]byte{0, 12, 217}: "Itcare Co., Ltd", + [3]byte{0, 12, 218}: "FreeHand Systems, Inc.", + [3]byte{0, 12, 219}: "Brocade Communications Systems, Inc", + [3]byte{0, 12, 220}: "BECS Technology, Inc", + [3]byte{0, 12, 221}: "AOS Technologies AG", + [3]byte{0, 12, 222}: "ABB STOTZ-KONTAKT GmbH", + [3]byte{0, 12, 223}: "PULNiX America, Inc", + [3]byte{0, 12, 224}: "Trek Diagnostics Inc.", + [3]byte{0, 12, 225}: "The Open Group", + [3]byte{0, 12, 226}: "Rolls-Royce", + [3]byte{0, 12, 227}: "Option International N.V.", + [3]byte{0, 12, 228}: "NeuroCom International, Inc.", + [3]byte{0, 12, 229}: "ARRIS Group, Inc.", + [3]byte{0, 12, 230}: "Meru Networks Inc", + [3]byte{0, 12, 231}: "MediaTek Inc.", + [3]byte{0, 12, 232}: "GuangZhou AnJuBao Co., Ltd", + [3]byte{0, 12, 233}: "BLOOMBERG L.P.", + [3]byte{0, 12, 234}: "aphona Kommunikationssysteme", + [3]byte{0, 12, 235}: "CNMP Networks, Inc.", + [3]byte{0, 12, 236}: "Spectracom Corp.", + [3]byte{0, 12, 237}: "Real Digital Media", + [3]byte{0, 12, 238}: "jp-embedded", + [3]byte{0, 12, 239}: "Open Networks Engineering Ltd", + [3]byte{0, 12, 240}: "M & N GmbH", + [3]byte{0, 12, 241}: "Intel Corporation", + [3]byte{0, 12, 242}: "GAMESA Eólica", + [3]byte{0, 12, 243}: "CALL IMAGE SA", + [3]byte{0, 12, 244}: "AKATSUKI ELECTRIC MFG.CO.,LTD.", + [3]byte{0, 12, 245}: "InfoExpress", + [3]byte{0, 12, 246}: "Sitecom Europe BV", + [3]byte{0, 12, 247}: "Nortel Networks", + [3]byte{0, 12, 248}: "Nortel Networks", + [3]byte{0, 12, 249}: "Xylem Water Solutions", + [3]byte{0, 12, 250}: "Digital Systems Corp", + [3]byte{0, 12, 251}: "Korea Network Systems", + [3]byte{0, 12, 252}: "S2io Technologies Corp", + [3]byte{0, 12, 253}: "Hyundai ImageQuest Co.,Ltd.", + [3]byte{0, 12, 254}: "Grand Electronic Co., Ltd", + [3]byte{0, 12, 255}: "MRO-TEK LIMITED", + [3]byte{0, 13, 0}: "Seaway Networks Inc.", + [3]byte{0, 13, 1}: "P&E Microcomputer Systems, Inc.", + [3]byte{0, 13, 2}: "NEC Platforms, Ltd.", + [3]byte{0, 13, 3}: "Matrics, Inc.", + [3]byte{0, 13, 4}: "Foxboro Eckardt Development GmbH", + [3]byte{0, 13, 5}: "cybernet manufacturing inc.", + [3]byte{0, 13, 6}: "Compulogic Limited", + [3]byte{0, 13, 7}: "Calrec Audio Ltd", + [3]byte{0, 13, 8}: "AboveCable, Inc.", + [3]byte{0, 13, 9}: "Yuehua(Zhuhai) Electronic CO. LTD", + [3]byte{0, 13, 10}: "Projectiondesign as", + [3]byte{0, 13, 11}: "Buffalo Inc.", + [3]byte{0, 13, 12}: "MDI Security Systems", + [3]byte{0, 13, 13}: "ITSupported, LLC", + [3]byte{0, 13, 14}: "Inqnet Systems, Inc.", + [3]byte{0, 13, 15}: "Finlux Ltd", + [3]byte{0, 13, 16}: "Embedtronics Oy", + [3]byte{0, 13, 17}: "DENTSPLY - Gendex", + [3]byte{0, 13, 18}: "AXELL Corporation", + [3]byte{0, 13, 19}: "Wilhelm Rutenbeck GmbH&Co.KG", + [3]byte{0, 13, 20}: "Vtech Innovation LP dba Advanced American Telephones", + [3]byte{0, 13, 21}: "Voipac s.r.o.", + [3]byte{0, 13, 22}: "UHS Systems Pty Ltd", + [3]byte{0, 13, 23}: "Turbo Networks Co.Ltd", + [3]byte{0, 13, 24}: "Mega-Trend Electronics CO., LTD.", + [3]byte{0, 13, 25}: "ROBE Show lighting", + [3]byte{0, 13, 26}: "Mustek System Inc.", + [3]byte{0, 13, 27}: "Kyoto Electronics Manufacturing Co., Ltd.", + [3]byte{0, 13, 28}: "Amesys Defense", + [3]byte{0, 13, 29}: "HIGH-TEK HARNESS ENT. CO., LTD.", + [3]byte{0, 13, 30}: "Control Techniques", + [3]byte{0, 13, 31}: "AV Digital", + [3]byte{0, 13, 32}: "ASAHIKASEI TECHNOSYSTEM CO.,LTD.", + [3]byte{0, 13, 33}: "WISCORE Inc.", + [3]byte{0, 13, 34}: "Unitronics LTD", + [3]byte{0, 13, 35}: "Smart Solution, Inc", + [3]byte{0, 13, 36}: "SENTEC E&E CO., LTD.", + [3]byte{0, 13, 37}: "SANDEN CORPORATION", + [3]byte{0, 13, 38}: "Primagraphics Limited", + [3]byte{0, 13, 39}: "MICROPLEX Printware AG", + [3]byte{0, 13, 40}: "CISCO SYSTEMS, INC.", + [3]byte{0, 13, 41}: "CISCO SYSTEMS, INC.", + [3]byte{0, 13, 42}: "Scanmatic AS", + [3]byte{0, 13, 43}: "Racal Instruments", + [3]byte{0, 13, 44}: "Patapsco Designs Ltd", + [3]byte{0, 13, 45}: "NCT Deutschland GmbH", + [3]byte{0, 13, 46}: "Matsushita Avionics Systems Corporation", + [3]byte{0, 13, 47}: "AIN Comm.Tech.Co., LTD", + [3]byte{0, 13, 48}: "IceFyre Semiconductor", + [3]byte{0, 13, 49}: "Compellent Technologies, Inc.", + [3]byte{0, 13, 50}: "DispenseSource, Inc.", + [3]byte{0, 13, 51}: "Prediwave Corp.", + [3]byte{0, 13, 52}: "Shell International Exploration and Production, Inc.", + [3]byte{0, 13, 53}: "PAC International Ltd", + [3]byte{0, 13, 54}: "Wu Han Routon Electronic Co., Ltd", + [3]byte{0, 13, 55}: "WIPLUG", + [3]byte{0, 13, 56}: "NISSIN INC.", + [3]byte{0, 13, 57}: "Network Electronics", + [3]byte{0, 13, 58}: "Microsoft Corp.", + [3]byte{0, 13, 59}: "Microelectronics Technology Inc.", + [3]byte{0, 13, 60}: "i.Tech Dynamic Ltd", + [3]byte{0, 13, 61}: "Hammerhead Systems, Inc.", + [3]byte{0, 13, 62}: "APLUX Communications Ltd.", + [3]byte{0, 13, 63}: "VTI Instruments Corporation", + [3]byte{0, 13, 64}: "Verint Loronix Video Solutions", + [3]byte{0, 13, 65}: "Siemens AG ICM MP UC RD IT KLF1", + [3]byte{0, 13, 66}: "Newbest Development Limited", + [3]byte{0, 13, 67}: "DRS Tactical Systems Inc.", + [3]byte{0, 13, 68}: "Audio BU - Logitech", + [3]byte{0, 13, 69}: "Tottori SANYO Electric Co., Ltd.", + [3]byte{0, 13, 70}: "Parker SSD Drives", + [3]byte{0, 13, 71}: "Collex", + [3]byte{0, 13, 72}: "AEWIN Technologies Co., Ltd.", + [3]byte{0, 13, 73}: "Triton Systems of Delaware, Inc.", + [3]byte{0, 13, 74}: "Steag ETA-Optik", + [3]byte{0, 13, 75}: "Roku, LLC", + [3]byte{0, 13, 76}: "Outline Electronics Ltd.", + [3]byte{0, 13, 77}: "Ninelanes", + [3]byte{0, 13, 78}: "NDR Co.,LTD.", + [3]byte{0, 13, 79}: "Kenwood Corporation", + [3]byte{0, 13, 80}: "Galazar Networks", + [3]byte{0, 13, 81}: "DIVR Systems, Inc.", + [3]byte{0, 13, 82}: "Comart system", + [3]byte{0, 13, 83}: "Beijing 5w Communication Corp.", + [3]byte{0, 13, 84}: "3Com Ltd", + [3]byte{0, 13, 85}: "SANYCOM Technology Co.,Ltd", + [3]byte{0, 13, 86}: "Dell Inc", + [3]byte{0, 13, 87}: "Fujitsu I-Network Systems Limited.", + [3]byte{0, 13, 88}: "PRIVATE", + [3]byte{0, 13, 89}: "Amity Systems, Inc.", + [3]byte{0, 13, 90}: "Tiesse SpA", + [3]byte{0, 13, 91}: "Smart Empire Investments Limited", + [3]byte{0, 13, 92}: "Robert Bosch GmbH, VT-ATMO", + [3]byte{0, 13, 93}: "Raritan Computer, Inc", + [3]byte{0, 13, 94}: "NEC Personal Products", + [3]byte{0, 13, 95}: "Minds Inc", + [3]byte{0, 13, 96}: "IBM Corp", + [3]byte{0, 13, 97}: "Giga-Byte Technology Co., Ltd.", + [3]byte{0, 13, 98}: "Funkwerk Dabendorf GmbH", + [3]byte{0, 13, 99}: "DENT Instruments, Inc.", + [3]byte{0, 13, 100}: "COMAG Handels AG", + [3]byte{0, 13, 101}: "CISCO SYSTEMS, INC.", + [3]byte{0, 13, 102}: "CISCO SYSTEMS, INC.", + [3]byte{0, 13, 103}: "Ericsson", + [3]byte{0, 13, 104}: "Vinci Systems, Inc.", + [3]byte{0, 13, 105}: "TMT&D Corporation", + [3]byte{0, 13, 106}: "Redwood Technologies LTD", + [3]byte{0, 13, 107}: "Mita-Teknik A/S", + [3]byte{0, 13, 108}: "M-Audio", + [3]byte{0, 13, 109}: "K-Tech Devices Corp.", + [3]byte{0, 13, 110}: "K-Patents Oy", + [3]byte{0, 13, 111}: "Ember Corporation", + [3]byte{0, 13, 112}: "Datamax Corporation", + [3]byte{0, 13, 113}: "boca systems", + [3]byte{0, 13, 114}: "2Wire, Inc", + [3]byte{0, 13, 115}: "Technical Support, Inc.", + [3]byte{0, 13, 116}: "Sand Network Systems, Inc.", + [3]byte{0, 13, 117}: "Kobian Pte Ltd - Taiwan Branch", + [3]byte{0, 13, 118}: "Hokuto Denshi Co,. Ltd.", + [3]byte{0, 13, 119}: "FalconStor Software", + [3]byte{0, 13, 120}: "Engineering & Security", + [3]byte{0, 13, 121}: "Dynamic Solutions Co,.Ltd.", + [3]byte{0, 13, 122}: "DiGATTO Asia Pacific Pte Ltd", + [3]byte{0, 13, 123}: "Consensys Computers Inc.", + [3]byte{0, 13, 124}: "Codian Ltd", + [3]byte{0, 13, 125}: "Afco Systems", + [3]byte{0, 13, 126}: "Axiowave Networks, Inc.", + [3]byte{0, 13, 127}: "MIDAS COMMUNICATION TECHNOLOGIES PTE LTD ( Foreign Branch)", + [3]byte{0, 13, 128}: "Online Development Inc", + [3]byte{0, 13, 129}: "Pepperl+Fuchs GmbH", + [3]byte{0, 13, 130}: "PHS srl", + [3]byte{0, 13, 131}: "Sanmina-SCI Hungary Ltd.", + [3]byte{0, 13, 132}: "Makus Inc.", + [3]byte{0, 13, 133}: "Tapwave, Inc.", + [3]byte{0, 13, 134}: "Huber + Suhner AG", + [3]byte{0, 13, 135}: "Elitegroup Computer System Co. (ECS)", + [3]byte{0, 13, 136}: "D-Link Corporation", + [3]byte{0, 13, 137}: "Bils Technology Inc", + [3]byte{0, 13, 138}: "Winners Electronics Co., Ltd.", + [3]byte{0, 13, 139}: "T&D Corporation", + [3]byte{0, 13, 140}: "Shanghai Wedone Digital Ltd. CO.", + [3]byte{0, 13, 141}: "Prosoft Technology, Inc", + [3]byte{0, 13, 142}: "Koden Electronics Co., Ltd.", + [3]byte{0, 13, 143}: "King Tsushin Kogyo Co., LTD.", + [3]byte{0, 13, 144}: "Factum Electronics AB", + [3]byte{0, 13, 145}: "Eclipse (HQ Espana) S.L.", + [3]byte{0, 13, 146}: "Arima Communication Corporation", + [3]byte{0, 13, 147}: "Apple", + [3]byte{0, 13, 148}: "AFAR Communications,Inc", + [3]byte{0, 13, 149}: "Opti-cell, Inc.", + [3]byte{0, 13, 150}: "Vtera Technology Inc.", + [3]byte{0, 13, 151}: "Tropos Networks, Inc.", + [3]byte{0, 13, 152}: "S.W.A.C. Schmitt-Walter Automation Consult GmbH", + [3]byte{0, 13, 153}: "Orbital Sciences Corp.; Launch Systems Group", + [3]byte{0, 13, 154}: "INFOTEC LTD", + [3]byte{0, 13, 155}: "Heraeus Electro-Nite International N.V.", + [3]byte{0, 13, 156}: "Elan GmbH & Co KG", + [3]byte{0, 13, 157}: "Hewlett-Packard Company", + [3]byte{0, 13, 158}: "TOKUDEN OHIZUMI SEISAKUSYO Co.,Ltd.", + [3]byte{0, 13, 159}: "RF Micro Devices", + [3]byte{0, 13, 160}: "NEDAP N.V.", + [3]byte{0, 13, 161}: "MIRAE ITS Co.,LTD.", + [3]byte{0, 13, 162}: "Infrant Technologies, Inc.", + [3]byte{0, 13, 163}: "Emerging Technologies Limited", + [3]byte{0, 13, 164}: "DOSCH & AMAND SYSTEMS AG", + [3]byte{0, 13, 165}: "Fabric7 Systems, Inc", + [3]byte{0, 13, 166}: "Universal Switching Corporation", + [3]byte{0, 13, 167}: "PRIVATE", + [3]byte{0, 13, 168}: "Teletronics Technology Corporation", + [3]byte{0, 13, 169}: "T.E.A.M. S.L.", + [3]byte{0, 13, 170}: "S.A.Tehnology co.,Ltd.", + [3]byte{0, 13, 171}: "Parker Hannifin GmbH Electromechanical Division Europe", + [3]byte{0, 13, 172}: "Japan CBM Corporation", + [3]byte{0, 13, 173}: "Dataprobe, Inc.", + [3]byte{0, 13, 174}: "SAMSUNG HEAVY INDUSTRIES CO., LTD.", + [3]byte{0, 13, 175}: "Plexus Corp (UK) Ltd", + [3]byte{0, 13, 176}: "Olym-tech Co.,Ltd.", + [3]byte{0, 13, 177}: "Japan Network Service Co., Ltd.", + [3]byte{0, 13, 178}: "Ammasso, Inc.", + [3]byte{0, 13, 179}: "SDO Communication Corperation", + [3]byte{0, 13, 180}: "NETASQ", + [3]byte{0, 13, 181}: "GLOBALSAT TECHNOLOGY CORPORATION", + [3]byte{0, 13, 182}: "Broadcom Corporation", + [3]byte{0, 13, 183}: "SANKO ELECTRIC CO,.LTD", + [3]byte{0, 13, 184}: "SCHILLER AG", + [3]byte{0, 13, 185}: "PC Engines GmbH", + [3]byte{0, 13, 186}: "Océ Document Technologies GmbH", + [3]byte{0, 13, 187}: "Nippon Dentsu Co.,Ltd.", + [3]byte{0, 13, 188}: "CISCO SYSTEMS, INC.", + [3]byte{0, 13, 189}: "CISCO SYSTEMS, INC.", + [3]byte{0, 13, 190}: "Bel Fuse Europe Ltd.,UK", + [3]byte{0, 13, 191}: "TekTone Sound & Signal Mfg., Inc.", + [3]byte{0, 13, 192}: "Spagat AS", + [3]byte{0, 13, 193}: "SafeWeb Inc", + [3]byte{0, 13, 194}: "PRIVATE", + [3]byte{0, 13, 195}: "First Communication, Inc.", + [3]byte{0, 13, 196}: "Emcore Corporation", + [3]byte{0, 13, 197}: "EchoStar Global B.V.", + [3]byte{0, 13, 198}: "DigiRose Technology Co., Ltd.", + [3]byte{0, 13, 199}: "COSMIC ENGINEERING INC.", + [3]byte{0, 13, 200}: "AirMagnet, Inc", + [3]byte{0, 13, 201}: "THALES Elektronik Systeme GmbH", + [3]byte{0, 13, 202}: "Tait Electronics", + [3]byte{0, 13, 203}: "Petcomkorea Co., Ltd.", + [3]byte{0, 13, 204}: "NEOSMART Corp.", + [3]byte{0, 13, 205}: "GROUPE TXCOM", + [3]byte{0, 13, 206}: "Dynavac Technology Pte Ltd", + [3]byte{0, 13, 207}: "Cidra Corp.", + [3]byte{0, 13, 208}: "TetraTec Instruments GmbH", + [3]byte{0, 13, 209}: "Stryker Corporation", + [3]byte{0, 13, 210}: "Simrad Optronics ASA", + [3]byte{0, 13, 211}: "SAMWOO Telecommunication Co.,Ltd.", + [3]byte{0, 13, 212}: "Symantec Corporation", + [3]byte{0, 13, 213}: "O'RITE TECHNOLOGY CO.,LTD", + [3]byte{0, 13, 214}: "ITI LTD", + [3]byte{0, 13, 215}: "Bright", + [3]byte{0, 13, 216}: "BBN", + [3]byte{0, 13, 217}: "Anton Paar GmbH", + [3]byte{0, 13, 218}: "ALLIED TELESIS K.K.", + [3]byte{0, 13, 219}: "AIRWAVE TECHNOLOGIES INC.", + [3]byte{0, 13, 220}: "VAC", + [3]byte{0, 13, 221}: "Profilo Telra Elektronik Sanayi ve Ticaret. A.Ş", + [3]byte{0, 13, 222}: "Joyteck Co., Ltd.", + [3]byte{0, 13, 223}: "Japan Image & Network Inc.", + [3]byte{0, 13, 224}: "ICPDAS Co.,LTD", + [3]byte{0, 13, 225}: "Control Products, Inc.", + [3]byte{0, 13, 226}: "CMZ Sistemi Elettronici", + [3]byte{0, 13, 227}: "AT Sweden AB", + [3]byte{0, 13, 228}: "DIGINICS, Inc.", + [3]byte{0, 13, 229}: "Samsung Thales", + [3]byte{0, 13, 230}: "YOUNGBO ENGINEERING CO.,LTD", + [3]byte{0, 13, 231}: "Snap-on OEM Group", + [3]byte{0, 13, 232}: "Nasaco Electronics Pte. Ltd", + [3]byte{0, 13, 233}: "Napatech Aps", + [3]byte{0, 13, 234}: "Kingtel Telecommunication Corp.", + [3]byte{0, 13, 235}: "CompXs Limited", + [3]byte{0, 13, 236}: "CISCO SYSTEMS, INC.", + [3]byte{0, 13, 237}: "CISCO SYSTEMS, INC.", + [3]byte{0, 13, 238}: "Andrew RF Power Amplifier Group", + [3]byte{0, 13, 239}: "Soc. Coop. Bilanciai", + [3]byte{0, 13, 240}: "QCOM TECHNOLOGY INC.", + [3]byte{0, 13, 241}: "IONIX INC.", + [3]byte{0, 13, 242}: "PRIVATE", + [3]byte{0, 13, 243}: "Asmax Solutions", + [3]byte{0, 13, 244}: "Watertek Co.", + [3]byte{0, 13, 245}: "Teletronics International Inc.", + [3]byte{0, 13, 246}: "Technology Thesaurus Corp.", + [3]byte{0, 13, 247}: "Space Dynamics Lab", + [3]byte{0, 13, 248}: "ORGA Kartensysteme GmbH", + [3]byte{0, 13, 249}: "NDS Limited", + [3]byte{0, 13, 250}: "Micro Control Systems Ltd.", + [3]byte{0, 13, 251}: "Komax AG", + [3]byte{0, 13, 252}: "ITFOR Inc.", + [3]byte{0, 13, 253}: "Huges Hi-Tech Inc.,", + [3]byte{0, 13, 254}: "Hauppauge Computer Works, Inc.", + [3]byte{0, 13, 255}: "CHENMING MOLD INDUSTRY CORP.", + [3]byte{0, 14, 0}: "Atrie", + [3]byte{0, 14, 1}: "ASIP Technologies Inc.", + [3]byte{0, 14, 2}: "Advantech AMT Inc.", + [3]byte{0, 14, 3}: "Emulex Corporation", + [3]byte{0, 14, 4}: "CMA/Microdialysis AB", + [3]byte{0, 14, 5}: "WIRELESS MATRIX CORP.", + [3]byte{0, 14, 6}: "Team Simoco Ltd", + [3]byte{0, 14, 7}: "Sony Ericsson Mobile Communications AB", + [3]byte{0, 14, 8}: "Cisco Linksys LLC", + [3]byte{0, 14, 9}: "Shenzhen Coship Software Co.,LTD.", + [3]byte{0, 14, 10}: "SAKUMA DESIGN OFFICE", + [3]byte{0, 14, 11}: "Netac Technology Co., Ltd.", + [3]byte{0, 14, 12}: "Intel Corporation", + [3]byte{0, 14, 13}: "Hesch Schröder GmbH", + [3]byte{0, 14, 14}: "ESA elettronica S.P.A.", + [3]byte{0, 14, 15}: "ERMME", + [3]byte{0, 14, 16}: "C-guys, Inc.", + [3]byte{0, 14, 17}: "BDT Büro und Datentechnik GmbH & Co.KG", + [3]byte{0, 14, 18}: "Adaptive Micro Systems Inc.", + [3]byte{0, 14, 19}: "Accu-Sort Systems inc.", + [3]byte{0, 14, 20}: "Visionary Solutions, Inc.", + [3]byte{0, 14, 21}: "Tadlys LTD", + [3]byte{0, 14, 22}: "SouthWing S.L.", + [3]byte{0, 14, 23}: "PRIVATE", + [3]byte{0, 14, 24}: "MyA Technology", + [3]byte{0, 14, 25}: "LogicaCMG Pty Ltd", + [3]byte{0, 14, 26}: "JPS Communications", + [3]byte{0, 14, 27}: "IAV GmbH", + [3]byte{0, 14, 28}: "Hach Company", + [3]byte{0, 14, 29}: "ARION Technology Inc.", + [3]byte{0, 14, 30}: "QLogic Corporation", + [3]byte{0, 14, 31}: "TCL Networks Equipment Co., Ltd.", + [3]byte{0, 14, 32}: "ACCESS Systems Americas, Inc.", + [3]byte{0, 14, 33}: "MTU Friedrichshafen GmbH", + [3]byte{0, 14, 34}: "PRIVATE", + [3]byte{0, 14, 35}: "Incipient, Inc.", + [3]byte{0, 14, 36}: "Huwell Technology Inc.", + [3]byte{0, 14, 37}: "Hannae Technology Co., Ltd", + [3]byte{0, 14, 38}: "Gincom Technology Corp.", + [3]byte{0, 14, 39}: "Crere Networks, Inc.", + [3]byte{0, 14, 40}: "Dynamic Ratings P/L", + [3]byte{0, 14, 41}: "Shester Communications Inc", + [3]byte{0, 14, 42}: "PRIVATE", + [3]byte{0, 14, 43}: "Safari Technologies", + [3]byte{0, 14, 44}: "Netcodec co.", + [3]byte{0, 14, 45}: "Hyundai Digital Technology Co.,Ltd.", + [3]byte{0, 14, 46}: "Edimax Technology Co., Ltd.", + [3]byte{0, 14, 47}: "Roche Diagnostics GmbH", + [3]byte{0, 14, 48}: "AERAS Networks, Inc.", + [3]byte{0, 14, 49}: "Olympus Soft Imaging Solutions GmbH", + [3]byte{0, 14, 50}: "Kontron Medical", + [3]byte{0, 14, 51}: "Shuko Electronics Co.,Ltd", + [3]byte{0, 14, 52}: "NexGen City, LP", + [3]byte{0, 14, 53}: "Intel Corp", + [3]byte{0, 14, 54}: "HEINESYS, Inc.", + [3]byte{0, 14, 55}: "Harms & Wende GmbH & Co.KG", + [3]byte{0, 14, 56}: "CISCO SYSTEMS, INC.", + [3]byte{0, 14, 57}: "CISCO SYSTEMS, INC.", + [3]byte{0, 14, 58}: "Cirrus Logic", + [3]byte{0, 14, 59}: "Hawking Technologies, Inc.", + [3]byte{0, 14, 60}: "Transact Technologies Inc", + [3]byte{0, 14, 61}: "Televic N.V.", + [3]byte{0, 14, 62}: "Sun Optronics Inc", + [3]byte{0, 14, 63}: "Soronti, Inc.", + [3]byte{0, 14, 64}: "Nortel Networks", + [3]byte{0, 14, 65}: "NIHON MECHATRONICS CO.,LTD.", + [3]byte{0, 14, 66}: "Motic Incoporation Ltd.", + [3]byte{0, 14, 67}: "G-Tek Electronics Sdn. Bhd.", + [3]byte{0, 14, 68}: "Digital 5, Inc.", + [3]byte{0, 14, 69}: "Beijing Newtry Electronic Technology Ltd", + [3]byte{0, 14, 70}: "Niigata Seimitsu Co.,Ltd.", + [3]byte{0, 14, 71}: "NCI System Co.,Ltd.", + [3]byte{0, 14, 72}: "Lipman TransAction Solutions", + [3]byte{0, 14, 73}: "Forsway Scandinavia AB", + [3]byte{0, 14, 74}: "Changchun Huayu WEBPAD Co.,LTD", + [3]byte{0, 14, 75}: "atrium c and i", + [3]byte{0, 14, 76}: "Bermai Inc.", + [3]byte{0, 14, 77}: "Numesa Inc.", + [3]byte{0, 14, 78}: "Waveplus Technology Co., Ltd.", + [3]byte{0, 14, 79}: "Trajet GmbH", + [3]byte{0, 14, 80}: "Thomson Telecom Belgium", + [3]byte{0, 14, 81}: "tecna elettronica srl", + [3]byte{0, 14, 82}: "Optium Corporation", + [3]byte{0, 14, 83}: "AV TECH CORPORATION", + [3]byte{0, 14, 84}: "AlphaCell Wireless Ltd.", + [3]byte{0, 14, 85}: "AUVITRAN", + [3]byte{0, 14, 86}: "4G Systems GmbH & Co. KG", + [3]byte{0, 14, 87}: "Iworld Networking, Inc.", + [3]byte{0, 14, 88}: "Sonos, Inc.", + [3]byte{0, 14, 89}: "SAGEM SA", + [3]byte{0, 14, 90}: "TELEFIELD inc.", + [3]byte{0, 14, 91}: "ParkerVision - Direct2Data", + [3]byte{0, 14, 92}: "ARRIS Group, Inc.", + [3]byte{0, 14, 93}: "Triple Play Technologies A/S", + [3]byte{0, 14, 94}: "Raisecom Technology", + [3]byte{0, 14, 95}: "activ-net GmbH & Co. KG", + [3]byte{0, 14, 96}: "360SUN Digital Broadband Corporation", + [3]byte{0, 14, 97}: "MICROTROL LIMITED", + [3]byte{0, 14, 98}: "Nortel Networks", + [3]byte{0, 14, 99}: "Lemke Diagnostics GmbH", + [3]byte{0, 14, 100}: "Elphel, Inc", + [3]byte{0, 14, 101}: "TransCore", + [3]byte{0, 14, 102}: "Hitachi Industry & Control Solutions, Ltd.", + [3]byte{0, 14, 103}: "Eltis Microelectronics Ltd.", + [3]byte{0, 14, 104}: "E-TOP Network Technology Inc.", + [3]byte{0, 14, 105}: "China Electric Power Research Institute", + [3]byte{0, 14, 106}: "3Com Ltd", + [3]byte{0, 14, 107}: "Janitza electronics GmbH", + [3]byte{0, 14, 108}: "Device Drivers Limited", + [3]byte{0, 14, 109}: "Murata Manufacturing Co., Ltd.", + [3]byte{0, 14, 110}: "MAT S.A. (Mircrelec Advanced Technology)", + [3]byte{0, 14, 111}: "IRIS Corporation Berhad", + [3]byte{0, 14, 112}: "in2 Networks", + [3]byte{0, 14, 113}: "Gemstar Technology Development Ltd.", + [3]byte{0, 14, 114}: "CTS electronics", + [3]byte{0, 14, 115}: "Tpack A/S", + [3]byte{0, 14, 116}: "Solar Telecom. Tech", + [3]byte{0, 14, 117}: "New York Air Brake Corp.", + [3]byte{0, 14, 118}: "GEMSOC INNOVISION INC.", + [3]byte{0, 14, 119}: "Decru, Inc.", + [3]byte{0, 14, 120}: "Amtelco", + [3]byte{0, 14, 121}: "Ample Communications Inc.", + [3]byte{0, 14, 122}: "GemWon Communications Co., Ltd.", + [3]byte{0, 14, 123}: "Toshiba", + [3]byte{0, 14, 124}: "Televes S.A.", + [3]byte{0, 14, 125}: "Electronics Line 3000 Ltd.", + [3]byte{0, 14, 126}: "ionSign Oy", + [3]byte{0, 14, 127}: "Hewlett-Packard Company", + [3]byte{0, 14, 128}: "Thomson Technology Inc", + [3]byte{0, 14, 129}: "Devicescape Software, Inc.", + [3]byte{0, 14, 130}: "Commtech Wireless", + [3]byte{0, 14, 131}: "CISCO SYSTEMS, INC.", + [3]byte{0, 14, 132}: "CISCO SYSTEMS, INC.", + [3]byte{0, 14, 133}: "Catalyst Enterprises, Inc.", + [3]byte{0, 14, 134}: "Alcatel North America", + [3]byte{0, 14, 135}: "adp Gauselmann GmbH", + [3]byte{0, 14, 136}: "VIDEOTRON CORP.", + [3]byte{0, 14, 137}: "CLEMATIC", + [3]byte{0, 14, 138}: "Avara Technologies Pty. Ltd.", + [3]byte{0, 14, 139}: "Astarte Technology Co, Ltd.", + [3]byte{0, 14, 140}: "Siemens AG A&D ET", + [3]byte{0, 14, 141}: "Systems in Progress Holding GmbH", + [3]byte{0, 14, 142}: "SparkLAN Communications, Inc.", + [3]byte{0, 14, 143}: "Sercomm Corp.", + [3]byte{0, 14, 144}: "PONICO CORP.", + [3]byte{0, 14, 145}: "Navico Auckland Ltd", + [3]byte{0, 14, 146}: "Open Telecom", + [3]byte{0, 14, 147}: "Milénio 3 Sistemas Electrónicos, Lda.", + [3]byte{0, 14, 148}: "Maas International BV", + [3]byte{0, 14, 149}: "Fujiya Denki Seisakusho Co.,Ltd.", + [3]byte{0, 14, 150}: "Cubic Defense Applications, Inc.", + [3]byte{0, 14, 151}: "Ultracker Technology CO., Inc", + [3]byte{0, 14, 152}: "HME Clear-Com LTD.", + [3]byte{0, 14, 153}: "Spectrum Digital, Inc", + [3]byte{0, 14, 154}: "BOE TECHNOLOGY GROUP CO.,LTD", + [3]byte{0, 14, 155}: "Ambit Microsystems Corporation", + [3]byte{0, 14, 156}: "Benchmark Electronics", + [3]byte{0, 14, 157}: "Tiscali UK Ltd", + [3]byte{0, 14, 158}: "Topfield Co., Ltd", + [3]byte{0, 14, 159}: "TEMIC SDS GmbH", + [3]byte{0, 14, 160}: "NetKlass Technology Inc.", + [3]byte{0, 14, 161}: "Formosa Teletek Corporation", + [3]byte{0, 14, 162}: "McAfee, Inc", + [3]byte{0, 14, 163}: "CNCR-IT CO.,LTD,HangZhou P.R.CHINA", + [3]byte{0, 14, 164}: "Certance Inc.", + [3]byte{0, 14, 165}: "BLIP Systems", + [3]byte{0, 14, 166}: "ASUSTEK COMPUTER INC.", + [3]byte{0, 14, 167}: "Endace Technology", + [3]byte{0, 14, 168}: "United Technologists Europe Limited", + [3]byte{0, 14, 169}: "Shanghai Xun Shi Communications Equipment Ltd. Co.", + [3]byte{0, 14, 170}: "Scalent Systems, Inc.", + [3]byte{0, 14, 171}: "Cray Inc", + [3]byte{0, 14, 172}: "MINTRON ENTERPRISE CO., LTD.", + [3]byte{0, 14, 173}: "Metanoia Technologies, Inc.", + [3]byte{0, 14, 174}: "GAWELL TECHNOLOGIES CORP.", + [3]byte{0, 14, 175}: "CASTEL", + [3]byte{0, 14, 176}: "Solutions Radio BV", + [3]byte{0, 14, 177}: "Newcotech,Ltd", + [3]byte{0, 14, 178}: "Micro-Research Finland Oy", + [3]byte{0, 14, 179}: "Hewlett-Packard", + [3]byte{0, 14, 180}: "GUANGZHOU GAOKE COMMUNICATIONS TECHNOLOGY CO.LTD.", + [3]byte{0, 14, 181}: "Ecastle Electronics Co., Ltd.", + [3]byte{0, 14, 182}: "Riverbed Technology, Inc.", + [3]byte{0, 14, 183}: "Knovative, Inc.", + [3]byte{0, 14, 184}: "Iiga co.,Ltd", + [3]byte{0, 14, 185}: "HASHIMOTO Electronics Industry Co.,Ltd.", + [3]byte{0, 14, 186}: "HANMI SEMICONDUCTOR CO., LTD.", + [3]byte{0, 14, 187}: "Everbee Networks", + [3]byte{0, 14, 188}: "Paragon Fidelity GmbH", + [3]byte{0, 14, 189}: "Burdick, a Quinton Compny", + [3]byte{0, 14, 190}: "B&B Electronics Manufacturing Co.", + [3]byte{0, 14, 191}: "Remsdaq Limited", + [3]byte{0, 14, 192}: "Nortel Networks", + [3]byte{0, 14, 193}: "MYNAH Technologies", + [3]byte{0, 14, 194}: "Lowrance Electronics, Inc.", + [3]byte{0, 14, 195}: "Logic Controls, Inc.", + [3]byte{0, 14, 196}: "Iskra Transmission d.d.", + [3]byte{0, 14, 197}: "Digital Multitools Inc", + [3]byte{0, 14, 198}: "ASIX ELECTRONICS CORP.", + [3]byte{0, 14, 199}: "Motorola Korea", + [3]byte{0, 14, 200}: "Zoran Corporation", + [3]byte{0, 14, 201}: "YOKO Technology Corp.", + [3]byte{0, 14, 202}: "WTSS Inc", + [3]byte{0, 14, 203}: "VineSys Technology", + [3]byte{0, 14, 204}: "Tableau, LLC", + [3]byte{0, 14, 205}: "SKOV A/S", + [3]byte{0, 14, 206}: "S.I.T.T.I. S.p.A.", + [3]byte{0, 14, 207}: "PROFIBUS Nutzerorganisation e.V.", + [3]byte{0, 14, 208}: "Privaris, Inc.", + [3]byte{0, 14, 209}: "Osaka Micro Computer.", + [3]byte{0, 14, 210}: "Filtronic plc", + [3]byte{0, 14, 211}: "Epicenter, Inc.", + [3]byte{0, 14, 212}: "CRESITT INDUSTRIE", + [3]byte{0, 14, 213}: "COPAN Systems Inc.", + [3]byte{0, 14, 214}: "CISCO SYSTEMS, INC.", + [3]byte{0, 14, 215}: "CISCO SYSTEMS, INC.", + [3]byte{0, 14, 216}: "Aktino, Inc.", + [3]byte{0, 14, 217}: "Aksys, Ltd.", + [3]byte{0, 14, 218}: "C-TECH UNITED CORP.", + [3]byte{0, 14, 219}: "XiNCOM Corp.", + [3]byte{0, 14, 220}: "Tellion INC.", + [3]byte{0, 14, 221}: "SHURE INCORPORATED", + [3]byte{0, 14, 222}: "REMEC, Inc.", + [3]byte{0, 14, 223}: "PLX Technology", + [3]byte{0, 14, 224}: "Mcharge", + [3]byte{0, 14, 225}: "ExtremeSpeed Inc.", + [3]byte{0, 14, 226}: "Custom Engineering", + [3]byte{0, 14, 227}: "Chiyu Technology Co.,Ltd", + [3]byte{0, 14, 228}: "BOE TECHNOLOGY GROUP CO.,LTD", + [3]byte{0, 14, 229}: "bitWallet, Inc.", + [3]byte{0, 14, 230}: "Adimos Systems LTD", + [3]byte{0, 14, 231}: "AAC ELECTRONICS CORP.", + [3]byte{0, 14, 232}: "zioncom", + [3]byte{0, 14, 233}: "WayTech Development, Inc.", + [3]byte{0, 14, 234}: "Shadong Luneng Jicheng Electronics,Co.,Ltd", + [3]byte{0, 14, 235}: "Sandmartin(zhong shan)Electronics Co.,Ltd", + [3]byte{0, 14, 236}: "Orban", + [3]byte{0, 14, 237}: "Nokia Danmark A/S", + [3]byte{0, 14, 238}: "Muco Industrie BV", + [3]byte{0, 14, 239}: "PRIVATE", + [3]byte{0, 14, 240}: "Festo AG & Co. KG", + [3]byte{0, 14, 241}: "EZQUEST INC.", + [3]byte{0, 14, 242}: "Infinico Corporation", + [3]byte{0, 14, 243}: "Smarthome", + [3]byte{0, 14, 244}: "Kasda Digital Technology Co.,Ltd", + [3]byte{0, 14, 245}: "iPAC Technology Co., Ltd.", + [3]byte{0, 14, 246}: "E-TEN Information Systems Co., Ltd.", + [3]byte{0, 14, 247}: "Vulcan Portals Inc", + [3]byte{0, 14, 248}: "SBC ASI", + [3]byte{0, 14, 249}: "REA Elektronik GmbH", + [3]byte{0, 14, 250}: "Optoway Technology Incorporation", + [3]byte{0, 14, 251}: "Macey Enterprises", + [3]byte{0, 14, 252}: "JTAG Technologies B.V.", + [3]byte{0, 14, 253}: "FUJINON CORPORATION", + [3]byte{0, 14, 254}: "EndRun Technologies LLC", + [3]byte{0, 14, 255}: "Megasolution,Inc.", + [3]byte{0, 15, 0}: "Legra Systems, Inc.", + [3]byte{0, 15, 1}: "DIGITALKS INC", + [3]byte{0, 15, 2}: "Digicube Technology Co., Ltd", + [3]byte{0, 15, 3}: "COM&C CO., LTD", + [3]byte{0, 15, 4}: "cim-usa inc", + [3]byte{0, 15, 5}: "3B SYSTEM INC.", + [3]byte{0, 15, 6}: "Nortel Networks", + [3]byte{0, 15, 7}: "Mangrove Systems, Inc.", + [3]byte{0, 15, 8}: "Indagon Oy", + [3]byte{0, 15, 9}: "PRIVATE", + [3]byte{0, 15, 10}: "Clear Edge Networks", + [3]byte{0, 15, 11}: "Kentima Technologies AB", + [3]byte{0, 15, 12}: "SYNCHRONIC ENGINEERING", + [3]byte{0, 15, 13}: "Hunt Electronic Co., Ltd.", + [3]byte{0, 15, 14}: "WaveSplitter Technologies, Inc.", + [3]byte{0, 15, 15}: "Real ID Technology Co., Ltd.", + [3]byte{0, 15, 16}: "RDM Corporation", + [3]byte{0, 15, 17}: "Prodrive B.V.", + [3]byte{0, 15, 18}: "Panasonic Europe Ltd.", + [3]byte{0, 15, 19}: "Nisca corporation", + [3]byte{0, 15, 20}: "Mindray Co., Ltd.", + [3]byte{0, 15, 21}: "Kjaerulff1 A/S", + [3]byte{0, 15, 22}: "JAY HOW TECHNOLOGY CO.,", + [3]byte{0, 15, 23}: "Insta Elektro GmbH", + [3]byte{0, 15, 24}: "Industrial Control Systems", + [3]byte{0, 15, 25}: "Boston Scientific", + [3]byte{0, 15, 26}: "Gaming Support B.V.", + [3]byte{0, 15, 27}: "Ego Systems Inc.", + [3]byte{0, 15, 28}: "DigitAll World Co., Ltd", + [3]byte{0, 15, 29}: "Cosmo Techs Co., Ltd.", + [3]byte{0, 15, 30}: "Chengdu KT Electric Co.of High & New Technology", + [3]byte{0, 15, 31}: "Dell Inc", + [3]byte{0, 15, 32}: "Hewlett-Packard Company", + [3]byte{0, 15, 33}: "Scientific Atlanta, Inc", + [3]byte{0, 15, 34}: "Helius, Inc.", + [3]byte{0, 15, 35}: "CISCO SYSTEMS, INC.", + [3]byte{0, 15, 36}: "CISCO SYSTEMS, INC.", + [3]byte{0, 15, 37}: "AimValley B.V.", + [3]byte{0, 15, 38}: "WorldAccxx LLC", + [3]byte{0, 15, 39}: "TEAL Electronics, Inc.", + [3]byte{0, 15, 40}: "Itronix Corporation", + [3]byte{0, 15, 41}: "Augmentix Corporation", + [3]byte{0, 15, 42}: "Cableware Electronics", + [3]byte{0, 15, 43}: "GREENBELL SYSTEMS", + [3]byte{0, 15, 44}: "Uplogix, Inc.", + [3]byte{0, 15, 45}: "CHUNG-HSIN ELECTRIC & MACHINERY MFG.CORP.", + [3]byte{0, 15, 46}: "Megapower International Corp.", + [3]byte{0, 15, 47}: "W-LINX TECHNOLOGY CO., LTD.", + [3]byte{0, 15, 48}: "Raza Microelectronics Inc", + [3]byte{0, 15, 49}: "Allied Vision Technologies Canada Inc", + [3]byte{0, 15, 50}: "Lootom Telcovideo Network Wuxi Co Ltd", + [3]byte{0, 15, 51}: "DUALi Inc.", + [3]byte{0, 15, 52}: "CISCO SYSTEMS, INC.", + [3]byte{0, 15, 53}: "CISCO SYSTEMS, INC.", + [3]byte{0, 15, 54}: "Accurate Techhnologies, Inc.", + [3]byte{0, 15, 55}: "Xambala Incorporated", + [3]byte{0, 15, 56}: "Netstar", + [3]byte{0, 15, 57}: "IRIS SENSORS", + [3]byte{0, 15, 58}: "HISHARP", + [3]byte{0, 15, 59}: "Fuji System Machines Co., Ltd.", + [3]byte{0, 15, 60}: "Endeleo Limited", + [3]byte{0, 15, 61}: "D-Link Corporation", + [3]byte{0, 15, 62}: "CardioNet, Inc", + [3]byte{0, 15, 63}: "Big Bear Networks", + [3]byte{0, 15, 64}: "Optical Internetworking Forum", + [3]byte{0, 15, 65}: "Zipher Ltd", + [3]byte{0, 15, 66}: "Xalyo Systems", + [3]byte{0, 15, 67}: "Wasabi Systems Inc.", + [3]byte{0, 15, 68}: "Tivella Inc.", + [3]byte{0, 15, 69}: "Stretch, Inc.", + [3]byte{0, 15, 70}: "SINAR AG", + [3]byte{0, 15, 71}: "ROBOX SPA", + [3]byte{0, 15, 72}: "Polypix Inc.", + [3]byte{0, 15, 73}: "Northover Solutions Limited", + [3]byte{0, 15, 74}: "Kyushu-kyohan co.,ltd", + [3]byte{0, 15, 75}: "Oracle Corporation", + [3]byte{0, 15, 76}: "Elextech INC", + [3]byte{0, 15, 77}: "TalkSwitch", + [3]byte{0, 15, 78}: "Cellink", + [3]byte{0, 15, 79}: "Cadmus Technology Ltd", + [3]byte{0, 15, 80}: "StreamScale Limited", + [3]byte{0, 15, 81}: "Azul Systems, Inc.", + [3]byte{0, 15, 82}: "YORK Refrigeration, Marine & Controls", + [3]byte{0, 15, 83}: "Solarflare Communications Inc", + [3]byte{0, 15, 84}: "Entrelogic Corporation", + [3]byte{0, 15, 85}: "Datawire Communication Networks Inc.", + [3]byte{0, 15, 86}: "Continuum Photonics Inc", + [3]byte{0, 15, 87}: "CABLELOGIC Co., Ltd.", + [3]byte{0, 15, 88}: "Adder Technology Limited", + [3]byte{0, 15, 89}: "Phonak Communications AG", + [3]byte{0, 15, 90}: "Peribit Networks", + [3]byte{0, 15, 91}: "Delta Information Systems, Inc.", + [3]byte{0, 15, 92}: "Day One Digital Media Limited", + [3]byte{0, 15, 93}: "Genexis BV", + [3]byte{0, 15, 94}: "Veo", + [3]byte{0, 15, 95}: "Nicety Technologies Inc. (NTS)", + [3]byte{0, 15, 96}: "Lifetron Co.,Ltd", + [3]byte{0, 15, 97}: "Hewlett-Packard Company", + [3]byte{0, 15, 98}: "Alcatel Bell Space N.V.", + [3]byte{0, 15, 99}: "Obzerv Technologies", + [3]byte{0, 15, 100}: "D&R Electronica Weesp BV", + [3]byte{0, 15, 101}: "icube Corp.", + [3]byte{0, 15, 102}: "Cisco-Linksys", + [3]byte{0, 15, 103}: "West Instruments", + [3]byte{0, 15, 104}: "Vavic Network Technology, Inc.", + [3]byte{0, 15, 105}: "SEW Eurodrive GmbH & Co. KG", + [3]byte{0, 15, 106}: "Nortel Networks", + [3]byte{0, 15, 107}: "GateWare Communications GmbH", + [3]byte{0, 15, 108}: "ADDI-DATA GmbH", + [3]byte{0, 15, 109}: "Midas Engineering", + [3]byte{0, 15, 110}: "BBox", + [3]byte{0, 15, 111}: "FTA Communication Technologies", + [3]byte{0, 15, 112}: "Wintec Industries, inc.", + [3]byte{0, 15, 113}: "Sanmei Electronics Co.,Ltd", + [3]byte{0, 15, 114}: "Sandburst", + [3]byte{0, 15, 115}: "RS Automation Co., Ltd", + [3]byte{0, 15, 116}: "Qamcom Technology AB", + [3]byte{0, 15, 117}: "First Silicon Solutions", + [3]byte{0, 15, 118}: "Digital Keystone, Inc.", + [3]byte{0, 15, 119}: "DENTUM CO.,LTD", + [3]byte{0, 15, 120}: "Datacap Systems Inc", + [3]byte{0, 15, 121}: "Bluetooth Interest Group Inc.", + [3]byte{0, 15, 122}: "BeiJing NuQX Technology CO.,LTD", + [3]byte{0, 15, 123}: "Arce Sistemas, S.A.", + [3]byte{0, 15, 124}: "ACTi Corporation", + [3]byte{0, 15, 125}: "Xirrus", + [3]byte{0, 15, 126}: "Ablerex Electronics Co., LTD", + [3]byte{0, 15, 127}: "UBSTORAGE Co.,Ltd.", + [3]byte{0, 15, 128}: "Trinity Security Systems,Inc.", + [3]byte{0, 15, 129}: "PAL Pacific Inc.", + [3]byte{0, 15, 130}: "Mortara Instrument, Inc.", + [3]byte{0, 15, 131}: "Brainium Technologies Inc.", + [3]byte{0, 15, 132}: "Astute Networks, Inc.", + [3]byte{0, 15, 133}: "ADDO-Japan Corporation", + [3]byte{0, 15, 134}: "Research In Motion Limited", + [3]byte{0, 15, 135}: "Maxcess International", + [3]byte{0, 15, 136}: "AMETEK, Inc.", + [3]byte{0, 15, 137}: "Winnertec System Co., Ltd.", + [3]byte{0, 15, 138}: "WideView", + [3]byte{0, 15, 139}: "Orion MultiSystems Inc", + [3]byte{0, 15, 140}: "Gigawavetech Pte Ltd", + [3]byte{0, 15, 141}: "FAST TV-Server AG", + [3]byte{0, 15, 142}: "DONGYANG TELECOM CO.,LTD.", + [3]byte{0, 15, 143}: "CISCO SYSTEMS, INC.", + [3]byte{0, 15, 144}: "CISCO SYSTEMS, INC.", + [3]byte{0, 15, 145}: "Aerotelecom Co.,Ltd.", + [3]byte{0, 15, 146}: "Microhard Systems Inc.", + [3]byte{0, 15, 147}: "Landis+Gyr Ltd.", + [3]byte{0, 15, 148}: "Genexis BV", + [3]byte{0, 15, 149}: "ELECOM Co.,LTD Laneed Division", + [3]byte{0, 15, 150}: "Telco Systems, Inc.", + [3]byte{0, 15, 151}: "Avanex Corporation", + [3]byte{0, 15, 152}: "Avamax Co. Ltd.", + [3]byte{0, 15, 153}: "APAC opto Electronics Inc.", + [3]byte{0, 15, 154}: "Synchrony, Inc.", + [3]byte{0, 15, 155}: "Ross Video Limited", + [3]byte{0, 15, 156}: "Panduit Corp", + [3]byte{0, 15, 157}: "DisplayLink (UK) Ltd", + [3]byte{0, 15, 158}: "Murrelektronik GmbH", + [3]byte{0, 15, 159}: "ARRIS Group, Inc.", + [3]byte{0, 15, 160}: "CANON KOREA BUSINESS SOLUTIONS INC.", + [3]byte{0, 15, 161}: "Gigabit Systems Inc.", + [3]byte{0, 15, 162}: "2xWireless", + [3]byte{0, 15, 163}: "Alpha Networks Inc.", + [3]byte{0, 15, 164}: "Sprecher Automation GmbH", + [3]byte{0, 15, 165}: "BWA Technology GmbH", + [3]byte{0, 15, 166}: "S2 Security Corporation", + [3]byte{0, 15, 167}: "Raptor Networks Technology", + [3]byte{0, 15, 168}: "Photometrics, Inc.", + [3]byte{0, 15, 169}: "PC Fabrik", + [3]byte{0, 15, 170}: "Nexus Technologies", + [3]byte{0, 15, 171}: "Kyushu Electronics Systems Inc.", + [3]byte{0, 15, 172}: "IEEE 802.11", + [3]byte{0, 15, 173}: "FMN communications GmbH", + [3]byte{0, 15, 174}: "E2O Communications", + [3]byte{0, 15, 175}: "Dialog Inc.", + [3]byte{0, 15, 176}: "Compal Electronics,INC.", + [3]byte{0, 15, 177}: "Cognio Inc.", + [3]byte{0, 15, 178}: "Broadband Pacenet (India) Pvt. Ltd.", + [3]byte{0, 15, 179}: "Actiontec Electronics, Inc", + [3]byte{0, 15, 180}: "Timespace Technology", + [3]byte{0, 15, 181}: "NETGEAR Inc", + [3]byte{0, 15, 182}: "Europlex Technologies", + [3]byte{0, 15, 183}: "Cavium Networks", + [3]byte{0, 15, 184}: "CallURL Inc.", + [3]byte{0, 15, 185}: "Adaptive Instruments", + [3]byte{0, 15, 186}: "Tevebox AB", + [3]byte{0, 15, 187}: "Nokia Siemens Networks GmbH & Co. KG.", + [3]byte{0, 15, 188}: "Onkey Technologies, Inc.", + [3]byte{0, 15, 189}: "MRV Communications (Networks) LTD", + [3]byte{0, 15, 190}: "e-w/you Inc.", + [3]byte{0, 15, 191}: "DGT Sp. z o.o.", + [3]byte{0, 15, 192}: "DELCOMp", + [3]byte{0, 15, 193}: "WAVE Corporation", + [3]byte{0, 15, 194}: "Uniwell Corporation", + [3]byte{0, 15, 195}: "PalmPalm Technology, Inc.", + [3]byte{0, 15, 196}: "NST co.,LTD.", + [3]byte{0, 15, 197}: "KeyMed Ltd", + [3]byte{0, 15, 198}: "Eurocom Industries A/S", + [3]byte{0, 15, 199}: "Dionica R&D Ltd.", + [3]byte{0, 15, 200}: "Chantry Networks", + [3]byte{0, 15, 201}: "Allnet GmbH", + [3]byte{0, 15, 202}: "A-JIN TECHLINE CO, LTD", + [3]byte{0, 15, 203}: "3Com Ltd", + [3]byte{0, 15, 204}: "Netopia, Inc.", + [3]byte{0, 15, 205}: "Nortel Networks", + [3]byte{0, 15, 206}: "Kikusui Electronics Corp.", + [3]byte{0, 15, 207}: "Datawind Research", + [3]byte{0, 15, 208}: "ASTRI", + [3]byte{0, 15, 209}: "Applied Wireless Identifications Group, Inc.", + [3]byte{0, 15, 210}: "EWA Technologies, Inc.", + [3]byte{0, 15, 211}: "Digium", + [3]byte{0, 15, 212}: "Soundcraft", + [3]byte{0, 15, 213}: "Schwechat - RISE", + [3]byte{0, 15, 214}: "Sarotech Co., Ltd", + [3]byte{0, 15, 215}: "Harman Music Group", + [3]byte{0, 15, 216}: "Force, Inc.", + [3]byte{0, 15, 217}: "FlexDSL Telecommunications AG", + [3]byte{0, 15, 218}: "YAZAKI CORPORATION", + [3]byte{0, 15, 219}: "Westell Technologies", + [3]byte{0, 15, 220}: "Ueda Japan Radio Co., Ltd.", + [3]byte{0, 15, 221}: "SORDIN AB", + [3]byte{0, 15, 222}: "Sony Ericsson Mobile Communications AB", + [3]byte{0, 15, 223}: "SOLOMON Technology Corp.", + [3]byte{0, 15, 224}: "NComputing Co.,Ltd.", + [3]byte{0, 15, 225}: "ID DIGITAL CORPORATION", + [3]byte{0, 15, 226}: "Hangzhou H3C Technologies Co., Ltd.", + [3]byte{0, 15, 227}: "Damm Cellular Systems A/S", + [3]byte{0, 15, 228}: "Pantech Co.,Ltd", + [3]byte{0, 15, 229}: "MERCURY SECURITY CORPORATION", + [3]byte{0, 15, 230}: "MBTech Systems, Inc.", + [3]byte{0, 15, 231}: "Lutron Electronics Co., Inc.", + [3]byte{0, 15, 232}: "Lobos, Inc.", + [3]byte{0, 15, 233}: "GW TECHNOLOGIES CO.,LTD.", + [3]byte{0, 15, 234}: "Giga-Byte Technology Co.,LTD.", + [3]byte{0, 15, 235}: "Cylon Controls", + [3]byte{0, 15, 236}: "ARKUS Inc.", + [3]byte{0, 15, 237}: "Anam Electronics Co., Ltd", + [3]byte{0, 15, 238}: "XTec, Incorporated", + [3]byte{0, 15, 239}: "Thales e-Transactions GmbH", + [3]byte{0, 15, 240}: "Sunray Co. Ltd.", + [3]byte{0, 15, 241}: "nex-G Systems Pte.Ltd", + [3]byte{0, 15, 242}: "Loud Technologies Inc.", + [3]byte{0, 15, 243}: "Jung Myoung Communications&Technology", + [3]byte{0, 15, 244}: "Guntermann & Drunck GmbH", + [3]byte{0, 15, 245}: "GN&S company", + [3]byte{0, 15, 246}: "Darfon Electronics Corp.", + [3]byte{0, 15, 247}: "CISCO SYSTEMS, INC.", + [3]byte{0, 15, 248}: "CISCO SYSTEMS, INC.", + [3]byte{0, 15, 249}: "Valcretec, Inc.", + [3]byte{0, 15, 250}: "Optinel Systems, Inc.", + [3]byte{0, 15, 251}: "Nippon Denso Industry Co., Ltd.", + [3]byte{0, 15, 252}: "Merit Li-Lin Ent.", + [3]byte{0, 15, 253}: "Glorytek Network Inc.", + [3]byte{0, 15, 254}: "G-PRO COMPUTER", + [3]byte{0, 15, 255}: "Control4", + [3]byte{0, 16, 0}: "CABLE TELEVISION LABORATORIES, INC.", + [3]byte{0, 16, 1}: "Citel", + [3]byte{0, 16, 2}: "ACTIA", + [3]byte{0, 16, 3}: "IMATRON, INC.", + [3]byte{0, 16, 4}: "THE BRANTLEY COILE COMPANY,INC", + [3]byte{0, 16, 5}: "UEC COMMERCIAL", + [3]byte{0, 16, 6}: "Thales Contact Solutions Ltd.", + [3]byte{0, 16, 7}: "CISCO SYSTEMS, INC.", + [3]byte{0, 16, 8}: "VIENNA SYSTEMS CORPORATION", + [3]byte{0, 16, 9}: "HORO QUARTZ", + [3]byte{0, 16, 10}: "WILLIAMS COMMUNICATIONS GROUP", + [3]byte{0, 16, 11}: "CISCO SYSTEMS, INC.", + [3]byte{0, 16, 12}: "ITO CO., LTD.", + [3]byte{0, 16, 13}: "CISCO SYSTEMS, INC.", + [3]byte{0, 16, 14}: "MICRO LINEAR COPORATION", + [3]byte{0, 16, 15}: "INDUSTRIAL CPU SYSTEMS", + [3]byte{0, 16, 16}: "INITIO CORPORATION", + [3]byte{0, 16, 17}: "CISCO SYSTEMS, INC.", + [3]byte{0, 16, 18}: "PROCESSOR SYSTEMS (I) PVT LTD", + [3]byte{0, 16, 19}: "Kontron America, Inc.", + [3]byte{0, 16, 20}: "CISCO SYSTEMS, INC.", + [3]byte{0, 16, 21}: "OOmon Inc.", + [3]byte{0, 16, 22}: "T.SQWARE", + [3]byte{0, 16, 23}: "Bosch Access Systems GmbH", + [3]byte{0, 16, 24}: "BROADCOM CORPORATION", + [3]byte{0, 16, 25}: "SIRONA DENTAL SYSTEMS GmbH & Co. KG", + [3]byte{0, 16, 26}: "PictureTel Corp.", + [3]byte{0, 16, 27}: "CORNET TECHNOLOGY, INC.", + [3]byte{0, 16, 28}: "OHM TECHNOLOGIES INTL, LLC", + [3]byte{0, 16, 29}: "WINBOND ELECTRONICS CORP.", + [3]byte{0, 16, 30}: "MATSUSHITA ELECTRONIC INSTRUMENTS CORP.", + [3]byte{0, 16, 31}: "CISCO SYSTEMS, INC.", + [3]byte{0, 16, 32}: "Hand Held Products Inc", + [3]byte{0, 16, 33}: "ENCANTO NETWORKS, INC.", + [3]byte{0, 16, 34}: "SatCom Media Corporation", + [3]byte{0, 16, 35}: "Network Equipment Technologies", + [3]byte{0, 16, 36}: "NAGOYA ELECTRIC WORKS CO., LTD", + [3]byte{0, 16, 37}: "Grayhill, Inc", + [3]byte{0, 16, 38}: "ACCELERATED NETWORKS, INC.", + [3]byte{0, 16, 39}: "L-3 COMMUNICATIONS EAST", + [3]byte{0, 16, 40}: "COMPUTER TECHNICA, INC.", + [3]byte{0, 16, 41}: "CISCO SYSTEMS, INC.", + [3]byte{0, 16, 42}: "ZF MICROSYSTEMS, INC.", + [3]byte{0, 16, 43}: "UMAX DATA SYSTEMS, INC.", + [3]byte{0, 16, 44}: "Lasat Networks A/S", + [3]byte{0, 16, 45}: "HITACHI SOFTWARE ENGINEERING", + [3]byte{0, 16, 46}: "NETWORK SYSTEMS & TECHNOLOGIES PVT. LTD.", + [3]byte{0, 16, 47}: "CISCO SYSTEMS, INC.", + [3]byte{0, 16, 48}: "EION Inc.", + [3]byte{0, 16, 49}: "OBJECTIVE COMMUNICATIONS, INC.", + [3]byte{0, 16, 50}: "ALTA TECHNOLOGY", + [3]byte{0, 16, 51}: "ACCESSLAN COMMUNICATIONS, INC.", + [3]byte{0, 16, 52}: "GNP Computers", + [3]byte{0, 16, 53}: "ELITEGROUP COMPUTER SYSTEMS CO., LTD", + [3]byte{0, 16, 54}: "INTER-TEL INTEGRATED SYSTEMS", + [3]byte{0, 16, 55}: "CYQ've Technology Co., Ltd.", + [3]byte{0, 16, 56}: "MICRO RESEARCH INSTITUTE, INC.", + [3]byte{0, 16, 57}: "Vectron Systems AG", + [3]byte{0, 16, 58}: "DIAMOND NETWORK TECH", + [3]byte{0, 16, 59}: "HIPPI NETWORKING FORUM", + [3]byte{0, 16, 60}: "IC ENSEMBLE, INC.", + [3]byte{0, 16, 61}: "PHASECOM, LTD.", + [3]byte{0, 16, 62}: "NETSCHOOLS CORPORATION", + [3]byte{0, 16, 63}: "TOLLGRADE COMMUNICATIONS, INC.", + [3]byte{0, 16, 64}: "INTERMEC CORPORATION", + [3]byte{0, 16, 65}: "BRISTOL BABCOCK, INC.", + [3]byte{0, 16, 66}: "Alacritech, Inc.", + [3]byte{0, 16, 67}: "A2 CORPORATION", + [3]byte{0, 16, 68}: "InnoLabs Corporation", + [3]byte{0, 16, 69}: "Nortel Networks", + [3]byte{0, 16, 70}: "ALCORN MCBRIDE INC.", + [3]byte{0, 16, 71}: "ECHO ELETRIC CO. LTD.", + [3]byte{0, 16, 72}: "HTRC AUTOMATION, INC.", + [3]byte{0, 16, 73}: "ShoreTel, Inc", + [3]byte{0, 16, 74}: "The Parvus Corporation", + [3]byte{0, 16, 75}: "3COM CORPORATION", + [3]byte{0, 16, 76}: "Teledyne LeCroy, Inc", + [3]byte{0, 16, 77}: "SURTEC INDUSTRIES, INC.", + [3]byte{0, 16, 78}: "CEOLOGIC", + [3]byte{0, 16, 79}: "Oracle Corporation", + [3]byte{0, 16, 80}: "RION CO., LTD.", + [3]byte{0, 16, 81}: "CMICRO CORPORATION", + [3]byte{0, 16, 82}: "METTLER-TOLEDO (ALBSTADT) GMBH", + [3]byte{0, 16, 83}: "COMPUTER TECHNOLOGY CORP.", + [3]byte{0, 16, 84}: "CISCO SYSTEMS, INC.", + [3]byte{0, 16, 85}: "FUJITSU MICROELECTRONICS, INC.", + [3]byte{0, 16, 86}: "SODICK CO., LTD.", + [3]byte{0, 16, 87}: "Rebel.com, Inc.", + [3]byte{0, 16, 88}: "ArrowPoint Communications", + [3]byte{0, 16, 89}: "DIABLO RESEARCH CO. LLC", + [3]byte{0, 16, 90}: "3COM CORPORATION", + [3]byte{0, 16, 91}: "NET INSIGHT AB", + [3]byte{0, 16, 92}: "QUANTUM DESIGNS (H.K.) LTD.", + [3]byte{0, 16, 93}: "Draeger Medical", + [3]byte{0, 16, 94}: "Spirent plc, Service Assurance Broadband", + [3]byte{0, 16, 95}: "ZODIAC DATA SYSTEMS", + [3]byte{0, 16, 96}: "BILLIONTON SYSTEMS, INC.", + [3]byte{0, 16, 97}: "HOSTLINK CORP.", + [3]byte{0, 16, 98}: "NX SERVER, ILNC.", + [3]byte{0, 16, 99}: "STARGUIDE DIGITAL NETWORKS", + [3]byte{0, 16, 100}: "DNPG, LLC", + [3]byte{0, 16, 101}: "RADYNE CORPORATION", + [3]byte{0, 16, 102}: "ADVANCED CONTROL SYSTEMS, INC.", + [3]byte{0, 16, 103}: "Ericsson", + [3]byte{0, 16, 104}: "COMOS TELECOM", + [3]byte{0, 16, 105}: "HELIOSS COMMUNICATIONS, INC.", + [3]byte{0, 16, 106}: "DIGITAL MICROWAVE CORPORATION", + [3]byte{0, 16, 107}: "SONUS NETWORKS, INC.", + [3]byte{0, 16, 108}: "EDNT GmbH", + [3]byte{0, 16, 109}: "Axxcelera Broadband Wireless", + [3]byte{0, 16, 110}: "TADIRAN COM. LTD.", + [3]byte{0, 16, 111}: "TRENTON TECHNOLOGY INC.", + [3]byte{0, 16, 112}: "CARADON TREND LTD.", + [3]byte{0, 16, 113}: "ADVANET INC.", + [3]byte{0, 16, 114}: "GVN TECHNOLOGIES, INC.", + [3]byte{0, 16, 115}: "Technobox, Inc.", + [3]byte{0, 16, 116}: "ATEN INTERNATIONAL CO., LTD.", + [3]byte{0, 16, 117}: "Segate Technology LLC", + [3]byte{0, 16, 118}: "EUREM GmbH", + [3]byte{0, 16, 119}: "SAF DRIVE SYSTEMS, LTD.", + [3]byte{0, 16, 120}: "NUERA COMMUNICATIONS, INC.", + [3]byte{0, 16, 121}: "CISCO SYSTEMS, INC.", + [3]byte{0, 16, 122}: "AmbiCom, Inc.", + [3]byte{0, 16, 123}: "CISCO SYSTEMS, INC.", + [3]byte{0, 16, 124}: "P-COM, INC.", + [3]byte{0, 16, 125}: "AURORA COMMUNICATIONS, LTD.", + [3]byte{0, 16, 126}: "BACHMANN ELECTRONIC GmbH", + [3]byte{0, 16, 127}: "CRESTRON ELECTRONICS, INC.", + [3]byte{0, 16, 128}: "METAWAVE COMMUNICATIONS", + [3]byte{0, 16, 129}: "DPS, INC.", + [3]byte{0, 16, 130}: "JNA TELECOMMUNICATIONS LIMITED", + [3]byte{0, 16, 131}: "HEWLETT-PACKARD COMPANY", + [3]byte{0, 16, 132}: "K-BOT COMMUNICATIONS", + [3]byte{0, 16, 133}: "POLARIS COMMUNICATIONS, INC.", + [3]byte{0, 16, 134}: "ATTO Technology, Inc.", + [3]byte{0, 16, 135}: "Xstreamis PLC", + [3]byte{0, 16, 136}: "AMERICAN NETWORKS INC.", + [3]byte{0, 16, 137}: "WebSonic", + [3]byte{0, 16, 138}: "TeraLogic, Inc.", + [3]byte{0, 16, 139}: "LASERANIMATION SOLLINGER GmbH", + [3]byte{0, 16, 140}: "FUJITSU TELECOMMUNICATIONS EUROPE, LTD.", + [3]byte{0, 16, 141}: "Johnson Controls, Inc.", + [3]byte{0, 16, 142}: "HUGH SYMONS CONCEPT Technologies Ltd.", + [3]byte{0, 16, 143}: "RAPTOR SYSTEMS", + [3]byte{0, 16, 144}: "CIMETRICS, INC.", + [3]byte{0, 16, 145}: "NO WIRES NEEDED BV", + [3]byte{0, 16, 146}: "NETCORE INC.", + [3]byte{0, 16, 147}: "CMS COMPUTERS, LTD.", + [3]byte{0, 16, 148}: "Performance Analysis Broadband, Spirent plc", + [3]byte{0, 16, 149}: "Thomson Inc.", + [3]byte{0, 16, 150}: "TRACEWELL SYSTEMS, INC.", + [3]byte{0, 16, 151}: "WinNet Metropolitan Communications Systems, Inc.", + [3]byte{0, 16, 152}: "STARNET TECHNOLOGIES, INC.", + [3]byte{0, 16, 153}: "InnoMedia, Inc.", + [3]byte{0, 16, 154}: "NETLINE", + [3]byte{0, 16, 155}: "Emulex Corporation", + [3]byte{0, 16, 156}: "M-SYSTEM CO., LTD.", + [3]byte{0, 16, 157}: "CLARINET SYSTEMS, INC.", + [3]byte{0, 16, 158}: "AWARE, INC.", + [3]byte{0, 16, 159}: "PAVO, INC.", + [3]byte{0, 16, 160}: "INNOVEX TECHNOLOGIES, INC.", + [3]byte{0, 16, 161}: "KENDIN SEMICONDUCTOR, INC.", + [3]byte{0, 16, 162}: "TNS", + [3]byte{0, 16, 163}: "OMNITRONIX, INC.", + [3]byte{0, 16, 164}: "XIRCOM", + [3]byte{0, 16, 165}: "OXFORD INSTRUMENTS", + [3]byte{0, 16, 166}: "CISCO SYSTEMS, INC.", + [3]byte{0, 16, 167}: "UNEX TECHNOLOGY CORPORATION", + [3]byte{0, 16, 168}: "RELIANCE COMPUTER CORP.", + [3]byte{0, 16, 169}: "ADHOC TECHNOLOGIES", + [3]byte{0, 16, 170}: "MEDIA4, INC.", + [3]byte{0, 16, 171}: "KOITO ELECTRIC INDUSTRIES, LTD.", + [3]byte{0, 16, 172}: "IMCI TECHNOLOGIES", + [3]byte{0, 16, 173}: "SOFTRONICS USB, INC.", + [3]byte{0, 16, 174}: "SHINKO ELECTRIC INDUSTRIES CO.", + [3]byte{0, 16, 175}: "TAC SYSTEMS, INC.", + [3]byte{0, 16, 176}: "MERIDIAN TECHNOLOGY CORP.", + [3]byte{0, 16, 177}: "FOR-A CO., LTD.", + [3]byte{0, 16, 178}: "COACTIVE AESTHETICS", + [3]byte{0, 16, 179}: "NOKIA MULTIMEDIA TERMINALS", + [3]byte{0, 16, 180}: "ATMOSPHERE NETWORKS", + [3]byte{0, 16, 181}: "ACCTON TECHNOLOGY CORPORATION", + [3]byte{0, 16, 182}: "ENTRATA COMMUNICATIONS CORP.", + [3]byte{0, 16, 183}: "COYOTE TECHNOLOGIES, LLC", + [3]byte{0, 16, 184}: "ISHIGAKI COMPUTER SYSTEM CO.", + [3]byte{0, 16, 185}: "MAXTOR CORP.", + [3]byte{0, 16, 186}: "MARTINHO-DAVIS SYSTEMS, INC.", + [3]byte{0, 16, 187}: "DATA & INFORMATION TECHNOLOGY", + [3]byte{0, 16, 188}: "Aastra Telecom", + [3]byte{0, 16, 189}: "THE TELECOMMUNICATION TECHNOLOGY COMMITTEE (TTC)", + [3]byte{0, 16, 190}: "MARCH NETWORKS CORPORATION", + [3]byte{0, 16, 191}: "InterAir Wireless", + [3]byte{0, 16, 192}: "ARMA, Inc.", + [3]byte{0, 16, 193}: "OI ELECTRIC CO., LTD.", + [3]byte{0, 16, 194}: "WILLNET, INC.", + [3]byte{0, 16, 195}: "CSI-CONTROL SYSTEMS", + [3]byte{0, 16, 196}: "MEDIA LINKS CO., LTD.", + [3]byte{0, 16, 197}: "PROTOCOL TECHNOLOGIES, INC.", + [3]byte{0, 16, 198}: "Universal Global Scientific Industrial Co., Ltd.", + [3]byte{0, 16, 199}: "DATA TRANSMISSION NETWORK", + [3]byte{0, 16, 200}: "COMMUNICATIONS ELECTRONICS SECURITY GROUP", + [3]byte{0, 16, 201}: "MITSUBISHI ELECTRONICS LOGISTIC SUPPORT CO.", + [3]byte{0, 16, 202}: "Telco Systems, Inc.", + [3]byte{0, 16, 203}: "FACIT K.K.", + [3]byte{0, 16, 204}: "CLP COMPUTER LOGISTIK PLANUNG GmbH", + [3]byte{0, 16, 205}: "INTERFACE CONCEPT", + [3]byte{0, 16, 206}: "VOLAMP, LTD.", + [3]byte{0, 16, 207}: "FIBERLANE COMMUNICATIONS", + [3]byte{0, 16, 208}: "WITCOM, LTD.", + [3]byte{0, 16, 209}: "Top Layer Networks, Inc.", + [3]byte{0, 16, 210}: "NITTO TSUSHINKI CO., LTD", + [3]byte{0, 16, 211}: "GRIPS ELECTRONIC GMBH", + [3]byte{0, 16, 212}: "STORAGE COMPUTER CORPORATION", + [3]byte{0, 16, 213}: "IMASDE CANARIAS, S.A.", + [3]byte{0, 16, 214}: "Exelis", + [3]byte{0, 16, 215}: "ARGOSY RESEARCH INC.", + [3]byte{0, 16, 216}: "CALISTA", + [3]byte{0, 16, 217}: "IBM JAPAN, FUJISAWA MT+D", + [3]byte{0, 16, 218}: "Kollmorgen Corp", + [3]byte{0, 16, 219}: "Juniper Networks, Inc.", + [3]byte{0, 16, 220}: "MICRO-STAR INTERNATIONAL CO., LTD.", + [3]byte{0, 16, 221}: "ENABLE SEMICONDUCTOR, INC.", + [3]byte{0, 16, 222}: "INTERNATIONAL DATACASTING CORPORATION", + [3]byte{0, 16, 223}: "RISE COMPUTER INC.", + [3]byte{0, 16, 224}: "Oracle Corporation", + [3]byte{0, 16, 225}: "S.I. TECH, INC.", + [3]byte{0, 16, 226}: "ArrayComm, Inc.", + [3]byte{0, 16, 227}: "Hewlett-Packard Company", + [3]byte{0, 16, 228}: "NSI CORPORATION", + [3]byte{0, 16, 229}: "SOLECTRON TEXAS", + [3]byte{0, 16, 230}: "APPLIED INTELLIGENT SYSTEMS, INC.", + [3]byte{0, 16, 231}: "BreezeCom", + [3]byte{0, 16, 232}: "TELOCITY, INCORPORATED", + [3]byte{0, 16, 233}: "RAIDTEC LTD.", + [3]byte{0, 16, 234}: "ADEPT TECHNOLOGY", + [3]byte{0, 16, 235}: "SELSIUS SYSTEMS, INC.", + [3]byte{0, 16, 236}: "RPCG, LLC", + [3]byte{0, 16, 237}: "SUNDANCE TECHNOLOGY, INC.", + [3]byte{0, 16, 238}: "CTI PRODUCTS, INC.", + [3]byte{0, 16, 239}: "DBTEL INCORPORATED", + [3]byte{0, 16, 240}: "RITTAL-WERK RUDOLF LOH GmbH & Co.", + [3]byte{0, 16, 241}: "I-O CORPORATION", + [3]byte{0, 16, 242}: "ANTEC", + [3]byte{0, 16, 243}: "Nexcom International Co., Ltd.", + [3]byte{0, 16, 244}: "Vertical Communications", + [3]byte{0, 16, 245}: "AMHERST SYSTEMS, INC.", + [3]byte{0, 16, 246}: "CISCO SYSTEMS, INC.", + [3]byte{0, 16, 247}: "IRIICHI TECHNOLOGIES Inc.", + [3]byte{0, 16, 248}: "TEXIO TECHNOLOGY CORPORATION", + [3]byte{0, 16, 249}: "UNIQUE SYSTEMS, INC.", + [3]byte{0, 16, 250}: "Apple", + [3]byte{0, 16, 251}: "ZIDA TECHNOLOGIES LIMITED", + [3]byte{0, 16, 252}: "BROADBAND NETWORKS, INC.", + [3]byte{0, 16, 253}: "COCOM A/S", + [3]byte{0, 16, 254}: "DIGITAL EQUIPMENT CORPORATION", + [3]byte{0, 16, 255}: "CISCO SYSTEMS, INC.", + [3]byte{0, 17, 0}: "Schneider Electric", + [3]byte{0, 17, 1}: "CET Technologies Pte Ltd", + [3]byte{0, 17, 2}: "Aurora Multimedia Corp.", + [3]byte{0, 17, 3}: "kawamura electric inc.", + [3]byte{0, 17, 4}: "TELEXY", + [3]byte{0, 17, 5}: "Sunplus Technology Co., Ltd.", + [3]byte{0, 17, 6}: "Siemens NV (Belgium)", + [3]byte{0, 17, 7}: "RGB Networks Inc.", + [3]byte{0, 17, 8}: "Orbital Data Corporation", + [3]byte{0, 17, 9}: "Micro-Star International", + [3]byte{0, 17, 10}: "Hewlett-Packard Company", + [3]byte{0, 17, 11}: "Franklin Technology Systems", + [3]byte{0, 17, 12}: "Atmark Techno, Inc.", + [3]byte{0, 17, 13}: "SANBlaze Technology, Inc.", + [3]byte{0, 17, 14}: "Tsurusaki Sealand Transportation Co. Ltd.", + [3]byte{0, 17, 15}: "netplat,Inc.", + [3]byte{0, 17, 16}: "Maxanna Technology Co., Ltd.", + [3]byte{0, 17, 17}: "Intel Corporation", + [3]byte{0, 17, 18}: "Honeywell CMSS", + [3]byte{0, 17, 19}: "Fraunhofer FOKUS", + [3]byte{0, 17, 20}: "EverFocus Electronics Corp.", + [3]byte{0, 17, 21}: "EPIN Technologies, Inc.", + [3]byte{0, 17, 22}: "COTEAU VERT CO., LTD.", + [3]byte{0, 17, 23}: "CESNET", + [3]byte{0, 17, 24}: "BLX IC Design Corp., Ltd.", + [3]byte{0, 17, 25}: "Solteras, Inc.", + [3]byte{0, 17, 26}: "ARRIS Group, Inc.", + [3]byte{0, 17, 27}: "Targa Systems Div L-3 Communications Canada", + [3]byte{0, 17, 28}: "Pleora Technologies Inc.", + [3]byte{0, 17, 29}: "Hectrix Limited", + [3]byte{0, 17, 30}: "EPSG (Ethernet Powerlink Standardization Group)", + [3]byte{0, 17, 31}: "Doremi Labs, Inc.", + [3]byte{0, 17, 32}: "CISCO SYSTEMS, INC.", + [3]byte{0, 17, 33}: "CISCO SYSTEMS, INC.", + [3]byte{0, 17, 34}: "CIMSYS Inc", + [3]byte{0, 17, 35}: "Appointech, Inc.", + [3]byte{0, 17, 36}: "Apple", + [3]byte{0, 17, 37}: "IBM Corp", + [3]byte{0, 17, 38}: "Venstar Inc.", + [3]byte{0, 17, 39}: "TASI, Inc", + [3]byte{0, 17, 40}: "Streamit", + [3]byte{0, 17, 41}: "Paradise Datacom Ltd.", + [3]byte{0, 17, 42}: "Niko NV", + [3]byte{0, 17, 43}: "NetModule AG", + [3]byte{0, 17, 44}: "IZT GmbH", + [3]byte{0, 17, 45}: "iPulse Systems", + [3]byte{0, 17, 46}: "CEICOM", + [3]byte{0, 17, 47}: "ASUSTek Computer Inc.", + [3]byte{0, 17, 48}: "Allied Telesis (Hong Kong) Ltd.", + [3]byte{0, 17, 49}: "UNATECH. CO.,LTD", + [3]byte{0, 17, 50}: "Synology Incorporated", + [3]byte{0, 17, 51}: "Siemens Austria SIMEA", + [3]byte{0, 17, 52}: "MediaCell, Inc.", + [3]byte{0, 17, 53}: "Grandeye Ltd", + [3]byte{0, 17, 54}: "Goodrich Sensor Systems", + [3]byte{0, 17, 55}: "AICHI ELECTRIC CO., LTD.", + [3]byte{0, 17, 56}: "TAISHIN CO., LTD.", + [3]byte{0, 17, 57}: "STOEBER ANTRIEBSTECHNIK GmbH + Co. KG.", + [3]byte{0, 17, 58}: "SHINBORAM", + [3]byte{0, 17, 59}: "Micronet Communications Inc.", + [3]byte{0, 17, 60}: "Micronas GmbH", + [3]byte{0, 17, 61}: "KN SOLTEC CO.,LTD.", + [3]byte{0, 17, 62}: "JL Corporation", + [3]byte{0, 17, 63}: "Alcatel DI", + [3]byte{0, 17, 64}: "Nanometrics Inc.", + [3]byte{0, 17, 65}: "GoodMan Corporation", + [3]byte{0, 17, 66}: "e-SMARTCOM INC.", + [3]byte{0, 17, 67}: "Dell Inc", + [3]byte{0, 17, 68}: "Assurance Technology Corp", + [3]byte{0, 17, 69}: "ValuePoint Networks", + [3]byte{0, 17, 70}: "Telecard-Pribor Ltd", + [3]byte{0, 17, 71}: "Secom-Industry co.LTD.", + [3]byte{0, 17, 72}: "Prolon Control Systems", + [3]byte{0, 17, 73}: "Proliphix Inc.", + [3]byte{0, 17, 74}: "KAYABA INDUSTRY Co,.Ltd.", + [3]byte{0, 17, 75}: "Francotyp-Postalia GmbH", + [3]byte{0, 17, 76}: "caffeina applied research ltd.", + [3]byte{0, 17, 77}: "Atsumi Electric Co.,LTD.", + [3]byte{0, 17, 78}: "690885 Ontario Inc.", + [3]byte{0, 17, 79}: "US Digital Television, Inc", + [3]byte{0, 17, 80}: "Belkin Corporation", + [3]byte{0, 17, 81}: "Mykotronx", + [3]byte{0, 17, 82}: "Eidsvoll Electronics AS", + [3]byte{0, 17, 83}: "Trident Tek, Inc.", + [3]byte{0, 17, 84}: "Webpro Technologies Inc.", + [3]byte{0, 17, 85}: "Sevis Systems", + [3]byte{0, 17, 86}: "Pharos Systems NZ", + [3]byte{0, 17, 87}: "OF Networks Co., Ltd.", + [3]byte{0, 17, 88}: "Nortel Networks", + [3]byte{0, 17, 89}: "MATISSE NETWORKS INC", + [3]byte{0, 17, 90}: "Ivoclar Vivadent AG", + [3]byte{0, 17, 91}: "Elitegroup Computer System Co. (ECS)", + [3]byte{0, 17, 92}: "CISCO SYSTEMS, INC.", + [3]byte{0, 17, 93}: "CISCO SYSTEMS, INC.", + [3]byte{0, 17, 94}: "ProMinent Dosiertechnik GmbH", + [3]byte{0, 17, 95}: "ITX Security Co., Ltd.", + [3]byte{0, 17, 96}: "ARTDIO Company Co., LTD", + [3]byte{0, 17, 97}: "NetStreams, LLC", + [3]byte{0, 17, 98}: "STAR MICRONICS CO.,LTD.", + [3]byte{0, 17, 99}: "SYSTEM SPA DEPT. ELECTRONICS", + [3]byte{0, 17, 100}: "ACARD Technology Corp.", + [3]byte{0, 17, 101}: "Znyx Networks", + [3]byte{0, 17, 102}: "Taelim Electronics Co., Ltd.", + [3]byte{0, 17, 103}: "Integrated System Solution Corp.", + [3]byte{0, 17, 104}: "HomeLogic LLC", + [3]byte{0, 17, 105}: "EMS Satcom", + [3]byte{0, 17, 106}: "Domo Ltd", + [3]byte{0, 17, 107}: "Digital Data Communications Asia Co.,Ltd", + [3]byte{0, 17, 108}: "Nanwang Multimedia Inc.,Ltd", + [3]byte{0, 17, 109}: "American Time and Signal", + [3]byte{0, 17, 110}: "PePLink Ltd.", + [3]byte{0, 17, 111}: "Netforyou Co., LTD.", + [3]byte{0, 17, 112}: "GSC SRL", + [3]byte{0, 17, 113}: "DEXTER Communications, Inc.", + [3]byte{0, 17, 114}: "COTRON CORPORATION", + [3]byte{0, 17, 115}: "SMART Storage Systems", + [3]byte{0, 17, 116}: "Wibhu Technologies, Inc.", + [3]byte{0, 17, 117}: "PathScale, Inc.", + [3]byte{0, 17, 118}: "Intellambda Systems, Inc.", + [3]byte{0, 17, 119}: "Coaxial Networks, Inc.", + [3]byte{0, 17, 120}: "Chiron Technology Ltd", + [3]byte{0, 17, 121}: "Singular Technology Co. Ltd.", + [3]byte{0, 17, 122}: "Singim International Corp.", + [3]byte{0, 17, 123}: "Büchi Labortechnik AG", + [3]byte{0, 17, 124}: "e-zy.net", + [3]byte{0, 17, 125}: "ZMD America, Inc.", + [3]byte{0, 17, 126}: "Progeny, A division of Midmark Corp", + [3]byte{0, 17, 127}: "Neotune Information Technology Corporation,.LTD", + [3]byte{0, 17, 128}: "ARRIS Group, Inc.", + [3]byte{0, 17, 129}: "InterEnergy Co.Ltd,", + [3]byte{0, 17, 130}: "IMI Norgren Ltd", + [3]byte{0, 17, 131}: "Datalogic ADC, Inc.", + [3]byte{0, 17, 132}: "Humo Laboratory,Ltd.", + [3]byte{0, 17, 133}: "Hewlett-Packard Company", + [3]byte{0, 17, 134}: "Prime Systems, Inc.", + [3]byte{0, 17, 135}: "Category Solutions, Inc", + [3]byte{0, 17, 136}: "Enterasys", + [3]byte{0, 17, 137}: "Aerotech Inc", + [3]byte{0, 17, 138}: "Viewtran Technology Limited", + [3]byte{0, 17, 139}: "Alcatel-Lucent, Enterprise Business Group", + [3]byte{0, 17, 140}: "Missouri Department of Transportation", + [3]byte{0, 17, 141}: "Hanchang System Corp.", + [3]byte{0, 17, 142}: "Halytech Mace", + [3]byte{0, 17, 143}: "EUTECH INSTRUMENTS PTE. LTD.", + [3]byte{0, 17, 144}: "Digital Design Corporation", + [3]byte{0, 17, 145}: "CTS-Clima Temperatur Systeme GmbH", + [3]byte{0, 17, 146}: "CISCO SYSTEMS, INC.", + [3]byte{0, 17, 147}: "CISCO SYSTEMS, INC.", + [3]byte{0, 17, 148}: "Chi Mei Communication Systems, Inc.", + [3]byte{0, 17, 149}: "D-Link Corporation", + [3]byte{0, 17, 150}: "Actuality Systems, Inc.", + [3]byte{0, 17, 151}: "Monitoring Technologies Limited", + [3]byte{0, 17, 152}: "Prism Media Products Limited", + [3]byte{0, 17, 153}: "2wcom Systems GmbH", + [3]byte{0, 17, 154}: "Alkeria srl", + [3]byte{0, 17, 155}: "Telesynergy Research Inc.", + [3]byte{0, 17, 156}: "EP&T Energy", + [3]byte{0, 17, 157}: "Diginfo Technology Corporation", + [3]byte{0, 17, 158}: "Solectron Brazil", + [3]byte{0, 17, 159}: "Nokia Danmark A/S", + [3]byte{0, 17, 160}: "Vtech Engineering Canada Ltd", + [3]byte{0, 17, 161}: "VISION NETWARE CO.,LTD", + [3]byte{0, 17, 162}: "Manufacturing Technology Inc", + [3]byte{0, 17, 163}: "LanReady Technologies Inc.", + [3]byte{0, 17, 164}: "JStream Technologies Inc.", + [3]byte{0, 17, 165}: "Fortuna Electronic Corp.", + [3]byte{0, 17, 166}: "Sypixx Networks", + [3]byte{0, 17, 167}: "Infilco Degremont Inc.", + [3]byte{0, 17, 168}: "Quest Technologies", + [3]byte{0, 17, 169}: "MOIMSTONE Co., LTD", + [3]byte{0, 17, 170}: "Uniclass Technology, Co., LTD", + [3]byte{0, 17, 171}: "TRUSTABLE TECHNOLOGY CO.,LTD.", + [3]byte{0, 17, 172}: "Simtec Electronics", + [3]byte{0, 17, 173}: "Shanghai Ruijie Technology", + [3]byte{0, 17, 174}: "ARRIS Group, Inc.", + [3]byte{0, 17, 175}: "Medialink-i,Inc", + [3]byte{0, 17, 176}: "Fortelink Inc.", + [3]byte{0, 17, 177}: "BlueExpert Technology Corp.", + [3]byte{0, 17, 178}: "2001 Technology Inc.", + [3]byte{0, 17, 179}: "YOSHIMIYA CO.,LTD.", + [3]byte{0, 17, 180}: "Westermo Teleindustri AB", + [3]byte{0, 17, 181}: "Shenzhen Powercom Co.,Ltd", + [3]byte{0, 17, 182}: "Open Systems International", + [3]byte{0, 17, 183}: "Octalix B.V.", + [3]byte{0, 17, 184}: "Liebherr - Elektronik GmbH", + [3]byte{0, 17, 185}: "Inner Range Pty. Ltd.", + [3]byte{0, 17, 186}: "Elexol Pty Ltd", + [3]byte{0, 17, 187}: "CISCO SYSTEMS, INC.", + [3]byte{0, 17, 188}: "CISCO SYSTEMS, INC.", + [3]byte{0, 17, 189}: "Bombardier Transportation", + [3]byte{0, 17, 190}: "AGP Telecom Co. Ltd", + [3]byte{0, 17, 191}: "AESYS S.p.A.", + [3]byte{0, 17, 192}: "Aday Technology Inc", + [3]byte{0, 17, 193}: "4P MOBILE DATA PROCESSING", + [3]byte{0, 17, 194}: "United Fiber Optic Communication", + [3]byte{0, 17, 195}: "Transceiving System Technology Corporation", + [3]byte{0, 17, 196}: "Terminales de Telecomunicacion Terrestre, S.L.", + [3]byte{0, 17, 197}: "TEN Technology", + [3]byte{0, 17, 198}: "Seagate Technology", + [3]byte{0, 17, 199}: "Raymarine UK Ltd", + [3]byte{0, 17, 200}: "Powercom Co., Ltd.", + [3]byte{0, 17, 201}: "MTT Corporation", + [3]byte{0, 17, 202}: "Long Range Systems, Inc.", + [3]byte{0, 17, 203}: "Jacobsons AB", + [3]byte{0, 17, 204}: "Guangzhou Jinpeng Group Co.,Ltd.", + [3]byte{0, 17, 205}: "Axsun Technologies", + [3]byte{0, 17, 206}: "Ubisense Limited", + [3]byte{0, 17, 207}: "Thrane & Thrane A/S", + [3]byte{0, 17, 208}: "Tandberg Data ASA", + [3]byte{0, 17, 209}: "Soft Imaging System GmbH", + [3]byte{0, 17, 210}: "Perception Digital Ltd", + [3]byte{0, 17, 211}: "NextGenTel Holding ASA", + [3]byte{0, 17, 212}: "NetEnrich, Inc", + [3]byte{0, 17, 213}: "Hangzhou Sunyard System Engineering Co.,Ltd.", + [3]byte{0, 17, 214}: "HandEra, Inc.", + [3]byte{0, 17, 215}: "eWerks Inc", + [3]byte{0, 17, 216}: "ASUSTek Computer Inc.", + [3]byte{0, 17, 217}: "TiVo", + [3]byte{0, 17, 218}: "Vivaas Technology Inc.", + [3]byte{0, 17, 219}: "Land-Cellular Corporation", + [3]byte{0, 17, 220}: "Glunz & Jensen", + [3]byte{0, 17, 221}: "FROMUS TEC. Co., Ltd.", + [3]byte{0, 17, 222}: "EURILOGIC", + [3]byte{0, 17, 223}: "Current Energy", + [3]byte{0, 17, 224}: "U-MEDIA Communications, Inc.", + [3]byte{0, 17, 225}: "Arcelik A.S", + [3]byte{0, 17, 226}: "Hua Jung Components Co., Ltd.", + [3]byte{0, 17, 227}: "Thomson, Inc.", + [3]byte{0, 17, 228}: "Danelec Electronics A/S", + [3]byte{0, 17, 229}: "KCodes Corporation", + [3]byte{0, 17, 230}: "Scientific Atlanta", + [3]byte{0, 17, 231}: "WORLDSAT - Texas de France", + [3]byte{0, 17, 232}: "Tixi.Com", + [3]byte{0, 17, 233}: "STARNEX CO., LTD.", + [3]byte{0, 17, 234}: "IWICS Inc.", + [3]byte{0, 17, 235}: "Innovative Integration", + [3]byte{0, 17, 236}: "AVIX INC.", + [3]byte{0, 17, 237}: "802 Global", + [3]byte{0, 17, 238}: "Estari, Inc.", + [3]byte{0, 17, 239}: "Conitec Datensysteme GmbH", + [3]byte{0, 17, 240}: "Wideful Limited", + [3]byte{0, 17, 241}: "QinetiQ Ltd", + [3]byte{0, 17, 242}: "Institute of Network Technologies", + [3]byte{0, 17, 243}: "NeoMedia Europe AG", + [3]byte{0, 17, 244}: "woori-net", + [3]byte{0, 17, 245}: "ASKEY COMPUTER CORP.", + [3]byte{0, 17, 246}: "Asia Pacific Microsystems , Inc.", + [3]byte{0, 17, 247}: "Shenzhen Forward Industry Co., Ltd", + [3]byte{0, 17, 248}: "AIRAYA Corp", + [3]byte{0, 17, 249}: "Nortel Networks", + [3]byte{0, 17, 250}: "Rane Corporation", + [3]byte{0, 17, 251}: "Heidelberg Engineering GmbH", + [3]byte{0, 17, 252}: "HARTING Electric Gmbh & Co.KG", + [3]byte{0, 17, 253}: "KORG INC.", + [3]byte{0, 17, 254}: "Keiyo System Research, Inc.", + [3]byte{0, 17, 255}: "Digitro Tecnologia Ltda", + [3]byte{0, 18, 0}: "CISCO SYSTEMS, INC.", + [3]byte{0, 18, 1}: "CISCO SYSTEMS, INC.", + [3]byte{0, 18, 2}: "Decrane Aerospace - Audio International Inc.", + [3]byte{0, 18, 3}: "ActivNetworks", + [3]byte{0, 18, 4}: "u10 Networks, Inc.", + [3]byte{0, 18, 5}: "Terrasat Communications, Inc.", + [3]byte{0, 18, 6}: "iQuest (NZ) Ltd", + [3]byte{0, 18, 7}: "Head Strong International Limited", + [3]byte{0, 18, 8}: "Gantner Instruments GmbH", + [3]byte{0, 18, 9}: "Fastrax Ltd", + [3]byte{0, 18, 10}: "Emerson Climate Technologies GmbH", + [3]byte{0, 18, 11}: "Chinasys Technologies Limited", + [3]byte{0, 18, 12}: "CE-Infosys Pte Ltd", + [3]byte{0, 18, 13}: "Advanced Telecommunication Technologies, Inc.", + [3]byte{0, 18, 14}: "AboCom", + [3]byte{0, 18, 15}: "IEEE 802.3", + [3]byte{0, 18, 16}: "WideRay Corp", + [3]byte{0, 18, 17}: "Protechna Herbst GmbH & Co. KG", + [3]byte{0, 18, 18}: "PLUS Corporation", + [3]byte{0, 18, 19}: "Metrohm AG", + [3]byte{0, 18, 20}: "Koenig & Bauer AG", + [3]byte{0, 18, 21}: "iStor Networks, Inc.", + [3]byte{0, 18, 22}: "ICP Internet Communication Payment AG", + [3]byte{0, 18, 23}: "Cisco-Linksys, LLC", + [3]byte{0, 18, 24}: "ARUZE Corporation", + [3]byte{0, 18, 25}: "Ahead Communication Systems Inc", + [3]byte{0, 18, 26}: "Techno Soft Systemnics Inc.", + [3]byte{0, 18, 27}: "Sound Devices, LLC", + [3]byte{0, 18, 28}: "PARROT S.A.", + [3]byte{0, 18, 29}: "Netfabric Corporation", + [3]byte{0, 18, 30}: "Juniper Networks, Inc.", + [3]byte{0, 18, 31}: "Harding Instruments", + [3]byte{0, 18, 32}: "Cadco Systems", + [3]byte{0, 18, 33}: "B.Braun Melsungen AG", + [3]byte{0, 18, 34}: "Skardin (UK) Ltd", + [3]byte{0, 18, 35}: "Pixim", + [3]byte{0, 18, 36}: "NexQL Corporation", + [3]byte{0, 18, 37}: "ARRIS Group, Inc.", + [3]byte{0, 18, 38}: "Japan Direx Corporation", + [3]byte{0, 18, 39}: "Franklin Electric Co., Inc.", + [3]byte{0, 18, 40}: "Data Ltd.", + [3]byte{0, 18, 41}: "BroadEasy Technologies Co.,Ltd", + [3]byte{0, 18, 42}: "VTech Telecommunications Ltd.", + [3]byte{0, 18, 43}: "Virbiage Pty Ltd", + [3]byte{0, 18, 44}: "Soenen Controls N.V.", + [3]byte{0, 18, 45}: "SiNett Corporation", + [3]byte{0, 18, 46}: "Signal Technology - AISD", + [3]byte{0, 18, 47}: "Sanei Electric Inc.", + [3]byte{0, 18, 48}: "Picaso Infocommunication CO., LTD.", + [3]byte{0, 18, 49}: "Motion Control Systems, Inc.", + [3]byte{0, 18, 50}: "LeWiz Communications Inc.", + [3]byte{0, 18, 51}: "JRC TOKKI Co.,Ltd.", + [3]byte{0, 18, 52}: "Camille Bauer", + [3]byte{0, 18, 53}: "Andrew Corporation", + [3]byte{0, 18, 54}: "ConSentry Networks", + [3]byte{0, 18, 55}: "Texas Instruments", + [3]byte{0, 18, 56}: "SetaBox Technology Co., Ltd.", + [3]byte{0, 18, 57}: "S Net Systems Inc.", + [3]byte{0, 18, 58}: "Posystech Inc., Co.", + [3]byte{0, 18, 59}: "KeRo Systems ApS", + [3]byte{0, 18, 60}: "Second Rule LLC", + [3]byte{0, 18, 61}: "GES", + [3]byte{0, 18, 62}: "ERUNE technology Co., Ltd.", + [3]byte{0, 18, 63}: "Dell Inc", + [3]byte{0, 18, 64}: "AMOI ELECTRONICS CO.,LTD", + [3]byte{0, 18, 65}: "a2i marketing center", + [3]byte{0, 18, 66}: "Millennial Net", + [3]byte{0, 18, 67}: "CISCO SYSTEMS, INC.", + [3]byte{0, 18, 68}: "CISCO SYSTEMS, INC.", + [3]byte{0, 18, 69}: "Zellweger Analytics, Inc.", + [3]byte{0, 18, 70}: "T.O.M TECHNOLOGY INC..", + [3]byte{0, 18, 71}: "Samsung Electronics Co., Ltd.", + [3]byte{0, 18, 72}: "EMC Corporation (Kashya)", + [3]byte{0, 18, 73}: "Delta Elettronica S.p.A.", + [3]byte{0, 18, 74}: "Dedicated Devices, Inc.", + [3]byte{0, 18, 75}: "Texas Instruments", + [3]byte{0, 18, 76}: "BBWM Corporation", + [3]byte{0, 18, 77}: "Inducon BV", + [3]byte{0, 18, 78}: "XAC AUTOMATION CORP.", + [3]byte{0, 18, 79}: "Pentair Thermal Management", + [3]byte{0, 18, 80}: "Tokyo Aircaft Instrument Co., Ltd.", + [3]byte{0, 18, 81}: "SILINK", + [3]byte{0, 18, 82}: "Citronix, LLC", + [3]byte{0, 18, 83}: "AudioDev AB", + [3]byte{0, 18, 84}: "Spectra Technologies Holdings Company Ltd", + [3]byte{0, 18, 85}: "NetEffect Incorporated", + [3]byte{0, 18, 86}: "LG INFORMATION & COMM.", + [3]byte{0, 18, 87}: "LeapComm Communication Technologies Inc.", + [3]byte{0, 18, 88}: "Activis Polska", + [3]byte{0, 18, 89}: "THERMO ELECTRON KARLSRUHE", + [3]byte{0, 18, 90}: "Microsoft Corporation", + [3]byte{0, 18, 91}: "KAIMEI ELECTRONI", + [3]byte{0, 18, 92}: "Green Hills Software, Inc.", + [3]byte{0, 18, 93}: "CyberNet Inc.", + [3]byte{0, 18, 94}: "CAEN", + [3]byte{0, 18, 95}: "AWIND Inc.", + [3]byte{0, 18, 96}: "Stanton Magnetics,inc.", + [3]byte{0, 18, 97}: "Adaptix, Inc", + [3]byte{0, 18, 98}: "Nokia Danmark A/S", + [3]byte{0, 18, 99}: "Data Voice Technologies GmbH", + [3]byte{0, 18, 100}: "daum electronic gmbh", + [3]byte{0, 18, 101}: "Enerdyne Technologies, Inc.", + [3]byte{0, 18, 102}: "Swisscom Hospitality Services SA", + [3]byte{0, 18, 103}: "Panasonic Corporation", + [3]byte{0, 18, 104}: "IPS d.o.o.", + [3]byte{0, 18, 105}: "Value Electronics", + [3]byte{0, 18, 106}: "OPTOELECTRONICS Co., Ltd.", + [3]byte{0, 18, 107}: "Ascalade Communications Limited", + [3]byte{0, 18, 108}: "Visonic Ltd.", + [3]byte{0, 18, 109}: "University of California, Berkeley", + [3]byte{0, 18, 110}: "Seidel Elektronik GmbH Nfg.KG", + [3]byte{0, 18, 111}: "Rayson Technology Co., Ltd.", + [3]byte{0, 18, 112}: "NGES Denro Systems", + [3]byte{0, 18, 113}: "Measurement Computing Corp", + [3]byte{0, 18, 114}: "Redux Communications Ltd.", + [3]byte{0, 18, 115}: "Stoke Inc", + [3]byte{0, 18, 116}: "NIT lab", + [3]byte{0, 18, 117}: "Sentilla Corporation", + [3]byte{0, 18, 118}: "CG Power Systems Ireland Limited", + [3]byte{0, 18, 119}: "Korenix Technologies Co., Ltd.", + [3]byte{0, 18, 120}: "International Bar Code", + [3]byte{0, 18, 121}: "Hewlett-Packard Company", + [3]byte{0, 18, 122}: "Sanyu Industry Co.,Ltd.", + [3]byte{0, 18, 123}: "VIA Networking Technologies, Inc.", + [3]byte{0, 18, 124}: "SWEGON AB", + [3]byte{0, 18, 125}: "MobileAria", + [3]byte{0, 18, 126}: "Digital Lifestyles Group, Inc.", + [3]byte{0, 18, 127}: "CISCO SYSTEMS, INC.", + [3]byte{0, 18, 128}: "CISCO SYSTEMS, INC.", + [3]byte{0, 18, 129}: "March Networks S.p.A.", + [3]byte{0, 18, 130}: "Qovia", + [3]byte{0, 18, 131}: "Nortel Networks", + [3]byte{0, 18, 132}: "Lab33 Srl", + [3]byte{0, 18, 133}: "Gizmondo Europe Ltd", + [3]byte{0, 18, 134}: "ENDEVCO CORP", + [3]byte{0, 18, 135}: "Digital Everywhere Unterhaltungselektronik GmbH", + [3]byte{0, 18, 136}: "2Wire, Inc", + [3]byte{0, 18, 137}: "Advance Sterilization Products", + [3]byte{0, 18, 138}: "ARRIS Group, Inc.", + [3]byte{0, 18, 139}: "Sensory Networks Inc", + [3]byte{0, 18, 140}: "Woodward Governor", + [3]byte{0, 18, 141}: "STB Datenservice GmbH", + [3]byte{0, 18, 142}: "Q-Free ASA", + [3]byte{0, 18, 143}: "Montilio", + [3]byte{0, 18, 144}: "KYOWA Electric & Machinery Corp.", + [3]byte{0, 18, 145}: "KWS Computersysteme GmbH", + [3]byte{0, 18, 146}: "Griffin Technology", + [3]byte{0, 18, 147}: "GE Energy", + [3]byte{0, 18, 148}: "SUMITOMO ELECTRIC DEVICE INNOVATIONS, INC", + [3]byte{0, 18, 149}: "Aiware Inc.", + [3]byte{0, 18, 150}: "Addlogix", + [3]byte{0, 18, 151}: "O2Micro, Inc.", + [3]byte{0, 18, 152}: "MICO ELECTRIC(SHENZHEN) LIMITED", + [3]byte{0, 18, 153}: "Ktech Telecommunications Inc", + [3]byte{0, 18, 154}: "IRT Electronics Pty Ltd", + [3]byte{0, 18, 155}: "E2S Electronic Engineering Solutions, S.L.", + [3]byte{0, 18, 156}: "Yulinet", + [3]byte{0, 18, 157}: "First International Computer do Brasil", + [3]byte{0, 18, 158}: "Surf Communications Inc.", + [3]byte{0, 18, 159}: "RAE Systems", + [3]byte{0, 18, 160}: "NeoMeridian Sdn Bhd", + [3]byte{0, 18, 161}: "BluePacket Communications Co., Ltd.", + [3]byte{0, 18, 162}: "VITA", + [3]byte{0, 18, 163}: "Trust International B.V.", + [3]byte{0, 18, 164}: "ThingMagic, LLC", + [3]byte{0, 18, 165}: "Stargen, Inc.", + [3]byte{0, 18, 166}: "Dolby Australia", + [3]byte{0, 18, 167}: "ISR TECHNOLOGIES Inc", + [3]byte{0, 18, 168}: "intec GmbH", + [3]byte{0, 18, 169}: "3Com Ltd", + [3]byte{0, 18, 170}: "IEE, Inc.", + [3]byte{0, 18, 171}: "WiLife, Inc.", + [3]byte{0, 18, 172}: "ONTIMETEK INC.", + [3]byte{0, 18, 173}: "IDS GmbH", + [3]byte{0, 18, 174}: "HLS HARD-LINE Solutions Inc.", + [3]byte{0, 18, 175}: "ELPRO Technologies", + [3]byte{0, 18, 176}: "Efore Oyj (Plc)", + [3]byte{0, 18, 177}: "Dai Nippon Printing Co., Ltd", + [3]byte{0, 18, 178}: "AVOLITES LTD.", + [3]byte{0, 18, 179}: "Advance Wireless Technology Corp.", + [3]byte{0, 18, 180}: "Work Microwave GmbH", + [3]byte{0, 18, 181}: "Vialta, Inc.", + [3]byte{0, 18, 182}: "Santa Barbara Infrared, Inc.", + [3]byte{0, 18, 183}: "PTW Freiburg", + [3]byte{0, 18, 184}: "G2 Microsystems", + [3]byte{0, 18, 185}: "Fusion Digital Technology", + [3]byte{0, 18, 186}: "FSI Systems, Inc.", + [3]byte{0, 18, 187}: "Telecommunications Industry Association TR-41 Committee", + [3]byte{0, 18, 188}: "Echolab LLC", + [3]byte{0, 18, 189}: "Avantec Manufacturing Limited", + [3]byte{0, 18, 190}: "Astek Corporation", + [3]byte{0, 18, 191}: "Arcadyan Technology Corporation", + [3]byte{0, 18, 192}: "HotLava Systems, Inc.", + [3]byte{0, 18, 193}: "Check Point Software Technologies", + [3]byte{0, 18, 194}: "Apex Electronics Factory", + [3]byte{0, 18, 195}: "WIT S.A.", + [3]byte{0, 18, 196}: "Viseon, Inc.", + [3]byte{0, 18, 197}: "V-Show Technology (China) Co.,Ltd", + [3]byte{0, 18, 198}: "TGC America, Inc", + [3]byte{0, 18, 199}: "SECURAY Technologies Ltd.Co.", + [3]byte{0, 18, 200}: "Perfect tech", + [3]byte{0, 18, 201}: "ARRIS Group, Inc.", + [3]byte{0, 18, 202}: "Mechatronic Brick Aps", + [3]byte{0, 18, 203}: "CSS Inc.", + [3]byte{0, 18, 204}: "Bitatek CO., LTD", + [3]byte{0, 18, 205}: "ASEM SpA", + [3]byte{0, 18, 206}: "Advanced Cybernetics Group", + [3]byte{0, 18, 207}: "Accton Technology Corporation", + [3]byte{0, 18, 208}: "Gossen-Metrawatt-GmbH", + [3]byte{0, 18, 209}: "Texas Instruments Inc", + [3]byte{0, 18, 210}: "Texas Instruments", + [3]byte{0, 18, 211}: "Zetta Systems, Inc.", + [3]byte{0, 18, 212}: "Princeton Technology, Ltd", + [3]byte{0, 18, 213}: "Motion Reality Inc.", + [3]byte{0, 18, 214}: "Jiangsu Yitong High-Tech Co.,Ltd", + [3]byte{0, 18, 215}: "Invento Networks, Inc.", + [3]byte{0, 18, 216}: "International Games System Co., Ltd.", + [3]byte{0, 18, 217}: "CISCO SYSTEMS, INC.", + [3]byte{0, 18, 218}: "CISCO SYSTEMS, INC.", + [3]byte{0, 18, 219}: "ZIEHL industrie-elektronik GmbH + Co KG", + [3]byte{0, 18, 220}: "SunCorp Industrial Limited", + [3]byte{0, 18, 221}: "Shengqu Information Technology (Shanghai) Co., Ltd.", + [3]byte{0, 18, 222}: "Radio Components Sweden AB", + [3]byte{0, 18, 223}: "Novomatic AG", + [3]byte{0, 18, 224}: "Codan Limited", + [3]byte{0, 18, 225}: "Alliant Networks, Inc", + [3]byte{0, 18, 226}: "ALAXALA Networks Corporation", + [3]byte{0, 18, 227}: "Agat-RT, Ltd.", + [3]byte{0, 18, 228}: "ZIEHL industrie-electronik GmbH + Co KG", + [3]byte{0, 18, 229}: "Time America, Inc.", + [3]byte{0, 18, 230}: "SPECTEC COMPUTER CO., LTD.", + [3]byte{0, 18, 231}: "Projectek Networking Electronics Corp.", + [3]byte{0, 18, 232}: "Fraunhofer IMS", + [3]byte{0, 18, 233}: "Abbey Systems Ltd", + [3]byte{0, 18, 234}: "Trane", + [3]byte{0, 18, 235}: "PDH Solutions, LLC", + [3]byte{0, 18, 236}: "Movacolor b.v.", + [3]byte{0, 18, 237}: "AVG Advanced Technologies", + [3]byte{0, 18, 238}: "Sony Ericsson Mobile Communications AB", + [3]byte{0, 18, 239}: "OneAccess SA", + [3]byte{0, 18, 240}: "Intel Corporate", + [3]byte{0, 18, 241}: "IFOTEC", + [3]byte{0, 18, 242}: "Brocade Communications Systems, Inc", + [3]byte{0, 18, 243}: "connectBlue AB", + [3]byte{0, 18, 244}: "Belco International Co.,Ltd.", + [3]byte{0, 18, 245}: "Imarda New Zealand Limited", + [3]byte{0, 18, 246}: "MDK CO.,LTD.", + [3]byte{0, 18, 247}: "Xiamen Xinglian Electronics Co., Ltd.", + [3]byte{0, 18, 248}: "WNI Resources, LLC", + [3]byte{0, 18, 249}: "URYU SEISAKU, LTD.", + [3]byte{0, 18, 250}: "THX LTD", + [3]byte{0, 18, 251}: "Samsung Electronics", + [3]byte{0, 18, 252}: "PLANET System Co.,LTD", + [3]byte{0, 18, 253}: "OPTIMUS IC S.A.", + [3]byte{0, 18, 254}: "Lenovo Mobile Communication Technology Ltd.", + [3]byte{0, 18, 255}: "Lely Industries N.V.", + [3]byte{0, 19, 0}: "IT-FACTORY, INC.", + [3]byte{0, 19, 1}: "IronGate S.L.", + [3]byte{0, 19, 2}: "Intel Corporate", + [3]byte{0, 19, 3}: "GateConnect", + [3]byte{0, 19, 4}: "Flaircomm Technologies Co. LTD", + [3]byte{0, 19, 5}: "Epicom, Inc.", + [3]byte{0, 19, 6}: "Always On Wireless", + [3]byte{0, 19, 7}: "Paravirtual Corporation", + [3]byte{0, 19, 8}: "Nuvera Fuel Cells", + [3]byte{0, 19, 9}: "Ocean Broadband Networks", + [3]byte{0, 19, 10}: "Nortel", + [3]byte{0, 19, 11}: "Mextal B.V.", + [3]byte{0, 19, 12}: "HF System Corporation", + [3]byte{0, 19, 13}: "GALILEO AVIONICA", + [3]byte{0, 19, 14}: "Focusrite Audio Engineering Limited", + [3]byte{0, 19, 15}: "EGEMEN Bilgisayar Muh San ve Tic LTD STI", + [3]byte{0, 19, 16}: "Cisco-Linksys, LLC", + [3]byte{0, 19, 17}: "ARRIS International", + [3]byte{0, 19, 18}: "Amedia Networks Inc.", + [3]byte{0, 19, 19}: "GuangZhou Post & Telecom Equipment ltd", + [3]byte{0, 19, 20}: "Asiamajor Inc.", + [3]byte{0, 19, 21}: "SONY Computer Entertainment inc,", + [3]byte{0, 19, 22}: "L-S-B Broadcast Technologies GmbH", + [3]byte{0, 19, 23}: "GN Netcom as", + [3]byte{0, 19, 24}: "DGSTATION Co., Ltd.", + [3]byte{0, 19, 25}: "CISCO SYSTEMS, INC.", + [3]byte{0, 19, 26}: "CISCO SYSTEMS, INC.", + [3]byte{0, 19, 27}: "BeCell Innovations Corp.", + [3]byte{0, 19, 28}: "LiteTouch, Inc.", + [3]byte{0, 19, 29}: "Scanvaegt International A/S", + [3]byte{0, 19, 30}: "Peiker acustic GmbH & Co. KG", + [3]byte{0, 19, 31}: "NxtPhase T&D, Corp.", + [3]byte{0, 19, 32}: "Intel Corporate", + [3]byte{0, 19, 33}: "Hewlett-Packard Company", + [3]byte{0, 19, 34}: "DAQ Electronics, Inc.", + [3]byte{0, 19, 35}: "Cap Co., Ltd.", + [3]byte{0, 19, 36}: "Schneider Electric Ultra Terminal", + [3]byte{0, 19, 37}: "Cortina Systems Inc", + [3]byte{0, 19, 38}: "ECM Systems Ltd", + [3]byte{0, 19, 39}: "Data Acquisitions limited", + [3]byte{0, 19, 40}: "Westech Korea Inc.,", + [3]byte{0, 19, 41}: "VSST Co., LTD", + [3]byte{0, 19, 42}: "Sitronics Telecom Solutions", + [3]byte{0, 19, 43}: "Phoenix Digital", + [3]byte{0, 19, 44}: "MAZ Brandenburg GmbH", + [3]byte{0, 19, 45}: "iWise Communications", + [3]byte{0, 19, 46}: "ITian Coporation", + [3]byte{0, 19, 47}: "Interactek", + [3]byte{0, 19, 48}: "EURO PROTECTION SURVEILLANCE", + [3]byte{0, 19, 49}: "CellPoint Connect", + [3]byte{0, 19, 50}: "Beijing Topsec Network Security Technology Co., Ltd.", + [3]byte{0, 19, 51}: "BaudTec Corporation", + [3]byte{0, 19, 52}: "Arkados, Inc.", + [3]byte{0, 19, 53}: "VS Industry Berhad", + [3]byte{0, 19, 54}: "Tianjin 712 Communication Broadcasting co., ltd.", + [3]byte{0, 19, 55}: "Orient Power Home Network Ltd.", + [3]byte{0, 19, 56}: "FRESENIUS-VIAL", + [3]byte{0, 19, 57}: "CCV Deutschland GmbH", + [3]byte{0, 19, 58}: "VadaTech Inc.", + [3]byte{0, 19, 59}: "Speed Dragon Multimedia Limited", + [3]byte{0, 19, 60}: "QUINTRON SYSTEMS INC.", + [3]byte{0, 19, 61}: "Micro Memory Curtiss Wright Co", + [3]byte{0, 19, 62}: "MetaSwitch", + [3]byte{0, 19, 63}: "Eppendorf Instrumente GmbH", + [3]byte{0, 19, 64}: "AD.EL s.r.l.", + [3]byte{0, 19, 65}: "Shandong New Beiyang Information Technology Co.,Ltd", + [3]byte{0, 19, 66}: "Vision Research, Inc.", + [3]byte{0, 19, 67}: "Matsushita Electronic Components (Europe) GmbH", + [3]byte{0, 19, 68}: "Fargo Electronics Inc.", + [3]byte{0, 19, 69}: "Eaton Corporation", + [3]byte{0, 19, 70}: "D-Link Corporation", + [3]byte{0, 19, 71}: "BlueTree Wireless Data Inc.", + [3]byte{0, 19, 72}: "Artila Electronics Co., Ltd.", + [3]byte{0, 19, 73}: "ZyXEL Communications Corporation", + [3]byte{0, 19, 74}: "Engim, Inc.", + [3]byte{0, 19, 75}: "ToGoldenNet Technology Inc.", + [3]byte{0, 19, 76}: "YDT Technology International", + [3]byte{0, 19, 77}: "Inepro BV", + [3]byte{0, 19, 78}: "Valox Systems, Inc.", + [3]byte{0, 19, 79}: "Tranzeo Wireless Technologies Inc.", + [3]byte{0, 19, 80}: "Silver Spring Networks, Inc", + [3]byte{0, 19, 81}: "Niles Audio Corporation", + [3]byte{0, 19, 82}: "Naztec, Inc.", + [3]byte{0, 19, 83}: "HYDAC Filtertechnik GMBH", + [3]byte{0, 19, 84}: "Zcomax Technologies, Inc.", + [3]byte{0, 19, 85}: "TOMEN Cyber-business Solutions, Inc.", + [3]byte{0, 19, 86}: "FLIR Radiation Inc", + [3]byte{0, 19, 87}: "Soyal Technology Co., Ltd.", + [3]byte{0, 19, 88}: "Realm Systems, Inc.", + [3]byte{0, 19, 89}: "ProTelevision Technologies A/S", + [3]byte{0, 19, 90}: "Project T&E Limited", + [3]byte{0, 19, 91}: "PanelLink Cinema, LLC", + [3]byte{0, 19, 92}: "OnSite Systems, Inc.", + [3]byte{0, 19, 93}: "NTTPC Communications, Inc.", + [3]byte{0, 19, 94}: "EAB/RWI/K", + [3]byte{0, 19, 95}: "CISCO SYSTEMS, INC.", + [3]byte{0, 19, 96}: "CISCO SYSTEMS, INC.", + [3]byte{0, 19, 97}: "Biospace Co., Ltd.", + [3]byte{0, 19, 98}: "ShinHeung Precision Co., Ltd.", + [3]byte{0, 19, 99}: "Verascape, Inc.", + [3]byte{0, 19, 100}: "Paradigm Technology Inc..", + [3]byte{0, 19, 101}: "Nortel", + [3]byte{0, 19, 102}: "Neturity Technologies Inc.", + [3]byte{0, 19, 103}: "Narayon. Co., Ltd.", + [3]byte{0, 19, 104}: "Saab Danmark A/S", + [3]byte{0, 19, 105}: "Honda Electron Co., LED.", + [3]byte{0, 19, 106}: "Hach Lange Sarl", + [3]byte{0, 19, 107}: "E-TEC", + [3]byte{0, 19, 108}: "TomTom", + [3]byte{0, 19, 109}: "Tentaculus AB", + [3]byte{0, 19, 110}: "Techmetro Corp.", + [3]byte{0, 19, 111}: "PacketMotion, Inc.", + [3]byte{0, 19, 112}: "Nokia Danmark A/S", + [3]byte{0, 19, 113}: "ARRIS Group, Inc.", + [3]byte{0, 19, 114}: "Dell Inc", + [3]byte{0, 19, 115}: "BLwave Electronics Co., Ltd", + [3]byte{0, 19, 116}: "Atheros Communications, Inc.", + [3]byte{0, 19, 117}: "American Security Products Co.", + [3]byte{0, 19, 118}: "Tabor Electronics Ltd.", + [3]byte{0, 19, 119}: "Samsung Electronics CO., LTD", + [3]byte{0, 19, 120}: "Qsan Technology, Inc.", + [3]byte{0, 19, 121}: "PONDER INFORMATION INDUSTRIES LTD.", + [3]byte{0, 19, 122}: "Netvox Technology Co., Ltd.", + [3]byte{0, 19, 123}: "Movon Corporation", + [3]byte{0, 19, 124}: "Kaicom co., Ltd.", + [3]byte{0, 19, 125}: "Dynalab, Inc.", + [3]byte{0, 19, 126}: "CorEdge Networks, Inc.", + [3]byte{0, 19, 127}: "CISCO SYSTEMS, INC.", + [3]byte{0, 19, 128}: "CISCO SYSTEMS, INC.", + [3]byte{0, 19, 129}: "CHIPS & Systems, Inc.", + [3]byte{0, 19, 130}: "Cetacea Networks Corporation", + [3]byte{0, 19, 131}: "Application Technologies and Engineering Research Laboratory", + [3]byte{0, 19, 132}: "Advanced Motion Controls", + [3]byte{0, 19, 133}: "Add-On Technology Co., LTD.", + [3]byte{0, 19, 134}: "ABB Inc./Totalflow", + [3]byte{0, 19, 135}: "27M Technologies AB", + [3]byte{0, 19, 136}: "WiMedia Alliance", + [3]byte{0, 19, 137}: "Redes de Telefonía Móvil S.A.", + [3]byte{0, 19, 138}: "QINGDAO GOERTEK ELECTRONICS CO.,LTD.", + [3]byte{0, 19, 139}: "Phantom Technologies LLC", + [3]byte{0, 19, 140}: "Kumyoung.Co.Ltd", + [3]byte{0, 19, 141}: "Kinghold", + [3]byte{0, 19, 142}: "FOAB Elektronik AB", + [3]byte{0, 19, 143}: "Asiarock Incorporation", + [3]byte{0, 19, 144}: "Termtek Computer Co., Ltd", + [3]byte{0, 19, 145}: "OUEN CO.,LTD.", + [3]byte{0, 19, 146}: "Ruckus Wireless", + [3]byte{0, 19, 147}: "Panta Systems, Inc.", + [3]byte{0, 19, 148}: "Infohand Co.,Ltd", + [3]byte{0, 19, 149}: "congatec AG", + [3]byte{0, 19, 150}: "Acbel Polytech Inc.", + [3]byte{0, 19, 151}: "Oracle Corporation", + [3]byte{0, 19, 152}: "TrafficSim Co.,Ltd", + [3]byte{0, 19, 153}: "STAC Corporation.", + [3]byte{0, 19, 154}: "K-ubique ID Corp.", + [3]byte{0, 19, 155}: "ioIMAGE Ltd.", + [3]byte{0, 19, 156}: "Exavera Technologies, Inc.", + [3]byte{0, 19, 157}: "Marvell Hispana S.L.", + [3]byte{0, 19, 158}: "Ciara Technologies Inc.", + [3]byte{0, 19, 159}: "Electronics Design Services, Co., Ltd.", + [3]byte{0, 19, 160}: "ALGOSYSTEM Co., Ltd.", + [3]byte{0, 19, 161}: "Crow Electronic Engeneering", + [3]byte{0, 19, 162}: "MaxStream, Inc", + [3]byte{0, 19, 163}: "Siemens Com CPE Devices", + [3]byte{0, 19, 164}: "KeyEye Communications", + [3]byte{0, 19, 165}: "General Solutions, LTD.", + [3]byte{0, 19, 166}: "Extricom Ltd", + [3]byte{0, 19, 167}: "BATTELLE MEMORIAL INSTITUTE", + [3]byte{0, 19, 168}: "Tanisys Technology", + [3]byte{0, 19, 169}: "Sony Corporation", + [3]byte{0, 19, 170}: "ALS & TEC Ltd.", + [3]byte{0, 19, 171}: "Telemotive AG", + [3]byte{0, 19, 172}: "Sunmyung Electronics Co., LTD", + [3]byte{0, 19, 173}: "Sendo Ltd", + [3]byte{0, 19, 174}: "Radiance Technologies, Inc.", + [3]byte{0, 19, 175}: "NUMA Technology,Inc.", + [3]byte{0, 19, 176}: "Jablotron", + [3]byte{0, 19, 177}: "Intelligent Control Systems (Asia) Pte Ltd", + [3]byte{0, 19, 178}: "Carallon Limited", + [3]byte{0, 19, 179}: "Ecom Communications Technology Co., Ltd.", + [3]byte{0, 19, 180}: "Appear TV", + [3]byte{0, 19, 181}: "Wavesat", + [3]byte{0, 19, 182}: "Sling Media, Inc.", + [3]byte{0, 19, 183}: "Scantech ID", + [3]byte{0, 19, 184}: "RyCo Electronic Systems Limited", + [3]byte{0, 19, 185}: "BM SPA", + [3]byte{0, 19, 186}: "ReadyLinks Inc", + [3]byte{0, 19, 187}: "Smartvue Corporation", + [3]byte{0, 19, 188}: "Artimi Ltd", + [3]byte{0, 19, 189}: "HYMATOM SA", + [3]byte{0, 19, 190}: "Virtual Conexions", + [3]byte{0, 19, 191}: "Media System Planning Corp.", + [3]byte{0, 19, 192}: "Trix Tecnologia Ltda.", + [3]byte{0, 19, 193}: "Asoka USA Corporation", + [3]byte{0, 19, 194}: "WACOM Co.,Ltd", + [3]byte{0, 19, 195}: "CISCO SYSTEMS, INC.", + [3]byte{0, 19, 196}: "CISCO SYSTEMS, INC.", + [3]byte{0, 19, 197}: "LIGHTRON FIBER-OPTIC DEVICES INC.", + [3]byte{0, 19, 198}: "OpenGear, Inc", + [3]byte{0, 19, 199}: "IONOS Co.,Ltd.", + [3]byte{0, 19, 200}: "ADB Broadband Italia", + [3]byte{0, 19, 201}: "Beyond Achieve Enterprises Ltd.", + [3]byte{0, 19, 202}: "Pico Digital", + [3]byte{0, 19, 203}: "Zenitel Norway AS", + [3]byte{0, 19, 204}: "Tall Maple Systems", + [3]byte{0, 19, 205}: "MTI co. LTD", + [3]byte{0, 19, 206}: "Intel Corporate", + [3]byte{0, 19, 207}: "4Access Communications", + [3]byte{0, 19, 208}: "t+ Medical Ltd", + [3]byte{0, 19, 209}: "KIRK telecom A/S", + [3]byte{0, 19, 210}: "PAGE IBERICA, S.A.", + [3]byte{0, 19, 211}: "MICRO-STAR INTERNATIONAL CO., LTD.", + [3]byte{0, 19, 212}: "ASUSTek COMPUTER INC.", + [3]byte{0, 19, 213}: "RuggedCom", + [3]byte{0, 19, 214}: "TII NETWORK TECHNOLOGIES, INC.", + [3]byte{0, 19, 215}: "SPIDCOM Technologies SA", + [3]byte{0, 19, 216}: "Princeton Instruments", + [3]byte{0, 19, 217}: "Matrix Product Development, Inc.", + [3]byte{0, 19, 218}: "Diskware Co., Ltd", + [3]byte{0, 19, 219}: "SHOEI Electric Co.,Ltd", + [3]byte{0, 19, 220}: "IBTEK INC.", + [3]byte{0, 19, 221}: "Abbott Diagnostics", + [3]byte{0, 19, 222}: "Adapt4, LLC", + [3]byte{0, 19, 223}: "Ryvor Corp.", + [3]byte{0, 19, 224}: "Murata Manufacturing Co., Ltd.", + [3]byte{0, 19, 225}: "Iprobe AB", + [3]byte{0, 19, 226}: "GeoVision Inc.", + [3]byte{0, 19, 227}: "CoVi Technologies, Inc.", + [3]byte{0, 19, 228}: "YANGJAE SYSTEMS CORP.", + [3]byte{0, 19, 229}: "TENOSYS, INC.", + [3]byte{0, 19, 230}: "Technolution", + [3]byte{0, 19, 231}: "Halcro", + [3]byte{0, 19, 232}: "Intel Corporate", + [3]byte{0, 19, 233}: "VeriWave, Inc.", + [3]byte{0, 19, 234}: "Kamstrup A/S", + [3]byte{0, 19, 235}: "Sysmaster Corporation", + [3]byte{0, 19, 236}: "Sunbay Software AG", + [3]byte{0, 19, 237}: "PSIA", + [3]byte{0, 19, 238}: "JBX Designs Inc.", + [3]byte{0, 19, 239}: "Kingjon Digital Technology Co.,Ltd", + [3]byte{0, 19, 240}: "Wavefront Semiconductor", + [3]byte{0, 19, 241}: "AMOD Technology Co., Ltd.", + [3]byte{0, 19, 242}: "Klas Ltd", + [3]byte{0, 19, 243}: "Giga-byte Communications Inc.", + [3]byte{0, 19, 244}: "Psitek (Pty) Ltd", + [3]byte{0, 19, 245}: "Akimbi Systems", + [3]byte{0, 19, 246}: "Cintech", + [3]byte{0, 19, 247}: "SMC Networks, Inc.", + [3]byte{0, 19, 248}: "Dex Security Solutions", + [3]byte{0, 19, 249}: "Cavera Systems", + [3]byte{0, 19, 250}: "LifeSize Communications, Inc", + [3]byte{0, 19, 251}: "RKC INSTRUMENT INC.", + [3]byte{0, 19, 252}: "SiCortex, Inc", + [3]byte{0, 19, 253}: "Nokia Danmark A/S", + [3]byte{0, 19, 254}: "GRANDTEC ELECTRONIC CORP.", + [3]byte{0, 19, 255}: "Dage-MTI of MC, Inc.", + [3]byte{0, 20, 0}: "MINERVA KOREA CO., LTD", + [3]byte{0, 20, 1}: "Rivertree Networks Corp.", + [3]byte{0, 20, 2}: "kk-electronic a/s", + [3]byte{0, 20, 3}: "Renasis, LLC", + [3]byte{0, 20, 4}: "ARRIS Group, Inc.", + [3]byte{0, 20, 5}: "OpenIB, Inc.", + [3]byte{0, 20, 6}: "Go Networks", + [3]byte{0, 20, 7}: "Sperian Protection Instrumentation", + [3]byte{0, 20, 8}: "Eka Systems Inc.", + [3]byte{0, 20, 9}: "MAGNETI MARELLI S.E. S.p.A.", + [3]byte{0, 20, 10}: "WEPIO Co., Ltd.", + [3]byte{0, 20, 11}: "FIRST INTERNATIONAL COMPUTER, INC.", + [3]byte{0, 20, 12}: "GKB CCTV CO., LTD.", + [3]byte{0, 20, 13}: "Nortel", + [3]byte{0, 20, 14}: "Nortel", + [3]byte{0, 20, 15}: "Federal State Unitary Enterprise Leningrad R&D Institute of", + [3]byte{0, 20, 16}: "Suzhou Keda Technology CO.,Ltd", + [3]byte{0, 20, 17}: "Deutschmann Automation GmbH & Co. KG", + [3]byte{0, 20, 18}: "S-TEC electronics AG", + [3]byte{0, 20, 19}: "Trebing & Himstedt Prozeßautomation GmbH & Co. KG", + [3]byte{0, 20, 20}: "Jumpnode Systems LLC.", + [3]byte{0, 20, 21}: "Intec Automation Inc.", + [3]byte{0, 20, 22}: "Scosche Industries, Inc.", + [3]byte{0, 20, 23}: "RSE Informations Technologie GmbH", + [3]byte{0, 20, 24}: "C4Line", + [3]byte{0, 20, 25}: "SIDSA", + [3]byte{0, 20, 26}: "DEICY CORPORATION", + [3]byte{0, 20, 27}: "CISCO SYSTEMS, INC.", + [3]byte{0, 20, 28}: "CISCO SYSTEMS, INC.", + [3]byte{0, 20, 29}: "LTi DRIVES GmbH", + [3]byte{0, 20, 30}: "P.A. Semi, Inc.", + [3]byte{0, 20, 31}: "SunKwang Electronics Co., Ltd", + [3]byte{0, 20, 32}: "G-Links networking company", + [3]byte{0, 20, 33}: "Total Wireless Technologies Pte. Ltd.", + [3]byte{0, 20, 34}: "Dell Inc", + [3]byte{0, 20, 35}: "J-S Co. NEUROCOM", + [3]byte{0, 20, 36}: "Merry Electrics CO., LTD.", + [3]byte{0, 20, 37}: "Galactic Computing Corp.", + [3]byte{0, 20, 38}: "NL Technology", + [3]byte{0, 20, 39}: "JazzMutant", + [3]byte{0, 20, 40}: "Vocollect, Inc", + [3]byte{0, 20, 41}: "V Center Technologies Co., Ltd.", + [3]byte{0, 20, 42}: "Elitegroup Computer System Co., Ltd", + [3]byte{0, 20, 43}: "Edata Communication Inc.", + [3]byte{0, 20, 44}: "Koncept International, Inc.", + [3]byte{0, 20, 45}: "Toradex AG", + [3]byte{0, 20, 46}: "77 Elektronika Kft.", + [3]byte{0, 20, 47}: "WildPackets", + [3]byte{0, 20, 48}: "ViPowER, Inc", + [3]byte{0, 20, 49}: "PDL Electronics Ltd", + [3]byte{0, 20, 50}: "Tarallax Wireless, Inc.", + [3]byte{0, 20, 51}: "Empower Technologies(Canada) Inc.", + [3]byte{0, 20, 52}: "Keri Systems, Inc", + [3]byte{0, 20, 53}: "CityCom Corp.", + [3]byte{0, 20, 54}: "Qwerty Elektronik AB", + [3]byte{0, 20, 55}: "GSTeletech Co.,Ltd.", + [3]byte{0, 20, 56}: "Hewlett-Packard Company", + [3]byte{0, 20, 57}: "Blonder Tongue Laboratories, Inc.", + [3]byte{0, 20, 58}: "RAYTALK INTERNATIONAL SRL", + [3]byte{0, 20, 59}: "Sensovation AG", + [3]byte{0, 20, 60}: "Rheinmetall Canada Inc.", + [3]byte{0, 20, 61}: "Aevoe Inc.", + [3]byte{0, 20, 62}: "AirLink Communications, Inc.", + [3]byte{0, 20, 63}: "Hotway Technology Corporation", + [3]byte{0, 20, 64}: "ATOMIC Corporation", + [3]byte{0, 20, 65}: "Innovation Sound Technology Co., LTD.", + [3]byte{0, 20, 66}: "ATTO CORPORATION", + [3]byte{0, 20, 67}: "Consultronics Europe Ltd", + [3]byte{0, 20, 68}: "Grundfos Holding", + [3]byte{0, 20, 69}: "Telefon-Gradnja d.o.o.", + [3]byte{0, 20, 70}: "SuperVision Solutions LLC", + [3]byte{0, 20, 71}: "BOAZ Inc.", + [3]byte{0, 20, 72}: "Inventec Multimedia & Telecom Corporation", + [3]byte{0, 20, 73}: "Sichuan Changhong Electric Ltd.", + [3]byte{0, 20, 74}: "Taiwan Thick-Film Ind. Corp.", + [3]byte{0, 20, 75}: "Hifn, Inc.", + [3]byte{0, 20, 76}: "General Meters Corp.", + [3]byte{0, 20, 77}: "Intelligent Systems", + [3]byte{0, 20, 78}: "SRISA", + [3]byte{0, 20, 79}: "Oracle Corporation", + [3]byte{0, 20, 80}: "Heim Systems GmbH", + [3]byte{0, 20, 81}: "Apple", + [3]byte{0, 20, 82}: "CALCULEX,INC.", + [3]byte{0, 20, 83}: "ADVANTECH TECHNOLOGIES CO.,LTD", + [3]byte{0, 20, 84}: "Symwave", + [3]byte{0, 20, 85}: "Coder Electronics Corporation", + [3]byte{0, 20, 86}: "Edge Products", + [3]byte{0, 20, 87}: "T-VIPS AS", + [3]byte{0, 20, 88}: "HS Automatic ApS", + [3]byte{0, 20, 89}: "Moram Co., Ltd.", + [3]byte{0, 20, 90}: "Neratec Solutions AG", + [3]byte{0, 20, 91}: "SeekerNet Inc.", + [3]byte{0, 20, 92}: "Intronics B.V.", + [3]byte{0, 20, 93}: "WJ Communications, Inc.", + [3]byte{0, 20, 94}: "IBM Corp", + [3]byte{0, 20, 95}: "ADITEC CO. LTD", + [3]byte{0, 20, 96}: "Kyocera Wireless Corp.", + [3]byte{0, 20, 97}: "CORONA CORPORATION", + [3]byte{0, 20, 98}: "Digiwell Technology, inc", + [3]byte{0, 20, 99}: "IDCS N.V.", + [3]byte{0, 20, 100}: "Cryptosoft", + [3]byte{0, 20, 101}: "Novo Nordisk A/S", + [3]byte{0, 20, 102}: "Kleinhenz Elektronik GmbH", + [3]byte{0, 20, 103}: "ArrowSpan Inc.", + [3]byte{0, 20, 104}: "CelPlan International, Inc.", + [3]byte{0, 20, 105}: "CISCO SYSTEMS, INC.", + [3]byte{0, 20, 106}: "CISCO SYSTEMS, INC.", + [3]byte{0, 20, 107}: "Anagran, Inc.", + [3]byte{0, 20, 108}: "Netgear Inc.", + [3]byte{0, 20, 109}: "RF Technologies", + [3]byte{0, 20, 110}: "H. Stoll GmbH & Co. KG", + [3]byte{0, 20, 111}: "Kohler Co", + [3]byte{0, 20, 112}: "Prokom Software SA", + [3]byte{0, 20, 113}: "Eastern Asia Technology Limited", + [3]byte{0, 20, 114}: "China Broadband Wireless IP Standard Group", + [3]byte{0, 20, 115}: "Bookham Inc", + [3]byte{0, 20, 116}: "K40 Electronics", + [3]byte{0, 20, 117}: "Wiline Networks, Inc.", + [3]byte{0, 20, 118}: "MultiCom Industries Limited", + [3]byte{0, 20, 119}: "Nertec Inc.", + [3]byte{0, 20, 120}: "ShenZhen TP-LINK Technologies Co., Ltd.", + [3]byte{0, 20, 121}: "NEC Magnus Communications,Ltd.", + [3]byte{0, 20, 122}: "Eubus GmbH", + [3]byte{0, 20, 123}: "Iteris, Inc.", + [3]byte{0, 20, 124}: "3Com Ltd", + [3]byte{0, 20, 125}: "Aeon Digital International", + [3]byte{0, 20, 126}: "InnerWireless", + [3]byte{0, 20, 127}: "Thomson Telecom Belgium", + [3]byte{0, 20, 128}: "Hitachi-LG Data Storage Korea, Inc", + [3]byte{0, 20, 129}: "Multilink Inc", + [3]byte{0, 20, 130}: "Aurora Networks", + [3]byte{0, 20, 131}: "eXS Inc.", + [3]byte{0, 20, 132}: "Cermate Technologies Inc.", + [3]byte{0, 20, 133}: "Giga-Byte", + [3]byte{0, 20, 134}: "Echo Digital Audio Corporation", + [3]byte{0, 20, 135}: "American Technology Integrators", + [3]byte{0, 20, 136}: "Akorri", + [3]byte{0, 20, 137}: "B15402100 - JANDEI, S.L.", + [3]byte{0, 20, 138}: "Elin Ebg Traction Gmbh", + [3]byte{0, 20, 139}: "Globo Electronic GmbH & Co. KG", + [3]byte{0, 20, 140}: "Fortress Technologies", + [3]byte{0, 20, 141}: "Cubic Defense Simulation Systems", + [3]byte{0, 20, 142}: "Tele Power Inc.", + [3]byte{0, 20, 143}: "Protronic (Far East) Ltd.", + [3]byte{0, 20, 144}: "ASP Corporation", + [3]byte{0, 20, 145}: "Daniels Electronics Ltd. dbo Codan Rado Communications", + [3]byte{0, 20, 146}: "Liteon, Mobile Media Solution SBU", + [3]byte{0, 20, 147}: "Systimax Solutions", + [3]byte{0, 20, 148}: "ESU AG", + [3]byte{0, 20, 149}: "2Wire, Inc.", + [3]byte{0, 20, 150}: "Phonic Corp.", + [3]byte{0, 20, 151}: "ZHIYUAN Eletronics co.,ltd.", + [3]byte{0, 20, 152}: "Viking Design Technology", + [3]byte{0, 20, 153}: "Helicomm Inc", + [3]byte{0, 20, 154}: "ARRIS Group, Inc.", + [3]byte{0, 20, 155}: "Nokota Communications, LLC", + [3]byte{0, 20, 156}: "HF Company", + [3]byte{0, 20, 157}: "Sound ID Inc.", + [3]byte{0, 20, 158}: "UbONE Co., Ltd", + [3]byte{0, 20, 159}: "System and Chips, Inc.", + [3]byte{0, 20, 160}: "Accsense, Inc.", + [3]byte{0, 20, 161}: "Synchronous Communication Corp", + [3]byte{0, 20, 162}: "Core Micro Systems Inc.", + [3]byte{0, 20, 163}: "Vitelec BV", + [3]byte{0, 20, 164}: "Hon Hai Precision Ind. Co., Ltd.", + [3]byte{0, 20, 165}: "Gemtek Technology Co., Ltd.", + [3]byte{0, 20, 166}: "Teranetics, Inc.", + [3]byte{0, 20, 167}: "Nokia Danmark A/S", + [3]byte{0, 20, 168}: "CISCO SYSTEMS, INC.", + [3]byte{0, 20, 169}: "CISCO SYSTEMS, INC.", + [3]byte{0, 20, 170}: "Ashly Audio, Inc.", + [3]byte{0, 20, 171}: "Senhai Electronic Technology Co., Ltd.", + [3]byte{0, 20, 172}: "Bountiful WiFi", + [3]byte{0, 20, 173}: "Gassner Wiege- und Meßtechnik GmbH", + [3]byte{0, 20, 174}: "Wizlogics Co., Ltd.", + [3]byte{0, 20, 175}: "Datasym POS Inc.", + [3]byte{0, 20, 176}: "Naeil Community", + [3]byte{0, 20, 177}: "Avitec AB", + [3]byte{0, 20, 178}: "mCubelogics Corporation", + [3]byte{0, 20, 179}: "CoreStar International Corp", + [3]byte{0, 20, 180}: "General Dynamics United Kingdom Ltd", + [3]byte{0, 20, 181}: "PHYSIOMETRIX,INC", + [3]byte{0, 20, 182}: "Enswer Technology Inc.", + [3]byte{0, 20, 183}: "AR Infotek Inc.", + [3]byte{0, 20, 184}: "Hill-Rom", + [3]byte{0, 20, 185}: "MSTAR SEMICONDUCTOR", + [3]byte{0, 20, 186}: "Carvers SA de CV", + [3]byte{0, 20, 187}: "Open Interface North America", + [3]byte{0, 20, 188}: "SYNECTIC TELECOM EXPORTS PVT. LTD.", + [3]byte{0, 20, 189}: "incNETWORKS, Inc", + [3]byte{0, 20, 190}: "Wink communication technology CO.LTD", + [3]byte{0, 20, 191}: "Cisco-Linksys LLC", + [3]byte{0, 20, 192}: "Symstream Technology Group Ltd", + [3]byte{0, 20, 193}: "U.S. Robotics Corporation", + [3]byte{0, 20, 194}: "Hewlett-Packard Company", + [3]byte{0, 20, 195}: "Seagate Technology", + [3]byte{0, 20, 196}: "Vitelcom Mobile Technology", + [3]byte{0, 20, 197}: "Alive Technologies Pty Ltd", + [3]byte{0, 20, 198}: "Quixant Ltd", + [3]byte{0, 20, 199}: "Nortel", + [3]byte{0, 20, 200}: "Contemporary Research Corp", + [3]byte{0, 20, 201}: "Brocade Communications Systems, Inc.", + [3]byte{0, 20, 202}: "Key Radio Systems Limited", + [3]byte{0, 20, 203}: "LifeSync Corporation", + [3]byte{0, 20, 204}: "Zetec, Inc.", + [3]byte{0, 20, 205}: "DigitalZone Co., Ltd.", + [3]byte{0, 20, 206}: "NF CORPORATION", + [3]byte{0, 20, 207}: "INVISIO Communications", + [3]byte{0, 20, 208}: "BTI Systems Inc.", + [3]byte{0, 20, 209}: "TRENDnet", + [3]byte{0, 20, 210}: "Kyuden Technosystems Corporation", + [3]byte{0, 20, 211}: "SEPSA", + [3]byte{0, 20, 212}: "K Technology Corporation", + [3]byte{0, 20, 213}: "Datang Telecom Technology CO. , LCD,Optical Communication Br", + [3]byte{0, 20, 214}: "Jeongmin Electronics Co.,Ltd.", + [3]byte{0, 20, 215}: "Datastore Technology Corp", + [3]byte{0, 20, 216}: "bio-logic SA", + [3]byte{0, 20, 217}: "IP Fabrics, Inc.", + [3]byte{0, 20, 218}: "Huntleigh Healthcare", + [3]byte{0, 20, 219}: "Elma Trenew Electronic GmbH", + [3]byte{0, 20, 220}: "Communication System Design & Manufacturing (CSDM)", + [3]byte{0, 20, 221}: "Covergence Inc.", + [3]byte{0, 20, 222}: "Sage Instruments Inc.", + [3]byte{0, 20, 223}: "HI-P Tech Corporation", + [3]byte{0, 20, 224}: "LET'S Corporation", + [3]byte{0, 20, 225}: "Data Display AG", + [3]byte{0, 20, 226}: "datacom systems inc.", + [3]byte{0, 20, 227}: "mm-lab GmbH", + [3]byte{0, 20, 228}: "infinias, LLC", + [3]byte{0, 20, 229}: "Alticast", + [3]byte{0, 20, 230}: "AIM Infrarotmodule GmbH", + [3]byte{0, 20, 231}: "Stolinx,. Inc", + [3]byte{0, 20, 232}: "ARRIS Group, Inc.", + [3]byte{0, 20, 233}: "Nortech International", + [3]byte{0, 20, 234}: "S Digm Inc. (Safe Paradigm Inc.)", + [3]byte{0, 20, 235}: "AwarePoint Corporation", + [3]byte{0, 20, 236}: "Acro Telecom", + [3]byte{0, 20, 237}: "Airak, Inc.", + [3]byte{0, 20, 238}: "Western Digital Technologies, Inc.", + [3]byte{0, 20, 239}: "TZero Technologies, Inc.", + [3]byte{0, 20, 240}: "Business Security OL AB", + [3]byte{0, 20, 241}: "CISCO SYSTEMS, INC.", + [3]byte{0, 20, 242}: "CISCO SYSTEMS, INC.", + [3]byte{0, 20, 243}: "ViXS Systems Inc", + [3]byte{0, 20, 244}: "DekTec Digital Video B.V.", + [3]byte{0, 20, 245}: "OSI Security Devices", + [3]byte{0, 20, 246}: "Juniper Networks, Inc.", + [3]byte{0, 20, 247}: "CREVIS Co., LTD", + [3]byte{0, 20, 248}: "Scientific Atlanta", + [3]byte{0, 20, 249}: "Vantage Controls", + [3]byte{0, 20, 250}: "AsGa S.A.", + [3]byte{0, 20, 251}: "Technical Solutions Inc.", + [3]byte{0, 20, 252}: "Extandon, Inc.", + [3]byte{0, 20, 253}: "Thecus Technology Corp.", + [3]byte{0, 20, 254}: "Artech Electronics", + [3]byte{0, 20, 255}: "Precise Automation, Inc.", + [3]byte{0, 21, 0}: "Intel Corporate", + [3]byte{0, 21, 1}: "LexBox", + [3]byte{0, 21, 2}: "BETA tech", + [3]byte{0, 21, 3}: "PROFIcomms s.r.o.", + [3]byte{0, 21, 4}: "GAME PLUS CO., LTD.", + [3]byte{0, 21, 5}: "Actiontec Electronics, Inc", + [3]byte{0, 21, 6}: "Neo Photonics", + [3]byte{0, 21, 7}: "Renaissance Learning Inc", + [3]byte{0, 21, 8}: "Global Target Enterprise Inc", + [3]byte{0, 21, 9}: "Plus Technology Co., Ltd", + [3]byte{0, 21, 10}: "Sonoa Systems, Inc", + [3]byte{0, 21, 11}: "SAGE INFOTECH LTD.", + [3]byte{0, 21, 12}: "AVM GmbH", + [3]byte{0, 21, 13}: "Hoana Medical, Inc.", + [3]byte{0, 21, 14}: "OPENBRAIN TECHNOLOGIES CO., LTD.", + [3]byte{0, 21, 15}: "mingjong", + [3]byte{0, 21, 16}: "Techsphere Co., Ltd", + [3]byte{0, 21, 17}: "Data Center Systems", + [3]byte{0, 21, 18}: "Zurich University of Applied Sciences", + [3]byte{0, 21, 19}: "EFS sas", + [3]byte{0, 21, 20}: "Hu Zhou NAVA Networks&Electronics Ltd.", + [3]byte{0, 21, 21}: "Leipold+Co.GmbH", + [3]byte{0, 21, 22}: "URIEL SYSTEMS INC.", + [3]byte{0, 21, 23}: "Intel Corporate", + [3]byte{0, 21, 24}: "Shenzhen 10MOONS Technology Development CO.,Ltd", + [3]byte{0, 21, 25}: "StoreAge Networking Technologies", + [3]byte{0, 21, 26}: "Hunter Engineering Company", + [3]byte{0, 21, 27}: "Isilon Systems Inc.", + [3]byte{0, 21, 28}: "LENECO", + [3]byte{0, 21, 29}: "M2I CORPORATION", + [3]byte{0, 21, 30}: "Ethernet Powerlink Standardization Group (EPSG)", + [3]byte{0, 21, 31}: "Multivision Intelligent Surveillance (Hong Kong) Ltd", + [3]byte{0, 21, 32}: "Radiocrafts AS", + [3]byte{0, 21, 33}: "Horoquartz", + [3]byte{0, 21, 34}: "Dea Security", + [3]byte{0, 21, 35}: "Meteor Communications Corporation", + [3]byte{0, 21, 36}: "Numatics, Inc.", + [3]byte{0, 21, 37}: "Chamberlain Access Solutions", + [3]byte{0, 21, 38}: "Remote Technologies Inc", + [3]byte{0, 21, 39}: "Balboa Instruments", + [3]byte{0, 21, 40}: "Beacon Medical Products LLC d.b.a. BeaconMedaes", + [3]byte{0, 21, 41}: "N3 Corporation", + [3]byte{0, 21, 42}: "Nokia GmbH", + [3]byte{0, 21, 43}: "CISCO SYSTEMS, INC.", + [3]byte{0, 21, 44}: "CISCO SYSTEMS, INC.", + [3]byte{0, 21, 45}: "TenX Networks, LLC", + [3]byte{0, 21, 46}: "PacketHop, Inc.", + [3]byte{0, 21, 47}: "ARRIS Group, Inc.", + [3]byte{0, 21, 48}: "EMC Corporation", + [3]byte{0, 21, 49}: "KOCOM", + [3]byte{0, 21, 50}: "Consumer Technologies Group, LLC", + [3]byte{0, 21, 51}: "NADAM.CO.,LTD", + [3]byte{0, 21, 52}: "A Beltrónica-Companhia de Comunicações, Lda", + [3]byte{0, 21, 53}: "OTE Spa", + [3]byte{0, 21, 54}: "Powertech co.,Ltd", + [3]byte{0, 21, 55}: "Ventus Networks", + [3]byte{0, 21, 56}: "RFID, Inc.", + [3]byte{0, 21, 57}: "Technodrive SRL", + [3]byte{0, 21, 58}: "Shenzhen Syscan Technology Co.,Ltd.", + [3]byte{0, 21, 59}: "EMH metering GmbH & Co. KG", + [3]byte{0, 21, 60}: "Kprotech Co., Ltd.", + [3]byte{0, 21, 61}: "ELIM PRODUCT CO.", + [3]byte{0, 21, 62}: "Q-Matic Sweden AB", + [3]byte{0, 21, 63}: "Alcatel Alenia Space Italia", + [3]byte{0, 21, 64}: "Nortel", + [3]byte{0, 21, 65}: "StrataLight Communications, Inc.", + [3]byte{0, 21, 66}: "MICROHARD S.R.L.", + [3]byte{0, 21, 67}: "Aberdeen Test Center", + [3]byte{0, 21, 68}: "coM.s.a.t. AG", + [3]byte{0, 21, 69}: "SEECODE Co., Ltd.", + [3]byte{0, 21, 70}: "ITG Worldwide Sdn Bhd", + [3]byte{0, 21, 71}: "AiZen Solutions Inc.", + [3]byte{0, 21, 72}: "CUBE TECHNOLOGIES", + [3]byte{0, 21, 73}: "Dixtal Biomedica Ind. Com. Ltda", + [3]byte{0, 21, 74}: "WANSHIH ELECTRONIC CO., LTD", + [3]byte{0, 21, 75}: "Wonde Proud Technology Co., Ltd", + [3]byte{0, 21, 76}: "Saunders Electronics", + [3]byte{0, 21, 77}: "Netronome Systems, Inc.", + [3]byte{0, 21, 78}: "IEC", + [3]byte{0, 21, 79}: "one RF Technology", + [3]byte{0, 21, 80}: "Nits Technology Inc", + [3]byte{0, 21, 81}: "RadioPulse Inc.", + [3]byte{0, 21, 82}: "Wi-Gear Inc.", + [3]byte{0, 21, 83}: "Cytyc Corporation", + [3]byte{0, 21, 84}: "Atalum Wireless S.A.", + [3]byte{0, 21, 85}: "DFM GmbH", + [3]byte{0, 21, 86}: "SAGEM COMMUNICATION", + [3]byte{0, 21, 87}: "Olivetti", + [3]byte{0, 21, 88}: "FOXCONN", + [3]byte{0, 21, 89}: "Securaplane Technologies, Inc.", + [3]byte{0, 21, 90}: "DAINIPPON PHARMACEUTICAL CO., LTD.", + [3]byte{0, 21, 91}: "Sampo Corporation", + [3]byte{0, 21, 92}: "Dresser Wayne", + [3]byte{0, 21, 93}: "Microsoft Corporation", + [3]byte{0, 21, 94}: "Morgan Stanley", + [3]byte{0, 21, 95}: "GreenPeak Technologies", + [3]byte{0, 21, 96}: "Hewlett-Packard Company", + [3]byte{0, 21, 97}: "JJPlus Corporation", + [3]byte{0, 21, 98}: "CISCO SYSTEMS, INC.", + [3]byte{0, 21, 99}: "CISCO SYSTEMS, INC.", + [3]byte{0, 21, 100}: "BEHRINGER Spezielle Studiotechnik GmbH", + [3]byte{0, 21, 101}: "XIAMEN YEALINK NETWORK TECHNOLOGY CO.,LTD", + [3]byte{0, 21, 102}: "A-First Technology Co., Ltd.", + [3]byte{0, 21, 103}: "RADWIN Inc.", + [3]byte{0, 21, 104}: "Dilithium Networks", + [3]byte{0, 21, 105}: "PECO II, Inc.", + [3]byte{0, 21, 106}: "DG2L Technologies Pvt. Ltd.", + [3]byte{0, 21, 107}: "Perfisans Networks Corp.", + [3]byte{0, 21, 108}: "SANE SYSTEM CO., LTD", + [3]byte{0, 21, 109}: "Ubiquiti Networks Inc.", + [3]byte{0, 21, 110}: "A. W. Communication Systems Ltd", + [3]byte{0, 21, 111}: "Xiranet Communications GmbH", + [3]byte{0, 21, 112}: "Symbol TechnologiesWholly owned Subsidiary of Motorola", + [3]byte{0, 21, 113}: "Nolan Systems", + [3]byte{0, 21, 114}: "Red-Lemon", + [3]byte{0, 21, 115}: "NewSoft Technology Corporation", + [3]byte{0, 21, 116}: "Horizon Semiconductors Ltd.", + [3]byte{0, 21, 117}: "Nevis Networks Inc.", + [3]byte{0, 21, 118}: "LABiTec - Labor Biomedical Technologies GmbH", + [3]byte{0, 21, 119}: "Allied Telesis", + [3]byte{0, 21, 120}: "Audio / Video Innovations", + [3]byte{0, 21, 121}: "Lunatone Industrielle Elektronik GmbH", + [3]byte{0, 21, 122}: "Telefin S.p.A.", + [3]byte{0, 21, 123}: "Leuze electronic GmbH + Co. KG", + [3]byte{0, 21, 124}: "Dave Networks, Inc.", + [3]byte{0, 21, 125}: "POSDATA CO., LTD.", + [3]byte{0, 21, 126}: "Weidmüller Interface GmbH & Co. KG", + [3]byte{0, 21, 127}: "ChuanG International Holding CO.,LTD.", + [3]byte{0, 21, 128}: "U-WAY CORPORATION", + [3]byte{0, 21, 129}: "MAKUS Inc.", + [3]byte{0, 21, 130}: "Pulse Eight Limited", + [3]byte{0, 21, 131}: "IVT corporation", + [3]byte{0, 21, 132}: "Schenck Process GmbH", + [3]byte{0, 21, 133}: "Aonvision Technolopy Corp.", + [3]byte{0, 21, 134}: "Xiamen Overseas Chinese Electronic Co., Ltd.", + [3]byte{0, 21, 135}: "Takenaka Seisakusho Co.,Ltd", + [3]byte{0, 21, 136}: "Salutica Allied Solutions Sdn Bhd", + [3]byte{0, 21, 137}: "D-MAX Technology Co.,Ltd", + [3]byte{0, 21, 138}: "SURECOM Technology Corp.", + [3]byte{0, 21, 139}: "Park Air Systems Ltd", + [3]byte{0, 21, 140}: "Liab ApS", + [3]byte{0, 21, 141}: "Jennic Ltd", + [3]byte{0, 21, 142}: "Plustek.INC", + [3]byte{0, 21, 143}: "NTT Advanced Technology Corporation", + [3]byte{0, 21, 144}: "Hectronic GmbH", + [3]byte{0, 21, 145}: "RLW Inc.", + [3]byte{0, 21, 146}: "Facom UK Ltd (Melksham)", + [3]byte{0, 21, 147}: "U4EA Technologies Inc.", + [3]byte{0, 21, 148}: "BIXOLON CO.,LTD", + [3]byte{0, 21, 149}: "Quester Tangent Corporation", + [3]byte{0, 21, 150}: "ARRIS International", + [3]byte{0, 21, 151}: "AETA AUDIO SYSTEMS", + [3]byte{0, 21, 152}: "Kolektor group", + [3]byte{0, 21, 153}: "Samsung Electronics Co., LTD", + [3]byte{0, 21, 154}: "ARRIS Group, Inc.", + [3]byte{0, 21, 155}: "Nortel", + [3]byte{0, 21, 156}: "B-KYUNG SYSTEM Co.,Ltd.", + [3]byte{0, 21, 157}: "Tripp Lite", + [3]byte{0, 21, 158}: "Mad Catz Interactive Inc", + [3]byte{0, 21, 159}: "Terascala, Inc.", + [3]byte{0, 21, 160}: "Nokia Danmark A/S", + [3]byte{0, 21, 161}: "ECA-SINTERS", + [3]byte{0, 21, 162}: "ARRIS International", + [3]byte{0, 21, 163}: "ARRIS International", + [3]byte{0, 21, 164}: "ARRIS International", + [3]byte{0, 21, 165}: "DCI Co., Ltd.", + [3]byte{0, 21, 166}: "Digital Electronics Products Ltd.", + [3]byte{0, 21, 167}: "Robatech AG", + [3]byte{0, 21, 168}: "ARRIS Group, Inc.", + [3]byte{0, 21, 169}: "KWANG WOO I&C CO.,LTD", + [3]byte{0, 21, 170}: "Rextechnik International Co.,", + [3]byte{0, 21, 171}: "PRO CO SOUND INC", + [3]byte{0, 21, 172}: "Capelon AB", + [3]byte{0, 21, 173}: "Accedian Networks", + [3]byte{0, 21, 174}: "kyung il", + [3]byte{0, 21, 175}: "AzureWave Technologies, Inc.", + [3]byte{0, 21, 176}: "AUTOTELENET CO.,LTD", + [3]byte{0, 21, 177}: "Ambient Corporation", + [3]byte{0, 21, 178}: "Advanced Industrial Computer, Inc.", + [3]byte{0, 21, 179}: "Caretech AB", + [3]byte{0, 21, 180}: "Polymap Wireless LLC", + [3]byte{0, 21, 181}: "CI Network Corp.", + [3]byte{0, 21, 182}: "ShinMaywa Industries, Ltd.", + [3]byte{0, 21, 183}: "Toshiba", + [3]byte{0, 21, 184}: "Tahoe", + [3]byte{0, 21, 185}: "Samsung Electronics Co., Ltd.", + [3]byte{0, 21, 186}: "iba AG", + [3]byte{0, 21, 187}: "SMA Solar Technology AG", + [3]byte{0, 21, 188}: "Develco", + [3]byte{0, 21, 189}: "Group 4 Technology Ltd", + [3]byte{0, 21, 190}: "Iqua Ltd.", + [3]byte{0, 21, 191}: "technicob", + [3]byte{0, 21, 192}: "DIGITAL TELEMEDIA CO.,LTD.", + [3]byte{0, 21, 193}: "SONY Computer Entertainment inc,", + [3]byte{0, 21, 194}: "3M Germany", + [3]byte{0, 21, 195}: "Ruf Telematik AG", + [3]byte{0, 21, 196}: "FLOVEL CO., LTD.", + [3]byte{0, 21, 197}: "Dell Inc", + [3]byte{0, 21, 198}: "CISCO SYSTEMS, INC.", + [3]byte{0, 21, 199}: "CISCO SYSTEMS, INC.", + [3]byte{0, 21, 200}: "FlexiPanel Ltd", + [3]byte{0, 21, 201}: "Gumstix, Inc", + [3]byte{0, 21, 202}: "TeraRecon, Inc.", + [3]byte{0, 21, 203}: "Surf Communication Solutions Ltd.", + [3]byte{0, 21, 204}: "UQUEST, LTD.", + [3]byte{0, 21, 205}: "Exartech International Corp.", + [3]byte{0, 21, 206}: "ARRIS International", + [3]byte{0, 21, 207}: "ARRIS International", + [3]byte{0, 21, 208}: "ARRIS International", + [3]byte{0, 21, 209}: "ARRIS Group, Inc.", + [3]byte{0, 21, 210}: "Xantech Corporation", + [3]byte{0, 21, 211}: "Pantech&Curitel Communications, Inc.", + [3]byte{0, 21, 212}: "Emitor AB", + [3]byte{0, 21, 213}: "NICEVT", + [3]byte{0, 21, 214}: "OSLiNK Sp. z o.o.", + [3]byte{0, 21, 215}: "Reti Corporation", + [3]byte{0, 21, 216}: "Interlink Electronics", + [3]byte{0, 21, 217}: "PKC Electronics Oy", + [3]byte{0, 21, 218}: "IRITEL A.D.", + [3]byte{0, 21, 219}: "Canesta Inc.", + [3]byte{0, 21, 220}: "KT&C Co., Ltd.", + [3]byte{0, 21, 221}: "IP Control Systems Ltd.", + [3]byte{0, 21, 222}: "Nokia Danmark A/S", + [3]byte{0, 21, 223}: "Clivet S.p.A.", + [3]byte{0, 21, 224}: "Ericsson", + [3]byte{0, 21, 225}: "Picochip Ltd", + [3]byte{0, 21, 226}: "Dr.Ing. Herbert Knauer GmbH", + [3]byte{0, 21, 227}: "Dream Technologies Corporation", + [3]byte{0, 21, 228}: "Zimmer Elektromedizin", + [3]byte{0, 21, 229}: "Cheertek Inc.", + [3]byte{0, 21, 230}: "MOBILE TECHNIKA Inc.", + [3]byte{0, 21, 231}: "Quantec Tontechnik", + [3]byte{0, 21, 232}: "Nortel", + [3]byte{0, 21, 233}: "D-Link Corporation", + [3]byte{0, 21, 234}: "Tellumat (Pty) Ltd", + [3]byte{0, 21, 235}: "ZTE CORPORATION", + [3]byte{0, 21, 236}: "Boca Devices LLC", + [3]byte{0, 21, 237}: "Fulcrum Microsystems, Inc.", + [3]byte{0, 21, 238}: "Omnex Control Systems", + [3]byte{0, 21, 239}: "NEC TOKIN Corporation", + [3]byte{0, 21, 240}: "EGO BV", + [3]byte{0, 21, 241}: "KYLINK Communications Corp.", + [3]byte{0, 21, 242}: "ASUSTek COMPUTER INC.", + [3]byte{0, 21, 243}: "PELTOR AB", + [3]byte{0, 21, 244}: "Eventide", + [3]byte{0, 21, 245}: "Sustainable Energy Systems", + [3]byte{0, 21, 246}: "SCIENCE AND ENGINEERING SERVICES, INC.", + [3]byte{0, 21, 247}: "Wintecronics Ltd.", + [3]byte{0, 21, 248}: "Kingtronics Industrial Co. Ltd.", + [3]byte{0, 21, 249}: "CISCO SYSTEMS, INC.", + [3]byte{0, 21, 250}: "CISCO SYSTEMS, INC.", + [3]byte{0, 21, 251}: "setex schermuly textile computer gmbh", + [3]byte{0, 21, 252}: "Littelfuse Startco", + [3]byte{0, 21, 253}: "Complete Media Systems", + [3]byte{0, 21, 254}: "SCHILLING ROBOTICS LLC", + [3]byte{0, 21, 255}: "Novatel Wireless, Inc.", + [3]byte{0, 22, 0}: "CelleBrite Mobile Synchronization", + [3]byte{0, 22, 1}: "Buffalo Inc.", + [3]byte{0, 22, 2}: "CEYON TECHNOLOGY CO.,LTD.", + [3]byte{0, 22, 3}: "COOLKSKY Co., LTD", + [3]byte{0, 22, 4}: "Sigpro", + [3]byte{0, 22, 5}: "YORKVILLE SOUND INC.", + [3]byte{0, 22, 6}: "Ideal Industries", + [3]byte{0, 22, 7}: "Curves International Inc.", + [3]byte{0, 22, 8}: "Sequans Communications", + [3]byte{0, 22, 9}: "Unitech electronics co., ltd.", + [3]byte{0, 22, 10}: "SWEEX Europe BV", + [3]byte{0, 22, 11}: "TVWorks LLC", + [3]byte{0, 22, 12}: "LPL DEVELOPMENT S.A. DE C.V", + [3]byte{0, 22, 13}: "Be Here Corporation", + [3]byte{0, 22, 14}: "Optica Technologies Inc.", + [3]byte{0, 22, 15}: "BADGER METER INC", + [3]byte{0, 22, 16}: "Carina Technology", + [3]byte{0, 22, 17}: "Altecon Srl", + [3]byte{0, 22, 18}: "Otsuka Electronics Co., Ltd.", + [3]byte{0, 22, 19}: "LibreStream Technologies Inc.", + [3]byte{0, 22, 20}: "Picosecond Pulse Labs", + [3]byte{0, 22, 21}: "Nittan Company, Limited", + [3]byte{0, 22, 22}: "BROWAN COMMUNICATION INC.", + [3]byte{0, 22, 23}: "MSI", + [3]byte{0, 22, 24}: "HIVION Co., Ltd.", + [3]byte{0, 22, 25}: "Lancelan Technologies S.L.", + [3]byte{0, 22, 26}: "Dametric AB", + [3]byte{0, 22, 27}: "Micronet Corporation", + [3]byte{0, 22, 28}: "e:cue", + [3]byte{0, 22, 29}: "Innovative Wireless Technologies, Inc.", + [3]byte{0, 22, 30}: "Woojinnet", + [3]byte{0, 22, 31}: "SUNWAVETEC Co., Ltd.", + [3]byte{0, 22, 32}: "Sony Ericsson Mobile Communications AB", + [3]byte{0, 22, 33}: "Colorado Vnet", + [3]byte{0, 22, 34}: "BBH SYSTEMS GMBH", + [3]byte{0, 22, 35}: "Interval Media", + [3]byte{0, 22, 36}: "Teneros, Inc.", + [3]byte{0, 22, 37}: "Impinj, Inc.", + [3]byte{0, 22, 38}: "ARRIS Group, Inc.", + [3]byte{0, 22, 39}: "embedded-logic DESIGN AND MORE GmbH", + [3]byte{0, 22, 40}: "Ultra Electronics Manufacturing and Card Systems", + [3]byte{0, 22, 41}: "Nivus GmbH", + [3]byte{0, 22, 42}: "Antik computers & communications s.r.o.", + [3]byte{0, 22, 43}: "Togami Electric Mfg.co.,Ltd.", + [3]byte{0, 22, 44}: "Xanboo", + [3]byte{0, 22, 45}: "STNet Co., Ltd.", + [3]byte{0, 22, 46}: "Space Shuttle Hi-Tech Co., Ltd.", + [3]byte{0, 22, 47}: "Geutebrück GmbH", + [3]byte{0, 22, 48}: "Vativ Technologies", + [3]byte{0, 22, 49}: "Xteam", + [3]byte{0, 22, 50}: "SAMSUNG ELECTRONICS CO., LTD.", + [3]byte{0, 22, 51}: "Oxford Diagnostics Ltd.", + [3]byte{0, 22, 52}: "Mathtech, Inc.", + [3]byte{0, 22, 53}: "Hewlett-Packard Company", + [3]byte{0, 22, 54}: "Quanta Computer Inc.", + [3]byte{0, 22, 55}: "CITEL SpA", + [3]byte{0, 22, 56}: "TECOM Co., Ltd.", + [3]byte{0, 22, 57}: "UBIQUAM Co.,Ltd", + [3]byte{0, 22, 58}: "YVES TECHNOLOGY CO., LTD.", + [3]byte{0, 22, 59}: "VertexRSI/General Dynamics", + [3]byte{0, 22, 60}: "Rebox B.V.", + [3]byte{0, 22, 61}: "Tsinghua Tongfang Legend Silicon Tech. Co., Ltd.", + [3]byte{0, 22, 62}: "Xensource, Inc.", + [3]byte{0, 22, 63}: "CReTE SYSTEMS Inc.", + [3]byte{0, 22, 64}: "Asmobile Communication Inc.", + [3]byte{0, 22, 65}: "Universal Global Scientific Industrial Co., Ltd.", + [3]byte{0, 22, 66}: "Pangolin", + [3]byte{0, 22, 67}: "Sunhillo Corporation", + [3]byte{0, 22, 68}: "LITE-ON Technology Corp.", + [3]byte{0, 22, 69}: "Power Distribution, Inc.", + [3]byte{0, 22, 70}: "CISCO SYSTEMS, INC.", + [3]byte{0, 22, 71}: "CISCO SYSTEMS, INC.", + [3]byte{0, 22, 72}: "SSD Company Limited", + [3]byte{0, 22, 73}: "SetOne GmbH", + [3]byte{0, 22, 74}: "Vibration Technology Limited", + [3]byte{0, 22, 75}: "Quorion Data Systems GmbH", + [3]byte{0, 22, 76}: "PLANET INT Co., Ltd", + [3]byte{0, 22, 77}: "Alcatel North America IP Division", + [3]byte{0, 22, 78}: "Nokia Danmark A/S", + [3]byte{0, 22, 79}: "World Ethnic Broadcastin Inc.", + [3]byte{0, 22, 80}: "Herley General Microwave Israel.", + [3]byte{0, 22, 81}: "Exeo Systems", + [3]byte{0, 22, 82}: "Hoatech Technologies, Inc.", + [3]byte{0, 22, 83}: "LEGO System A/S IE Electronics Division", + [3]byte{0, 22, 84}: "Flex-P Industries Sdn. Bhd.", + [3]byte{0, 22, 85}: "FUHO TECHNOLOGY Co., LTD", + [3]byte{0, 22, 86}: "Nintendo Co., Ltd.", + [3]byte{0, 22, 87}: "Aegate Ltd", + [3]byte{0, 22, 88}: "Fusiontech Technologies Inc.", + [3]byte{0, 22, 89}: "Z.M.P. RADWAG", + [3]byte{0, 22, 90}: "Harman Specialty Group", + [3]byte{0, 22, 91}: "Grip Audio", + [3]byte{0, 22, 92}: "Trackflow Ltd", + [3]byte{0, 22, 93}: "AirDefense, Inc.", + [3]byte{0, 22, 94}: "Precision I/O", + [3]byte{0, 22, 95}: "Fairmount Automation", + [3]byte{0, 22, 96}: "Nortel", + [3]byte{0, 22, 97}: "Novatium Solutions (P) Ltd", + [3]byte{0, 22, 98}: "Liyuh Technology Ltd.", + [3]byte{0, 22, 99}: "KBT Mobile", + [3]byte{0, 22, 100}: "Prod-El SpA", + [3]byte{0, 22, 101}: "Cellon France", + [3]byte{0, 22, 102}: "Quantier Communication Inc.", + [3]byte{0, 22, 103}: "A-TEC Subsystem INC.", + [3]byte{0, 22, 104}: "Eishin Electronics", + [3]byte{0, 22, 105}: "MRV Communication (Networks) LTD", + [3]byte{0, 22, 106}: "TPS", + [3]byte{0, 22, 107}: "Samsung Electronics", + [3]byte{0, 22, 108}: "Samsung Electonics Digital Video System Division", + [3]byte{0, 22, 109}: "Yulong Computer Telecommunication Scientific(shenzhen)Co.,Lt", + [3]byte{0, 22, 110}: "Arbitron Inc.", + [3]byte{0, 22, 111}: "Intel Corporate", + [3]byte{0, 22, 112}: "SKNET Corporation", + [3]byte{0, 22, 113}: "Symphox Information Co.", + [3]byte{0, 22, 114}: "Zenway enterprise ltd", + [3]byte{0, 22, 115}: "Bury GmbH & Co. KG", + [3]byte{0, 22, 116}: "EuroCB (Phils.), Inc.", + [3]byte{0, 22, 117}: "ARRIS Group, Inc.", + [3]byte{0, 22, 118}: "Intel Corporate", + [3]byte{0, 22, 119}: "Bihl + Wiedemann GmbH", + [3]byte{0, 22, 120}: "SHENZHEN BAOAN GAOKE ELECTRONICS CO., LTD", + [3]byte{0, 22, 121}: "eOn Communications", + [3]byte{0, 22, 122}: "Skyworth Overseas Dvelopment Ltd.", + [3]byte{0, 22, 123}: "Haver&Boecker", + [3]byte{0, 22, 124}: "iRex Technologies BV", + [3]byte{0, 22, 125}: "Sky-Line Information Co., Ltd.", + [3]byte{0, 22, 126}: "DIBOSS.CO.,LTD", + [3]byte{0, 22, 127}: "Bluebird Soft Inc.", + [3]byte{0, 22, 128}: "Bally Gaming + Systems", + [3]byte{0, 22, 129}: "Vector Informatik GmbH", + [3]byte{0, 22, 130}: "Pro Dex, Inc", + [3]byte{0, 22, 131}: "WEBIO International Co.,.Ltd.", + [3]byte{0, 22, 132}: "Donjin Co.,Ltd.", + [3]byte{0, 22, 133}: "Elisa Oyj", + [3]byte{0, 22, 134}: "Karl Storz Imaging", + [3]byte{0, 22, 135}: "Chubb CSC-Vendor AP", + [3]byte{0, 22, 136}: "ServerEngines LLC", + [3]byte{0, 22, 137}: "Pilkor Electronics Co., Ltd", + [3]byte{0, 22, 138}: "id-Confirm Inc", + [3]byte{0, 22, 139}: "Paralan Corporation", + [3]byte{0, 22, 140}: "DSL Partner AS", + [3]byte{0, 22, 141}: "KORWIN CO., Ltd.", + [3]byte{0, 22, 142}: "Vimicro corporation", + [3]byte{0, 22, 143}: "GN Netcom as", + [3]byte{0, 22, 144}: "J-TEK INCORPORATION", + [3]byte{0, 22, 145}: "Moser-Baer AG", + [3]byte{0, 22, 146}: "Scientific-Atlanta, Inc.", + [3]byte{0, 22, 147}: "PowerLink Technology Inc.", + [3]byte{0, 22, 148}: "Sennheiser Communications A/S", + [3]byte{0, 22, 149}: "AVC Technology (International) Limited", + [3]byte{0, 22, 150}: "QDI Technology (H.K.) Limited", + [3]byte{0, 22, 151}: "NEC Corporation", + [3]byte{0, 22, 152}: "T&A Mobile Phones", + [3]byte{0, 22, 153}: "Tonic DVB Marketing Ltd", + [3]byte{0, 22, 154}: "Quadrics Ltd", + [3]byte{0, 22, 155}: "Alstom Transport", + [3]byte{0, 22, 156}: "CISCO SYSTEMS, INC.", + [3]byte{0, 22, 157}: "CISCO SYSTEMS, INC.", + [3]byte{0, 22, 158}: "TV One Ltd", + [3]byte{0, 22, 159}: "Vimtron Electronics Co., Ltd.", + [3]byte{0, 22, 160}: "Auto-Maskin", + [3]byte{0, 22, 161}: "3Leaf Networks", + [3]byte{0, 22, 162}: "CentraLite Systems, Inc.", + [3]byte{0, 22, 163}: "Ingeteam Transmission&Distribution, S.A.", + [3]byte{0, 22, 164}: "Ezurio Ltd", + [3]byte{0, 22, 165}: "Tandberg Storage ASA", + [3]byte{0, 22, 166}: "Dovado FZ-LLC", + [3]byte{0, 22, 167}: "AWETA G&P", + [3]byte{0, 22, 168}: "CWT CO., LTD.", + [3]byte{0, 22, 169}: "2EI", + [3]byte{0, 22, 170}: "Kei Communication Technology Inc.", + [3]byte{0, 22, 171}: "Dansensor A/S", + [3]byte{0, 22, 172}: "Toho Technology Corp.", + [3]byte{0, 22, 173}: "BT-Links Company Limited", + [3]byte{0, 22, 174}: "INVENTEL", + [3]byte{0, 22, 175}: "Shenzhen Union Networks Equipment Co.,Ltd.", + [3]byte{0, 22, 176}: "VK Corporation", + [3]byte{0, 22, 177}: "KBS", + [3]byte{0, 22, 178}: "DriveCam Inc", + [3]byte{0, 22, 179}: "Photonicbridges (China) Co., Ltd.", + [3]byte{0, 22, 180}: "PRIVATE", + [3]byte{0, 22, 181}: "ARRIS Group, Inc.", + [3]byte{0, 22, 182}: "Cisco-Linksys", + [3]byte{0, 22, 183}: "Seoul Commtech", + [3]byte{0, 22, 184}: "Sony Ericsson Mobile Communications", + [3]byte{0, 22, 185}: "ProCurve Networking", + [3]byte{0, 22, 186}: "WEATHERNEWS INC.", + [3]byte{0, 22, 187}: "Law-Chain Computer Technology Co Ltd", + [3]byte{0, 22, 188}: "Nokia Danmark A/S", + [3]byte{0, 22, 189}: "ATI Industrial Automation", + [3]byte{0, 22, 190}: "INFRANET, Inc.", + [3]byte{0, 22, 191}: "PaloDEx Group Oy", + [3]byte{0, 22, 192}: "Semtech Corporation", + [3]byte{0, 22, 193}: "Eleksen Ltd", + [3]byte{0, 22, 194}: "Avtec Systems Inc", + [3]byte{0, 22, 195}: "BA Systems Inc", + [3]byte{0, 22, 196}: "SiRF Technology, Inc.", + [3]byte{0, 22, 197}: "Shenzhen Xing Feng Industry Co.,Ltd", + [3]byte{0, 22, 198}: "North Atlantic Industries", + [3]byte{0, 22, 199}: "CISCO SYSTEMS, INC.", + [3]byte{0, 22, 200}: "CISCO SYSTEMS, INC.", + [3]byte{0, 22, 201}: "NAT Seattle, Inc.", + [3]byte{0, 22, 202}: "Nortel", + [3]byte{0, 22, 203}: "Apple", + [3]byte{0, 22, 204}: "Xcute Mobile Corp.", + [3]byte{0, 22, 205}: "HIJI HIGH-TECH CO., LTD.", + [3]byte{0, 22, 206}: "Hon Hai Precision Ind. Co., Ltd.", + [3]byte{0, 22, 207}: "Hon Hai Precision Ind. Co., Ltd.", + [3]byte{0, 22, 208}: "ATech elektronika d.o.o.", + [3]byte{0, 22, 209}: "ZAT a.s.", + [3]byte{0, 22, 210}: "Caspian", + [3]byte{0, 22, 211}: "Wistron Corporation", + [3]byte{0, 22, 212}: "Compal Communications, Inc.", + [3]byte{0, 22, 213}: "Synccom Co., Ltd", + [3]byte{0, 22, 214}: "TDA Tech Pty Ltd", + [3]byte{0, 22, 215}: "Sunways AG", + [3]byte{0, 22, 216}: "Senea AB", + [3]byte{0, 22, 217}: "NINGBO BIRD CO.,LTD.", + [3]byte{0, 22, 218}: "Futronic Technology Co. Ltd.", + [3]byte{0, 22, 219}: "Samsung Electronics Co., Ltd.", + [3]byte{0, 22, 220}: "ARCHOS", + [3]byte{0, 22, 221}: "Gigabeam Corporation", + [3]byte{0, 22, 222}: "FAST Inc", + [3]byte{0, 22, 223}: "Lundinova AB", + [3]byte{0, 22, 224}: "3Com Ltd", + [3]byte{0, 22, 225}: "SiliconStor, Inc.", + [3]byte{0, 22, 226}: "American Fibertek, Inc.", + [3]byte{0, 22, 227}: "ASKEY COMPUTER CORP.", + [3]byte{0, 22, 228}: "VANGUARD SECURITY ENGINEERING CORP.", + [3]byte{0, 22, 229}: "FORDLEY DEVELOPMENT LIMITED", + [3]byte{0, 22, 230}: "GIGA-BYTE TECHNOLOGY CO.,LTD.", + [3]byte{0, 22, 231}: "Dynamix Promotions Limited", + [3]byte{0, 22, 232}: "Sigma Designs, Inc.", + [3]byte{0, 22, 233}: "Tiba Medical Inc", + [3]byte{0, 22, 234}: "Intel Corporate", + [3]byte{0, 22, 235}: "Intel Corporate", + [3]byte{0, 22, 236}: "Elitegroup Computer Systems Co., Ltd.", + [3]byte{0, 22, 237}: "Digital Safety Technologies, Inc", + [3]byte{0, 22, 238}: "RoyalDigital Inc.", + [3]byte{0, 22, 239}: "Koko Fitness, Inc.", + [3]byte{0, 22, 240}: "Dell", + [3]byte{0, 22, 241}: "OmniSense, LLC", + [3]byte{0, 22, 242}: "Dmobile System Co., Ltd.", + [3]byte{0, 22, 243}: "CAST Information Co., Ltd", + [3]byte{0, 22, 244}: "Eidicom Co., Ltd.", + [3]byte{0, 22, 245}: "Dalian Golden Hualu Digital Technology Co.,Ltd", + [3]byte{0, 22, 246}: "Video Products Group", + [3]byte{0, 22, 247}: "L-3 Communications, Aviation Recorders", + [3]byte{0, 22, 248}: "AVIQTECH TECHNOLOGY CO., LTD.", + [3]byte{0, 22, 249}: "CETRTA POT, d.o.o., Kranj", + [3]byte{0, 22, 250}: "ECI Telecom Ltd.", + [3]byte{0, 22, 251}: "SHENZHEN MTC CO.,LTD.", + [3]byte{0, 22, 252}: "TOHKEN CO.,LTD.", + [3]byte{0, 22, 253}: "Jaty Electronics", + [3]byte{0, 22, 254}: "Alps Electric Co., Ltd", + [3]byte{0, 22, 255}: "Wamin Optocomm Mfg Corp", + [3]byte{0, 23, 0}: "ARRIS Group, Inc.", + [3]byte{0, 23, 1}: "KDE, Inc.", + [3]byte{0, 23, 2}: "Osung Midicom Co., Ltd", + [3]byte{0, 23, 3}: "MOSDAN Internation Co.,Ltd", + [3]byte{0, 23, 4}: "Shinco Electronics Group Co.,Ltd", + [3]byte{0, 23, 5}: "Methode Electronics", + [3]byte{0, 23, 6}: "Techfaith Wireless Communication Technology Limited.", + [3]byte{0, 23, 7}: "InGrid, Inc", + [3]byte{0, 23, 8}: "Hewlett-Packard Company", + [3]byte{0, 23, 9}: "Exalt Communications", + [3]byte{0, 23, 10}: "INEW DIGITAL COMPANY", + [3]byte{0, 23, 11}: "Contela, Inc.", + [3]byte{0, 23, 12}: "Twig Com Ltd.", + [3]byte{0, 23, 13}: "Dust Networks Inc.", + [3]byte{0, 23, 14}: "CISCO SYSTEMS, INC.", + [3]byte{0, 23, 15}: "CISCO SYSTEMS, INC.", + [3]byte{0, 23, 16}: "Casa Systems Inc.", + [3]byte{0, 23, 17}: "GE Healthcare Bio-Sciences AB", + [3]byte{0, 23, 18}: "ISCO International", + [3]byte{0, 23, 19}: "Tiger NetCom", + [3]byte{0, 23, 20}: "BR Controls Nederland bv", + [3]byte{0, 23, 21}: "Qstik", + [3]byte{0, 23, 22}: "Qno Technology Inc.", + [3]byte{0, 23, 23}: "Leica Geosystems AG", + [3]byte{0, 23, 24}: "Vansco Electronics Oy", + [3]byte{0, 23, 25}: "AudioCodes USA, Inc", + [3]byte{0, 23, 26}: "Winegard Company", + [3]byte{0, 23, 27}: "Innovation Lab Corp.", + [3]byte{0, 23, 28}: "NT MicroSystems, Inc.", + [3]byte{0, 23, 29}: "DIGIT", + [3]byte{0, 23, 30}: "Theo Benning GmbH & Co. KG", + [3]byte{0, 23, 31}: "IMV Corporation", + [3]byte{0, 23, 32}: "Image Sensing Systems, Inc.", + [3]byte{0, 23, 33}: "FITRE S.p.A.", + [3]byte{0, 23, 34}: "Hanazeder Electronic GmbH", + [3]byte{0, 23, 35}: "Summit Data Communications", + [3]byte{0, 23, 36}: "Studer Professional Audio GmbH", + [3]byte{0, 23, 37}: "Liquid Computing", + [3]byte{0, 23, 38}: "m2c Electronic Technology Ltd.", + [3]byte{0, 23, 39}: "Thermo Ramsey Italia s.r.l.", + [3]byte{0, 23, 40}: "Selex Communications", + [3]byte{0, 23, 41}: "Ubicod Co.LTD", + [3]byte{0, 23, 42}: "Proware Technology Corp.(By Unifosa)", + [3]byte{0, 23, 43}: "Global Technologies Inc.", + [3]byte{0, 23, 44}: "TAEJIN INFOTECH", + [3]byte{0, 23, 45}: "Axcen Photonics Corporation", + [3]byte{0, 23, 46}: "FXC Inc.", + [3]byte{0, 23, 47}: "NeuLion Incorporated", + [3]byte{0, 23, 48}: "Automation Electronics", + [3]byte{0, 23, 49}: "ASUSTek COMPUTER INC.", + [3]byte{0, 23, 50}: "Science-Technical Center \"RISSA\"", + [3]byte{0, 23, 51}: "SFR", + [3]byte{0, 23, 52}: "ADC Telecommunications", + [3]byte{0, 23, 53}: "PRIVATE", + [3]byte{0, 23, 54}: "iiTron Inc.", + [3]byte{0, 23, 55}: "Industrie Dial Face S.p.A.", + [3]byte{0, 23, 56}: "International Business Machines", + [3]byte{0, 23, 57}: "Bright Headphone Electronics Company", + [3]byte{0, 23, 58}: "Reach Systems Inc.", + [3]byte{0, 23, 59}: "Cisco Systems, Inc.", + [3]byte{0, 23, 60}: "Extreme Engineering Solutions", + [3]byte{0, 23, 61}: "Neology", + [3]byte{0, 23, 62}: "LeucotronEquipamentos Ltda.", + [3]byte{0, 23, 63}: "Belkin Corporation", + [3]byte{0, 23, 64}: "Bluberi Gaming Technologies Inc", + [3]byte{0, 23, 65}: "DEFIDEV", + [3]byte{0, 23, 66}: "FUJITSU LIMITED", + [3]byte{0, 23, 67}: "Deck Srl", + [3]byte{0, 23, 68}: "Araneo Ltd.", + [3]byte{0, 23, 69}: "INNOTZ CO., Ltd", + [3]byte{0, 23, 70}: "Freedom9 Inc.", + [3]byte{0, 23, 71}: "Trimble", + [3]byte{0, 23, 72}: "Neokoros Brasil Ltda", + [3]byte{0, 23, 73}: "HYUNDAE YONG-O-SA CO.,LTD", + [3]byte{0, 23, 74}: "SOCOMEC", + [3]byte{0, 23, 75}: "Nokia Danmark A/S", + [3]byte{0, 23, 76}: "Millipore", + [3]byte{0, 23, 77}: "DYNAMIC NETWORK FACTORY, INC.", + [3]byte{0, 23, 78}: "Parama-tech Co.,Ltd.", + [3]byte{0, 23, 79}: "iCatch Inc.", + [3]byte{0, 23, 80}: "GSI Group, MicroE Systems", + [3]byte{0, 23, 81}: "Online Corporation", + [3]byte{0, 23, 82}: "DAGS, Inc", + [3]byte{0, 23, 83}: "nFore Technology Inc.", + [3]byte{0, 23, 84}: "Arkino HiTOP Corporation Limited", + [3]byte{0, 23, 85}: "GE Security", + [3]byte{0, 23, 86}: "Vinci Labs Oy", + [3]byte{0, 23, 87}: "RIX TECHNOLOGY LIMITED", + [3]byte{0, 23, 88}: "ThruVision Ltd", + [3]byte{0, 23, 89}: "CISCO SYSTEMS, INC.", + [3]byte{0, 23, 90}: "CISCO SYSTEMS, INC.", + [3]byte{0, 23, 91}: "ACS Solutions Switzerland Ltd.", + [3]byte{0, 23, 92}: "SHARP CORPORATION", + [3]byte{0, 23, 93}: "Dongseo system.", + [3]byte{0, 23, 94}: "Zed-3", + [3]byte{0, 23, 95}: "XENOLINK Communications Co., Ltd.", + [3]byte{0, 23, 96}: "Naito Densei Machida MFG.CO.,LTD", + [3]byte{0, 23, 97}: "PRIVATE", + [3]byte{0, 23, 98}: "Solar Technology, Inc.", + [3]byte{0, 23, 99}: "Essentia S.p.A.", + [3]byte{0, 23, 100}: "ATMedia GmbH", + [3]byte{0, 23, 101}: "Nortel", + [3]byte{0, 23, 102}: "Accense Technology, Inc.", + [3]byte{0, 23, 103}: "Earforce AS", + [3]byte{0, 23, 104}: "Zinwave Ltd", + [3]byte{0, 23, 105}: "Cymphonix Corp", + [3]byte{0, 23, 106}: "Avago Technologies", + [3]byte{0, 23, 107}: "Kiyon, Inc.", + [3]byte{0, 23, 108}: "Pivot3, Inc.", + [3]byte{0, 23, 109}: "CORE CORPORATION", + [3]byte{0, 23, 110}: "DUCATI SISTEMI", + [3]byte{0, 23, 111}: "PAX Computer Technology(Shenzhen) Ltd.", + [3]byte{0, 23, 112}: "Arti Industrial Electronics Ltd.", + [3]byte{0, 23, 113}: "APD Communications Ltd", + [3]byte{0, 23, 114}: "ASTRO Strobel Kommunikationssysteme GmbH", + [3]byte{0, 23, 115}: "Laketune Technologies Co. Ltd", + [3]byte{0, 23, 116}: "Elesta GmbH", + [3]byte{0, 23, 117}: "TTE Germany GmbH", + [3]byte{0, 23, 118}: "Meso Scale Diagnostics, LLC", + [3]byte{0, 23, 119}: "Obsidian Research Corporation", + [3]byte{0, 23, 120}: "Central Music Co.", + [3]byte{0, 23, 121}: "QuickTel", + [3]byte{0, 23, 122}: "ASSA ABLOY AB", + [3]byte{0, 23, 123}: "Azalea Networks inc", + [3]byte{0, 23, 124}: "Smartlink Network Systems Limited", + [3]byte{0, 23, 125}: "IDT International Limited", + [3]byte{0, 23, 126}: "Meshcom Technologies Inc.", + [3]byte{0, 23, 127}: "Worldsmart Retech", + [3]byte{0, 23, 128}: "Applied Biosystems B.V.", + [3]byte{0, 23, 129}: "Greystone Data System, Inc.", + [3]byte{0, 23, 130}: "LoBenn Inc.", + [3]byte{0, 23, 131}: "Texas Instruments", + [3]byte{0, 23, 132}: "ARRIS Group, Inc.", + [3]byte{0, 23, 133}: "Sparr Electronics Ltd", + [3]byte{0, 23, 134}: "wisembed", + [3]byte{0, 23, 135}: "Brother, Brother & Sons ApS", + [3]byte{0, 23, 136}: "Philips Lighting BV", + [3]byte{0, 23, 137}: "Zenitron Corporation", + [3]byte{0, 23, 138}: "DARTS TECHNOLOGIES CORP.", + [3]byte{0, 23, 139}: "Teledyne Technologies Incorporated", + [3]byte{0, 23, 140}: "Independent Witness, Inc", + [3]byte{0, 23, 141}: "Checkpoint Systems, Inc.", + [3]byte{0, 23, 142}: "Gunnebo Cash Automation AB", + [3]byte{0, 23, 143}: "NINGBO YIDONG ELECTRONIC CO.,LTD.", + [3]byte{0, 23, 144}: "HYUNDAI DIGITECH Co, Ltd.", + [3]byte{0, 23, 145}: "LinTech GmbH", + [3]byte{0, 23, 146}: "Falcom Wireless Comunications Gmbh", + [3]byte{0, 23, 147}: "Tigi Corporation", + [3]byte{0, 23, 148}: "CISCO SYSTEMS, INC.", + [3]byte{0, 23, 149}: "CISCO SYSTEMS, INC.", + [3]byte{0, 23, 150}: "Rittmeyer AG", + [3]byte{0, 23, 151}: "Telsy Elettronica S.p.A.", + [3]byte{0, 23, 152}: "Azonic Technology Co., LTD", + [3]byte{0, 23, 153}: "SmarTire Systems Inc.", + [3]byte{0, 23, 154}: "D-Link Corporation", + [3]byte{0, 23, 155}: "Chant Sincere CO., LTD.", + [3]byte{0, 23, 156}: "DEPRAG SCHULZ GMBH u. CO.", + [3]byte{0, 23, 157}: "Kelman Limited", + [3]byte{0, 23, 158}: "Sirit Inc", + [3]byte{0, 23, 159}: "Apricorn", + [3]byte{0, 23, 160}: "RoboTech srl", + [3]byte{0, 23, 161}: "3soft inc.", + [3]byte{0, 23, 162}: "Camrivox Ltd.", + [3]byte{0, 23, 163}: "MIX s.r.l.", + [3]byte{0, 23, 164}: "Hewlett-Packard Company", + [3]byte{0, 23, 165}: "Ralink Technology Corp", + [3]byte{0, 23, 166}: "YOSIN ELECTRONICS CO., LTD.", + [3]byte{0, 23, 167}: "Mobile Computing Promotion Consortium", + [3]byte{0, 23, 168}: "EDM Corporation", + [3]byte{0, 23, 169}: "Sentivision", + [3]byte{0, 23, 170}: "elab-experience inc.", + [3]byte{0, 23, 171}: "Nintendo Co., Ltd.", + [3]byte{0, 23, 172}: "O'Neil Product Development Inc.", + [3]byte{0, 23, 173}: "AceNet Corporation", + [3]byte{0, 23, 174}: "GAI-Tronics", + [3]byte{0, 23, 175}: "Enermet", + [3]byte{0, 23, 176}: "Nokia Danmark A/S", + [3]byte{0, 23, 177}: "ACIST Medical Systems, Inc.", + [3]byte{0, 23, 178}: "SK Telesys", + [3]byte{0, 23, 179}: "Aftek Infosys Limited", + [3]byte{0, 23, 180}: "Remote Security Systems, LLC", + [3]byte{0, 23, 181}: "Peerless Systems Corporation", + [3]byte{0, 23, 182}: "Aquantia", + [3]byte{0, 23, 183}: "Tonze Technology Co.", + [3]byte{0, 23, 184}: "NOVATRON CO., LTD.", + [3]byte{0, 23, 185}: "Gambro Lundia AB", + [3]byte{0, 23, 186}: "SEDO CO., LTD.", + [3]byte{0, 23, 187}: "Syrinx Industrial Electronics", + [3]byte{0, 23, 188}: "Touchtunes Music Corporation", + [3]byte{0, 23, 189}: "Tibetsystem", + [3]byte{0, 23, 190}: "Tratec Telecom B.V.", + [3]byte{0, 23, 191}: "Coherent Research Limited", + [3]byte{0, 23, 192}: "PureTech Systems, Inc.", + [3]byte{0, 23, 193}: "CM Precision Technology LTD.", + [3]byte{0, 23, 194}: "ADB Broadband Italia", + [3]byte{0, 23, 195}: "KTF Technologies Inc.", + [3]byte{0, 23, 196}: "Quanta Microsystems, INC.", + [3]byte{0, 23, 197}: "SonicWALL", + [3]byte{0, 23, 198}: "Cross Match Technologies Inc", + [3]byte{0, 23, 199}: "MARA Systems Consulting AB", + [3]byte{0, 23, 200}: "KYOCERA Document Solutions Inc.", + [3]byte{0, 23, 201}: "Samsung Electronics Co., Ltd.", + [3]byte{0, 23, 202}: "Qisda Corporation", + [3]byte{0, 23, 203}: "Juniper Networks", + [3]byte{0, 23, 204}: "Alcatel-Lucent", + [3]byte{0, 23, 205}: "CEC Wireless R&D Ltd.", + [3]byte{0, 23, 206}: "Screen Service Spa", + [3]byte{0, 23, 207}: "iMCA-GmbH", + [3]byte{0, 23, 208}: "Opticom Communications, LLC", + [3]byte{0, 23, 209}: "Nortel", + [3]byte{0, 23, 210}: "THINLINX PTY LTD", + [3]byte{0, 23, 211}: "Etymotic Research, Inc.", + [3]byte{0, 23, 212}: "Monsoon Multimedia, Inc", + [3]byte{0, 23, 213}: "Samsung Electronics Co., Ltd.", + [3]byte{0, 23, 214}: "Bluechips Microhouse Co.,Ltd.", + [3]byte{0, 23, 215}: "ION Geophysical Corporation Inc.", + [3]byte{0, 23, 216}: "Magnum Semiconductor, Inc.", + [3]byte{0, 23, 217}: "AAI Corporation", + [3]byte{0, 23, 218}: "Spans Logic", + [3]byte{0, 23, 219}: "CANKO TECHNOLOGIES INC.", + [3]byte{0, 23, 220}: "DAEMYUNG ZERO1", + [3]byte{0, 23, 221}: "Clipsal Australia", + [3]byte{0, 23, 222}: "Advantage Six Ltd", + [3]byte{0, 23, 223}: "CISCO SYSTEMS, INC.", + [3]byte{0, 23, 224}: "CISCO SYSTEMS, INC.", + [3]byte{0, 23, 225}: "DACOS Technologies Co., Ltd.", + [3]byte{0, 23, 226}: "ARRIS Group, Inc.", + [3]byte{0, 23, 227}: "Texas Instruments", + [3]byte{0, 23, 228}: "Texas Instruments", + [3]byte{0, 23, 229}: "Texas Instruments", + [3]byte{0, 23, 230}: "Texas Instruments", + [3]byte{0, 23, 231}: "Texas Instruments", + [3]byte{0, 23, 232}: "Texas Instruments", + [3]byte{0, 23, 233}: "Texas Instruments", + [3]byte{0, 23, 234}: "Texas Instruments", + [3]byte{0, 23, 235}: "Texas Instruments", + [3]byte{0, 23, 236}: "Texas Instruments", + [3]byte{0, 23, 237}: "WooJooIT Ltd.", + [3]byte{0, 23, 238}: "ARRIS Group, Inc.", + [3]byte{0, 23, 239}: "IBM Corp", + [3]byte{0, 23, 240}: "SZCOM Broadband Network Technology Co.,Ltd", + [3]byte{0, 23, 241}: "Renu Electronics Pvt Ltd", + [3]byte{0, 23, 242}: "Apple", + [3]byte{0, 23, 243}: "Harris Corparation", + [3]byte{0, 23, 244}: "ZERON ALLIANCE", + [3]byte{0, 23, 245}: "LIG NEOPTEK", + [3]byte{0, 23, 246}: "Pyramid Meriden Inc.", + [3]byte{0, 23, 247}: "CEM Solutions Pvt Ltd", + [3]byte{0, 23, 248}: "Motech Industries Inc.", + [3]byte{0, 23, 249}: "Forcom Sp. z o.o.", + [3]byte{0, 23, 250}: "Microsoft Corporation", + [3]byte{0, 23, 251}: "FA", + [3]byte{0, 23, 252}: "Suprema Inc.", + [3]byte{0, 23, 253}: "Amulet Hotkey", + [3]byte{0, 23, 254}: "TALOS SYSTEM INC.", + [3]byte{0, 23, 255}: "PLAYLINE Co.,Ltd.", + [3]byte{0, 24, 0}: "UNIGRAND LTD", + [3]byte{0, 24, 1}: "Actiontec Electronics, Inc", + [3]byte{0, 24, 2}: "Alpha Networks Inc.", + [3]byte{0, 24, 3}: "ArcSoft Shanghai Co. LTD", + [3]byte{0, 24, 4}: "E-TEK DIGITAL TECHNOLOGY LIMITED", + [3]byte{0, 24, 5}: "Beijing InHand Networking Technology Co.,Ltd.", + [3]byte{0, 24, 6}: "Hokkei Industries Co., Ltd.", + [3]byte{0, 24, 7}: "Fanstel Corp.", + [3]byte{0, 24, 8}: "SightLogix, Inc.", + [3]byte{0, 24, 9}: "CRESYN", + [3]byte{0, 24, 10}: "Meraki, Inc.", + [3]byte{0, 24, 11}: "Brilliant Telecommunications", + [3]byte{0, 24, 12}: "Optelian Access Networks", + [3]byte{0, 24, 13}: "Terabytes Server Storage Tech Corp", + [3]byte{0, 24, 14}: "Avega Systems", + [3]byte{0, 24, 15}: "Nokia Danmark A/S", + [3]byte{0, 24, 16}: "IPTrade S.A.", + [3]byte{0, 24, 17}: "Neuros Technology International, LLC.", + [3]byte{0, 24, 18}: "Beijing Xinwei Telecom Technology Co., Ltd.", + [3]byte{0, 24, 19}: "Sony Ericsson Mobile Communications", + [3]byte{0, 24, 20}: "Mitutoyo Corporation", + [3]byte{0, 24, 21}: "GZ Technologies, Inc.", + [3]byte{0, 24, 22}: "Ubixon Co., Ltd.", + [3]byte{0, 24, 23}: "D. E. Shaw Research, LLC", + [3]byte{0, 24, 24}: "CISCO SYSTEMS, INC.", + [3]byte{0, 24, 25}: "CISCO SYSTEMS, INC.", + [3]byte{0, 24, 26}: "AVerMedia Information Inc.", + [3]byte{0, 24, 27}: "TaiJin Metal Co., Ltd.", + [3]byte{0, 24, 28}: "Exterity Limited", + [3]byte{0, 24, 29}: "ASIA ELECTRONICS CO.,LTD", + [3]byte{0, 24, 30}: "GDX Technologies Ltd.", + [3]byte{0, 24, 31}: "Palmmicro Communications", + [3]byte{0, 24, 32}: "w5networks", + [3]byte{0, 24, 33}: "SINDORICOH", + [3]byte{0, 24, 34}: "CEC TELECOM CO.,LTD.", + [3]byte{0, 24, 35}: "Delta Electronics, Inc.", + [3]byte{0, 24, 36}: "Kimaldi Electronics, S.L.", + [3]byte{0, 24, 37}: "PRIVATE", + [3]byte{0, 24, 38}: "Cale Access AB", + [3]byte{0, 24, 39}: "NEC UNIFIED SOLUTIONS NEDERLAND B.V.", + [3]byte{0, 24, 40}: "e2v technologies (UK) ltd.", + [3]byte{0, 24, 41}: "Gatsometer", + [3]byte{0, 24, 42}: "Taiwan Video & Monitor", + [3]byte{0, 24, 43}: "Softier", + [3]byte{0, 24, 44}: "Ascend Networks, Inc.", + [3]byte{0, 24, 45}: "Artec Design", + [3]byte{0, 24, 46}: "XStreamHD, LLC", + [3]byte{0, 24, 47}: "Texas Instruments", + [3]byte{0, 24, 48}: "Texas Instruments", + [3]byte{0, 24, 49}: "Texas Instruments", + [3]byte{0, 24, 50}: "Texas Instruments", + [3]byte{0, 24, 51}: "Texas Instruments", + [3]byte{0, 24, 52}: "Texas Instruments", + [3]byte{0, 24, 53}: "Thoratec / ITC", + [3]byte{0, 24, 54}: "Reliance Electric Limited", + [3]byte{0, 24, 55}: "Universal ABIT Co., Ltd.", + [3]byte{0, 24, 56}: "PanAccess Communications,Inc.", + [3]byte{0, 24, 57}: "Cisco-Linksys LLC", + [3]byte{0, 24, 58}: "Westell Technologies", + [3]byte{0, 24, 59}: "CENITS Co., Ltd.", + [3]byte{0, 24, 60}: "Encore Software Limited", + [3]byte{0, 24, 61}: "Vertex Link Corporation", + [3]byte{0, 24, 62}: "Digilent, Inc", + [3]byte{0, 24, 63}: "2Wire, Inc", + [3]byte{0, 24, 64}: "3 Phoenix, Inc.", + [3]byte{0, 24, 65}: "High Tech Computer Corp", + [3]byte{0, 24, 66}: "Nokia Danmark A/S", + [3]byte{0, 24, 67}: "Dawevision Ltd", + [3]byte{0, 24, 68}: "Heads Up Technologies, Inc.", + [3]byte{0, 24, 69}: "Pulsar-Telecom LLC.", + [3]byte{0, 24, 70}: "Crypto S.A.", + [3]byte{0, 24, 71}: "AceNet Technology Inc.", + [3]byte{0, 24, 72}: "Vecima Networks Inc.", + [3]byte{0, 24, 73}: "Pigeon Point Systems LLC", + [3]byte{0, 24, 74}: "Catcher, Inc.", + [3]byte{0, 24, 75}: "Las Vegas Gaming, Inc.", + [3]byte{0, 24, 76}: "Bogen Communications", + [3]byte{0, 24, 77}: "Netgear Inc.", + [3]byte{0, 24, 78}: "Lianhe Technologies, Inc.", + [3]byte{0, 24, 79}: "8 Ways Technology Corp.", + [3]byte{0, 24, 80}: "Secfone Kft", + [3]byte{0, 24, 81}: "SWsoft", + [3]byte{0, 24, 82}: "StorLink Semiconductors, Inc.", + [3]byte{0, 24, 83}: "Atera Networks LTD.", + [3]byte{0, 24, 84}: "Argard Co., Ltd", + [3]byte{0, 24, 85}: "Aeromaritime Systembau GmbH", + [3]byte{0, 24, 86}: "EyeFi, Inc", + [3]byte{0, 24, 87}: "Unilever R&D", + [3]byte{0, 24, 88}: "TagMaster AB", + [3]byte{0, 24, 89}: "Strawberry Linux Co.,Ltd.", + [3]byte{0, 24, 90}: "uControl, Inc.", + [3]byte{0, 24, 91}: "Network Chemistry, Inc", + [3]byte{0, 24, 92}: "EDS Lab Pte Ltd", + [3]byte{0, 24, 93}: "TAIGUEN TECHNOLOGY (SHEN-ZHEN) CO., LTD.", + [3]byte{0, 24, 94}: "Nexterm Inc.", + [3]byte{0, 24, 95}: "TAC Inc.", + [3]byte{0, 24, 96}: "SIM Technology Group Shanghai Simcom Ltd.,", + [3]byte{0, 24, 97}: "Ooma, Inc.", + [3]byte{0, 24, 98}: "Seagate Technology", + [3]byte{0, 24, 99}: "Veritech Electronics Limited", + [3]byte{0, 24, 100}: "Eaton Corporation", + [3]byte{0, 24, 101}: "Siemens Healthcare Diagnostics Manufacturing Ltd", + [3]byte{0, 24, 102}: "Leutron Vision", + [3]byte{0, 24, 103}: "Datalogic ADC", + [3]byte{0, 24, 104}: "Scientific Atlanta, A Cisco Company", + [3]byte{0, 24, 105}: "KINGJIM", + [3]byte{0, 24, 106}: "Global Link Digital Technology Co,.LTD", + [3]byte{0, 24, 107}: "Sambu Communics CO., LTD.", + [3]byte{0, 24, 108}: "Neonode AB", + [3]byte{0, 24, 109}: "Zhenjiang Sapphire Electronic Industry CO.", + [3]byte{0, 24, 110}: "3Com Ltd", + [3]byte{0, 24, 111}: "Setha Industria Eletronica LTDA", + [3]byte{0, 24, 112}: "E28 Shanghai Limited", + [3]byte{0, 24, 113}: "Hewlett-Packard Company", + [3]byte{0, 24, 114}: "Expertise Engineering", + [3]byte{0, 24, 115}: "CISCO SYSTEMS, INC.", + [3]byte{0, 24, 116}: "CISCO SYSTEMS, INC.", + [3]byte{0, 24, 117}: "AnaCise Testnology Pte Ltd", + [3]byte{0, 24, 118}: "WowWee Ltd.", + [3]byte{0, 24, 119}: "Amplex A/S", + [3]byte{0, 24, 120}: "Mackware GmbH", + [3]byte{0, 24, 121}: "dSys", + [3]byte{0, 24, 122}: "Wiremold", + [3]byte{0, 24, 123}: "4NSYS Co. Ltd.", + [3]byte{0, 24, 124}: "INTERCROSS, LLC", + [3]byte{0, 24, 125}: "Armorlink shanghai Co. Ltd", + [3]byte{0, 24, 126}: "RGB Spectrum", + [3]byte{0, 24, 127}: "ZODIANET", + [3]byte{0, 24, 128}: "Maxim Integrated Products", + [3]byte{0, 24, 129}: "Buyang Electronics Industrial Co., Ltd", + [3]byte{0, 24, 130}: "Huawei Technologies Co., Ltd.", + [3]byte{0, 24, 131}: "FORMOSA21 INC.", + [3]byte{0, 24, 132}: "Fon Technology S.L.", + [3]byte{0, 24, 133}: "Avigilon Corporation", + [3]byte{0, 24, 134}: "EL-TECH, INC.", + [3]byte{0, 24, 135}: "Metasystem SpA", + [3]byte{0, 24, 136}: "GOTIVE a.s.", + [3]byte{0, 24, 137}: "WinNet Solutions Limited", + [3]byte{0, 24, 138}: "Infinova LLC", + [3]byte{0, 24, 139}: "Dell Inc", + [3]byte{0, 24, 140}: "Mobile Action Technology Inc.", + [3]byte{0, 24, 141}: "Nokia Danmark A/S", + [3]byte{0, 24, 142}: "Ekahau, Inc.", + [3]byte{0, 24, 143}: "Montgomery Technology, Inc.", + [3]byte{0, 24, 144}: "RadioCOM, s.r.o.", + [3]byte{0, 24, 145}: "Zhongshan General K-mate Electronics Co., Ltd", + [3]byte{0, 24, 146}: "ads-tec GmbH", + [3]byte{0, 24, 147}: "SHENZHEN PHOTON BROADBAND TECHNOLOGY CO.,LTD", + [3]byte{0, 24, 148}: "NPCore, Inc.", + [3]byte{0, 24, 149}: "Hansun Technologies Inc.", + [3]byte{0, 24, 150}: "Great Well Electronic LTD", + [3]byte{0, 24, 151}: "JESS-LINK PRODUCTS Co., LTD", + [3]byte{0, 24, 152}: "KINGSTATE ELECTRONICS CORPORATION", + [3]byte{0, 24, 153}: "ShenZhen jieshun Science&Technology Industry CO,LTD.", + [3]byte{0, 24, 154}: "HANA Micron Inc.", + [3]byte{0, 24, 155}: "Thomson Inc.", + [3]byte{0, 24, 156}: "Weldex Corporation", + [3]byte{0, 24, 157}: "Navcast Inc.", + [3]byte{0, 24, 158}: "OMNIKEY GmbH.", + [3]byte{0, 24, 159}: "Lenntek Corporation", + [3]byte{0, 24, 160}: "Cierma Ascenseurs", + [3]byte{0, 24, 161}: "Tiqit Computers, Inc.", + [3]byte{0, 24, 162}: "XIP Technology AB", + [3]byte{0, 24, 163}: "ZIPPY TECHNOLOGY CORP.", + [3]byte{0, 24, 164}: "ARRIS Group, Inc.", + [3]byte{0, 24, 165}: "ADigit Technologies Corp.", + [3]byte{0, 24, 166}: "Persistent Systems, LLC", + [3]byte{0, 24, 167}: "Yoggie Security Systems LTD.", + [3]byte{0, 24, 168}: "AnNeal Technology Inc.", + [3]byte{0, 24, 169}: "Ethernet Direct Corporation", + [3]byte{0, 24, 170}: "Protec Fire Detection plc", + [3]byte{0, 24, 171}: "BEIJING LHWT MICROELECTRONICS INC.", + [3]byte{0, 24, 172}: "Shanghai Jiao Da HISYS Technology Co. Ltd.", + [3]byte{0, 24, 173}: "NIDEC SANKYO CORPORATION", + [3]byte{0, 24, 174}: "TVT CO.,LTD", + [3]byte{0, 24, 175}: "Samsung Electronics Co., Ltd.", + [3]byte{0, 24, 176}: "Nortel", + [3]byte{0, 24, 177}: "IBM Corp", + [3]byte{0, 24, 178}: "ADEUNIS RF", + [3]byte{0, 24, 179}: "TEC WizHome Co., Ltd.", + [3]byte{0, 24, 180}: "Dawon Media Inc.", + [3]byte{0, 24, 181}: "Magna Carta", + [3]byte{0, 24, 182}: "S3C, Inc.", + [3]byte{0, 24, 183}: "D3 LED, LLC", + [3]byte{0, 24, 184}: "New Voice International AG", + [3]byte{0, 24, 185}: "CISCO SYSTEMS, INC.", + [3]byte{0, 24, 186}: "CISCO SYSTEMS, INC.", + [3]byte{0, 24, 187}: "Eliwell Controls srl", + [3]byte{0, 24, 188}: "ZAO NVP Bolid", + [3]byte{0, 24, 189}: "SHENZHEN DVBWORLD TECHNOLOGY CO., LTD.", + [3]byte{0, 24, 190}: "ANSA Corporation", + [3]byte{0, 24, 191}: "Essence Technology Solution, Inc.", + [3]byte{0, 24, 192}: "ARRIS Group, Inc.", + [3]byte{0, 24, 193}: "Almitec Informática e Comércio", + [3]byte{0, 24, 194}: "Firetide, Inc", + [3]byte{0, 24, 195}: "CS Corporation", + [3]byte{0, 24, 196}: "Raba Technologies LLC", + [3]byte{0, 24, 197}: "Nokia Danmark A/S", + [3]byte{0, 24, 198}: "OPW Fuel Management Systems", + [3]byte{0, 24, 199}: "Real Time Automation", + [3]byte{0, 24, 200}: "ISONAS Inc.", + [3]byte{0, 24, 201}: "EOps Technology Limited", + [3]byte{0, 24, 202}: "Viprinet GmbH", + [3]byte{0, 24, 203}: "Tecobest Technology Limited", + [3]byte{0, 24, 204}: "AXIOHM SAS", + [3]byte{0, 24, 205}: "Erae Electronics Industry Co., Ltd", + [3]byte{0, 24, 206}: "Dreamtech Co., Ltd", + [3]byte{0, 24, 207}: "Baldor Electric Company", + [3]byte{0, 24, 208}: "AtRoad, A Trimble Company", + [3]byte{0, 24, 209}: "Siemens Home & Office Comm. Devices", + [3]byte{0, 24, 210}: "High-Gain Antennas LLC", + [3]byte{0, 24, 211}: "TEAMCAST", + [3]byte{0, 24, 212}: "Unified Display Interface SIG", + [3]byte{0, 24, 213}: "REIGNCOM", + [3]byte{0, 24, 214}: "Swirlnet A/S", + [3]byte{0, 24, 215}: "Javad Navigation Systems Inc.", + [3]byte{0, 24, 216}: "ARCH METER Corporation", + [3]byte{0, 24, 217}: "Santosha Internatonal, Inc", + [3]byte{0, 24, 218}: "AMBER wireless GmbH", + [3]byte{0, 24, 219}: "EPL Technology Ltd", + [3]byte{0, 24, 220}: "Prostar Co., Ltd.", + [3]byte{0, 24, 221}: "Silicondust Engineering Ltd", + [3]byte{0, 24, 222}: "Intel Corporate", + [3]byte{0, 24, 223}: "The Morey Corporation", + [3]byte{0, 24, 224}: "ANAVEO", + [3]byte{0, 24, 225}: "Verkerk Service Systemen", + [3]byte{0, 24, 226}: "Topdata Sistemas de Automacao Ltda", + [3]byte{0, 24, 227}: "Visualgate Systems, Inc.", + [3]byte{0, 24, 228}: "YIGUANG", + [3]byte{0, 24, 229}: "Adhoco AG", + [3]byte{0, 24, 230}: "Computer Hardware Design SIA", + [3]byte{0, 24, 231}: "Cameo Communications, INC.", + [3]byte{0, 24, 232}: "Hacetron Corporation", + [3]byte{0, 24, 233}: "Numata Corporation", + [3]byte{0, 24, 234}: "Alltec GmbH", + [3]byte{0, 24, 235}: "BroVis Wireless Networks", + [3]byte{0, 24, 236}: "Welding Technology Corporation", + [3]byte{0, 24, 237}: "Accutech Ultrasystems Co., Ltd.", + [3]byte{0, 24, 238}: "Videology Imaging Solutions, Inc.", + [3]byte{0, 24, 239}: "Escape Communications, Inc.", + [3]byte{0, 24, 240}: "JOYTOTO Co., Ltd.", + [3]byte{0, 24, 241}: "Chunichi Denshi Co.,LTD.", + [3]byte{0, 24, 242}: "Beijing Tianyu Communication Equipment Co., Ltd", + [3]byte{0, 24, 243}: "ASUSTek COMPUTER INC.", + [3]byte{0, 24, 244}: "EO TECHNICS Co., Ltd.", + [3]byte{0, 24, 245}: "Shenzhen Streaming Video Technology Company Limited", + [3]byte{0, 24, 246}: "Thomson Telecom Belgium", + [3]byte{0, 24, 247}: "Kameleon Technologies", + [3]byte{0, 24, 248}: "Cisco-Linksys LLC", + [3]byte{0, 24, 249}: "VVOND, Inc.", + [3]byte{0, 24, 250}: "Yushin Precision Equipment Co.,Ltd.", + [3]byte{0, 24, 251}: "Compro Technology", + [3]byte{0, 24, 252}: "Altec Electronic AG", + [3]byte{0, 24, 253}: "Optimal Technologies International Inc.", + [3]byte{0, 24, 254}: "Hewlett-Packard Company", + [3]byte{0, 24, 255}: "PowerQuattro Co.", + [3]byte{0, 25, 0}: "Intelliverese - DBA Voicecom", + [3]byte{0, 25, 1}: "F1MEDIA", + [3]byte{0, 25, 2}: "Cambridge Consultants Ltd", + [3]byte{0, 25, 3}: "Bigfoot Networks Inc", + [3]byte{0, 25, 4}: "WB Electronics Sp. z o.o.", + [3]byte{0, 25, 5}: "SCHRACK Seconet AG", + [3]byte{0, 25, 6}: "CISCO SYSTEMS, INC.", + [3]byte{0, 25, 7}: "CISCO SYSTEMS, INC.", + [3]byte{0, 25, 8}: "Duaxes Corporation", + [3]byte{0, 25, 9}: "DEVI - Danfoss A/S", + [3]byte{0, 25, 10}: "HASWARE INC.", + [3]byte{0, 25, 11}: "Southern Vision Systems, Inc.", + [3]byte{0, 25, 12}: "Encore Electronics, Inc.", + [3]byte{0, 25, 13}: "IEEE 1394c", + [3]byte{0, 25, 14}: "Atech Technology Co., Ltd.", + [3]byte{0, 25, 15}: "Advansus Corp.", + [3]byte{0, 25, 16}: "Knick Elektronische Messgeraete GmbH & Co. KG", + [3]byte{0, 25, 17}: "Just In Mobile Information Technologies (Shanghai) Co., Ltd.", + [3]byte{0, 25, 18}: "Welcat Inc", + [3]byte{0, 25, 19}: "Chuang-Yi Network Equipment Co.Ltd.", + [3]byte{0, 25, 20}: "Winix Co., Ltd", + [3]byte{0, 25, 21}: "TECOM Co., Ltd.", + [3]byte{0, 25, 22}: "PayTec AG", + [3]byte{0, 25, 23}: "Posiflex Inc.", + [3]byte{0, 25, 24}: "Interactive Wear AG", + [3]byte{0, 25, 25}: "ASTEL Inc.", + [3]byte{0, 25, 26}: "IRLINK", + [3]byte{0, 25, 27}: "Sputnik Engineering AG", + [3]byte{0, 25, 28}: "Sensicast Systems", + [3]byte{0, 25, 29}: "Nintendo Co., Ltd.", + [3]byte{0, 25, 30}: "Beyondwiz Co., Ltd.", + [3]byte{0, 25, 31}: "Microlink communications Inc.", + [3]byte{0, 25, 32}: "KUME electric Co.,Ltd.", + [3]byte{0, 25, 33}: "Elitegroup Computer System Co.", + [3]byte{0, 25, 34}: "CM Comandos Lineares", + [3]byte{0, 25, 35}: "Phonex Korea Co., LTD.", + [3]byte{0, 25, 36}: "LBNL Engineering", + [3]byte{0, 25, 37}: "Intelicis Corporation", + [3]byte{0, 25, 38}: "BitsGen Co., Ltd.", + [3]byte{0, 25, 39}: "ImCoSys Ltd", + [3]byte{0, 25, 40}: "Siemens AG, Transportation Systems", + [3]byte{0, 25, 41}: "2M2B Montadora de Maquinas Bahia Brasil LTDA", + [3]byte{0, 25, 42}: "Antiope Associates", + [3]byte{0, 25, 43}: "Aclara RF Systems Inc.", + [3]byte{0, 25, 44}: "ARRIS Group, Inc.", + [3]byte{0, 25, 45}: "Nokia Corporation", + [3]byte{0, 25, 46}: "Spectral Instruments, Inc.", + [3]byte{0, 25, 47}: "CISCO SYSTEMS, INC.", + [3]byte{0, 25, 48}: "CISCO SYSTEMS, INC.", + [3]byte{0, 25, 49}: "Balluff GmbH", + [3]byte{0, 25, 50}: "Gude Analog- und Digialsysteme GmbH", + [3]byte{0, 25, 51}: "Strix Systems, Inc.", + [3]byte{0, 25, 52}: "TRENDON TOUCH TECHNOLOGY CORP.", + [3]byte{0, 25, 53}: "DUERR DENTAL AG", + [3]byte{0, 25, 54}: "STERLITE OPTICAL TECHNOLOGIES LIMITED", + [3]byte{0, 25, 55}: "CommerceGuard AB", + [3]byte{0, 25, 56}: "UMB Communications Co., Ltd.", + [3]byte{0, 25, 57}: "Gigamips", + [3]byte{0, 25, 58}: "OESOLUTIONS", + [3]byte{0, 25, 59}: "Wilibox Deliberant Group LLC", + [3]byte{0, 25, 60}: "HighPoint Technologies Incorporated", + [3]byte{0, 25, 61}: "GMC Guardian Mobility Corp.", + [3]byte{0, 25, 62}: "ADB Broadband Italia", + [3]byte{0, 25, 63}: "RDI technology(Shenzhen) Co.,LTD", + [3]byte{0, 25, 64}: "Rackable Systems", + [3]byte{0, 25, 65}: "Pitney Bowes, Inc", + [3]byte{0, 25, 66}: "ON SOFTWARE INTERNATIONAL LIMITED", + [3]byte{0, 25, 67}: "Belden", + [3]byte{0, 25, 68}: "Fossil Partners, L.P.", + [3]byte{0, 25, 69}: "Ten-Tec Inc.", + [3]byte{0, 25, 70}: "Cianet Industria e Comercio S/A", + [3]byte{0, 25, 71}: "Scientific Atlanta, A Cisco Company", + [3]byte{0, 25, 72}: "AireSpider Networks", + [3]byte{0, 25, 73}: "TENTEL COMTECH CO., LTD.", + [3]byte{0, 25, 74}: "TESTO AG", + [3]byte{0, 25, 75}: "SAGEM COMMUNICATION", + [3]byte{0, 25, 76}: "Fujian Stelcom information & Technology CO.,Ltd", + [3]byte{0, 25, 77}: "Avago Technologies Sdn Bhd", + [3]byte{0, 25, 78}: "Ultra Electronics - TCS (Tactical Communication Systems)", + [3]byte{0, 25, 79}: "Nokia Danmark A/S", + [3]byte{0, 25, 80}: "Harman Multimedia", + [3]byte{0, 25, 81}: "NETCONS, s.r.o.", + [3]byte{0, 25, 82}: "ACOGITO Co., Ltd", + [3]byte{0, 25, 83}: "Chainleader Communications Corp.", + [3]byte{0, 25, 84}: "Leaf Corporation.", + [3]byte{0, 25, 85}: "CISCO SYSTEMS, INC.", + [3]byte{0, 25, 86}: "CISCO SYSTEMS, INC.", + [3]byte{0, 25, 87}: "Saafnet Canada Inc.", + [3]byte{0, 25, 88}: "Bluetooth SIG, Inc.", + [3]byte{0, 25, 89}: "Staccato Communications Inc.", + [3]byte{0, 25, 90}: "Jenaer Antriebstechnik GmbH", + [3]byte{0, 25, 91}: "D-Link Corporation", + [3]byte{0, 25, 92}: "Innotech Corporation", + [3]byte{0, 25, 93}: "ShenZhen XinHuaTong Opto Electronics Co.,Ltd", + [3]byte{0, 25, 94}: "ARRIS Group, Inc.", + [3]byte{0, 25, 95}: "Valemount Networks Corporation", + [3]byte{0, 25, 96}: "DoCoMo Systems, Inc.", + [3]byte{0, 25, 97}: "Blaupunkt Embedded Systems GmbH", + [3]byte{0, 25, 98}: "Commerciant, LP", + [3]byte{0, 25, 99}: "Sony Ericsson Mobile Communications AB", + [3]byte{0, 25, 100}: "Doorking Inc.", + [3]byte{0, 25, 101}: "YuHua TelTech (ShangHai) Co., Ltd.", + [3]byte{0, 25, 102}: "Asiarock Technology Limited", + [3]byte{0, 25, 103}: "TELDAT Sp.J.", + [3]byte{0, 25, 104}: "Digital Video Networks(Shanghai) CO. LTD.", + [3]byte{0, 25, 105}: "Nortel", + [3]byte{0, 25, 106}: "MikroM GmbH", + [3]byte{0, 25, 107}: "Danpex Corporation", + [3]byte{0, 25, 108}: "ETROVISION TECHNOLOGY", + [3]byte{0, 25, 109}: "Raybit Systems Korea, Inc", + [3]byte{0, 25, 110}: "Metacom (Pty) Ltd.", + [3]byte{0, 25, 111}: "SensoPart GmbH", + [3]byte{0, 25, 112}: "Z-Com, Inc.", + [3]byte{0, 25, 113}: "Guangzhou Unicomp Technology Co.,Ltd", + [3]byte{0, 25, 114}: "Plexus (Xiamen) Co.,ltd", + [3]byte{0, 25, 115}: "Zeugma Systems", + [3]byte{0, 25, 116}: "AboCom Systems, Inc.", + [3]byte{0, 25, 117}: "Beijing Huisen networks technology Inc", + [3]byte{0, 25, 118}: "Xipher Technologies, LLC", + [3]byte{0, 25, 119}: "Aerohive Networks, Inc.", + [3]byte{0, 25, 120}: "Datum Systems, Inc.", + [3]byte{0, 25, 121}: "Nokia Danmark A/S", + [3]byte{0, 25, 122}: "MAZeT GmbH", + [3]byte{0, 25, 123}: "Picotest Corp.", + [3]byte{0, 25, 124}: "Riedel Communications GmbH", + [3]byte{0, 25, 125}: "Hon Hai Precision Ind. Co., Ltd", + [3]byte{0, 25, 126}: "Hon Hai Precision Ind. Co., Ltd", + [3]byte{0, 25, 127}: "PLANTRONICS, INC.", + [3]byte{0, 25, 128}: "Gridpoint Systems", + [3]byte{0, 25, 129}: "Vivox Inc", + [3]byte{0, 25, 130}: "SmarDTV", + [3]byte{0, 25, 131}: "CCT R&D Limited", + [3]byte{0, 25, 132}: "ESTIC Corporation", + [3]byte{0, 25, 133}: "IT Watchdogs, Inc", + [3]byte{0, 25, 134}: "Cheng Hongjian", + [3]byte{0, 25, 135}: "Panasonic Mobile Communications Co., Ltd.", + [3]byte{0, 25, 136}: "Wi2Wi, Inc", + [3]byte{0, 25, 137}: "Sonitrol Corporation", + [3]byte{0, 25, 138}: "Northrop Grumman Systems Corp.", + [3]byte{0, 25, 139}: "Novera Optics Korea, Inc.", + [3]byte{0, 25, 140}: "iXSea", + [3]byte{0, 25, 141}: "Ocean Optics, Inc.", + [3]byte{0, 25, 142}: "Oticon A/S", + [3]byte{0, 25, 143}: "Alcatel Bell N.V.", + [3]byte{0, 25, 144}: "ELM DATA Co., Ltd.", + [3]byte{0, 25, 145}: "avinfo", + [3]byte{0, 25, 146}: "ADTRAN INC.", + [3]byte{0, 25, 147}: "Changshu Switchgear MFG. Co.,Ltd. (Former Changshu Switchgea", + [3]byte{0, 25, 148}: "Jorjin Technologies Inc.", + [3]byte{0, 25, 149}: "Jurong Hi-Tech (Suzhou)Co.ltd", + [3]byte{0, 25, 150}: "TurboChef Technologies Inc.", + [3]byte{0, 25, 151}: "Soft Device Sdn Bhd", + [3]byte{0, 25, 152}: "SATO CORPORATION", + [3]byte{0, 25, 153}: "Fujitsu Technology Solutions", + [3]byte{0, 25, 154}: "EDO-EVI", + [3]byte{0, 25, 155}: "Diversified Technical Systems, Inc.", + [3]byte{0, 25, 156}: "CTRING", + [3]byte{0, 25, 157}: "VIZIO, Inc.", + [3]byte{0, 25, 158}: "Nifty", + [3]byte{0, 25, 159}: "DKT A/S", + [3]byte{0, 25, 160}: "NIHON DATA SYSTENS, INC.", + [3]byte{0, 25, 161}: "LG INFORMATION & COMM.", + [3]byte{0, 25, 162}: "ORDYN TECHNOLOGIES", + [3]byte{0, 25, 163}: "asteel electronique atlantique", + [3]byte{0, 25, 164}: "Austar Technology (hang zhou) Co.,Ltd", + [3]byte{0, 25, 165}: "RadarFind Corporation", + [3]byte{0, 25, 166}: "ARRIS Group, Inc.", + [3]byte{0, 25, 167}: "ITU-T", + [3]byte{0, 25, 168}: "WiQuest Communications", + [3]byte{0, 25, 169}: "CISCO SYSTEMS, INC.", + [3]byte{0, 25, 170}: "CISCO SYSTEMS, INC.", + [3]byte{0, 25, 171}: "Raycom CO ., LTD", + [3]byte{0, 25, 172}: "GSP SYSTEMS Inc.", + [3]byte{0, 25, 173}: "BOBST SA", + [3]byte{0, 25, 174}: "Hopling Technologies b.v.", + [3]byte{0, 25, 175}: "Rigol Technologies, Inc.", + [3]byte{0, 25, 176}: "HanYang System", + [3]byte{0, 25, 177}: "Arrow7 Corporation", + [3]byte{0, 25, 178}: "XYnetsoft Co.,Ltd", + [3]byte{0, 25, 179}: "Stanford Research Systems", + [3]byte{0, 25, 180}: "VideoCast Ltd.", + [3]byte{0, 25, 181}: "Famar Fueguina S.A.", + [3]byte{0, 25, 182}: "Euro Emme s.r.l.", + [3]byte{0, 25, 183}: "Nokia Danmark A/S", + [3]byte{0, 25, 184}: "Boundary Devices", + [3]byte{0, 25, 185}: "Dell Inc.", + [3]byte{0, 25, 186}: "Paradox Security Systems Ltd", + [3]byte{0, 25, 187}: "Hewlett-Packard Company", + [3]byte{0, 25, 188}: "ELECTRO CHANCE SRL", + [3]byte{0, 25, 189}: "New Media Life", + [3]byte{0, 25, 190}: "Altai Technologies Limited", + [3]byte{0, 25, 191}: "Citiway technology Co.,ltd", + [3]byte{0, 25, 192}: "ARRIS Group, Inc.", + [3]byte{0, 25, 193}: "Alps Electric Co., Ltd", + [3]byte{0, 25, 194}: "Equustek Solutions, Inc.", + [3]byte{0, 25, 195}: "Qualitrol", + [3]byte{0, 25, 196}: "Infocrypt Inc.", + [3]byte{0, 25, 197}: "SONY Computer Entertainment inc,", + [3]byte{0, 25, 198}: "ZTE Corporation", + [3]byte{0, 25, 199}: "Cambridge Industries(Group) Co.,Ltd.", + [3]byte{0, 25, 200}: "AnyDATA Corporation", + [3]byte{0, 25, 201}: "S&C ELECTRIC COMPANY", + [3]byte{0, 25, 202}: "Broadata Communications, Inc", + [3]byte{0, 25, 203}: "ZyXEL Communications Corporation", + [3]byte{0, 25, 204}: "RCG (HK) Ltd", + [3]byte{0, 25, 205}: "Chengdu ethercom information technology Ltd.", + [3]byte{0, 25, 206}: "Progressive Gaming International", + [3]byte{0, 25, 207}: "SALICRU, S.A.", + [3]byte{0, 25, 208}: "Cathexis", + [3]byte{0, 25, 209}: "Intel Corporate", + [3]byte{0, 25, 210}: "Intel Corporate", + [3]byte{0, 25, 211}: "TRAK Microwave", + [3]byte{0, 25, 212}: "ICX Technologies", + [3]byte{0, 25, 213}: "IP Innovations, Inc.", + [3]byte{0, 25, 214}: "LS Cable and System Ltd.", + [3]byte{0, 25, 215}: "FORTUNETEK CO., LTD", + [3]byte{0, 25, 216}: "MAXFOR", + [3]byte{0, 25, 217}: "Zeutschel GmbH", + [3]byte{0, 25, 218}: "Welltrans O&E Technology Co. , Ltd.", + [3]byte{0, 25, 219}: "MICRO-STAR INTERNATIONAL CO., LTD.", + [3]byte{0, 25, 220}: "ENENSYS Technologies", + [3]byte{0, 25, 221}: "FEI-Zyfer, Inc.", + [3]byte{0, 25, 222}: "MOBITEK", + [3]byte{0, 25, 223}: "Thomson Inc.", + [3]byte{0, 25, 224}: "TP-LINK Technologies Co., Ltd.", + [3]byte{0, 25, 225}: "Nortel", + [3]byte{0, 25, 226}: "Juniper Networks", + [3]byte{0, 25, 227}: "Apple", + [3]byte{0, 25, 228}: "2Wire, Inc", + [3]byte{0, 25, 229}: "Lynx Studio Technology, Inc.", + [3]byte{0, 25, 230}: "TOYO MEDIC CO.,LTD.", + [3]byte{0, 25, 231}: "CISCO SYSTEMS, INC.", + [3]byte{0, 25, 232}: "CISCO SYSTEMS, INC.", + [3]byte{0, 25, 233}: "S-Information Technolgy, Co., Ltd.", + [3]byte{0, 25, 234}: "TeraMage Technologies Co., Ltd.", + [3]byte{0, 25, 235}: "Pyronix Ltd", + [3]byte{0, 25, 236}: "Sagamore Systems, Inc.", + [3]byte{0, 25, 237}: "Axesstel Inc.", + [3]byte{0, 25, 238}: "CARLO GAVAZZI CONTROLS SPA-Controls Division", + [3]byte{0, 25, 239}: "SHENZHEN LINNKING ELECTRONICS CO.,LTD", + [3]byte{0, 25, 240}: "UNIONMAN TECHNOLOGY CO.,LTD", + [3]byte{0, 25, 241}: "Star Communication Network Technology Co.,Ltd", + [3]byte{0, 25, 242}: "Teradyne K.K.", + [3]byte{0, 25, 243}: "Cetis, Inc", + [3]byte{0, 25, 244}: "Convergens Oy Ltd", + [3]byte{0, 25, 245}: "Imagination Technologies Ltd", + [3]byte{0, 25, 246}: "Acconet (PTE) Ltd", + [3]byte{0, 25, 247}: "Onset Computer Corporation", + [3]byte{0, 25, 248}: "Embedded Systems Design, Inc.", + [3]byte{0, 25, 249}: "TDK-Lambda", + [3]byte{0, 25, 250}: "Cable Vision Electronics CO., LTD.", + [3]byte{0, 25, 251}: "BSkyB Ltd", + [3]byte{0, 25, 252}: "PT. Ufoakses Sukses Luarbiasa", + [3]byte{0, 25, 253}: "Nintendo Co., Ltd.", + [3]byte{0, 25, 254}: "SHENZHEN SEECOMM TECHNOLOGY CO.,LTD.", + [3]byte{0, 25, 255}: "Finnzymes", + [3]byte{0, 26, 0}: "MATRIX INC.", + [3]byte{0, 26, 1}: "Smiths Medical", + [3]byte{0, 26, 2}: "SECURE CARE PRODUCTS, INC", + [3]byte{0, 26, 3}: "Angel Electronics Co., Ltd.", + [3]byte{0, 26, 4}: "Interay Solutions BV", + [3]byte{0, 26, 5}: "OPTIBASE LTD", + [3]byte{0, 26, 6}: "OpVista, Inc.", + [3]byte{0, 26, 7}: "Arecont Vision", + [3]byte{0, 26, 8}: "Simoco Ltd.", + [3]byte{0, 26, 9}: "Wayfarer Transit Systems Ltd", + [3]byte{0, 26, 10}: "Adaptive Micro-Ware Inc.", + [3]byte{0, 26, 11}: "BONA TECHNOLOGY INC.", + [3]byte{0, 26, 12}: "Swe-Dish Satellite Systems AB", + [3]byte{0, 26, 13}: "HandHeld entertainment, Inc.", + [3]byte{0, 26, 14}: "Cheng Uei Precision Industry Co.,Ltd", + [3]byte{0, 26, 15}: "Sistemas Avanzados de Control, S.A.", + [3]byte{0, 26, 16}: "LUCENT TRANS ELECTRONICS CO.,LTD", + [3]byte{0, 26, 17}: "Google Inc.", + [3]byte{0, 26, 18}: "Essilor", + [3]byte{0, 26, 19}: "Wanlida Group Co., LTD", + [3]byte{0, 26, 20}: "Xin Hua Control Engineering Co.,Ltd.", + [3]byte{0, 26, 21}: "gemalto e-Payment", + [3]byte{0, 26, 22}: "Nokia Danmark A/S", + [3]byte{0, 26, 23}: "Teak Technologies, Inc.", + [3]byte{0, 26, 24}: "Advanced Simulation Technology inc.", + [3]byte{0, 26, 25}: "Computer Engineering Limited", + [3]byte{0, 26, 26}: "Gentex Corporation/Electro-Acoustic Products", + [3]byte{0, 26, 27}: "ARRIS Group, Inc.", + [3]byte{0, 26, 28}: "GT&T Engineering Pte Ltd", + [3]byte{0, 26, 29}: "PChome Online Inc.", + [3]byte{0, 26, 30}: "Aruba Networks", + [3]byte{0, 26, 31}: "Coastal Environmental Systems", + [3]byte{0, 26, 32}: "CMOTECH Co. Ltd.", + [3]byte{0, 26, 33}: "Indac B.V.", + [3]byte{0, 26, 34}: "eQ-3 Entwicklung GmbH", + [3]byte{0, 26, 35}: "Ice Qube, Inc", + [3]byte{0, 26, 36}: "Galaxy Telecom Technologies Ltd", + [3]byte{0, 26, 37}: "DELTA DORE", + [3]byte{0, 26, 38}: "Deltanode Solutions AB", + [3]byte{0, 26, 39}: "Ubistar", + [3]byte{0, 26, 40}: "ASWT Co., LTD. Taiwan Branch H.K.", + [3]byte{0, 26, 41}: "Johnson Outdoors Marine Electronics, Inc", + [3]byte{0, 26, 42}: "Arcadyan Technology Corporation", + [3]byte{0, 26, 43}: "Ayecom Technology Co., Ltd.", + [3]byte{0, 26, 44}: "SATEC Co.,LTD", + [3]byte{0, 26, 45}: "The Navvo Group", + [3]byte{0, 26, 46}: "Ziova Coporation", + [3]byte{0, 26, 47}: "CISCO SYSTEMS, INC.", + [3]byte{0, 26, 48}: "CISCO SYSTEMS, INC.", + [3]byte{0, 26, 49}: "SCAN COIN Industries AB", + [3]byte{0, 26, 50}: "ACTIVA MULTIMEDIA", + [3]byte{0, 26, 51}: "ASI Communications, Inc.", + [3]byte{0, 26, 52}: "Konka Group Co., Ltd.", + [3]byte{0, 26, 53}: "BARTEC GmbH", + [3]byte{0, 26, 54}: "Aipermon GmbH & Co. KG", + [3]byte{0, 26, 55}: "Lear Corporation", + [3]byte{0, 26, 56}: "Sanmina-SCI", + [3]byte{0, 26, 57}: "Merten GmbH&CoKG", + [3]byte{0, 26, 58}: "Dongahelecomm", + [3]byte{0, 26, 59}: "Doah Elecom Inc.", + [3]byte{0, 26, 60}: "Technowave Ltd.", + [3]byte{0, 26, 61}: "Ajin Vision Co.,Ltd", + [3]byte{0, 26, 62}: "Faster Technology LLC", + [3]byte{0, 26, 63}: "intelbras", + [3]byte{0, 26, 64}: "A-FOUR TECH CO., LTD.", + [3]byte{0, 26, 65}: "INOCOVA Co.,Ltd", + [3]byte{0, 26, 66}: "Techcity Technology co., Ltd.", + [3]byte{0, 26, 67}: "Logical Link Communications", + [3]byte{0, 26, 68}: "JWTrading Co., Ltd", + [3]byte{0, 26, 69}: "GN Netcom as", + [3]byte{0, 26, 70}: "Digital Multimedia Technology Co., Ltd", + [3]byte{0, 26, 71}: "Agami Systems, Inc.", + [3]byte{0, 26, 72}: "Takacom Corporation", + [3]byte{0, 26, 73}: "Micro Vision Co.,LTD", + [3]byte{0, 26, 74}: "Qumranet Inc.", + [3]byte{0, 26, 75}: "Hewlett-Packard Company", + [3]byte{0, 26, 76}: "Crossbow Technology, Inc", + [3]byte{0, 26, 77}: "GIGA-BYTE TECHNOLOGY CO.,LTD.", + [3]byte{0, 26, 78}: "NTI AG / LinMot", + [3]byte{0, 26, 79}: "AVM GmbH", + [3]byte{0, 26, 80}: "PheeNet Technology Corp.", + [3]byte{0, 26, 81}: "Alfred Mann Foundation", + [3]byte{0, 26, 82}: "Meshlinx Wireless Inc.", + [3]byte{0, 26, 83}: "Zylaya", + [3]byte{0, 26, 84}: "Hip Shing Electronics Ltd.", + [3]byte{0, 26, 85}: "ACA-Digital Corporation", + [3]byte{0, 26, 86}: "ViewTel Co,. Ltd.", + [3]byte{0, 26, 87}: "Matrix Design Group, LLC", + [3]byte{0, 26, 88}: "CCV Deutschland GmbH - Celectronic eHealth Div.", + [3]byte{0, 26, 89}: "Ircona", + [3]byte{0, 26, 90}: "Korea Electric Power Data Network (KDN) Co., Ltd", + [3]byte{0, 26, 91}: "NetCare Service Co., Ltd.", + [3]byte{0, 26, 92}: "Euchner GmbH+Co. KG", + [3]byte{0, 26, 93}: "Mobinnova Corp.", + [3]byte{0, 26, 94}: "Thincom Technology Co.,Ltd", + [3]byte{0, 26, 95}: "KitWorks.fi Ltd.", + [3]byte{0, 26, 96}: "Wave Electronics Co.,Ltd.", + [3]byte{0, 26, 97}: "PacStar Corp.", + [3]byte{0, 26, 98}: "Data Robotics, Incorporated", + [3]byte{0, 26, 99}: "Elster Solutions, LLC,", + [3]byte{0, 26, 100}: "IBM Corp", + [3]byte{0, 26, 101}: "Seluxit", + [3]byte{0, 26, 102}: "ARRIS Group, Inc.", + [3]byte{0, 26, 103}: "Infinite QL Sdn Bhd", + [3]byte{0, 26, 104}: "Weltec Enterprise Co., Ltd.", + [3]byte{0, 26, 105}: "Wuhan Yangtze Optical Technology CO.,Ltd.", + [3]byte{0, 26, 106}: "Tranzas, Inc.", + [3]byte{0, 26, 107}: "Universal Global Scientific Industrial Co., Ltd.", + [3]byte{0, 26, 108}: "CISCO SYSTEMS, INC.", + [3]byte{0, 26, 109}: "CISCO SYSTEMS, INC.", + [3]byte{0, 26, 110}: "Impro Technologies", + [3]byte{0, 26, 111}: "MI.TEL s.r.l.", + [3]byte{0, 26, 112}: "Cisco-Linksys, LLC", + [3]byte{0, 26, 113}: "Diostech Co., Ltd.", + [3]byte{0, 26, 114}: "Mosart Semiconductor Corp.", + [3]byte{0, 26, 115}: "Gemtek Technology Co., Ltd.", + [3]byte{0, 26, 116}: "Procare International Co", + [3]byte{0, 26, 117}: "Sony Ericsson Mobile Communications", + [3]byte{0, 26, 118}: "SDT information Technology Co.,LTD.", + [3]byte{0, 26, 119}: "ARRIS Group, Inc.", + [3]byte{0, 26, 120}: "ubtos", + [3]byte{0, 26, 121}: "TELECOMUNICATION TECHNOLOGIES LTD.", + [3]byte{0, 26, 122}: "Lismore Instruments Limited", + [3]byte{0, 26, 123}: "Teleco, Inc.", + [3]byte{0, 26, 124}: "Hirschmann Multimedia B.V.", + [3]byte{0, 26, 125}: "cyber-blue(HK)Ltd", + [3]byte{0, 26, 126}: "LN Srithai Comm Ltd.", + [3]byte{0, 26, 127}: "GCI Science&Technology Co.,Ltd.", + [3]byte{0, 26, 128}: "Sony Corporation", + [3]byte{0, 26, 129}: "Zelax", + [3]byte{0, 26, 130}: "PROBA Building Automation Co.,LTD", + [3]byte{0, 26, 131}: "Pegasus Technologies Inc.", + [3]byte{0, 26, 132}: "V One Multimedia Pte Ltd", + [3]byte{0, 26, 133}: "NV Michel Van de Wiele", + [3]byte{0, 26, 134}: "AdvancedIO Systems Inc", + [3]byte{0, 26, 135}: "Canhold International Limited", + [3]byte{0, 26, 136}: "Venergy,Co,Ltd", + [3]byte{0, 26, 137}: "Nokia Danmark A/S", + [3]byte{0, 26, 138}: "Samsung Electronics Co., Ltd.", + [3]byte{0, 26, 139}: "CHUNIL ELECTRIC IND., CO.", + [3]byte{0, 26, 140}: "Sophos Ltd", + [3]byte{0, 26, 141}: "AVECS Bergen GmbH", + [3]byte{0, 26, 142}: "3Way Networks Ltd", + [3]byte{0, 26, 143}: "Nortel", + [3]byte{0, 26, 144}: "Trópico Sistemas e Telecomunicações da Amazônia LTDA.", + [3]byte{0, 26, 145}: "FusionDynamic Ltd.", + [3]byte{0, 26, 146}: "ASUSTek COMPUTER INC.", + [3]byte{0, 26, 147}: "ERCO Leuchten GmbH", + [3]byte{0, 26, 148}: "Votronic GmbH", + [3]byte{0, 26, 149}: "Hisense Mobile Communications Technoligy Co.,Ltd.", + [3]byte{0, 26, 150}: "ECLER S.A.", + [3]byte{0, 26, 151}: "fitivision technology Inc.", + [3]byte{0, 26, 152}: "Asotel Communication Limited Taiwan Branch", + [3]byte{0, 26, 153}: "Smarty (HZ) Information Electronics Co., Ltd", + [3]byte{0, 26, 154}: "Skyworth Digital technology(shenzhen)co.ltd.", + [3]byte{0, 26, 155}: "ADEC & Parter AG", + [3]byte{0, 26, 156}: "RightHand Technologies, Inc.", + [3]byte{0, 26, 157}: "Skipper Wireless, Inc.", + [3]byte{0, 26, 158}: "ICON Digital International Limited", + [3]byte{0, 26, 159}: "A-Link Ltd", + [3]byte{0, 26, 160}: "Dell Inc", + [3]byte{0, 26, 161}: "CISCO SYSTEMS, INC.", + [3]byte{0, 26, 162}: "CISCO SYSTEMS, INC.", + [3]byte{0, 26, 163}: "DELORME", + [3]byte{0, 26, 164}: "Future University-Hakodate", + [3]byte{0, 26, 165}: "BRN Phoenix", + [3]byte{0, 26, 166}: "Telefunken Radio Communication Systems GmbH &CO.KG", + [3]byte{0, 26, 167}: "Torian Wireless", + [3]byte{0, 26, 168}: "Mamiya Digital Imaging Co., Ltd.", + [3]byte{0, 26, 169}: "FUJIAN STAR-NET COMMUNICATION CO.,LTD", + [3]byte{0, 26, 170}: "Analogic Corp.", + [3]byte{0, 26, 171}: "eWings s.r.l.", + [3]byte{0, 26, 172}: "Corelatus AB", + [3]byte{0, 26, 173}: "ARRIS Group, Inc.", + [3]byte{0, 26, 174}: "Savant Systems LLC", + [3]byte{0, 26, 175}: "BLUSENS TECHNOLOGY", + [3]byte{0, 26, 176}: "Signal Networks Pvt. Ltd.,", + [3]byte{0, 26, 177}: "Asia Pacific Satellite Industries Co., Ltd.", + [3]byte{0, 26, 178}: "Cyber Solutions Inc.", + [3]byte{0, 26, 179}: "VISIONITE INC.", + [3]byte{0, 26, 180}: "FFEI Ltd.", + [3]byte{0, 26, 181}: "Home Network System", + [3]byte{0, 26, 182}: "Texas Instruments", + [3]byte{0, 26, 183}: "Ethos Networks LTD.", + [3]byte{0, 26, 184}: "Anseri Corporation", + [3]byte{0, 26, 185}: "PMC", + [3]byte{0, 26, 186}: "Caton Overseas Limited", + [3]byte{0, 26, 187}: "Fontal Technology Incorporation", + [3]byte{0, 26, 188}: "U4EA Technologies Ltd", + [3]byte{0, 26, 189}: "Impatica Inc.", + [3]byte{0, 26, 190}: "COMPUTER HI-TECH INC.", + [3]byte{0, 26, 191}: "TRUMPF Laser Marking Systems AG", + [3]byte{0, 26, 192}: "JOYBIEN TECHNOLOGIES CO., LTD.", + [3]byte{0, 26, 193}: "3Com Ltd", + [3]byte{0, 26, 194}: "YEC Co.,Ltd.", + [3]byte{0, 26, 195}: "Scientific-Atlanta, Inc", + [3]byte{0, 26, 196}: "2Wire, Inc", + [3]byte{0, 26, 197}: "BreakingPoint Systems, Inc.", + [3]byte{0, 26, 198}: "Micro Control Designs", + [3]byte{0, 26, 199}: "UNIPOINT", + [3]byte{0, 26, 200}: "ISL (Instrumentation Scientifique de Laboratoire)", + [3]byte{0, 26, 201}: "SUZUKEN CO.,LTD", + [3]byte{0, 26, 202}: "Tilera Corporation", + [3]byte{0, 26, 203}: "Autocom Products Ltd", + [3]byte{0, 26, 204}: "Celestial Semiconductor, Ltd", + [3]byte{0, 26, 205}: "Tidel Engineering LP", + [3]byte{0, 26, 206}: "YUPITERU CORPORATION", + [3]byte{0, 26, 207}: "C.T. ELETTRONICA", + [3]byte{0, 26, 208}: "Albis Technologies AG", + [3]byte{0, 26, 209}: "FARGO CO., LTD.", + [3]byte{0, 26, 210}: "Eletronica Nitron Ltda", + [3]byte{0, 26, 211}: "Vamp Ltd.", + [3]byte{0, 26, 212}: "iPOX Technology Co., Ltd.", + [3]byte{0, 26, 213}: "KMC CHAIN INDUSTRIAL CO., LTD.", + [3]byte{0, 26, 214}: "JIAGNSU AETNA ELECTRIC CO.,LTD", + [3]byte{0, 26, 215}: "Christie Digital Systems, Inc.", + [3]byte{0, 26, 216}: "AlsterAero GmbH", + [3]byte{0, 26, 217}: "International Broadband Electric Communications, Inc.", + [3]byte{0, 26, 218}: "Biz-2-Me Inc.", + [3]byte{0, 26, 219}: "ARRIS Group, Inc.", + [3]byte{0, 26, 220}: "Nokia Danmark A/S", + [3]byte{0, 26, 221}: "PePWave Ltd", + [3]byte{0, 26, 222}: "ARRIS Group, Inc.", + [3]byte{0, 26, 223}: "Interactivetv Pty Limited", + [3]byte{0, 26, 224}: "Mythology Tech Express Inc.", + [3]byte{0, 26, 225}: "EDGE ACCESS INC", + [3]byte{0, 26, 226}: "CISCO SYSTEMS, INC.", + [3]byte{0, 26, 227}: "CISCO SYSTEMS, INC.", + [3]byte{0, 26, 228}: "Medicis Technologies Corporation", + [3]byte{0, 26, 229}: "Mvox Technologies Inc.", + [3]byte{0, 26, 230}: "Atlanta Advanced Communications Holdings Limited", + [3]byte{0, 26, 231}: "Aztek Networks, Inc.", + [3]byte{0, 26, 232}: "Unify GmbH and Co KG", + [3]byte{0, 26, 233}: "Nintendo Co., Ltd.", + [3]byte{0, 26, 234}: "Radio Terminal Systems Pty Ltd", + [3]byte{0, 26, 235}: "Allied Telesis K.K.", + [3]byte{0, 26, 236}: "Keumbee Electronics Co.,Ltd.", + [3]byte{0, 26, 237}: "INCOTEC GmbH", + [3]byte{0, 26, 238}: "Shenztech Ltd", + [3]byte{0, 26, 239}: "Loopcomm Technology, Inc.", + [3]byte{0, 26, 240}: "Alcatel - IPD", + [3]byte{0, 26, 241}: "Embedded Artists AB", + [3]byte{0, 26, 242}: "Dynavisions Schweiz AG", + [3]byte{0, 26, 243}: "Samyoung Electronics", + [3]byte{0, 26, 244}: "Handreamnet", + [3]byte{0, 26, 245}: "PENTAONE. CO., LTD.", + [3]byte{0, 26, 246}: "Woven Systems, Inc.", + [3]byte{0, 26, 247}: "dataschalt e+a GmbH", + [3]byte{0, 26, 248}: "Copley Controls Corporation", + [3]byte{0, 26, 249}: "AeroVIronment (AV Inc)", + [3]byte{0, 26, 250}: "Welch Allyn, Inc.", + [3]byte{0, 26, 251}: "Joby Inc.", + [3]byte{0, 26, 252}: "ModusLink Corporation", + [3]byte{0, 26, 253}: "EVOLIS", + [3]byte{0, 26, 254}: "SOFACREAL", + [3]byte{0, 26, 255}: "Wizyoung Tech.", + [3]byte{0, 27, 0}: "Neopost Technologies", + [3]byte{0, 27, 1}: "Applied Radio Technologies", + [3]byte{0, 27, 2}: "ED Co.Ltd", + [3]byte{0, 27, 3}: "Action Technology (SZ) Co., Ltd", + [3]byte{0, 27, 4}: "Affinity International S.p.a", + [3]byte{0, 27, 5}: "YMC AG", + [3]byte{0, 27, 6}: "Ateliers R. LAUMONIER", + [3]byte{0, 27, 7}: "Mendocino Software", + [3]byte{0, 27, 8}: "Danfoss Drives A/S", + [3]byte{0, 27, 9}: "Matrix Telecom Pvt. Ltd.", + [3]byte{0, 27, 10}: "Intelligent Distributed Controls Ltd", + [3]byte{0, 27, 11}: "Phidgets Inc.", + [3]byte{0, 27, 12}: "CISCO SYSTEMS, INC.", + [3]byte{0, 27, 13}: "CISCO SYSTEMS, INC.", + [3]byte{0, 27, 14}: "InoTec GmbH Organisationssysteme", + [3]byte{0, 27, 15}: "Petratec", + [3]byte{0, 27, 16}: "ShenZhen Kang Hui Technology Co.,ltd", + [3]byte{0, 27, 17}: "D-Link Corporation", + [3]byte{0, 27, 18}: "Apprion", + [3]byte{0, 27, 19}: "Icron Technologies Corporation", + [3]byte{0, 27, 20}: "Carex Lighting Equipment Factory", + [3]byte{0, 27, 21}: "Voxtel, Inc.", + [3]byte{0, 27, 22}: "Celtro Ltd.", + [3]byte{0, 27, 23}: "Palo Alto Networks", + [3]byte{0, 27, 24}: "Tsuken Electric Ind. Co.,Ltd", + [3]byte{0, 27, 25}: "IEEE I&M Society TC9", + [3]byte{0, 27, 26}: "e-trees Japan, Inc.", + [3]byte{0, 27, 27}: "Siemens AG,", + [3]byte{0, 27, 28}: "Coherent", + [3]byte{0, 27, 29}: "Phoenix International Co., Ltd", + [3]byte{0, 27, 30}: "HART Communication Foundation", + [3]byte{0, 27, 31}: "DELTA - Danish Electronics, Light & Acoustics", + [3]byte{0, 27, 32}: "TPine Technology", + [3]byte{0, 27, 33}: "Intel Corporate", + [3]byte{0, 27, 34}: "Palit Microsystems ( H.K.) Ltd.", + [3]byte{0, 27, 35}: "SimpleComTools", + [3]byte{0, 27, 36}: "Quanta Computer Inc.", + [3]byte{0, 27, 37}: "Nortel", + [3]byte{0, 27, 38}: "RON-Telecom ZAO", + [3]byte{0, 27, 39}: "Merlin CSI", + [3]byte{0, 27, 40}: "POLYGON, JSC", + [3]byte{0, 27, 41}: "Avantis.Co.,Ltd", + [3]byte{0, 27, 42}: "CISCO SYSTEMS, INC.", + [3]byte{0, 27, 43}: "CISCO SYSTEMS, INC.", + [3]byte{0, 27, 44}: "ATRON electronic GmbH", + [3]byte{0, 27, 45}: "Med-Eng Systems Inc.", + [3]byte{0, 27, 46}: "Sinkyo Electron Inc", + [3]byte{0, 27, 47}: "NETGEAR Inc.", + [3]byte{0, 27, 48}: "Solitech Inc.", + [3]byte{0, 27, 49}: "Neural Image. Co. Ltd.", + [3]byte{0, 27, 50}: "QLogic Corporation", + [3]byte{0, 27, 51}: "Nokia Danmark A/S", + [3]byte{0, 27, 52}: "Focus System Inc.", + [3]byte{0, 27, 53}: "ChongQing JINOU Science & Technology Development CO.,Ltd", + [3]byte{0, 27, 54}: "Tsubata Engineering Co.,Ltd. (Head Office)", + [3]byte{0, 27, 55}: "Computec Oy", + [3]byte{0, 27, 56}: "COMPAL INFORMATION (KUNSHAN) CO., LTD.", + [3]byte{0, 27, 57}: "Proxicast", + [3]byte{0, 27, 58}: "SIMS Corp.", + [3]byte{0, 27, 59}: "Yi-Qing CO., LTD", + [3]byte{0, 27, 60}: "Software Technologies Group,Inc.", + [3]byte{0, 27, 61}: "EuroTel Spa", + [3]byte{0, 27, 62}: "Curtis, Inc.", + [3]byte{0, 27, 63}: "ProCurve Networking by HP", + [3]byte{0, 27, 64}: "Network Automation mxc AB", + [3]byte{0, 27, 65}: "General Infinity Co.,Ltd.", + [3]byte{0, 27, 66}: "Wise & Blue", + [3]byte{0, 27, 67}: "Beijing DG Telecommunications equipment Co.,Ltd", + [3]byte{0, 27, 68}: "SanDisk Corporation", + [3]byte{0, 27, 69}: "ABB AS, Division Automation Products", + [3]byte{0, 27, 70}: "Blueone Technology Co.,Ltd", + [3]byte{0, 27, 71}: "Futarque A/S", + [3]byte{0, 27, 72}: "Shenzhen Lantech Electronics Co., Ltd.", + [3]byte{0, 27, 73}: "Roberts Radio limited", + [3]byte{0, 27, 74}: "W&W Communications, Inc.", + [3]byte{0, 27, 75}: "SANION Co., Ltd.", + [3]byte{0, 27, 76}: "Signtech", + [3]byte{0, 27, 77}: "Areca Technology Corporation", + [3]byte{0, 27, 78}: "Navman New Zealand", + [3]byte{0, 27, 79}: "Avaya Inc.", + [3]byte{0, 27, 80}: "Nizhny Novgorod Factory named after M.Frunze, FSUE (NZiF)", + [3]byte{0, 27, 81}: "Vector Technology Corp.", + [3]byte{0, 27, 82}: "ARRIS Group, Inc.", + [3]byte{0, 27, 83}: "CISCO SYSTEMS, INC.", + [3]byte{0, 27, 84}: "CISCO SYSTEMS, INC.", + [3]byte{0, 27, 85}: "Hurco Automation Ltd.", + [3]byte{0, 27, 86}: "Tehuti Networks Ltd.", + [3]byte{0, 27, 87}: "SEMINDIA SYSTEMS PRIVATE LIMITED", + [3]byte{0, 27, 88}: "ACE CAD Enterprise Co., Ltd.", + [3]byte{0, 27, 89}: "Sony Ericsson Mobile Communications AB", + [3]byte{0, 27, 90}: "Apollo Imaging Technologies, Inc.", + [3]byte{0, 27, 91}: "2Wire, Inc.", + [3]byte{0, 27, 92}: "Azuretec Co., Ltd.", + [3]byte{0, 27, 93}: "Vololink Pty Ltd", + [3]byte{0, 27, 94}: "BPL Limited", + [3]byte{0, 27, 95}: "Alien Technology", + [3]byte{0, 27, 96}: "NAVIGON AG", + [3]byte{0, 27, 97}: "Digital Acoustics, LLC", + [3]byte{0, 27, 98}: "JHT Optoelectronics Co.,Ltd.", + [3]byte{0, 27, 99}: "Apple", + [3]byte{0, 27, 100}: "IsaacLandKorea Co., Ltd,", + [3]byte{0, 27, 101}: "China Gridcom Co., Ltd", + [3]byte{0, 27, 102}: "Sennheiser electronic GmbH & Co. KG", + [3]byte{0, 27, 103}: "Cisco Systems Inc", + [3]byte{0, 27, 104}: "Modnnet Co., Ltd", + [3]byte{0, 27, 105}: "Equaline Corporation", + [3]byte{0, 27, 106}: "Powerwave Technologies Sweden AB", + [3]byte{0, 27, 107}: "Swyx Solutions AG", + [3]byte{0, 27, 108}: "LookX Digital Media BV", + [3]byte{0, 27, 109}: "Midtronics, Inc.", + [3]byte{0, 27, 110}: "Anue Systems, Inc.", + [3]byte{0, 27, 111}: "Teletrak Ltd", + [3]byte{0, 27, 112}: "IRI Ubiteq, INC.", + [3]byte{0, 27, 113}: "Telular Corp.", + [3]byte{0, 27, 114}: "Sicep s.p.a.", + [3]byte{0, 27, 115}: "DTL Broadcast Ltd", + [3]byte{0, 27, 116}: "MiraLink Corporation", + [3]byte{0, 27, 117}: "Hypermedia Systems", + [3]byte{0, 27, 118}: "Ripcode, Inc.", + [3]byte{0, 27, 119}: "Intel Corporate", + [3]byte{0, 27, 120}: "Hewlett-Packard Company", + [3]byte{0, 27, 121}: "FAIVELEY TRANSPORT", + [3]byte{0, 27, 122}: "Nintendo Co., Ltd.", + [3]byte{0, 27, 123}: "The Tintometer Ltd", + [3]byte{0, 27, 124}: "A & R Cambridge", + [3]byte{0, 27, 125}: "CXR Anderson Jacobson", + [3]byte{0, 27, 126}: "Beckmann GmbH", + [3]byte{0, 27, 127}: "TMN Technologies Telecomunicacoes Ltda", + [3]byte{0, 27, 128}: "LORD Corporation", + [3]byte{0, 27, 129}: "DATAQ Instruments, Inc.", + [3]byte{0, 27, 130}: "Taiwan Semiconductor Co., Ltd.", + [3]byte{0, 27, 131}: "Finsoft Ltd", + [3]byte{0, 27, 132}: "Scan Engineering Telecom", + [3]byte{0, 27, 133}: "MAN Diesel SE", + [3]byte{0, 27, 134}: "Bosch Access Systems GmbH", + [3]byte{0, 27, 135}: "Deepsound Tech. Co., Ltd", + [3]byte{0, 27, 136}: "Divinet Access Technologies Ltd", + [3]byte{0, 27, 137}: "EMZA Visual Sense Ltd.", + [3]byte{0, 27, 138}: "2M Electronic A/S", + [3]byte{0, 27, 139}: "NEC Platforms, Ltd.", + [3]byte{0, 27, 140}: "JMicron Technology Corp.", + [3]byte{0, 27, 141}: "Electronic Computer Systems, Inc.", + [3]byte{0, 27, 142}: "Hulu Sweden AB", + [3]byte{0, 27, 143}: "CISCO SYSTEMS, INC.", + [3]byte{0, 27, 144}: "CISCO SYSTEMS, INC.", + [3]byte{0, 27, 145}: "EFKON AG", + [3]byte{0, 27, 146}: "l-acoustics", + [3]byte{0, 27, 147}: "JC Decaux SA DNT", + [3]byte{0, 27, 148}: "T.E.M.A. S.p.A.", + [3]byte{0, 27, 149}: "VIDEO SYSTEMS SRL", + [3]byte{0, 27, 150}: "General Sensing", + [3]byte{0, 27, 151}: "Violin Technologies", + [3]byte{0, 27, 152}: "Samsung Electronics Co., Ltd.", + [3]byte{0, 27, 153}: "KS System GmbH", + [3]byte{0, 27, 154}: "Apollo Fire Detectors Ltd", + [3]byte{0, 27, 155}: "Hose-McCann Communications", + [3]byte{0, 27, 156}: "SATEL sp. z o.o.", + [3]byte{0, 27, 157}: "Novus Security Sp. z o.o.", + [3]byte{0, 27, 158}: "ASKEY COMPUTER CORP", + [3]byte{0, 27, 159}: "Calyptech Pty Ltd", + [3]byte{0, 27, 160}: "Awox", + [3]byte{0, 27, 161}: "Åmic AB", + [3]byte{0, 27, 162}: "IDS Imaging Development Systems GmbH", + [3]byte{0, 27, 163}: "Flexit Group GmbH", + [3]byte{0, 27, 164}: "S.A.E Afikim", + [3]byte{0, 27, 165}: "MyungMin Systems, Inc.", + [3]byte{0, 27, 166}: "intotech inc.", + [3]byte{0, 27, 167}: "Lorica Solutions", + [3]byte{0, 27, 168}: "UBI&MOBI,.Inc", + [3]byte{0, 27, 169}: "BROTHER INDUSTRIES, LTD.", + [3]byte{0, 27, 170}: "XenICs nv", + [3]byte{0, 27, 171}: "Telchemy, Incorporated", + [3]byte{0, 27, 172}: "Curtiss Wright Controls Embedded Computing", + [3]byte{0, 27, 173}: "iControl Incorporated", + [3]byte{0, 27, 174}: "Micro Control Systems, Inc", + [3]byte{0, 27, 175}: "Nokia Danmark A/S", + [3]byte{0, 27, 176}: "BHARAT ELECTRONICS", + [3]byte{0, 27, 177}: "Wistron Neweb Corp.", + [3]byte{0, 27, 178}: "Intellect International NV", + [3]byte{0, 27, 179}: "Condalo GmbH", + [3]byte{0, 27, 180}: "Airvod Limited", + [3]byte{0, 27, 181}: "ZF Electronics GmbH", + [3]byte{0, 27, 182}: "Bird Electronic Corp.", + [3]byte{0, 27, 183}: "Alta Heights Technology Corp.", + [3]byte{0, 27, 184}: "BLUEWAY ELECTRONIC CO;LTD", + [3]byte{0, 27, 185}: "Elitegroup Computer System Co.", + [3]byte{0, 27, 186}: "Nortel", + [3]byte{0, 27, 187}: "RFTech Co.,Ltd", + [3]byte{0, 27, 188}: "Silver Peak Systems, Inc.", + [3]byte{0, 27, 189}: "FMC Kongsberg Subsea AS", + [3]byte{0, 27, 190}: "ICOP Digital", + [3]byte{0, 27, 191}: "SAGEM COMMUNICATION", + [3]byte{0, 27, 192}: "Juniper Networks", + [3]byte{0, 27, 193}: "HOLUX Technology, Inc.", + [3]byte{0, 27, 194}: "Integrated Control Technology Limitied", + [3]byte{0, 27, 195}: "Mobisolution Co.,Ltd", + [3]byte{0, 27, 196}: "Ultratec, Inc.", + [3]byte{0, 27, 197}: "IEEE Registration Authority", + [3]byte{0, 27, 198}: "Strato Rechenzentrum AG", + [3]byte{0, 27, 199}: "StarVedia Technology Inc.", + [3]byte{0, 27, 200}: "MIURA CO.,LTD", + [3]byte{0, 27, 201}: "FSN DISPLAY INC", + [3]byte{0, 27, 202}: "Beijing Run Technology LTD. Company", + [3]byte{0, 27, 203}: "PEMPEK SYSTEMS PTY LTD", + [3]byte{0, 27, 204}: "KINGTEK CCTV ALLIANCE CO., LTD.", + [3]byte{0, 27, 205}: "DAVISCOMMS (S) PTE LTD", + [3]byte{0, 27, 206}: "Measurement Devices Ltd", + [3]byte{0, 27, 207}: "Dataupia Corporation", + [3]byte{0, 27, 208}: "IDENTEC SOLUTIONS", + [3]byte{0, 27, 209}: "SOGESTMATIC", + [3]byte{0, 27, 210}: "ULTRA-X ASIA PACIFIC Inc.", + [3]byte{0, 27, 211}: "Panasonic Corp. AVC Company", + [3]byte{0, 27, 212}: "CISCO SYSTEMS, INC.", + [3]byte{0, 27, 213}: "CISCO SYSTEMS, INC.", + [3]byte{0, 27, 214}: "Kelvin Hughes Ltd", + [3]byte{0, 27, 215}: "Scientific Atlanta, A Cisco Company", + [3]byte{0, 27, 216}: "DVTel LTD", + [3]byte{0, 27, 217}: "Edgewater Computer Systems", + [3]byte{0, 27, 218}: "UTStarcom Inc", + [3]byte{0, 27, 219}: "Valeo VECS", + [3]byte{0, 27, 220}: "Vencer Co., Ltd.", + [3]byte{0, 27, 221}: "ARRIS Group, Inc.", + [3]byte{0, 27, 222}: "Renkus-Heinz, Inc.", + [3]byte{0, 27, 223}: "Iskra Sistemi d.d.", + [3]byte{0, 27, 224}: "TELENOT ELECTRONIC GmbH", + [3]byte{0, 27, 225}: "ViaLogy", + [3]byte{0, 27, 226}: "AhnLab,Inc.", + [3]byte{0, 27, 227}: "Health Hero Network, Inc.", + [3]byte{0, 27, 228}: "TOWNET SRL", + [3]byte{0, 27, 229}: "802automation Limited", + [3]byte{0, 27, 230}: "VR AG", + [3]byte{0, 27, 231}: "Postek Electronics Co., Ltd.", + [3]byte{0, 27, 232}: "Ultratronik GmbH", + [3]byte{0, 27, 233}: "Broadcom Corporation", + [3]byte{0, 27, 234}: "Nintendo Co., Ltd.", + [3]byte{0, 27, 235}: "DMP Electronics INC.", + [3]byte{0, 27, 236}: "Netio Technologies Co., Ltd", + [3]byte{0, 27, 237}: "Brocade Communications Systems, Inc", + [3]byte{0, 27, 238}: "Nokia Danmark A/S", + [3]byte{0, 27, 239}: "Blossoms Digital Technology Co.,Ltd.", + [3]byte{0, 27, 240}: "Value Platforms Limited", + [3]byte{0, 27, 241}: "Nanjing SilverNet Software Co., Ltd.", + [3]byte{0, 27, 242}: "KWORLD COMPUTER CO., LTD", + [3]byte{0, 27, 243}: "TRANSRADIO SenderSysteme Berlin AG", + [3]byte{0, 27, 244}: "KENWIN INDUSTRIAL(HK) LTD.", + [3]byte{0, 27, 245}: "Tellink Sistemas de Telecomunicación S.L.", + [3]byte{0, 27, 246}: "CONWISE Technology Corporation Ltd.", + [3]byte{0, 27, 247}: "Lund IP Products AB", + [3]byte{0, 27, 248}: "Digitrax Inc.", + [3]byte{0, 27, 249}: "Intellitect Water Ltd", + [3]byte{0, 27, 250}: "G.i.N. mbH", + [3]byte{0, 27, 251}: "Alps Electric Co., Ltd", + [3]byte{0, 27, 252}: "ASUSTek COMPUTER INC.", + [3]byte{0, 27, 253}: "Dignsys Inc.", + [3]byte{0, 27, 254}: "Zavio Inc.", + [3]byte{0, 27, 255}: "Millennia Media inc.", + [3]byte{0, 28, 0}: "Entry Point, LLC", + [3]byte{0, 28, 1}: "ABB Oy Drives", + [3]byte{0, 28, 2}: "Pano Logic", + [3]byte{0, 28, 3}: "Betty TV Technology AG", + [3]byte{0, 28, 4}: "Airgain, Inc.", + [3]byte{0, 28, 5}: "Nonin Medical Inc.", + [3]byte{0, 28, 6}: "Siemens Numerical Control Ltd., Nanjing", + [3]byte{0, 28, 7}: "Cwlinux Limited", + [3]byte{0, 28, 8}: "Echo360, Inc.", + [3]byte{0, 28, 9}: "SAE Electronic Co.,Ltd.", + [3]byte{0, 28, 10}: "Shenzhen AEE Technology Co.,Ltd.", + [3]byte{0, 28, 11}: "SmartAnt Telecom", + [3]byte{0, 28, 12}: "TANITA Corporation", + [3]byte{0, 28, 13}: "G-Technology, Inc.", + [3]byte{0, 28, 14}: "CISCO SYSTEMS, INC.", + [3]byte{0, 28, 15}: "CISCO SYSTEMS, INC.", + [3]byte{0, 28, 16}: "Cisco-Linksys, LLC", + [3]byte{0, 28, 17}: "ARRIS Group, Inc.", + [3]byte{0, 28, 18}: "ARRIS Group, Inc.", + [3]byte{0, 28, 19}: "OPTSYS TECHNOLOGY CO., LTD.", + [3]byte{0, 28, 20}: "VMware, Inc", + [3]byte{0, 28, 21}: "iPhotonix LLC", + [3]byte{0, 28, 22}: "ThyssenKrupp Elevator", + [3]byte{0, 28, 23}: "Nortel", + [3]byte{0, 28, 24}: "Sicert S.r.L.", + [3]byte{0, 28, 25}: "secunet Security Networks AG", + [3]byte{0, 28, 26}: "Thomas Instrumentation, Inc", + [3]byte{0, 28, 27}: "Hyperstone GmbH", + [3]byte{0, 28, 28}: "Center Communication Systems GmbH", + [3]byte{0, 28, 29}: "CHENZHOU GOSPELL DIGITAL TECHNOLOGY CO.,LTD", + [3]byte{0, 28, 30}: "emtrion GmbH", + [3]byte{0, 28, 31}: "Quest Retail Technology Pty Ltd", + [3]byte{0, 28, 32}: "CLB Benelux", + [3]byte{0, 28, 33}: "Nucsafe Inc.", + [3]byte{0, 28, 34}: "Aeris Elettronica s.r.l.", + [3]byte{0, 28, 35}: "Dell Inc", + [3]byte{0, 28, 36}: "Formosa Wireless Systems Corp.", + [3]byte{0, 28, 37}: "Hon Hai Precision Ind. Co.,Ltd.", + [3]byte{0, 28, 38}: "Hon Hai Precision Ind. Co.,Ltd.", + [3]byte{0, 28, 39}: "Sunell Electronics Co.", + [3]byte{0, 28, 40}: "Sphairon Technologies GmbH", + [3]byte{0, 28, 41}: "CORE DIGITAL ELECTRONICS CO., LTD", + [3]byte{0, 28, 42}: "Envisacor Technologies Inc.", + [3]byte{0, 28, 43}: "Alertme.com Limited", + [3]byte{0, 28, 44}: "Synapse", + [3]byte{0, 28, 45}: "FlexRadio Systems", + [3]byte{0, 28, 46}: "HPN Supply Chain", + [3]byte{0, 28, 47}: "Pfister GmbH", + [3]byte{0, 28, 48}: "Mode Lighting (UK ) Ltd.", + [3]byte{0, 28, 49}: "Mobile XP Technology Co., LTD", + [3]byte{0, 28, 50}: "Telian Corporation", + [3]byte{0, 28, 51}: "Sutron", + [3]byte{0, 28, 52}: "HUEY CHIAO INTERNATIONAL CO., LTD.", + [3]byte{0, 28, 53}: "Nokia Danmark A/S", + [3]byte{0, 28, 54}: "iNEWiT NV", + [3]byte{0, 28, 55}: "Callpod, Inc.", + [3]byte{0, 28, 56}: "Bio-Rad Laboratories, Inc.", + [3]byte{0, 28, 57}: "S Netsystems Inc.", + [3]byte{0, 28, 58}: "Element Labs, Inc.", + [3]byte{0, 28, 59}: "AmRoad Technology Inc.", + [3]byte{0, 28, 60}: "Seon Design Inc.", + [3]byte{0, 28, 61}: "WaveStorm", + [3]byte{0, 28, 62}: "ECKey Corporation", + [3]byte{0, 28, 63}: "International Police Technologies, Inc.", + [3]byte{0, 28, 64}: "VDG-Security bv", + [3]byte{0, 28, 65}: "scemtec Transponder Technology GmbH", + [3]byte{0, 28, 66}: "Parallels, Inc.", + [3]byte{0, 28, 67}: "Samsung Electronics Co.,Ltd", + [3]byte{0, 28, 68}: "Bosch Security Systems BV", + [3]byte{0, 28, 69}: "Chenbro Micom Co., Ltd.", + [3]byte{0, 28, 70}: "QTUM", + [3]byte{0, 28, 71}: "Hangzhou Hollysys Automation Co., Ltd", + [3]byte{0, 28, 72}: "WiDeFi, Inc.", + [3]byte{0, 28, 73}: "Zoltan Technology Inc.", + [3]byte{0, 28, 74}: "AVM GmbH", + [3]byte{0, 28, 75}: "Gener8, Inc.", + [3]byte{0, 28, 76}: "Petrotest Instruments", + [3]byte{0, 28, 77}: "Aplix IP Holdings Corporation", + [3]byte{0, 28, 78}: "TASA International Limited", + [3]byte{0, 28, 79}: "MACAB AB", + [3]byte{0, 28, 80}: "TCL Technoly Electronics(Huizhou)Co.,Ltd", + [3]byte{0, 28, 81}: "Celeno Communications", + [3]byte{0, 28, 82}: "VISIONEE SRL", + [3]byte{0, 28, 83}: "Synergy Lighting Controls", + [3]byte{0, 28, 84}: "Hillstone Networks Inc", + [3]byte{0, 28, 85}: "Shenzhen Kaifa Technology Co.", + [3]byte{0, 28, 86}: "Pado Systems, Inc.", + [3]byte{0, 28, 87}: "CISCO SYSTEMS, INC.", + [3]byte{0, 28, 88}: "CISCO SYSTEMS, INC.", + [3]byte{0, 28, 89}: "DEVON IT", + [3]byte{0, 28, 90}: "Advanced Relay Corporation", + [3]byte{0, 28, 91}: "Chubb Electronic Security Systems Ltd", + [3]byte{0, 28, 92}: "Integrated Medical Systems, Inc.", + [3]byte{0, 28, 93}: "Leica Microsystems", + [3]byte{0, 28, 94}: "ASTON France", + [3]byte{0, 28, 95}: "Winland Electronics, Inc.", + [3]byte{0, 28, 96}: "CSP Frontier Technologies,Inc.", + [3]byte{0, 28, 97}: "Galaxy Microsystems LImited", + [3]byte{0, 28, 98}: "LG Electronics Inc", + [3]byte{0, 28, 99}: "TRUEN", + [3]byte{0, 28, 100}: "Landis+Gyr", + [3]byte{0, 28, 101}: "JoeScan, Inc.", + [3]byte{0, 28, 102}: "UCAMP CO.,LTD", + [3]byte{0, 28, 103}: "Pumpkin Networks, Inc.", + [3]byte{0, 28, 104}: "Anhui Sun Create Electronics Co., Ltd", + [3]byte{0, 28, 105}: "Packet Vision Ltd", + [3]byte{0, 28, 106}: "Weiss Engineering Ltd.", + [3]byte{0, 28, 107}: "COVAX Co. Ltd", + [3]byte{0, 28, 108}: "Jabil Circuit (Guangzhou) Limited", + [3]byte{0, 28, 109}: "KYOHRITSU ELECTRONIC INDUSTRY CO., LTD.", + [3]byte{0, 28, 110}: "Newbury Networks, Inc.", + [3]byte{0, 28, 111}: "Emfit Ltd", + [3]byte{0, 28, 112}: "NOVACOMM LTDA", + [3]byte{0, 28, 113}: "Emergent Electronics", + [3]byte{0, 28, 114}: "Mayer & Cie GmbH & Co KG", + [3]byte{0, 28, 115}: "Arista Networks, Inc.", + [3]byte{0, 28, 116}: "Syswan Technologies Inc.", + [3]byte{0, 28, 117}: "Segnet Ltd.", + [3]byte{0, 28, 118}: "The Wandsworth Group Ltd", + [3]byte{0, 28, 119}: "Prodys", + [3]byte{0, 28, 120}: "WYPLAY SAS", + [3]byte{0, 28, 121}: "Cohesive Financial Technologies LLC", + [3]byte{0, 28, 122}: "Perfectone Netware Company Ltd", + [3]byte{0, 28, 123}: "Castlenet Technology Inc.", + [3]byte{0, 28, 124}: "PERQ SYSTEMS CORPORATION", + [3]byte{0, 28, 125}: "Excelpoint Manufacturing Pte Ltd", + [3]byte{0, 28, 126}: "Toshiba", + [3]byte{0, 28, 127}: "Check Point Software Technologies", + [3]byte{0, 28, 128}: "New Business Division/Rhea-Information CO., LTD.", + [3]byte{0, 28, 129}: "NextGen Venturi LTD", + [3]byte{0, 28, 130}: "Genew Technologies", + [3]byte{0, 28, 131}: "New Level Telecom Co., Ltd.", + [3]byte{0, 28, 132}: "STL Solution Co.,Ltd.", + [3]byte{0, 28, 133}: "Eunicorn", + [3]byte{0, 28, 134}: "Cranite Systems, Inc.", + [3]byte{0, 28, 135}: "Uriver Inc.", + [3]byte{0, 28, 136}: "TRANSYSTEM INC.", + [3]byte{0, 28, 137}: "Force Communications, Inc.", + [3]byte{0, 28, 138}: "Cirrascale Corporation", + [3]byte{0, 28, 139}: "MJ Innovations Ltd.", + [3]byte{0, 28, 140}: "DIAL TECHNOLOGY LTD.", + [3]byte{0, 28, 141}: "Mesa Imaging", + [3]byte{0, 28, 142}: "Alcatel-Lucent IPD", + [3]byte{0, 28, 143}: "Advanced Electronic Design, Inc.", + [3]byte{0, 28, 144}: "Empacket Corporation", + [3]byte{0, 28, 145}: "Gefen Inc.", + [3]byte{0, 28, 146}: "Tervela", + [3]byte{0, 28, 147}: "ExaDigm Inc", + [3]byte{0, 28, 148}: "LI-COR Biosciences", + [3]byte{0, 28, 149}: "Opticomm Corporation", + [3]byte{0, 28, 150}: "Linkwise Technology Pte Ltd", + [3]byte{0, 28, 151}: "Enzytek Technology Inc.,", + [3]byte{0, 28, 152}: "LUCKY TECHNOLOGY (HK) COMPANY LIMITED", + [3]byte{0, 28, 153}: "Shunra Software Ltd.", + [3]byte{0, 28, 154}: "Nokia Danmark A/S", + [3]byte{0, 28, 155}: "FEIG ELECTRONIC GmbH", + [3]byte{0, 28, 156}: "Nortel", + [3]byte{0, 28, 157}: "Liecthi AG", + [3]byte{0, 28, 158}: "Dualtech IT AB", + [3]byte{0, 28, 159}: "Razorstream, LLC", + [3]byte{0, 28, 160}: "Production Resource Group, LLC", + [3]byte{0, 28, 161}: "AKAMAI TECHNOLOGIES, INC.", + [3]byte{0, 28, 162}: "ADB Broadband Italia", + [3]byte{0, 28, 163}: "Terra", + [3]byte{0, 28, 164}: "Sony Ericsson Mobile Communications", + [3]byte{0, 28, 165}: "Zygo Corporation", + [3]byte{0, 28, 166}: "Win4NET", + [3]byte{0, 28, 167}: "International Quartz Limited", + [3]byte{0, 28, 168}: "AirTies Wireless Networks", + [3]byte{0, 28, 169}: "Audiomatica Srl", + [3]byte{0, 28, 170}: "Bellon Pty Ltd", + [3]byte{0, 28, 171}: "Meyer Sound Laboratories, Inc.", + [3]byte{0, 28, 172}: "Qniq Technology Corp.", + [3]byte{0, 28, 173}: "Wuhan Telecommunication Devices Co.,Ltd", + [3]byte{0, 28, 174}: "WiChorus, Inc.", + [3]byte{0, 28, 175}: "Plato Networks Inc.", + [3]byte{0, 28, 176}: "CISCO SYSTEMS, INC.", + [3]byte{0, 28, 177}: "CISCO SYSTEMS, INC.", + [3]byte{0, 28, 178}: "BPT SPA", + [3]byte{0, 28, 179}: "Apple", + [3]byte{0, 28, 180}: "Iridium Satellite LLC", + [3]byte{0, 28, 181}: "Neihua Network Technology Co.,LTD.(NHN)", + [3]byte{0, 28, 182}: "Duzon CNT Co., Ltd.", + [3]byte{0, 28, 183}: "USC DigiArk Corporation", + [3]byte{0, 28, 184}: "CBC Co., Ltd", + [3]byte{0, 28, 185}: "KWANG SUNG ELECTRONICS CO., LTD.", + [3]byte{0, 28, 186}: "VerScient, Inc.", + [3]byte{0, 28, 187}: "MusicianLink", + [3]byte{0, 28, 188}: "CastGrabber, LLC", + [3]byte{0, 28, 189}: "Ezze Mobile Tech., Inc.", + [3]byte{0, 28, 190}: "Nintendo Co., Ltd.", + [3]byte{0, 28, 191}: "Intel Corporate", + [3]byte{0, 28, 192}: "Intel Corporate", + [3]byte{0, 28, 193}: "ARRIS Group, Inc.", + [3]byte{0, 28, 194}: "Part II Research, Inc.", + [3]byte{0, 28, 195}: "Pace plc", + [3]byte{0, 28, 196}: "Hewlett-Packard Company", + [3]byte{0, 28, 197}: "3COM LTD", + [3]byte{0, 28, 198}: "ProStor Systems", + [3]byte{0, 28, 199}: "Rembrandt Technologies, LLC d/b/a REMSTREAM", + [3]byte{0, 28, 200}: "INDUSTRONIC Industrie-Electronic GmbH & Co. KG", + [3]byte{0, 28, 201}: "Kaise Electronic Technology Co., Ltd.", + [3]byte{0, 28, 202}: "Shanghai Gaozhi Science & Technology Development Co.", + [3]byte{0, 28, 203}: "Forth Corporation Public Company Limited", + [3]byte{0, 28, 204}: "Research In Motion Limited", + [3]byte{0, 28, 205}: "Alektrona Corporation", + [3]byte{0, 28, 206}: "By Techdesign", + [3]byte{0, 28, 207}: "LIMETEK", + [3]byte{0, 28, 208}: "Circleone Co.,Ltd.", + [3]byte{0, 28, 209}: "Waves Audio LTD", + [3]byte{0, 28, 210}: "King Champion (Hong Kong) Limited", + [3]byte{0, 28, 211}: "ZP Engineering SEL", + [3]byte{0, 28, 212}: "Nokia Danmark A/S", + [3]byte{0, 28, 213}: "ZeeVee, Inc.", + [3]byte{0, 28, 214}: "Nokia Danmark A/S", + [3]byte{0, 28, 215}: "Harman/Becker Automotive Systems GmbH", + [3]byte{0, 28, 216}: "BlueAnt Wireless", + [3]byte{0, 28, 217}: "GlobalTop Technology Inc.", + [3]byte{0, 28, 218}: "Exegin Technologies Limited", + [3]byte{0, 28, 219}: "CARPOINT CO.,LTD", + [3]byte{0, 28, 220}: "Custom Computer Services, Inc.", + [3]byte{0, 28, 221}: "COWBELL ENGINEERING CO., LTD.", + [3]byte{0, 28, 222}: "Interactive Multimedia eXchange Inc.", + [3]byte{0, 28, 223}: "Belkin International Inc.", + [3]byte{0, 28, 224}: "DASAN TPS", + [3]byte{0, 28, 225}: "INDRA SISTEMAS, S.A.", + [3]byte{0, 28, 226}: "Attero Tech, LLC.", + [3]byte{0, 28, 227}: "Optimedical Systems", + [3]byte{0, 28, 228}: "EleSy JSC", + [3]byte{0, 28, 229}: "MBS Electronic Systems GmbH", + [3]byte{0, 28, 230}: "INNES", + [3]byte{0, 28, 231}: "Rocon PLC Research Centre", + [3]byte{0, 28, 232}: "Cummins Inc", + [3]byte{0, 28, 233}: "Galaxy Technology Limited", + [3]byte{0, 28, 234}: "Scientific-Atlanta, Inc", + [3]byte{0, 28, 235}: "Nortel", + [3]byte{0, 28, 236}: "Mobilesoft (Aust.) Pty Ltd", + [3]byte{0, 28, 237}: "ENVIRONNEMENT SA", + [3]byte{0, 28, 238}: "SHARP Corporation", + [3]byte{0, 28, 239}: "Primax Electronics LTD", + [3]byte{0, 28, 240}: "D-Link Corporation", + [3]byte{0, 28, 241}: "SUPoX Technology Co. , LTD.", + [3]byte{0, 28, 242}: "Tenlon Technology Co.,Ltd.", + [3]byte{0, 28, 243}: "EVS BROADCAST EQUIPMENT", + [3]byte{0, 28, 244}: "Media Technology Systems Inc", + [3]byte{0, 28, 245}: "Wiseblue Technology Limited", + [3]byte{0, 28, 246}: "CISCO SYSTEMS, INC.", + [3]byte{0, 28, 247}: "AudioScience", + [3]byte{0, 28, 248}: "Parade Technologies, Ltd.", + [3]byte{0, 28, 249}: "CISCO SYSTEMS, INC.", + [3]byte{0, 28, 250}: "Alarm.com", + [3]byte{0, 28, 251}: "ARRIS Group, Inc.", + [3]byte{0, 28, 252}: "Suminet Communication Technologies (Shanghai) Co., Ltd.", + [3]byte{0, 28, 253}: "Universal Electronics", + [3]byte{0, 28, 254}: "Quartics Inc", + [3]byte{0, 28, 255}: "Napera Networks Inc", + [3]byte{0, 29, 0}: "Brivo Systems, LLC", + [3]byte{0, 29, 1}: "Neptune Digital", + [3]byte{0, 29, 2}: "Cybertech Telecom Development", + [3]byte{0, 29, 3}: "Design Solutions Inc.", + [3]byte{0, 29, 4}: "Zipit Wireless, Inc.", + [3]byte{0, 29, 5}: "Eaton Corporation", + [3]byte{0, 29, 6}: "HM Electronics, Inc.", + [3]byte{0, 29, 7}: "Shenzhen Sang Fei Consumer Communications Co.,Ltd", + [3]byte{0, 29, 8}: "JIANGSU YINHE ELECTRONICS CO., LTD", + [3]byte{0, 29, 9}: "Dell Inc", + [3]byte{0, 29, 10}: "Davis Instruments, Inc.", + [3]byte{0, 29, 11}: "Power Standards Lab", + [3]byte{0, 29, 12}: "MobileCompia", + [3]byte{0, 29, 13}: "Sony Computer Entertainment inc.", + [3]byte{0, 29, 14}: "Agapha Technology co., Ltd.", + [3]byte{0, 29, 15}: "TP-LINK Technologies Co., Ltd.", + [3]byte{0, 29, 16}: "LightHaus Logic, Inc.", + [3]byte{0, 29, 17}: "Analogue & Micro Ltd", + [3]byte{0, 29, 18}: "ROHM CO., LTD.", + [3]byte{0, 29, 19}: "NextGTV", + [3]byte{0, 29, 20}: "SPERADTONE INFORMATION TECHNOLOGY LIMITED", + [3]byte{0, 29, 21}: "Shenzhen Dolphin Electronic Co., Ltd", + [3]byte{0, 29, 22}: "SFR", + [3]byte{0, 29, 23}: "Digital Sky Corporation", + [3]byte{0, 29, 24}: "Power Innovation GmbH", + [3]byte{0, 29, 25}: "Arcadyan Technology Corporation", + [3]byte{0, 29, 26}: "OvisLink S.A.", + [3]byte{0, 29, 27}: "Sangean Electronics Inc.", + [3]byte{0, 29, 28}: "Gennet s.a.", + [3]byte{0, 29, 29}: "Inter-M Corporation", + [3]byte{0, 29, 30}: "KYUSHU TEN CO.,LTD", + [3]byte{0, 29, 31}: "Siauliu Tauro Televizoriai, JSC", + [3]byte{0, 29, 32}: "COMTREND CO.", + [3]byte{0, 29, 33}: "Alcad SL", + [3]byte{0, 29, 34}: "Foss Analytical A/S", + [3]byte{0, 29, 35}: "SENSUS", + [3]byte{0, 29, 36}: "Aclara Power-Line Systems Inc.", + [3]byte{0, 29, 37}: "Samsung Electronics Co.,Ltd", + [3]byte{0, 29, 38}: "Rockridgesound Technology Co.", + [3]byte{0, 29, 39}: "NAC-INTERCOM", + [3]byte{0, 29, 40}: "Sony Ericsson Mobile Communications AB", + [3]byte{0, 29, 41}: "Doro AB", + [3]byte{0, 29, 42}: "SHENZHEN BUL-TECH CO.,LTD.", + [3]byte{0, 29, 43}: "Wuhan Pont Technology CO. , LTD", + [3]byte{0, 29, 44}: "Wavetrend Technologies (Pty) Limited", + [3]byte{0, 29, 45}: "Pylone, Inc.", + [3]byte{0, 29, 46}: "Ruckus Wireless", + [3]byte{0, 29, 47}: "QuantumVision Corporation", + [3]byte{0, 29, 48}: "YX Wireless S.A.", + [3]byte{0, 29, 49}: "HIGHPRO INTERNATIONAL R&D CO,.LTD.", + [3]byte{0, 29, 50}: "Longkay Communication & Technology (Shanghai) Co. Ltd", + [3]byte{0, 29, 51}: "Maverick Systems Inc.", + [3]byte{0, 29, 52}: "SYRIS Technology Corp", + [3]byte{0, 29, 53}: "Viconics Electronics Inc.", + [3]byte{0, 29, 54}: "ELECTRONICS CORPORATION OF INDIA LIMITED", + [3]byte{0, 29, 55}: "Thales-Panda Transportation System", + [3]byte{0, 29, 56}: "Seagate Technology", + [3]byte{0, 29, 57}: "MOOHADIGITAL CO., LTD", + [3]byte{0, 29, 58}: "mh acoustics LLC", + [3]byte{0, 29, 59}: "Nokia Danmark A/S", + [3]byte{0, 29, 60}: "Muscle Corporation", + [3]byte{0, 29, 61}: "Avidyne Corporation", + [3]byte{0, 29, 62}: "SAKA TECHNO SCIENCE CO.,LTD", + [3]byte{0, 29, 63}: "Mitron Pty Ltd", + [3]byte{0, 29, 64}: "Intel – GE Care Innovations LLC", + [3]byte{0, 29, 65}: "Hardy Instruments", + [3]byte{0, 29, 66}: "Nortel", + [3]byte{0, 29, 67}: "Shenzhen G-link Digital Technology Co., Ltd.", + [3]byte{0, 29, 68}: "KROHNE Messtechnik GmbH", + [3]byte{0, 29, 69}: "CISCO SYSTEMS, INC.", + [3]byte{0, 29, 70}: "CISCO SYSTEMS, INC.", + [3]byte{0, 29, 71}: "Covote GmbH & Co KG", + [3]byte{0, 29, 72}: "Sensor-Technik Wiedemann GmbH", + [3]byte{0, 29, 73}: "Innovation Wireless Inc.", + [3]byte{0, 29, 74}: "Carestream Health, Inc.", + [3]byte{0, 29, 75}: "Grid Connect Inc.", + [3]byte{0, 29, 76}: "Alcatel-Lucent", + [3]byte{0, 29, 77}: "Adaptive Recognition Hungary, Inc", + [3]byte{0, 29, 78}: "TCM Mobile LLC", + [3]byte{0, 29, 79}: "Apple", + [3]byte{0, 29, 80}: "SPINETIX SA", + [3]byte{0, 29, 81}: "Babcock & Wilcox Power Generation Group, Inc", + [3]byte{0, 29, 82}: "Defzone B.V.", + [3]byte{0, 29, 83}: "S&O Electronics (Malaysia) Sdn. Bhd.", + [3]byte{0, 29, 84}: "Sunnic Technology & Merchandise INC.", + [3]byte{0, 29, 85}: "ZANTAZ, Inc", + [3]byte{0, 29, 86}: "Kramer Electronics Ltd.", + [3]byte{0, 29, 87}: "CAETEC Messtechnik", + [3]byte{0, 29, 88}: "CQ Inc", + [3]byte{0, 29, 89}: "Mitra Energy & Infrastructure", + [3]byte{0, 29, 90}: "2Wire Inc.", + [3]byte{0, 29, 91}: "Tecvan Informática Ltda", + [3]byte{0, 29, 92}: "Tom Communication Industrial Co.,Ltd.", + [3]byte{0, 29, 93}: "Control Dynamics Pty. Ltd.", + [3]byte{0, 29, 94}: "COMING MEDIA CORP.", + [3]byte{0, 29, 95}: "OverSpeed SARL", + [3]byte{0, 29, 96}: "ASUSTek COMPUTER INC.", + [3]byte{0, 29, 97}: "BIJ Corporation", + [3]byte{0, 29, 98}: "InPhase Technologies", + [3]byte{0, 29, 99}: "Miele & Cie. KG", + [3]byte{0, 29, 100}: "Adam Communications Systems Int Ltd", + [3]byte{0, 29, 101}: "Microwave Radio Communications", + [3]byte{0, 29, 102}: "Hyundai Telecom", + [3]byte{0, 29, 103}: "AMEC", + [3]byte{0, 29, 104}: "Thomson Telecom Belgium", + [3]byte{0, 29, 105}: "Knorr-Bremse IT-Services GmbH", + [3]byte{0, 29, 106}: "Alpha Networks Inc.", + [3]byte{0, 29, 107}: "ARRIS Group, Inc.", + [3]byte{0, 29, 108}: "ClariPhy Communications, Inc.", + [3]byte{0, 29, 109}: "Confidant International LLC", + [3]byte{0, 29, 110}: "Nokia Danmark A/S", + [3]byte{0, 29, 111}: "Chainzone Technology Co., Ltd", + [3]byte{0, 29, 112}: "CISCO SYSTEMS, INC.", + [3]byte{0, 29, 113}: "CISCO SYSTEMS, INC.", + [3]byte{0, 29, 114}: "Wistron Corporation", + [3]byte{0, 29, 115}: "Buffalo Inc.", + [3]byte{0, 29, 116}: "Tianjin China-Silicon Microelectronics Co., Ltd.", + [3]byte{0, 29, 117}: "Radioscape PLC", + [3]byte{0, 29, 118}: "Eyeheight Ltd.", + [3]byte{0, 29, 119}: "NSGate", + [3]byte{0, 29, 120}: "Invengo Information Technology Co.,Ltd", + [3]byte{0, 29, 121}: "SIGNAMAX LLC", + [3]byte{0, 29, 122}: "Wideband Semiconductor, Inc.", + [3]byte{0, 29, 123}: "Ice Energy, Inc.", + [3]byte{0, 29, 124}: "ABE Elettronica S.p.A.", + [3]byte{0, 29, 125}: "GIGA-BYTE TECHNOLOGY CO.,LTD.", + [3]byte{0, 29, 126}: "Cisco-Linksys, LLC", + [3]byte{0, 29, 127}: "Tekron International Ltd", + [3]byte{0, 29, 128}: "Beijing Huahuan Eletronics Co.,Ltd", + [3]byte{0, 29, 129}: "GUANGZHOU GATEWAY ELECTRONICS CO., LTD", + [3]byte{0, 29, 130}: "GN A/S (GN Netcom A/S)", + [3]byte{0, 29, 131}: "Emitech Corporation", + [3]byte{0, 29, 132}: "Gateway, Inc.", + [3]byte{0, 29, 133}: "Call Direct Cellular Solutions", + [3]byte{0, 29, 134}: "Shinwa Industries(China) Ltd.", + [3]byte{0, 29, 135}: "VigTech Labs Sdn Bhd", + [3]byte{0, 29, 136}: "Clearwire", + [3]byte{0, 29, 137}: "VaultStor Corporation", + [3]byte{0, 29, 138}: "TechTrex Inc", + [3]byte{0, 29, 139}: "ADB Broadband Italia", + [3]byte{0, 29, 140}: "La Crosse Technology LTD", + [3]byte{0, 29, 141}: "Raytek GmbH", + [3]byte{0, 29, 142}: "Alereon, Inc.", + [3]byte{0, 29, 143}: "PureWave Networks", + [3]byte{0, 29, 144}: "EMCO Flow Systems", + [3]byte{0, 29, 145}: "Digitize, Inc", + [3]byte{0, 29, 146}: "MICRO-STAR INT'L CO.,LTD.", + [3]byte{0, 29, 147}: "Modacom", + [3]byte{0, 29, 148}: "Climax Technology Co., Ltd", + [3]byte{0, 29, 149}: "Flash, Inc.", + [3]byte{0, 29, 150}: "WatchGuard Video", + [3]byte{0, 29, 151}: "Alertus Technologies LLC", + [3]byte{0, 29, 152}: "Nokia Danmark A/S", + [3]byte{0, 29, 153}: "Cyan Optic, Inc.", + [3]byte{0, 29, 154}: "GODEX INTERNATIONAL CO., LTD", + [3]byte{0, 29, 155}: "Hokuyo Automatic Co., Ltd.", + [3]byte{0, 29, 156}: "Rockwell Automation", + [3]byte{0, 29, 157}: "ARTJOY INTERNATIONAL LIMITED", + [3]byte{0, 29, 158}: "AXION TECHNOLOGIES", + [3]byte{0, 29, 159}: "MATT R.P.Traczynscy Sp.J.", + [3]byte{0, 29, 160}: "Heng Yu Electronic Manufacturing Company Limited", + [3]byte{0, 29, 161}: "CISCO SYSTEMS, INC.", + [3]byte{0, 29, 162}: "CISCO SYSTEMS, INC.", + [3]byte{0, 29, 163}: "SabiOso", + [3]byte{0, 29, 164}: "Hangzhou System Technology CO., LTD", + [3]byte{0, 29, 165}: "WB Electronics", + [3]byte{0, 29, 166}: "Media Numerics Limited", + [3]byte{0, 29, 167}: "Seamless Internet", + [3]byte{0, 29, 168}: "Takahata Electronics Co.,Ltd", + [3]byte{0, 29, 169}: "Castles Technology, Co., LTD", + [3]byte{0, 29, 170}: "DrayTek Corp.", + [3]byte{0, 29, 171}: "SwissQual License AG", + [3]byte{0, 29, 172}: "Gigamon Systems LLC", + [3]byte{0, 29, 173}: "Sinotech Engineering Consultants, Inc. Geotechnical Enginee", + [3]byte{0, 29, 174}: "CHANG TSENG TECHNOLOGY CO., LTD", + [3]byte{0, 29, 175}: "Nortel", + [3]byte{0, 29, 176}: "FuJian HengTong Information Technology Co.,Ltd", + [3]byte{0, 29, 177}: "Crescendo Networks", + [3]byte{0, 29, 178}: "HOKKAIDO ELECTRIC ENGINEERING CO.,LTD.", + [3]byte{0, 29, 179}: "HPN Supply Chain", + [3]byte{0, 29, 180}: "KUMHO ENG CO.,LTD", + [3]byte{0, 29, 181}: "Juniper networks", + [3]byte{0, 29, 182}: "BestComm Networks, Inc.", + [3]byte{0, 29, 183}: "Tendril Networks, Inc.", + [3]byte{0, 29, 184}: "Intoto Inc.", + [3]byte{0, 29, 185}: "Wellspring Wireless", + [3]byte{0, 29, 186}: "Sony Corporation", + [3]byte{0, 29, 187}: "Dynamic System Electronics Corp.", + [3]byte{0, 29, 188}: "Nintendo Co., Ltd.", + [3]byte{0, 29, 189}: "Versamed Inc.", + [3]byte{0, 29, 190}: "ARRIS Group, Inc.", + [3]byte{0, 29, 191}: "Radiient Technologies, Inc.", + [3]byte{0, 29, 192}: "Enphase Energy", + [3]byte{0, 29, 193}: "Audinate Pty L", + [3]byte{0, 29, 194}: "XORTEC OY", + [3]byte{0, 29, 195}: "RIKOR TV, Ltd", + [3]byte{0, 29, 196}: "AIOI Systems Co., Ltd.", + [3]byte{0, 29, 197}: "Beijing Jiaxun Feihong Electricial Co., Ltd.", + [3]byte{0, 29, 198}: "SNR Inc.", + [3]byte{0, 29, 199}: "L-3 Communications Geneva Aerospace", + [3]byte{0, 29, 200}: "Navionics Research Inc., dba SCADAmetrics", + [3]byte{0, 29, 201}: "GainSpan Corp.", + [3]byte{0, 29, 202}: "PAV Electronics Limited", + [3]byte{0, 29, 203}: "Exéns Development Oy", + [3]byte{0, 29, 204}: "Hetra Secure Solutions", + [3]byte{0, 29, 205}: "ARRIS Group, Inc.", + [3]byte{0, 29, 206}: "ARRIS Group, Inc.", + [3]byte{0, 29, 207}: "ARRIS Group, Inc.", + [3]byte{0, 29, 208}: "ARRIS Group, Inc.", + [3]byte{0, 29, 209}: "ARRIS Group, Inc.", + [3]byte{0, 29, 210}: "ARRIS Group, Inc.", + [3]byte{0, 29, 211}: "ARRIS Group, Inc.", + [3]byte{0, 29, 212}: "ARRIS Group, Inc.", + [3]byte{0, 29, 213}: "ARRIS Group, Inc.", + [3]byte{0, 29, 214}: "ARRIS Group, Inc.", + [3]byte{0, 29, 215}: "Algolith", + [3]byte{0, 29, 216}: "Microsoft Corporation", + [3]byte{0, 29, 217}: "Hon Hai Precision Ind.Co.,Ltd.", + [3]byte{0, 29, 218}: "Mikroelektronika spol. s r. o.", + [3]byte{0, 29, 219}: "C-BEL Corporation", + [3]byte{0, 29, 220}: "HangZhou DeChangLong Tech&Info Co.,Ltd", + [3]byte{0, 29, 221}: "DAT H.K. LIMITED", + [3]byte{0, 29, 222}: "Zhejiang Broadcast&Television Technology Co.,Ltd.", + [3]byte{0, 29, 223}: "Sunitec Enterprise Co., Ltd.", + [3]byte{0, 29, 224}: "Intel Corporate", + [3]byte{0, 29, 225}: "Intel Corporate", + [3]byte{0, 29, 226}: "Radionor Communications", + [3]byte{0, 29, 227}: "Intuicom", + [3]byte{0, 29, 228}: "Visioneered Image Systems", + [3]byte{0, 29, 229}: "CISCO SYSTEMS, INC.", + [3]byte{0, 29, 230}: "CISCO SYSTEMS, INC.", + [3]byte{0, 29, 231}: "Marine Sonic Technology, Ltd.", + [3]byte{0, 29, 232}: "Nikko Denki Tsushin Corporation(NDTC)", + [3]byte{0, 29, 233}: "Nokia Danmark A/S", + [3]byte{0, 29, 234}: "Commtest Instruments Ltd", + [3]byte{0, 29, 235}: "DINEC International", + [3]byte{0, 29, 236}: "Marusys", + [3]byte{0, 29, 237}: "Grid Net, Inc.", + [3]byte{0, 29, 238}: "NEXTVISION SISTEMAS DIGITAIS DE TELEVISÃO LTDA.", + [3]byte{0, 29, 239}: "TRIMM, INC.", + [3]byte{0, 29, 240}: "Vidient Systems, Inc.", + [3]byte{0, 29, 241}: "Intego Systems, Inc.", + [3]byte{0, 29, 242}: "Netflix, Inc.", + [3]byte{0, 29, 243}: "SBS Science & Technology Co., Ltd", + [3]byte{0, 29, 244}: "Magellan Technology Pty Limited", + [3]byte{0, 29, 245}: "Sunshine Co,LTD", + [3]byte{0, 29, 246}: "Samsung Electronics Co.,Ltd", + [3]byte{0, 29, 247}: "R. STAHL Schaltgeräte GmbH", + [3]byte{0, 29, 248}: "Webpro Vision Technology Corporation", + [3]byte{0, 29, 249}: "Cybiotronics (Far East) Limited", + [3]byte{0, 29, 250}: "Fujian LANDI Commercial Equipment Co.,Ltd", + [3]byte{0, 29, 251}: "NETCLEUS Systems Corporation", + [3]byte{0, 29, 252}: "KSIC", + [3]byte{0, 29, 253}: "Nokia Danmark A/S", + [3]byte{0, 29, 254}: "Palm, Inc", + [3]byte{0, 29, 255}: "Network Critical Solutions Ltd", + [3]byte{0, 30, 0}: "Shantou Institute of Ultrasonic Instruments", + [3]byte{0, 30, 1}: "Renesas Technology Sales Co., Ltd.", + [3]byte{0, 30, 2}: "Sougou Keikaku Kougyou Co.,Ltd.", + [3]byte{0, 30, 3}: "LiComm Co., Ltd.", + [3]byte{0, 30, 4}: "Hanson Research Corporation", + [3]byte{0, 30, 5}: "Xseed Technologies & Computing", + [3]byte{0, 30, 6}: "WIBRAIN", + [3]byte{0, 30, 7}: "Winy Technology Co., Ltd.", + [3]byte{0, 30, 8}: "Centec Networks Inc", + [3]byte{0, 30, 9}: "ZEFATEK Co.,LTD", + [3]byte{0, 30, 10}: "Syba Tech Limited", + [3]byte{0, 30, 11}: "Hewlett-Packard Company", + [3]byte{0, 30, 12}: "Sherwood Information Partners, Inc.", + [3]byte{0, 30, 13}: "Micran Ltd.", + [3]byte{0, 30, 14}: "MAXI VIEW HOLDINGS LIMITED", + [3]byte{0, 30, 15}: "Briot International", + [3]byte{0, 30, 16}: "ShenZhen Huawei Communication Technologies Co.,Ltd.", + [3]byte{0, 30, 17}: "ELELUX INTERNATIONAL LTD", + [3]byte{0, 30, 18}: "Ecolab", + [3]byte{0, 30, 19}: "CISCO SYSTEMS, INC.", + [3]byte{0, 30, 20}: "CISCO SYSTEMS, INC.", + [3]byte{0, 30, 21}: "Beech Hill Electronics", + [3]byte{0, 30, 22}: "Keytronix", + [3]byte{0, 30, 23}: "STN BV", + [3]byte{0, 30, 24}: "Radio Activity srl", + [3]byte{0, 30, 25}: "GTRI", + [3]byte{0, 30, 26}: "Best Source Taiwan Inc.", + [3]byte{0, 30, 27}: "Digital Stream Technology, Inc.", + [3]byte{0, 30, 28}: "SWS Australia Pty Limited", + [3]byte{0, 30, 29}: "East Coast Datacom, Inc.", + [3]byte{0, 30, 30}: "Honeywell Life Safety", + [3]byte{0, 30, 31}: "Nortel", + [3]byte{0, 30, 32}: "Intertain Inc.", + [3]byte{0, 30, 33}: "Qisda Co.", + [3]byte{0, 30, 34}: "ARVOO Imaging Products BV", + [3]byte{0, 30, 35}: "Electronic Educational Devices, Inc", + [3]byte{0, 30, 36}: "Zhejiang Bell Technology Co.,ltd", + [3]byte{0, 30, 37}: "Intek Digital Inc", + [3]byte{0, 30, 38}: "Digifriends Co. Ltd", + [3]byte{0, 30, 39}: "SBN TECH Co.,Ltd.", + [3]byte{0, 30, 40}: "Lumexis Corporation", + [3]byte{0, 30, 41}: "Hypertherm Inc", + [3]byte{0, 30, 42}: "Netgear Inc.", + [3]byte{0, 30, 43}: "Radio Systems Design, Inc.", + [3]byte{0, 30, 44}: "CyVerse Corporation", + [3]byte{0, 30, 45}: "STIM", + [3]byte{0, 30, 46}: "SIRTI S.p.A.", + [3]byte{0, 30, 47}: "DiMoto Pty Ltd", + [3]byte{0, 30, 48}: "Shireen Inc", + [3]byte{0, 30, 49}: "INFOMARK CO.,LTD.", + [3]byte{0, 30, 50}: "Zensys", + [3]byte{0, 30, 51}: "Inventec Corporation", + [3]byte{0, 30, 52}: "CryptoMetrics", + [3]byte{0, 30, 53}: "Nintendo Co., Ltd.", + [3]byte{0, 30, 54}: "IPTE", + [3]byte{0, 30, 55}: "Universal Global Scientific Industrial Co., Ltd.", + [3]byte{0, 30, 56}: "Bluecard Software Technology Co., Ltd.", + [3]byte{0, 30, 57}: "Comsys Communication Ltd.", + [3]byte{0, 30, 58}: "Nokia Danmark A/S", + [3]byte{0, 30, 59}: "Nokia Danmark A/S", + [3]byte{0, 30, 60}: "Lyngbox Media AB", + [3]byte{0, 30, 61}: "Alps Electric Co., Ltd", + [3]byte{0, 30, 62}: "KMW Inc.", + [3]byte{0, 30, 63}: "TrellisWare Technologies, Inc.", + [3]byte{0, 30, 64}: "Shanghai DareGlobal Technologies Co.,Ltd.", + [3]byte{0, 30, 65}: "Microwave Communication & Component, Inc.", + [3]byte{0, 30, 66}: "Teltonika", + [3]byte{0, 30, 67}: "AISIN AW CO.,LTD.", + [3]byte{0, 30, 68}: "SANTEC", + [3]byte{0, 30, 69}: "Sony Ericsson Mobile Communications AB", + [3]byte{0, 30, 70}: "ARRIS Group, Inc.", + [3]byte{0, 30, 71}: "PT. Hariff Daya Tunggal Engineering", + [3]byte{0, 30, 72}: "Wi-Links", + [3]byte{0, 30, 73}: "CISCO SYSTEMS, INC.", + [3]byte{0, 30, 74}: "CISCO SYSTEMS, INC.", + [3]byte{0, 30, 75}: "City Theatrical", + [3]byte{0, 30, 76}: "Hon Hai Precision Ind.Co., Ltd.", + [3]byte{0, 30, 77}: "Welkin Sciences, LLC", + [3]byte{0, 30, 78}: "DAKO EDV-Ingenieur- und Systemhaus GmbH", + [3]byte{0, 30, 79}: "Dell Inc.", + [3]byte{0, 30, 80}: "BATTISTONI RESEARCH", + [3]byte{0, 30, 81}: "Converter Industry Srl", + [3]byte{0, 30, 82}: "Apple", + [3]byte{0, 30, 83}: "Further Tech Co., LTD", + [3]byte{0, 30, 84}: "TOYO ELECTRIC Corporation", + [3]byte{0, 30, 85}: "COWON SYSTEMS,Inc.", + [3]byte{0, 30, 86}: "Bally Wulff Entertainment GmbH", + [3]byte{0, 30, 87}: "ALCOMA, spol. s r.o.", + [3]byte{0, 30, 88}: "D-Link Corporation", + [3]byte{0, 30, 89}: "Silicon Turnkey Express, LLC", + [3]byte{0, 30, 90}: "ARRIS Group, Inc.", + [3]byte{0, 30, 91}: "Unitron Company, Inc.", + [3]byte{0, 30, 92}: "RB GeneralEkonomik", + [3]byte{0, 30, 93}: "Holosys d.o.o.", + [3]byte{0, 30, 94}: "COmputime Ltd.", + [3]byte{0, 30, 95}: "KwikByte, LLC", + [3]byte{0, 30, 96}: "Digital Lighting Systems, Inc", + [3]byte{0, 30, 97}: "ITEC GmbH", + [3]byte{0, 30, 98}: "Siemon", + [3]byte{0, 30, 99}: "Vibro-Meter SA", + [3]byte{0, 30, 100}: "Intel Corporate", + [3]byte{0, 30, 101}: "Intel Corporate", + [3]byte{0, 30, 102}: "RESOL Elektronische Regelungen GmbH", + [3]byte{0, 30, 103}: "Intel Corporate", + [3]byte{0, 30, 104}: "Quanta Computer", + [3]byte{0, 30, 105}: "Thomson Inc.", + [3]byte{0, 30, 106}: "Beijing Bluexon Technology Co.,Ltd", + [3]byte{0, 30, 107}: "Cisco SPVTG", + [3]byte{0, 30, 108}: "Opaque Systems", + [3]byte{0, 30, 109}: "IT R&D Center", + [3]byte{0, 30, 110}: "Shenzhen First Mile Communications Ltd", + [3]byte{0, 30, 111}: "Magna-Power Electronics, Inc.", + [3]byte{0, 30, 112}: "Cobham Defence Communications Ltd", + [3]byte{0, 30, 113}: "MIrcom Group of Companies", + [3]byte{0, 30, 114}: "PCS", + [3]byte{0, 30, 115}: "ZTE CORPORATION", + [3]byte{0, 30, 116}: "SAGEM COMMUNICATION", + [3]byte{0, 30, 117}: "LG Electronics", + [3]byte{0, 30, 118}: "Thermo Fisher Scientific", + [3]byte{0, 30, 119}: "Air2App", + [3]byte{0, 30, 120}: "Owitek Technology Ltd.,", + [3]byte{0, 30, 121}: "CISCO SYSTEMS, INC.", + [3]byte{0, 30, 122}: "CISCO SYSTEMS, INC.", + [3]byte{0, 30, 123}: "R.I.CO. S.r.l.", + [3]byte{0, 30, 124}: "Taiwick Limited", + [3]byte{0, 30, 125}: "Samsung Electronics Co.,Ltd", + [3]byte{0, 30, 126}: "Nortel", + [3]byte{0, 30, 127}: "CBM of America", + [3]byte{0, 30, 128}: "Last Mile Ltd.", + [3]byte{0, 30, 129}: "CNB Technology Inc.", + [3]byte{0, 30, 130}: "SanDisk Corporation", + [3]byte{0, 30, 131}: "LAN/MAN Standards Association (LMSC)", + [3]byte{0, 30, 132}: "Pika Technologies Inc.", + [3]byte{0, 30, 133}: "Lagotek Corporation", + [3]byte{0, 30, 134}: "MEL Co.,Ltd.", + [3]byte{0, 30, 135}: "Realease Limited", + [3]byte{0, 30, 136}: "ANDOR SYSTEM SUPPORT CO., LTD.", + [3]byte{0, 30, 137}: "CRFS Limited", + [3]byte{0, 30, 138}: "eCopy, Inc", + [3]byte{0, 30, 139}: "Infra Access Korea Co., Ltd.", + [3]byte{0, 30, 140}: "ASUSTek COMPUTER INC.", + [3]byte{0, 30, 141}: "ARRIS Group, Inc.", + [3]byte{0, 30, 142}: "Hunkeler AG", + [3]byte{0, 30, 143}: "CANON INC.", + [3]byte{0, 30, 144}: "Elitegroup Computer Systems Co", + [3]byte{0, 30, 145}: "KIMIN Electronic Co., Ltd.", + [3]byte{0, 30, 146}: "JEULIN S.A.", + [3]byte{0, 30, 147}: "CiriTech Systems Inc", + [3]byte{0, 30, 148}: "SUPERCOM TECHNOLOGY CORPORATION", + [3]byte{0, 30, 149}: "SIGMALINK", + [3]byte{0, 30, 150}: "Sepura Plc", + [3]byte{0, 30, 151}: "Medium Link System Technology CO., LTD,", + [3]byte{0, 30, 152}: "GreenLine Communications", + [3]byte{0, 30, 153}: "Vantanol Industrial Corporation", + [3]byte{0, 30, 154}: "HAMILTON Bonaduz AG", + [3]byte{0, 30, 155}: "San-Eisha, Ltd.", + [3]byte{0, 30, 156}: "Fidustron INC", + [3]byte{0, 30, 157}: "Recall Technologies, Inc.", + [3]byte{0, 30, 158}: "ddm hopt + schuler Gmbh + Co. KG", + [3]byte{0, 30, 159}: "Visioneering Systems, Inc.", + [3]byte{0, 30, 160}: "XLN-t", + [3]byte{0, 30, 161}: "Brunata a/s", + [3]byte{0, 30, 162}: "Symx Systems, Inc.", + [3]byte{0, 30, 163}: "Nokia Danmark A/S", + [3]byte{0, 30, 164}: "Nokia Danmark A/S", + [3]byte{0, 30, 165}: "ROBOTOUS, Inc.", + [3]byte{0, 30, 166}: "Best IT World (India) Pvt. Ltd.", + [3]byte{0, 30, 167}: "ActionTec Electronics, Inc", + [3]byte{0, 30, 168}: "Datang Mobile Communications Equipment CO.,LTD", + [3]byte{0, 30, 169}: "Nintendo Co., Ltd.", + [3]byte{0, 30, 170}: "E-Senza Technologies GmbH", + [3]byte{0, 30, 171}: "TeleWell Oy", + [3]byte{0, 30, 172}: "Armadeus Systems", + [3]byte{0, 30, 173}: "Wingtech Group Limited", + [3]byte{0, 30, 174}: "Continental Automotive Systems", + [3]byte{0, 30, 175}: "Ophir Optronics Ltd", + [3]byte{0, 30, 176}: "ImesD Electronica S.L.", + [3]byte{0, 30, 177}: "Cryptsoft Pty Ltd", + [3]byte{0, 30, 178}: "LG innotek", + [3]byte{0, 30, 179}: "Primex Wireless", + [3]byte{0, 30, 180}: "UNIFAT TECHNOLOGY LTD.", + [3]byte{0, 30, 181}: "Ever Sparkle Technologies Ltd", + [3]byte{0, 30, 182}: "TAG Heuer SA", + [3]byte{0, 30, 183}: "TBTech, Co., Ltd.", + [3]byte{0, 30, 184}: "Fortis, Inc.", + [3]byte{0, 30, 185}: "Sing Fai Technology Limited", + [3]byte{0, 30, 186}: "High Density Devices AS", + [3]byte{0, 30, 187}: "BLUELIGHT TECHNOLOGY INC.", + [3]byte{0, 30, 188}: "WINTECH AUTOMATION CO.,LTD.", + [3]byte{0, 30, 189}: "CISCO SYSTEMS, INC.", + [3]byte{0, 30, 190}: "CISCO SYSTEMS, INC.", + [3]byte{0, 30, 191}: "Haas Automation Inc.", + [3]byte{0, 30, 192}: "Microchip Technology Inc.", + [3]byte{0, 30, 193}: "3COM EUROPE LTD", + [3]byte{0, 30, 194}: "Apple", + [3]byte{0, 30, 195}: "Kozio, Inc.", + [3]byte{0, 30, 196}: "Celio Corp", + [3]byte{0, 30, 197}: "Middle Atlantic Products Inc", + [3]byte{0, 30, 198}: "Obvius Holdings LLC", + [3]byte{0, 30, 199}: "2Wire, Inc.", + [3]byte{0, 30, 200}: "Rapid Mobile (Pty) Ltd", + [3]byte{0, 30, 201}: "Dell Inc", + [3]byte{0, 30, 202}: "Nortel", + [3]byte{0, 30, 203}: "\"RPC \"Energoautomatika\" Ltd", + [3]byte{0, 30, 204}: "CDVI", + [3]byte{0, 30, 205}: "KYLAND Technology Co. LTD", + [3]byte{0, 30, 206}: "BISA Technologies (Hong Kong) Limited", + [3]byte{0, 30, 207}: "PHILIPS ELECTRONICS UK LTD", + [3]byte{0, 30, 208}: "Ingespace", + [3]byte{0, 30, 209}: "Keyprocessor B.V.", + [3]byte{0, 30, 210}: "Ray Shine Video Technology Inc", + [3]byte{0, 30, 211}: "Dot Technology Int'l Co., Ltd.", + [3]byte{0, 30, 212}: "Doble Engineering", + [3]byte{0, 30, 213}: "Tekon-Automatics", + [3]byte{0, 30, 214}: "Alentec & Orion AB", + [3]byte{0, 30, 215}: "H-Stream Wireless, Inc.", + [3]byte{0, 30, 216}: "Digital United Inc.", + [3]byte{0, 30, 217}: "Mitsubishi Precision Co.,LTd.", + [3]byte{0, 30, 218}: "Wesemann Elektrotechniek B.V.", + [3]byte{0, 30, 219}: "Giken Trastem Co., Ltd.", + [3]byte{0, 30, 220}: "Sony Ericsson Mobile Communications AB", + [3]byte{0, 30, 221}: "WASKO S.A.", + [3]byte{0, 30, 222}: "BYD COMPANY LIMITED", + [3]byte{0, 30, 223}: "Master Industrialization Center Kista", + [3]byte{0, 30, 224}: "Urmet Domus SpA", + [3]byte{0, 30, 225}: "Samsung Electronics Co.,Ltd", + [3]byte{0, 30, 226}: "Samsung Electronics Co.,Ltd", + [3]byte{0, 30, 227}: "T&W Electronics (ShenZhen) Co.,Ltd", + [3]byte{0, 30, 228}: "ACS Solutions France", + [3]byte{0, 30, 229}: "Cisco-Linksys, LLC", + [3]byte{0, 30, 230}: "Shenzhen Advanced Video Info-Tech Co., Ltd.", + [3]byte{0, 30, 231}: "Epic Systems Inc", + [3]byte{0, 30, 232}: "Mytek", + [3]byte{0, 30, 233}: "Stoneridge Electronics AB", + [3]byte{0, 30, 234}: "Sensor Switch, Inc.", + [3]byte{0, 30, 235}: "Talk-A-Phone Co.", + [3]byte{0, 30, 236}: "COMPAL INFORMATION (KUNSHAN) CO., LTD.", + [3]byte{0, 30, 237}: "Adventiq Ltd.", + [3]byte{0, 30, 238}: "ETL Systems Ltd", + [3]byte{0, 30, 239}: "Cantronic International Limited", + [3]byte{0, 30, 240}: "Gigafin Networks", + [3]byte{0, 30, 241}: "Servimat", + [3]byte{0, 30, 242}: "Micro Motion Inc", + [3]byte{0, 30, 243}: "From2", + [3]byte{0, 30, 244}: "L-3 Communications Display Systems", + [3]byte{0, 30, 245}: "Hitek Automated Inc.", + [3]byte{0, 30, 246}: "CISCO SYSTEMS, INC.", + [3]byte{0, 30, 247}: "CISCO SYSTEMS, INC.", + [3]byte{0, 30, 248}: "Emfinity Inc.", + [3]byte{0, 30, 249}: "Pascom Kommunikations systeme GmbH.", + [3]byte{0, 30, 250}: "PROTEI Ltd.", + [3]byte{0, 30, 251}: "Trio Motion Technology Ltd", + [3]byte{0, 30, 252}: "JSC \"MASSA-K\"", + [3]byte{0, 30, 253}: "Microbit 2.0 AB", + [3]byte{0, 30, 254}: "LEVEL s.r.o.", + [3]byte{0, 30, 255}: "Mueller-Elektronik GmbH & Co. KG", + [3]byte{0, 31, 0}: "Nokia Danmark A/S", + [3]byte{0, 31, 1}: "Nokia Danmark A/S", + [3]byte{0, 31, 2}: "Pixelmetrix Corporation Pte Ltd", + [3]byte{0, 31, 3}: "NUM AG", + [3]byte{0, 31, 4}: "Granch Ltd.", + [3]byte{0, 31, 5}: "iTAS Technology Corp.", + [3]byte{0, 31, 6}: "Integrated Dispatch Solutions", + [3]byte{0, 31, 7}: "AZTEQ Mobile", + [3]byte{0, 31, 8}: "RISCO LTD", + [3]byte{0, 31, 9}: "JASTEC CO., LTD.", + [3]byte{0, 31, 10}: "Nortel", + [3]byte{0, 31, 11}: "Federal State Unitary Enterprise Industrial Union\"Electropribor\"", + [3]byte{0, 31, 12}: "Intelligent Digital Services GmbH", + [3]byte{0, 31, 13}: "L3 Communications - Telemetry West", + [3]byte{0, 31, 14}: "Japan Kyastem Co., Ltd", + [3]byte{0, 31, 15}: "Select Engineered Systems", + [3]byte{0, 31, 16}: "TOLEDO DO BRASIL INDUSTRIA DE BALANCAS LTDA", + [3]byte{0, 31, 17}: "OPENMOKO, INC.", + [3]byte{0, 31, 18}: "Juniper Networks", + [3]byte{0, 31, 19}: "S.& A.S. Ltd.", + [3]byte{0, 31, 20}: "NexG", + [3]byte{0, 31, 21}: "Bioscrypt Inc", + [3]byte{0, 31, 22}: "Wistron Corporation", + [3]byte{0, 31, 23}: "IDX Company, Ltd.", + [3]byte{0, 31, 24}: "Hakusan.Mfg.Co,.Ltd", + [3]byte{0, 31, 25}: "BEN-RI ELECTRONICA S.A.", + [3]byte{0, 31, 26}: "Prominvest", + [3]byte{0, 31, 27}: "RoyalTek Company Ltd.", + [3]byte{0, 31, 28}: "KOBISHI ELECTRIC Co.,Ltd.", + [3]byte{0, 31, 29}: "Atlas Material Testing Technology LLC", + [3]byte{0, 31, 30}: "Astec Technology Co., Ltd", + [3]byte{0, 31, 31}: "Edimax Technology Co. Ltd.", + [3]byte{0, 31, 32}: "Logitech Europe SA", + [3]byte{0, 31, 33}: "Inner Mongolia Yin An Science & Technology Development Co.,L", + [3]byte{0, 31, 34}: "Source Photonics, Inc.", + [3]byte{0, 31, 35}: "Interacoustics", + [3]byte{0, 31, 36}: "DIGITVIEW TECHNOLOGY CO., LTD.", + [3]byte{0, 31, 37}: "MBS GmbH", + [3]byte{0, 31, 38}: "CISCO SYSTEMS, INC.", + [3]byte{0, 31, 39}: "CISCO SYSTEMS, INC.", + [3]byte{0, 31, 40}: "HPN Supply Chain", + [3]byte{0, 31, 41}: "Hewlett-Packard Company", + [3]byte{0, 31, 42}: "ACCM", + [3]byte{0, 31, 43}: "Orange Logic", + [3]byte{0, 31, 44}: "Starbridge Networks", + [3]byte{0, 31, 45}: "Electro-Optical Imaging, Inc.", + [3]byte{0, 31, 46}: "Triangle Research Int'l Pte Ltd", + [3]byte{0, 31, 47}: "Berker GmbH & Co. KG", + [3]byte{0, 31, 48}: "Travelping", + [3]byte{0, 31, 49}: "Radiocomp", + [3]byte{0, 31, 50}: "Nintendo Co., Ltd.", + [3]byte{0, 31, 51}: "Netgear Inc.", + [3]byte{0, 31, 52}: "Lung Hwa Electronics Co., Ltd.", + [3]byte{0, 31, 53}: "AIR802 LLC", + [3]byte{0, 31, 54}: "Bellwin Information Co. Ltd.,", + [3]byte{0, 31, 55}: "Genesis I&C", + [3]byte{0, 31, 56}: "POSITRON", + [3]byte{0, 31, 57}: "Construcciones y Auxiliar de Ferrocarriles, S.A.", + [3]byte{0, 31, 58}: "Hon Hai Precision Ind.Co., Ltd.", + [3]byte{0, 31, 59}: "Intel Corporate", + [3]byte{0, 31, 60}: "Intel Corporate", + [3]byte{0, 31, 61}: "Qbit GmbH", + [3]byte{0, 31, 62}: "RP-Technik e.K.", + [3]byte{0, 31, 63}: "AVM GmbH", + [3]byte{0, 31, 64}: "Speakercraft Inc.", + [3]byte{0, 31, 65}: "Ruckus Wireless", + [3]byte{0, 31, 66}: "Etherstack plc", + [3]byte{0, 31, 67}: "ENTES ELEKTRONIK", + [3]byte{0, 31, 68}: "GE Transportation Systems", + [3]byte{0, 31, 69}: "Enterasys", + [3]byte{0, 31, 70}: "Nortel", + [3]byte{0, 31, 71}: "MCS Logic Inc.", + [3]byte{0, 31, 72}: "Mojix Inc.", + [3]byte{0, 31, 73}: "Eurosat Distribution Ltd", + [3]byte{0, 31, 74}: "Albentia Systems S.A.", + [3]byte{0, 31, 75}: "Lineage Power", + [3]byte{0, 31, 76}: "Roseman Engineering Ltd", + [3]byte{0, 31, 77}: "Segnetics LLC", + [3]byte{0, 31, 78}: "ConMed Linvatec", + [3]byte{0, 31, 79}: "Thinkware Co. Ltd.", + [3]byte{0, 31, 80}: "Swissdis AG", + [3]byte{0, 31, 81}: "HD Communications Corp", + [3]byte{0, 31, 82}: "UVT Unternehmensberatung fur Verkehr und Technik GmbH", + [3]byte{0, 31, 83}: "GEMAC Gesellschaft für Mikroelektronikanwendung Chemnitz mbH", + [3]byte{0, 31, 84}: "Lorex Technology Inc.", + [3]byte{0, 31, 85}: "Honeywell Security (China) Co., Ltd.", + [3]byte{0, 31, 86}: "DIGITAL FORECAST", + [3]byte{0, 31, 87}: "Phonik Innovation Co.,LTD", + [3]byte{0, 31, 88}: "EMH Energiemesstechnik GmbH", + [3]byte{0, 31, 89}: "Kronback Tracers", + [3]byte{0, 31, 90}: "Beckwith Electric Co.", + [3]byte{0, 31, 91}: "Apple", + [3]byte{0, 31, 92}: "Nokia Danmark A/S", + [3]byte{0, 31, 93}: "Nokia Danmark A/S", + [3]byte{0, 31, 94}: "Dyna Technology Co.,Ltd.", + [3]byte{0, 31, 95}: "Blatand GmbH", + [3]byte{0, 31, 96}: "COMPASS SYSTEMS CORP.", + [3]byte{0, 31, 97}: "Talent Communication Networks Inc.", + [3]byte{0, 31, 98}: "JSC \"Stilsoft\"", + [3]byte{0, 31, 99}: "JSC Goodwin-Europa", + [3]byte{0, 31, 100}: "Beijing Autelan Technology Inc.", + [3]byte{0, 31, 101}: "KOREA ELECTRIC TERMINAL CO., LTD.", + [3]byte{0, 31, 102}: "PLANAR LLC", + [3]byte{0, 31, 103}: "Hitachi,Ltd.", + [3]byte{0, 31, 104}: "Martinsson Elektronik AB", + [3]byte{0, 31, 105}: "Pingood Technology Co., Ltd.", + [3]byte{0, 31, 106}: "PacketFlux Technologies, Inc.", + [3]byte{0, 31, 107}: "LG Electronics", + [3]byte{0, 31, 108}: "CISCO SYSTEMS, INC.", + [3]byte{0, 31, 109}: "CISCO SYSTEMS, INC.", + [3]byte{0, 31, 110}: "Vtech Engineering Corporation", + [3]byte{0, 31, 111}: "Fujian Sunnada Communication Co.,Ltd.", + [3]byte{0, 31, 112}: "Botik Technologies LTD", + [3]byte{0, 31, 113}: "xG Technology, Inc.", + [3]byte{0, 31, 114}: "QingDao Hiphone Technology Co,.Ltd", + [3]byte{0, 31, 115}: "Teraview Technology Co., Ltd.", + [3]byte{0, 31, 116}: "Eigen Development", + [3]byte{0, 31, 117}: "GiBahn Media", + [3]byte{0, 31, 118}: "AirLogic Systems Inc.", + [3]byte{0, 31, 119}: "HEOL DESIGN", + [3]byte{0, 31, 120}: "Blue Fox Porini Textile", + [3]byte{0, 31, 121}: "Lodam Electronics A/S", + [3]byte{0, 31, 122}: "WiWide Inc.", + [3]byte{0, 31, 123}: "TechNexion Ltd.", + [3]byte{0, 31, 124}: "Witelcom AS", + [3]byte{0, 31, 125}: "embedded wireless GmbH", + [3]byte{0, 31, 126}: "ARRIS Group, Inc.", + [3]byte{0, 31, 127}: "Phabrix Limited", + [3]byte{0, 31, 128}: "Lucas Holding bv", + [3]byte{0, 31, 129}: "Accel Semiconductor Corp", + [3]byte{0, 31, 130}: "Cal-Comp Electronics & Communications Co., Ltd", + [3]byte{0, 31, 131}: "Teleplan Technology Services Sdn Bhd", + [3]byte{0, 31, 132}: "Gigle Semiconductor", + [3]byte{0, 31, 133}: "Apriva ISS, LLC", + [3]byte{0, 31, 134}: "digEcor", + [3]byte{0, 31, 135}: "Skydigital Inc.", + [3]byte{0, 31, 136}: "FMS Force Measuring Systems AG", + [3]byte{0, 31, 137}: "Signalion GmbH", + [3]byte{0, 31, 138}: "Ellion Digital Inc.", + [3]byte{0, 31, 139}: "Cache IQ", + [3]byte{0, 31, 140}: "CCS Inc.", + [3]byte{0, 31, 141}: "Ingenieurbuero Stark GmbH und Ko. KG", + [3]byte{0, 31, 142}: "Metris USA Inc.", + [3]byte{0, 31, 143}: "Shanghai Bellmann Digital Source Co.,Ltd.", + [3]byte{0, 31, 144}: "Actiontec Electronics, Inc", + [3]byte{0, 31, 145}: "DBS Lodging Technologies, LLC", + [3]byte{0, 31, 146}: "VideoIQ, Inc.", + [3]byte{0, 31, 147}: "Xiotech Corporation", + [3]byte{0, 31, 148}: "Lascar Electronics Ltd", + [3]byte{0, 31, 149}: "SAGEM COMMUNICATION", + [3]byte{0, 31, 150}: "APROTECH CO.LTD", + [3]byte{0, 31, 151}: "BERTANA SRL", + [3]byte{0, 31, 152}: "DAIICHI-DENTSU LTD.", + [3]byte{0, 31, 153}: "SERONICS co.ltd", + [3]byte{0, 31, 154}: "Nortel Networks", + [3]byte{0, 31, 155}: "POSBRO", + [3]byte{0, 31, 156}: "LEDCO", + [3]byte{0, 31, 157}: "CISCO SYSTEMS, INC.", + [3]byte{0, 31, 158}: "CISCO SYSTEMS, INC.", + [3]byte{0, 31, 159}: "Thomson Telecom Belgium", + [3]byte{0, 31, 160}: "A10 Networks", + [3]byte{0, 31, 161}: "Gtran Inc", + [3]byte{0, 31, 162}: "Datron World Communications, Inc.", + [3]byte{0, 31, 163}: "T&W Electronics(Shenzhen)Co.,Ltd.", + [3]byte{0, 31, 164}: "ShenZhen Gongjin Electronics Co.,Ltd", + [3]byte{0, 31, 165}: "Blue-White Industries", + [3]byte{0, 31, 166}: "Stilo srl", + [3]byte{0, 31, 167}: "Sony Computer Entertainment Inc.", + [3]byte{0, 31, 168}: "Smart Energy Instruments Inc.", + [3]byte{0, 31, 169}: "Atlanta DTH, Inc.", + [3]byte{0, 31, 170}: "Taseon, Inc.", + [3]byte{0, 31, 171}: "I.S HIGH TECH.INC", + [3]byte{0, 31, 172}: "Goodmill Systems Ltd", + [3]byte{0, 31, 173}: "Brown Innovations, Inc", + [3]byte{0, 31, 174}: "Blick South Africa (Pty) Ltd", + [3]byte{0, 31, 175}: "NextIO, Inc.", + [3]byte{0, 31, 176}: "TimeIPS, Inc.", + [3]byte{0, 31, 177}: "Cybertech Inc.", + [3]byte{0, 31, 178}: "Sontheim Industrie Elektronik GmbH", + [3]byte{0, 31, 179}: "2Wire", + [3]byte{0, 31, 180}: "SmartShare Systems", + [3]byte{0, 31, 181}: "I/O Interconnect Inc.", + [3]byte{0, 31, 182}: "Chi Lin Technology Co., Ltd.", + [3]byte{0, 31, 183}: "WiMate Technologies Corp.", + [3]byte{0, 31, 184}: "Universal Remote Control, Inc.", + [3]byte{0, 31, 185}: "Paltronics", + [3]byte{0, 31, 186}: "BoYoung Tech. & Marketing, Inc.", + [3]byte{0, 31, 187}: "Xenatech Co.,LTD", + [3]byte{0, 31, 188}: "EVGA Corporation", + [3]byte{0, 31, 189}: "Kyocera Wireless Corp.", + [3]byte{0, 31, 190}: "Shenzhen Mopnet Industrial Co.,Ltd", + [3]byte{0, 31, 191}: "Fulhua Microelectronics Corp. Taiwan Branch", + [3]byte{0, 31, 192}: "Control Express Finland Oy", + [3]byte{0, 31, 193}: "Hanlong Technology Co.,LTD", + [3]byte{0, 31, 194}: "Jow Tong Technology Co Ltd", + [3]byte{0, 31, 195}: "SmartSynch, Inc", + [3]byte{0, 31, 196}: "ARRIS Group, Inc.", + [3]byte{0, 31, 197}: "Nintendo Co., Ltd.", + [3]byte{0, 31, 198}: "ASUSTek COMPUTER INC.", + [3]byte{0, 31, 199}: "Casio Hitachi Mobile Comunications Co., Ltd.", + [3]byte{0, 31, 200}: "Up-Today Industrial Co., Ltd.", + [3]byte{0, 31, 201}: "CISCO SYSTEMS, INC.", + [3]byte{0, 31, 202}: "CISCO SYSTEMS, INC.", + [3]byte{0, 31, 203}: "NIW Solutions", + [3]byte{0, 31, 204}: "Samsung Electronics Co.,Ltd", + [3]byte{0, 31, 205}: "Samsung Electronics", + [3]byte{0, 31, 206}: "QTECH LLC", + [3]byte{0, 31, 207}: "MSI Technology GmbH", + [3]byte{0, 31, 208}: "GIGA-BYTE TECHNOLOGY CO.,LTD.", + [3]byte{0, 31, 209}: "OPTEX CO.,LTD.", + [3]byte{0, 31, 210}: "COMMTECH TECHNOLOGY MACAO COMMERCIAL OFFSHORE LTD.", + [3]byte{0, 31, 211}: "RIVA Networks Inc.", + [3]byte{0, 31, 212}: "4IPNET, INC.", + [3]byte{0, 31, 213}: "MICRORISC s.r.o.", + [3]byte{0, 31, 214}: "Shenzhen Allywll", + [3]byte{0, 31, 215}: "TELERAD SA", + [3]byte{0, 31, 216}: "A-TRUST COMPUTER CORPORATION", + [3]byte{0, 31, 217}: "RSD Communications Ltd", + [3]byte{0, 31, 218}: "Nortel Networks", + [3]byte{0, 31, 219}: "Network Supply Corp.,", + [3]byte{0, 31, 220}: "Mobile Safe Track Ltd", + [3]byte{0, 31, 221}: "GDI LLC", + [3]byte{0, 31, 222}: "Nokia Danmark A/S", + [3]byte{0, 31, 223}: "Nokia Danmark A/S", + [3]byte{0, 31, 224}: "EdgeVelocity Corp", + [3]byte{0, 31, 225}: "Hon Hai Precision Ind. Co., Ltd.", + [3]byte{0, 31, 226}: "Hon Hai Precision Ind. Co., Ltd.", + [3]byte{0, 31, 227}: "LG Electronics", + [3]byte{0, 31, 228}: "Sony Ericsson Mobile Communications", + [3]byte{0, 31, 229}: "In-Circuit GmbH", + [3]byte{0, 31, 230}: "Alphion Corporation", + [3]byte{0, 31, 231}: "Simet", + [3]byte{0, 31, 232}: "KURUSUGAWA Electronics Industry Inc,.", + [3]byte{0, 31, 233}: "Printrex, Inc.", + [3]byte{0, 31, 234}: "Applied Media Technologies Corporation", + [3]byte{0, 31, 235}: "Trio Datacom Pty Ltd", + [3]byte{0, 31, 236}: "Synapse Électronique", + [3]byte{0, 31, 237}: "Tecan Systems Inc.", + [3]byte{0, 31, 238}: "ubisys technologies GmbH", + [3]byte{0, 31, 239}: "SHINSEI INDUSTRIES CO.,LTD", + [3]byte{0, 31, 240}: "Audio Partnership", + [3]byte{0, 31, 241}: "Paradox Hellas S.A.", + [3]byte{0, 31, 242}: "VIA Technologies, Inc.", + [3]byte{0, 31, 243}: "Apple", + [3]byte{0, 31, 244}: "Power Monitors, Inc.", + [3]byte{0, 31, 245}: "Kongsberg Defence & Aerospace", + [3]byte{0, 31, 246}: "PS Audio International", + [3]byte{0, 31, 247}: "Nakajima All Precision Co., Ltd.", + [3]byte{0, 31, 248}: "Siemens AG, Sector Industry, Drive Technologies, Motion Control Systems", + [3]byte{0, 31, 249}: "Advanced Knowledge Associates", + [3]byte{0, 31, 250}: "Coretree, Co, Ltd", + [3]byte{0, 31, 251}: "Green Packet Bhd", + [3]byte{0, 31, 252}: "Riccius+Sohn GmbH", + [3]byte{0, 31, 253}: "Indigo Mobile Technologies Corp.", + [3]byte{0, 31, 254}: "HPN Supply Chain", + [3]byte{0, 31, 255}: "Respironics, Inc.", + [3]byte{0, 32, 0}: "LEXMARK INTERNATIONAL, INC.", + [3]byte{0, 32, 1}: "DSP SOLUTIONS, INC.", + [3]byte{0, 32, 2}: "SERITECH ENTERPRISE CO., LTD.", + [3]byte{0, 32, 3}: "PIXEL POWER LTD.", + [3]byte{0, 32, 4}: "YAMATAKE-HONEYWELL CO., LTD.", + [3]byte{0, 32, 5}: "SIMPLE TECHNOLOGY", + [3]byte{0, 32, 6}: "GARRETT COMMUNICATIONS, INC.", + [3]byte{0, 32, 7}: "SFA, INC.", + [3]byte{0, 32, 8}: "CABLE & COMPUTER TECHNOLOGY", + [3]byte{0, 32, 9}: "PACKARD BELL ELEC., INC.", + [3]byte{0, 32, 10}: "SOURCE-COMM CORP.", + [3]byte{0, 32, 11}: "OCTAGON SYSTEMS CORP.", + [3]byte{0, 32, 12}: "ADASTRA SYSTEMS CORP.", + [3]byte{0, 32, 13}: "CARL ZEISS", + [3]byte{0, 32, 14}: "SATELLITE TECHNOLOGY MGMT, INC", + [3]byte{0, 32, 15}: "TANBAC CO., LTD.", + [3]byte{0, 32, 16}: "JEOL SYSTEM TECHNOLOGY CO. LTD", + [3]byte{0, 32, 17}: "CANOPUS CO., LTD.", + [3]byte{0, 32, 18}: "CAMTRONICS MEDICAL SYSTEMS", + [3]byte{0, 32, 19}: "DIVERSIFIED TECHNOLOGY, INC.", + [3]byte{0, 32, 20}: "GLOBAL VIEW CO., LTD.", + [3]byte{0, 32, 21}: "ACTIS COMPUTER SA", + [3]byte{0, 32, 22}: "SHOWA ELECTRIC WIRE & CABLE CO", + [3]byte{0, 32, 23}: "ORBOTECH", + [3]byte{0, 32, 24}: "CIS TECHNOLOGY INC.", + [3]byte{0, 32, 25}: "OHLER GmbH", + [3]byte{0, 32, 26}: "MRV Communications, Inc.", + [3]byte{0, 32, 27}: "NORTHERN TELECOM/NETWORK", + [3]byte{0, 32, 28}: "EXCEL, INC.", + [3]byte{0, 32, 29}: "KATANA PRODUCTS", + [3]byte{0, 32, 30}: "NETQUEST CORPORATION", + [3]byte{0, 32, 31}: "BEST POWER TECHNOLOGY, INC.", + [3]byte{0, 32, 32}: "MEGATRON COMPUTER INDUSTRIES PTY, LTD.", + [3]byte{0, 32, 33}: "ALGORITHMS SOFTWARE PVT. LTD.", + [3]byte{0, 32, 34}: "NMS Communications", + [3]byte{0, 32, 35}: "T.C. TECHNOLOGIES PTY. LTD", + [3]byte{0, 32, 36}: "PACIFIC COMMUNICATION SCIENCES", + [3]byte{0, 32, 37}: "CONTROL TECHNOLOGY, INC.", + [3]byte{0, 32, 38}: "AMKLY SYSTEMS, INC.", + [3]byte{0, 32, 39}: "MING FORTUNE INDUSTRY CO., LTD", + [3]byte{0, 32, 40}: "WEST EGG SYSTEMS, INC.", + [3]byte{0, 32, 41}: "TELEPROCESSING PRODUCTS, INC.", + [3]byte{0, 32, 42}: "N.V. DZINE", + [3]byte{0, 32, 43}: "ADVANCED TELECOMMUNICATIONS MODULES, LTD.", + [3]byte{0, 32, 44}: "WELLTRONIX CO., LTD.", + [3]byte{0, 32, 45}: "TAIYO CORPORATION", + [3]byte{0, 32, 46}: "DAYSTAR DIGITAL", + [3]byte{0, 32, 47}: "ZETA COMMUNICATIONS, LTD.", + [3]byte{0, 32, 48}: "ANALOG & DIGITAL SYSTEMS", + [3]byte{0, 32, 49}: "Tattile SRL", + [3]byte{0, 32, 50}: "ALCATEL TAISEL", + [3]byte{0, 32, 51}: "SYNAPSE TECHNOLOGIES, INC.", + [3]byte{0, 32, 52}: "ROTEC INDUSTRIEAUTOMATION GMBH", + [3]byte{0, 32, 53}: "IBM Corp", + [3]byte{0, 32, 54}: "BMC SOFTWARE", + [3]byte{0, 32, 55}: "SEAGATE TECHNOLOGY", + [3]byte{0, 32, 56}: "VME MICROSYSTEMS INTERNATIONAL CORPORATION", + [3]byte{0, 32, 57}: "SCINETS", + [3]byte{0, 32, 58}: "DIGITAL BI0METRICS INC.", + [3]byte{0, 32, 59}: "WISDM LTD.", + [3]byte{0, 32, 60}: "EUROTIME AB", + [3]byte{0, 32, 61}: "Honeywell ECC", + [3]byte{0, 32, 62}: "LogiCan Technologies, Inc.", + [3]byte{0, 32, 63}: "JUKI CORPORATION", + [3]byte{0, 32, 64}: "ARRIS Group, Inc.", + [3]byte{0, 32, 65}: "DATA NET", + [3]byte{0, 32, 66}: "DATAMETRICS CORP.", + [3]byte{0, 32, 67}: "NEURON COMPANY LIMITED", + [3]byte{0, 32, 68}: "GENITECH PTY LTD", + [3]byte{0, 32, 69}: "ION Networks, Inc.", + [3]byte{0, 32, 70}: "CIPRICO, INC.", + [3]byte{0, 32, 71}: "STEINBRECHER CORP.", + [3]byte{0, 32, 72}: "Marconi Communications", + [3]byte{0, 32, 73}: "COMTRON, INC.", + [3]byte{0, 32, 74}: "PRONET GMBH", + [3]byte{0, 32, 75}: "AUTOCOMPUTER CO., LTD.", + [3]byte{0, 32, 76}: "MITRON COMPUTER PTE LTD.", + [3]byte{0, 32, 77}: "INOVIS GMBH", + [3]byte{0, 32, 78}: "NETWORK SECURITY SYSTEMS, INC.", + [3]byte{0, 32, 79}: "DEUTSCHE AEROSPACE AG", + [3]byte{0, 32, 80}: "KOREA COMPUTER INC.", + [3]byte{0, 32, 81}: "Verilink Corporation", + [3]byte{0, 32, 82}: "RAGULA SYSTEMS", + [3]byte{0, 32, 83}: "HUNTSVILLE MICROSYSTEMS, INC.", + [3]byte{0, 32, 84}: "Sycamore Networks", + [3]byte{0, 32, 85}: "ALTECH CO., LTD.", + [3]byte{0, 32, 86}: "NEOPRODUCTS", + [3]byte{0, 32, 87}: "TITZE DATENTECHNIK GmbH", + [3]byte{0, 32, 88}: "ALLIED SIGNAL INC.", + [3]byte{0, 32, 89}: "MIRO COMPUTER PRODUCTS AG", + [3]byte{0, 32, 90}: "COMPUTER IDENTICS", + [3]byte{0, 32, 91}: "Kentrox, LLC", + [3]byte{0, 32, 92}: "InterNet Systems of Florida, Inc.", + [3]byte{0, 32, 93}: "NANOMATIC OY", + [3]byte{0, 32, 94}: "CASTLE ROCK, INC.", + [3]byte{0, 32, 95}: "GAMMADATA COMPUTER GMBH", + [3]byte{0, 32, 96}: "ALCATEL ITALIA S.p.A.", + [3]byte{0, 32, 97}: "GarrettCom, Inc.", + [3]byte{0, 32, 98}: "SCORPION LOGIC, LTD.", + [3]byte{0, 32, 99}: "WIPRO INFOTECH LTD.", + [3]byte{0, 32, 100}: "PROTEC MICROSYSTEMS, INC.", + [3]byte{0, 32, 101}: "SUPERNET NETWORKING INC.", + [3]byte{0, 32, 102}: "GENERAL MAGIC, INC.", + [3]byte{0, 32, 103}: "PRIVATE", + [3]byte{0, 32, 104}: "ISDYNE", + [3]byte{0, 32, 105}: "ISDN SYSTEMS CORPORATION", + [3]byte{0, 32, 106}: "OSAKA COMPUTER CORP.", + [3]byte{0, 32, 107}: "KONICA MINOLTA HOLDINGS, INC.", + [3]byte{0, 32, 108}: "EVERGREEN TECHNOLOGY CORP.", + [3]byte{0, 32, 109}: "DATA RACE, INC.", + [3]byte{0, 32, 110}: "XACT, INC.", + [3]byte{0, 32, 111}: "FLOWPOINT CORPORATION", + [3]byte{0, 32, 112}: "HYNET, LTD.", + [3]byte{0, 32, 113}: "IBR GMBH", + [3]byte{0, 32, 114}: "WORKLINK INNOVATIONS", + [3]byte{0, 32, 115}: "FUSION SYSTEMS CORPORATION", + [3]byte{0, 32, 116}: "SUNGWOON SYSTEMS", + [3]byte{0, 32, 117}: "MOTOROLA COMMUNICATION ISRAEL", + [3]byte{0, 32, 118}: "REUDO CORPORATION", + [3]byte{0, 32, 119}: "KARDIOS SYSTEMS CORP.", + [3]byte{0, 32, 120}: "RUNTOP, INC.", + [3]byte{0, 32, 121}: "MIKRON GMBH", + [3]byte{0, 32, 122}: "WiSE Communications, Inc.", + [3]byte{0, 32, 123}: "Intel Corporation", + [3]byte{0, 32, 124}: "AUTEC GmbH", + [3]byte{0, 32, 125}: "ADVANCED COMPUTER APPLICATIONS", + [3]byte{0, 32, 126}: "FINECOM Co., Ltd.", + [3]byte{0, 32, 127}: "KYOEI SANGYO CO., LTD.", + [3]byte{0, 32, 128}: "SYNERGY (UK) LTD.", + [3]byte{0, 32, 129}: "TITAN ELECTRONICS", + [3]byte{0, 32, 130}: "ONEAC CORPORATION", + [3]byte{0, 32, 131}: "PRESTICOM INCORPORATED", + [3]byte{0, 32, 132}: "OCE PRINTING SYSTEMS, GMBH", + [3]byte{0, 32, 133}: "Eaton Corporation", + [3]byte{0, 32, 134}: "MICROTECH ELECTRONICS LIMITED", + [3]byte{0, 32, 135}: "MEMOTEC, INC.", + [3]byte{0, 32, 136}: "GLOBAL VILLAGE COMMUNICATION", + [3]byte{0, 32, 137}: "T3PLUS NETWORKING, INC.", + [3]byte{0, 32, 138}: "SONIX COMMUNICATIONS, LTD.", + [3]byte{0, 32, 139}: "LAPIS TECHNOLOGIES, INC.", + [3]byte{0, 32, 140}: "GALAXY NETWORKS, INC.", + [3]byte{0, 32, 141}: "CMD TECHNOLOGY", + [3]byte{0, 32, 142}: "CHEVIN SOFTWARE ENG. LTD.", + [3]byte{0, 32, 143}: "ECI TELECOM LTD.", + [3]byte{0, 32, 144}: "ADVANCED COMPRESSION TECHNOLOGY, INC.", + [3]byte{0, 32, 145}: "J125, NATIONAL SECURITY AGENCY", + [3]byte{0, 32, 146}: "CHESS ENGINEERING B.V.", + [3]byte{0, 32, 147}: "LANDINGS TECHNOLOGY CORP.", + [3]byte{0, 32, 148}: "CUBIX CORPORATION", + [3]byte{0, 32, 149}: "RIVA ELECTRONICS", + [3]byte{0, 32, 150}: "Invensys", + [3]byte{0, 32, 151}: "APPLIED SIGNAL TECHNOLOGY", + [3]byte{0, 32, 152}: "HECTRONIC AB", + [3]byte{0, 32, 153}: "BON ELECTRIC CO., LTD.", + [3]byte{0, 32, 154}: "THE 3DO COMPANY", + [3]byte{0, 32, 155}: "ERSAT ELECTRONIC GMBH", + [3]byte{0, 32, 156}: "PRIMARY ACCESS CORP.", + [3]byte{0, 32, 157}: "LIPPERT AUTOMATIONSTECHNIK", + [3]byte{0, 32, 158}: "BROWN'S OPERATING SYSTEM SERVICES, LTD.", + [3]byte{0, 32, 159}: "MERCURY COMPUTER SYSTEMS, INC.", + [3]byte{0, 32, 160}: "OA LABORATORY CO., LTD.", + [3]byte{0, 32, 161}: "DOVATRON", + [3]byte{0, 32, 162}: "GALCOM NETWORKING LTD.", + [3]byte{0, 32, 163}: "Harmonic, Inc", + [3]byte{0, 32, 164}: "MULTIPOINT NETWORKS", + [3]byte{0, 32, 165}: "API ENGINEERING", + [3]byte{0, 32, 166}: "Proxim Wireless", + [3]byte{0, 32, 167}: "PAIRGAIN TECHNOLOGIES, INC.", + [3]byte{0, 32, 168}: "SAST TECHNOLOGY CORP.", + [3]byte{0, 32, 169}: "WHITE HORSE INDUSTRIAL", + [3]byte{0, 32, 170}: "Ericsson Television Limited", + [3]byte{0, 32, 171}: "MICRO INDUSTRIES CORP.", + [3]byte{0, 32, 172}: "INTERFLEX DATENSYSTEME GMBH", + [3]byte{0, 32, 173}: "LINQ SYSTEMS", + [3]byte{0, 32, 174}: "ORNET DATA COMMUNICATION TECH.", + [3]byte{0, 32, 175}: "3COM CORPORATION", + [3]byte{0, 32, 176}: "GATEWAY DEVICES, INC.", + [3]byte{0, 32, 177}: "COMTECH RESEARCH INC.", + [3]byte{0, 32, 178}: "GKD Gesellschaft Fur Kommunikation Und Datentechnik", + [3]byte{0, 32, 179}: "Tattile SRL", + [3]byte{0, 32, 180}: "TERMA ELEKTRONIK AS", + [3]byte{0, 32, 181}: "YASKAWA ELECTRIC CORPORATION", + [3]byte{0, 32, 182}: "AGILE NETWORKS, INC.", + [3]byte{0, 32, 183}: "NAMAQUA COMPUTERWARE", + [3]byte{0, 32, 184}: "PRIME OPTION, INC.", + [3]byte{0, 32, 185}: "METRICOM, INC.", + [3]byte{0, 32, 186}: "CENTER FOR HIGH PERFORMANCE", + [3]byte{0, 32, 187}: "ZAX CORPORATION", + [3]byte{0, 32, 188}: "Long Reach Networks Pty Ltd", + [3]byte{0, 32, 189}: "NIOBRARA R & D CORPORATION", + [3]byte{0, 32, 190}: "LAN ACCESS CORP.", + [3]byte{0, 32, 191}: "AEHR TEST SYSTEMS", + [3]byte{0, 32, 192}: "PULSE ELECTRONICS, INC.", + [3]byte{0, 32, 193}: "SAXA, Inc.", + [3]byte{0, 32, 194}: "TEXAS MEMORY SYSTEMS, INC.", + [3]byte{0, 32, 195}: "COUNTER SOLUTIONS LTD.", + [3]byte{0, 32, 196}: "INET,INC.", + [3]byte{0, 32, 197}: "EAGLE TECHNOLOGY", + [3]byte{0, 32, 198}: "NECTEC", + [3]byte{0, 32, 199}: "AKAI Professional M.I. Corp.", + [3]byte{0, 32, 200}: "LARSCOM INCORPORATED", + [3]byte{0, 32, 201}: "VICTRON BV", + [3]byte{0, 32, 202}: "DIGITAL OCEAN", + [3]byte{0, 32, 203}: "PRETEC ELECTRONICS CORP.", + [3]byte{0, 32, 204}: "DIGITAL SERVICES, LTD.", + [3]byte{0, 32, 205}: "HYBRID NETWORKS, INC.", + [3]byte{0, 32, 206}: "LOGICAL DESIGN GROUP, INC.", + [3]byte{0, 32, 207}: "TEST & MEASUREMENT SYSTEMS INC", + [3]byte{0, 32, 208}: "VERSALYNX CORPORATION", + [3]byte{0, 32, 209}: "MICROCOMPUTER SYSTEMS (M) SDN.", + [3]byte{0, 32, 210}: "RAD DATA COMMUNICATIONS, LTD.", + [3]byte{0, 32, 211}: "OST (OUEST STANDARD TELEMATIQU", + [3]byte{0, 32, 212}: "CABLETRON - ZEITTNET INC.", + [3]byte{0, 32, 213}: "VIPA GMBH", + [3]byte{0, 32, 214}: "BREEZECOM", + [3]byte{0, 32, 215}: "JAPAN MINICOMPUTER SYSTEMS CO., Ltd.", + [3]byte{0, 32, 216}: "Nortel Networks", + [3]byte{0, 32, 217}: "PANASONIC TECHNOLOGIES, INC./MIECO-US", + [3]byte{0, 32, 218}: "Alcatel North America ESD", + [3]byte{0, 32, 219}: "XNET TECHNOLOGY, INC.", + [3]byte{0, 32, 220}: "DENSITRON TAIWAN LTD.", + [3]byte{0, 32, 221}: "Cybertec Pty Ltd", + [3]byte{0, 32, 222}: "JAPAN DIGITAL LABORAT'Y CO.LTD", + [3]byte{0, 32, 223}: "KYOSAN ELECTRIC MFG. CO., LTD.", + [3]byte{0, 32, 224}: "Actiontec Electronics, Inc.", + [3]byte{0, 32, 225}: "ALAMAR ELECTRONICS", + [3]byte{0, 32, 226}: "INFORMATION RESOURCE ENGINEERING", + [3]byte{0, 32, 227}: "MCD KENCOM CORPORATION", + [3]byte{0, 32, 228}: "HSING TECH ENTERPRISE CO., LTD", + [3]byte{0, 32, 229}: "APEX DATA, INC.", + [3]byte{0, 32, 230}: "LIDKOPING MACHINE TOOLS AB", + [3]byte{0, 32, 231}: "B&W NUCLEAR SERVICE COMPANY", + [3]byte{0, 32, 232}: "DATATREK CORPORATION", + [3]byte{0, 32, 233}: "DANTEL", + [3]byte{0, 32, 234}: "EFFICIENT NETWORKS, INC.", + [3]byte{0, 32, 235}: "CINCINNATI MICROWAVE, INC.", + [3]byte{0, 32, 236}: "TECHWARE SYSTEMS CORP.", + [3]byte{0, 32, 237}: "GIGA-BYTE TECHNOLOGY CO., LTD.", + [3]byte{0, 32, 238}: "GTECH CORPORATION", + [3]byte{0, 32, 239}: "USC CORPORATION", + [3]byte{0, 32, 240}: "UNIVERSAL MICROELECTRONICS CO.", + [3]byte{0, 32, 241}: "ALTOS INDIA LIMITED", + [3]byte{0, 32, 242}: "Oracle Corporation", + [3]byte{0, 32, 243}: "RAYNET CORPORATION", + [3]byte{0, 32, 244}: "SPECTRIX CORPORATION", + [3]byte{0, 32, 245}: "PANDATEL AG", + [3]byte{0, 32, 246}: "NET TEK AND KARLNET, INC.", + [3]byte{0, 32, 247}: "CYBERDATA CORPORATION", + [3]byte{0, 32, 248}: "CARRERA COMPUTERS, INC.", + [3]byte{0, 32, 249}: "PARALINK NETWORKS, INC.", + [3]byte{0, 32, 250}: "GDE SYSTEMS, INC.", + [3]byte{0, 32, 251}: "OCTEL COMMUNICATIONS CORP.", + [3]byte{0, 32, 252}: "MATROX", + [3]byte{0, 32, 253}: "ITV TECHNOLOGIES, INC.", + [3]byte{0, 32, 254}: "TOPWARE INC. / GRAND COMPUTER", + [3]byte{0, 32, 255}: "SYMMETRICAL TECHNOLOGIES", + [3]byte{0, 33, 0}: "GemTek Technology Co., Ltd.", + [3]byte{0, 33, 1}: "Aplicaciones Electronicas Quasar (AEQ)", + [3]byte{0, 33, 2}: "UpdateLogic Inc.", + [3]byte{0, 33, 3}: "GHI Electronics, LLC", + [3]byte{0, 33, 4}: "Gigaset Communications GmbH", + [3]byte{0, 33, 5}: "Alcatel-Lucent", + [3]byte{0, 33, 6}: "RIM Testing Services", + [3]byte{0, 33, 7}: "Seowonintech Co Ltd.", + [3]byte{0, 33, 8}: "Nokia Danmark A/S", + [3]byte{0, 33, 9}: "Nokia Danmark A/S", + [3]byte{0, 33, 10}: "byd:sign Corporation", + [3]byte{0, 33, 11}: "GEMINI TRAZE RFID PVT. LTD.", + [3]byte{0, 33, 12}: "Cymtec Systems, Inc.", + [3]byte{0, 33, 13}: "SAMSIN INNOTEC", + [3]byte{0, 33, 14}: "Orpak Systems L.T.D.", + [3]byte{0, 33, 15}: "Cernium Corp", + [3]byte{0, 33, 16}: "Clearbox Systems", + [3]byte{0, 33, 17}: "Uniphone Inc.", + [3]byte{0, 33, 18}: "WISCOM SYSTEM CO.,LTD", + [3]byte{0, 33, 19}: "Padtec S/A", + [3]byte{0, 33, 20}: "Hylab Technology Inc.", + [3]byte{0, 33, 21}: "PHYWE Systeme GmbH & Co. KG", + [3]byte{0, 33, 22}: "Transcon Electronic Systems, spol. s r. o.", + [3]byte{0, 33, 23}: "Tellord", + [3]byte{0, 33, 24}: "Athena Tech, Inc.", + [3]byte{0, 33, 25}: "Samsung Electro-Mechanics", + [3]byte{0, 33, 26}: "LInTech Corporation", + [3]byte{0, 33, 27}: "CISCO SYSTEMS, INC.", + [3]byte{0, 33, 28}: "CISCO SYSTEMS, INC.", + [3]byte{0, 33, 29}: "Dataline AB", + [3]byte{0, 33, 30}: "ARRIS Group, Inc.", + [3]byte{0, 33, 31}: "SHINSUNG DELTATECH CO.,LTD.", + [3]byte{0, 33, 32}: "Sequel Technologies", + [3]byte{0, 33, 33}: "VRmagic GmbH", + [3]byte{0, 33, 34}: "Chip-pro Ltd.", + [3]byte{0, 33, 35}: "Aerosat Avionics", + [3]byte{0, 33, 36}: "Optos Plc", + [3]byte{0, 33, 37}: "KUK JE TONG SHIN Co.,LTD", + [3]byte{0, 33, 38}: "Shenzhen Torch Equipment Co., Ltd.", + [3]byte{0, 33, 39}: "TP-LINK Technology Co., Ltd.", + [3]byte{0, 33, 40}: "Oracle Corporation", + [3]byte{0, 33, 41}: "Cisco-Linksys, LLC", + [3]byte{0, 33, 42}: "Audiovox Corporation", + [3]byte{0, 33, 43}: "MSA Auer", + [3]byte{0, 33, 44}: "SemIndia System Private Limited", + [3]byte{0, 33, 45}: "SCIMOLEX CORPORATION", + [3]byte{0, 33, 46}: "dresden-elektronik", + [3]byte{0, 33, 47}: "Phoebe Micro Inc.", + [3]byte{0, 33, 48}: "Keico Hightech Inc.", + [3]byte{0, 33, 49}: "Blynke Inc.", + [3]byte{0, 33, 50}: "Masterclock, Inc.", + [3]byte{0, 33, 51}: "Building B, Inc", + [3]byte{0, 33, 52}: "Brandywine Communications", + [3]byte{0, 33, 53}: "ALCATEL-LUCENT", + [3]byte{0, 33, 54}: "ARRIS Group, Inc.", + [3]byte{0, 33, 55}: "Bay Controls, LLC", + [3]byte{0, 33, 56}: "Cepheid", + [3]byte{0, 33, 57}: "Escherlogic Inc.", + [3]byte{0, 33, 58}: "Winchester Systems Inc.", + [3]byte{0, 33, 59}: "Berkshire Products, Inc", + [3]byte{0, 33, 60}: "AliphCom", + [3]byte{0, 33, 61}: "Cermetek Microelectronics, Inc.", + [3]byte{0, 33, 62}: "TomTom", + [3]byte{0, 33, 63}: "A-Team Technology Ltd.", + [3]byte{0, 33, 64}: "EN Technologies Inc.", + [3]byte{0, 33, 65}: "RADLIVE", + [3]byte{0, 33, 66}: "Advanced Control Systems doo", + [3]byte{0, 33, 67}: "ARRIS Group, Inc.", + [3]byte{0, 33, 68}: "SS Telecoms", + [3]byte{0, 33, 69}: "Semptian Technologies Ltd.", + [3]byte{0, 33, 70}: "Sanmina-SCI", + [3]byte{0, 33, 71}: "Nintendo Co., Ltd.", + [3]byte{0, 33, 72}: "Kaco Solar Korea", + [3]byte{0, 33, 73}: "China Daheng Group ,Inc.", + [3]byte{0, 33, 74}: "Pixel Velocity, Inc", + [3]byte{0, 33, 75}: "Shenzhen HAMP Science & Technology Co.,Ltd", + [3]byte{0, 33, 76}: "SAMSUNG ELECTRONICS CO., LTD.", + [3]byte{0, 33, 77}: "Guangzhou Skytone Transmission Technology Com. Ltd.", + [3]byte{0, 33, 78}: "GS Yuasa Power Supply Ltd.", + [3]byte{0, 33, 79}: "ALPS Electric Co., Ltd", + [3]byte{0, 33, 80}: "EYEVIEW ELECTRONICS", + [3]byte{0, 33, 81}: "Millinet Co., Ltd.", + [3]byte{0, 33, 82}: "General Satellite Research & Development Limited", + [3]byte{0, 33, 83}: "SeaMicro Inc.", + [3]byte{0, 33, 84}: "D-TACQ Solutions Ltd", + [3]byte{0, 33, 85}: "CISCO SYSTEMS, INC.", + [3]byte{0, 33, 86}: "CISCO SYSTEMS, INC.", + [3]byte{0, 33, 87}: "National Datacast, Inc.", + [3]byte{0, 33, 88}: "Style Flying Technology Co.", + [3]byte{0, 33, 89}: "Juniper Networks", + [3]byte{0, 33, 90}: "Hewlett-Packard Company", + [3]byte{0, 33, 91}: "Inotive", + [3]byte{0, 33, 92}: "Intel Corporate", + [3]byte{0, 33, 93}: "Intel Corporate", + [3]byte{0, 33, 94}: "IBM Corp", + [3]byte{0, 33, 95}: "IHSE GmbH", + [3]byte{0, 33, 96}: "Hidea Solutions Co. Ltd.", + [3]byte{0, 33, 97}: "Yournet Inc.", + [3]byte{0, 33, 98}: "Nortel", + [3]byte{0, 33, 99}: "ASKEY COMPUTER CORP", + [3]byte{0, 33, 100}: "Special Design Bureau for Seismic Instrumentation", + [3]byte{0, 33, 101}: "Presstek Inc.", + [3]byte{0, 33, 102}: "NovAtel Inc.", + [3]byte{0, 33, 103}: "HWA JIN T&I Corp.", + [3]byte{0, 33, 104}: "iVeia, LLC", + [3]byte{0, 33, 105}: "Prologix, LLC.", + [3]byte{0, 33, 106}: "Intel Corporate", + [3]byte{0, 33, 107}: "Intel Corporate", + [3]byte{0, 33, 108}: "ODVA", + [3]byte{0, 33, 109}: "Soltech Co., Ltd.", + [3]byte{0, 33, 110}: "Function ATI (Huizhou) Telecommunications Co., Ltd.", + [3]byte{0, 33, 111}: "SymCom, Inc.", + [3]byte{0, 33, 112}: "Dell Inc", + [3]byte{0, 33, 113}: "Wesung TNC Co., Ltd.", + [3]byte{0, 33, 114}: "Seoultek Valley", + [3]byte{0, 33, 115}: "Ion Torrent Systems, Inc.", + [3]byte{0, 33, 116}: "AvaLAN Wireless", + [3]byte{0, 33, 117}: "Pacific Satellite International Ltd.", + [3]byte{0, 33, 118}: "YMax Telecom Ltd.", + [3]byte{0, 33, 119}: "W. L. Gore & Associates", + [3]byte{0, 33, 120}: "Matuschek Messtechnik GmbH", + [3]byte{0, 33, 121}: "IOGEAR, Inc.", + [3]byte{0, 33, 122}: "Sejin Electron, Inc.", + [3]byte{0, 33, 123}: "Bastec AB", + [3]byte{0, 33, 124}: "2Wire", + [3]byte{0, 33, 125}: "PYXIS S.R.L.", + [3]byte{0, 33, 126}: "Telit Communication s.p.a", + [3]byte{0, 33, 127}: "Intraco Technology Pte Ltd", + [3]byte{0, 33, 128}: "ARRIS Group, Inc.", + [3]byte{0, 33, 129}: "Si2 Microsystems Limited", + [3]byte{0, 33, 130}: "SandLinks Systems, Ltd.", + [3]byte{0, 33, 131}: "VATECH HYDRO", + [3]byte{0, 33, 132}: "POWERSOFT SRL", + [3]byte{0, 33, 133}: "MICRO-STAR INT'L CO.,LTD.", + [3]byte{0, 33, 134}: "Universal Global Scientific Industrial Co., Ltd", + [3]byte{0, 33, 135}: "Imacs GmbH", + [3]byte{0, 33, 136}: "EMC Corporation", + [3]byte{0, 33, 137}: "AppTech, Inc.", + [3]byte{0, 33, 138}: "Electronic Design and Manufacturing Company", + [3]byte{0, 33, 139}: "Wescon Technology, Inc.", + [3]byte{0, 33, 140}: "TopControl GMBH", + [3]byte{0, 33, 141}: "AP Router Ind. Eletronica LTDA", + [3]byte{0, 33, 142}: "MEKICS CO., LTD.", + [3]byte{0, 33, 143}: "Avantgarde Acoustic Lautsprechersysteme GmbH", + [3]byte{0, 33, 144}: "Goliath Solutions", + [3]byte{0, 33, 145}: "D-Link Corporation", + [3]byte{0, 33, 146}: "Baoding Galaxy Electronic Technology Co.,Ltd", + [3]byte{0, 33, 147}: "Videofon MV", + [3]byte{0, 33, 148}: "Ping Communication", + [3]byte{0, 33, 149}: "GWD Media Limited", + [3]byte{0, 33, 150}: "Telsey S.p.A.", + [3]byte{0, 33, 151}: "ELITEGROUP COMPUTER SYSTEM", + [3]byte{0, 33, 152}: "Thai Radio Co, LTD", + [3]byte{0, 33, 153}: "Vacon Plc", + [3]byte{0, 33, 154}: "Cambridge Visual Networks Ltd", + [3]byte{0, 33, 155}: "Dell Inc", + [3]byte{0, 33, 156}: "Honeywld Technology Corp.", + [3]byte{0, 33, 157}: "Adesys BV", + [3]byte{0, 33, 158}: "Sony Ericsson Mobile Communications", + [3]byte{0, 33, 159}: "SATEL OY", + [3]byte{0, 33, 160}: "CISCO SYSTEMS, INC.", + [3]byte{0, 33, 161}: "CISCO SYSTEMS, INC.", + [3]byte{0, 33, 162}: "EKE-Electronics Ltd.", + [3]byte{0, 33, 163}: "Micromint", + [3]byte{0, 33, 164}: "Dbii Networks", + [3]byte{0, 33, 165}: "ERLPhase Power Technologies Ltd.", + [3]byte{0, 33, 166}: "Videotec Spa", + [3]byte{0, 33, 167}: "Hantle System Co., Ltd.", + [3]byte{0, 33, 168}: "Telephonics Corporation", + [3]byte{0, 33, 169}: "Mobilink Telecom Co.,Ltd", + [3]byte{0, 33, 170}: "Nokia Danmark A/S", + [3]byte{0, 33, 171}: "Nokia Danmark A/S", + [3]byte{0, 33, 172}: "Infrared Integrated Systems Ltd", + [3]byte{0, 33, 173}: "Nordic ID Oy", + [3]byte{0, 33, 174}: "ALCATEL-LUCENT FRANCE - WTD", + [3]byte{0, 33, 175}: "Radio Frequency Systems", + [3]byte{0, 33, 176}: "Tyco Telecommunications", + [3]byte{0, 33, 177}: "DIGITAL SOLUTIONS LTD", + [3]byte{0, 33, 178}: "Fiberblaze A/S", + [3]byte{0, 33, 179}: "Ross Controls", + [3]byte{0, 33, 180}: "APRO MEDIA CO., LTD", + [3]byte{0, 33, 181}: "Galvanic Ltd", + [3]byte{0, 33, 182}: "Triacta Power Technologies Inc.", + [3]byte{0, 33, 183}: "Lexmark International Inc.", + [3]byte{0, 33, 184}: "Inphi Corporation", + [3]byte{0, 33, 185}: "Universal Devices Inc.", + [3]byte{0, 33, 186}: "Texas Instruments", + [3]byte{0, 33, 187}: "Riken Keiki Co., Ltd.", + [3]byte{0, 33, 188}: "ZALA COMPUTER", + [3]byte{0, 33, 189}: "Nintendo Co., Ltd.", + [3]byte{0, 33, 190}: "Cisco, Service Provider Video Technology Group", + [3]byte{0, 33, 191}: "Hitachi High-Tech Control Systems Corporation", + [3]byte{0, 33, 192}: "Mobile Appliance, Inc.", + [3]byte{0, 33, 193}: "ABB Oy / Medium Voltage Products", + [3]byte{0, 33, 194}: "GL Communications Inc", + [3]byte{0, 33, 195}: "CORNELL Communications, Inc.", + [3]byte{0, 33, 196}: "Consilium AB", + [3]byte{0, 33, 197}: "3DSP Corp", + [3]byte{0, 33, 198}: "CSJ Global, Inc.", + [3]byte{0, 33, 199}: "Russound", + [3]byte{0, 33, 200}: "LOHUIS Networks", + [3]byte{0, 33, 201}: "Wavecom Asia Pacific Limited", + [3]byte{0, 33, 202}: "ART System Co., Ltd.", + [3]byte{0, 33, 203}: "SMS TECNOLOGIA ELETRONICA LTDA", + [3]byte{0, 33, 204}: "Flextronics International", + [3]byte{0, 33, 205}: "LiveTV", + [3]byte{0, 33, 206}: "NTC-Metrotek", + [3]byte{0, 33, 207}: "The Crypto Group", + [3]byte{0, 33, 208}: "Global Display Solutions Spa", + [3]byte{0, 33, 209}: "Samsung Electronics Co.,Ltd", + [3]byte{0, 33, 210}: "Samsung Electronics Co.,Ltd", + [3]byte{0, 33, 211}: "BOCOM SECURITY(ASIA PACIFIC) LIMITED", + [3]byte{0, 33, 212}: "Vollmer Werke GmbH", + [3]byte{0, 33, 213}: "X2E GmbH", + [3]byte{0, 33, 214}: "LXI Consortium", + [3]byte{0, 33, 215}: "CISCO SYSTEMS, INC.", + [3]byte{0, 33, 216}: "CISCO SYSTEMS, INC.", + [3]byte{0, 33, 217}: "SEKONIC CORPORATION", + [3]byte{0, 33, 218}: "Automation Products Group Inc.", + [3]byte{0, 33, 219}: "Santachi Video Technology (Shenzhen) Co., Ltd.", + [3]byte{0, 33, 220}: "TECNOALARM S.r.l.", + [3]byte{0, 33, 221}: "Northstar Systems Corp", + [3]byte{0, 33, 222}: "Firepro Wireless", + [3]byte{0, 33, 223}: "Martin Christ GmbH", + [3]byte{0, 33, 224}: "CommAgility Ltd", + [3]byte{0, 33, 225}: "Nortel Networks", + [3]byte{0, 33, 226}: "Creative Electronic GmbH", + [3]byte{0, 33, 227}: "SerialTek LLC", + [3]byte{0, 33, 228}: "I-WIN", + [3]byte{0, 33, 229}: "Display Solution AG", + [3]byte{0, 33, 230}: "Starlight Video Limited", + [3]byte{0, 33, 231}: "Informatics Services Corporation", + [3]byte{0, 33, 232}: "Murata Manufacturing Co., Ltd.", + [3]byte{0, 33, 233}: "Apple", + [3]byte{0, 33, 234}: "Bystronic Laser AG", + [3]byte{0, 33, 235}: "ESP SYSTEMS, LLC", + [3]byte{0, 33, 236}: "Solutronic GmbH", + [3]byte{0, 33, 237}: "Telegesis", + [3]byte{0, 33, 238}: "Full Spectrum Inc.", + [3]byte{0, 33, 239}: "Kapsys", + [3]byte{0, 33, 240}: "EW3 Technologies LLC", + [3]byte{0, 33, 241}: "Tutus Data AB", + [3]byte{0, 33, 242}: "EASY3CALL Technology Limited", + [3]byte{0, 33, 243}: "Si14 SpA", + [3]byte{0, 33, 244}: "INRange Systems, Inc", + [3]byte{0, 33, 245}: "Western Engravers Supply, Inc.", + [3]byte{0, 33, 246}: "Oracle Corporation", + [3]byte{0, 33, 247}: "HPN Supply Chain", + [3]byte{0, 33, 248}: "Enseo, Inc.", + [3]byte{0, 33, 249}: "WIRECOM Technologies", + [3]byte{0, 33, 250}: "A4SP Technologies Ltd.", + [3]byte{0, 33, 251}: "LG Electronics", + [3]byte{0, 33, 252}: "Nokia Danmark A/S", + [3]byte{0, 33, 253}: "DSTA S.L.", + [3]byte{0, 33, 254}: "Nokia Danmark A/S", + [3]byte{0, 33, 255}: "Cyfrowy Polsat SA", + [3]byte{0, 34, 0}: "IBM Corp", + [3]byte{0, 34, 1}: "Aksys Networks Inc", + [3]byte{0, 34, 2}: "Excito Elektronik i Skåne AB", + [3]byte{0, 34, 3}: "Glensound Electronics Ltd", + [3]byte{0, 34, 4}: "KORATEK", + [3]byte{0, 34, 5}: "WeLink Solutions, Inc.", + [3]byte{0, 34, 6}: "Cyberdyne Inc.", + [3]byte{0, 34, 7}: "Inteno Broadband Technology AB", + [3]byte{0, 34, 8}: "Certicom Corp", + [3]byte{0, 34, 9}: "Omron Healthcare Co., Ltd", + [3]byte{0, 34, 10}: "OnLive, Inc", + [3]byte{0, 34, 11}: "National Source Coding Center", + [3]byte{0, 34, 12}: "CISCO SYSTEMS, INC.", + [3]byte{0, 34, 13}: "CISCO SYSTEMS, INC.", + [3]byte{0, 34, 14}: "Indigo Security Co., Ltd.", + [3]byte{0, 34, 15}: "MoCA (Multimedia over Coax Alliance)", + [3]byte{0, 34, 16}: "ARRIS Group, Inc.", + [3]byte{0, 34, 17}: "Rohati Systems", + [3]byte{0, 34, 18}: "CAI Networks, Inc.", + [3]byte{0, 34, 19}: "PCI CORPORATION", + [3]byte{0, 34, 20}: "RINNAI KOREA", + [3]byte{0, 34, 21}: "ASUSTek COMPUTER INC.", + [3]byte{0, 34, 22}: "SHIBAURA VENDING MACHINE CORPORATION", + [3]byte{0, 34, 23}: "Neat Electronics", + [3]byte{0, 34, 24}: "Verivue Inc.", + [3]byte{0, 34, 25}: "Dell Inc", + [3]byte{0, 34, 26}: "Audio Precision", + [3]byte{0, 34, 27}: "Morega Systems", + [3]byte{0, 34, 28}: "PRIVATE", + [3]byte{0, 34, 29}: "Freegene Technology LTD", + [3]byte{0, 34, 30}: "Media Devices Co., Ltd.", + [3]byte{0, 34, 31}: "eSang Technologies Co., Ltd.", + [3]byte{0, 34, 32}: "Mitac Technology Corp", + [3]byte{0, 34, 33}: "ITOH DENKI CO,LTD.", + [3]byte{0, 34, 34}: "Schaffner Deutschland GmbH", + [3]byte{0, 34, 35}: "TimeKeeping Systems, Inc.", + [3]byte{0, 34, 36}: "Good Will Instrument Co., Ltd.", + [3]byte{0, 34, 37}: "Thales Avionics Ltd", + [3]byte{0, 34, 38}: "Avaak, Inc.", + [3]byte{0, 34, 39}: "uv-electronic GmbH", + [3]byte{0, 34, 40}: "Breeze Innovations Ltd.", + [3]byte{0, 34, 41}: "Compumedics Ltd", + [3]byte{0, 34, 42}: "SoundEar A/S", + [3]byte{0, 34, 43}: "Nucomm, Inc.", + [3]byte{0, 34, 44}: "Ceton Corp", + [3]byte{0, 34, 45}: "SMC Networks Inc.", + [3]byte{0, 34, 46}: "maintech GmbH", + [3]byte{0, 34, 47}: "Open Grid Computing, Inc.", + [3]byte{0, 34, 48}: "FutureLogic Inc.", + [3]byte{0, 34, 49}: "SMT&C Co., Ltd.", + [3]byte{0, 34, 50}: "Design Design Technology Ltd", + [3]byte{0, 34, 51}: "ADB Broadband Italia", + [3]byte{0, 34, 52}: "Corventis Inc.", + [3]byte{0, 34, 53}: "Strukton Systems bv", + [3]byte{0, 34, 54}: "VECTOR SP. Z O.O.", + [3]byte{0, 34, 55}: "Shinhint Group", + [3]byte{0, 34, 56}: "LOGIPLUS", + [3]byte{0, 34, 57}: "Indiana Life Sciences Incorporated", + [3]byte{0, 34, 58}: "Scientific Atlanta, Cisco SPVT Group", + [3]byte{0, 34, 59}: "Communication Networks, LLC", + [3]byte{0, 34, 60}: "RATIO Entwicklungen GmbH", + [3]byte{0, 34, 61}: "JumpGen Systems, LLC", + [3]byte{0, 34, 62}: "IRTrans GmbH", + [3]byte{0, 34, 63}: "Netgear Inc.", + [3]byte{0, 34, 64}: "Universal Telecom S/A", + [3]byte{0, 34, 65}: "Apple", + [3]byte{0, 34, 66}: "Alacron Inc.", + [3]byte{0, 34, 67}: "AzureWave Technologies, Inc.", + [3]byte{0, 34, 68}: "Chengdu Linkon Communications Device Co., Ltd", + [3]byte{0, 34, 69}: "Leine & Linde AB", + [3]byte{0, 34, 70}: "Evoc Intelligent Technology Co.,Ltd.", + [3]byte{0, 34, 71}: "DAC ENGINEERING CO., LTD.", + [3]byte{0, 34, 72}: "Microsoft Corporation", + [3]byte{0, 34, 73}: "HOME MULTIENERGY SL", + [3]byte{0, 34, 74}: "RAYLASE AG", + [3]byte{0, 34, 75}: "AIRTECH TECHNOLOGIES, INC.", + [3]byte{0, 34, 76}: "Nintendo Co., Ltd.", + [3]byte{0, 34, 77}: "MITAC INTERNATIONAL CORP.", + [3]byte{0, 34, 78}: "SEEnergy Corp.", + [3]byte{0, 34, 79}: "Byzoro Networks Ltd.", + [3]byte{0, 34, 80}: "Point Six Wireless, LLC", + [3]byte{0, 34, 81}: "Lumasense Technologies", + [3]byte{0, 34, 82}: "ZOLL Lifecor Corporation", + [3]byte{0, 34, 83}: "Entorian Technologies", + [3]byte{0, 34, 84}: "Bigelow Aerospace", + [3]byte{0, 34, 85}: "CISCO SYSTEMS, INC.", + [3]byte{0, 34, 86}: "CISCO SYSTEMS, INC.", + [3]byte{0, 34, 87}: "3Com Europe Ltd", + [3]byte{0, 34, 88}: "Taiyo Yuden Co., Ltd.", + [3]byte{0, 34, 89}: "Guangzhou New Postcom Equipment Co.,Ltd.", + [3]byte{0, 34, 90}: "Garde Security AB", + [3]byte{0, 34, 91}: "Teradici Corporation", + [3]byte{0, 34, 92}: "Multimedia & Communication Technology", + [3]byte{0, 34, 93}: "Digicable Network India Pvt. Ltd.", + [3]byte{0, 34, 94}: "Uwin Technologies Co.,LTD", + [3]byte{0, 34, 95}: "Liteon Technology Corporation", + [3]byte{0, 34, 96}: "AFREEY Inc.", + [3]byte{0, 34, 97}: "Frontier Silicon Ltd", + [3]byte{0, 34, 98}: "BEP Marine", + [3]byte{0, 34, 99}: "Koos Technical Services, Inc.", + [3]byte{0, 34, 100}: "Hewlett-Packard Company", + [3]byte{0, 34, 101}: "Nokia Danmark A/S", + [3]byte{0, 34, 102}: "Nokia Danmark A/S", + [3]byte{0, 34, 103}: "Nortel Networks", + [3]byte{0, 34, 104}: "Hon Hai Precision Ind. Co., Ltd.", + [3]byte{0, 34, 105}: "Hon Hai Precision Ind. Co., Ltd.", + [3]byte{0, 34, 106}: "Honeywell", + [3]byte{0, 34, 107}: "Cisco-Linksys, LLC", + [3]byte{0, 34, 108}: "LinkSprite Technologies, Inc.", + [3]byte{0, 34, 109}: "Shenzhen GIEC Electronics Co., Ltd.", + [3]byte{0, 34, 110}: "Gowell Electronic Limited", + [3]byte{0, 34, 111}: "3onedata Technology Co. Ltd.", + [3]byte{0, 34, 112}: "ABK North America, LLC", + [3]byte{0, 34, 113}: "Jäger Computergesteuerte Meßtechnik GmbH.", + [3]byte{0, 34, 114}: "American Micro-Fuel Device Corp.", + [3]byte{0, 34, 115}: "Techway", + [3]byte{0, 34, 116}: "FamilyPhone AB", + [3]byte{0, 34, 117}: "Belkin International Inc.", + [3]byte{0, 34, 118}: "Triple EYE B.V.", + [3]byte{0, 34, 119}: "NEC Australia Pty Ltd", + [3]byte{0, 34, 120}: "Shenzhen Tongfang Multimedia Technology Co.,Ltd.", + [3]byte{0, 34, 121}: "Nippon Conlux Co., Ltd.", + [3]byte{0, 34, 122}: "Telecom Design", + [3]byte{0, 34, 123}: "Apogee Labs, Inc.", + [3]byte{0, 34, 124}: "Woori SMT Co.,ltd", + [3]byte{0, 34, 125}: "YE DATA INC.", + [3]byte{0, 34, 126}: "Chengdu 30Kaitian Communication Industry Co.Ltd", + [3]byte{0, 34, 127}: "Ruckus Wireless", + [3]byte{0, 34, 128}: "A2B Electronics AB", + [3]byte{0, 34, 129}: "Daintree Networks Pty", + [3]byte{0, 34, 130}: "8086 Consultancy", + [3]byte{0, 34, 131}: "Juniper Networks", + [3]byte{0, 34, 132}: "DESAY A&V SCIENCE AND TECHNOLOGY CO.,LTD", + [3]byte{0, 34, 133}: "NOMUS COMM SYSTEMS", + [3]byte{0, 34, 134}: "ASTRON", + [3]byte{0, 34, 135}: "Titan Wireless LLC", + [3]byte{0, 34, 136}: "Sagrad, Inc.", + [3]byte{0, 34, 137}: "Optosecurity Inc.", + [3]byte{0, 34, 138}: "Teratronik elektronische systeme gmbh", + [3]byte{0, 34, 139}: "Kensington Computer Products Group", + [3]byte{0, 34, 140}: "Photon Europe GmbH", + [3]byte{0, 34, 141}: "GBS Laboratories LLC", + [3]byte{0, 34, 142}: "TV-NUMERIC", + [3]byte{0, 34, 143}: "CNRS", + [3]byte{0, 34, 144}: "CISCO SYSTEMS, INC.", + [3]byte{0, 34, 145}: "CISCO SYSTEMS, INC.", + [3]byte{0, 34, 146}: "Cinetal", + [3]byte{0, 34, 147}: "ZTE Corporation", + [3]byte{0, 34, 148}: "Kyocera Corporation", + [3]byte{0, 34, 149}: "SGM Technology for lighting spa", + [3]byte{0, 34, 150}: "LinoWave Corporation", + [3]byte{0, 34, 151}: "XMOS Semiconductor", + [3]byte{0, 34, 152}: "Sony Ericsson Mobile Communications", + [3]byte{0, 34, 153}: "SeaMicro Inc.", + [3]byte{0, 34, 154}: "Lastar, Inc.", + [3]byte{0, 34, 155}: "AverLogic Technologies, Inc.", + [3]byte{0, 34, 156}: "Verismo Networks Inc", + [3]byte{0, 34, 157}: "PYUNG-HWA IND.CO.,LTD", + [3]byte{0, 34, 158}: "Social Aid Research Co., Ltd.", + [3]byte{0, 34, 159}: "Sensys Traffic AB", + [3]byte{0, 34, 160}: "Delphi Corporation", + [3]byte{0, 34, 161}: "Huawei Symantec Technologies Co.,Ltd.", + [3]byte{0, 34, 162}: "Xtramus Technologies", + [3]byte{0, 34, 163}: "California Eastern Laboratories", + [3]byte{0, 34, 164}: "2Wire", + [3]byte{0, 34, 165}: "Texas Instruments", + [3]byte{0, 34, 166}: "Sony Computer Entertainment America", + [3]byte{0, 34, 167}: "Tyco Electronics AMP GmbH", + [3]byte{0, 34, 168}: "Ouman Oy", + [3]byte{0, 34, 169}: "LG Electronics Inc", + [3]byte{0, 34, 170}: "Nintendo Co., Ltd.", + [3]byte{0, 34, 171}: "Shenzhen Turbosight Technology Ltd", + [3]byte{0, 34, 172}: "Hangzhou Siyuan Tech. Co., Ltd", + [3]byte{0, 34, 173}: "TELESIS TECHNOLOGIES, INC.", + [3]byte{0, 34, 174}: "Mattel Inc.", + [3]byte{0, 34, 175}: "Safety Vision", + [3]byte{0, 34, 176}: "D-Link Corporation", + [3]byte{0, 34, 177}: "Elbit Systems", + [3]byte{0, 34, 178}: "4RF Communications Ltd", + [3]byte{0, 34, 179}: "Sei S.p.A.", + [3]byte{0, 34, 180}: "ARRIS Group, Inc.", + [3]byte{0, 34, 181}: "NOVITA", + [3]byte{0, 34, 182}: "Superflow Technologies Group", + [3]byte{0, 34, 183}: "GSS Grundig SAT-Systems GmbH", + [3]byte{0, 34, 184}: "Norcott", + [3]byte{0, 34, 185}: "Analogix Seminconductor, Inc", + [3]byte{0, 34, 186}: "HUTH Elektronik Systeme GmbH", + [3]byte{0, 34, 187}: "beyerdynamic GmbH & Co. KG", + [3]byte{0, 34, 188}: "JDSU France SAS", + [3]byte{0, 34, 189}: "CISCO SYSTEMS, INC.", + [3]byte{0, 34, 190}: "CISCO SYSTEMS, INC.", + [3]byte{0, 34, 191}: "SieAmp Group of Companies", + [3]byte{0, 34, 192}: "Shenzhen Forcelink Electronic Co, Ltd", + [3]byte{0, 34, 193}: "Active Storage Inc.", + [3]byte{0, 34, 194}: "Proview Eletrônica do Brasil LTDA", + [3]byte{0, 34, 195}: "Zeeport Technology Inc.", + [3]byte{0, 34, 196}: "epro GmbH", + [3]byte{0, 34, 197}: "INFORSON Co,Ltd.", + [3]byte{0, 34, 198}: "Sutus Inc", + [3]byte{0, 34, 199}: "SEGGER Microcontroller GmbH & Co. KG", + [3]byte{0, 34, 200}: "Applied Instruments B.V.", + [3]byte{0, 34, 201}: "Lenord, Bauer & Co GmbH", + [3]byte{0, 34, 202}: "Anviz Biometric Tech. Co., Ltd.", + [3]byte{0, 34, 203}: "IONODES Inc.", + [3]byte{0, 34, 204}: "SciLog, Inc.", + [3]byte{0, 34, 205}: "Ared Technology Co., Ltd.", + [3]byte{0, 34, 206}: "Cisco, Service Provider Video Technology Group", + [3]byte{0, 34, 207}: "PLANEX Communications INC", + [3]byte{0, 34, 208}: "Polar Electro Oy", + [3]byte{0, 34, 209}: "Albrecht Jung GmbH & Co. KG", + [3]byte{0, 34, 210}: "All Earth Comércio de Eletrônicos LTDA.", + [3]byte{0, 34, 211}: "Hub-Tech", + [3]byte{0, 34, 212}: "ComWorth Co., Ltd.", + [3]byte{0, 34, 213}: "Eaton Corp. Electrical Group Data Center Solutions - Pulizzi", + [3]byte{0, 34, 214}: "Cypak AB", + [3]byte{0, 34, 215}: "Nintendo Co., Ltd.", + [3]byte{0, 34, 216}: "Shenzhen GST Security and Safety Technology Limited", + [3]byte{0, 34, 217}: "Fortex Industrial Ltd.", + [3]byte{0, 34, 218}: "ANATEK, LLC", + [3]byte{0, 34, 219}: "Translogic Corporation", + [3]byte{0, 34, 220}: "Vigil Health Solutions Inc.", + [3]byte{0, 34, 221}: "Protecta Electronics Ltd", + [3]byte{0, 34, 222}: "OPPO Digital, Inc.", + [3]byte{0, 34, 223}: "TAMUZ Monitors", + [3]byte{0, 34, 224}: "Atlantic Software Technologies S.r.L.", + [3]byte{0, 34, 225}: "ZORT Labs, LLC.", + [3]byte{0, 34, 226}: "WABTEC Transit Division", + [3]byte{0, 34, 227}: "Amerigon", + [3]byte{0, 34, 228}: "APASS TECHNOLOGY CO., LTD.", + [3]byte{0, 34, 229}: "Fisher-Rosemount Systems Inc.", + [3]byte{0, 34, 230}: "Intelligent Data", + [3]byte{0, 34, 231}: "WPS Parking Systems", + [3]byte{0, 34, 232}: "Applition Co., Ltd.", + [3]byte{0, 34, 233}: "ProVision Communications", + [3]byte{0, 34, 234}: "Rustelcom Inc.", + [3]byte{0, 34, 235}: "Data Respons A/S", + [3]byte{0, 34, 236}: "IDEALBT TECHNOLOGY CORPORATION", + [3]byte{0, 34, 237}: "TSI Power Corporation", + [3]byte{0, 34, 238}: "Algo Communication Products Ltd", + [3]byte{0, 34, 239}: "iWDL Technologies", + [3]byte{0, 34, 240}: "3 Greens Aviation Limited", + [3]byte{0, 34, 241}: "PRIVATE", + [3]byte{0, 34, 242}: "SunPower Corp", + [3]byte{0, 34, 243}: "SHARP Corporation", + [3]byte{0, 34, 244}: "AMPAK Technology, Inc.", + [3]byte{0, 34, 245}: "Advanced Realtime Tracking GmbH", + [3]byte{0, 34, 246}: "Syracuse Research Corporation", + [3]byte{0, 34, 247}: "Conceptronic", + [3]byte{0, 34, 248}: "PIMA Electronic Systems Ltd.", + [3]byte{0, 34, 249}: "Pollin Electronic GmbH", + [3]byte{0, 34, 250}: "Intel Corporate", + [3]byte{0, 34, 251}: "Intel Corporate", + [3]byte{0, 34, 252}: "Nokia Danmark A/S", + [3]byte{0, 34, 253}: "Nokia Danmark A/S", + [3]byte{0, 34, 254}: "Microprocessor Designs Inc", + [3]byte{0, 34, 255}: "iWDL Technologies", + [3]byte{0, 35, 0}: "Cayee Computer Ltd.", + [3]byte{0, 35, 1}: "Witron Technology Limited", + [3]byte{0, 35, 2}: "Cobalt Digital, Inc.", + [3]byte{0, 35, 3}: "LITE-ON IT Corporation", + [3]byte{0, 35, 4}: "CISCO SYSTEMS, INC.", + [3]byte{0, 35, 5}: "CISCO SYSTEMS, INC.", + [3]byte{0, 35, 6}: "ALPS Electric Co., Ltd", + [3]byte{0, 35, 7}: "FUTURE INNOVATION TECH CO.,LTD", + [3]byte{0, 35, 8}: "Arcadyan Technology Corporation", + [3]byte{0, 35, 9}: "Janam Technologies LLC", + [3]byte{0, 35, 10}: "ARBURG GmbH & Co KG", + [3]byte{0, 35, 11}: "ARRIS Group, Inc.", + [3]byte{0, 35, 12}: "CLOVER ELECTRONICS CO.,LTD.", + [3]byte{0, 35, 13}: "Nortel Networks", + [3]byte{0, 35, 14}: "Gorba AG", + [3]byte{0, 35, 15}: "Hirsch Electronics Corporation", + [3]byte{0, 35, 16}: "LNC Technology Co., Ltd.", + [3]byte{0, 35, 17}: "Gloscom Co., Ltd.", + [3]byte{0, 35, 18}: "Apple", + [3]byte{0, 35, 19}: "Qool Technologies Ltd.", + [3]byte{0, 35, 20}: "Intel Corporate", + [3]byte{0, 35, 21}: "Intel Corporate", + [3]byte{0, 35, 22}: "KISAN ELECTRONICS CO", + [3]byte{0, 35, 23}: "Lasercraft Inc", + [3]byte{0, 35, 24}: "Toshiba", + [3]byte{0, 35, 25}: "Sielox LLC", + [3]byte{0, 35, 26}: "ITF Co., Ltd.", + [3]byte{0, 35, 27}: "Danaher Motion - Kollmorgen", + [3]byte{0, 35, 28}: "Fourier Systems Ltd.", + [3]byte{0, 35, 29}: "Deltacom Electronics Ltd", + [3]byte{0, 35, 30}: "Cezzer Multimedia Technologies", + [3]byte{0, 35, 31}: "Guangda Electronic & Telecommunication Technology Development Co., Ltd.", + [3]byte{0, 35, 32}: "Nicira Networks", + [3]byte{0, 35, 33}: "Avitech International Corp", + [3]byte{0, 35, 34}: "KISS Teknical Solutions, Inc.", + [3]byte{0, 35, 35}: "Zylin AS", + [3]byte{0, 35, 36}: "G-PRO COMPUTER", + [3]byte{0, 35, 37}: "IOLAN Holding", + [3]byte{0, 35, 38}: "Fujitsu Limited", + [3]byte{0, 35, 39}: "Shouyo Electronics CO., LTD", + [3]byte{0, 35, 40}: "ALCON TELECOMMUNICATIONS CO., LTD.", + [3]byte{0, 35, 41}: "DDRdrive LLC", + [3]byte{0, 35, 42}: "eonas IT-Beratung und -Entwicklung GmbH", + [3]byte{0, 35, 43}: "IRD A/S", + [3]byte{0, 35, 44}: "Senticare", + [3]byte{0, 35, 45}: "SandForce", + [3]byte{0, 35, 46}: "Kedah Electronics Engineering, LLC", + [3]byte{0, 35, 47}: "Advanced Card Systems Ltd.", + [3]byte{0, 35, 48}: "DIZIPIA, INC.", + [3]byte{0, 35, 49}: "Nintendo Co., Ltd.", + [3]byte{0, 35, 50}: "Apple", + [3]byte{0, 35, 51}: "CISCO SYSTEMS, INC.", + [3]byte{0, 35, 52}: "CISCO SYSTEMS, INC.", + [3]byte{0, 35, 53}: "Linkflex Co.,Ltd", + [3]byte{0, 35, 54}: "METEL s.r.o.", + [3]byte{0, 35, 55}: "Global Star Solutions ULC", + [3]byte{0, 35, 56}: "OJ-Electronics A/S", + [3]byte{0, 35, 57}: "Samsung Electronics", + [3]byte{0, 35, 58}: "Samsung Electronics Co.,Ltd", + [3]byte{0, 35, 59}: "C-Matic Systems Ltd", + [3]byte{0, 35, 60}: "Alflex", + [3]byte{0, 35, 61}: "Novero holding B.V.", + [3]byte{0, 35, 62}: "Alcatel-Lucent-IPD", + [3]byte{0, 35, 63}: "Purechoice Inc", + [3]byte{0, 35, 64}: "MiX Telematics", + [3]byte{0, 35, 65}: "Siemens AB, Infrastructure & Cities, Building Technologies Division, IC BT SSP SP BA PR", + [3]byte{0, 35, 66}: "Coffee Equipment Company", + [3]byte{0, 35, 67}: "TEM AG", + [3]byte{0, 35, 68}: "Objective Interface Systems, Inc.", + [3]byte{0, 35, 69}: "Sony Ericsson Mobile Communications", + [3]byte{0, 35, 70}: "Vestac", + [3]byte{0, 35, 71}: "ProCurve Networking by HP", + [3]byte{0, 35, 72}: "SAGEM COMMUNICATION", + [3]byte{0, 35, 73}: "Helmholtz Centre Berlin for Material and Energy", + [3]byte{0, 35, 74}: "PRIVATE", + [3]byte{0, 35, 75}: "Inyuan Technology Inc.", + [3]byte{0, 35, 76}: "KTC AB", + [3]byte{0, 35, 77}: "Hon Hai Precision Ind. Co., Ltd.", + [3]byte{0, 35, 78}: "Hon Hai Precision Ind. Co., Ltd.", + [3]byte{0, 35, 79}: "Luminous Power Technologies Pvt. Ltd.", + [3]byte{0, 35, 80}: "LynTec", + [3]byte{0, 35, 81}: "2Wire", + [3]byte{0, 35, 82}: "DATASENSOR S.p.A.", + [3]byte{0, 35, 83}: "F E T Elettronica snc", + [3]byte{0, 35, 84}: "ASUSTek COMPUTER INC.", + [3]byte{0, 35, 85}: "Kinco Automation(Shanghai) Ltd.", + [3]byte{0, 35, 86}: "Packet Forensics LLC", + [3]byte{0, 35, 87}: "Pitronot Technologies and Engineering P.T.E. Ltd.", + [3]byte{0, 35, 88}: "SYSTEL SA", + [3]byte{0, 35, 89}: "Benchmark Electronics ( Thailand ) Public Company Limited", + [3]byte{0, 35, 90}: "COMPAL INFORMATION (KUNSHAN) CO., Ltd.", + [3]byte{0, 35, 91}: "Gulfstream", + [3]byte{0, 35, 92}: "Aprius, Inc.", + [3]byte{0, 35, 93}: "CISCO SYSTEMS, INC.", + [3]byte{0, 35, 94}: "CISCO SYSTEMS, INC.", + [3]byte{0, 35, 95}: "Silicon Micro Sensors GmbH", + [3]byte{0, 35, 96}: "Lookit Technology Co., Ltd", + [3]byte{0, 35, 97}: "Unigen Corporation", + [3]byte{0, 35, 98}: "Goldline Controls", + [3]byte{0, 35, 99}: "Zhuhai RaySharp Technology Co., Ltd.", + [3]byte{0, 35, 100}: "Power Instruments Pte Ltd", + [3]byte{0, 35, 101}: "ELKA-Elektronik GmbH", + [3]byte{0, 35, 102}: "Beijing Siasun Electronic System Co.,Ltd.", + [3]byte{0, 35, 103}: "UniControls a.s.", + [3]byte{0, 35, 104}: "Motorola", + [3]byte{0, 35, 105}: "Cisco-Linksys, LLC", + [3]byte{0, 35, 106}: "SmartRG Inc", + [3]byte{0, 35, 107}: "Xembedded, Inc.", + [3]byte{0, 35, 108}: "Apple", + [3]byte{0, 35, 109}: "ResMed Ltd", + [3]byte{0, 35, 110}: "Burster GmbH & Co KG", + [3]byte{0, 35, 111}: "DAQ System", + [3]byte{0, 35, 112}: "Snell", + [3]byte{0, 35, 113}: "SOAM Systel", + [3]byte{0, 35, 114}: "MORE STAR INDUSTRIAL GROUP LIMITED", + [3]byte{0, 35, 115}: "GridIron Systems, Inc.", + [3]byte{0, 35, 116}: "ARRIS Group, Inc.", + [3]byte{0, 35, 117}: "ARRIS Group, Inc.", + [3]byte{0, 35, 118}: "HTC Corporation", + [3]byte{0, 35, 119}: "Isotek Electronics Ltd", + [3]byte{0, 35, 120}: "GN Netcom A/S", + [3]byte{0, 35, 121}: "Union Business Machines Co. Ltd.", + [3]byte{0, 35, 122}: "RIM", + [3]byte{0, 35, 123}: "WHDI LLC", + [3]byte{0, 35, 124}: "NEOTION", + [3]byte{0, 35, 125}: "Hewlett-Packard Company", + [3]byte{0, 35, 126}: "ELSTER GMBH", + [3]byte{0, 35, 127}: "PLANTRONICS, INC.", + [3]byte{0, 35, 128}: "Nanoteq", + [3]byte{0, 35, 129}: "Lengda Technology(Xiamen) Co.,Ltd.", + [3]byte{0, 35, 130}: "Lih Rong Electronic Enterprise Co., Ltd.", + [3]byte{0, 35, 131}: "InMage Systems Inc", + [3]byte{0, 35, 132}: "GGH Engineering s.r.l.", + [3]byte{0, 35, 133}: "ANTIPODE", + [3]byte{0, 35, 134}: "Tour & Andersson AB", + [3]byte{0, 35, 135}: "ThinkFlood, Inc.", + [3]byte{0, 35, 136}: "V.T. Telematica S.p.a.", + [3]byte{0, 35, 137}: "HANGZHOU H3C Technologies Co., Ltd.", + [3]byte{0, 35, 138}: "Ciena Corporation", + [3]byte{0, 35, 139}: "Quanta Computer Inc.", + [3]byte{0, 35, 140}: "PRIVATE", + [3]byte{0, 35, 141}: "Techno Design Co., Ltd.", + [3]byte{0, 35, 142}: "Pirelli Tyre S.p.A.", + [3]byte{0, 35, 143}: "NIDEC COPAL CORPORATION", + [3]byte{0, 35, 144}: "Algolware Corporation", + [3]byte{0, 35, 145}: "Maxian", + [3]byte{0, 35, 146}: "Proteus Industries Inc.", + [3]byte{0, 35, 147}: "AJINEXTEK", + [3]byte{0, 35, 148}: "Samjeon", + [3]byte{0, 35, 149}: "ARRIS Group, Inc.", + [3]byte{0, 35, 150}: "ANDES TECHNOLOGY CORPORATION", + [3]byte{0, 35, 151}: "Westell Technologies Inc.", + [3]byte{0, 35, 152}: "Sky Control", + [3]byte{0, 35, 153}: "VD Division, Samsung Electronics Co.", + [3]byte{0, 35, 154}: "EasyData Hardware GmbH", + [3]byte{0, 35, 155}: "Elster Solutions, LLC", + [3]byte{0, 35, 156}: "Juniper Networks", + [3]byte{0, 35, 157}: "Mapower Electronics Co., Ltd", + [3]byte{0, 35, 158}: "Jiangsu Lemote Technology Corporation Limited", + [3]byte{0, 35, 159}: "Institut für Prüftechnik", + [3]byte{0, 35, 160}: "Hana CNS Co., LTD.", + [3]byte{0, 35, 161}: "Trend Electronics Ltd", + [3]byte{0, 35, 162}: "ARRIS Group, Inc.", + [3]byte{0, 35, 163}: "ARRIS Group, Inc.", + [3]byte{0, 35, 164}: "New Concepts Development Corp.", + [3]byte{0, 35, 165}: "SageTV, LLC", + [3]byte{0, 35, 166}: "E-Mon", + [3]byte{0, 35, 167}: "Redpine Signals, Inc.", + [3]byte{0, 35, 168}: "Marshall Electronics", + [3]byte{0, 35, 169}: "Beijing Detianquan Electromechanical Equipment Co., Ltd", + [3]byte{0, 35, 170}: "HFR, Inc.", + [3]byte{0, 35, 171}: "CISCO SYSTEMS, INC.", + [3]byte{0, 35, 172}: "CISCO SYSTEMS, INC.", + [3]byte{0, 35, 173}: "Xmark Corporation", + [3]byte{0, 35, 174}: "Dell Inc.", + [3]byte{0, 35, 175}: "ARRIS Group, Inc.", + [3]byte{0, 35, 176}: "COMXION Technology Inc.", + [3]byte{0, 35, 177}: "Longcheer Technology (Singapore) Pte Ltd", + [3]byte{0, 35, 178}: "Intelligent Mechatronic Systems Inc", + [3]byte{0, 35, 179}: "Lyyn AB", + [3]byte{0, 35, 180}: "Nokia Danmark A/S", + [3]byte{0, 35, 181}: "ORTANA LTD", + [3]byte{0, 35, 182}: "SECURITE COMMUNICATIONS / HONEYWELL", + [3]byte{0, 35, 183}: "Q-Light Co., Ltd.", + [3]byte{0, 35, 184}: "Sichuan Jiuzhou Electronic Technology Co.,Ltd", + [3]byte{0, 35, 185}: "EADS Deutschland GmbH", + [3]byte{0, 35, 186}: "Chroma", + [3]byte{0, 35, 187}: "Schmitt Industries", + [3]byte{0, 35, 188}: "EQ-SYS GmbH", + [3]byte{0, 35, 189}: "Digital Ally, Inc.", + [3]byte{0, 35, 190}: "Cisco SPVTG", + [3]byte{0, 35, 191}: "Mainpine, Inc.", + [3]byte{0, 35, 192}: "Broadway Networks", + [3]byte{0, 35, 193}: "Securitas Direct AB", + [3]byte{0, 35, 194}: "SAMSUNG Electronics. Co. LTD", + [3]byte{0, 35, 195}: "LogMeIn, Inc.", + [3]byte{0, 35, 196}: "Lux Lumen", + [3]byte{0, 35, 197}: "Radiation Safety and Control Services Inc", + [3]byte{0, 35, 198}: "SMC Corporation", + [3]byte{0, 35, 199}: "AVSystem", + [3]byte{0, 35, 200}: "TEAM-R", + [3]byte{0, 35, 201}: "Sichuan Tianyi Information Science & Technology Stock CO.,LTD", + [3]byte{0, 35, 202}: "Behind The Set, LLC", + [3]byte{0, 35, 203}: "Shenzhen Full-join Technology Co.,Ltd", + [3]byte{0, 35, 204}: "Nintendo Co., Ltd.", + [3]byte{0, 35, 205}: "TP-LINK TECHNOLOGIES CO., LTD.", + [3]byte{0, 35, 206}: "KITA DENSHI CORPORATION", + [3]byte{0, 35, 207}: "CUMMINS-ALLISON CORP.", + [3]byte{0, 35, 208}: "Uniloc USA Inc.", + [3]byte{0, 35, 209}: "TRG", + [3]byte{0, 35, 210}: "Inhand Electronics, Inc.", + [3]byte{0, 35, 211}: "AirLink WiFi Networking Corp.", + [3]byte{0, 35, 212}: "Texas Instruments", + [3]byte{0, 35, 213}: "WAREMA electronic GmbH", + [3]byte{0, 35, 214}: "Samsung Electronics Co.,LTD", + [3]byte{0, 35, 215}: "Samsung Electronics", + [3]byte{0, 35, 216}: "Ball-It Oy", + [3]byte{0, 35, 217}: "Banner Engineering", + [3]byte{0, 35, 218}: "Industrial Computer Source (Deutschland)GmbH", + [3]byte{0, 35, 219}: "saxnet gmbh", + [3]byte{0, 35, 220}: "Benein, Inc", + [3]byte{0, 35, 221}: "ELGIN S.A.", + [3]byte{0, 35, 222}: "Ansync Inc.", + [3]byte{0, 35, 223}: "Apple", + [3]byte{0, 35, 224}: "INO Therapeutics LLC", + [3]byte{0, 35, 225}: "Cavena Image Products AB", + [3]byte{0, 35, 226}: "SEA Signalisation", + [3]byte{0, 35, 227}: "Microtronic AG", + [3]byte{0, 35, 228}: "IPnect co. ltd.", + [3]byte{0, 35, 229}: "IPaXiom Networks", + [3]byte{0, 35, 230}: "Pirkus, Inc.", + [3]byte{0, 35, 231}: "Hinke A/S", + [3]byte{0, 35, 232}: "Demco Corp.", + [3]byte{0, 35, 233}: "F5 Networks, Inc.", + [3]byte{0, 35, 234}: "CISCO SYSTEMS, INC.", + [3]byte{0, 35, 235}: "CISCO SYSTEMS, INC.", + [3]byte{0, 35, 236}: "Algorithmix GmbH", + [3]byte{0, 35, 237}: "ARRIS Group, Inc.", + [3]byte{0, 35, 238}: "ARRIS Group, Inc.", + [3]byte{0, 35, 239}: "Zuend Systemtechnik AG", + [3]byte{0, 35, 240}: "Shanghai Jinghan Weighing Apparatus Co. Ltd.", + [3]byte{0, 35, 241}: "Sony Ericsson Mobile Communications", + [3]byte{0, 35, 242}: "TVLogic", + [3]byte{0, 35, 243}: "Glocom, Inc.", + [3]byte{0, 35, 244}: "Masternaut", + [3]byte{0, 35, 245}: "WILO SE", + [3]byte{0, 35, 246}: "Softwell Technology Co., Ltd.", + [3]byte{0, 35, 247}: "PRIVATE", + [3]byte{0, 35, 248}: "ZyXEL Communications Corporation", + [3]byte{0, 35, 249}: "Double-Take Software, INC.", + [3]byte{0, 35, 250}: "RG Nets, Inc.", + [3]byte{0, 35, 251}: "IP Datatel, LLC.", + [3]byte{0, 35, 252}: "Ultra Stereo Labs, Inc", + [3]byte{0, 35, 253}: "AFT Atlas Fahrzeugtechnik GmbH", + [3]byte{0, 35, 254}: "Biodevices, SA", + [3]byte{0, 35, 255}: "Beijing HTTC Technology Ltd.", + [3]byte{0, 36, 0}: "Nortel Networks", + [3]byte{0, 36, 1}: "D-Link Corporation", + [3]byte{0, 36, 2}: "Op-Tection GmbH", + [3]byte{0, 36, 3}: "Nokia Danmark A/S", + [3]byte{0, 36, 4}: "Nokia Danmark A/S", + [3]byte{0, 36, 5}: "Dilog Nordic AB", + [3]byte{0, 36, 6}: "Pointmobile", + [3]byte{0, 36, 7}: "TELEM SAS", + [3]byte{0, 36, 8}: "Pacific Biosciences", + [3]byte{0, 36, 9}: "The Toro Company", + [3]byte{0, 36, 10}: "US Beverage Net", + [3]byte{0, 36, 11}: "Virtual Computer Inc.", + [3]byte{0, 36, 12}: "DELEC GmbH", + [3]byte{0, 36, 13}: "OnePath Networks LTD.", + [3]byte{0, 36, 14}: "Inventec Besta Co., Ltd.", + [3]byte{0, 36, 15}: "Ishii Tool & Engineering Corporation", + [3]byte{0, 36, 16}: "NUETEQ Technology,Inc.", + [3]byte{0, 36, 17}: "PharmaSmart LLC", + [3]byte{0, 36, 18}: "Benign Technologies Co, Ltd.", + [3]byte{0, 36, 19}: "CISCO SYSTEMS, INC.", + [3]byte{0, 36, 20}: "CISCO SYSTEMS, INC.", + [3]byte{0, 36, 21}: "Magnetic Autocontrol GmbH", + [3]byte{0, 36, 22}: "Any Use", + [3]byte{0, 36, 23}: "Thomson Telecom Belgium", + [3]byte{0, 36, 24}: "Nextwave Semiconductor", + [3]byte{0, 36, 25}: "PRIVATE", + [3]byte{0, 36, 26}: "Red Beetle Inc.", + [3]byte{0, 36, 27}: "iWOW Communications Pte Ltd", + [3]byte{0, 36, 28}: "FuGang Electronic (DG) Co.,Ltd", + [3]byte{0, 36, 29}: "GIGA-BYTE TECHNOLOGY CO.,LTD.", + [3]byte{0, 36, 30}: "Nintendo Co., Ltd.", + [3]byte{0, 36, 31}: "DCT-Delta GmbH", + [3]byte{0, 36, 32}: "NetUP Inc.", + [3]byte{0, 36, 33}: "MICRO-STAR INT'L CO., LTD.", + [3]byte{0, 36, 34}: "Knapp Logistik Automation GmbH", + [3]byte{0, 36, 35}: "AzureWave Technologies (Shanghai) Inc.", + [3]byte{0, 36, 36}: "Axis Network Technology", + [3]byte{0, 36, 37}: "Shenzhenshi chuangzhicheng Technology Co.,Ltd", + [3]byte{0, 36, 38}: "NOHMI BOSAI LTD.", + [3]byte{0, 36, 39}: "SSI COMPUTER CORP", + [3]byte{0, 36, 40}: "EnergyICT", + [3]byte{0, 36, 41}: "MK MASTER INC.", + [3]byte{0, 36, 42}: "Hittite Microwave Corporation", + [3]byte{0, 36, 43}: "Hon Hai Precision Ind.Co.,Ltd.", + [3]byte{0, 36, 44}: "Hon Hai Precision Ind. Co., Ltd.", + [3]byte{0, 36, 46}: "Datastrip Inc.", + [3]byte{0, 36, 47}: "Micron", + [3]byte{0, 36, 48}: "Ruby Tech Corp.", + [3]byte{0, 36, 49}: "Uni-v co.,ltd", + [3]byte{0, 36, 50}: "Neostar Technology Co.,LTD", + [3]byte{0, 36, 51}: "Alps Electric Co., Ltd", + [3]byte{0, 36, 52}: "Lectrosonics, Inc.", + [3]byte{0, 36, 53}: "WIDE CORPORATION", + [3]byte{0, 36, 54}: "Apple", + [3]byte{0, 36, 55}: "Motorola - BSG", + [3]byte{0, 36, 56}: "Brocade Communications Systems, Inc", + [3]byte{0, 36, 57}: "Digital Barriers Advanced Technologies", + [3]byte{0, 36, 58}: "Ludl Electronic Products", + [3]byte{0, 36, 59}: "CSSI (S) Pte Ltd", + [3]byte{0, 36, 60}: "S.A.A.A.", + [3]byte{0, 36, 61}: "Emerson Appliance Motors and Controls", + [3]byte{0, 36, 63}: "Storwize, Inc.", + [3]byte{0, 36, 64}: "Halo Monitoring, Inc.", + [3]byte{0, 36, 65}: "Wanzl Metallwarenfabrik GmbH", + [3]byte{0, 36, 66}: "Axona Limited", + [3]byte{0, 36, 67}: "Nortel Networks", + [3]byte{0, 36, 68}: "Nintendo Co., Ltd.", + [3]byte{0, 36, 69}: "CommScope Canada Inc.", + [3]byte{0, 36, 70}: "MMB Research Inc.", + [3]byte{0, 36, 71}: "Kaztek Systems", + [3]byte{0, 36, 72}: "SpiderCloud Wireless, Inc", + [3]byte{0, 36, 73}: "Shen Zhen Lite Star Electronics Technology Co., Ltd", + [3]byte{0, 36, 74}: "Voyant International", + [3]byte{0, 36, 75}: "PERCEPTRON INC", + [3]byte{0, 36, 76}: "Solartron Metrology Ltd", + [3]byte{0, 36, 77}: "Hokkaido Electronics Corporation", + [3]byte{0, 36, 78}: "RadChips, Inc.", + [3]byte{0, 36, 79}: "Asantron Technologies Ltd.", + [3]byte{0, 36, 80}: "CISCO SYSTEMS, INC.", + [3]byte{0, 36, 81}: "CISCO SYSTEMS, INC.", + [3]byte{0, 36, 82}: "Silicon Software GmbH", + [3]byte{0, 36, 83}: "Initra d.o.o.", + [3]byte{0, 36, 84}: "Samsung Electronics CO., LTD", + [3]byte{0, 36, 85}: "MuLogic BV", + [3]byte{0, 36, 86}: "2Wire", + [3]byte{0, 36, 88}: "PA Bastion CC", + [3]byte{0, 36, 89}: "ABB STOTZ-KONTAKT GmbH", + [3]byte{0, 36, 90}: "Nanjing Panda Electronics Company Limited", + [3]byte{0, 36, 91}: "RAIDON TECHNOLOGY, INC.", + [3]byte{0, 36, 92}: "Design-Com Technologies Pty. Ltd.", + [3]byte{0, 36, 93}: "Terberg besturingstechniek B.V.", + [3]byte{0, 36, 94}: "Hivision Co.,ltd", + [3]byte{0, 36, 95}: "Vine Telecom CO.,Ltd.", + [3]byte{0, 36, 96}: "Giaval Science Development Co. Ltd.", + [3]byte{0, 36, 97}: "Shin Wang Tech.", + [3]byte{0, 36, 98}: "Rayzone Corporation", + [3]byte{0, 36, 99}: "Phybridge Inc", + [3]byte{0, 36, 100}: "Bridge Technologies Co AS", + [3]byte{0, 36, 101}: "Elentec", + [3]byte{0, 36, 102}: "Unitron nv", + [3]byte{0, 36, 103}: "AOC International (Europe) GmbH", + [3]byte{0, 36, 104}: "Sumavision Technologies Co.,Ltd", + [3]byte{0, 36, 105}: "Smart Doorphones", + [3]byte{0, 36, 106}: "Solid Year Co., Ltd.", + [3]byte{0, 36, 107}: "Covia, Inc.", + [3]byte{0, 36, 108}: "ARUBA NETWORKS, INC.", + [3]byte{0, 36, 109}: "Weinzierl Engineering GmbH", + [3]byte{0, 36, 110}: "Phihong USA Corp.", + [3]byte{0, 36, 111}: "Onda Communication spa", + [3]byte{0, 36, 112}: "AUROTECH ultrasound AS.", + [3]byte{0, 36, 113}: "Fusion MultiSystems dba Fusion-io", + [3]byte{0, 36, 114}: "ReDriven Power Inc.", + [3]byte{0, 36, 115}: "3Com Europe Ltd", + [3]byte{0, 36, 116}: "Autronica Fire And Securirty", + [3]byte{0, 36, 117}: "Compass System(Embedded Dept.)", + [3]byte{0, 36, 118}: "TAP.tv", + [3]byte{0, 36, 119}: "Tibbo Technology", + [3]byte{0, 36, 120}: "Mag Tech Electronics Co Limited", + [3]byte{0, 36, 121}: "Optec Displays, Inc.", + [3]byte{0, 36, 122}: "FU YI CHENG Technology Co., Ltd.", + [3]byte{0, 36, 123}: "Actiontec Electronics, Inc", + [3]byte{0, 36, 124}: "Nokia Danmark A/S", + [3]byte{0, 36, 125}: "Nokia Danmark A/S", + [3]byte{0, 36, 126}: "Universal Global Scientific Industrial Co., Ltd", + [3]byte{0, 36, 127}: "Nortel Networks", + [3]byte{0, 36, 128}: "Meteocontrol GmbH", + [3]byte{0, 36, 129}: "Hewlett-Packard Company", + [3]byte{0, 36, 130}: "Ruckus Wireless", + [3]byte{0, 36, 131}: "LG Electronics", + [3]byte{0, 36, 132}: "Bang and Olufsen Medicom a/s", + [3]byte{0, 36, 133}: "ConteXtream Ltd", + [3]byte{0, 36, 134}: "DesignArt Networks", + [3]byte{0, 36, 135}: "Blackboard Inc.", + [3]byte{0, 36, 136}: "Centre For Development Of Telematics", + [3]byte{0, 36, 137}: "Vodafone Omnitel N.V.", + [3]byte{0, 36, 138}: "Kaga Electronics Co., Ltd.", + [3]byte{0, 36, 139}: "HYBUS CO., LTD.", + [3]byte{0, 36, 140}: "ASUSTek COMPUTER INC.", + [3]byte{0, 36, 141}: "Sony Computer Entertainment Inc.", + [3]byte{0, 36, 142}: "Infoware ZRt.", + [3]byte{0, 36, 143}: "DO-MONIX", + [3]byte{0, 36, 144}: "Samsung Electronics Co.,LTD", + [3]byte{0, 36, 145}: "Samsung Electronics", + [3]byte{0, 36, 146}: "Motorola, Broadband Solutions Group", + [3]byte{0, 36, 147}: "ARRIS Group, Inc.", + [3]byte{0, 36, 148}: "Shenzhen Baoxin Tech CO., Ltd.", + [3]byte{0, 36, 149}: "ARRIS Group, Inc.", + [3]byte{0, 36, 150}: "Ginzinger electronic systems", + [3]byte{0, 36, 151}: "CISCO SYSTEMS, INC.", + [3]byte{0, 36, 152}: "CISCO SYSTEMS, INC.", + [3]byte{0, 36, 153}: "Aquila Technologies", + [3]byte{0, 36, 154}: "Beijing Zhongchuang Telecommunication Test Co., Ltd.", + [3]byte{0, 36, 155}: "Action Star Enterprise Co., Ltd.", + [3]byte{0, 36, 156}: "Bimeng Comunication System Co. Ltd", + [3]byte{0, 36, 157}: "NES Technology Inc.", + [3]byte{0, 36, 158}: "ADC-Elektronik GmbH", + [3]byte{0, 36, 159}: "RIM Testing Services", + [3]byte{0, 36, 160}: "ARRIS Group, Inc.", + [3]byte{0, 36, 161}: "ARRIS Group, Inc.", + [3]byte{0, 36, 162}: "Hong Kong Middleware Technology Limited", + [3]byte{0, 36, 163}: "Sonim Technologies Inc", + [3]byte{0, 36, 164}: "Siklu Communication", + [3]byte{0, 36, 165}: "Buffalo Inc.", + [3]byte{0, 36, 166}: "TELESTAR DIGITAL GmbH", + [3]byte{0, 36, 167}: "Advanced Video Communications Inc.", + [3]byte{0, 36, 168}: "ProCurve Networking by HP", + [3]byte{0, 36, 169}: "Ag Leader Technology", + [3]byte{0, 36, 170}: "Dycor Technologies Ltd.", + [3]byte{0, 36, 171}: "A7 Engineering, Inc.", + [3]byte{0, 36, 172}: "Hangzhou DPtech Technologies Co., Ltd.", + [3]byte{0, 36, 173}: "Adolf Thies Gmbh & Co. KG", + [3]byte{0, 36, 174}: "Morpho", + [3]byte{0, 36, 175}: "EchoStar Technologies", + [3]byte{0, 36, 176}: "ESAB AB", + [3]byte{0, 36, 177}: "Coulomb Technologies", + [3]byte{0, 36, 178}: "Netgear", + [3]byte{0, 36, 179}: "Graf-Syteco GmbH & Co. KG", + [3]byte{0, 36, 180}: "ESCATRONIC GmbH", + [3]byte{0, 36, 181}: "Nortel Networks", + [3]byte{0, 36, 182}: "Seagate Technology", + [3]byte{0, 36, 183}: "GridPoint, Inc.", + [3]byte{0, 36, 184}: "free alliance sdn bhd", + [3]byte{0, 36, 185}: "Wuhan Higheasy Electronic Technology Development Co.Ltd", + [3]byte{0, 36, 186}: "Texas Instruments", + [3]byte{0, 36, 187}: "CENTRAL Corporation", + [3]byte{0, 36, 188}: "HuRob Co.,Ltd", + [3]byte{0, 36, 189}: "Hainzl Industriesysteme GmbH", + [3]byte{0, 36, 190}: "Sony Corporation", + [3]byte{0, 36, 191}: "CIAT", + [3]byte{0, 36, 192}: "NTI COMODO INC", + [3]byte{0, 36, 193}: "ARRIS Group, Inc.", + [3]byte{0, 36, 194}: "Asumo Co.,Ltd.", + [3]byte{0, 36, 195}: "CISCO SYSTEMS, INC.", + [3]byte{0, 36, 196}: "CISCO SYSTEMS, INC.", + [3]byte{0, 36, 197}: "Meridian Audio Limited", + [3]byte{0, 36, 198}: "Hager Electro SAS", + [3]byte{0, 36, 199}: "Mobilarm Ltd", + [3]byte{0, 36, 200}: "Broadband Solutions Group", + [3]byte{0, 36, 201}: "Broadband Solutions Group", + [3]byte{0, 36, 202}: "Tobii Technology AB", + [3]byte{0, 36, 203}: "Autonet Mobile", + [3]byte{0, 36, 204}: "Fascinations Toys and Gifts, Inc.", + [3]byte{0, 36, 205}: "Willow Garage, Inc.", + [3]byte{0, 36, 206}: "Exeltech Inc", + [3]byte{0, 36, 207}: "Inscape Data Corporation", + [3]byte{0, 36, 208}: "Shenzhen SOGOOD Industry CO.,LTD.", + [3]byte{0, 36, 209}: "Thomson Inc.", + [3]byte{0, 36, 210}: "Askey Computer", + [3]byte{0, 36, 211}: "QUALICA Inc.", + [3]byte{0, 36, 212}: "FREEBOX SA", + [3]byte{0, 36, 213}: "Winward Industrial Limited", + [3]byte{0, 36, 214}: "Intel Corporate", + [3]byte{0, 36, 215}: "Intel Corporate", + [3]byte{0, 36, 216}: "IlSung Precision", + [3]byte{0, 36, 217}: "BICOM, Inc.", + [3]byte{0, 36, 218}: "Innovar Systems Limited", + [3]byte{0, 36, 219}: "Alcohol Monitoring Systems", + [3]byte{0, 36, 220}: "Juniper Networks", + [3]byte{0, 36, 221}: "Centrak, Inc.", + [3]byte{0, 36, 222}: "GLOBAL Technology Inc.", + [3]byte{0, 36, 223}: "Digitalbox Europe GmbH", + [3]byte{0, 36, 224}: "DS Tech, LLC", + [3]byte{0, 36, 225}: "Convey Computer Corp.", + [3]byte{0, 36, 226}: "HASEGAWA ELECTRIC CO.,LTD.", + [3]byte{0, 36, 227}: "CAO Group", + [3]byte{0, 36, 228}: "Withings", + [3]byte{0, 36, 229}: "Seer Technology, Inc", + [3]byte{0, 36, 230}: "In Motion Technology Inc.", + [3]byte{0, 36, 231}: "Plaster Networks", + [3]byte{0, 36, 232}: "Dell Inc.", + [3]byte{0, 36, 233}: "Samsung Electronics Co., Ltd., Storage System Division", + [3]byte{0, 36, 234}: "iris-GmbH infrared & intelligent sensors", + [3]byte{0, 36, 235}: "ClearPath Networks, Inc.", + [3]byte{0, 36, 236}: "United Information Technology Co.,Ltd.", + [3]byte{0, 36, 237}: "YT Elec. Co,.Ltd.", + [3]byte{0, 36, 238}: "Wynmax Inc.", + [3]byte{0, 36, 239}: "Sony Ericsson Mobile Communications", + [3]byte{0, 36, 240}: "Seanodes", + [3]byte{0, 36, 241}: "Shenzhen Fanhai Sanjiang Electronics Co., Ltd.", + [3]byte{0, 36, 242}: "Uniphone Telecommunication Co., Ltd.", + [3]byte{0, 36, 243}: "Nintendo Co., Ltd.", + [3]byte{0, 36, 244}: "Kaminario Technologies Ltd.", + [3]byte{0, 36, 245}: "NDS Surgical Imaging", + [3]byte{0, 36, 246}: "MIYOSHI ELECTRONICS CORPORATION", + [3]byte{0, 36, 247}: "CISCO SYSTEMS, INC.", + [3]byte{0, 36, 248}: "Technical Solutions Company Ltd.", + [3]byte{0, 36, 249}: "CISCO SYSTEMS, INC.", + [3]byte{0, 36, 250}: "Hilger u. Kern GMBH", + [3]byte{0, 36, 251}: "PRIVATE", + [3]byte{0, 36, 252}: "QuoPin Co., Ltd.", + [3]byte{0, 36, 253}: "Accedian Networks Inc", + [3]byte{0, 36, 254}: "AVM GmbH", + [3]byte{0, 36, 255}: "QLogic Corporation", + [3]byte{0, 37, 0}: "Apple", + [3]byte{0, 37, 1}: "JSC \"Supertel\"", + [3]byte{0, 37, 2}: "NaturalPoint", + [3]byte{0, 37, 3}: "IBM Corp", + [3]byte{0, 37, 4}: "Valiant Communications Limited", + [3]byte{0, 37, 5}: "eks Engel GmbH & Co. KG", + [3]byte{0, 37, 6}: "A.I. ANTITACCHEGGIO ITALIA SRL", + [3]byte{0, 37, 7}: "ASTAK Inc.", + [3]byte{0, 37, 8}: "Maquet Cardiopulmonary AG", + [3]byte{0, 37, 9}: "SHARETRONIC Group LTD", + [3]byte{0, 37, 10}: "Security Expert Co. Ltd", + [3]byte{0, 37, 11}: "CENTROFACTOR INC", + [3]byte{0, 37, 12}: "Enertrac", + [3]byte{0, 37, 13}: "GZT Telkom-Telmor sp. z o.o.", + [3]byte{0, 37, 14}: "gt german telematics gmbh", + [3]byte{0, 37, 15}: "On-Ramp Wireless, Inc.", + [3]byte{0, 37, 16}: "Pico-Tesla Magnetic Therapies", + [3]byte{0, 37, 17}: "ELITEGROUP COMPUTER SYSTEM CO., LTD.", + [3]byte{0, 37, 18}: "ZTE Corporation", + [3]byte{0, 37, 19}: "CXP DIGITAL BV", + [3]byte{0, 37, 20}: "PC Worth Int'l Co., Ltd.", + [3]byte{0, 37, 21}: "SFR", + [3]byte{0, 37, 22}: "Integrated Design Tools, Inc.", + [3]byte{0, 37, 23}: "Venntis, LLC", + [3]byte{0, 37, 24}: "Power PLUS Communications AG", + [3]byte{0, 37, 25}: "Viaas Inc", + [3]byte{0, 37, 26}: "Psiber Data Systems Inc.", + [3]byte{0, 37, 27}: "Philips CareServant", + [3]byte{0, 37, 28}: "EDT", + [3]byte{0, 37, 29}: "DSA Encore, LLC", + [3]byte{0, 37, 30}: "ROTEL TECHNOLOGIES", + [3]byte{0, 37, 31}: "ZYNUS VISION INC.", + [3]byte{0, 37, 32}: "SMA Railway Technology GmbH", + [3]byte{0, 37, 33}: "Logitek Electronic Systems, Inc.", + [3]byte{0, 37, 34}: "ASRock Incorporation", + [3]byte{0, 37, 35}: "OCP Inc.", + [3]byte{0, 37, 36}: "Lightcomm Technology Co., Ltd", + [3]byte{0, 37, 37}: "CTERA Networks Ltd.", + [3]byte{0, 37, 38}: "Genuine Technologies Co., Ltd.", + [3]byte{0, 37, 39}: "Bitrode Corp.", + [3]byte{0, 37, 40}: "Daido Signal Co., Ltd.", + [3]byte{0, 37, 41}: "COMELIT GROUP S.P.A", + [3]byte{0, 37, 42}: "Chengdu GeeYa Technology Co.,LTD", + [3]byte{0, 37, 43}: "Stirling Energy Systems", + [3]byte{0, 37, 44}: "Entourage Systems, Inc.", + [3]byte{0, 37, 45}: "Kiryung Electronics", + [3]byte{0, 37, 46}: "Cisco SPVTG", + [3]byte{0, 37, 47}: "Energy, Inc.", + [3]byte{0, 37, 48}: "Aetas Systems Inc.", + [3]byte{0, 37, 49}: "Cloud Engines, Inc.", + [3]byte{0, 37, 50}: "Digital Recorders", + [3]byte{0, 37, 51}: "WITTENSTEIN AG", + [3]byte{0, 37, 53}: "Minimax GmbH & Co KG", + [3]byte{0, 37, 54}: "Oki Electric Industry Co., Ltd.", + [3]byte{0, 37, 55}: "Runcom Technologies Ltd.", + [3]byte{0, 37, 56}: "Samsung Electronics Co., Ltd., Memory Division", + [3]byte{0, 37, 57}: "IfTA GmbH", + [3]byte{0, 37, 58}: "CEVA, Ltd.", + [3]byte{0, 37, 59}: "din Dietmar Nocker Facilitymanagement GmbH", + [3]byte{0, 37, 60}: "2Wire", + [3]byte{0, 37, 61}: "DRS Consolidated Controls", + [3]byte{0, 37, 62}: "Sensus Metering Systems", + [3]byte{0, 37, 64}: "Quasar Technologies, Inc.", + [3]byte{0, 37, 65}: "Maquet Critical Care AB", + [3]byte{0, 37, 66}: "Pittasoft", + [3]byte{0, 37, 67}: "MONEYTECH", + [3]byte{0, 37, 68}: "LoJack Corporation", + [3]byte{0, 37, 69}: "CISCO SYSTEMS, INC.", + [3]byte{0, 37, 70}: "CISCO SYSTEMS, INC.", + [3]byte{0, 37, 71}: "Nokia Danmark A/S", + [3]byte{0, 37, 72}: "Nokia Danmark A/S", + [3]byte{0, 37, 73}: "Jeorich Tech. Co.,Ltd.", + [3]byte{0, 37, 74}: "RingCube Technologies, Inc.", + [3]byte{0, 37, 75}: "Apple", + [3]byte{0, 37, 76}: "Videon Central, Inc.", + [3]byte{0, 37, 77}: "Singapore Technologies Electronics Limited", + [3]byte{0, 37, 78}: "Vertex Wireless Co., Ltd.", + [3]byte{0, 37, 79}: "ELETTROLAB Srl", + [3]byte{0, 37, 80}: "Riverbed Technology", + [3]byte{0, 37, 81}: "SE-Elektronic GmbH", + [3]byte{0, 37, 82}: "VXI CORPORATION", + [3]byte{0, 37, 83}: "Pirelli Tyre S.p.A.", + [3]byte{0, 37, 84}: "Pixel8 Networks", + [3]byte{0, 37, 85}: "Visonic Technologies 1993 Ltd", + [3]byte{0, 37, 86}: "Hon Hai Precision Ind. Co., Ltd.", + [3]byte{0, 37, 87}: "Research In Motion", + [3]byte{0, 37, 88}: "MPEDIA", + [3]byte{0, 37, 89}: "Syphan Technologies Ltd", + [3]byte{0, 37, 90}: "Tantalus Systems Corp.", + [3]byte{0, 37, 91}: "CoachComm, LLC", + [3]byte{0, 37, 92}: "NEC Corporation", + [3]byte{0, 37, 93}: "Morningstar Corporation", + [3]byte{0, 37, 94}: "Shanghai Dare Technologies Co.,Ltd.", + [3]byte{0, 37, 95}: "SenTec AG", + [3]byte{0, 37, 96}: "Ibridge Networks & Communications Ltd.", + [3]byte{0, 37, 97}: "ProCurve Networking by HP", + [3]byte{0, 37, 98}: "interbro Co. Ltd.", + [3]byte{0, 37, 99}: "Luxtera Inc", + [3]byte{0, 37, 100}: "Dell Inc.", + [3]byte{0, 37, 101}: "Vizimax Inc.", + [3]byte{0, 37, 102}: "Samsung Electronics Co.,Ltd", + [3]byte{0, 37, 103}: "Samsung Electronics", + [3]byte{0, 37, 104}: "Shenzhen Huawei Communication Technologies Co., Ltd", + [3]byte{0, 37, 105}: "SAGEM COMMUNICATION", + [3]byte{0, 37, 106}: "inIT - Institut Industrial IT", + [3]byte{0, 37, 107}: "ATENIX E.E. s.r.l.", + [3]byte{0, 37, 108}: "\"Azimut\" Production Association JSC", + [3]byte{0, 37, 109}: "Broadband Forum", + [3]byte{0, 37, 110}: "Van Breda B.V.", + [3]byte{0, 37, 111}: "Dantherm Power", + [3]byte{0, 37, 112}: "Eastern Communications Company Limited", + [3]byte{0, 37, 113}: "Zhejiang Tianle Digital Electric Co.,Ltd", + [3]byte{0, 37, 114}: "Nemo-Q International AB", + [3]byte{0, 37, 115}: "ST Electronics (Info-Security) Pte Ltd", + [3]byte{0, 37, 116}: "KUNIMI MEDIA DEVICE Co., Ltd.", + [3]byte{0, 37, 117}: "FiberPlex Technologies, LLC", + [3]byte{0, 37, 118}: "NELI TECHNOLOGIES", + [3]byte{0, 37, 119}: "D-BOX Technologies", + [3]byte{0, 37, 120}: "JSC \"Concern \"Sozvezdie\"", + [3]byte{0, 37, 121}: "J & F Labs", + [3]byte{0, 37, 122}: "CAMCO Produktions- und Vertriebs-GmbH für Beschallungs- und Beleuchtungsanlagen", + [3]byte{0, 37, 123}: "STJ ELECTRONICS PVT LTD", + [3]byte{0, 37, 124}: "Huachentel Technology Development Co., Ltd", + [3]byte{0, 37, 125}: "PointRed Telecom Private Ltd.", + [3]byte{0, 37, 126}: "NEW POS Technology Limited", + [3]byte{0, 37, 127}: "CallTechSolution Co.,Ltd", + [3]byte{0, 37, 128}: "Equipson S.A.", + [3]byte{0, 37, 129}: "x-star networks Inc.", + [3]byte{0, 37, 130}: "Maksat Technologies (P) Ltd", + [3]byte{0, 37, 131}: "CISCO SYSTEMS, INC.", + [3]byte{0, 37, 132}: "CISCO SYSTEMS, INC.", + [3]byte{0, 37, 133}: "KOKUYO S&T Co., Ltd.", + [3]byte{0, 37, 134}: "TP-LINK Technologies Co., Ltd.", + [3]byte{0, 37, 135}: "Vitality, Inc.", + [3]byte{0, 37, 136}: "Genie Industries, Inc.", + [3]byte{0, 37, 137}: "Hills Industries Limited", + [3]byte{0, 37, 138}: "Pole/Zero Corporation", + [3]byte{0, 37, 139}: "Mellanox Technologies Ltd", + [3]byte{0, 37, 140}: "ESUS ELEKTRONIK SAN. VE DIS. TIC. LTD. STI.", + [3]byte{0, 37, 141}: "Haier", + [3]byte{0, 37, 142}: "The Weather Channel", + [3]byte{0, 37, 143}: "Trident Microsystems, Inc.", + [3]byte{0, 37, 144}: "Super Micro Computer, Inc.", + [3]byte{0, 37, 145}: "NEXTEK, Inc.", + [3]byte{0, 37, 146}: "Guangzhou Shirui Electronic Co., Ltd", + [3]byte{0, 37, 147}: "DatNet Informatikai Kft.", + [3]byte{0, 37, 148}: "Eurodesign BG LTD", + [3]byte{0, 37, 149}: "Northwest Signal Supply, Inc", + [3]byte{0, 37, 150}: "GIGAVISION srl", + [3]byte{0, 37, 151}: "Kalki Communication Technologies", + [3]byte{0, 37, 152}: "Zhong Shan City Litai Electronic Industrial Co. Ltd", + [3]byte{0, 37, 153}: "Hedon e.d. B.V.", + [3]byte{0, 37, 154}: "CEStronics GmbH", + [3]byte{0, 37, 155}: "Beijing PKUNITY Microsystems Technology Co., Ltd", + [3]byte{0, 37, 156}: "Cisco-Linksys, LLC", + [3]byte{0, 37, 157}: "PRIVATE", + [3]byte{0, 37, 158}: "Huawei Technologies Co., Ltd.", + [3]byte{0, 37, 159}: "TechnoDigital Technologies GmbH", + [3]byte{0, 37, 160}: "Nintendo Co., Ltd.", + [3]byte{0, 37, 161}: "Enalasys", + [3]byte{0, 37, 162}: "Alta Definicion LINCEO S.L.", + [3]byte{0, 37, 163}: "Trimax Wireless, Inc.", + [3]byte{0, 37, 164}: "EuroDesign embedded technologies GmbH", + [3]byte{0, 37, 165}: "Walnut Media Network", + [3]byte{0, 37, 166}: "Central Network Solution Co., Ltd.", + [3]byte{0, 37, 167}: "Comverge, Inc.", + [3]byte{0, 37, 168}: "Kontron (BeiJing) Technology Co.,Ltd", + [3]byte{0, 37, 169}: "Shanghai Embedway Information Technologies Co.,Ltd", + [3]byte{0, 37, 170}: "Beijing Soul Technology Co.,Ltd.", + [3]byte{0, 37, 171}: "AIO LCD PC BU / TPV", + [3]byte{0, 37, 172}: "I-Tech corporation", + [3]byte{0, 37, 173}: "Manufacturing Resources International", + [3]byte{0, 37, 174}: "Microsoft Corporation", + [3]byte{0, 37, 175}: "COMFILE Technology", + [3]byte{0, 37, 176}: "Schmartz Inc", + [3]byte{0, 37, 177}: "Maya-Creation Corporation", + [3]byte{0, 37, 178}: "MBDA Deutschland GmbH", + [3]byte{0, 37, 179}: "Hewlett-Packard Company", + [3]byte{0, 37, 180}: "CISCO SYSTEMS, INC.", + [3]byte{0, 37, 181}: "CISCO SYSTEMS, INC.", + [3]byte{0, 37, 182}: "Telecom FM", + [3]byte{0, 37, 183}: "Costar electronics, inc.,", + [3]byte{0, 37, 184}: "Agile Communications, Inc.", + [3]byte{0, 37, 185}: "Cypress Solutions Inc", + [3]byte{0, 37, 186}: "Alcatel-Lucent IPD", + [3]byte{0, 37, 187}: "INNERINT Co., Ltd.", + [3]byte{0, 37, 188}: "Apple", + [3]byte{0, 37, 189}: "Italdata Ingegneria dell'Idea S.p.A.", + [3]byte{0, 37, 190}: "Tektrap Systems Inc.", + [3]byte{0, 37, 191}: "Wireless Cables Inc.", + [3]byte{0, 37, 192}: "ZillionTV Corporation", + [3]byte{0, 37, 193}: "Nawoo Korea Corp.", + [3]byte{0, 37, 194}: "RingBell Co.,Ltd.", + [3]byte{0, 37, 195}: "Nortel Networks", + [3]byte{0, 37, 196}: "Ruckus Wireless", + [3]byte{0, 37, 197}: "Star Link Communication Pvt. Ltd.", + [3]byte{0, 37, 198}: "kasercorp, ltd", + [3]byte{0, 37, 199}: "altek Corporation", + [3]byte{0, 37, 200}: "S-Access GmbH", + [3]byte{0, 37, 201}: "SHENZHEN HUAPU DIGITAL CO., LTD", + [3]byte{0, 37, 202}: "LS Research, LLC", + [3]byte{0, 37, 203}: "Reiner SCT", + [3]byte{0, 37, 204}: "Mobile Communications Korea Incorporated", + [3]byte{0, 37, 205}: "Skylane Optics", + [3]byte{0, 37, 206}: "InnerSpace", + [3]byte{0, 37, 207}: "Nokia Danmark A/S", + [3]byte{0, 37, 208}: "Nokia Danmark A/S", + [3]byte{0, 37, 209}: "Eastern Asia Technology Limited", + [3]byte{0, 37, 210}: "InpegVision Co., Ltd", + [3]byte{0, 37, 211}: "AzureWave Technologies, Inc", + [3]byte{0, 37, 212}: "Fortress Technologies", + [3]byte{0, 37, 213}: "Robonica (Pty) Ltd", + [3]byte{0, 37, 214}: "The Kroger Co.", + [3]byte{0, 37, 215}: "CEDO", + [3]byte{0, 37, 216}: "KOREA MAINTENANCE", + [3]byte{0, 37, 217}: "DataFab Systems Inc.", + [3]byte{0, 37, 218}: "Secura Key", + [3]byte{0, 37, 219}: "ATI Electronics(Shenzhen) Co., LTD", + [3]byte{0, 37, 220}: "Sumitomo Electric Networks, Inc", + [3]byte{0, 37, 221}: "SUNNYTEK INFORMATION CO., LTD.", + [3]byte{0, 37, 222}: "Probits Co., LTD.", + [3]byte{0, 37, 223}: "PRIVATE", + [3]byte{0, 37, 224}: "CeedTec Sdn Bhd", + [3]byte{0, 37, 225}: "SHANGHAI SEEYOO ELECTRONIC & TECHNOLOGY CO., LTD", + [3]byte{0, 37, 226}: "Everspring Industry Co., Ltd.", + [3]byte{0, 37, 227}: "Hanshinit Inc.", + [3]byte{0, 37, 228}: "OMNI-WiFi, LLC", + [3]byte{0, 37, 229}: "LG Electronics Inc", + [3]byte{0, 37, 230}: "Belgian Monitoring Systems bvba", + [3]byte{0, 37, 231}: "Sony Ericsson Mobile Communications", + [3]byte{0, 37, 232}: "Idaho Technology", + [3]byte{0, 37, 233}: "i-mate Development, Inc.", + [3]byte{0, 37, 234}: "Iphion BV", + [3]byte{0, 37, 235}: "Reutech Radar Systems (PTY) Ltd", + [3]byte{0, 37, 236}: "Humanware", + [3]byte{0, 37, 237}: "NuVo Technologies LLC", + [3]byte{0, 37, 238}: "Avtex Ltd", + [3]byte{0, 37, 239}: "I-TEC Co., Ltd.", + [3]byte{0, 37, 240}: "Suga Electronics Limited", + [3]byte{0, 37, 241}: "ARRIS Group, Inc.", + [3]byte{0, 37, 242}: "ARRIS Group, Inc.", + [3]byte{0, 37, 243}: "Nordwestdeutsche Zählerrevision", + [3]byte{0, 37, 244}: "KoCo Connector AG", + [3]byte{0, 37, 245}: "DVS Korea, Co., Ltd", + [3]byte{0, 37, 246}: "netTALK.com, Inc.", + [3]byte{0, 37, 247}: "Ansaldo STS USA", + [3]byte{0, 37, 249}: "GMK electronic design GmbH", + [3]byte{0, 37, 250}: "J&M Analytik AG", + [3]byte{0, 37, 251}: "Tunstall Healthcare A/S", + [3]byte{0, 37, 252}: "ENDA ENDUSTRIYEL ELEKTRONIK LTD. STI.", + [3]byte{0, 37, 253}: "OBR Centrum Techniki Morskiej S.A.", + [3]byte{0, 37, 254}: "Pilot Electronics Corporation", + [3]byte{0, 37, 255}: "CreNova Multimedia Co., Ltd", + [3]byte{0, 38, 0}: "TEAC Australia Pty Ltd.", + [3]byte{0, 38, 1}: "Cutera Inc", + [3]byte{0, 38, 2}: "SMART Temps LLC", + [3]byte{0, 38, 3}: "Shenzhen Wistar Technology Co., Ltd", + [3]byte{0, 38, 4}: "Audio Processing Technology Ltd", + [3]byte{0, 38, 5}: "CC Systems AB", + [3]byte{0, 38, 6}: "RAUMFELD GmbH", + [3]byte{0, 38, 7}: "Enabling Technology Pty Ltd", + [3]byte{0, 38, 8}: "Apple", + [3]byte{0, 38, 9}: "Phyllis Co., Ltd.", + [3]byte{0, 38, 10}: "CISCO SYSTEMS, INC.", + [3]byte{0, 38, 11}: "CISCO SYSTEMS, INC.", + [3]byte{0, 38, 12}: "Dataram", + [3]byte{0, 38, 13}: "Mercury Systems, Inc.", + [3]byte{0, 38, 14}: "Ablaze Systems, LLC", + [3]byte{0, 38, 15}: "Linn Products Ltd", + [3]byte{0, 38, 16}: "Apacewave Technologies", + [3]byte{0, 38, 17}: "Licera AB", + [3]byte{0, 38, 18}: "Space Exploration Technologies", + [3]byte{0, 38, 19}: "Engel Axil S.L.", + [3]byte{0, 38, 20}: "KTNF", + [3]byte{0, 38, 21}: "Teracom Limited", + [3]byte{0, 38, 22}: "Rosemount Inc.", + [3]byte{0, 38, 23}: "OEM Worldwide", + [3]byte{0, 38, 24}: "ASUSTek COMPUTER INC.", + [3]byte{0, 38, 25}: "FRC", + [3]byte{0, 38, 26}: "Femtocomm System Technology Corp.", + [3]byte{0, 38, 27}: "LAUREL BANK MACHINES CO., LTD.", + [3]byte{0, 38, 28}: "NEOVIA INC.", + [3]byte{0, 38, 29}: "COP SECURITY SYSTEM CORP.", + [3]byte{0, 38, 30}: "QINGBANG ELEC(SZ) CO., LTD", + [3]byte{0, 38, 31}: "SAE Magnetics (H.K.) Ltd.", + [3]byte{0, 38, 32}: "ISGUS GmbH", + [3]byte{0, 38, 33}: "InteliCloud Technology Inc.", + [3]byte{0, 38, 34}: "COMPAL INFORMATION (KUNSHAN) CO., LTD.", + [3]byte{0, 38, 35}: "JRD Communication Inc", + [3]byte{0, 38, 36}: "Thomson Inc.", + [3]byte{0, 38, 37}: "MediaSputnik", + [3]byte{0, 38, 38}: "Geophysical Survey Systems, Inc.", + [3]byte{0, 38, 39}: "Truesell", + [3]byte{0, 38, 40}: "companytec automação e controle ltda.", + [3]byte{0, 38, 41}: "Juphoon System Software Inc.", + [3]byte{0, 38, 42}: "Proxense, LLC", + [3]byte{0, 38, 43}: "Wongs Electronics Co. Ltd.", + [3]byte{0, 38, 44}: "IKT Advanced Technologies s.r.o.", + [3]byte{0, 38, 45}: "Wistron Corporation", + [3]byte{0, 38, 46}: "Chengdu Jiuzhou Electronic Technology Inc", + [3]byte{0, 38, 47}: "HAMAMATSU TOA ELECTRONICS", + [3]byte{0, 38, 48}: "ACOREL S.A.S", + [3]byte{0, 38, 49}: "COMMTACT LTD", + [3]byte{0, 38, 50}: "Instrumentation Technologies d.d.", + [3]byte{0, 38, 51}: "MIR - Medical International Research", + [3]byte{0, 38, 52}: "Infineta Systems, Inc", + [3]byte{0, 38, 53}: "Bluetechnix GmbH", + [3]byte{0, 38, 54}: "ARRIS Group, Inc.", + [3]byte{0, 38, 55}: "Samsung Electro-Mechanics", + [3]byte{0, 38, 56}: "Xia Men Joyatech Co., Ltd.", + [3]byte{0, 38, 57}: "T.M. Electronics, Inc.", + [3]byte{0, 38, 58}: "Digitec Systems", + [3]byte{0, 38, 59}: "Onbnetech", + [3]byte{0, 38, 60}: "Bachmann Technology GmbH & Co. KG", + [3]byte{0, 38, 61}: "MIA Corporation", + [3]byte{0, 38, 62}: "Trapeze Networks", + [3]byte{0, 38, 63}: "LIOS Technology GmbH", + [3]byte{0, 38, 64}: "Baustem Broadband Technologies, Ltd.", + [3]byte{0, 38, 65}: "ARRIS Group, Inc.", + [3]byte{0, 38, 66}: "ARRIS Group, Inc.", + [3]byte{0, 38, 67}: "Alps Electric Co., Ltd", + [3]byte{0, 38, 68}: "Thomson Telecom Belgium", + [3]byte{0, 38, 69}: "Circontrol S.A.", + [3]byte{0, 38, 70}: "SHENYANG TONGFANG MULTIMEDIA TECHNOLOGY COMPANY LIMITED", + [3]byte{0, 38, 71}: "WFE TECHNOLOGY CORP.", + [3]byte{0, 38, 72}: "Emitech Corp.", + [3]byte{0, 38, 74}: "Apple", + [3]byte{0, 38, 76}: "Shanghai DigiVision Technology Co., Ltd.", + [3]byte{0, 38, 77}: "Arcadyan Technology Corporation", + [3]byte{0, 38, 78}: "Rail & Road Protec GmbH", + [3]byte{0, 38, 79}: "Krüger &Gothe GmbH", + [3]byte{0, 38, 80}: "2Wire", + [3]byte{0, 38, 81}: "CISCO SYSTEMS, INC.", + [3]byte{0, 38, 82}: "CISCO SYSTEMS, INC.", + [3]byte{0, 38, 83}: "DaySequerra Corporation", + [3]byte{0, 38, 84}: "3Com Corporation", + [3]byte{0, 38, 85}: "Hewlett-Packard Company", + [3]byte{0, 38, 86}: "Sansonic Electronics USA", + [3]byte{0, 38, 87}: "OOO NPP EKRA", + [3]byte{0, 38, 88}: "T-Platforms (Cyprus) Limited", + [3]byte{0, 38, 89}: "Nintendo Co., Ltd.", + [3]byte{0, 38, 90}: "D-Link Corporation", + [3]byte{0, 38, 91}: "Hitron Technologies. Inc", + [3]byte{0, 38, 92}: "Hon Hai Precision Ind. Co.,Ltd.", + [3]byte{0, 38, 93}: "Samsung Electronics", + [3]byte{0, 38, 94}: "Hon Hai Precision Ind. Co.,Ltd.", + [3]byte{0, 38, 95}: "Samsung Electronics Co.,Ltd", + [3]byte{0, 38, 96}: "Logiways", + [3]byte{0, 38, 97}: "Irumtek Co., Ltd.", + [3]byte{0, 38, 98}: "Actiontec Electronics, Inc", + [3]byte{0, 38, 99}: "Shenzhen Huitaiwei Tech. Ltd, co.", + [3]byte{0, 38, 100}: "Core System Japan", + [3]byte{0, 38, 101}: "ProtectedLogic Corporation", + [3]byte{0, 38, 102}: "EFM Networks", + [3]byte{0, 38, 103}: "CARECOM CO.,LTD.", + [3]byte{0, 38, 104}: "Nokia Danmark A/S", + [3]byte{0, 38, 105}: "Nokia Danmark A/S", + [3]byte{0, 38, 106}: "ESSENSIUM NV", + [3]byte{0, 38, 107}: "SHINE UNION ENTERPRISE LIMITED", + [3]byte{0, 38, 108}: "Inventec", + [3]byte{0, 38, 109}: "MobileAccess Networks", + [3]byte{0, 38, 110}: "Nissho-denki Co.,LTD.", + [3]byte{0, 38, 111}: "Coordiwise Technology Corp.", + [3]byte{0, 38, 112}: "Cinch Connectors", + [3]byte{0, 38, 113}: "AUTOVISION Co., Ltd", + [3]byte{0, 38, 114}: "AAMP of America", + [3]byte{0, 38, 115}: "RICOH COMPANY,LTD.", + [3]byte{0, 38, 116}: "Electronic Solutions, Inc.", + [3]byte{0, 38, 117}: "Aztech Electronics Pte Ltd", + [3]byte{0, 38, 118}: "COMMidt AS", + [3]byte{0, 38, 119}: "DEIF A/S", + [3]byte{0, 38, 120}: "Logic Instrument SA", + [3]byte{0, 38, 121}: "Euphonic Technologies, Inc.", + [3]byte{0, 38, 122}: "wuhan hongxin telecommunication technologies co.,ltd", + [3]byte{0, 38, 123}: "GSI Helmholtzzentrum für Schwerionenforschung GmbH", + [3]byte{0, 38, 124}: "Metz-Werke GmbH & Co KG", + [3]byte{0, 38, 125}: "A-Max Technology Macao Commercial Offshore Company Limited", + [3]byte{0, 38, 126}: "Parrot SA", + [3]byte{0, 38, 127}: "Zenterio AB", + [3]byte{0, 38, 128}: "Lockie Innovation Pty Ltd", + [3]byte{0, 38, 129}: "Interspiro AB", + [3]byte{0, 38, 130}: "Gemtek Technology Co., Ltd.", + [3]byte{0, 38, 131}: "Ajoho Enterprise Co., Ltd.", + [3]byte{0, 38, 132}: "KISAN SYSTEM", + [3]byte{0, 38, 133}: "Digital Innovation", + [3]byte{0, 38, 134}: "Quantenna Communcations, Inc.", + [3]byte{0, 38, 135}: "Corega K.K", + [3]byte{0, 38, 136}: "Juniper Networks", + [3]byte{0, 38, 137}: "General Dynamics Robotic Systems", + [3]byte{0, 38, 138}: "Terrier SC Ltd", + [3]byte{0, 38, 139}: "Guangzhou Escene Computer Technology Limited", + [3]byte{0, 38, 140}: "StarLeaf Ltd.", + [3]byte{0, 38, 141}: "CellTel S.p.A.", + [3]byte{0, 38, 142}: "Alta Solutions, Inc.", + [3]byte{0, 38, 143}: "MTA SpA", + [3]byte{0, 38, 144}: "I DO IT", + [3]byte{0, 38, 145}: "SAGEM COMMUNICATION", + [3]byte{0, 38, 146}: "Mitsubishi Electric Co.", + [3]byte{0, 38, 147}: "QVidium Technologies, Inc.", + [3]byte{0, 38, 148}: "Senscient Ltd", + [3]byte{0, 38, 149}: "ZT Group Int'l Inc", + [3]byte{0, 38, 150}: "NOOLIX Co., Ltd", + [3]byte{0, 38, 151}: "Cheetah Technologies, L.P.", + [3]byte{0, 38, 152}: "CISCO SYSTEMS, INC.", + [3]byte{0, 38, 153}: "CISCO SYSTEMS, INC.", + [3]byte{0, 38, 154}: "Carina System Co., Ltd.", + [3]byte{0, 38, 155}: "SOKRAT Ltd.", + [3]byte{0, 38, 156}: "ITUS JAPAN CO. LTD", + [3]byte{0, 38, 157}: "M2Mnet Co., Ltd.", + [3]byte{0, 38, 158}: "Quanta Computer Inc", + [3]byte{0, 38, 159}: "PRIVATE", + [3]byte{0, 38, 160}: "moblic", + [3]byte{0, 38, 161}: "Megger", + [3]byte{0, 38, 162}: "Instrumentation Technology Systems", + [3]byte{0, 38, 163}: "FQ Ingenieria Electronica S.A.", + [3]byte{0, 38, 164}: "Novus Produtos Eletronicos Ltda", + [3]byte{0, 38, 165}: "MICROROBOT.CO.,LTD", + [3]byte{0, 38, 166}: "TRIXELL", + [3]byte{0, 38, 167}: "CONNECT SRL", + [3]byte{0, 38, 168}: "DAEHAP HYPER-TECH", + [3]byte{0, 38, 169}: "Strong Technologies Pty Ltd", + [3]byte{0, 38, 170}: "Kenmec Mechanical Engineering Co., Ltd.", + [3]byte{0, 38, 171}: "SEIKO EPSON CORPORATION", + [3]byte{0, 38, 172}: "Shanghai LUSTER Teraband photonic Co., Ltd.", + [3]byte{0, 38, 173}: "Arada Systems, Inc.", + [3]byte{0, 38, 174}: "Wireless Measurement Ltd", + [3]byte{0, 38, 175}: "Duelco A/S", + [3]byte{0, 38, 176}: "Apple", + [3]byte{0, 38, 177}: "Navis Auto Motive Systems, Inc.", + [3]byte{0, 38, 178}: "Setrix GmbH", + [3]byte{0, 38, 179}: "Thales Communications Inc", + [3]byte{0, 38, 180}: "Ford Motor Company", + [3]byte{0, 38, 181}: "ICOMM Tele Ltd", + [3]byte{0, 38, 182}: "Askey Computer", + [3]byte{0, 38, 183}: "Kingston Technology Company, Inc.", + [3]byte{0, 38, 184}: "Actiontec Electronics, Inc", + [3]byte{0, 38, 185}: "Dell Inc", + [3]byte{0, 38, 186}: "ARRIS Group, Inc.", + [3]byte{0, 38, 187}: "Apple", + [3]byte{0, 38, 188}: "General Jack Technology Ltd.", + [3]byte{0, 38, 189}: "JTEC Card & Communication Co., Ltd.", + [3]byte{0, 38, 190}: "Schoonderbeek Elektronica Systemen B.V.", + [3]byte{0, 38, 191}: "ShenZhen Temobi Science&Tech Development Co.,Ltd", + [3]byte{0, 38, 192}: "EnergyHub", + [3]byte{0, 38, 193}: "ARTRAY CO., LTD.", + [3]byte{0, 38, 194}: "SCDI Co. LTD", + [3]byte{0, 38, 195}: "Insightek Corp.", + [3]byte{0, 38, 196}: "Cadmos microsystems S.r.l.", + [3]byte{0, 38, 197}: "Guangdong Gosun Telecommunications Co.,Ltd", + [3]byte{0, 38, 198}: "Intel Corporate", + [3]byte{0, 38, 199}: "Intel Corporate", + [3]byte{0, 38, 200}: "System Sensor", + [3]byte{0, 38, 201}: "Proventix Systems, Inc.", + [3]byte{0, 38, 202}: "CISCO SYSTEMS, INC.", + [3]byte{0, 38, 203}: "CISCO SYSTEMS, INC.", + [3]byte{0, 38, 204}: "Nokia Danmark A/S", + [3]byte{0, 38, 205}: "PurpleComm, Inc.", + [3]byte{0, 38, 206}: "Kozumi USA Corp.", + [3]byte{0, 38, 207}: "DEKA R&D", + [3]byte{0, 38, 208}: "Semihalf", + [3]byte{0, 38, 209}: "S Squared Innovations Inc.", + [3]byte{0, 38, 210}: "Pcube Systems, Inc.", + [3]byte{0, 38, 211}: "Zeno Information System", + [3]byte{0, 38, 212}: "IRCA SpA", + [3]byte{0, 38, 213}: "Ory Solucoes em Comercio de Informatica Ltda.", + [3]byte{0, 38, 214}: "Ningbo Andy Optoelectronic Co., Ltd.", + [3]byte{0, 38, 215}: "KM Electornic Technology Co., Ltd.", + [3]byte{0, 38, 216}: "Magic Point Inc.", + [3]byte{0, 38, 217}: "Pace plc", + [3]byte{0, 38, 218}: "Universal Media Corporation /Slovakia/ s.r.o.", + [3]byte{0, 38, 219}: "Ionics EMS Inc.", + [3]byte{0, 38, 220}: "Optical Systems Design", + [3]byte{0, 38, 221}: "Fival Science & Technology Co.,Ltd.", + [3]byte{0, 38, 222}: "FDI MATELEC", + [3]byte{0, 38, 223}: "TaiDoc Technology Corp.", + [3]byte{0, 38, 224}: "ASITEQ", + [3]byte{0, 38, 225}: "Stanford University, OpenFlow Group", + [3]byte{0, 38, 226}: "LG Electronics", + [3]byte{0, 38, 227}: "DTI", + [3]byte{0, 38, 228}: "CANAL OVERSEAS", + [3]byte{0, 38, 229}: "AEG Power Solutions", + [3]byte{0, 38, 230}: "Visionhitech Co., Ltd.", + [3]byte{0, 38, 231}: "Shanghai ONLAN Communication Tech. Co., Ltd.", + [3]byte{0, 38, 232}: "Murata Manufacturing Co., Ltd.", + [3]byte{0, 38, 233}: "SP Corp", + [3]byte{0, 38, 234}: "Cheerchip Electronic Technology (ShangHai) Co., Ltd.", + [3]byte{0, 38, 235}: "Advanced Spectrum Technology Co., Ltd.", + [3]byte{0, 38, 236}: "Legrand Home Systems, Inc", + [3]byte{0, 38, 237}: "zte corporation", + [3]byte{0, 38, 238}: "TKM GmbH", + [3]byte{0, 38, 239}: "Technology Advancement Group, Inc.", + [3]byte{0, 38, 240}: "cTrixs International GmbH.", + [3]byte{0, 38, 241}: "ProCurve Networking by HP", + [3]byte{0, 38, 242}: "Netgear", + [3]byte{0, 38, 243}: "SMC Networks", + [3]byte{0, 38, 244}: "Nesslab", + [3]byte{0, 38, 245}: "XRPLUS Inc.", + [3]byte{0, 38, 246}: "Military Communication Institute", + [3]byte{0, 38, 247}: "Infosys Technologies Ltd.", + [3]byte{0, 38, 248}: "Golden Highway Industry Development Co., Ltd.", + [3]byte{0, 38, 249}: "S.E.M. srl", + [3]byte{0, 38, 250}: "BandRich Inc.", + [3]byte{0, 38, 251}: "AirDio Wireless, Inc.", + [3]byte{0, 38, 252}: "AcSiP Technology Corp.", + [3]byte{0, 38, 253}: "Interactive Intelligence", + [3]byte{0, 38, 254}: "MKD Technology Inc.", + [3]byte{0, 38, 255}: "Research In Motion", + [3]byte{0, 39, 0}: "Shenzhen Siglent Technology Co., Ltd.", + [3]byte{0, 39, 1}: "INCOstartec GmbH", + [3]byte{0, 39, 2}: "SolarEdge Technologies", + [3]byte{0, 39, 3}: "Testech Electronics Pte Ltd", + [3]byte{0, 39, 4}: "Accelerated Concepts, Inc", + [3]byte{0, 39, 5}: "Sectronic", + [3]byte{0, 39, 6}: "YOISYS", + [3]byte{0, 39, 7}: "Lift Complex DS, JSC", + [3]byte{0, 39, 8}: "Nordiag ASA", + [3]byte{0, 39, 9}: "Nintendo Co., Ltd.", + [3]byte{0, 39, 10}: "IEE S.A.", + [3]byte{0, 39, 11}: "Adura Technologies", + [3]byte{0, 39, 12}: "CISCO SYSTEMS, INC.", + [3]byte{0, 39, 13}: "CISCO SYSTEMS, INC.", + [3]byte{0, 39, 14}: "Intel Corporate", + [3]byte{0, 39, 15}: "Envisionnovation Inc", + [3]byte{0, 39, 16}: "Intel Corporate", + [3]byte{0, 39, 17}: "LanPro Inc", + [3]byte{0, 39, 18}: "MaxVision LLC", + [3]byte{0, 39, 19}: "Universal Global Scientific Industrial Co., Ltd.", + [3]byte{0, 39, 20}: "Grainmustards, Co,ltd.", + [3]byte{0, 39, 21}: "Rebound Telecom. Co., Ltd", + [3]byte{0, 39, 22}: "Adachi-Syokai Co., Ltd.", + [3]byte{0, 39, 23}: "CE Digital(Zhenjiang)Co.,Ltd", + [3]byte{0, 39, 24}: "Suzhou NEW SEAUNION Video Technology Co.,Ltd", + [3]byte{0, 39, 25}: "TP-LINK TECHNOLOGIES CO., LTD.", + [3]byte{0, 39, 26}: "Geenovo Technology Ltd.", + [3]byte{0, 39, 27}: "Alec Sicherheitssysteme GmbH", + [3]byte{0, 39, 28}: "MERCURY CORPORATION", + [3]byte{0, 39, 29}: "Comba Telecom Systems (China) Ltd.", + [3]byte{0, 39, 30}: "Xagyl Communications", + [3]byte{0, 39, 31}: "MIPRO Electronics Co., Ltd", + [3]byte{0, 39, 32}: "NEW-SOL COM", + [3]byte{0, 39, 33}: "Shenzhen Baoan Fenda Industrial Co., Ltd", + [3]byte{0, 39, 34}: "Ubiquiti Networks", + [3]byte{0, 39, 248}: "Brocade Communications Systems, Inc.", + [3]byte{0, 42, 106}: "CISCO SYSTEMS, INC.", + [3]byte{0, 42, 175}: "LARsys-Automation GmbH", + [3]byte{0, 45, 118}: "TITECH GmbH", + [3]byte{0, 48, 0}: "ALLWELL TECHNOLOGY CORP.", + [3]byte{0, 48, 1}: "SMP", + [3]byte{0, 48, 2}: "Expand Networks", + [3]byte{0, 48, 3}: "Phasys Ltd.", + [3]byte{0, 48, 4}: "LEADTEK RESEARCH INC.", + [3]byte{0, 48, 5}: "Fujitsu Siemens Computers", + [3]byte{0, 48, 6}: "SUPERPOWER COMPUTER", + [3]byte{0, 48, 7}: "OPTI, INC.", + [3]byte{0, 48, 8}: "AVIO DIGITAL, INC.", + [3]byte{0, 48, 9}: "Tachion Networks, Inc.", + [3]byte{0, 48, 10}: "AZTECH Electronics Pte Ltd", + [3]byte{0, 48, 11}: "mPHASE Technologies, Inc.", + [3]byte{0, 48, 12}: "CONGRUENCY, LTD.", + [3]byte{0, 48, 13}: "MMC Technology, Inc.", + [3]byte{0, 48, 14}: "Klotz Digital AG", + [3]byte{0, 48, 15}: "IMT - Information Management T", + [3]byte{0, 48, 16}: "VISIONETICS INTERNATIONAL", + [3]byte{0, 48, 17}: "HMS Industrial Networks", + [3]byte{0, 48, 18}: "DIGITAL ENGINEERING LTD.", + [3]byte{0, 48, 19}: "NEC Corporation", + [3]byte{0, 48, 20}: "DIVIO, INC.", + [3]byte{0, 48, 21}: "CP CLARE CORP.", + [3]byte{0, 48, 22}: "ISHIDA CO., LTD.", + [3]byte{0, 48, 23}: "BlueArc UK Ltd", + [3]byte{0, 48, 24}: "Jetway Information Co., Ltd.", + [3]byte{0, 48, 25}: "CISCO SYSTEMS, INC.", + [3]byte{0, 48, 26}: "SMARTBRIDGES PTE. LTD.", + [3]byte{0, 48, 27}: "SHUTTLE, INC.", + [3]byte{0, 48, 28}: "ALTVATER AIRDATA SYSTEMS", + [3]byte{0, 48, 29}: "SKYSTREAM, INC.", + [3]byte{0, 48, 30}: "3COM Europe Ltd.", + [3]byte{0, 48, 31}: "OPTICAL NETWORKS, INC.", + [3]byte{0, 48, 32}: "TSI, Inc..", + [3]byte{0, 48, 33}: "HSING TECH. ENTERPRISE CO.,LTD", + [3]byte{0, 48, 34}: "Fong Kai Industrial Co., Ltd.", + [3]byte{0, 48, 35}: "COGENT COMPUTER SYSTEMS, INC.", + [3]byte{0, 48, 36}: "CISCO SYSTEMS, INC.", + [3]byte{0, 48, 37}: "CHECKOUT COMPUTER SYSTEMS, LTD", + [3]byte{0, 48, 38}: "HeiTel Digital Video GmbH", + [3]byte{0, 48, 39}: "KERBANGO, INC.", + [3]byte{0, 48, 40}: "FASE Saldatura srl", + [3]byte{0, 48, 41}: "OPICOM", + [3]byte{0, 48, 42}: "SOUTHERN INFORMATION", + [3]byte{0, 48, 43}: "INALP NETWORKS, INC.", + [3]byte{0, 48, 44}: "SYLANTRO SYSTEMS CORPORATION", + [3]byte{0, 48, 45}: "QUANTUM BRIDGE COMMUNICATIONS", + [3]byte{0, 48, 46}: "Hoft & Wessel AG", + [3]byte{0, 48, 47}: "GE Aviation System", + [3]byte{0, 48, 48}: "HARMONIX CORPORATION", + [3]byte{0, 48, 49}: "LIGHTWAVE COMMUNICATIONS, INC.", + [3]byte{0, 48, 50}: "MagicRam, Inc.", + [3]byte{0, 48, 51}: "ORIENT TELECOM CO., LTD.", + [3]byte{0, 48, 52}: "SET ENGINEERING", + [3]byte{0, 48, 53}: "Corning Incorporated", + [3]byte{0, 48, 54}: "RMP ELEKTRONIKSYSTEME GMBH", + [3]byte{0, 48, 55}: "Packard Bell Nec Services", + [3]byte{0, 48, 56}: "XCP, INC.", + [3]byte{0, 48, 57}: "SOFTBOOK PRESS", + [3]byte{0, 48, 58}: "MAATEL", + [3]byte{0, 48, 59}: "PowerCom Technology", + [3]byte{0, 48, 60}: "ONNTO CORP.", + [3]byte{0, 48, 61}: "IVA CORPORATION", + [3]byte{0, 48, 62}: "Radcom Ltd.", + [3]byte{0, 48, 63}: "TurboComm Tech Inc.", + [3]byte{0, 48, 64}: "CISCO SYSTEMS, INC.", + [3]byte{0, 48, 65}: "SAEJIN T & M CO., LTD.", + [3]byte{0, 48, 66}: "DeTeWe-Deutsche Telephonwerke", + [3]byte{0, 48, 67}: "IDREAM TECHNOLOGIES, PTE. LTD.", + [3]byte{0, 48, 68}: "CradlePoint, Inc", + [3]byte{0, 48, 69}: "Village Networks, Inc. (VNI)", + [3]byte{0, 48, 70}: "Controlled Electronic Manageme", + [3]byte{0, 48, 71}: "NISSEI ELECTRIC CO., LTD.", + [3]byte{0, 48, 72}: "Supermicro Computer, Inc.", + [3]byte{0, 48, 73}: "BRYANT TECHNOLOGY, LTD.", + [3]byte{0, 48, 74}: "Fraunhofer IPMS", + [3]byte{0, 48, 75}: "ORBACOM SYSTEMS, INC.", + [3]byte{0, 48, 76}: "APPIAN COMMUNICATIONS, INC.", + [3]byte{0, 48, 77}: "ESI", + [3]byte{0, 48, 78}: "BUSTEC PRODUCTION LTD.", + [3]byte{0, 48, 79}: "PLANET Technology Corporation", + [3]byte{0, 48, 80}: "Versa Technology", + [3]byte{0, 48, 81}: "ORBIT AVIONIC & COMMUNICATION", + [3]byte{0, 48, 82}: "ELASTIC NETWORKS", + [3]byte{0, 48, 83}: "Basler AG", + [3]byte{0, 48, 84}: "CASTLENET TECHNOLOGY, INC.", + [3]byte{0, 48, 85}: "Renesas Technology America, Inc.", + [3]byte{0, 48, 86}: "Beck IPC GmbH", + [3]byte{0, 48, 87}: "QTelNet, Inc.", + [3]byte{0, 48, 88}: "API MOTION", + [3]byte{0, 48, 89}: "KONTRON COMPACT COMPUTERS AG", + [3]byte{0, 48, 90}: "TELGEN CORPORATION", + [3]byte{0, 48, 91}: "Toko Inc.", + [3]byte{0, 48, 92}: "SMAR Laboratories Corp.", + [3]byte{0, 48, 93}: "DIGITRA SYSTEMS, INC.", + [3]byte{0, 48, 94}: "Abelko Innovation", + [3]byte{0, 48, 95}: "Hasselblad", + [3]byte{0, 48, 96}: "Powerfile, Inc.", + [3]byte{0, 48, 97}: "MobyTEL", + [3]byte{0, 48, 98}: "IP Video Networks Inc", + [3]byte{0, 48, 99}: "SANTERA SYSTEMS, INC.", + [3]byte{0, 48, 100}: "ADLINK TECHNOLOGY, INC.", + [3]byte{0, 48, 101}: "Apple", + [3]byte{0, 48, 102}: "RFM", + [3]byte{0, 48, 103}: "BIOSTAR MICROTECH INT'L CORP.", + [3]byte{0, 48, 104}: "CYBERNETICS TECH. CO., LTD.", + [3]byte{0, 48, 105}: "IMPACCT TECHNOLOGY CORP.", + [3]byte{0, 48, 106}: "PENTA MEDIA CO., LTD.", + [3]byte{0, 48, 107}: "CMOS SYSTEMS, INC.", + [3]byte{0, 48, 108}: "Hitex Holding GmbH", + [3]byte{0, 48, 109}: "LUCENT TECHNOLOGIES", + [3]byte{0, 48, 110}: "HEWLETT PACKARD", + [3]byte{0, 48, 111}: "SEYEON TECH. CO., LTD.", + [3]byte{0, 48, 112}: "1Net Corporation", + [3]byte{0, 48, 113}: "CISCO SYSTEMS, INC.", + [3]byte{0, 48, 114}: "Intellibyte Inc.", + [3]byte{0, 48, 115}: "International Microsystems, In", + [3]byte{0, 48, 116}: "EQUIINET LTD.", + [3]byte{0, 48, 117}: "ADTECH", + [3]byte{0, 48, 118}: "Akamba Corporation", + [3]byte{0, 48, 119}: "ONPREM NETWORKS", + [3]byte{0, 48, 120}: "CISCO SYSTEMS, INC.", + [3]byte{0, 48, 121}: "CQOS, INC.", + [3]byte{0, 48, 122}: "Advanced Technology & Systems", + [3]byte{0, 48, 123}: "CISCO SYSTEMS, INC.", + [3]byte{0, 48, 124}: "ADID SA", + [3]byte{0, 48, 125}: "GRE AMERICA, INC.", + [3]byte{0, 48, 126}: "Redflex Communication Systems", + [3]byte{0, 48, 127}: "IRLAN LTD.", + [3]byte{0, 48, 128}: "CISCO SYSTEMS, INC.", + [3]byte{0, 48, 129}: "ALTOS C&C", + [3]byte{0, 48, 130}: "TAIHAN ELECTRIC WIRE CO., LTD.", + [3]byte{0, 48, 131}: "Ivron Systems", + [3]byte{0, 48, 132}: "ALLIED TELESYN INTERNAIONAL", + [3]byte{0, 48, 133}: "CISCO SYSTEMS, INC.", + [3]byte{0, 48, 134}: "Transistor Devices, Inc.", + [3]byte{0, 48, 135}: "VEGA GRIESHABER KG", + [3]byte{0, 48, 136}: "Ericsson", + [3]byte{0, 48, 137}: "Spectrapoint Wireless, LLC", + [3]byte{0, 48, 138}: "NICOTRA SISTEMI S.P.A", + [3]byte{0, 48, 139}: "Brix Networks", + [3]byte{0, 48, 140}: "Quantum Corporation", + [3]byte{0, 48, 141}: "Pinnacle Systems, Inc.", + [3]byte{0, 48, 142}: "CROSS MATCH TECHNOLOGIES, INC.", + [3]byte{0, 48, 143}: "MICRILOR, Inc.", + [3]byte{0, 48, 144}: "CYRA TECHNOLOGIES, INC.", + [3]byte{0, 48, 145}: "TAIWAN FIRST LINE ELEC. CORP.", + [3]byte{0, 48, 146}: "ModuNORM GmbH", + [3]byte{0, 48, 147}: "Sonnet Technologies, Inc", + [3]byte{0, 48, 148}: "CISCO SYSTEMS, INC.", + [3]byte{0, 48, 149}: "Procomp Informatics, Ltd.", + [3]byte{0, 48, 150}: "CISCO SYSTEMS, INC.", + [3]byte{0, 48, 151}: "AB Regin", + [3]byte{0, 48, 152}: "Global Converging Technologies", + [3]byte{0, 48, 153}: "BOENIG UND KALLENBACH OHG", + [3]byte{0, 48, 154}: "ASTRO TERRA CORP.", + [3]byte{0, 48, 155}: "Smartware", + [3]byte{0, 48, 156}: "Timing Applications, Inc.", + [3]byte{0, 48, 157}: "Nimble Microsystems, Inc.", + [3]byte{0, 48, 158}: "WORKBIT CORPORATION.", + [3]byte{0, 48, 159}: "AMBER NETWORKS", + [3]byte{0, 48, 160}: "TYCO SUBMARINE SYSTEMS, LTD.", + [3]byte{0, 48, 161}: "WEBGATE Inc.", + [3]byte{0, 48, 162}: "Lightner Engineering", + [3]byte{0, 48, 163}: "CISCO SYSTEMS, INC.", + [3]byte{0, 48, 164}: "Woodwind Communications System", + [3]byte{0, 48, 165}: "ACTIVE POWER", + [3]byte{0, 48, 166}: "VIANET TECHNOLOGIES, LTD.", + [3]byte{0, 48, 167}: "SCHWEITZER ENGINEERING", + [3]byte{0, 48, 168}: "OL'E COMMUNICATIONS, INC.", + [3]byte{0, 48, 169}: "Netiverse, Inc.", + [3]byte{0, 48, 170}: "AXUS MICROSYSTEMS, INC.", + [3]byte{0, 48, 171}: "DELTA NETWORKS, INC.", + [3]byte{0, 48, 172}: "Systeme Lauer GmbH & Co., Ltd.", + [3]byte{0, 48, 173}: "SHANGHAI COMMUNICATION", + [3]byte{0, 48, 174}: "Times N System, Inc.", + [3]byte{0, 48, 175}: "Honeywell GmbH", + [3]byte{0, 48, 176}: "Convergenet Technologies", + [3]byte{0, 48, 177}: "TrunkNet", + [3]byte{0, 48, 178}: "L-3 Sonoma EO", + [3]byte{0, 48, 179}: "San Valley Systems, Inc.", + [3]byte{0, 48, 180}: "INTERSIL CORP.", + [3]byte{0, 48, 181}: "Tadiran Microwave Networks", + [3]byte{0, 48, 182}: "CISCO SYSTEMS, INC.", + [3]byte{0, 48, 183}: "Teletrol Systems, Inc.", + [3]byte{0, 48, 184}: "RiverDelta Networks", + [3]byte{0, 48, 185}: "ECTEL", + [3]byte{0, 48, 186}: "AC&T SYSTEM CO., LTD.", + [3]byte{0, 48, 187}: "CacheFlow, Inc.", + [3]byte{0, 48, 188}: "Optronic AG", + [3]byte{0, 48, 189}: "BELKIN COMPONENTS", + [3]byte{0, 48, 190}: "City-Net Technology, Inc.", + [3]byte{0, 48, 191}: "MULTIDATA GMBH", + [3]byte{0, 48, 192}: "Lara Technology, Inc.", + [3]byte{0, 48, 193}: "HEWLETT-PACKARD", + [3]byte{0, 48, 194}: "COMONE", + [3]byte{0, 48, 195}: "FLUECKIGER ELEKTRONIK AG", + [3]byte{0, 48, 196}: "Canon Imaging Systems Inc.", + [3]byte{0, 48, 197}: "CADENCE DESIGN SYSTEMS", + [3]byte{0, 48, 198}: "CONTROL SOLUTIONS, INC.", + [3]byte{0, 48, 199}: "Macromate Corp.", + [3]byte{0, 48, 200}: "GAD LINE, LTD.", + [3]byte{0, 48, 201}: "LuxN, N", + [3]byte{0, 48, 202}: "Discovery Com", + [3]byte{0, 48, 203}: "OMNI FLOW COMPUTERS, INC.", + [3]byte{0, 48, 204}: "Tenor Networks, Inc.", + [3]byte{0, 48, 205}: "CONEXANT SYSTEMS, INC.", + [3]byte{0, 48, 206}: "Zaffire", + [3]byte{0, 48, 207}: "TWO TECHNOLOGIES, INC.", + [3]byte{0, 48, 208}: "Tellabs", + [3]byte{0, 48, 209}: "INOVA CORPORATION", + [3]byte{0, 48, 210}: "WIN TECHNOLOGIES, CO., LTD.", + [3]byte{0, 48, 211}: "Agilent Technologies", + [3]byte{0, 48, 212}: "AAE Systems, Inc.", + [3]byte{0, 48, 213}: "DResearch GmbH", + [3]byte{0, 48, 214}: "MSC VERTRIEBS GMBH", + [3]byte{0, 48, 215}: "Innovative Systems, L.L.C.", + [3]byte{0, 48, 216}: "SITEK", + [3]byte{0, 48, 217}: "DATACORE SOFTWARE CORP.", + [3]byte{0, 48, 218}: "COMTREND CO.", + [3]byte{0, 48, 219}: "Mindready Solutions, Inc.", + [3]byte{0, 48, 220}: "RIGHTECH CORPORATION", + [3]byte{0, 48, 221}: "INDIGITA CORPORATION", + [3]byte{0, 48, 222}: "WAGO Kontakttechnik GmbH", + [3]byte{0, 48, 223}: "KB/TEL TELECOMUNICACIONES", + [3]byte{0, 48, 224}: "OXFORD SEMICONDUCTOR LTD.", + [3]byte{0, 48, 225}: "Network Equipment Technologies, Inc.", + [3]byte{0, 48, 226}: "GARNET SYSTEMS CO., LTD.", + [3]byte{0, 48, 227}: "SEDONA NETWORKS CORP.", + [3]byte{0, 48, 228}: "CHIYODA SYSTEM RIKEN", + [3]byte{0, 48, 229}: "Amper Datos S.A.", + [3]byte{0, 48, 230}: "Draeger Medical Systems, Inc.", + [3]byte{0, 48, 231}: "CNF MOBILE SOLUTIONS, INC.", + [3]byte{0, 48, 232}: "ENSIM CORP.", + [3]byte{0, 48, 233}: "GMA COMMUNICATION MANUFACT'G", + [3]byte{0, 48, 234}: "TeraForce Technology Corporation", + [3]byte{0, 48, 235}: "TURBONET COMMUNICATIONS, INC.", + [3]byte{0, 48, 236}: "BORGARDT", + [3]byte{0, 48, 237}: "Expert Magnetics Corp.", + [3]byte{0, 48, 238}: "DSG Technology, Inc.", + [3]byte{0, 48, 239}: "NEON TECHNOLOGY, INC.", + [3]byte{0, 48, 240}: "Uniform Industrial Corp.", + [3]byte{0, 48, 241}: "Accton Technology Corp.", + [3]byte{0, 48, 242}: "CISCO SYSTEMS, INC.", + [3]byte{0, 48, 243}: "At Work Computers", + [3]byte{0, 48, 244}: "STARDOT TECHNOLOGIES", + [3]byte{0, 48, 245}: "Wild Lab. Ltd.", + [3]byte{0, 48, 246}: "SECURELOGIX CORPORATION", + [3]byte{0, 48, 247}: "RAMIX INC.", + [3]byte{0, 48, 248}: "Dynapro Systems, Inc.", + [3]byte{0, 48, 249}: "Sollae Systems Co., Ltd.", + [3]byte{0, 48, 250}: "TELICA, INC.", + [3]byte{0, 48, 251}: "AZS Technology AG", + [3]byte{0, 48, 252}: "Terawave Communications, Inc.", + [3]byte{0, 48, 253}: "INTEGRATED SYSTEMS DESIGN", + [3]byte{0, 48, 254}: "DSA GmbH", + [3]byte{0, 48, 255}: "DATAFAB SYSTEMS, INC.", + [3]byte{0, 51, 108}: "SynapSense Corporation", + [3]byte{0, 52, 241}: "Radicom Research, Inc.", + [3]byte{0, 53, 50}: "Electro-Metrics Corporation", + [3]byte{0, 53, 96}: "Rosen Aviation", + [3]byte{0, 54, 248}: "Conti Temic microelectronic GmbH", + [3]byte{0, 54, 254}: "SuperVision", + [3]byte{0, 55, 109}: "Murata Manufacturing Co., Ltd.", + [3]byte{0, 58, 152}: "CISCO SYSTEMS, INC.", + [3]byte{0, 58, 153}: "CISCO SYSTEMS, INC.", + [3]byte{0, 58, 154}: "CISCO SYSTEMS, INC.", + [3]byte{0, 58, 155}: "CISCO SYSTEMS, INC.", + [3]byte{0, 58, 156}: "CISCO SYSTEMS, INC.", + [3]byte{0, 58, 157}: "NEC Platforms, Ltd.", + [3]byte{0, 58, 175}: "BlueBit Ltd.", + [3]byte{0, 60, 197}: "WONWOO Engineering Co., Ltd", + [3]byte{0, 61, 65}: "Hatteland Computer AS", + [3]byte{0, 62, 225}: "Apple", + [3]byte{0, 64, 0}: "PCI COMPONENTES DA AMZONIA LTD", + [3]byte{0, 64, 1}: "Zero One Technology Co. Ltd.", + [3]byte{0, 64, 2}: "PERLE SYSTEMS LIMITED", + [3]byte{0, 64, 3}: "Emerson Process Management Power & Water Solutions, Inc.", + [3]byte{0, 64, 4}: "ICM CO. LTD.", + [3]byte{0, 64, 5}: "ANI COMMUNICATIONS INC.", + [3]byte{0, 64, 6}: "SAMPO TECHNOLOGY CORPORATION", + [3]byte{0, 64, 7}: "TELMAT INFORMATIQUE", + [3]byte{0, 64, 8}: "A PLUS INFO CORPORATION", + [3]byte{0, 64, 9}: "TACHIBANA TECTRON CO., LTD.", + [3]byte{0, 64, 10}: "PIVOTAL TECHNOLOGIES, INC.", + [3]byte{0, 64, 11}: "CISCO SYSTEMS, INC.", + [3]byte{0, 64, 12}: "GENERAL MICRO SYSTEMS, INC.", + [3]byte{0, 64, 13}: "LANNET DATA COMMUNICATIONS,LTD", + [3]byte{0, 64, 14}: "MEMOTEC, INC.", + [3]byte{0, 64, 15}: "DATACOM TECHNOLOGIES", + [3]byte{0, 64, 16}: "SONIC SYSTEMS, INC.", + [3]byte{0, 64, 17}: "ANDOVER CONTROLS CORPORATION", + [3]byte{0, 64, 18}: "WINDATA, INC.", + [3]byte{0, 64, 19}: "NTT DATA COMM. SYSTEMS CORP.", + [3]byte{0, 64, 20}: "COMSOFT GMBH", + [3]byte{0, 64, 21}: "ASCOM INFRASYS AG", + [3]byte{0, 64, 22}: "ADC - Global Connectivity Solutions Division", + [3]byte{0, 64, 23}: "Silex Technology America", + [3]byte{0, 64, 24}: "ADOBE SYSTEMS, INC.", + [3]byte{0, 64, 25}: "AEON SYSTEMS, INC.", + [3]byte{0, 64, 26}: "FUJI ELECTRIC CO., LTD.", + [3]byte{0, 64, 27}: "PRINTER SYSTEMS CORP.", + [3]byte{0, 64, 28}: "AST RESEARCH, INC.", + [3]byte{0, 64, 29}: "INVISIBLE SOFTWARE, INC.", + [3]byte{0, 64, 30}: "ICC", + [3]byte{0, 64, 31}: "COLORGRAPH LTD", + [3]byte{0, 64, 32}: "TE Connectivity Ltd.", + [3]byte{0, 64, 33}: "RASTER GRAPHICS", + [3]byte{0, 64, 34}: "KLEVER COMPUTERS, INC.", + [3]byte{0, 64, 35}: "LOGIC CORPORATION", + [3]byte{0, 64, 36}: "COMPAC INC.", + [3]byte{0, 64, 37}: "MOLECULAR DYNAMICS", + [3]byte{0, 64, 38}: "Buffalo Inc.", + [3]byte{0, 64, 39}: "SMC MASSACHUSETTS, INC.", + [3]byte{0, 64, 40}: "NETCOMM LIMITED", + [3]byte{0, 64, 41}: "COMPEX", + [3]byte{0, 64, 42}: "CANOGA-PERKINS", + [3]byte{0, 64, 43}: "TRIGEM COMPUTER, INC.", + [3]byte{0, 64, 44}: "ISIS DISTRIBUTED SYSTEMS, INC.", + [3]byte{0, 64, 45}: "HARRIS ADACOM CORPORATION", + [3]byte{0, 64, 46}: "PRECISION SOFTWARE, INC.", + [3]byte{0, 64, 47}: "XLNT DESIGNS INC.", + [3]byte{0, 64, 48}: "GK COMPUTER", + [3]byte{0, 64, 49}: "KOKUSAI ELECTRIC CO., LTD", + [3]byte{0, 64, 50}: "DIGITAL COMMUNICATIONS", + [3]byte{0, 64, 51}: "ADDTRON TECHNOLOGY CO., LTD.", + [3]byte{0, 64, 52}: "BUSTEK CORPORATION", + [3]byte{0, 64, 53}: "OPCOM", + [3]byte{0, 64, 54}: "TRIBE COMPUTER WORKS, INC.", + [3]byte{0, 64, 55}: "SEA-ILAN, INC.", + [3]byte{0, 64, 56}: "TALENT ELECTRIC INCORPORATED", + [3]byte{0, 64, 57}: "OPTEC DAIICHI DENKO CO., LTD.", + [3]byte{0, 64, 58}: "IMPACT TECHNOLOGIES", + [3]byte{0, 64, 59}: "SYNERJET INTERNATIONAL CORP.", + [3]byte{0, 64, 60}: "FORKS, INC.", + [3]byte{0, 64, 61}: "Teradata Corporation", + [3]byte{0, 64, 62}: "RASTER OPS CORPORATION", + [3]byte{0, 64, 63}: "SSANGYONG COMPUTER SYSTEMS", + [3]byte{0, 64, 64}: "RING ACCESS, INC.", + [3]byte{0, 64, 65}: "FUJIKURA LTD.", + [3]byte{0, 64, 66}: "N.A.T. GMBH", + [3]byte{0, 64, 67}: "Nokia Siemens Networks GmbH & Co. KG.", + [3]byte{0, 64, 68}: "QNIX COMPUTER CO., LTD.", + [3]byte{0, 64, 69}: "TWINHEAD CORPORATION", + [3]byte{0, 64, 70}: "UDC RESEARCH LIMITED", + [3]byte{0, 64, 71}: "WIND RIVER SYSTEMS", + [3]byte{0, 64, 72}: "SMD INFORMATICA S.A.", + [3]byte{0, 64, 73}: "Roche Diagnostics International Ltd.", + [3]byte{0, 64, 74}: "WEST AUSTRALIAN DEPARTMENT", + [3]byte{0, 64, 75}: "MAPLE COMPUTER SYSTEMS", + [3]byte{0, 64, 76}: "HYPERTEC PTY LTD.", + [3]byte{0, 64, 77}: "TELECOMMUNICATIONS TECHNIQUES", + [3]byte{0, 64, 78}: "FLUENT, INC.", + [3]byte{0, 64, 79}: "SPACE & NAVAL WARFARE SYSTEMS", + [3]byte{0, 64, 80}: "IRONICS, INCORPORATED", + [3]byte{0, 64, 81}: "GRACILIS, INC.", + [3]byte{0, 64, 82}: "STAR TECHNOLOGIES, INC.", + [3]byte{0, 64, 83}: "AMPRO COMPUTERS", + [3]byte{0, 64, 84}: "CONNECTION MACHINES SERVICES", + [3]byte{0, 64, 85}: "METRONIX GMBH", + [3]byte{0, 64, 86}: "MCM JAPAN LTD.", + [3]byte{0, 64, 87}: "LOCKHEED - SANDERS", + [3]byte{0, 64, 88}: "KRONOS, INC.", + [3]byte{0, 64, 89}: "YOSHIDA KOGYO K. K.", + [3]byte{0, 64, 90}: "GOLDSTAR INFORMATION & COMM.", + [3]byte{0, 64, 91}: "FUNASSET LIMITED", + [3]byte{0, 64, 92}: "FUTURE SYSTEMS, INC.", + [3]byte{0, 64, 93}: "STAR-TEK, INC.", + [3]byte{0, 64, 94}: "NORTH HILLS ISRAEL", + [3]byte{0, 64, 95}: "AFE COMPUTERS LTD.", + [3]byte{0, 64, 96}: "COMENDEC LTD", + [3]byte{0, 64, 97}: "DATATECH ENTERPRISES CO., LTD.", + [3]byte{0, 64, 98}: "E-SYSTEMS, INC./GARLAND DIV.", + [3]byte{0, 64, 99}: "VIA TECHNOLOGIES, INC.", + [3]byte{0, 64, 100}: "KLA INSTRUMENTS CORPORATION", + [3]byte{0, 64, 101}: "GTE SPACENET", + [3]byte{0, 64, 102}: "Hitachi Metals, Ltd.", + [3]byte{0, 64, 103}: "OMNIBYTE CORPORATION", + [3]byte{0, 64, 104}: "EXTENDED SYSTEMS", + [3]byte{0, 64, 105}: "LEMCOM SYSTEMS, INC.", + [3]byte{0, 64, 106}: "KENTEK INFORMATION SYSTEMS,INC", + [3]byte{0, 64, 107}: "SYSGEN", + [3]byte{0, 64, 108}: "COPERNIQUE", + [3]byte{0, 64, 109}: "LANCO, INC.", + [3]byte{0, 64, 110}: "COROLLARY, INC.", + [3]byte{0, 64, 111}: "SYNC RESEARCH INC.", + [3]byte{0, 64, 112}: "INTERWARE CO., LTD.", + [3]byte{0, 64, 113}: "ATM COMPUTER GMBH", + [3]byte{0, 64, 114}: "Applied Innovation Inc.", + [3]byte{0, 64, 115}: "BASS ASSOCIATES", + [3]byte{0, 64, 116}: "CABLE AND WIRELESS", + [3]byte{0, 64, 117}: "Tattile SRL", + [3]byte{0, 64, 118}: "Sun Conversion Technologies", + [3]byte{0, 64, 119}: "MAXTON TECHNOLOGY CORPORATION", + [3]byte{0, 64, 120}: "WEARNES AUTOMATION PTE LTD", + [3]byte{0, 64, 121}: "JUKO MANUFACTURE COMPANY, LTD.", + [3]byte{0, 64, 122}: "SOCIETE D'EXPLOITATION DU CNIT", + [3]byte{0, 64, 123}: "SCIENTIFIC ATLANTA", + [3]byte{0, 64, 124}: "QUME CORPORATION", + [3]byte{0, 64, 125}: "EXTENSION TECHNOLOGY CORP.", + [3]byte{0, 64, 126}: "EVERGREEN SYSTEMS, INC.", + [3]byte{0, 64, 127}: "FLIR Systems", + [3]byte{0, 64, 128}: "ATHENIX CORPORATION", + [3]byte{0, 64, 129}: "MANNESMANN SCANGRAPHIC GMBH", + [3]byte{0, 64, 130}: "LABORATORY EQUIPMENT CORP.", + [3]byte{0, 64, 131}: "TDA INDUSTRIA DE PRODUTOS", + [3]byte{0, 64, 132}: "HONEYWELL ACS", + [3]byte{0, 64, 133}: "SAAB INSTRUMENTS AB", + [3]byte{0, 64, 134}: "MICHELS & KLEBERHOFF COMPUTER", + [3]byte{0, 64, 135}: "UBITREX CORPORATION", + [3]byte{0, 64, 136}: "MOBIUS TECHNOLOGIES, INC.", + [3]byte{0, 64, 137}: "MEIDENSHA CORPORATION", + [3]byte{0, 64, 138}: "TPS TELEPROCESSING SYS. GMBH", + [3]byte{0, 64, 139}: "RAYLAN CORPORATION", + [3]byte{0, 64, 140}: "AXIS COMMUNICATIONS AB", + [3]byte{0, 64, 141}: "THE GOODYEAR TIRE & RUBBER CO.", + [3]byte{0, 64, 142}: "Tattile SRL", + [3]byte{0, 64, 143}: "WM-DATA MINFO AB", + [3]byte{0, 64, 144}: "ANSEL COMMUNICATIONS", + [3]byte{0, 64, 145}: "PROCOMP INDUSTRIA ELETRONICA", + [3]byte{0, 64, 146}: "ASP COMPUTER PRODUCTS, INC.", + [3]byte{0, 64, 147}: "PAXDATA NETWORKS LTD.", + [3]byte{0, 64, 148}: "SHOGRAPHICS, INC.", + [3]byte{0, 64, 149}: "R.P.T. INTERGROUPS INT'L LTD.", + [3]byte{0, 64, 150}: "Cisco Systems", + [3]byte{0, 64, 151}: "DATEX DIVISION OF", + [3]byte{0, 64, 152}: "DRESSLER GMBH & CO.", + [3]byte{0, 64, 153}: "NEWGEN SYSTEMS CORP.", + [3]byte{0, 64, 154}: "NETWORK EXPRESS, INC.", + [3]byte{0, 64, 155}: "HAL COMPUTER SYSTEMS INC.", + [3]byte{0, 64, 156}: "TRANSWARE", + [3]byte{0, 64, 157}: "DIGIBOARD, INC.", + [3]byte{0, 64, 158}: "CONCURRENT TECHNOLOGIES LTD.", + [3]byte{0, 64, 159}: "Telco Systems, Inc.", + [3]byte{0, 64, 160}: "GOLDSTAR CO., LTD.", + [3]byte{0, 64, 161}: "ERGO COMPUTING", + [3]byte{0, 64, 162}: "KINGSTAR TECHNOLOGY INC.", + [3]byte{0, 64, 163}: "MICROUNITY SYSTEMS ENGINEERING", + [3]byte{0, 64, 164}: "ROSE ELECTRONICS", + [3]byte{0, 64, 165}: "CLINICOMP INTL.", + [3]byte{0, 64, 166}: "Cray, Inc.", + [3]byte{0, 64, 167}: "ITAUTEC PHILCO S.A.", + [3]byte{0, 64, 168}: "IMF INTERNATIONAL LTD.", + [3]byte{0, 64, 169}: "DATACOM INC.", + [3]byte{0, 64, 170}: "Metso Automation", + [3]byte{0, 64, 171}: "ROLAND DG CORPORATION", + [3]byte{0, 64, 172}: "SUPER WORKSTATION, INC.", + [3]byte{0, 64, 173}: "SMA REGELSYSTEME GMBH", + [3]byte{0, 64, 174}: "DELTA CONTROLS, INC.", + [3]byte{0, 64, 175}: "DIGITAL PRODUCTS, INC.", + [3]byte{0, 64, 176}: "BYTEX CORPORATION, ENGINEERING", + [3]byte{0, 64, 177}: "CODONICS INC.", + [3]byte{0, 64, 178}: "SYSTEMFORSCHUNG", + [3]byte{0, 64, 179}: "ParTech Inc.", + [3]byte{0, 64, 180}: "NEXTCOM K.K.", + [3]byte{0, 64, 181}: "VIDEO TECHNOLOGY COMPUTERS LTD", + [3]byte{0, 64, 182}: "COMPUTERM CORPORATION", + [3]byte{0, 64, 183}: "STEALTH COMPUTER SYSTEMS", + [3]byte{0, 64, 184}: "IDEA ASSOCIATES", + [3]byte{0, 64, 185}: "MACQ ELECTRONIQUE SA", + [3]byte{0, 64, 186}: "ALLIANT COMPUTER SYSTEMS CORP.", + [3]byte{0, 64, 187}: "GOLDSTAR CABLE CO., LTD.", + [3]byte{0, 64, 188}: "ALGORITHMICS LTD.", + [3]byte{0, 64, 189}: "STARLIGHT NETWORKS, INC.", + [3]byte{0, 64, 190}: "BOEING DEFENSE & SPACE", + [3]byte{0, 64, 191}: "CHANNEL SYSTEMS INTERN'L INC.", + [3]byte{0, 64, 192}: "VISTA CONTROLS CORPORATION", + [3]byte{0, 64, 193}: "BIZERBA-WERKE WILHEIM KRAUT", + [3]byte{0, 64, 194}: "APPLIED COMPUTING DEVICES", + [3]byte{0, 64, 195}: "FISCHER AND PORTER CO.", + [3]byte{0, 64, 196}: "KINKEI SYSTEM CORPORATION", + [3]byte{0, 64, 197}: "MICOM COMMUNICATIONS INC.", + [3]byte{0, 64, 198}: "FIBERNET RESEARCH, INC.", + [3]byte{0, 64, 199}: "RUBY TECH CORPORATION", + [3]byte{0, 64, 200}: "MILAN TECHNOLOGY CORPORATION", + [3]byte{0, 64, 201}: "NCUBE", + [3]byte{0, 64, 202}: "FIRST INTERNAT'L COMPUTER, INC", + [3]byte{0, 64, 203}: "LANWAN TECHNOLOGIES", + [3]byte{0, 64, 204}: "SILCOM MANUF'G TECHNOLOGY INC.", + [3]byte{0, 64, 205}: "TERA MICROSYSTEMS, INC.", + [3]byte{0, 64, 206}: "NET-SOURCE, INC.", + [3]byte{0, 64, 207}: "STRAWBERRY TREE, INC.", + [3]byte{0, 64, 208}: "MITAC INTERNATIONAL CORP.", + [3]byte{0, 64, 209}: "FUKUDA DENSHI CO., LTD.", + [3]byte{0, 64, 210}: "PAGINE CORPORATION", + [3]byte{0, 64, 211}: "KIMPSION INTERNATIONAL CORP.", + [3]byte{0, 64, 212}: "GAGE TALKER CORP.", + [3]byte{0, 64, 213}: "Sartorius Mechatronics T&H GmbH", + [3]byte{0, 64, 214}: "LOCAMATION B.V.", + [3]byte{0, 64, 215}: "STUDIO GEN INC.", + [3]byte{0, 64, 216}: "OCEAN OFFICE AUTOMATION LTD.", + [3]byte{0, 64, 217}: "AMERICAN MEGATRENDS INC.", + [3]byte{0, 64, 218}: "TELSPEC LTD", + [3]byte{0, 64, 219}: "ADVANCED TECHNICAL SOLUTIONS", + [3]byte{0, 64, 220}: "TRITEC ELECTRONIC GMBH", + [3]byte{0, 64, 221}: "HONG TECHNOLOGIES", + [3]byte{0, 64, 222}: "Elsag Datamat spa", + [3]byte{0, 64, 223}: "DIGALOG SYSTEMS, INC.", + [3]byte{0, 64, 224}: "ATOMWIDE LTD.", + [3]byte{0, 64, 225}: "MARNER INTERNATIONAL, INC.", + [3]byte{0, 64, 226}: "MESA RIDGE TECHNOLOGIES, INC.", + [3]byte{0, 64, 227}: "QUIN SYSTEMS LTD", + [3]byte{0, 64, 228}: "E-M TECHNOLOGY, INC.", + [3]byte{0, 64, 229}: "SYBUS CORPORATION", + [3]byte{0, 64, 230}: "C.A.E.N.", + [3]byte{0, 64, 231}: "ARNOS INSTRUMENTS & COMPUTER", + [3]byte{0, 64, 232}: "CHARLES RIVER DATA SYSTEMS,INC", + [3]byte{0, 64, 233}: "ACCORD SYSTEMS, INC.", + [3]byte{0, 64, 234}: "PLAIN TREE SYSTEMS INC", + [3]byte{0, 64, 235}: "MARTIN MARIETTA CORPORATION", + [3]byte{0, 64, 236}: "MIKASA SYSTEM ENGINEERING", + [3]byte{0, 64, 237}: "NETWORK CONTROLS INT'NATL INC.", + [3]byte{0, 64, 238}: "OPTIMEM", + [3]byte{0, 64, 239}: "HYPERCOM, INC.", + [3]byte{0, 64, 240}: "MicroBrain,Inc.", + [3]byte{0, 64, 241}: "CHUO ELECTRONICS CO., LTD.", + [3]byte{0, 64, 242}: "JANICH & KLASS COMPUTERTECHNIK", + [3]byte{0, 64, 243}: "NETCOR", + [3]byte{0, 64, 244}: "CAMEO COMMUNICATIONS, INC.", + [3]byte{0, 64, 245}: "OEM ENGINES", + [3]byte{0, 64, 246}: "KATRON COMPUTERS INC.", + [3]byte{0, 64, 247}: "Polaroid Corporation", + [3]byte{0, 64, 248}: "SYSTEMHAUS DISCOM", + [3]byte{0, 64, 249}: "COMBINET", + [3]byte{0, 64, 250}: "MICROBOARDS, INC.", + [3]byte{0, 64, 251}: "CASCADE COMMUNICATIONS CORP.", + [3]byte{0, 64, 252}: "IBR COMPUTER TECHNIK GMBH", + [3]byte{0, 64, 253}: "LXE", + [3]byte{0, 64, 254}: "SYMPLEX COMMUNICATIONS", + [3]byte{0, 64, 255}: "TELEBIT CORPORATION", + [3]byte{0, 65, 180}: "Wuxi Zhongxing Optoelectronics Technology Co.,Ltd.", + [3]byte{0, 66, 82}: "RLX Technologies", + [3]byte{0, 67, 255}: "KETRON S.R.L.", + [3]byte{0, 69, 1}: "Versus Technology, Inc.", + [3]byte{0, 70, 75}: "HUAWEI TECHNOLOGIES CO.,LTD", + [3]byte{0, 77, 50}: "Andon Health Co.,Ltd.", + [3]byte{0, 80, 0}: "NEXO COMMUNICATIONS, INC.", + [3]byte{0, 80, 1}: "YAMASHITA SYSTEMS CORP.", + [3]byte{0, 80, 2}: "OMNISEC AG", + [3]byte{0, 80, 3}: "Xrite Inc", + [3]byte{0, 80, 4}: "3COM CORPORATION", + [3]byte{0, 80, 6}: "TAC AB", + [3]byte{0, 80, 7}: "SIEMENS TELECOMMUNICATION SYSTEMS LIMITED", + [3]byte{0, 80, 8}: "TIVA MICROCOMPUTER CORP. (TMC)", + [3]byte{0, 80, 9}: "PHILIPS BROADBAND NETWORKS", + [3]byte{0, 80, 10}: "IRIS TECHNOLOGIES, INC.", + [3]byte{0, 80, 11}: "CISCO SYSTEMS, INC.", + [3]byte{0, 80, 12}: "e-Tek Labs, Inc.", + [3]byte{0, 80, 13}: "SATORI ELECTORIC CO., LTD.", + [3]byte{0, 80, 14}: "CHROMATIS NETWORKS, INC.", + [3]byte{0, 80, 15}: "CISCO SYSTEMS, INC.", + [3]byte{0, 80, 16}: "NovaNET Learning, Inc.", + [3]byte{0, 80, 18}: "CBL - GMBH", + [3]byte{0, 80, 19}: "Chaparral Network Storage", + [3]byte{0, 80, 20}: "CISCO SYSTEMS, INC.", + [3]byte{0, 80, 21}: "BRIGHT STAR ENGINEERING", + [3]byte{0, 80, 22}: "SST/WOODHEAD INDUSTRIES", + [3]byte{0, 80, 23}: "RSR S.R.L.", + [3]byte{0, 80, 24}: "AMIT, Inc.", + [3]byte{0, 80, 25}: "SPRING TIDE NETWORKS, INC.", + [3]byte{0, 80, 26}: "IQinVision", + [3]byte{0, 80, 27}: "ABL CANADA, INC.", + [3]byte{0, 80, 28}: "JATOM SYSTEMS, INC.", + [3]byte{0, 80, 30}: "Miranda Technologies, Inc.", + [3]byte{0, 80, 31}: "MRG SYSTEMS, LTD.", + [3]byte{0, 80, 32}: "MEDIASTAR CO., LTD.", + [3]byte{0, 80, 33}: "EIS INTERNATIONAL, INC.", + [3]byte{0, 80, 34}: "ZONET TECHNOLOGY, INC.", + [3]byte{0, 80, 35}: "PG DESIGN ELECTRONICS, INC.", + [3]byte{0, 80, 36}: "NAVIC SYSTEMS, INC.", + [3]byte{0, 80, 38}: "COSYSTEMS, INC.", + [3]byte{0, 80, 39}: "GENICOM CORPORATION", + [3]byte{0, 80, 40}: "AVAL COMMUNICATIONS", + [3]byte{0, 80, 41}: "1394 PRINTER WORKING GROUP", + [3]byte{0, 80, 42}: "CISCO SYSTEMS, INC.", + [3]byte{0, 80, 43}: "GENRAD LTD.", + [3]byte{0, 80, 44}: "SOYO COMPUTER, INC.", + [3]byte{0, 80, 45}: "ACCEL, INC.", + [3]byte{0, 80, 46}: "CAMBEX CORPORATION", + [3]byte{0, 80, 47}: "TollBridge Technologies, Inc.", + [3]byte{0, 80, 48}: "FUTURE PLUS SYSTEMS", + [3]byte{0, 80, 49}: "AEROFLEX LABORATORIES, INC.", + [3]byte{0, 80, 50}: "PICAZO COMMUNICATIONS, INC.", + [3]byte{0, 80, 51}: "MAYAN NETWORKS", + [3]byte{0, 80, 54}: "NETCAM, LTD.", + [3]byte{0, 80, 55}: "KOGA ELECTRONICS CO.", + [3]byte{0, 80, 56}: "DAIN TELECOM CO., LTD.", + [3]byte{0, 80, 57}: "MARINER NETWORKS", + [3]byte{0, 80, 58}: "DATONG ELECTRONICS LTD.", + [3]byte{0, 80, 59}: "MEDIAFIRE CORPORATION", + [3]byte{0, 80, 60}: "TSINGHUA NOVEL ELECTRONICS", + [3]byte{0, 80, 62}: "CISCO SYSTEMS, INC.", + [3]byte{0, 80, 63}: "ANCHOR GAMES", + [3]byte{0, 80, 64}: "Panasonic Electric Works Co., Ltd.", + [3]byte{0, 80, 65}: "Coretronic Corporation", + [3]byte{0, 80, 66}: "SCI MANUFACTURING SINGAPORE PTE, LTD.", + [3]byte{0, 80, 67}: "MARVELL SEMICONDUCTOR, INC.", + [3]byte{0, 80, 68}: "ASACA CORPORATION", + [3]byte{0, 80, 69}: "RIOWORKS SOLUTIONS, INC.", + [3]byte{0, 80, 70}: "MENICX INTERNATIONAL CO., LTD.", + [3]byte{0, 80, 71}: "PRIVATE", + [3]byte{0, 80, 72}: "INFOLIBRIA", + [3]byte{0, 80, 73}: "Arbor Networks Inc", + [3]byte{0, 80, 74}: "ELTECO A.S.", + [3]byte{0, 80, 75}: "BARCONET N.V.", + [3]byte{0, 80, 76}: "Galil Motion Control", + [3]byte{0, 80, 77}: "Tokyo Electron Device Limited", + [3]byte{0, 80, 78}: "SIERRA MONITOR CORP.", + [3]byte{0, 80, 79}: "OLENCOM ELECTRONICS", + [3]byte{0, 80, 80}: "CISCO SYSTEMS, INC.", + [3]byte{0, 80, 81}: "IWATSU ELECTRIC CO., LTD.", + [3]byte{0, 80, 82}: "TIARA NETWORKS, INC.", + [3]byte{0, 80, 83}: "CISCO SYSTEMS, INC.", + [3]byte{0, 80, 84}: "CISCO SYSTEMS, INC.", + [3]byte{0, 80, 85}: "DOMS A/S", + [3]byte{0, 80, 86}: "VMware, Inc.", + [3]byte{0, 80, 87}: "BROADBAND ACCESS SYSTEMS", + [3]byte{0, 80, 88}: "VegaStream Group Limted", + [3]byte{0, 80, 89}: "iBAHN", + [3]byte{0, 80, 90}: "NETWORK ALCHEMY, INC.", + [3]byte{0, 80, 91}: "KAWASAKI LSI U.S.A., INC.", + [3]byte{0, 80, 92}: "TUNDO CORPORATION", + [3]byte{0, 80, 94}: "DIGITEK MICROLOGIC S.A.", + [3]byte{0, 80, 95}: "BRAND INNOVATORS", + [3]byte{0, 80, 96}: "TANDBERG TELECOM AS", + [3]byte{0, 80, 98}: "KOUWELL ELECTRONICS CORP. **", + [3]byte{0, 80, 99}: "OY COMSEL SYSTEM AB", + [3]byte{0, 80, 100}: "CAE ELECTRONICS", + [3]byte{0, 80, 101}: "TDK-Lambda Corporation", + [3]byte{0, 80, 102}: "AtecoM GmbH advanced telecomunication modules", + [3]byte{0, 80, 103}: "AEROCOMM, INC.", + [3]byte{0, 80, 104}: "ELECTRONIC INDUSTRIES ASSOCIATION", + [3]byte{0, 80, 105}: "PixStream Incorporated", + [3]byte{0, 80, 106}: "EDEVA, INC.", + [3]byte{0, 80, 107}: "SPX-ATEG", + [3]byte{0, 80, 108}: "Beijer Electronics Products AB", + [3]byte{0, 80, 109}: "VIDEOJET SYSTEMS", + [3]byte{0, 80, 110}: "CORDER ENGINEERING CORPORATION", + [3]byte{0, 80, 111}: "G-CONNECT", + [3]byte{0, 80, 112}: "CHAINTECH COMPUTER CO., LTD.", + [3]byte{0, 80, 113}: "AIWA CO., LTD.", + [3]byte{0, 80, 114}: "CORVIS CORPORATION", + [3]byte{0, 80, 115}: "CISCO SYSTEMS, INC.", + [3]byte{0, 80, 116}: "ADVANCED HI-TECH CORP.", + [3]byte{0, 80, 117}: "KESTREL SOLUTIONS", + [3]byte{0, 80, 118}: "IBM Corp", + [3]byte{0, 80, 119}: "PROLIFIC TECHNOLOGY, INC.", + [3]byte{0, 80, 120}: "MEGATON HOUSE, LTD.", + [3]byte{0, 80, 121}: "PRIVATE", + [3]byte{0, 80, 122}: "XPEED, INC.", + [3]byte{0, 80, 123}: "MERLOT COMMUNICATIONS", + [3]byte{0, 80, 124}: "VIDEOCON AG", + [3]byte{0, 80, 125}: "IFP", + [3]byte{0, 80, 126}: "NEWER TECHNOLOGY", + [3]byte{0, 80, 127}: "DrayTek Corp.", + [3]byte{0, 80, 128}: "CISCO SYSTEMS, INC.", + [3]byte{0, 80, 129}: "MURATA MACHINERY, LTD.", + [3]byte{0, 80, 130}: "FORESSON CORPORATION", + [3]byte{0, 80, 131}: "GILBARCO, INC.", + [3]byte{0, 80, 132}: "ATL PRODUCTS", + [3]byte{0, 80, 134}: "TELKOM SA, LTD.", + [3]byte{0, 80, 135}: "TERASAKI ELECTRIC CO., LTD.", + [3]byte{0, 80, 136}: "AMANO CORPORATION", + [3]byte{0, 80, 137}: "SAFETY MANAGEMENT SYSTEMS", + [3]byte{0, 80, 139}: "Hewlett-Packard Company", + [3]byte{0, 80, 140}: "RSI SYSTEMS", + [3]byte{0, 80, 141}: "ABIT COMPUTER CORPORATION", + [3]byte{0, 80, 142}: "OPTIMATION, INC.", + [3]byte{0, 80, 143}: "ASITA TECHNOLOGIES INT'L LTD.", + [3]byte{0, 80, 144}: "DCTRI", + [3]byte{0, 80, 145}: "NETACCESS, INC.", + [3]byte{0, 80, 146}: "RIGAKU INDUSTRIAL CORPORATION", + [3]byte{0, 80, 147}: "BOEING", + [3]byte{0, 80, 148}: "PACE plc", + [3]byte{0, 80, 149}: "PERACOM NETWORKS", + [3]byte{0, 80, 150}: "SALIX TECHNOLOGIES, INC.", + [3]byte{0, 80, 151}: "MMC-EMBEDDED COMPUTERTECHNIK GmbH", + [3]byte{0, 80, 152}: "GLOBALOOP, LTD.", + [3]byte{0, 80, 153}: "3COM EUROPE, LTD.", + [3]byte{0, 80, 154}: "TAG ELECTRONIC SYSTEMS", + [3]byte{0, 80, 155}: "SWITCHCORE AB", + [3]byte{0, 80, 156}: "BETA RESEARCH", + [3]byte{0, 80, 157}: "THE INDUSTREE B.V.", + [3]byte{0, 80, 158}: "Les Technologies SoftAcoustik Inc.", + [3]byte{0, 80, 159}: "HORIZON COMPUTER", + [3]byte{0, 80, 160}: "DELTA COMPUTER SYSTEMS, INC.", + [3]byte{0, 80, 161}: "CARLO GAVAZZI, INC.", + [3]byte{0, 80, 162}: "CISCO SYSTEMS, INC.", + [3]byte{0, 80, 163}: "TransMedia Communications, Inc.", + [3]byte{0, 80, 164}: "IO TECH, INC.", + [3]byte{0, 80, 165}: "CAPITOL BUSINESS SYSTEMS, LTD.", + [3]byte{0, 80, 166}: "OPTRONICS", + [3]byte{0, 80, 167}: "CISCO SYSTEMS, INC.", + [3]byte{0, 80, 168}: "OpenCon Systems, Inc.", + [3]byte{0, 80, 169}: "MOLDAT WIRELESS TECHNOLGIES", + [3]byte{0, 80, 170}: "KONICA MINOLTA HOLDINGS, INC.", + [3]byte{0, 80, 171}: "NALTEC, Inc.", + [3]byte{0, 80, 172}: "MAPLE COMPUTER CORPORATION", + [3]byte{0, 80, 173}: "CommUnique Wireless Corp.", + [3]byte{0, 80, 174}: "FDK Co., Ltd", + [3]byte{0, 80, 175}: "INTERGON, INC.", + [3]byte{0, 80, 176}: "TECHNOLOGY ATLANTA CORPORATION", + [3]byte{0, 80, 177}: "GIDDINGS & LEWIS", + [3]byte{0, 80, 178}: "BRODEL GmbH", + [3]byte{0, 80, 179}: "VOICEBOARD CORPORATION", + [3]byte{0, 80, 180}: "SATCHWELL CONTROL SYSTEMS, LTD", + [3]byte{0, 80, 181}: "FICHET-BAUCHE", + [3]byte{0, 80, 182}: "GOOD WAY IND. CO., LTD.", + [3]byte{0, 80, 183}: "BOSER TECHNOLOGY CO., LTD.", + [3]byte{0, 80, 184}: "INOVA COMPUTERS GMBH & CO. KG", + [3]byte{0, 80, 185}: "XITRON TECHNOLOGIES, INC.", + [3]byte{0, 80, 186}: "D-LINK", + [3]byte{0, 80, 187}: "CMS TECHNOLOGIES", + [3]byte{0, 80, 188}: "HAMMER STORAGE SOLUTIONS", + [3]byte{0, 80, 189}: "CISCO SYSTEMS, INC.", + [3]byte{0, 80, 190}: "FAST MULTIMEDIA AG", + [3]byte{0, 80, 191}: "Metalligence Technology Corp.", + [3]byte{0, 80, 192}: "GATAN, INC.", + [3]byte{0, 80, 193}: "GEMFLEX NETWORKS, LTD.", + [3]byte{0, 80, 194}: "IEEE REGISTRATION AUTHORITY - Please see IAB public listing for more information.", + [3]byte{0, 80, 196}: "IMD", + [3]byte{0, 80, 197}: "ADS Technologies, Inc", + [3]byte{0, 80, 198}: "LOOP TELECOMMUNICATION INTERNATIONAL, INC.", + [3]byte{0, 80, 200}: "Addonics Technologies, Inc.", + [3]byte{0, 80, 201}: "MASPRO DENKOH CORP.", + [3]byte{0, 80, 202}: "NET TO NET TECHNOLOGIES", + [3]byte{0, 80, 203}: "JETTER", + [3]byte{0, 80, 204}: "XYRATEX", + [3]byte{0, 80, 205}: "DIGIANSWER A/S", + [3]byte{0, 80, 206}: "LG INTERNATIONAL CORP.", + [3]byte{0, 80, 207}: "VANLINK COMMUNICATION TECHNOLOGY RESEARCH INSTITUTE", + [3]byte{0, 80, 208}: "MINERVA SYSTEMS", + [3]byte{0, 80, 209}: "CISCO SYSTEMS, INC.", + [3]byte{0, 80, 210}: "CMC Electronics Inc", + [3]byte{0, 80, 211}: "DIGITAL AUDIO PROCESSING PTY. LTD.", + [3]byte{0, 80, 212}: "JOOHONG INFORMATION &", + [3]byte{0, 80, 213}: "AD SYSTEMS CORP.", + [3]byte{0, 80, 214}: "ATLAS COPCO TOOLS AB", + [3]byte{0, 80, 215}: "TELSTRAT", + [3]byte{0, 80, 216}: "UNICORN COMPUTER CORP.", + [3]byte{0, 80, 217}: "ENGETRON-ENGENHARIA ELETRONICA IND. e COM. LTDA", + [3]byte{0, 80, 218}: "3COM CORPORATION", + [3]byte{0, 80, 219}: "CONTEMPORARY CONTROL", + [3]byte{0, 80, 220}: "TAS TELEFONBAU A. SCHWABE GMBH & CO. KG", + [3]byte{0, 80, 221}: "SERRA SOLDADURA, S.A.", + [3]byte{0, 80, 222}: "SIGNUM SYSTEMS CORP.", + [3]byte{0, 80, 223}: "AirFiber, Inc.", + [3]byte{0, 80, 225}: "NS TECH ELECTRONICS SDN BHD", + [3]byte{0, 80, 226}: "CISCO SYSTEMS, INC.", + [3]byte{0, 80, 227}: "ARRIS Group, Inc.", + [3]byte{0, 80, 228}: "Apple", + [3]byte{0, 80, 230}: "HAKUSAN CORPORATION", + [3]byte{0, 80, 231}: "PARADISE INNOVATIONS (ASIA)", + [3]byte{0, 80, 232}: "NOMADIX INC.", + [3]byte{0, 80, 234}: "XEL COMMUNICATIONS, INC.", + [3]byte{0, 80, 235}: "ALPHA-TOP CORPORATION", + [3]byte{0, 80, 236}: "OLICOM A/S", + [3]byte{0, 80, 237}: "ANDA NETWORKS", + [3]byte{0, 80, 238}: "TEK DIGITEL CORPORATION", + [3]byte{0, 80, 239}: "SPE Systemhaus GmbH", + [3]byte{0, 80, 240}: "CISCO SYSTEMS, INC.", + [3]byte{0, 80, 241}: "Intel Corporation", + [3]byte{0, 80, 242}: "MICROSOFT CORP.", + [3]byte{0, 80, 243}: "GLOBAL NET INFORMATION CO., Ltd.", + [3]byte{0, 80, 244}: "SIGMATEK GMBH & CO. KG", + [3]byte{0, 80, 246}: "PAN-INTERNATIONAL INDUSTRIAL CORP.", + [3]byte{0, 80, 247}: "VENTURE MANUFACTURING (SINGAPORE) LTD.", + [3]byte{0, 80, 248}: "ENTREGA TECHNOLOGIES, INC.", + [3]byte{0, 80, 249}: "Sensormatic Electronics LLC", + [3]byte{0, 80, 250}: "OXTEL, LTD.", + [3]byte{0, 80, 251}: "VSK ELECTRONICS", + [3]byte{0, 80, 252}: "EDIMAX TECHNOLOGY CO., LTD.", + [3]byte{0, 80, 253}: "VISIONCOMM CO., LTD.", + [3]byte{0, 80, 254}: "PCTVnet ASA", + [3]byte{0, 80, 255}: "HAKKO ELECTRONICS CO., LTD.", + [3]byte{0, 82, 24}: "Wuxi Keboda Electron Co.Ltd", + [3]byte{0, 84, 175}: "Continental Automotive Systems Inc.", + [3]byte{0, 89, 7}: "LenovoEMC Products USA, LLC", + [3]byte{0, 90, 57}: "SHENZHEN FAST TECHNOLOGIES CO., LTD.", + [3]byte{0, 92, 177}: "Gospell DIGITAL TECHNOLOGY CO., LTD", + [3]byte{0, 93, 3}: "Xilinx, Inc", + [3]byte{0, 96, 0}: "XYCOM INC.", + [3]byte{0, 96, 1}: "InnoSys, Inc.", + [3]byte{0, 96, 2}: "SCREEN SUBTITLING SYSTEMS, LTD", + [3]byte{0, 96, 3}: "TERAOKA WEIGH SYSTEM PTE, LTD.", + [3]byte{0, 96, 4}: "COMPUTADORES MODULARES SA", + [3]byte{0, 96, 5}: "FEEDBACK DATA LTD.", + [3]byte{0, 96, 6}: "SOTEC CO., LTD", + [3]byte{0, 96, 7}: "ACRES GAMING, INC.", + [3]byte{0, 96, 8}: "3COM CORPORATION", + [3]byte{0, 96, 9}: "CISCO SYSTEMS, INC.", + [3]byte{0, 96, 10}: "SORD COMPUTER CORPORATION", + [3]byte{0, 96, 11}: "LOGWARE GmbH", + [3]byte{0, 96, 12}: "Eurotech Inc.", + [3]byte{0, 96, 13}: "Digital Logic GmbH", + [3]byte{0, 96, 14}: "WAVENET INTERNATIONAL, INC.", + [3]byte{0, 96, 15}: "WESTELL, INC.", + [3]byte{0, 96, 16}: "NETWORK MACHINES, INC.", + [3]byte{0, 96, 17}: "CRYSTAL SEMICONDUCTOR CORP.", + [3]byte{0, 96, 18}: "POWER COMPUTING CORPORATION", + [3]byte{0, 96, 19}: "NETSTAL MASCHINEN AG", + [3]byte{0, 96, 20}: "EDEC CO., LTD.", + [3]byte{0, 96, 21}: "NET2NET CORPORATION", + [3]byte{0, 96, 22}: "CLARIION", + [3]byte{0, 96, 23}: "TOKIMEC INC.", + [3]byte{0, 96, 24}: "STELLAR ONE CORPORATION", + [3]byte{0, 96, 25}: "Roche Diagnostics", + [3]byte{0, 96, 26}: "KEITHLEY INSTRUMENTS", + [3]byte{0, 96, 27}: "MESA ELECTRONICS", + [3]byte{0, 96, 28}: "TELXON CORPORATION", + [3]byte{0, 96, 29}: "LUCENT TECHNOLOGIES", + [3]byte{0, 96, 30}: "SOFTLAB, INC.", + [3]byte{0, 96, 31}: "STALLION TECHNOLOGIES", + [3]byte{0, 96, 32}: "PIVOTAL NETWORKING, INC.", + [3]byte{0, 96, 33}: "DSC CORPORATION", + [3]byte{0, 96, 34}: "VICOM SYSTEMS, INC.", + [3]byte{0, 96, 35}: "PERICOM SEMICONDUCTOR CORP.", + [3]byte{0, 96, 36}: "GRADIENT TECHNOLOGIES, INC.", + [3]byte{0, 96, 37}: "ACTIVE IMAGING PLC", + [3]byte{0, 96, 38}: "VIKING Modular Solutions", + [3]byte{0, 96, 39}: "Superior Modular Products", + [3]byte{0, 96, 40}: "MACROVISION CORPORATION", + [3]byte{0, 96, 41}: "CARY PERIPHERALS INC.", + [3]byte{0, 96, 42}: "SYMICRON COMPUTER COMMUNICATIONS, LTD.", + [3]byte{0, 96, 43}: "PEAK AUDIO", + [3]byte{0, 96, 44}: "LINX Data Terminals, Inc.", + [3]byte{0, 96, 45}: "ALERTON TECHNOLOGIES, INC.", + [3]byte{0, 96, 46}: "CYCLADES CORPORATION", + [3]byte{0, 96, 47}: "CISCO SYSTEMS, INC.", + [3]byte{0, 96, 48}: "VILLAGE TRONIC ENTWICKLUNG", + [3]byte{0, 96, 49}: "HRK SYSTEMS", + [3]byte{0, 96, 50}: "I-CUBE, INC.", + [3]byte{0, 96, 51}: "ACUITY IMAGING, INC.", + [3]byte{0, 96, 52}: "ROBERT BOSCH GmbH", + [3]byte{0, 96, 53}: "DALLAS SEMICONDUCTOR, INC.", + [3]byte{0, 96, 54}: "AIT Austrian Institute of Technology GmbH", + [3]byte{0, 96, 55}: "NXP Semiconductors", + [3]byte{0, 96, 56}: "Nortel Networks", + [3]byte{0, 96, 57}: "SanCom Technology, Inc.", + [3]byte{0, 96, 58}: "QUICK CONTROLS LTD.", + [3]byte{0, 96, 59}: "AMTEC spa", + [3]byte{0, 96, 60}: "HAGIWARA SYS-COM CO., LTD.", + [3]byte{0, 96, 61}: "3CX", + [3]byte{0, 96, 62}: "CISCO SYSTEMS, INC.", + [3]byte{0, 96, 63}: "PATAPSCO DESIGNS", + [3]byte{0, 96, 64}: "NETRO CORP.", + [3]byte{0, 96, 65}: "Yokogawa Electric Corporation", + [3]byte{0, 96, 66}: "TKS (USA), INC.", + [3]byte{0, 96, 67}: "iDirect, INC.", + [3]byte{0, 96, 68}: "LITTON/POLY-SCIENTIFIC", + [3]byte{0, 96, 69}: "PATHLIGHT TECHNOLOGIES", + [3]byte{0, 96, 70}: "VMETRO, INC.", + [3]byte{0, 96, 71}: "CISCO SYSTEMS, INC.", + [3]byte{0, 96, 72}: "EMC CORPORATION", + [3]byte{0, 96, 73}: "VINA TECHNOLOGIES", + [3]byte{0, 96, 74}: "SAIC IDEAS GROUP", + [3]byte{0, 96, 75}: "Safe-com GmbH & Co. KG", + [3]byte{0, 96, 76}: "SAGEM COMMUNICATION", + [3]byte{0, 96, 77}: "MMC NETWORKS, INC.", + [3]byte{0, 96, 78}: "CYCLE COMPUTER CORPORATION, INC.", + [3]byte{0, 96, 79}: "Tattile SRL", + [3]byte{0, 96, 80}: "INTERNIX INC.", + [3]byte{0, 96, 81}: "QUALITY SEMICONDUCTOR", + [3]byte{0, 96, 82}: "PERIPHERALS ENTERPRISE CO., Ltd.", + [3]byte{0, 96, 83}: "TOYODA MACHINE WORKS, LTD.", + [3]byte{0, 96, 84}: "CONTROLWARE GMBH", + [3]byte{0, 96, 85}: "CORNELL UNIVERSITY", + [3]byte{0, 96, 86}: "NETWORK TOOLS, INC.", + [3]byte{0, 96, 87}: "MURATA MANUFACTURING CO., LTD.", + [3]byte{0, 96, 88}: "COPPER MOUNTAIN COMMUNICATIONS, INC.", + [3]byte{0, 96, 89}: "TECHNICAL COMMUNICATIONS CORP.", + [3]byte{0, 96, 90}: "CELCORE, INC.", + [3]byte{0, 96, 91}: "IntraServer Technology, Inc.", + [3]byte{0, 96, 92}: "CISCO SYSTEMS, INC.", + [3]byte{0, 96, 93}: "SCANIVALVE CORP.", + [3]byte{0, 96, 94}: "LIBERTY TECHNOLOGY NETWORKING", + [3]byte{0, 96, 95}: "NIPPON UNISOFT CORPORATION", + [3]byte{0, 96, 96}: "Data Innovations North America", + [3]byte{0, 96, 97}: "WHISTLE COMMUNICATIONS CORP.", + [3]byte{0, 96, 98}: "TELESYNC, INC.", + [3]byte{0, 96, 99}: "PSION DACOM PLC.", + [3]byte{0, 96, 100}: "NETCOMM LIMITED", + [3]byte{0, 96, 101}: "BERNECKER & RAINER INDUSTRIE-ELEKTRONIC GmbH", + [3]byte{0, 96, 102}: "LACROIX Trafic", + [3]byte{0, 96, 103}: "ACER NETXUS INC.", + [3]byte{0, 96, 104}: "Dialogic Corporation", + [3]byte{0, 96, 105}: "Brocade Communications Systems, Inc.", + [3]byte{0, 96, 106}: "MITSUBISHI WIRELESS COMMUNICATIONS. INC.", + [3]byte{0, 96, 107}: "Synclayer Inc.", + [3]byte{0, 96, 108}: "ARESCOM", + [3]byte{0, 96, 109}: "DIGITAL EQUIPMENT CORP.", + [3]byte{0, 96, 110}: "DAVICOM SEMICONDUCTOR, INC.", + [3]byte{0, 96, 111}: "CLARION CORPORATION OF AMERICA", + [3]byte{0, 96, 112}: "CISCO SYSTEMS, INC.", + [3]byte{0, 96, 113}: "MIDAS LAB, INC.", + [3]byte{0, 96, 114}: "VXL INSTRUMENTS, LIMITED", + [3]byte{0, 96, 115}: "REDCREEK COMMUNICATIONS, INC.", + [3]byte{0, 96, 116}: "QSC AUDIO PRODUCTS", + [3]byte{0, 96, 117}: "PENTEK, INC.", + [3]byte{0, 96, 118}: "SCHLUMBERGER TECHNOLOGIES RETAIL PETROLEUM SYSTEMS", + [3]byte{0, 96, 119}: "PRISA NETWORKS", + [3]byte{0, 96, 120}: "POWER MEASUREMENT LTD.", + [3]byte{0, 96, 121}: "Mainstream Data, Inc.", + [3]byte{0, 96, 122}: "DVS GmbH", + [3]byte{0, 96, 123}: "FORE SYSTEMS, INC.", + [3]byte{0, 96, 124}: "WaveAccess, Ltd.", + [3]byte{0, 96, 125}: "SENTIENT NETWORKS INC.", + [3]byte{0, 96, 126}: "GIGALABS, INC.", + [3]byte{0, 96, 127}: "AURORA TECHNOLOGIES, INC.", + [3]byte{0, 96, 128}: "MICROTRONIX DATACOM LTD.", + [3]byte{0, 96, 129}: "TV/COM INTERNATIONAL", + [3]byte{0, 96, 130}: "NOVALINK TECHNOLOGIES, INC.", + [3]byte{0, 96, 131}: "CISCO SYSTEMS, INC.", + [3]byte{0, 96, 132}: "DIGITAL VIDEO", + [3]byte{0, 96, 133}: "Storage Concepts", + [3]byte{0, 96, 134}: "LOGIC REPLACEMENT TECH. LTD.", + [3]byte{0, 96, 135}: "KANSAI ELECTRIC CO., LTD.", + [3]byte{0, 96, 136}: "WHITE MOUNTAIN DSP, INC.", + [3]byte{0, 96, 137}: "XATA", + [3]byte{0, 96, 138}: "CITADEL COMPUTER", + [3]byte{0, 96, 139}: "ConferTech International", + [3]byte{0, 96, 140}: "3COM CORPORATION", + [3]byte{0, 96, 141}: "UNIPULSE CORP.", + [3]byte{0, 96, 142}: "HE ELECTRONICS, TECHNOLOGIE & SYSTEMTECHNIK GmbH", + [3]byte{0, 96, 143}: "TEKRAM TECHNOLOGY CO., LTD.", + [3]byte{0, 96, 144}: "Artiza Networks Inc", + [3]byte{0, 96, 145}: "FIRST PACIFIC NETWORKS, INC.", + [3]byte{0, 96, 146}: "MICRO/SYS, INC.", + [3]byte{0, 96, 147}: "VARIAN", + [3]byte{0, 96, 148}: "IBM Corp", + [3]byte{0, 96, 149}: "ACCU-TIME SYSTEMS, INC.", + [3]byte{0, 96, 150}: "T.S. MICROTECH INC.", + [3]byte{0, 96, 151}: "3COM CORPORATION", + [3]byte{0, 96, 152}: "HT COMMUNICATIONS", + [3]byte{0, 96, 153}: "SBE, Inc.", + [3]byte{0, 96, 154}: "NJK TECHNO CO.", + [3]byte{0, 96, 155}: "ASTRO-MED, INC.", + [3]byte{0, 96, 156}: "Perkin-Elmer Incorporated", + [3]byte{0, 96, 157}: "PMI FOOD EQUIPMENT GROUP", + [3]byte{0, 96, 158}: "ASC X3 - INFORMATION TECHNOLOGY STANDARDS SECRETARIATS", + [3]byte{0, 96, 159}: "PHAST CORPORATION", + [3]byte{0, 96, 160}: "SWITCHED NETWORK TECHNOLOGIES, INC.", + [3]byte{0, 96, 161}: "VPNet, Inc.", + [3]byte{0, 96, 162}: "NIHON UNISYS LIMITED CO.", + [3]byte{0, 96, 163}: "CONTINUUM TECHNOLOGY CORP.", + [3]byte{0, 96, 164}: "GEW Technologies (PTY)Ltd", + [3]byte{0, 96, 165}: "PERFORMANCE TELECOM CORP.", + [3]byte{0, 96, 166}: "PARTICLE MEASURING SYSTEMS", + [3]byte{0, 96, 167}: "MICROSENS GmbH & CO. KG", + [3]byte{0, 96, 168}: "TIDOMAT AB", + [3]byte{0, 96, 169}: "GESYTEC MbH", + [3]byte{0, 96, 170}: "INTELLIGENT DEVICES INC. (IDI)", + [3]byte{0, 96, 171}: "LARSCOM INCORPORATED", + [3]byte{0, 96, 172}: "RESILIENCE CORPORATION", + [3]byte{0, 96, 173}: "MegaChips Corporation", + [3]byte{0, 96, 174}: "TRIO INFORMATION SYSTEMS AB", + [3]byte{0, 96, 175}: "PACIFIC MICRO DATA, INC.", + [3]byte{0, 96, 176}: "HEWLETT-PACKARD CO.", + [3]byte{0, 96, 177}: "INPUT/OUTPUT, INC.", + [3]byte{0, 96, 178}: "PROCESS CONTROL CORP.", + [3]byte{0, 96, 179}: "Z-COM, INC.", + [3]byte{0, 96, 180}: "GLENAYRE R&D INC.", + [3]byte{0, 96, 181}: "KEBA GmbH", + [3]byte{0, 96, 182}: "LAND COMPUTER CO., LTD.", + [3]byte{0, 96, 183}: "CHANNELMATIC, INC.", + [3]byte{0, 96, 184}: "CORELIS Inc.", + [3]byte{0, 96, 185}: "NEC Platforms, Ltd", + [3]byte{0, 96, 186}: "SAHARA NETWORKS, INC.", + [3]byte{0, 96, 187}: "CABLETRON - NETLINK, INC.", + [3]byte{0, 96, 188}: "KeunYoung Electronics & Communication Co., Ltd.", + [3]byte{0, 96, 189}: "HUBBELL-PULSECOM", + [3]byte{0, 96, 190}: "WEBTRONICS", + [3]byte{0, 96, 191}: "MACRAIGOR SYSTEMS, INC.", + [3]byte{0, 96, 192}: "Nera Networks AS", + [3]byte{0, 96, 193}: "WaveSpan Corporation", + [3]byte{0, 96, 194}: "MPL AG", + [3]byte{0, 96, 195}: "NETVISION CORPORATION", + [3]byte{0, 96, 196}: "SOLITON SYSTEMS K.K.", + [3]byte{0, 96, 197}: "ANCOT CORP.", + [3]byte{0, 96, 198}: "DCS AG", + [3]byte{0, 96, 199}: "AMATI COMMUNICATIONS CORP.", + [3]byte{0, 96, 200}: "KUKA WELDING SYSTEMS & ROBOTS", + [3]byte{0, 96, 201}: "ControlNet, Inc.", + [3]byte{0, 96, 202}: "HARMONIC SYSTEMS INCORPORATED", + [3]byte{0, 96, 203}: "HITACHI ZOSEN CORPORATION", + [3]byte{0, 96, 204}: "EMTRAK, INCORPORATED", + [3]byte{0, 96, 205}: "VideoServer, Inc.", + [3]byte{0, 96, 206}: "ACCLAIM COMMUNICATIONS", + [3]byte{0, 96, 207}: "ALTEON NETWORKS, INC.", + [3]byte{0, 96, 208}: "SNMP RESEARCH INCORPORATED", + [3]byte{0, 96, 209}: "CASCADE COMMUNICATIONS", + [3]byte{0, 96, 210}: "LUCENT TECHNOLOGIES TAIWAN TELECOMMUNICATIONS CO., LTD.", + [3]byte{0, 96, 211}: "AT&T", + [3]byte{0, 96, 212}: "ELDAT COMMUNICATION LTD.", + [3]byte{0, 96, 213}: "MIYACHI TECHNOS CORP.", + [3]byte{0, 96, 214}: "NovAtel Wireless Technologies Ltd.", + [3]byte{0, 96, 215}: "ECOLE POLYTECHNIQUE FEDERALE DE LAUSANNE (EPFL)", + [3]byte{0, 96, 216}: "ELMIC SYSTEMS, INC.", + [3]byte{0, 96, 217}: "TRANSYS NETWORKS INC.", + [3]byte{0, 96, 218}: "JBM ELECTRONICS CO.", + [3]byte{0, 96, 219}: "NTP ELEKTRONIK A/S", + [3]byte{0, 96, 220}: "Toyo Network Systems & System Integration Co. LTD", + [3]byte{0, 96, 221}: "MYRICOM, INC.", + [3]byte{0, 96, 222}: "Kayser-Threde GmbH", + [3]byte{0, 96, 223}: "Brocade Communications Systems, Inc.", + [3]byte{0, 96, 224}: "AXIOM TECHNOLOGY CO., LTD.", + [3]byte{0, 96, 225}: "ORCKIT COMMUNICATIONS LTD.", + [3]byte{0, 96, 226}: "QUEST ENGINEERING & DEVELOPMENT", + [3]byte{0, 96, 227}: "ARBIN INSTRUMENTS", + [3]byte{0, 96, 228}: "COMPUSERVE, INC.", + [3]byte{0, 96, 229}: "FUJI AUTOMATION CO., LTD.", + [3]byte{0, 96, 230}: "SHOMITI SYSTEMS INCORPORATED", + [3]byte{0, 96, 231}: "RANDATA", + [3]byte{0, 96, 232}: "HITACHI COMPUTER PRODUCTS (AMERICA), INC.", + [3]byte{0, 96, 233}: "ATOP TECHNOLOGIES, INC.", + [3]byte{0, 96, 234}: "StreamLogic", + [3]byte{0, 96, 235}: "FOURTHTRACK SYSTEMS", + [3]byte{0, 96, 236}: "HERMARY OPTO ELECTRONICS INC.", + [3]byte{0, 96, 237}: "RICARDO TEST AUTOMATION LTD.", + [3]byte{0, 96, 238}: "APOLLO", + [3]byte{0, 96, 239}: "FLYTECH TECHNOLOGY CO., LTD.", + [3]byte{0, 96, 240}: "JOHNSON & JOHNSON MEDICAL, INC", + [3]byte{0, 96, 241}: "EXP COMPUTER, INC.", + [3]byte{0, 96, 242}: "LASERGRAPHICS, INC.", + [3]byte{0, 96, 243}: "Performance Analysis Broadband, Spirent plc", + [3]byte{0, 96, 244}: "ADVANCED COMPUTER SOLUTIONS, Inc.", + [3]byte{0, 96, 245}: "ICON WEST, INC.", + [3]byte{0, 96, 246}: "NEXTEST COMMUNICATIONS PRODUCTS, INC.", + [3]byte{0, 96, 247}: "DATAFUSION SYSTEMS", + [3]byte{0, 96, 248}: "Loran International Technologies Inc.", + [3]byte{0, 96, 249}: "DIAMOND LANE COMMUNICATIONS", + [3]byte{0, 96, 250}: "EDUCATIONAL TECHNOLOGY RESOURCES, INC.", + [3]byte{0, 96, 251}: "PACKETEER, INC.", + [3]byte{0, 96, 252}: "CONSERVATION THROUGH INNOVATION LTD.", + [3]byte{0, 96, 253}: "NetICs, Inc.", + [3]byte{0, 96, 254}: "LYNX SYSTEM DEVELOPERS, INC.", + [3]byte{0, 96, 255}: "QuVis, Inc.", + [3]byte{0, 97, 113}: "Apple", + [3]byte{0, 100, 64}: "CISCO SYSTEMS, INC.", + [3]byte{0, 100, 166}: "Maquet CardioVascular", + [3]byte{0, 102, 75}: "Huawei Technologies Co., Ltd", + [3]byte{0, 107, 142}: "Shanghai Feixun Communication Co.,Ltd.", + [3]byte{0, 107, 158}: "VIZIO Inc", + [3]byte{0, 107, 160}: "SHENZHEN UNIVERSAL INTELLISYS PTE LTD", + [3]byte{0, 109, 251}: "Vutrix (UK) Ltd", + [3]byte{0, 112, 176}: "M/A-COM INC. COMPANIES", + [3]byte{0, 112, 179}: "DATA RECALL LTD.", + [3]byte{0, 113, 204}: "Hon Hai Precision Ind. Co.,Ltd.", + [3]byte{0, 115, 141}: "Tinno Mobile Technology Corp", + [3]byte{0, 115, 224}: "Samsung Electronics Co.,Ltd", + [3]byte{0, 117, 50}: "INID BV", + [3]byte{0, 117, 225}: "Ampt, LLC", + [3]byte{0, 120, 158}: "SAGEMCOM", + [3]byte{0, 125, 250}: "Volkswagen Group of America", + [3]byte{0, 127, 40}: "Actiontec Electronics, Inc", + [3]byte{0, 128, 0}: "MULTITECH SYSTEMS, INC.", + [3]byte{0, 128, 1}: "PERIPHONICS CORPORATION", + [3]byte{0, 128, 2}: "SATELCOM (UK) LTD", + [3]byte{0, 128, 3}: "HYTEC ELECTRONICS LTD.", + [3]byte{0, 128, 4}: "ANTLOW COMMUNICATIONS, LTD.", + [3]byte{0, 128, 5}: "CACTUS COMPUTER INC.", + [3]byte{0, 128, 6}: "COMPUADD CORPORATION", + [3]byte{0, 128, 7}: "DLOG NC-SYSTEME", + [3]byte{0, 128, 8}: "DYNATECH COMPUTER SYSTEMS", + [3]byte{0, 128, 9}: "JUPITER SYSTEMS, INC.", + [3]byte{0, 128, 10}: "JAPAN COMPUTER CORP.", + [3]byte{0, 128, 11}: "CSK CORPORATION", + [3]byte{0, 128, 12}: "VIDECOM LIMITED", + [3]byte{0, 128, 13}: "VOSSWINKEL F.U.", + [3]byte{0, 128, 14}: "ATLANTIX CORPORATION", + [3]byte{0, 128, 15}: "STANDARD MICROSYSTEMS", + [3]byte{0, 128, 16}: "COMMODORE INTERNATIONAL", + [3]byte{0, 128, 17}: "DIGITAL SYSTEMS INT'L. INC.", + [3]byte{0, 128, 18}: "INTEGRATED MEASUREMENT SYSTEMS", + [3]byte{0, 128, 19}: "THOMAS-CONRAD CORPORATION", + [3]byte{0, 128, 20}: "ESPRIT SYSTEMS", + [3]byte{0, 128, 21}: "SEIKO SYSTEMS, INC.", + [3]byte{0, 128, 22}: "WANDEL AND GOLTERMANN", + [3]byte{0, 128, 23}: "PFU LIMITED", + [3]byte{0, 128, 24}: "KOBE STEEL, LTD.", + [3]byte{0, 128, 25}: "DAYNA COMMUNICATIONS, INC.", + [3]byte{0, 128, 26}: "BELL ATLANTIC", + [3]byte{0, 128, 27}: "KODIAK TECHNOLOGY", + [3]byte{0, 128, 28}: "NEWPORT SYSTEMS SOLUTIONS", + [3]byte{0, 128, 29}: "INTEGRATED INFERENCE MACHINES", + [3]byte{0, 128, 30}: "XINETRON, INC.", + [3]byte{0, 128, 31}: "KRUPP ATLAS ELECTRONIK GMBH", + [3]byte{0, 128, 32}: "NETWORK PRODUCTS", + [3]byte{0, 128, 33}: "Alcatel Canada Inc.", + [3]byte{0, 128, 34}: "SCAN-OPTICS", + [3]byte{0, 128, 35}: "INTEGRATED BUSINESS NETWORKS", + [3]byte{0, 128, 36}: "KALPANA, INC.", + [3]byte{0, 128, 37}: "STOLLMANN GMBH", + [3]byte{0, 128, 38}: "NETWORK PRODUCTS CORPORATION", + [3]byte{0, 128, 39}: "ADAPTIVE SYSTEMS, INC.", + [3]byte{0, 128, 40}: "TRADPOST (HK) LTD", + [3]byte{0, 128, 41}: "EAGLE TECHNOLOGY, INC.", + [3]byte{0, 128, 42}: "TEST SYSTEMS & SIMULATIONS INC", + [3]byte{0, 128, 43}: "INTEGRATED MARKETING CO", + [3]byte{0, 128, 44}: "THE SAGE GROUP PLC", + [3]byte{0, 128, 45}: "XYLOGICS INC", + [3]byte{0, 128, 46}: "CASTLE ROCK COMPUTING", + [3]byte{0, 128, 47}: "NATIONAL INSTRUMENTS CORP.", + [3]byte{0, 128, 48}: "NEXUS ELECTRONICS", + [3]byte{0, 128, 49}: "BASYS, CORP.", + [3]byte{0, 128, 50}: "ACCESS CO., LTD.", + [3]byte{0, 128, 51}: "EMS Aviation, Inc.", + [3]byte{0, 128, 52}: "SMT GOUPIL", + [3]byte{0, 128, 53}: "TECHNOLOGY WORKS, INC.", + [3]byte{0, 128, 54}: "REFLEX MANUFACTURING SYSTEMS", + [3]byte{0, 128, 55}: "Ericsson Group", + [3]byte{0, 128, 56}: "DATA RESEARCH & APPLICATIONS", + [3]byte{0, 128, 57}: "ALCATEL STC AUSTRALIA", + [3]byte{0, 128, 58}: "VARITYPER, INC.", + [3]byte{0, 128, 59}: "APT COMMUNICATIONS, INC.", + [3]byte{0, 128, 60}: "TVS ELECTRONICS LTD", + [3]byte{0, 128, 61}: "SURIGIKEN CO., LTD.", + [3]byte{0, 128, 62}: "SYNERNETICS", + [3]byte{0, 128, 63}: "TATUNG COMPANY", + [3]byte{0, 128, 64}: "JOHN FLUKE MANUFACTURING CO.", + [3]byte{0, 128, 65}: "VEB KOMBINAT ROBOTRON", + [3]byte{0, 128, 66}: "Artesyn Embedded Technologies", + [3]byte{0, 128, 67}: "NETWORLD, INC.", + [3]byte{0, 128, 68}: "SYSTECH COMPUTER CORP.", + [3]byte{0, 128, 69}: "MATSUSHITA ELECTRIC IND. CO", + [3]byte{0, 128, 70}: "Tattile SRL", + [3]byte{0, 128, 71}: "IN-NET CORP.", + [3]byte{0, 128, 72}: "COMPEX INCORPORATED", + [3]byte{0, 128, 73}: "NISSIN ELECTRIC CO., LTD.", + [3]byte{0, 128, 74}: "PRO-LOG", + [3]byte{0, 128, 75}: "EAGLE TECHNOLOGIES PTY.LTD.", + [3]byte{0, 128, 76}: "CONTEC CO., LTD.", + [3]byte{0, 128, 77}: "CYCLONE MICROSYSTEMS, INC.", + [3]byte{0, 128, 78}: "APEX COMPUTER COMPANY", + [3]byte{0, 128, 79}: "DAIKIN INDUSTRIES, LTD.", + [3]byte{0, 128, 80}: "ZIATECH CORPORATION", + [3]byte{0, 128, 81}: "FIBERMUX", + [3]byte{0, 128, 82}: "TECHNICALLY ELITE CONCEPTS", + [3]byte{0, 128, 83}: "INTELLICOM, INC.", + [3]byte{0, 128, 84}: "FRONTIER TECHNOLOGIES CORP.", + [3]byte{0, 128, 85}: "FERMILAB", + [3]byte{0, 128, 86}: "SPHINX ELEKTRONIK GMBH", + [3]byte{0, 128, 87}: "ADSOFT, LTD.", + [3]byte{0, 128, 88}: "PRINTER SYSTEMS CORPORATION", + [3]byte{0, 128, 89}: "STANLEY ELECTRIC CO., LTD", + [3]byte{0, 128, 90}: "TULIP COMPUTERS INTERNAT'L B.V", + [3]byte{0, 128, 91}: "CONDOR SYSTEMS, INC.", + [3]byte{0, 128, 92}: "AGILIS CORPORATION", + [3]byte{0, 128, 93}: "CANSTAR", + [3]byte{0, 128, 94}: "LSI LOGIC CORPORATION", + [3]byte{0, 128, 95}: "Hewlett-Packard Company", + [3]byte{0, 128, 96}: "NETWORK INTERFACE CORPORATION", + [3]byte{0, 128, 97}: "LITTON SYSTEMS, INC.", + [3]byte{0, 128, 98}: "INTERFACE CO.", + [3]byte{0, 128, 99}: "Hirschmann Automation and Control GmbH", + [3]byte{0, 128, 100}: "WYSE TECHNOLOGY LLC", + [3]byte{0, 128, 101}: "CYBERGRAPHIC SYSTEMS PTY LTD.", + [3]byte{0, 128, 102}: "ARCOM CONTROL SYSTEMS, LTD.", + [3]byte{0, 128, 103}: "SQUARE D COMPANY", + [3]byte{0, 128, 104}: "YAMATECH SCIENTIFIC LTD.", + [3]byte{0, 128, 105}: "COMPUTONE SYSTEMS", + [3]byte{0, 128, 106}: "ERI (EMPAC RESEARCH INC.)", + [3]byte{0, 128, 107}: "SCHMID TELECOMMUNICATION", + [3]byte{0, 128, 108}: "CEGELEC PROJECTS LTD", + [3]byte{0, 128, 109}: "CENTURY SYSTEMS CORP.", + [3]byte{0, 128, 110}: "NIPPON STEEL CORPORATION", + [3]byte{0, 128, 111}: "ONELAN LTD.", + [3]byte{0, 128, 112}: "COMPUTADORAS MICRON", + [3]byte{0, 128, 113}: "SAI TECHNOLOGY", + [3]byte{0, 128, 114}: "MICROPLEX SYSTEMS LTD.", + [3]byte{0, 128, 115}: "DWB ASSOCIATES", + [3]byte{0, 128, 116}: "FISHER CONTROLS", + [3]byte{0, 128, 117}: "PARSYTEC GMBH", + [3]byte{0, 128, 118}: "MCNC", + [3]byte{0, 128, 119}: "BROTHER INDUSTRIES, LTD.", + [3]byte{0, 128, 120}: "PRACTICAL PERIPHERALS, INC.", + [3]byte{0, 128, 121}: "MICROBUS DESIGNS LTD.", + [3]byte{0, 128, 122}: "AITECH SYSTEMS LTD.", + [3]byte{0, 128, 123}: "ARTEL COMMUNICATIONS CORP.", + [3]byte{0, 128, 124}: "FIBERCOM, INC.", + [3]byte{0, 128, 125}: "EQUINOX SYSTEMS INC.", + [3]byte{0, 128, 126}: "SOUTHERN PACIFIC LTD.", + [3]byte{0, 128, 127}: "DY-4 INCORPORATED", + [3]byte{0, 128, 128}: "DATAMEDIA CORPORATION", + [3]byte{0, 128, 129}: "KENDALL SQUARE RESEARCH CORP.", + [3]byte{0, 128, 130}: "PEP MODULAR COMPUTERS GMBH", + [3]byte{0, 128, 131}: "AMDAHL", + [3]byte{0, 128, 132}: "THE CLOUD INC.", + [3]byte{0, 128, 133}: "H-THREE SYSTEMS CORPORATION", + [3]byte{0, 128, 134}: "COMPUTER GENERATION INC.", + [3]byte{0, 128, 135}: "OKI ELECTRIC INDUSTRY CO., LTD", + [3]byte{0, 128, 136}: "VICTOR COMPANY OF JAPAN, LTD.", + [3]byte{0, 128, 137}: "TECNETICS (PTY) LTD.", + [3]byte{0, 128, 138}: "SUMMIT MICROSYSTEMS CORP.", + [3]byte{0, 128, 139}: "DACOLL LIMITED", + [3]byte{0, 128, 140}: "NetScout Systems, Inc.", + [3]byte{0, 128, 141}: "WESTCOAST TECHNOLOGY B.V.", + [3]byte{0, 128, 142}: "RADSTONE TECHNOLOGY", + [3]byte{0, 128, 143}: "C. ITOH ELECTRONICS, INC.", + [3]byte{0, 128, 144}: "MICROTEK INTERNATIONAL, INC.", + [3]byte{0, 128, 145}: "TOKYO ELECTRIC CO.,LTD", + [3]byte{0, 128, 146}: "Silex Technology, Inc.", + [3]byte{0, 128, 147}: "XYRON CORPORATION", + [3]byte{0, 128, 148}: "ALFA LAVAL AUTOMATION AB", + [3]byte{0, 128, 149}: "BASIC MERTON HANDELSGES.M.B.H.", + [3]byte{0, 128, 150}: "HUMAN DESIGNED SYSTEMS, INC.", + [3]byte{0, 128, 151}: "CENTRALP AUTOMATISMES", + [3]byte{0, 128, 152}: "TDK CORPORATION", + [3]byte{0, 128, 153}: "Eaton Industries GmbH", + [3]byte{0, 128, 154}: "NOVUS NETWORKS LTD", + [3]byte{0, 128, 155}: "JUSTSYSTEM CORPORATION", + [3]byte{0, 128, 156}: "LUXCOM, INC.", + [3]byte{0, 128, 157}: "Commscraft Ltd.", + [3]byte{0, 128, 158}: "DATUS GMBH", + [3]byte{0, 128, 159}: "ALCATEL BUSINESS SYSTEMS", + [3]byte{0, 128, 160}: "EDISA HEWLETT PACKARD S/A", + [3]byte{0, 128, 161}: "MICROTEST, INC.", + [3]byte{0, 128, 162}: "CREATIVE ELECTRONIC SYSTEMS", + [3]byte{0, 128, 163}: "Lantronix", + [3]byte{0, 128, 164}: "LIBERTY ELECTRONICS", + [3]byte{0, 128, 165}: "SPEED INTERNATIONAL", + [3]byte{0, 128, 166}: "REPUBLIC TECHNOLOGY, INC.", + [3]byte{0, 128, 167}: "Honeywell International Inc", + [3]byte{0, 128, 168}: "VITACOM CORPORATION", + [3]byte{0, 128, 169}: "CLEARPOINT RESEARCH", + [3]byte{0, 128, 170}: "MAXPEED", + [3]byte{0, 128, 171}: "DUKANE NETWORK INTEGRATION", + [3]byte{0, 128, 172}: "IMLOGIX, DIVISION OF GENESYS", + [3]byte{0, 128, 173}: "CNET TECHNOLOGY, INC.", + [3]byte{0, 128, 174}: "HUGHES NETWORK SYSTEMS", + [3]byte{0, 128, 175}: "ALLUMER CO., LTD.", + [3]byte{0, 128, 176}: "ADVANCED INFORMATION", + [3]byte{0, 128, 177}: "SOFTCOM A/S", + [3]byte{0, 128, 178}: "NETWORK EQUIPMENT TECHNOLOGIES", + [3]byte{0, 128, 179}: "AVAL DATA CORPORATION", + [3]byte{0, 128, 180}: "SOPHIA SYSTEMS", + [3]byte{0, 128, 181}: "UNITED NETWORKS INC.", + [3]byte{0, 128, 182}: "THEMIS COMPUTER", + [3]byte{0, 128, 183}: "STELLAR COMPUTER", + [3]byte{0, 128, 184}: "B.U.G. MORISEIKI, INCORPORATED", + [3]byte{0, 128, 185}: "ARCHE TECHNOLIGIES INC.", + [3]byte{0, 128, 186}: "SPECIALIX (ASIA) PTE, LTD", + [3]byte{0, 128, 187}: "HUGHES LAN SYSTEMS", + [3]byte{0, 128, 188}: "HITACHI ENGINEERING CO., LTD", + [3]byte{0, 128, 189}: "THE FURUKAWA ELECTRIC CO., LTD", + [3]byte{0, 128, 190}: "ARIES RESEARCH", + [3]byte{0, 128, 191}: "TAKAOKA ELECTRIC MFG. CO. LTD.", + [3]byte{0, 128, 192}: "PENRIL DATACOMM", + [3]byte{0, 128, 193}: "LANEX CORPORATION", + [3]byte{0, 128, 194}: "IEEE 802.1 COMMITTEE", + [3]byte{0, 128, 195}: "BICC INFORMATION SYSTEMS & SVC", + [3]byte{0, 128, 196}: "DOCUMENT TECHNOLOGIES, INC.", + [3]byte{0, 128, 197}: "NOVELLCO DE MEXICO", + [3]byte{0, 128, 198}: "NATIONAL DATACOMM CORPORATION", + [3]byte{0, 128, 199}: "XIRCOM", + [3]byte{0, 128, 200}: "D-LINK SYSTEMS, INC.", + [3]byte{0, 128, 201}: "ALBERTA MICROELECTRONIC CENTRE", + [3]byte{0, 128, 202}: "NETCOM RESEARCH INCORPORATED", + [3]byte{0, 128, 203}: "FALCO DATA PRODUCTS", + [3]byte{0, 128, 204}: "MICROWAVE BYPASS SYSTEMS", + [3]byte{0, 128, 205}: "MICRONICS COMPUTER, INC.", + [3]byte{0, 128, 206}: "BROADCAST TELEVISION SYSTEMS", + [3]byte{0, 128, 207}: "EMBEDDED PERFORMANCE INC.", + [3]byte{0, 128, 208}: "COMPUTER PERIPHERALS, INC.", + [3]byte{0, 128, 209}: "KIMTRON CORPORATION", + [3]byte{0, 128, 210}: "SHINNIHONDENKO CO., LTD.", + [3]byte{0, 128, 211}: "SHIVA CORP.", + [3]byte{0, 128, 212}: "CHASE RESEARCH LTD.", + [3]byte{0, 128, 213}: "CADRE TECHNOLOGIES", + [3]byte{0, 128, 214}: "NUVOTECH, INC.", + [3]byte{0, 128, 215}: "Fantum Engineering", + [3]byte{0, 128, 216}: "NETWORK PERIPHERALS INC.", + [3]byte{0, 128, 217}: "EMK Elektronik GmbH & Co. KG", + [3]byte{0, 128, 218}: "Bruel & Kjaer Sound & Vibration Measurement A/S", + [3]byte{0, 128, 219}: "GRAPHON CORPORATION", + [3]byte{0, 128, 220}: "PICKER INTERNATIONAL", + [3]byte{0, 128, 221}: "GMX INC/GIMIX", + [3]byte{0, 128, 222}: "GIPSI S.A.", + [3]byte{0, 128, 223}: "ADC CODENOLL TECHNOLOGY CORP.", + [3]byte{0, 128, 224}: "XTP SYSTEMS, INC.", + [3]byte{0, 128, 225}: "STMICROELECTRONICS", + [3]byte{0, 128, 226}: "T.D.I. CO., LTD.", + [3]byte{0, 128, 227}: "CORAL NETWORK CORPORATION", + [3]byte{0, 128, 228}: "NORTHWEST DIGITAL SYSTEMS, INC", + [3]byte{0, 128, 229}: "NetApp, Inc", + [3]byte{0, 128, 230}: "PEER NETWORKS, INC.", + [3]byte{0, 128, 231}: "LYNWOOD SCIENTIFIC DEV. LTD.", + [3]byte{0, 128, 232}: "CUMULUS CORPORATIION", + [3]byte{0, 128, 233}: "Madge Ltd.", + [3]byte{0, 128, 234}: "ADVA Optical Networking Ltd.", + [3]byte{0, 128, 235}: "COMPCONTROL B.V.", + [3]byte{0, 128, 236}: "SUPERCOMPUTING SOLUTIONS, INC.", + [3]byte{0, 128, 237}: "IQ TECHNOLOGIES, INC.", + [3]byte{0, 128, 238}: "THOMSON CSF", + [3]byte{0, 128, 239}: "RATIONAL", + [3]byte{0, 128, 240}: "Panasonic Communications Co., Ltd.", + [3]byte{0, 128, 241}: "OPUS SYSTEMS", + [3]byte{0, 128, 242}: "RAYCOM SYSTEMS INC", + [3]byte{0, 128, 243}: "SUN ELECTRONICS CORP.", + [3]byte{0, 128, 244}: "TELEMECANIQUE ELECTRIQUE", + [3]byte{0, 128, 245}: "Quantel Ltd", + [3]byte{0, 128, 246}: "SYNERGY MICROSYSTEMS", + [3]byte{0, 128, 247}: "ZENITH ELECTRONICS", + [3]byte{0, 128, 248}: "MIZAR, INC.", + [3]byte{0, 128, 249}: "HEURIKON CORPORATION", + [3]byte{0, 128, 250}: "RWT GMBH", + [3]byte{0, 128, 251}: "BVM LIMITED", + [3]byte{0, 128, 252}: "AVATAR CORPORATION", + [3]byte{0, 128, 253}: "EXSCEED CORPRATION", + [3]byte{0, 128, 254}: "AZURE TECHNOLOGIES, INC.", + [3]byte{0, 128, 255}: "SOC. DE TELEINFORMATIQUE RTC", + [3]byte{0, 134, 160}: "PRIVATE", + [3]byte{0, 136, 101}: "Apple", + [3]byte{0, 139, 67}: "RFTECH", + [3]byte{0, 140, 16}: "Black Box Corp.", + [3]byte{0, 140, 84}: "ADB Broadband Italia", + [3]byte{0, 140, 250}: "Inventec Corporation", + [3]byte{0, 141, 78}: "CJSC NII STT", + [3]byte{0, 141, 218}: "Link One Co., Ltd.", + [3]byte{0, 142, 242}: "NETGEAR INC.,", + [3]byte{0, 144, 0}: "DIAMOND MULTIMEDIA", + [3]byte{0, 144, 1}: "NISHIMU ELECTRONICS INDUSTRIES CO., LTD.", + [3]byte{0, 144, 2}: "ALLGON AB", + [3]byte{0, 144, 3}: "APLIO", + [3]byte{0, 144, 4}: "3COM EUROPE LTD.", + [3]byte{0, 144, 5}: "PROTECH SYSTEMS CO., LTD.", + [3]byte{0, 144, 6}: "HAMAMATSU PHOTONICS K.K.", + [3]byte{0, 144, 7}: "DOMEX TECHNOLOGY CORP.", + [3]byte{0, 144, 8}: "HanA Systems Inc.", + [3]byte{0, 144, 9}: "I Controls, Inc.", + [3]byte{0, 144, 10}: "PROTON ELECTRONIC INDUSTRIAL CO., LTD.", + [3]byte{0, 144, 11}: "LANNER ELECTRONICS, INC.", + [3]byte{0, 144, 12}: "CISCO SYSTEMS, INC.", + [3]byte{0, 144, 13}: "Overland Storage Inc.", + [3]byte{0, 144, 14}: "HANDLINK TECHNOLOGIES, INC.", + [3]byte{0, 144, 15}: "KAWASAKI HEAVY INDUSTRIES, LTD", + [3]byte{0, 144, 16}: "SIMULATION LABORATORIES, INC.", + [3]byte{0, 144, 17}: "WAVTrace, Inc.", + [3]byte{0, 144, 18}: "GLOBESPAN SEMICONDUCTOR, INC.", + [3]byte{0, 144, 19}: "SAMSAN CORP.", + [3]byte{0, 144, 20}: "ROTORK INSTRUMENTS, LTD.", + [3]byte{0, 144, 21}: "CENTIGRAM COMMUNICATIONS CORP.", + [3]byte{0, 144, 22}: "ZAC", + [3]byte{0, 144, 23}: "Zypcom, Inc", + [3]byte{0, 144, 24}: "ITO ELECTRIC INDUSTRY CO, LTD.", + [3]byte{0, 144, 25}: "HERMES ELECTRONICS CO., LTD.", + [3]byte{0, 144, 26}: "UNISPHERE SOLUTIONS", + [3]byte{0, 144, 27}: "DIGITAL CONTROLS", + [3]byte{0, 144, 28}: "mps Software Gmbh", + [3]byte{0, 144, 29}: "PEC (NZ) LTD.", + [3]byte{0, 144, 30}: "Selesta Ingegneria S.p.A.", + [3]byte{0, 144, 31}: "ADTEC PRODUCTIONS, INC.", + [3]byte{0, 144, 32}: "PHILIPS ANALYTICAL X-RAY B.V.", + [3]byte{0, 144, 33}: "CISCO SYSTEMS, INC.", + [3]byte{0, 144, 34}: "IVEX", + [3]byte{0, 144, 35}: "ZILOG INC.", + [3]byte{0, 144, 36}: "PIPELINKS, INC.", + [3]byte{0, 144, 37}: "BAE Systems Australia (Electronic Systems) Pty Ltd", + [3]byte{0, 144, 38}: "ADVANCED SWITCHING COMMUNICATIONS, INC.", + [3]byte{0, 144, 39}: "INTEL CORPORATION", + [3]byte{0, 144, 40}: "NIPPON SIGNAL CO., LTD.", + [3]byte{0, 144, 41}: "CRYPTO AG", + [3]byte{0, 144, 42}: "COMMUNICATION DEVICES, INC.", + [3]byte{0, 144, 43}: "CISCO SYSTEMS, INC.", + [3]byte{0, 144, 44}: "DATA & CONTROL EQUIPMENT LTD.", + [3]byte{0, 144, 45}: "DATA ELECTRONICS (AUST.) PTY, LTD.", + [3]byte{0, 144, 46}: "NAMCO LIMITED", + [3]byte{0, 144, 47}: "NETCORE SYSTEMS, INC.", + [3]byte{0, 144, 48}: "HONEYWELL-DATING", + [3]byte{0, 144, 49}: "MYSTICOM, LTD.", + [3]byte{0, 144, 50}: "PELCOMBE GROUP LTD.", + [3]byte{0, 144, 51}: "INNOVAPHONE AG", + [3]byte{0, 144, 52}: "IMAGIC, INC.", + [3]byte{0, 144, 53}: "ALPHA TELECOM, INC.", + [3]byte{0, 144, 54}: "ens, inc.", + [3]byte{0, 144, 55}: "ACUCOMM, INC.", + [3]byte{0, 144, 56}: "FOUNTAIN TECHNOLOGIES, INC.", + [3]byte{0, 144, 57}: "SHASTA NETWORKS", + [3]byte{0, 144, 58}: "NIHON MEDIA TOOL INC.", + [3]byte{0, 144, 59}: "TriEMS Research Lab, Inc.", + [3]byte{0, 144, 60}: "ATLANTIC NETWORK SYSTEMS", + [3]byte{0, 144, 61}: "BIOPAC SYSTEMS, INC.", + [3]byte{0, 144, 62}: "N.V. PHILIPS INDUSTRIAL ACTIVITIES", + [3]byte{0, 144, 63}: "AZTEC RADIOMEDIA", + [3]byte{0, 144, 64}: "Siemens Network Convergence LLC", + [3]byte{0, 144, 65}: "APPLIED DIGITAL ACCESS", + [3]byte{0, 144, 66}: "ECCS, Inc.", + [3]byte{0, 144, 67}: "Tattile SRL", + [3]byte{0, 144, 68}: "ASSURED DIGITAL, INC.", + [3]byte{0, 144, 69}: "Marconi Communications", + [3]byte{0, 144, 70}: "DEXDYNE, LTD.", + [3]byte{0, 144, 71}: "GIGA FAST E. LTD.", + [3]byte{0, 144, 72}: "ZEAL CORPORATION", + [3]byte{0, 144, 73}: "ENTRIDIA CORPORATION", + [3]byte{0, 144, 74}: "CONCUR SYSTEM TECHNOLOGIES", + [3]byte{0, 144, 75}: "GemTek Technology Co., Ltd.", + [3]byte{0, 144, 76}: "EPIGRAM, INC.", + [3]byte{0, 144, 77}: "SPEC S.A.", + [3]byte{0, 144, 78}: "DELEM BV", + [3]byte{0, 144, 79}: "ABB POWER T&D COMPANY, INC.", + [3]byte{0, 144, 80}: "TELESTE OY", + [3]byte{0, 144, 81}: "ULTIMATE TECHNOLOGY CORP.", + [3]byte{0, 144, 82}: "SELCOM ELETTRONICA S.R.L.", + [3]byte{0, 144, 83}: "DAEWOO ELECTRONICS CO., LTD.", + [3]byte{0, 144, 84}: "INNOVATIVE SEMICONDUCTORS, INC", + [3]byte{0, 144, 85}: "PARKER HANNIFIN CORPORATION COMPUMOTOR DIVISION", + [3]byte{0, 144, 86}: "TELESTREAM, INC.", + [3]byte{0, 144, 87}: "AANetcom, Inc.", + [3]byte{0, 144, 88}: "Ultra Electronics Ltd., Command and Control Systems", + [3]byte{0, 144, 89}: "TELECOM DEVICE K.K.", + [3]byte{0, 144, 90}: "DEARBORN GROUP, INC.", + [3]byte{0, 144, 91}: "RAYMOND AND LAE ENGINEERING", + [3]byte{0, 144, 92}: "EDMI", + [3]byte{0, 144, 93}: "NETCOM SICHERHEITSTECHNIK GmbH", + [3]byte{0, 144, 94}: "RAULAND-BORG CORPORATION", + [3]byte{0, 144, 95}: "CISCO SYSTEMS, INC.", + [3]byte{0, 144, 96}: "SYSTEM CREATE CORP.", + [3]byte{0, 144, 97}: "PACIFIC RESEARCH & ENGINEERING CORPORATION", + [3]byte{0, 144, 98}: "ICP VORTEX COMPUTERSYSTEME GmbH", + [3]byte{0, 144, 99}: "COHERENT COMMUNICATIONS SYSTEMS CORPORATION", + [3]byte{0, 144, 100}: "Thomson Inc.", + [3]byte{0, 144, 101}: "FINISAR CORPORATION", + [3]byte{0, 144, 102}: "Troika Networks, Inc.", + [3]byte{0, 144, 103}: "WalkAbout Computers, Inc.", + [3]byte{0, 144, 104}: "DVT CORP.", + [3]byte{0, 144, 105}: "JUNIPER NETWORKS, INC.", + [3]byte{0, 144, 106}: "TURNSTONE SYSTEMS, INC.", + [3]byte{0, 144, 107}: "APPLIED RESOURCES, INC.", + [3]byte{0, 144, 108}: "Sartorius Hamburg GmbH", + [3]byte{0, 144, 109}: "CISCO SYSTEMS, INC.", + [3]byte{0, 144, 110}: "PRAXON, INC.", + [3]byte{0, 144, 111}: "CISCO SYSTEMS, INC.", + [3]byte{0, 144, 112}: "NEO NETWORKS, INC.", + [3]byte{0, 144, 113}: "Applied Innovation Inc.", + [3]byte{0, 144, 114}: "SIMRAD AS", + [3]byte{0, 144, 115}: "GAIO TECHNOLOGY", + [3]byte{0, 144, 116}: "ARGON NETWORKS, INC.", + [3]byte{0, 144, 117}: "NEC DO BRASIL S.A.", + [3]byte{0, 144, 118}: "FMT AIRCRAFT GATE SUPPORT SYSTEMS AB", + [3]byte{0, 144, 119}: "ADVANCED FIBRE COMMUNICATIONS", + [3]byte{0, 144, 120}: "MER TELEMANAGEMENT SOLUTIONS, LTD.", + [3]byte{0, 144, 121}: "ClearOne, Inc.", + [3]byte{0, 144, 122}: "Spectralink, Inc", + [3]byte{0, 144, 123}: "E-TECH, INC.", + [3]byte{0, 144, 124}: "DIGITALCAST, INC.", + [3]byte{0, 144, 125}: "Lake Communications", + [3]byte{0, 144, 126}: "VETRONIX CORP.", + [3]byte{0, 144, 127}: "WatchGuard Technologies, Inc.", + [3]byte{0, 144, 128}: "NOT LIMITED, INC.", + [3]byte{0, 144, 129}: "ALOHA NETWORKS, INC.", + [3]byte{0, 144, 130}: "FORCE INSTITUTE", + [3]byte{0, 144, 131}: "TURBO COMMUNICATION, INC.", + [3]byte{0, 144, 132}: "ATECH SYSTEM", + [3]byte{0, 144, 133}: "GOLDEN ENTERPRISES, INC.", + [3]byte{0, 144, 134}: "CISCO SYSTEMS, INC.", + [3]byte{0, 144, 135}: "ITIS", + [3]byte{0, 144, 136}: "BAXALL SECURITY LTD.", + [3]byte{0, 144, 137}: "SOFTCOM MICROSYSTEMS, INC.", + [3]byte{0, 144, 138}: "BAYLY COMMUNICATIONS, INC.", + [3]byte{0, 144, 139}: "Tattile SRL", + [3]byte{0, 144, 140}: "ETREND ELECTRONICS, INC.", + [3]byte{0, 144, 141}: "VICKERS ELECTRONICS SYSTEMS", + [3]byte{0, 144, 142}: "Nortel Networks Broadband Access", + [3]byte{0, 144, 143}: "AUDIO CODES LTD.", + [3]byte{0, 144, 144}: "I-BUS", + [3]byte{0, 144, 145}: "DigitalScape, Inc.", + [3]byte{0, 144, 146}: "CISCO SYSTEMS, INC.", + [3]byte{0, 144, 147}: "NANAO CORPORATION", + [3]byte{0, 144, 148}: "OSPREY TECHNOLOGIES, INC.", + [3]byte{0, 144, 149}: "UNIVERSAL AVIONICS", + [3]byte{0, 144, 150}: "ASKEY COMPUTER CORP.", + [3]byte{0, 144, 151}: "Sycamore Networks", + [3]byte{0, 144, 152}: "SBC DESIGNS, INC.", + [3]byte{0, 144, 153}: "ALLIED TELESIS, K.K.", + [3]byte{0, 144, 154}: "ONE WORLD SYSTEMS, INC.", + [3]byte{0, 144, 155}: "MARKEM-IMAJE", + [3]byte{0, 144, 156}: "ARRIS Group, Inc.", + [3]byte{0, 144, 157}: "NovaTech Process Solutions, LLC", + [3]byte{0, 144, 158}: "Critical IO, LLC", + [3]byte{0, 144, 159}: "DIGI-DATA CORPORATION", + [3]byte{0, 144, 160}: "8X8 INC.", + [3]byte{0, 144, 161}: "Flying Pig Systems/High End Systems Inc.", + [3]byte{0, 144, 162}: "CYBERTAN TECHNOLOGY, INC.", + [3]byte{0, 144, 163}: "Corecess Inc.", + [3]byte{0, 144, 164}: "ALTIGA NETWORKS", + [3]byte{0, 144, 165}: "SPECTRA LOGIC", + [3]byte{0, 144, 166}: "CISCO SYSTEMS, INC.", + [3]byte{0, 144, 167}: "CLIENTEC CORPORATION", + [3]byte{0, 144, 168}: "NineTiles Networks, Ltd.", + [3]byte{0, 144, 169}: "WESTERN DIGITAL", + [3]byte{0, 144, 170}: "INDIGO ACTIVE VISION SYSTEMS LIMITED", + [3]byte{0, 144, 171}: "CISCO SYSTEMS, INC.", + [3]byte{0, 144, 172}: "OPTIVISION, INC.", + [3]byte{0, 144, 173}: "ASPECT ELECTRONICS, INC.", + [3]byte{0, 144, 174}: "ITALTEL S.p.A.", + [3]byte{0, 144, 175}: "J. MORITA MFG. CORP.", + [3]byte{0, 144, 176}: "VADEM", + [3]byte{0, 144, 177}: "CISCO SYSTEMS, INC.", + [3]byte{0, 144, 178}: "AVICI SYSTEMS INC.", + [3]byte{0, 144, 179}: "AGRANAT SYSTEMS", + [3]byte{0, 144, 180}: "WILLOWBROOK TECHNOLOGIES", + [3]byte{0, 144, 181}: "NIKON CORPORATION", + [3]byte{0, 144, 182}: "FIBEX SYSTEMS", + [3]byte{0, 144, 183}: "DIGITAL LIGHTWAVE, INC.", + [3]byte{0, 144, 184}: "ROHDE & SCHWARZ GMBH & CO. KG", + [3]byte{0, 144, 185}: "BERAN INSTRUMENTS LTD.", + [3]byte{0, 144, 186}: "VALID NETWORKS, INC.", + [3]byte{0, 144, 187}: "TAINET COMMUNICATION SYSTEM Corp.", + [3]byte{0, 144, 188}: "TELEMANN CO., LTD.", + [3]byte{0, 144, 189}: "OMNIA COMMUNICATIONS, INC.", + [3]byte{0, 144, 190}: "IBC/INTEGRATED BUSINESS COMPUTERS", + [3]byte{0, 144, 191}: "CISCO SYSTEMS, INC.", + [3]byte{0, 144, 192}: "K.J. LAW ENGINEERS, INC.", + [3]byte{0, 144, 193}: "Peco II, Inc.", + [3]byte{0, 144, 194}: "JK microsystems, Inc.", + [3]byte{0, 144, 195}: "TOPIC SEMICONDUCTOR CORP.", + [3]byte{0, 144, 196}: "JAVELIN SYSTEMS, INC.", + [3]byte{0, 144, 197}: "INTERNET MAGIC, INC.", + [3]byte{0, 144, 198}: "OPTIM SYSTEMS, INC.", + [3]byte{0, 144, 199}: "ICOM INC.", + [3]byte{0, 144, 200}: "WAVERIDER COMMUNICATIONS (CANADA) INC.", + [3]byte{0, 144, 201}: "DPAC Technologies", + [3]byte{0, 144, 202}: "ACCORD VIDEO TELECOMMUNICATIONS, LTD.", + [3]byte{0, 144, 203}: "Wireless OnLine, Inc.", + [3]byte{0, 144, 204}: "Planex Communications", + [3]byte{0, 144, 205}: "ENT-EMPRESA NACIONAL DE TELECOMMUNICACOES, S.A.", + [3]byte{0, 144, 206}: "TETRA GmbH", + [3]byte{0, 144, 207}: "NORTEL", + [3]byte{0, 144, 208}: "Thomson Telecom Belgium", + [3]byte{0, 144, 209}: "LEICHU ENTERPRISE CO., LTD.", + [3]byte{0, 144, 210}: "ARTEL VIDEO SYSTEMS", + [3]byte{0, 144, 211}: "GIESECKE & DEVRIENT GmbH", + [3]byte{0, 144, 212}: "BindView Development Corp.", + [3]byte{0, 144, 213}: "EUPHONIX, INC.", + [3]byte{0, 144, 214}: "CRYSTAL GROUP", + [3]byte{0, 144, 215}: "NetBoost Corp.", + [3]byte{0, 144, 216}: "WHITECROSS SYSTEMS", + [3]byte{0, 144, 217}: "CISCO SYSTEMS, INC.", + [3]byte{0, 144, 218}: "DYNARC, INC.", + [3]byte{0, 144, 219}: "NEXT LEVEL COMMUNICATIONS", + [3]byte{0, 144, 220}: "TECO INFORMATION SYSTEMS", + [3]byte{0, 144, 221}: "MIHARU COMMUNICATIONS Inc", + [3]byte{0, 144, 222}: "CARDKEY SYSTEMS, INC.", + [3]byte{0, 144, 223}: "MITSUBISHI CHEMICAL AMERICA, INC.", + [3]byte{0, 144, 224}: "SYSTRAN CORP.", + [3]byte{0, 144, 225}: "TELENA S.P.A.", + [3]byte{0, 144, 226}: "DISTRIBUTED PROCESSING TECHNOLOGY", + [3]byte{0, 144, 227}: "AVEX ELECTRONICS INC.", + [3]byte{0, 144, 228}: "NEC AMERICA, INC.", + [3]byte{0, 144, 229}: "TEKNEMA, INC.", + [3]byte{0, 144, 230}: "ALi Corporation", + [3]byte{0, 144, 231}: "HORSCH ELEKTRONIK AG", + [3]byte{0, 144, 232}: "MOXA TECHNOLOGIES CORP., LTD.", + [3]byte{0, 144, 233}: "JANZ COMPUTER AG", + [3]byte{0, 144, 234}: "ALPHA TECHNOLOGIES, INC.", + [3]byte{0, 144, 235}: "SENTRY TELECOM SYSTEMS", + [3]byte{0, 144, 236}: "PYRESCOM", + [3]byte{0, 144, 237}: "CENTRAL SYSTEM RESEARCH CO., LTD.", + [3]byte{0, 144, 238}: "PERSONAL COMMUNICATIONS TECHNOLOGIES", + [3]byte{0, 144, 239}: "INTEGRIX, INC.", + [3]byte{0, 144, 240}: "Harmonic Video Systems Ltd.", + [3]byte{0, 144, 241}: "DOT HILL SYSTEMS CORPORATION", + [3]byte{0, 144, 242}: "CISCO SYSTEMS, INC.", + [3]byte{0, 144, 243}: "ASPECT COMMUNICATIONS", + [3]byte{0, 144, 244}: "LIGHTNING INSTRUMENTATION", + [3]byte{0, 144, 245}: "CLEVO CO.", + [3]byte{0, 144, 246}: "ESCALATE NETWORKS, INC.", + [3]byte{0, 144, 247}: "NBASE COMMUNICATIONS LTD.", + [3]byte{0, 144, 248}: "MEDIATRIX TELECOM", + [3]byte{0, 144, 249}: "LEITCH", + [3]byte{0, 144, 250}: "Emulex Corporation", + [3]byte{0, 144, 251}: "PORTWELL, INC.", + [3]byte{0, 144, 252}: "NETWORK COMPUTING DEVICES", + [3]byte{0, 144, 253}: "CopperCom, Inc.", + [3]byte{0, 144, 254}: "ELECOM CO., LTD. (LANEED DIV.)", + [3]byte{0, 144, 255}: "TELLUS TECHNOLOGY INC.", + [3]byte{0, 145, 214}: "Crystal Group, Inc.", + [3]byte{0, 145, 250}: "Synapse Product Development", + [3]byte{0, 146, 250}: "SHENZHEN WISKY TECHNOLOGY CO.,LTD", + [3]byte{0, 147, 99}: "Uni-Link Technology Co., Ltd.", + [3]byte{0, 149, 105}: "LSD Science and Technology Co.,Ltd.", + [3]byte{0, 151, 255}: "Heimann Sensor GmbH", + [3]byte{0, 156, 2}: "Hewlett-Packard Company", + [3]byte{0, 157, 142}: "CARDIAC RECORDERS, INC.", + [3]byte{0, 158, 200}: "Beijing Xiaomi Electronic Products Co., Ltd.", + [3]byte{0, 160, 0}: "CENTILLION NETWORKS, INC.", + [3]byte{0, 160, 1}: "DRS Signal Solutions", + [3]byte{0, 160, 2}: "LEEDS & NORTHRUP AUSTRALIA PTY LTD", + [3]byte{0, 160, 3}: "Siemens Switzerland Ltd., I B T HVP", + [3]byte{0, 160, 4}: "NETPOWER, INC.", + [3]byte{0, 160, 5}: "DANIEL INSTRUMENTS, LTD.", + [3]byte{0, 160, 6}: "IMAGE DATA PROCESSING SYSTEM GROUP", + [3]byte{0, 160, 7}: "APEXX TECHNOLOGY, INC.", + [3]byte{0, 160, 8}: "NETCORP", + [3]byte{0, 160, 9}: "WHITETREE NETWORK", + [3]byte{0, 160, 10}: "Airspan", + [3]byte{0, 160, 11}: "COMPUTEX CO., LTD.", + [3]byte{0, 160, 12}: "KINGMAX TECHNOLOGY, INC.", + [3]byte{0, 160, 13}: "THE PANDA PROJECT", + [3]byte{0, 160, 14}: "VISUAL NETWORKS, INC.", + [3]byte{0, 160, 15}: "Broadband Technologies", + [3]byte{0, 160, 16}: "SYSLOGIC DATENTECHNIK AG", + [3]byte{0, 160, 17}: "MUTOH INDUSTRIES LTD.", + [3]byte{0, 160, 18}: "Telco Systems, Inc.", + [3]byte{0, 160, 19}: "TELTREND LTD.", + [3]byte{0, 160, 20}: "CSIR", + [3]byte{0, 160, 21}: "WYLE", + [3]byte{0, 160, 22}: "MICROPOLIS CORP.", + [3]byte{0, 160, 23}: "J B M CORPORATION", + [3]byte{0, 160, 24}: "CREATIVE CONTROLLERS, INC.", + [3]byte{0, 160, 25}: "NEBULA CONSULTANTS, INC.", + [3]byte{0, 160, 26}: "BINAR ELEKTRONIK AB", + [3]byte{0, 160, 27}: "PREMISYS COMMUNICATIONS, INC.", + [3]byte{0, 160, 28}: "NASCENT NETWORKS CORPORATION", + [3]byte{0, 160, 29}: "SIXNET", + [3]byte{0, 160, 30}: "EST CORPORATION", + [3]byte{0, 160, 31}: "TRICORD SYSTEMS, INC.", + [3]byte{0, 160, 32}: "CITICORP/TTI", + [3]byte{0, 160, 33}: "General Dynamics", + [3]byte{0, 160, 34}: "CENTRE FOR DEVELOPMENT OF ADVANCED COMPUTING", + [3]byte{0, 160, 35}: "APPLIED CREATIVE TECHNOLOGY, INC.", + [3]byte{0, 160, 36}: "3COM CORPORATION", + [3]byte{0, 160, 37}: "REDCOM LABS INC.", + [3]byte{0, 160, 38}: "TELDAT, S.A.", + [3]byte{0, 160, 39}: "FIREPOWER SYSTEMS, INC.", + [3]byte{0, 160, 40}: "CONNER PERIPHERALS", + [3]byte{0, 160, 41}: "COULTER CORPORATION", + [3]byte{0, 160, 42}: "TRANCELL SYSTEMS", + [3]byte{0, 160, 43}: "TRANSITIONS RESEARCH CORP.", + [3]byte{0, 160, 44}: "interWAVE Communications", + [3]byte{0, 160, 45}: "1394 Trade Association", + [3]byte{0, 160, 46}: "BRAND COMMUNICATIONS, LTD.", + [3]byte{0, 160, 47}: "PIRELLI CAVI", + [3]byte{0, 160, 48}: "CAPTOR NV/SA", + [3]byte{0, 160, 49}: "HAZELTINE CORPORATION, MS 1-17", + [3]byte{0, 160, 50}: "GES SINGAPORE PTE. LTD.", + [3]byte{0, 160, 51}: "imc MeBsysteme GmbH", + [3]byte{0, 160, 52}: "AXEL", + [3]byte{0, 160, 53}: "CYLINK CORPORATION", + [3]byte{0, 160, 54}: "APPLIED NETWORK TECHNOLOGY", + [3]byte{0, 160, 55}: "Mindray DS USA, Inc.", + [3]byte{0, 160, 56}: "EMAIL ELECTRONICS", + [3]byte{0, 160, 57}: "ROSS TECHNOLOGY, INC.", + [3]byte{0, 160, 58}: "KUBOTEK CORPORATION", + [3]byte{0, 160, 59}: "TOSHIN ELECTRIC CO., LTD.", + [3]byte{0, 160, 60}: "EG&G NUCLEAR INSTRUMENTS", + [3]byte{0, 160, 61}: "OPTO-22", + [3]byte{0, 160, 62}: "ATM FORUM", + [3]byte{0, 160, 63}: "COMPUTER SOCIETY MICROPROCESSOR & MICROPROCESSOR STANDARDS C", + [3]byte{0, 160, 64}: "Apple", + [3]byte{0, 160, 65}: "INFICON", + [3]byte{0, 160, 66}: "SPUR PRODUCTS CORP.", + [3]byte{0, 160, 67}: "AMERICAN TECHNOLOGY LABS, INC.", + [3]byte{0, 160, 68}: "NTT IT CO., LTD.", + [3]byte{0, 160, 69}: "PHOENIX CONTACT GMBH & CO.", + [3]byte{0, 160, 70}: "SCITEX CORP. LTD.", + [3]byte{0, 160, 71}: "INTEGRATED FITNESS CORP.", + [3]byte{0, 160, 72}: "QUESTECH, LTD.", + [3]byte{0, 160, 73}: "DIGITECH INDUSTRIES, INC.", + [3]byte{0, 160, 74}: "NISSHIN ELECTRIC CO., LTD.", + [3]byte{0, 160, 75}: "TFL LAN INC.", + [3]byte{0, 160, 76}: "INNOVATIVE SYSTEMS & TECHNOLOGIES, INC.", + [3]byte{0, 160, 77}: "EDA INSTRUMENTS, INC.", + [3]byte{0, 160, 78}: "VOELKER TECHNOLOGIES, INC.", + [3]byte{0, 160, 79}: "AMERITEC CORP.", + [3]byte{0, 160, 80}: "CYPRESS SEMICONDUCTOR", + [3]byte{0, 160, 81}: "ANGIA COMMUNICATIONS. INC.", + [3]byte{0, 160, 82}: "STANILITE ELECTRONICS PTY. LTD", + [3]byte{0, 160, 83}: "COMPACT DEVICES, INC.", + [3]byte{0, 160, 84}: "PRIVATE", + [3]byte{0, 160, 85}: "Data Device Corporation", + [3]byte{0, 160, 86}: "MICROPROSS", + [3]byte{0, 160, 87}: "LANCOM Systems GmbH", + [3]byte{0, 160, 88}: "GLORY, LTD.", + [3]byte{0, 160, 89}: "HAMILTON HALLMARK", + [3]byte{0, 160, 90}: "KOFAX IMAGE PRODUCTS", + [3]byte{0, 160, 91}: "MARQUIP, INC.", + [3]byte{0, 160, 92}: "INVENTORY CONVERSION, INC./", + [3]byte{0, 160, 93}: "CS COMPUTER SYSTEME GmbH", + [3]byte{0, 160, 94}: "MYRIAD LOGIC INC.", + [3]byte{0, 160, 95}: "BTG Electronics Design BV", + [3]byte{0, 160, 96}: "ACER PERIPHERALS, INC.", + [3]byte{0, 160, 97}: "PURITAN BENNETT", + [3]byte{0, 160, 98}: "AES PRODATA", + [3]byte{0, 160, 99}: "JRL SYSTEMS, INC.", + [3]byte{0, 160, 100}: "KVB/ANALECT", + [3]byte{0, 160, 101}: "Symantec Corporation", + [3]byte{0, 160, 102}: "ISA CO., LTD.", + [3]byte{0, 160, 103}: "NETWORK SERVICES GROUP", + [3]byte{0, 160, 104}: "BHP LIMITED", + [3]byte{0, 160, 105}: "Symmetricom, Inc.", + [3]byte{0, 160, 106}: "Verilink Corporation", + [3]byte{0, 160, 107}: "DMS DORSCH MIKROSYSTEM GMBH", + [3]byte{0, 160, 108}: "SHINDENGEN ELECTRIC MFG. CO., LTD.", + [3]byte{0, 160, 109}: "MANNESMANN TALLY CORPORATION", + [3]byte{0, 160, 110}: "AUSTRON, INC.", + [3]byte{0, 160, 111}: "THE APPCON GROUP, INC.", + [3]byte{0, 160, 112}: "COASTCOM", + [3]byte{0, 160, 113}: "VIDEO LOTTERY TECHNOLOGIES,INC", + [3]byte{0, 160, 114}: "OVATION SYSTEMS LTD.", + [3]byte{0, 160, 115}: "COM21, INC.", + [3]byte{0, 160, 116}: "PERCEPTION TECHNOLOGY", + [3]byte{0, 160, 117}: "MICRON TECHNOLOGY, INC.", + [3]byte{0, 160, 118}: "CARDWARE LAB, INC.", + [3]byte{0, 160, 119}: "FUJITSU NEXION, INC.", + [3]byte{0, 160, 120}: "Marconi Communications", + [3]byte{0, 160, 121}: "ALPS ELECTRIC (USA), INC.", + [3]byte{0, 160, 122}: "ADVANCED PERIPHERALS TECHNOLOGIES, INC.", + [3]byte{0, 160, 123}: "DAWN COMPUTER INCORPORATION", + [3]byte{0, 160, 124}: "TONYANG NYLON CO., LTD.", + [3]byte{0, 160, 125}: "SEEQ TECHNOLOGY, INC.", + [3]byte{0, 160, 126}: "AVID TECHNOLOGY, INC.", + [3]byte{0, 160, 127}: "GSM-SYNTEL, LTD.", + [3]byte{0, 160, 128}: "Tattile SRL", + [3]byte{0, 160, 129}: "ALCATEL DATA NETWORKS", + [3]byte{0, 160, 130}: "NKT ELEKTRONIK A/S", + [3]byte{0, 160, 131}: "ASIMMPHONY TURKEY", + [3]byte{0, 160, 132}: "Dataplex Pty Ltd", + [3]byte{0, 160, 133}: "PRIVATE", + [3]byte{0, 160, 134}: "AMBER WAVE SYSTEMS, INC.", + [3]byte{0, 160, 135}: "Microsemi Corporation", + [3]byte{0, 160, 136}: "ESSENTIAL COMMUNICATIONS", + [3]byte{0, 160, 137}: "XPOINT TECHNOLOGIES, INC.", + [3]byte{0, 160, 138}: "BROOKTROUT TECHNOLOGY, INC.", + [3]byte{0, 160, 139}: "ASTON ELECTRONIC DESIGNS LTD.", + [3]byte{0, 160, 140}: "MultiMedia LANs, Inc.", + [3]byte{0, 160, 141}: "JACOMO CORPORATION", + [3]byte{0, 160, 142}: "Check Point Software Technologies", + [3]byte{0, 160, 143}: "DESKNET SYSTEMS, INC.", + [3]byte{0, 160, 144}: "TimeStep Corporation", + [3]byte{0, 160, 145}: "APPLICOM INTERNATIONAL", + [3]byte{0, 160, 146}: "H. BOLLMANN MANUFACTURERS, LTD", + [3]byte{0, 160, 147}: "B/E AEROSPACE, Inc.", + [3]byte{0, 160, 148}: "COMSAT CORPORATION", + [3]byte{0, 160, 149}: "ACACIA NETWORKS, INC.", + [3]byte{0, 160, 150}: "MITSUMI ELECTRIC CO., LTD.", + [3]byte{0, 160, 151}: "JC INFORMATION SYSTEMS", + [3]byte{0, 160, 152}: "NetApp", + [3]byte{0, 160, 153}: "K-NET LTD.", + [3]byte{0, 160, 154}: "NIHON KOHDEN AMERICA", + [3]byte{0, 160, 155}: "QPSX COMMUNICATIONS, LTD.", + [3]byte{0, 160, 156}: "Xyplex, Inc.", + [3]byte{0, 160, 157}: "JOHNATHON FREEMAN TECHNOLOGIES", + [3]byte{0, 160, 158}: "ICTV", + [3]byte{0, 160, 159}: "COMMVISION CORP.", + [3]byte{0, 160, 160}: "COMPACT DATA, LTD.", + [3]byte{0, 160, 161}: "EPIC DATA INC.", + [3]byte{0, 160, 162}: "DIGICOM S.P.A.", + [3]byte{0, 160, 163}: "RELIABLE POWER METERS", + [3]byte{0, 160, 164}: "MICROS SYSTEMS, INC.", + [3]byte{0, 160, 165}: "TEKNOR MICROSYSTEME, INC.", + [3]byte{0, 160, 166}: "M.I. SYSTEMS, K.K.", + [3]byte{0, 160, 167}: "VORAX CORPORATION", + [3]byte{0, 160, 168}: "RENEX CORPORATION", + [3]byte{0, 160, 169}: "NAVTEL COMMUNICATIONS INC.", + [3]byte{0, 160, 170}: "SPACELABS MEDICAL", + [3]byte{0, 160, 171}: "NETCS INFORMATIONSTECHNIK GMBH", + [3]byte{0, 160, 172}: "GILAT SATELLITE NETWORKS, LTD.", + [3]byte{0, 160, 173}: "MARCONI SPA", + [3]byte{0, 160, 174}: "NUCOM SYSTEMS, INC.", + [3]byte{0, 160, 175}: "WMS INDUSTRIES", + [3]byte{0, 160, 176}: "I-O DATA DEVICE, INC.", + [3]byte{0, 160, 177}: "FIRST VIRTUAL CORPORATION", + [3]byte{0, 160, 178}: "SHIMA SEIKI", + [3]byte{0, 160, 179}: "ZYKRONIX", + [3]byte{0, 160, 180}: "TEXAS MICROSYSTEMS, INC.", + [3]byte{0, 160, 181}: "3H TECHNOLOGY", + [3]byte{0, 160, 182}: "SANRITZ AUTOMATION CO., LTD.", + [3]byte{0, 160, 183}: "CORDANT, INC.", + [3]byte{0, 160, 184}: "SYMBIOS LOGIC INC.", + [3]byte{0, 160, 185}: "EAGLE TECHNOLOGY, INC.", + [3]byte{0, 160, 186}: "PATTON ELECTRONICS CO.", + [3]byte{0, 160, 187}: "HILAN GMBH", + [3]byte{0, 160, 188}: "VIASAT, INCORPORATED", + [3]byte{0, 160, 189}: "I-TECH CORP.", + [3]byte{0, 160, 190}: "INTEGRATED CIRCUIT SYSTEMS, INC. COMMUNICATIONS GROUP", + [3]byte{0, 160, 191}: "WIRELESS DATA GROUP MOTOROLA", + [3]byte{0, 160, 192}: "DIGITAL LINK CORP.", + [3]byte{0, 160, 193}: "ORTIVUS MEDICAL AB", + [3]byte{0, 160, 194}: "R.A. SYSTEMS CO., LTD.", + [3]byte{0, 160, 195}: "UNICOMPUTER GMBH", + [3]byte{0, 160, 196}: "CRISTIE ELECTRONICS LTD.", + [3]byte{0, 160, 197}: "ZYXEL COMMUNICATION", + [3]byte{0, 160, 198}: "QUALCOMM INCORPORATED", + [3]byte{0, 160, 199}: "TADIRAN TELECOMMUNICATIONS", + [3]byte{0, 160, 200}: "ADTRAN INC.", + [3]byte{0, 160, 201}: "INTEL CORPORATION - HF1-06", + [3]byte{0, 160, 202}: "FUJITSU DENSO LTD.", + [3]byte{0, 160, 203}: "ARK TELECOMMUNICATIONS, INC.", + [3]byte{0, 160, 204}: "LITE-ON COMMUNICATIONS, INC.", + [3]byte{0, 160, 205}: "DR. JOHANNES HEIDENHAIN GmbH", + [3]byte{0, 160, 206}: "Ecessa", + [3]byte{0, 160, 207}: "SOTAS, INC.", + [3]byte{0, 160, 208}: "TEN X TECHNOLOGY, INC.", + [3]byte{0, 160, 209}: "INVENTEC CORPORATION", + [3]byte{0, 160, 210}: "ALLIED TELESIS INTERNATIONAL CORPORATION", + [3]byte{0, 160, 211}: "INSTEM COMPUTER SYSTEMS, LTD.", + [3]byte{0, 160, 212}: "RADIOLAN, INC.", + [3]byte{0, 160, 213}: "SIERRA WIRELESS INC.", + [3]byte{0, 160, 214}: "SBE, INC.", + [3]byte{0, 160, 215}: "KASTEN CHASE APPLIED RESEARCH", + [3]byte{0, 160, 216}: "SPECTRA - TEK", + [3]byte{0, 160, 217}: "CONVEX COMPUTER CORPORATION", + [3]byte{0, 160, 218}: "INTEGRATED SYSTEMS Technology, Inc.", + [3]byte{0, 160, 219}: "FISHER & PAYKEL PRODUCTION", + [3]byte{0, 160, 220}: "O.N. ELECTRONIC CO., LTD.", + [3]byte{0, 160, 221}: "AZONIX CORPORATION", + [3]byte{0, 160, 222}: "YAMAHA CORPORATION", + [3]byte{0, 160, 223}: "STS TECHNOLOGIES, INC.", + [3]byte{0, 160, 224}: "TENNYSON TECHNOLOGIES PTY LTD", + [3]byte{0, 160, 225}: "WESTPORT RESEARCH ASSOCIATES, INC.", + [3]byte{0, 160, 226}: "Keisokugiken Corporation", + [3]byte{0, 160, 227}: "XKL SYSTEMS CORP.", + [3]byte{0, 160, 228}: "OPTIQUEST", + [3]byte{0, 160, 229}: "NHC COMMUNICATIONS", + [3]byte{0, 160, 230}: "DIALOGIC CORPORATION", + [3]byte{0, 160, 231}: "CENTRAL DATA CORPORATION", + [3]byte{0, 160, 232}: "REUTERS HOLDINGS PLC", + [3]byte{0, 160, 233}: "ELECTRONIC RETAILING SYSTEMS INTERNATIONAL", + [3]byte{0, 160, 234}: "ETHERCOM CORP.", + [3]byte{0, 160, 235}: "Encore Networks, Inc.", + [3]byte{0, 160, 236}: "TRANSMITTON LTD.", + [3]byte{0, 160, 237}: "Brooks Automation, Inc.", + [3]byte{0, 160, 238}: "NASHOBA NETWORKS", + [3]byte{0, 160, 239}: "LUCIDATA LTD.", + [3]byte{0, 160, 240}: "TORONTO MICROELECTRONICS INC.", + [3]byte{0, 160, 241}: "MTI", + [3]byte{0, 160, 242}: "INFOTEK COMMUNICATIONS, INC.", + [3]byte{0, 160, 243}: "STAUBLI", + [3]byte{0, 160, 244}: "GE", + [3]byte{0, 160, 245}: "RADGUARD LTD.", + [3]byte{0, 160, 246}: "AutoGas Systems Inc.", + [3]byte{0, 160, 247}: "V.I COMPUTER CORP.", + [3]byte{0, 160, 248}: "SYMBOL TECHNOLOGIES, INC.", + [3]byte{0, 160, 249}: "BINTEC COMMUNICATIONS GMBH", + [3]byte{0, 160, 250}: "Marconi Communication GmbH", + [3]byte{0, 160, 251}: "TORAY ENGINEERING CO., LTD.", + [3]byte{0, 160, 252}: "IMAGE SCIENCES, INC.", + [3]byte{0, 160, 253}: "SCITEX DIGITAL PRINTING, INC.", + [3]byte{0, 160, 254}: "BOSTON TECHNOLOGY, INC.", + [3]byte{0, 160, 255}: "TELLABS OPERATIONS, INC.", + [3]byte{0, 161, 222}: "ShenZhen ShiHua Technology CO.,LTD", + [3]byte{0, 162, 218}: "INAT GmbH", + [3]byte{0, 162, 245}: "Guangzhou Yuanyun Network Technology Co.,Ltd", + [3]byte{0, 162, 255}: "abatec group AG", + [3]byte{0, 170, 0}: "INTEL CORPORATION", + [3]byte{0, 170, 1}: "INTEL CORPORATION", + [3]byte{0, 170, 2}: "INTEL CORPORATION", + [3]byte{0, 170, 60}: "OLIVETTI TELECOM SPA (OLTECO)", + [3]byte{0, 170, 112}: "LG Electronics", + [3]byte{0, 172, 224}: "ARRIS Group, Inc.", + [3]byte{0, 174, 250}: "Murata Manufacturing Co., Ltd.", + [3]byte{0, 176, 9}: "Grass Valley Group", + [3]byte{0, 176, 23}: "InfoGear Technology Corp.", + [3]byte{0, 176, 25}: "UTC CCS", + [3]byte{0, 176, 28}: "Westport Technologies", + [3]byte{0, 176, 30}: "Rantic Labs, Inc.", + [3]byte{0, 176, 42}: "ORSYS GmbH", + [3]byte{0, 176, 45}: "ViaGate Technologies, Inc.", + [3]byte{0, 176, 51}: "OAO \"Izhevskiy radiozavod\"", + [3]byte{0, 176, 59}: "HiQ Networks", + [3]byte{0, 176, 72}: "Marconi Communications Inc.", + [3]byte{0, 176, 74}: "CISCO SYSTEMS, INC.", + [3]byte{0, 176, 82}: "Atheros Communications", + [3]byte{0, 176, 100}: "CISCO SYSTEMS, INC.", + [3]byte{0, 176, 105}: "Honewell Oy", + [3]byte{0, 176, 109}: "Jones Futurex Inc.", + [3]byte{0, 176, 128}: "Mannesmann Ipulsys B.V.", + [3]byte{0, 176, 134}: "LocSoft Limited", + [3]byte{0, 176, 142}: "CISCO SYSTEMS, INC.", + [3]byte{0, 176, 145}: "Transmeta Corp.", + [3]byte{0, 176, 148}: "Alaris, Inc.", + [3]byte{0, 176, 154}: "Morrow Technologies Corp.", + [3]byte{0, 176, 157}: "Point Grey Research Inc.", + [3]byte{0, 176, 172}: "SIAE-Microelettronica S.p.A.", + [3]byte{0, 176, 174}: "Symmetricom", + [3]byte{0, 176, 179}: "Xstreamis PLC", + [3]byte{0, 176, 194}: "CISCO SYSTEMS, INC.", + [3]byte{0, 176, 199}: "Tellabs Operations, Inc.", + [3]byte{0, 176, 206}: "TECHNOLOGY RESCUE", + [3]byte{0, 176, 208}: "Dell Computer Corp.", + [3]byte{0, 176, 219}: "Nextcell, Inc.", + [3]byte{0, 176, 223}: "Starboard Storage Systems", + [3]byte{0, 176, 231}: "British Federal Ltd.", + [3]byte{0, 176, 236}: "EACEM", + [3]byte{0, 176, 238}: "Ajile Systems, Inc.", + [3]byte{0, 176, 240}: "CALY NETWORKS", + [3]byte{0, 176, 245}: "NetWorth Technologies, Inc.", + [3]byte{0, 179, 56}: "Kontron Design Manufacturing Services (M) Sdn. Bhd", + [3]byte{0, 179, 66}: "MacroSAN Technologies Co., Ltd.", + [3]byte{0, 181, 109}: "David Electronics Co., LTD.", + [3]byte{0, 181, 214}: "Omnibit Inc.", + [3]byte{0, 183, 141}: "Nanjing Shining Electric Automation Co., Ltd", + [3]byte{0, 185, 246}: "Shenzhen Super Rich Electronics Co.,Ltd", + [3]byte{0, 186, 192}: "Biometric Access Company", + [3]byte{0, 187, 1}: "OCTOTHORPE CORP.", + [3]byte{0, 187, 58}: "PRIVATE", + [3]byte{0, 187, 142}: "HME Co., Ltd.", + [3]byte{0, 187, 240}: "UNGERMANN-BASS INC.", + [3]byte{0, 189, 39}: "Exar Corp.", + [3]byte{0, 189, 58}: "Nokia Corporation", + [3]byte{0, 191, 21}: "Genetec Inc.", + [3]byte{0, 192, 0}: "LANOPTICS, LTD.", + [3]byte{0, 192, 1}: "DIATEK PATIENT MANAGMENT", + [3]byte{0, 192, 2}: "SERCOMM CORPORATION", + [3]byte{0, 192, 3}: "GLOBALNET COMMUNICATIONS", + [3]byte{0, 192, 4}: "JAPAN BUSINESS COMPUTER CO.LTD", + [3]byte{0, 192, 5}: "LIVINGSTON ENTERPRISES, INC.", + [3]byte{0, 192, 6}: "NIPPON AVIONICS CO., LTD.", + [3]byte{0, 192, 7}: "PINNACLE DATA SYSTEMS, INC.", + [3]byte{0, 192, 8}: "SECO SRL", + [3]byte{0, 192, 9}: "KT TECHNOLOGY (S) PTE LTD", + [3]byte{0, 192, 10}: "MICRO CRAFT", + [3]byte{0, 192, 11}: "NORCONTROL A.S.", + [3]byte{0, 192, 12}: "RELIA TECHNOLGIES", + [3]byte{0, 192, 13}: "ADVANCED LOGIC RESEARCH, INC.", + [3]byte{0, 192, 14}: "PSITECH, INC.", + [3]byte{0, 192, 15}: "QUANTUM SOFTWARE SYSTEMS LTD.", + [3]byte{0, 192, 16}: "HIRAKAWA HEWTECH CORP.", + [3]byte{0, 192, 17}: "INTERACTIVE COMPUTING DEVICES", + [3]byte{0, 192, 18}: "NETSPAN CORPORATION", + [3]byte{0, 192, 19}: "NETRIX", + [3]byte{0, 192, 20}: "TELEMATICS CALABASAS INT'L,INC", + [3]byte{0, 192, 21}: "NEW MEDIA CORPORATION", + [3]byte{0, 192, 22}: "ELECTRONIC THEATRE CONTROLS", + [3]byte{0, 192, 23}: "Fluke Corporation", + [3]byte{0, 192, 24}: "LANART CORPORATION", + [3]byte{0, 192, 25}: "LEAP TECHNOLOGY, INC.", + [3]byte{0, 192, 26}: "COROMETRICS MEDICAL SYSTEMS", + [3]byte{0, 192, 27}: "SOCKET COMMUNICATIONS, INC.", + [3]byte{0, 192, 28}: "INTERLINK COMMUNICATIONS LTD.", + [3]byte{0, 192, 29}: "GRAND JUNCTION NETWORKS, INC.", + [3]byte{0, 192, 30}: "LA FRANCAISE DES JEUX", + [3]byte{0, 192, 31}: "S.E.R.C.E.L.", + [3]byte{0, 192, 32}: "ARCO ELECTRONIC, CONTROL LTD.", + [3]byte{0, 192, 33}: "NETEXPRESS", + [3]byte{0, 192, 34}: "LASERMASTER TECHNOLOGIES, INC.", + [3]byte{0, 192, 35}: "TUTANKHAMON ELECTRONICS", + [3]byte{0, 192, 36}: "EDEN SISTEMAS DE COMPUTACAO SA", + [3]byte{0, 192, 37}: "DATAPRODUCTS CORPORATION", + [3]byte{0, 192, 38}: "LANS TECHNOLOGY CO., LTD.", + [3]byte{0, 192, 39}: "CIPHER SYSTEMS, INC.", + [3]byte{0, 192, 40}: "JASCO CORPORATION", + [3]byte{0, 192, 41}: "Nexans Deutschland GmbH - ANS", + [3]byte{0, 192, 42}: "OHKURA ELECTRIC CO., LTD.", + [3]byte{0, 192, 43}: "GERLOFF GESELLSCHAFT FUR", + [3]byte{0, 192, 44}: "CENTRUM COMMUNICATIONS, INC.", + [3]byte{0, 192, 45}: "FUJI PHOTO FILM CO., LTD.", + [3]byte{0, 192, 46}: "NETWIZ", + [3]byte{0, 192, 47}: "OKUMA CORPORATION", + [3]byte{0, 192, 48}: "INTEGRATED ENGINEERING B. V.", + [3]byte{0, 192, 49}: "DESIGN RESEARCH SYSTEMS, INC.", + [3]byte{0, 192, 50}: "I-CUBED LIMITED", + [3]byte{0, 192, 51}: "TELEBIT COMMUNICATIONS APS", + [3]byte{0, 192, 52}: "TRANSACTION NETWORK", + [3]byte{0, 192, 53}: "QUINTAR COMPANY", + [3]byte{0, 192, 54}: "RAYTECH ELECTRONIC CORP.", + [3]byte{0, 192, 55}: "DYNATEM", + [3]byte{0, 192, 56}: "RASTER IMAGE PROCESSING SYSTEM", + [3]byte{0, 192, 57}: "Teridian Semiconductor Corporation", + [3]byte{0, 192, 58}: "MEN-MIKRO ELEKTRONIK GMBH", + [3]byte{0, 192, 59}: "MULTIACCESS COMPUTING CORP.", + [3]byte{0, 192, 60}: "TOWER TECH S.R.L.", + [3]byte{0, 192, 61}: "WIESEMANN & THEIS GMBH", + [3]byte{0, 192, 62}: "FA. GEBR. HELLER GMBH", + [3]byte{0, 192, 63}: "STORES AUTOMATED SYSTEMS, INC.", + [3]byte{0, 192, 64}: "ECCI", + [3]byte{0, 192, 65}: "DIGITAL TRANSMISSION SYSTEMS", + [3]byte{0, 192, 66}: "DATALUX CORP.", + [3]byte{0, 192, 67}: "STRATACOM", + [3]byte{0, 192, 68}: "EMCOM CORPORATION", + [3]byte{0, 192, 69}: "ISOLATION SYSTEMS, LTD.", + [3]byte{0, 192, 70}: "Blue Chip Technology Ltd", + [3]byte{0, 192, 71}: "UNIMICRO SYSTEMS, INC.", + [3]byte{0, 192, 72}: "BAY TECHNICAL ASSOCIATES", + [3]byte{0, 192, 73}: "U.S. ROBOTICS, INC.", + [3]byte{0, 192, 74}: "GROUP 2000 AG", + [3]byte{0, 192, 75}: "CREATIVE MICROSYSTEMS", + [3]byte{0, 192, 76}: "DEPARTMENT OF FOREIGN AFFAIRS", + [3]byte{0, 192, 77}: "MITEC, INC.", + [3]byte{0, 192, 78}: "COMTROL CORPORATION", + [3]byte{0, 192, 79}: "DELL COMPUTER CORPORATION", + [3]byte{0, 192, 80}: "TOYO DENKI SEIZO K.K.", + [3]byte{0, 192, 81}: "ADVANCED INTEGRATION RESEARCH", + [3]byte{0, 192, 82}: "BURR-BROWN", + [3]byte{0, 192, 83}: "Aspect Software Inc.", + [3]byte{0, 192, 84}: "NETWORK PERIPHERALS, LTD.", + [3]byte{0, 192, 85}: "MODULAR COMPUTING TECHNOLOGIES", + [3]byte{0, 192, 86}: "SOMELEC", + [3]byte{0, 192, 87}: "MYCO ELECTRONICS", + [3]byte{0, 192, 88}: "DATAEXPERT CORP.", + [3]byte{0, 192, 89}: "DENSO CORPORATION", + [3]byte{0, 192, 90}: "SEMAPHORE COMMUNICATIONS CORP.", + [3]byte{0, 192, 91}: "NETWORKS NORTHWEST, INC.", + [3]byte{0, 192, 92}: "ELONEX PLC", + [3]byte{0, 192, 93}: "L&N TECHNOLOGIES", + [3]byte{0, 192, 94}: "VARI-LITE, INC.", + [3]byte{0, 192, 95}: "FINE-PAL COMPANY LIMITED", + [3]byte{0, 192, 96}: "ID SCANDINAVIA AS", + [3]byte{0, 192, 97}: "SOLECTEK CORPORATION", + [3]byte{0, 192, 98}: "IMPULSE TECHNOLOGY", + [3]byte{0, 192, 99}: "MORNING STAR TECHNOLOGIES, INC", + [3]byte{0, 192, 100}: "GENERAL DATACOMM IND. INC.", + [3]byte{0, 192, 101}: "SCOPE COMMUNICATIONS, INC.", + [3]byte{0, 192, 102}: "DOCUPOINT, INC.", + [3]byte{0, 192, 103}: "UNITED BARCODE INDUSTRIES", + [3]byte{0, 192, 104}: "HME Clear-Com LTD.", + [3]byte{0, 192, 105}: "Axxcelera Broadband Wireless", + [3]byte{0, 192, 106}: "ZAHNER-ELEKTRIK GMBH & CO. KG", + [3]byte{0, 192, 107}: "OSI PLUS CORPORATION", + [3]byte{0, 192, 108}: "SVEC COMPUTER CORP.", + [3]byte{0, 192, 109}: "BOCA RESEARCH, INC.", + [3]byte{0, 192, 110}: "HAFT TECHNOLOGY, INC.", + [3]byte{0, 192, 111}: "KOMATSU LTD.", + [3]byte{0, 192, 112}: "SECTRA SECURE-TRANSMISSION AB", + [3]byte{0, 192, 113}: "AREANEX COMMUNICATIONS, INC.", + [3]byte{0, 192, 114}: "KNX LTD.", + [3]byte{0, 192, 115}: "XEDIA CORPORATION", + [3]byte{0, 192, 116}: "TOYODA AUTOMATIC LOOM", + [3]byte{0, 192, 117}: "XANTE CORPORATION", + [3]byte{0, 192, 118}: "I-DATA INTERNATIONAL A-S", + [3]byte{0, 192, 119}: "DAEWOO TELECOM LTD.", + [3]byte{0, 192, 120}: "COMPUTER SYSTEMS ENGINEERING", + [3]byte{0, 192, 121}: "FONSYS CO.,LTD.", + [3]byte{0, 192, 122}: "PRIVA B.V.", + [3]byte{0, 192, 123}: "ASCEND COMMUNICATIONS, INC.", + [3]byte{0, 192, 124}: "HIGHTECH INFORMATION", + [3]byte{0, 192, 125}: "RISC DEVELOPMENTS LTD.", + [3]byte{0, 192, 126}: "KUBOTA CORPORATION ELECTRONIC", + [3]byte{0, 192, 127}: "NUPON COMPUTING CORP.", + [3]byte{0, 192, 128}: "NETSTAR, INC.", + [3]byte{0, 192, 129}: "METRODATA LTD.", + [3]byte{0, 192, 130}: "MOORE PRODUCTS CO.", + [3]byte{0, 192, 131}: "TRACE MOUNTAIN PRODUCTS, INC.", + [3]byte{0, 192, 132}: "DATA LINK CORP. LTD.", + [3]byte{0, 192, 133}: "ELECTRONICS FOR IMAGING, INC.", + [3]byte{0, 192, 134}: "THE LYNK CORPORATION", + [3]byte{0, 192, 135}: "UUNET TECHNOLOGIES, INC.", + [3]byte{0, 192, 136}: "EKF ELEKTRONIK GMBH", + [3]byte{0, 192, 137}: "TELINDUS DISTRIBUTION", + [3]byte{0, 192, 138}: "Lauterbach GmbH", + [3]byte{0, 192, 139}: "RISQ MODULAR SYSTEMS, INC.", + [3]byte{0, 192, 140}: "PERFORMANCE TECHNOLOGIES, INC.", + [3]byte{0, 192, 141}: "TRONIX PRODUCT DEVELOPMENT", + [3]byte{0, 192, 142}: "NETWORK INFORMATION TECHNOLOGY", + [3]byte{0, 192, 143}: "Panasonic Electric Works Co., Ltd.", + [3]byte{0, 192, 144}: "PRAIM S.R.L.", + [3]byte{0, 192, 145}: "JABIL CIRCUIT, INC.", + [3]byte{0, 192, 146}: "MENNEN MEDICAL INC.", + [3]byte{0, 192, 147}: "ALTA RESEARCH CORP.", + [3]byte{0, 192, 148}: "VMX INC.", + [3]byte{0, 192, 149}: "ZNYX", + [3]byte{0, 192, 150}: "TAMURA CORPORATION", + [3]byte{0, 192, 151}: "ARCHIPEL SA", + [3]byte{0, 192, 152}: "CHUNTEX ELECTRONIC CO., LTD.", + [3]byte{0, 192, 153}: "YOSHIKI INDUSTRIAL CO.,LTD.", + [3]byte{0, 192, 154}: "PHOTONICS CORPORATION", + [3]byte{0, 192, 155}: "RELIANCE COMM/TEC, R-TEC", + [3]byte{0, 192, 156}: "HIOKI E.E. CORPORATION", + [3]byte{0, 192, 157}: "DISTRIBUTED SYSTEMS INT'L, INC", + [3]byte{0, 192, 158}: "CACHE COMPUTERS, INC.", + [3]byte{0, 192, 159}: "QUANTA COMPUTER, INC.", + [3]byte{0, 192, 160}: "ADVANCE MICRO RESEARCH, INC.", + [3]byte{0, 192, 161}: "TOKYO DENSHI SEKEI CO.", + [3]byte{0, 192, 162}: "INTERMEDIUM A/S", + [3]byte{0, 192, 163}: "DUAL ENTERPRISES CORPORATION", + [3]byte{0, 192, 164}: "UNIGRAF OY", + [3]byte{0, 192, 165}: "DICKENS DATA SYSTEMS", + [3]byte{0, 192, 166}: "EXICOM AUSTRALIA PTY. LTD", + [3]byte{0, 192, 167}: "SEEL LTD.", + [3]byte{0, 192, 168}: "GVC CORPORATION", + [3]byte{0, 192, 169}: "BARRON MCCANN LTD.", + [3]byte{0, 192, 170}: "SILICON VALLEY COMPUTER", + [3]byte{0, 192, 171}: "Telco Systems, Inc.", + [3]byte{0, 192, 172}: "GAMBIT COMPUTER COMMUNICATIONS", + [3]byte{0, 192, 173}: "MARBEN COMMUNICATION SYSTEMS", + [3]byte{0, 192, 174}: "TOWERCOM CO. INC. DBA PC HOUSE", + [3]byte{0, 192, 175}: "TEKLOGIX INC.", + [3]byte{0, 192, 176}: "GCC TECHNOLOGIES,INC.", + [3]byte{0, 192, 177}: "GENIUS NET CO.", + [3]byte{0, 192, 178}: "NORAND CORPORATION", + [3]byte{0, 192, 179}: "COMSTAT DATACOMM CORPORATION", + [3]byte{0, 192, 180}: "MYSON TECHNOLOGY, INC.", + [3]byte{0, 192, 181}: "CORPORATE NETWORK SYSTEMS,INC.", + [3]byte{0, 192, 182}: "Overland Storage, Inc.", + [3]byte{0, 192, 183}: "AMERICAN POWER CONVERSION CORP", + [3]byte{0, 192, 184}: "FRASER'S HILL LTD.", + [3]byte{0, 192, 185}: "FUNK SOFTWARE, INC.", + [3]byte{0, 192, 186}: "NETVANTAGE", + [3]byte{0, 192, 187}: "FORVAL CREATIVE, INC.", + [3]byte{0, 192, 188}: "TELECOM AUSTRALIA/CSSC", + [3]byte{0, 192, 189}: "INEX TECHNOLOGIES, INC.", + [3]byte{0, 192, 190}: "ALCATEL - SEL", + [3]byte{0, 192, 191}: "TECHNOLOGY CONCEPTS, LTD.", + [3]byte{0, 192, 192}: "SHORE MICROSYSTEMS, INC.", + [3]byte{0, 192, 193}: "QUAD/GRAPHICS, INC.", + [3]byte{0, 192, 194}: "INFINITE NETWORKS LTD.", + [3]byte{0, 192, 195}: "ACUSON COMPUTED SONOGRAPHY", + [3]byte{0, 192, 196}: "COMPUTER OPERATIONAL", + [3]byte{0, 192, 197}: "SID INFORMATICA", + [3]byte{0, 192, 198}: "PERSONAL MEDIA CORP.", + [3]byte{0, 192, 199}: "SPARKTRUM MICROSYSTEMS, INC.", + [3]byte{0, 192, 200}: "MICRO BYTE PTY. LTD.", + [3]byte{0, 192, 201}: "ELSAG BAILEY PROCESS", + [3]byte{0, 192, 202}: "ALFA, INC.", + [3]byte{0, 192, 203}: "CONTROL TECHNOLOGY CORPORATION", + [3]byte{0, 192, 204}: "TELESCIENCES CO SYSTEMS, INC.", + [3]byte{0, 192, 205}: "COMELTA, S.A.", + [3]byte{0, 192, 206}: "CEI SYSTEMS & ENGINEERING PTE", + [3]byte{0, 192, 207}: "IMATRAN VOIMA OY", + [3]byte{0, 192, 208}: "RATOC SYSTEM INC.", + [3]byte{0, 192, 209}: "COMTREE TECHNOLOGY CORPORATION", + [3]byte{0, 192, 210}: "SYNTELLECT, INC.", + [3]byte{0, 192, 211}: "OLYMPUS IMAGE SYSTEMS, INC.", + [3]byte{0, 192, 212}: "AXON NETWORKS, INC.", + [3]byte{0, 192, 213}: "Werbeagentur Jürgen Siebert", + [3]byte{0, 192, 214}: "J1 SYSTEMS, INC.", + [3]byte{0, 192, 215}: "TAIWAN TRADING CENTER DBA", + [3]byte{0, 192, 216}: "UNIVERSAL DATA SYSTEMS", + [3]byte{0, 192, 217}: "QUINTE NETWORK CONFIDENTIALITY", + [3]byte{0, 192, 218}: "NICE SYSTEMS LTD.", + [3]byte{0, 192, 219}: "IPC CORPORATION (PTE) LTD.", + [3]byte{0, 192, 220}: "EOS TECHNOLOGIES, INC.", + [3]byte{0, 192, 221}: "QLogic Corporation", + [3]byte{0, 192, 222}: "ZCOMM, INC.", + [3]byte{0, 192, 223}: "KYE Systems Corp.", + [3]byte{0, 192, 224}: "DSC COMMUNICATION CORP.", + [3]byte{0, 192, 225}: "SONIC SOLUTIONS", + [3]byte{0, 192, 226}: "CALCOMP, INC.", + [3]byte{0, 192, 227}: "OSITECH COMMUNICATIONS, INC.", + [3]byte{0, 192, 228}: "SIEMENS BUILDING", + [3]byte{0, 192, 229}: "GESPAC, S.A.", + [3]byte{0, 192, 230}: "Verilink Corporation", + [3]byte{0, 192, 231}: "FIBERDATA AB", + [3]byte{0, 192, 232}: "PLEXCOM, INC.", + [3]byte{0, 192, 233}: "OAK SOLUTIONS, LTD.", + [3]byte{0, 192, 234}: "ARRAY TECHNOLOGY LTD.", + [3]byte{0, 192, 235}: "SEH COMPUTERTECHNIK GMBH", + [3]byte{0, 192, 236}: "DAUPHIN TECHNOLOGY", + [3]byte{0, 192, 237}: "US ARMY ELECTRONIC", + [3]byte{0, 192, 238}: "KYOCERA CORPORATION", + [3]byte{0, 192, 239}: "ABIT CORPORATION", + [3]byte{0, 192, 240}: "KINGSTON TECHNOLOGY CORP.", + [3]byte{0, 192, 241}: "SHINKO ELECTRIC CO., LTD.", + [3]byte{0, 192, 242}: "TRANSITION NETWORKS", + [3]byte{0, 192, 243}: "NETWORK COMMUNICATIONS CORP.", + [3]byte{0, 192, 244}: "INTERLINK SYSTEM CO., LTD.", + [3]byte{0, 192, 245}: "METACOMP, INC.", + [3]byte{0, 192, 246}: "CELAN TECHNOLOGY INC.", + [3]byte{0, 192, 247}: "ENGAGE COMMUNICATION, INC.", + [3]byte{0, 192, 248}: "ABOUT COMPUTING INC.", + [3]byte{0, 192, 249}: "Artesyn Embedded Technologies", + [3]byte{0, 192, 250}: "CANARY COMMUNICATIONS, INC.", + [3]byte{0, 192, 251}: "ADVANCED TECHNOLOGY LABS", + [3]byte{0, 192, 252}: "ELASTIC REALITY, INC.", + [3]byte{0, 192, 253}: "PROSUM", + [3]byte{0, 192, 254}: "APTEC COMPUTER SYSTEMS, INC.", + [3]byte{0, 192, 255}: "DOT HILL SYSTEMS CORPORATION", + [3]byte{0, 193, 79}: "DDL Co,.ltd.", + [3]byte{0, 194, 198}: "Intel Corporate", + [3]byte{0, 197, 219}: "Datatech Sistemas Digitales Avanzados SL", + [3]byte{0, 198, 16}: "Apple", + [3]byte{0, 203, 189}: "Cambridge Broadband Networks Ltd.", + [3]byte{0, 205, 144}: "MAS Elektronik AG", + [3]byte{0, 207, 28}: "COMMUNICATION MACHINERY CORP.", + [3]byte{0, 208, 0}: "FERRAN SCIENTIFIC, INC.", + [3]byte{0, 208, 1}: "VST TECHNOLOGIES, INC.", + [3]byte{0, 208, 2}: "DITECH CORPORATION", + [3]byte{0, 208, 3}: "COMDA ENTERPRISES CORP.", + [3]byte{0, 208, 4}: "PENTACOM LTD.", + [3]byte{0, 208, 5}: "ZHS ZEITMANAGEMENTSYSTEME", + [3]byte{0, 208, 6}: "CISCO SYSTEMS, INC.", + [3]byte{0, 208, 7}: "MIC ASSOCIATES, INC.", + [3]byte{0, 208, 8}: "MACTELL CORPORATION", + [3]byte{0, 208, 9}: "HSING TECH. ENTERPRISE CO. LTD", + [3]byte{0, 208, 10}: "LANACCESS TELECOM S.A.", + [3]byte{0, 208, 11}: "RHK TECHNOLOGY, INC.", + [3]byte{0, 208, 12}: "SNIJDER MICRO SYSTEMS", + [3]byte{0, 208, 13}: "MICROMERITICS INSTRUMENT", + [3]byte{0, 208, 14}: "PLURIS, INC.", + [3]byte{0, 208, 15}: "SPEECH DESIGN GMBH", + [3]byte{0, 208, 16}: "CONVERGENT NETWORKS, INC.", + [3]byte{0, 208, 17}: "PRISM VIDEO, INC.", + [3]byte{0, 208, 18}: "GATEWORKS CORP.", + [3]byte{0, 208, 19}: "PRIMEX AEROSPACE COMPANY", + [3]byte{0, 208, 20}: "ROOT, INC.", + [3]byte{0, 208, 21}: "UNIVEX MICROTECHNOLOGY CORP.", + [3]byte{0, 208, 22}: "SCM MICROSYSTEMS, INC.", + [3]byte{0, 208, 23}: "SYNTECH INFORMATION CO., LTD.", + [3]byte{0, 208, 24}: "QWES. COM, INC.", + [3]byte{0, 208, 25}: "DAINIPPON SCREEN CORPORATE", + [3]byte{0, 208, 26}: "URMET TLC S.P.A.", + [3]byte{0, 208, 27}: "MIMAKI ENGINEERING CO., LTD.", + [3]byte{0, 208, 28}: "SBS TECHNOLOGIES,", + [3]byte{0, 208, 29}: "FURUNO ELECTRIC CO., LTD.", + [3]byte{0, 208, 30}: "PINGTEL CORP.", + [3]byte{0, 208, 31}: "Senetas Security", + [3]byte{0, 208, 32}: "AIM SYSTEM, INC.", + [3]byte{0, 208, 33}: "REGENT ELECTRONICS CORP.", + [3]byte{0, 208, 34}: "INCREDIBLE TECHNOLOGIES, INC.", + [3]byte{0, 208, 35}: "INFORTREND TECHNOLOGY, INC.", + [3]byte{0, 208, 36}: "Cognex Corporation", + [3]byte{0, 208, 37}: "XROSSTECH, INC.", + [3]byte{0, 208, 38}: "HIRSCHMANN AUSTRIA GMBH", + [3]byte{0, 208, 39}: "APPLIED AUTOMATION, INC.", + [3]byte{0, 208, 40}: "Harmonic, Inc", + [3]byte{0, 208, 41}: "WAKEFERN FOOD CORPORATION", + [3]byte{0, 208, 42}: "Voxent Systems Ltd.", + [3]byte{0, 208, 43}: "JETCELL, INC.", + [3]byte{0, 208, 44}: "CAMPBELL SCIENTIFIC, INC.", + [3]byte{0, 208, 45}: "ADEMCO", + [3]byte{0, 208, 46}: "COMMUNICATION AUTOMATION CORP.", + [3]byte{0, 208, 47}: "VLSI TECHNOLOGY INC.", + [3]byte{0, 208, 48}: "Safetran Systems Corp", + [3]byte{0, 208, 49}: "INDUSTRIAL LOGIC CORPORATION", + [3]byte{0, 208, 50}: "YANO ELECTRIC CO., LTD.", + [3]byte{0, 208, 51}: "DALIAN DAXIAN NETWORK", + [3]byte{0, 208, 52}: "ORMEC SYSTEMS CORP.", + [3]byte{0, 208, 53}: "BEHAVIOR TECH. COMPUTER CORP.", + [3]byte{0, 208, 54}: "TECHNOLOGY ATLANTA CORP.", + [3]byte{0, 208, 55}: "Pace France", + [3]byte{0, 208, 56}: "FIVEMERE, LTD.", + [3]byte{0, 208, 57}: "UTILICOM, INC.", + [3]byte{0, 208, 58}: "ZONEWORX, INC.", + [3]byte{0, 208, 59}: "VISION PRODUCTS PTY. LTD.", + [3]byte{0, 208, 60}: "Vieo, Inc.", + [3]byte{0, 208, 61}: "GALILEO TECHNOLOGY, LTD.", + [3]byte{0, 208, 62}: "ROCKETCHIPS, INC.", + [3]byte{0, 208, 63}: "AMERICAN COMMUNICATION", + [3]byte{0, 208, 64}: "SYSMATE CO., LTD.", + [3]byte{0, 208, 65}: "AMIGO TECHNOLOGY CO., LTD.", + [3]byte{0, 208, 66}: "MAHLO GMBH & CO. UG", + [3]byte{0, 208, 67}: "ZONAL RETAIL DATA SYSTEMS", + [3]byte{0, 208, 68}: "ALIDIAN NETWORKS, INC.", + [3]byte{0, 208, 69}: "KVASER AB", + [3]byte{0, 208, 70}: "DOLBY LABORATORIES, INC.", + [3]byte{0, 208, 71}: "XN TECHNOLOGIES", + [3]byte{0, 208, 72}: "ECTON, INC.", + [3]byte{0, 208, 73}: "IMPRESSTEK CO., LTD.", + [3]byte{0, 208, 74}: "PRESENCE TECHNOLOGY GMBH", + [3]byte{0, 208, 75}: "LA CIE GROUP S.A.", + [3]byte{0, 208, 76}: "EUROTEL TELECOM LTD.", + [3]byte{0, 208, 77}: "DIV OF RESEARCH & STATISTICS", + [3]byte{0, 208, 78}: "LOGIBAG", + [3]byte{0, 208, 79}: "BITRONICS, INC.", + [3]byte{0, 208, 80}: "ISKRATEL", + [3]byte{0, 208, 81}: "O2 MICRO, INC.", + [3]byte{0, 208, 82}: "ASCEND COMMUNICATIONS, INC.", + [3]byte{0, 208, 83}: "CONNECTED SYSTEMS", + [3]byte{0, 208, 84}: "SAS INSTITUTE INC.", + [3]byte{0, 208, 85}: "KATHREIN-WERKE KG", + [3]byte{0, 208, 86}: "SOMAT CORPORATION", + [3]byte{0, 208, 87}: "ULTRAK, INC.", + [3]byte{0, 208, 88}: "CISCO SYSTEMS, INC.", + [3]byte{0, 208, 89}: "AMBIT MICROSYSTEMS CORP.", + [3]byte{0, 208, 90}: "SYMBIONICS, LTD.", + [3]byte{0, 208, 91}: "ACROLOOP MOTION CONTROL", + [3]byte{0, 208, 92}: "TECHNOTREND SYSTEMTECHNIK GMBH", + [3]byte{0, 208, 93}: "INTELLIWORXX, INC.", + [3]byte{0, 208, 94}: "STRATABEAM TECHNOLOGY, INC.", + [3]byte{0, 208, 95}: "VALCOM, INC.", + [3]byte{0, 208, 96}: "Panasonic Europe Ltd.", + [3]byte{0, 208, 97}: "TREMON ENTERPRISES CO., LTD.", + [3]byte{0, 208, 98}: "DIGIGRAM", + [3]byte{0, 208, 99}: "CISCO SYSTEMS, INC.", + [3]byte{0, 208, 100}: "MULTITEL", + [3]byte{0, 208, 101}: "TOKO ELECTRIC", + [3]byte{0, 208, 102}: "WINTRISS ENGINEERING CORP.", + [3]byte{0, 208, 103}: "CAMPIO COMMUNICATIONS", + [3]byte{0, 208, 104}: "IWILL CORPORATION", + [3]byte{0, 208, 105}: "TECHNOLOGIC SYSTEMS", + [3]byte{0, 208, 106}: "LINKUP SYSTEMS CORPORATION", + [3]byte{0, 208, 107}: "SR TELECOM INC.", + [3]byte{0, 208, 108}: "SHAREWAVE, INC.", + [3]byte{0, 208, 109}: "ACRISON, INC.", + [3]byte{0, 208, 110}: "TRENDVIEW RECORDERS LTD.", + [3]byte{0, 208, 111}: "KMC CONTROLS", + [3]byte{0, 208, 112}: "LONG WELL ELECTRONICS CORP.", + [3]byte{0, 208, 113}: "ECHELON CORP.", + [3]byte{0, 208, 114}: "BROADLOGIC", + [3]byte{0, 208, 115}: "ACN ADVANCED COMMUNICATIONS", + [3]byte{0, 208, 116}: "TAQUA SYSTEMS, INC.", + [3]byte{0, 208, 117}: "ALARIS MEDICAL SYSTEMS, INC.", + [3]byte{0, 208, 118}: "Bank of America", + [3]byte{0, 208, 119}: "LUCENT TECHNOLOGIES", + [3]byte{0, 208, 120}: "Eltex of Sweden AB", + [3]byte{0, 208, 121}: "CISCO SYSTEMS, INC.", + [3]byte{0, 208, 122}: "AMAQUEST COMPUTER CORP.", + [3]byte{0, 208, 123}: "COMCAM INTERNATIONAL INC", + [3]byte{0, 208, 124}: "KOYO ELECTRONICS INC. CO.,LTD.", + [3]byte{0, 208, 125}: "COSINE COMMUNICATIONS", + [3]byte{0, 208, 126}: "KEYCORP LTD.", + [3]byte{0, 208, 127}: "STRATEGY & TECHNOLOGY, LIMITED", + [3]byte{0, 208, 128}: "EXABYTE CORPORATION", + [3]byte{0, 208, 129}: "RTD Embedded Technologies, Inc.", + [3]byte{0, 208, 130}: "IOWAVE INC.", + [3]byte{0, 208, 131}: "INVERTEX, INC.", + [3]byte{0, 208, 132}: "NEXCOMM SYSTEMS, INC.", + [3]byte{0, 208, 133}: "OTIS ELEVATOR COMPANY", + [3]byte{0, 208, 134}: "FOVEON, INC.", + [3]byte{0, 208, 135}: "MICROFIRST INC.", + [3]byte{0, 208, 136}: "ARRIS Group, Inc.", + [3]byte{0, 208, 137}: "DYNACOLOR, INC.", + [3]byte{0, 208, 138}: "PHOTRON USA", + [3]byte{0, 208, 139}: "ADVA Optical Networking Ltd.", + [3]byte{0, 208, 140}: "GENOA TECHNOLOGY, INC.", + [3]byte{0, 208, 141}: "PHOENIX GROUP, INC.", + [3]byte{0, 208, 142}: "NVISION INC.", + [3]byte{0, 208, 143}: "ARDENT TECHNOLOGIES, INC.", + [3]byte{0, 208, 144}: "CISCO SYSTEMS, INC.", + [3]byte{0, 208, 145}: "SMARTSAN SYSTEMS, INC.", + [3]byte{0, 208, 146}: "GLENAYRE WESTERN MULTIPLEX", + [3]byte{0, 208, 147}: "TQ - COMPONENTS GMBH", + [3]byte{0, 208, 148}: "TIMELINE VISTA, INC.", + [3]byte{0, 208, 149}: "Alcatel-Lucent, Enterprise Business Group", + [3]byte{0, 208, 150}: "3COM EUROPE LTD.", + [3]byte{0, 208, 151}: "CISCO SYSTEMS, INC.", + [3]byte{0, 208, 152}: "Photon Dynamics Canada Inc.", + [3]byte{0, 208, 153}: "Elcard Wireless Systems Oy", + [3]byte{0, 208, 154}: "FILANET CORPORATION", + [3]byte{0, 208, 155}: "SPECTEL LTD.", + [3]byte{0, 208, 156}: "KAPADIA COMMUNICATIONS", + [3]byte{0, 208, 157}: "VERIS INDUSTRIES", + [3]byte{0, 208, 158}: "2WIRE, INC.", + [3]byte{0, 208, 159}: "NOVTEK TEST SYSTEMS", + [3]byte{0, 208, 160}: "MIPS DENMARK", + [3]byte{0, 208, 161}: "OSKAR VIERLING GMBH + CO. KG", + [3]byte{0, 208, 162}: "INTEGRATED DEVICE", + [3]byte{0, 208, 163}: "VOCAL DATA, INC.", + [3]byte{0, 208, 164}: "ALANTRO COMMUNICATIONS", + [3]byte{0, 208, 165}: "AMERICAN ARIUM", + [3]byte{0, 208, 166}: "LANBIRD TECHNOLOGY CO., LTD.", + [3]byte{0, 208, 167}: "TOKYO SOKKI KENKYUJO CO., LTD.", + [3]byte{0, 208, 168}: "NETWORK ENGINES, INC.", + [3]byte{0, 208, 169}: "SHINANO KENSHI CO., LTD.", + [3]byte{0, 208, 170}: "CHASE COMMUNICATIONS", + [3]byte{0, 208, 171}: "DELTAKABEL TELECOM CV", + [3]byte{0, 208, 172}: "GRAYSON WIRELESS", + [3]byte{0, 208, 173}: "TL INDUSTRIES", + [3]byte{0, 208, 174}: "ORESIS COMMUNICATIONS, INC.", + [3]byte{0, 208, 175}: "CUTLER-HAMMER, INC.", + [3]byte{0, 208, 176}: "BITSWITCH LTD.", + [3]byte{0, 208, 177}: "OMEGA ELECTRONICS SA", + [3]byte{0, 208, 178}: "XIOTECH CORPORATION", + [3]byte{0, 208, 179}: "DRS Technologies Canada Ltd", + [3]byte{0, 208, 180}: "KATSUJIMA CO., LTD.", + [3]byte{0, 208, 181}: "IPricot formerly DotCom", + [3]byte{0, 208, 182}: "CRESCENT NETWORKS, INC.", + [3]byte{0, 208, 183}: "INTEL CORPORATION", + [3]byte{0, 208, 184}: "Iomega Corporation", + [3]byte{0, 208, 185}: "MICROTEK INTERNATIONAL, INC.", + [3]byte{0, 208, 186}: "CISCO SYSTEMS, INC.", + [3]byte{0, 208, 187}: "CISCO SYSTEMS, INC.", + [3]byte{0, 208, 188}: "CISCO SYSTEMS, INC.", + [3]byte{0, 208, 189}: "Silicon Image GmbH", + [3]byte{0, 208, 190}: "EMUTEC INC.", + [3]byte{0, 208, 191}: "PIVOTAL TECHNOLOGIES", + [3]byte{0, 208, 192}: "CISCO SYSTEMS, INC.", + [3]byte{0, 208, 193}: "HARMONIC DATA SYSTEMS, LTD.", + [3]byte{0, 208, 194}: "BALTHAZAR TECHNOLOGY AB", + [3]byte{0, 208, 195}: "VIVID TECHNOLOGY PTE, LTD.", + [3]byte{0, 208, 196}: "TERATECH CORPORATION", + [3]byte{0, 208, 197}: "COMPUTATIONAL SYSTEMS, INC.", + [3]byte{0, 208, 198}: "THOMAS & BETTS CORP.", + [3]byte{0, 208, 199}: "PATHWAY, INC.", + [3]byte{0, 208, 200}: "Prevas A/S", + [3]byte{0, 208, 201}: "ADVANTECH CO., LTD.", + [3]byte{0, 208, 202}: "Intrinsyc Software International Inc.", + [3]byte{0, 208, 203}: "DASAN CO., LTD.", + [3]byte{0, 208, 204}: "TECHNOLOGIES LYRE INC.", + [3]byte{0, 208, 205}: "ATAN TECHNOLOGY INC.", + [3]byte{0, 208, 206}: "ASYST ELECTRONIC", + [3]byte{0, 208, 207}: "MORETON BAY", + [3]byte{0, 208, 208}: "ZHONGXING TELECOM LTD.", + [3]byte{0, 208, 209}: "Sycamore Networks", + [3]byte{0, 208, 210}: "EPILOG CORPORATION", + [3]byte{0, 208, 211}: "CISCO SYSTEMS, INC.", + [3]byte{0, 208, 212}: "V-BITS, INC.", + [3]byte{0, 208, 213}: "GRUNDIG AG", + [3]byte{0, 208, 214}: "AETHRA TELECOMUNICAZIONI", + [3]byte{0, 208, 215}: "B2C2, INC.", + [3]byte{0, 208, 216}: "3Com Corporation", + [3]byte{0, 208, 217}: "DEDICATED MICROCOMPUTERS", + [3]byte{0, 208, 218}: "TAICOM DATA SYSTEMS CO., LTD.", + [3]byte{0, 208, 219}: "MCQUAY INTERNATIONAL", + [3]byte{0, 208, 220}: "MODULAR MINING SYSTEMS, INC.", + [3]byte{0, 208, 221}: "SUNRISE TELECOM, INC.", + [3]byte{0, 208, 222}: "PHILIPS MULTIMEDIA NETWORK", + [3]byte{0, 208, 223}: "KUZUMI ELECTRONICS, INC.", + [3]byte{0, 208, 224}: "DOOIN ELECTRONICS CO.", + [3]byte{0, 208, 225}: "AVIONITEK ISRAEL INC.", + [3]byte{0, 208, 226}: "MRT MICRO, INC.", + [3]byte{0, 208, 227}: "ELE-CHEM ENGINEERING CO., LTD.", + [3]byte{0, 208, 228}: "CISCO SYSTEMS, INC.", + [3]byte{0, 208, 229}: "SOLIDUM SYSTEMS CORP.", + [3]byte{0, 208, 230}: "IBOND INC.", + [3]byte{0, 208, 231}: "VCON TELECOMMUNICATION LTD.", + [3]byte{0, 208, 232}: "MAC SYSTEM CO., LTD.", + [3]byte{0, 208, 233}: "Advantage Century Telecommunication Corp.", + [3]byte{0, 208, 234}: "NEXTONE COMMUNICATIONS, INC.", + [3]byte{0, 208, 235}: "LIGHTERA NETWORKS, INC.", + [3]byte{0, 208, 236}: "NAKAYO TELECOMMUNICATIONS, INC", + [3]byte{0, 208, 237}: "XIOX", + [3]byte{0, 208, 238}: "DICTAPHONE CORPORATION", + [3]byte{0, 208, 239}: "IGT", + [3]byte{0, 208, 240}: "CONVISION TECHNOLOGY GMBH", + [3]byte{0, 208, 241}: "SEGA ENTERPRISES, LTD.", + [3]byte{0, 208, 242}: "MONTEREY NETWORKS", + [3]byte{0, 208, 243}: "SOLARI DI UDINE SPA", + [3]byte{0, 208, 244}: "CARINTHIAN TECH INSTITUTE", + [3]byte{0, 208, 245}: "ORANGE MICRO, INC.", + [3]byte{0, 208, 246}: "Alcatel Canada", + [3]byte{0, 208, 247}: "NEXT NETS CORPORATION", + [3]byte{0, 208, 248}: "FUJIAN STAR TERMINAL", + [3]byte{0, 208, 249}: "ACUTE COMMUNICATIONS CORP.", + [3]byte{0, 208, 250}: "Thales e-Security Ltd.", + [3]byte{0, 208, 251}: "TEK MICROSYSTEMS, INCORPORATED", + [3]byte{0, 208, 252}: "GRANITE MICROSYSTEMS", + [3]byte{0, 208, 253}: "OPTIMA TELE.COM, INC.", + [3]byte{0, 208, 254}: "ASTRAL POINT", + [3]byte{0, 208, 255}: "CISCO SYSTEMS, INC.", + [3]byte{0, 209, 28}: "ACETEL", + [3]byte{0, 211, 141}: "Hotel Technology Next Generation", + [3]byte{0, 214, 50}: "GE Energy", + [3]byte{0, 217, 209}: "Sony Computer Entertainment Inc.", + [3]byte{0, 219, 30}: "Albedo Telecom SL", + [3]byte{0, 219, 69}: "THAMWAY CO.,LTD.", + [3]byte{0, 219, 223}: "Intel Corporate", + [3]byte{0, 221, 0}: "UNGERMANN-BASS INC.", + [3]byte{0, 221, 1}: "UNGERMANN-BASS INC.", + [3]byte{0, 221, 2}: "UNGERMANN-BASS INC.", + [3]byte{0, 221, 3}: "UNGERMANN-BASS INC.", + [3]byte{0, 221, 4}: "UNGERMANN-BASS INC.", + [3]byte{0, 221, 5}: "UNGERMANN-BASS INC.", + [3]byte{0, 221, 6}: "UNGERMANN-BASS INC.", + [3]byte{0, 221, 7}: "UNGERMANN-BASS INC.", + [3]byte{0, 221, 8}: "UNGERMANN-BASS INC.", + [3]byte{0, 221, 9}: "UNGERMANN-BASS INC.", + [3]byte{0, 221, 10}: "UNGERMANN-BASS INC.", + [3]byte{0, 221, 11}: "UNGERMANN-BASS INC.", + [3]byte{0, 221, 12}: "UNGERMANN-BASS INC.", + [3]byte{0, 221, 13}: "UNGERMANN-BASS INC.", + [3]byte{0, 221, 14}: "UNGERMANN-BASS INC.", + [3]byte{0, 221, 15}: "UNGERMANN-BASS INC.", + [3]byte{0, 222, 251}: "CISCO SYSTEMS, INC.", + [3]byte{0, 224, 0}: "Fujitsu Limited", + [3]byte{0, 224, 1}: "STRAND LIGHTING LIMITED", + [3]byte{0, 224, 2}: "CROSSROADS SYSTEMS, INC.", + [3]byte{0, 224, 3}: "NOKIA WIRELESS BUSINESS COMMUN", + [3]byte{0, 224, 4}: "PMC-SIERRA, INC.", + [3]byte{0, 224, 5}: "TECHNICAL CORP.", + [3]byte{0, 224, 6}: "SILICON INTEGRATED SYS. CORP.", + [3]byte{0, 224, 7}: "Avaya ECS Ltd", + [3]byte{0, 224, 8}: "AMAZING CONTROLS! INC.", + [3]byte{0, 224, 9}: "MARATHON TECHNOLOGIES CORP.", + [3]byte{0, 224, 10}: "DIBA, INC.", + [3]byte{0, 224, 11}: "ROOFTOP COMMUNICATIONS CORP.", + [3]byte{0, 224, 12}: "MOTOROLA", + [3]byte{0, 224, 13}: "RADIANT SYSTEMS", + [3]byte{0, 224, 14}: "AVALON IMAGING SYSTEMS, INC.", + [3]byte{0, 224, 15}: "SHANGHAI BAUD DATA", + [3]byte{0, 224, 16}: "HESS SB-AUTOMATENBAU GmbH", + [3]byte{0, 224, 17}: "Uniden Corporation", + [3]byte{0, 224, 18}: "PLUTO TECHNOLOGIES INTERNATIONAL INC.", + [3]byte{0, 224, 19}: "EASTERN ELECTRONIC CO., LTD.", + [3]byte{0, 224, 20}: "CISCO SYSTEMS, INC.", + [3]byte{0, 224, 21}: "HEIWA CORPORATION", + [3]byte{0, 224, 22}: "RAPID CITY COMMUNICATIONS", + [3]byte{0, 224, 23}: "EXXACT GmbH", + [3]byte{0, 224, 24}: "ASUSTEK COMPUTER INC.", + [3]byte{0, 224, 25}: "ING. GIORDANO ELETTRONICA", + [3]byte{0, 224, 26}: "COMTEC SYSTEMS. CO., LTD.", + [3]byte{0, 224, 27}: "SPHERE COMMUNICATIONS, INC.", + [3]byte{0, 224, 28}: "Cradlepoint, Inc", + [3]byte{0, 224, 29}: "WebTV NETWORKS, INC.", + [3]byte{0, 224, 30}: "CISCO SYSTEMS, INC.", + [3]byte{0, 224, 31}: "AVIDIA Systems, Inc.", + [3]byte{0, 224, 32}: "TECNOMEN OY", + [3]byte{0, 224, 33}: "FREEGATE CORP.", + [3]byte{0, 224, 34}: "Analog Devices Inc.", + [3]byte{0, 224, 35}: "TELRAD", + [3]byte{0, 224, 36}: "GADZOOX NETWORKS", + [3]byte{0, 224, 37}: "dit Co., Ltd.", + [3]byte{0, 224, 38}: "Redlake MASD LLC", + [3]byte{0, 224, 39}: "DUX, INC.", + [3]byte{0, 224, 40}: "APTIX CORPORATION", + [3]byte{0, 224, 41}: "STANDARD MICROSYSTEMS CORP.", + [3]byte{0, 224, 42}: "TANDBERG TELEVISION AS", + [3]byte{0, 224, 43}: "EXTREME NETWORKS", + [3]byte{0, 224, 44}: "AST COMPUTER", + [3]byte{0, 224, 45}: "InnoMediaLogic, Inc.", + [3]byte{0, 224, 46}: "SPC ELECTRONICS CORPORATION", + [3]byte{0, 224, 47}: "MCNS HOLDINGS, L.P.", + [3]byte{0, 224, 48}: "MELITA INTERNATIONAL CORP.", + [3]byte{0, 224, 49}: "HAGIWARA ELECTRIC CO., LTD.", + [3]byte{0, 224, 50}: "MISYS FINANCIAL SYSTEMS, LTD.", + [3]byte{0, 224, 51}: "E.E.P.D. GmbH", + [3]byte{0, 224, 52}: "CISCO SYSTEMS, INC.", + [3]byte{0, 224, 53}: "Artesyn Embedded Technologies", + [3]byte{0, 224, 54}: "PIONEER CORPORATION", + [3]byte{0, 224, 55}: "CENTURY CORPORATION", + [3]byte{0, 224, 56}: "PROXIMA CORPORATION", + [3]byte{0, 224, 57}: "PARADYNE CORP.", + [3]byte{0, 224, 58}: "CABLETRON SYSTEMS, INC.", + [3]byte{0, 224, 59}: "PROMINET CORPORATION", + [3]byte{0, 224, 60}: "AdvanSys", + [3]byte{0, 224, 61}: "FOCON ELECTRONIC SYSTEMS A/S", + [3]byte{0, 224, 62}: "ALFATECH, INC.", + [3]byte{0, 224, 63}: "JATON CORPORATION", + [3]byte{0, 224, 64}: "DeskStation Technology, Inc.", + [3]byte{0, 224, 65}: "CSPI", + [3]byte{0, 224, 66}: "Pacom Systems Ltd.", + [3]byte{0, 224, 67}: "VitalCom", + [3]byte{0, 224, 68}: "LSICS CORPORATION", + [3]byte{0, 224, 69}: "TOUCHWAVE, INC.", + [3]byte{0, 224, 70}: "BENTLY NEVADA CORP.", + [3]byte{0, 224, 71}: "InFocus Corporation", + [3]byte{0, 224, 72}: "SDL COMMUNICATIONS, INC.", + [3]byte{0, 224, 73}: "MICROWI ELECTRONIC GmbH", + [3]byte{0, 224, 74}: "ENHANCED MESSAGING SYSTEMS, INC", + [3]byte{0, 224, 75}: "JUMP INDUSTRIELLE COMPUTERTECHNIK GmbH", + [3]byte{0, 224, 76}: "REALTEK SEMICONDUCTOR CORP.", + [3]byte{0, 224, 77}: "INTERNET INITIATIVE JAPAN, INC", + [3]byte{0, 224, 78}: "SANYO DENKI CO., LTD.", + [3]byte{0, 224, 79}: "CISCO SYSTEMS, INC.", + [3]byte{0, 224, 80}: "EXECUTONE INFORMATION SYSTEMS, INC.", + [3]byte{0, 224, 81}: "TALX CORPORATION", + [3]byte{0, 224, 82}: "Brocade Communications Systems, Inc", + [3]byte{0, 224, 83}: "CELLPORT LABS, INC.", + [3]byte{0, 224, 84}: "KODAI HITEC CO., LTD.", + [3]byte{0, 224, 85}: "INGENIERIA ELECTRONICA COMERCIAL INELCOM S.A.", + [3]byte{0, 224, 86}: "HOLONTECH CORPORATION", + [3]byte{0, 224, 87}: "HAN MICROTELECOM. CO., LTD.", + [3]byte{0, 224, 88}: "PHASE ONE DENMARK A/S", + [3]byte{0, 224, 89}: "CONTROLLED ENVIRONMENTS, LTD.", + [3]byte{0, 224, 90}: "GALEA NETWORK SECURITY", + [3]byte{0, 224, 91}: "WEST END SYSTEMS CORP.", + [3]byte{0, 224, 92}: "MATSUSHITA KOTOBUKI ELECTRONICS INDUSTRIES, LTD.", + [3]byte{0, 224, 93}: "UNITEC CO., LTD.", + [3]byte{0, 224, 94}: "JAPAN AVIATION ELECTRONICS INDUSTRY, LTD.", + [3]byte{0, 224, 95}: "e-Net, Inc.", + [3]byte{0, 224, 96}: "SHERWOOD", + [3]byte{0, 224, 97}: "EdgePoint Networks, Inc.", + [3]byte{0, 224, 98}: "HOST ENGINEERING", + [3]byte{0, 224, 99}: "CABLETRON - YAGO SYSTEMS, INC.", + [3]byte{0, 224, 100}: "SAMSUNG ELECTRONICS", + [3]byte{0, 224, 101}: "OPTICAL ACCESS INTERNATIONAL", + [3]byte{0, 224, 102}: "ProMax Systems, Inc.", + [3]byte{0, 224, 103}: "eac AUTOMATION-CONSULTING GmbH", + [3]byte{0, 224, 104}: "MERRIMAC SYSTEMS INC.", + [3]byte{0, 224, 105}: "JAYCOR", + [3]byte{0, 224, 106}: "KAPSCH AG", + [3]byte{0, 224, 107}: "W&G SPECIAL PRODUCTS", + [3]byte{0, 224, 108}: "Ultra Electronics Limited (AEP Networks)", + [3]byte{0, 224, 109}: "COMPUWARE CORPORATION", + [3]byte{0, 224, 110}: "FAR SYSTEMS S.p.A.", + [3]byte{0, 224, 111}: "ARRIS Group, Inc.", + [3]byte{0, 224, 112}: "DH TECHNOLOGY", + [3]byte{0, 224, 113}: "EPIS MICROCOMPUTER", + [3]byte{0, 224, 114}: "LYNK", + [3]byte{0, 224, 115}: "NATIONAL AMUSEMENT NETWORK, INC.", + [3]byte{0, 224, 116}: "TIERNAN COMMUNICATIONS, INC.", + [3]byte{0, 224, 117}: "Verilink Corporation", + [3]byte{0, 224, 118}: "DEVELOPMENT CONCEPTS, INC.", + [3]byte{0, 224, 119}: "WEBGEAR, INC.", + [3]byte{0, 224, 120}: "BERKELEY NETWORKS", + [3]byte{0, 224, 121}: "A.T.N.R.", + [3]byte{0, 224, 122}: "MIKRODIDAKT AB", + [3]byte{0, 224, 123}: "BAY NETWORKS", + [3]byte{0, 224, 124}: "METTLER-TOLEDO, INC.", + [3]byte{0, 224, 125}: "NETRONIX, INC.", + [3]byte{0, 224, 126}: "WALT DISNEY IMAGINEERING", + [3]byte{0, 224, 127}: "LOGISTISTEM s.r.l.", + [3]byte{0, 224, 128}: "CONTROL RESOURCES CORPORATION", + [3]byte{0, 224, 129}: "TYAN COMPUTER CORP.", + [3]byte{0, 224, 130}: "ANERMA", + [3]byte{0, 224, 131}: "JATO TECHNOLOGIES, INC.", + [3]byte{0, 224, 132}: "COMPULITE R&D", + [3]byte{0, 224, 133}: "GLOBAL MAINTECH, INC.", + [3]byte{0, 224, 134}: "Emerson Network Power, Avocent Division", + [3]byte{0, 224, 135}: "LeCroy - Networking Productions Division", + [3]byte{0, 224, 136}: "LTX-Credence CORPORATION", + [3]byte{0, 224, 137}: "ION Networks, Inc.", + [3]byte{0, 224, 138}: "GEC AVERY, LTD.", + [3]byte{0, 224, 139}: "QLogic Corp.", + [3]byte{0, 224, 140}: "NEOPARADIGM LABS, INC.", + [3]byte{0, 224, 141}: "PRESSURE SYSTEMS, INC.", + [3]byte{0, 224, 142}: "UTSTARCOM", + [3]byte{0, 224, 143}: "CISCO SYSTEMS, INC.", + [3]byte{0, 224, 144}: "BECKMAN LAB. AUTOMATION DIV.", + [3]byte{0, 224, 145}: "LG ELECTRONICS, INC.", + [3]byte{0, 224, 146}: "ADMTEK INCORPORATED", + [3]byte{0, 224, 147}: "ACKFIN NETWORKS", + [3]byte{0, 224, 148}: "OSAI SRL", + [3]byte{0, 224, 149}: "ADVANCED-VISION TECHNOLGIES CORP.", + [3]byte{0, 224, 150}: "SHIMADZU CORPORATION", + [3]byte{0, 224, 151}: "CARRIER ACCESS CORPORATION", + [3]byte{0, 224, 152}: "AboCom Systems, Inc.", + [3]byte{0, 224, 153}: "SAMSON AG", + [3]byte{0, 224, 154}: "Positron Inc.", + [3]byte{0, 224, 155}: "ENGAGE NETWORKS, INC.", + [3]byte{0, 224, 156}: "MII", + [3]byte{0, 224, 157}: "SARNOFF CORPORATION", + [3]byte{0, 224, 158}: "QUANTUM CORPORATION", + [3]byte{0, 224, 159}: "PIXEL VISION", + [3]byte{0, 224, 160}: "WILTRON CO.", + [3]byte{0, 224, 161}: "HIMA PAUL HILDEBRANDT GmbH Co. KG", + [3]byte{0, 224, 162}: "MICROSLATE INC.", + [3]byte{0, 224, 163}: "CISCO SYSTEMS, INC.", + [3]byte{0, 224, 164}: "ESAOTE S.p.A.", + [3]byte{0, 224, 165}: "ComCore Semiconductor, Inc.", + [3]byte{0, 224, 166}: "TELOGY NETWORKS, INC.", + [3]byte{0, 224, 167}: "IPC INFORMATION SYSTEMS, INC.", + [3]byte{0, 224, 168}: "SAT GmbH & Co.", + [3]byte{0, 224, 169}: "FUNAI ELECTRIC CO., LTD.", + [3]byte{0, 224, 170}: "ELECTROSONIC LTD.", + [3]byte{0, 224, 171}: "DIMAT S.A.", + [3]byte{0, 224, 172}: "MIDSCO, INC.", + [3]byte{0, 224, 173}: "EES TECHNOLOGY, LTD.", + [3]byte{0, 224, 174}: "XAQTI CORPORATION", + [3]byte{0, 224, 175}: "GENERAL DYNAMICS INFORMATION SYSTEMS", + [3]byte{0, 224, 176}: "CISCO SYSTEMS, INC.", + [3]byte{0, 224, 177}: "Alcatel-Lucent, Enterprise Business Group", + [3]byte{0, 224, 178}: "TELMAX COMMUNICATIONS CORP.", + [3]byte{0, 224, 179}: "EtherWAN Systems, Inc.", + [3]byte{0, 224, 180}: "TECHNO SCOPE CO., LTD.", + [3]byte{0, 224, 181}: "ARDENT COMMUNICATIONS CORP.", + [3]byte{0, 224, 182}: "Entrada Networks", + [3]byte{0, 224, 183}: "PI GROUP, LTD.", + [3]byte{0, 224, 184}: "GATEWAY 2000", + [3]byte{0, 224, 185}: "BYAS SYSTEMS", + [3]byte{0, 224, 186}: "BERGHOF AUTOMATIONSTECHNIK GmbH", + [3]byte{0, 224, 187}: "NBX CORPORATION", + [3]byte{0, 224, 188}: "SYMON COMMUNICATIONS, INC.", + [3]byte{0, 224, 189}: "INTERFACE SYSTEMS, INC.", + [3]byte{0, 224, 190}: "GENROCO INTERNATIONAL, INC.", + [3]byte{0, 224, 191}: "TORRENT NETWORKING TECHNOLOGIES CORP.", + [3]byte{0, 224, 192}: "SEIWA ELECTRIC MFG. CO., LTD.", + [3]byte{0, 224, 193}: "MEMOREX TELEX JAPAN, LTD.", + [3]byte{0, 224, 194}: "NECSY S.p.A.", + [3]byte{0, 224, 195}: "SAKAI SYSTEM DEVELOPMENT CORP.", + [3]byte{0, 224, 196}: "HORNER ELECTRIC, INC.", + [3]byte{0, 224, 197}: "BCOM ELECTRONICS INC.", + [3]byte{0, 224, 198}: "LINK2IT, L.L.C.", + [3]byte{0, 224, 199}: "EUROTECH SRL", + [3]byte{0, 224, 200}: "VIRTUAL ACCESS, LTD.", + [3]byte{0, 224, 201}: "AutomatedLogic Corporation", + [3]byte{0, 224, 202}: "BEST DATA PRODUCTS", + [3]byte{0, 224, 203}: "RESON, INC.", + [3]byte{0, 224, 204}: "HERO SYSTEMS, LTD.", + [3]byte{0, 224, 205}: "SAAB SENSIS CORPORATION", + [3]byte{0, 224, 206}: "ARN", + [3]byte{0, 224, 207}: "INTEGRATED DEVICE TECHNOLOGY, INC.", + [3]byte{0, 224, 208}: "NETSPEED, INC.", + [3]byte{0, 224, 209}: "TELSIS LIMITED", + [3]byte{0, 224, 210}: "VERSANET COMMUNICATIONS, INC.", + [3]byte{0, 224, 211}: "DATENTECHNIK GmbH", + [3]byte{0, 224, 212}: "EXCELLENT COMPUTER", + [3]byte{0, 224, 213}: "Emulex Corporation", + [3]byte{0, 224, 214}: "COMPUTER & COMMUNICATION RESEARCH LAB.", + [3]byte{0, 224, 215}: "SUNSHINE ELECTRONICS, INC.", + [3]byte{0, 224, 216}: "LANBit Computer, Inc.", + [3]byte{0, 224, 217}: "TAZMO CO., LTD.", + [3]byte{0, 224, 218}: "Alcatel North America ESD", + [3]byte{0, 224, 219}: "ViaVideo Communications, Inc.", + [3]byte{0, 224, 220}: "NEXWARE CORP.", + [3]byte{0, 224, 221}: "ZENITH ELECTRONICS CORPORATION", + [3]byte{0, 224, 222}: "DATAX NV", + [3]byte{0, 224, 223}: "KEYMILE GmbH", + [3]byte{0, 224, 224}: "SI ELECTRONICS, LTD.", + [3]byte{0, 224, 225}: "G2 NETWORKS, INC.", + [3]byte{0, 224, 226}: "INNOVA CORP.", + [3]byte{0, 224, 227}: "SK-ELEKTRONIK GmbH", + [3]byte{0, 224, 228}: "FANUC ROBOTICS NORTH AMERICA, Inc.", + [3]byte{0, 224, 229}: "CINCO NETWORKS, INC.", + [3]byte{0, 224, 230}: "INCAA DATACOM B.V.", + [3]byte{0, 224, 231}: "RAYTHEON E-SYSTEMS, INC.", + [3]byte{0, 224, 232}: "GRETACODER Data Systems AG", + [3]byte{0, 224, 233}: "DATA LABS, INC.", + [3]byte{0, 224, 234}: "INNOVAT COMMUNICATIONS, INC.", + [3]byte{0, 224, 235}: "DIGICOM SYSTEMS, INCORPORATED", + [3]byte{0, 224, 236}: "CELESTICA INC.", + [3]byte{0, 224, 237}: "SILICOM, LTD.", + [3]byte{0, 224, 238}: "MAREL HF", + [3]byte{0, 224, 239}: "DIONEX", + [3]byte{0, 224, 240}: "ABLER TECHNOLOGY, INC.", + [3]byte{0, 224, 241}: "THAT CORPORATION", + [3]byte{0, 224, 242}: "ARLOTTO COMNET, INC.", + [3]byte{0, 224, 243}: "WebSprint Communications, Inc.", + [3]byte{0, 224, 244}: "INSIDE Technology A/S", + [3]byte{0, 224, 245}: "TELES AG", + [3]byte{0, 224, 246}: "DECISION EUROPE", + [3]byte{0, 224, 247}: "CISCO SYSTEMS, INC.", + [3]byte{0, 224, 248}: "DICNA CONTROL AB", + [3]byte{0, 224, 249}: "CISCO SYSTEMS, INC.", + [3]byte{0, 224, 250}: "TRL TECHNOLOGY, LTD.", + [3]byte{0, 224, 251}: "LEIGHTRONIX, INC.", + [3]byte{0, 224, 252}: "HUAWEI TECHNOLOGIES CO., LTD.", + [3]byte{0, 224, 253}: "A-TREND TECHNOLOGY CO., LTD.", + [3]byte{0, 224, 254}: "CISCO SYSTEMS, INC.", + [3]byte{0, 224, 255}: "SECURITY DYNAMICS TECHNOLOGIES, Inc.", + [3]byte{0, 225, 109}: "Cisco", + [3]byte{0, 225, 117}: "AK-Systems Ltd", + [3]byte{0, 227, 178}: "Samsung Electronics Co.,Ltd", + [3]byte{0, 230, 102}: "ARIMA Communications Corp.", + [3]byte{0, 230, 211}: "NIXDORF COMPUTER CORP.", + [3]byte{0, 230, 232}: "Netzin Technology Corporation,.Ltd.", + [3]byte{0, 232, 171}: "Meggitt Training Systems, Inc.", + [3]byte{0, 235, 45}: "Sony Mobile Communications AB", + [3]byte{0, 238, 189}: "HTC Corporation", + [3]byte{0, 240, 81}: "KWB Gmbh", + [3]byte{0, 243, 219}: "WOO Sports", + [3]byte{0, 244, 3}: "Orbis Systems Oy", + [3]byte{0, 244, 111}: "Samsung Elec Co.,Ltd", + [3]byte{0, 244, 185}: "Apple", + [3]byte{0, 247, 111}: "Apple", + [3]byte{0, 248, 96}: "PT. Panggung Electric Citrabuana", + [3]byte{0, 250, 59}: "CLOOS ELECTRONIC GMBH", + [3]byte{0, 252, 88}: "WebSilicon Ltd.", + [3]byte{0, 252, 112}: "Intrepid Control Systems, Inc.", + [3]byte{0, 253, 76}: "NEVATEC", + [3]byte{2, 7, 1}: "RACAL-DATACOM", + [3]byte{2, 28, 124}: "PERQ SYSTEMS CORPORATION", + [3]byte{2, 96, 134}: "LOGIC REPLACEMENT TECH. LTD.", + [3]byte{2, 96, 140}: "3COM CORPORATION", + [3]byte{2, 112, 1}: "RACAL-DATACOM", + [3]byte{2, 112, 176}: "M/A-COM INC. COMPANIES", + [3]byte{2, 112, 179}: "DATA RECALL LTD", + [3]byte{2, 157, 142}: "CARDIAC RECORDERS INC.", + [3]byte{2, 170, 60}: "OLIVETTI TELECOMM SPA (OLTECO)", + [3]byte{2, 187, 1}: "OCTOTHORPE CORP.", + [3]byte{2, 192, 140}: "3COM CORPORATION", + [3]byte{2, 207, 28}: "COMMUNICATION MACHINERY CORP.", + [3]byte{2, 230, 211}: "NIXDORF COMPUTER CORPORATION", + [3]byte{4, 10, 131}: "Alcatel-Lucent", + [3]byte{4, 10, 224}: "XMIT AG COMPUTER NETWORKS", + [3]byte{4, 12, 206}: "Apple", + [3]byte{4, 14, 194}: "ViewSonic Mobile China Limited", + [3]byte{4, 21, 82}: "Apple", + [3]byte{4, 24, 15}: "Samsung Electronics Co.,Ltd", + [3]byte{4, 24, 182}: "PRIVATE", + [3]byte{4, 24, 214}: "Ubiquiti Networks", + [3]byte{4, 26, 4}: "WaveIP", + [3]byte{4, 27, 148}: "Host Mobility AB", + [3]byte{4, 27, 186}: "Samsung Electronics Co.,Ltd", + [3]byte{4, 29, 16}: "Dream Ware Inc.", + [3]byte{4, 30, 100}: "Apple", + [3]byte{4, 32, 154}: "Panasonic AVC Networks Company", + [3]byte{4, 34, 52}: "Wireless Standard Extensions", + [3]byte{4, 38, 5}: "GFR Gesellschaft für Regelungstechnik und Energieeinsparung mbH", + [3]byte{4, 38, 101}: "Apple", + [3]byte{4, 43, 187}: "PicoCELA, Inc.", + [3]byte{4, 47, 86}: "ATOCS (Shenzhen) LTD", + [3]byte{4, 50, 244}: "Partron", + [3]byte{4, 54, 4}: "Gyeyoung I&T", + [3]byte{4, 61, 152}: "ChongQing QingJia Electronics CO.,LTD", + [3]byte{4, 68, 161}: "TELECON GALICIA,S.A.", + [3]byte{4, 70, 101}: "Murata Manufacturing Co., Ltd.", + [3]byte{4, 72, 154}: "Apple", + [3]byte{4, 74, 80}: "Ramaxel Technology (Shenzhen) limited company", + [3]byte{4, 75, 255}: "GuangZhou Hedy Digital Technology Co., Ltd", + [3]byte{4, 76, 239}: "Fujian Sanao Technology Co.,Ltd", + [3]byte{4, 78, 6}: "Ericsson AB", + [3]byte{4, 79, 139}: "Adapteva, Inc.", + [3]byte{4, 79, 170}: "Ruckus Wireless", + [3]byte{4, 84, 83}: "Apple", + [3]byte{4, 85, 202}: "BriView (Xiamen) Corp.", + [3]byte{4, 87, 47}: "Sertel Electronics UK Ltd", + [3]byte{4, 88, 111}: "Sichuan Whayer information industry Co.,LTD", + [3]byte{4, 90, 149}: "Nokia Corporation", + [3]byte{4, 92, 6}: "Zmodo Technology Corporation", + [3]byte{4, 92, 142}: "gosund GROUP CO.,LTD", + [3]byte{4, 93, 86}: "camtron industrial inc.", + [3]byte{4, 95, 167}: "Shenzhen Yichen Technology Development Co.,LTD", + [3]byte{4, 98, 215}: "ALSTOM HYDRO FRANCE", + [3]byte{4, 99, 224}: "Nome Oy", + [3]byte{4, 103, 133}: "scemtec Hard- und Software fuer Mess- und Steuerungstechnik GmbH", + [3]byte{4, 109, 66}: "Bryston Ltd.", + [3]byte{4, 110, 73}: "TaiYear Electronic Technology (Suzhou) Co., Ltd", + [3]byte{4, 112, 188}: "Globalstar Inc.", + [3]byte{4, 116, 161}: "Aligera Equipamentos Digitais Ltda", + [3]byte{4, 117, 245}: "CSST", + [3]byte{4, 118, 110}: "ALPS Co,. Ltd.", + [3]byte{4, 125, 123}: "Quanta Computer Inc.", + [3]byte{4, 129, 174}: "Clack Corporation", + [3]byte{4, 132, 138}: "7INOVA TECHNOLOGY LIMITED", + [3]byte{4, 136, 140}: "Eifelwerk Butler Systeme GmbH", + [3]byte{4, 136, 226}: "Beats Electronics LLC", + [3]byte{4, 138, 21}: "Avaya, Inc", + [3]byte{4, 139, 66}: "Skspruce Technology Limited", + [3]byte{4, 140, 3}: "ThinPAD Technology (Shenzhen)CO.,LTD", + [3]byte{4, 141, 56}: "Netcore Technology Inc.", + [3]byte{4, 148, 161}: "CATCH THE WIND INC", + [3]byte{4, 152, 243}: "ALPS Electric Co,. Ltd.", + [3]byte{4, 153, 230}: "Shenzhen Yoostar Technology Co., Ltd", + [3]byte{4, 155, 156}: "Eadingcore Intelligent Technology Co., Ltd.", + [3]byte{4, 156, 98}: "BMT Medical Technology s.r.o.", + [3]byte{4, 159, 6}: "Smobile Co., Ltd.", + [3]byte{4, 159, 129}: "Netscout Systems, Inc.", + [3]byte{4, 161, 81}: "NETGEAR INC.,", + [3]byte{4, 163, 243}: "Emicon", + [3]byte{4, 168, 42}: "Nokia Corporation", + [3]byte{4, 179, 182}: "Seamap (UK) Ltd", + [3]byte{4, 180, 102}: "BSP Co., Ltd.", + [3]byte{4, 189, 112}: "HUAWEI TECHNOLOGIES CO.,LTD", + [3]byte{4, 191, 168}: "ISB Corporation", + [3]byte{4, 192, 91}: "Tigo Energy", + [3]byte{4, 192, 111}: "Shenzhen Huawei Communication Technologies Co., Ltd", + [3]byte{4, 192, 156}: "Tellabs Inc.", + [3]byte{4, 193, 185}: "Fiberhome Telecommunication Tech.Co.,Ltd.", + [3]byte{4, 197, 164}: "CISCO SYSTEMS, INC.", + [3]byte{4, 200, 128}: "Samtec Inc", + [3]byte{4, 201, 145}: "Phistek INC.", + [3]byte{4, 203, 29}: "Traka plc", + [3]byte{4, 206, 20}: "Wilocity LTD.", + [3]byte{4, 207, 37}: "MANYCOLORS, INC.", + [3]byte{4, 212, 55}: "ZNV", + [3]byte{4, 215, 131}: "Y&H E&C Co.,LTD.", + [3]byte{4, 218, 210}: "Cisco", + [3]byte{4, 219, 86}: "Apple, Inc.", + [3]byte{4, 219, 138}: "Suntech International Ltd.", + [3]byte{4, 221, 76}: "Velocytech", + [3]byte{4, 222, 219}: "Rockport Networks Inc", + [3]byte{4, 223, 105}: "Car Connectivity Consortium", + [3]byte{4, 224, 196}: "TRIUMPH-ADLER AG", + [3]byte{4, 225, 200}: "IMS Soluções em Energia Ltda.", + [3]byte{4, 226, 248}: "AEP Ticketing solutions srl", + [3]byte{4, 228, 81}: "Texas Instruments", + [3]byte{4, 229, 54}: "Apple", + [3]byte{4, 229, 72}: "Cohda Wireless Pty Ltd", + [3]byte{4, 230, 98}: "Acroname Inc.", + [3]byte{4, 230, 118}: "AMPAK Technology Inc.", + [3]byte{4, 233, 229}: "PJRC.COM, LLC", + [3]byte{4, 238, 145}: "x-fabric GmbH", + [3]byte{4, 240, 33}: "Compex Systems Pte Ltd", + [3]byte{4, 241, 62}: "Apple", + [3]byte{4, 241, 125}: "Tarana Wireless", + [3]byte{4, 244, 188}: "Xena Networks", + [3]byte{4, 247, 228}: "Apple", + [3]byte{4, 248, 194}: "Flaircomm Microelectronics, Inc.", + [3]byte{4, 249, 56}: "HUAWEI TECHNOLOGIES CO.,LTD", + [3]byte{4, 254, 49}: "Samsung Electronics Co.,Ltd", + [3]byte{4, 254, 127}: "CISCO SYSTEMS, INC.", + [3]byte{4, 255, 81}: "NOVAMEDIA INNOVISION SP. Z O.O.", + [3]byte{8, 0, 1}: "COMPUTERVISION CORPORATION", + [3]byte{8, 0, 2}: "BRIDGE COMMUNICATIONS INC.", + [3]byte{8, 0, 3}: "ADVANCED COMPUTER COMM.", + [3]byte{8, 0, 4}: "CROMEMCO INCORPORATED", + [3]byte{8, 0, 5}: "SYMBOLICS INC.", + [3]byte{8, 0, 6}: "SIEMENS AG", + [3]byte{8, 0, 7}: "Apple", + [3]byte{8, 0, 8}: "BOLT BERANEK AND NEWMAN INC.", + [3]byte{8, 0, 9}: "HEWLETT PACKARD", + [3]byte{8, 0, 10}: "NESTAR SYSTEMS INCORPORATED", + [3]byte{8, 0, 11}: "UNISYS CORPORATION", + [3]byte{8, 0, 12}: "MIKLYN DEVELOPMENT CO.", + [3]byte{8, 0, 13}: "INTERNATIONAL COMPUTERS LTD.", + [3]byte{8, 0, 14}: "NCR CORPORATION", + [3]byte{8, 0, 15}: "MITEL CORPORATION", + [3]byte{8, 0, 17}: "TEKTRONIX INC.", + [3]byte{8, 0, 18}: "BELL ATLANTIC INTEGRATED SYST.", + [3]byte{8, 0, 19}: "EXXON", + [3]byte{8, 0, 20}: "EXCELAN", + [3]byte{8, 0, 21}: "STC BUSINESS SYSTEMS", + [3]byte{8, 0, 22}: "BARRISTER INFO SYS CORP", + [3]byte{8, 0, 23}: "NATIONAL SEMICONDUCTOR", + [3]byte{8, 0, 24}: "PIRELLI FOCOM NETWORKS", + [3]byte{8, 0, 25}: "GENERAL ELECTRIC CORPORATION", + [3]byte{8, 0, 26}: "TIARA/ 10NET", + [3]byte{8, 0, 27}: "EMC Corporation", + [3]byte{8, 0, 28}: "KDD-KOKUSAI DEBNSIN DENWA CO.", + [3]byte{8, 0, 29}: "ABLE COMMUNICATIONS INC.", + [3]byte{8, 0, 30}: "APOLLO COMPUTER INC.", + [3]byte{8, 0, 31}: "SHARP CORPORATION", + [3]byte{8, 0, 32}: "Oracle Corporation", + [3]byte{8, 0, 33}: "3M COMPANY", + [3]byte{8, 0, 34}: "NBI INC.", + [3]byte{8, 0, 35}: "Panasonic Communications Co., Ltd.", + [3]byte{8, 0, 36}: "10NET COMMUNICATIONS/DCA", + [3]byte{8, 0, 37}: "CONTROL DATA", + [3]byte{8, 0, 38}: "NORSK DATA A.S.", + [3]byte{8, 0, 39}: "CADMUS COMPUTER SYSTEMS", + [3]byte{8, 0, 40}: "Texas Instruments", + [3]byte{8, 0, 41}: "MEGATEK CORPORATION", + [3]byte{8, 0, 42}: "MOSAIC TECHNOLOGIES INC.", + [3]byte{8, 0, 43}: "DIGITAL EQUIPMENT CORPORATION", + [3]byte{8, 0, 44}: "BRITTON LEE INC.", + [3]byte{8, 0, 45}: "LAN-TEC INC.", + [3]byte{8, 0, 46}: "METAPHOR COMPUTER SYSTEMS", + [3]byte{8, 0, 47}: "PRIME COMPUTER INC.", + [3]byte{8, 0, 48}: "NETWORK RESEARCH CORPORATION", + [3]byte{8, 0, 48}: "CERN", + [3]byte{8, 0, 48}: "ROYAL MELBOURNE INST OF TECH", + [3]byte{8, 0, 49}: "LITTLE MACHINES INC.", + [3]byte{8, 0, 50}: "TIGAN INCORPORATED", + [3]byte{8, 0, 51}: "BAUSCH & LOMB", + [3]byte{8, 0, 52}: "FILENET CORPORATION", + [3]byte{8, 0, 53}: "MICROFIVE CORPORATION", + [3]byte{8, 0, 54}: "INTERGRAPH CORPORATION", + [3]byte{8, 0, 55}: "FUJI-XEROX CO. LTD.", + [3]byte{8, 0, 56}: "BULL S.A.S.", + [3]byte{8, 0, 57}: "SPIDER SYSTEMS LIMITED", + [3]byte{8, 0, 58}: "ORCATECH INC.", + [3]byte{8, 0, 59}: "TORUS SYSTEMS LIMITED", + [3]byte{8, 0, 60}: "SCHLUMBERGER WELL SERVICES", + [3]byte{8, 0, 61}: "CADNETIX CORPORATIONS", + [3]byte{8, 0, 62}: "CODEX CORPORATION", + [3]byte{8, 0, 63}: "FRED KOSCHARA ENTERPRISES", + [3]byte{8, 0, 64}: "FERRANTI COMPUTER SYS. LIMITED", + [3]byte{8, 0, 65}: "RACAL-MILGO INFORMATION SYS..", + [3]byte{8, 0, 66}: "JAPAN MACNICS CORP.", + [3]byte{8, 0, 67}: "PIXEL COMPUTER INC.", + [3]byte{8, 0, 68}: "DAVID SYSTEMS INC.", + [3]byte{8, 0, 69}: "CONCURRENT COMPUTER CORP.", + [3]byte{8, 0, 70}: "Sony Corporation", + [3]byte{8, 0, 71}: "SEQUENT COMPUTER SYSTEMS INC.", + [3]byte{8, 0, 72}: "EUROTHERM GAUGING SYSTEMS", + [3]byte{8, 0, 73}: "UNIVATION", + [3]byte{8, 0, 74}: "BANYAN SYSTEMS INC.", + [3]byte{8, 0, 75}: "PLANNING RESEARCH CORP.", + [3]byte{8, 0, 76}: "HYDRA COMPUTER SYSTEMS INC.", + [3]byte{8, 0, 77}: "CORVUS SYSTEMS INC.", + [3]byte{8, 0, 78}: "3COM EUROPE LTD.", + [3]byte{8, 0, 79}: "CYGNET SYSTEMS", + [3]byte{8, 0, 80}: "DAISY SYSTEMS CORP.", + [3]byte{8, 0, 81}: "EXPERDATA", + [3]byte{8, 0, 82}: "INSYSTEC", + [3]byte{8, 0, 83}: "MIDDLE EAST TECH. UNIVERSITY", + [3]byte{8, 0, 85}: "STANFORD TELECOMM. INC.", + [3]byte{8, 0, 86}: "STANFORD LINEAR ACCEL. CENTER", + [3]byte{8, 0, 87}: "EVANS & SUTHERLAND", + [3]byte{8, 0, 88}: "SYSTEMS CONCEPTS", + [3]byte{8, 0, 89}: "A/S MYCRON", + [3]byte{8, 0, 90}: "IBM Corp", + [3]byte{8, 0, 91}: "VTA TECHNOLOGIES INC.", + [3]byte{8, 0, 92}: "FOUR PHASE SYSTEMS", + [3]byte{8, 0, 93}: "GOULD INC.", + [3]byte{8, 0, 94}: "COUNTERPOINT COMPUTER INC.", + [3]byte{8, 0, 95}: "SABER TECHNOLOGY CORP.", + [3]byte{8, 0, 96}: "INDUSTRIAL NETWORKING INC.", + [3]byte{8, 0, 97}: "JAROGATE LTD.", + [3]byte{8, 0, 98}: "GENERAL DYNAMICS", + [3]byte{8, 0, 99}: "PLESSEY", + [3]byte{8, 0, 100}: "Sitasys AG", + [3]byte{8, 0, 101}: "GENRAD INC.", + [3]byte{8, 0, 102}: "AGFA CORPORATION", + [3]byte{8, 0, 103}: "COMDESIGN", + [3]byte{8, 0, 104}: "RIDGE COMPUTERS", + [3]byte{8, 0, 105}: "SILICON GRAPHICS INC.", + [3]byte{8, 0, 106}: "ATT BELL LABORATORIES", + [3]byte{8, 0, 107}: "ACCEL TECHNOLOGIES INC.", + [3]byte{8, 0, 108}: "SUNTEK TECHNOLOGY INT'L", + [3]byte{8, 0, 109}: "WHITECHAPEL COMPUTER WORKS", + [3]byte{8, 0, 110}: "MASSCOMP", + [3]byte{8, 0, 111}: "PHILIPS APELDOORN B.V.", + [3]byte{8, 0, 112}: "MITSUBISHI ELECTRIC CORP.", + [3]byte{8, 0, 113}: "MATRA (DSIE)", + [3]byte{8, 0, 114}: "XEROX CORP UNIV GRANT PROGRAM", + [3]byte{8, 0, 115}: "TECMAR INC.", + [3]byte{8, 0, 116}: "CASIO COMPUTER CO. LTD.", + [3]byte{8, 0, 117}: "DANSK DATA ELECTRONIK", + [3]byte{8, 0, 118}: "PC LAN TECHNOLOGIES", + [3]byte{8, 0, 119}: "TSL COMMUNICATIONS LTD.", + [3]byte{8, 0, 120}: "ACCELL CORPORATION", + [3]byte{8, 0, 121}: "THE DROID WORKS", + [3]byte{8, 0, 122}: "INDATA", + [3]byte{8, 0, 123}: "SANYO ELECTRIC CO. LTD.", + [3]byte{8, 0, 124}: "VITALINK COMMUNICATIONS CORP.", + [3]byte{8, 0, 126}: "AMALGAMATED WIRELESS(AUS) LTD", + [3]byte{8, 0, 127}: "CARNEGIE-MELLON UNIVERSITY", + [3]byte{8, 0, 128}: "AES DATA INC.", + [3]byte{8, 0, 129}: "ASTECH INC.", + [3]byte{8, 0, 130}: "VERITAS SOFTWARE", + [3]byte{8, 0, 131}: "Seiko Instruments Inc.", + [3]byte{8, 0, 132}: "TOMEN ELECTRONICS CORP.", + [3]byte{8, 0, 133}: "ELXSI", + [3]byte{8, 0, 134}: "KONICA MINOLTA HOLDINGS, INC.", + [3]byte{8, 0, 135}: "XYPLEX", + [3]byte{8, 0, 136}: "Brocade Communications Systems, Inc.", + [3]byte{8, 0, 137}: "KINETICS", + [3]byte{8, 0, 138}: "PerfTech, Inc.", + [3]byte{8, 0, 139}: "PYRAMID TECHNOLOGY CORP.", + [3]byte{8, 0, 140}: "NETWORK RESEARCH CORPORATION", + [3]byte{8, 0, 141}: "XYVISION INC.", + [3]byte{8, 0, 142}: "TANDEM COMPUTERS", + [3]byte{8, 0, 143}: "CHIPCOM CORPORATION", + [3]byte{8, 0, 144}: "SONOMA SYSTEMS", + [3]byte{8, 3, 113}: "KRG CORPORATE", + [3]byte{8, 5, 205}: "DongGuang EnMai Electronic Product Co.Ltd.", + [3]byte{8, 8, 194}: "Samsung Electronics", + [3]byte{8, 8, 234}: "AMSC", + [3]byte{8, 9, 182}: "Masimo Corp", + [3]byte{8, 12, 11}: "SysMik GmbH Dresden", + [3]byte{8, 12, 201}: "Mission Technology Group, dba Magma", + [3]byte{8, 13, 132}: "GECO, Inc.", + [3]byte{8, 14, 168}: "Velex s.r.l.", + [3]byte{8, 15, 250}: "KSP INC.", + [3]byte{8, 17, 94}: "Bitel Co., Ltd.", + [3]byte{8, 17, 150}: "Intel Corporate", + [3]byte{8, 20, 67}: "UNIBRAIN S.A.", + [3]byte{8, 22, 81}: "Shenzhen Sea Star Technology Co.,Ltd", + [3]byte{8, 23, 53}: "CISCO SYSTEMS, INC.", + [3]byte{8, 23, 244}: "IBM Corp", + [3]byte{8, 24, 26}: "zte corporation", + [3]byte{8, 24, 76}: "A. S. Thomas, Inc.", + [3]byte{8, 25, 166}: "HUAWEI TECHNOLOGIES CO.,LTD", + [3]byte{8, 29, 251}: "Shanghai Mexon Communication Technology Co.,Ltd", + [3]byte{8, 31, 63}: "WondaLink Inc.", + [3]byte{8, 31, 243}: "CISCO SYSTEMS, INC.", + [3]byte{8, 37, 34}: "ADVANSEE", + [3]byte{8, 39, 25}: "APS systems/electronic AG", + [3]byte{8, 42, 208}: "SRD Innovations Inc.", + [3]byte{8, 46, 95}: "Hewlett Packard", + [3]byte{8, 53, 113}: "CASwell INC.", + [3]byte{8, 55, 61}: "Samsung Electronics Co.,Ltd", + [3]byte{8, 55, 156}: "Topaz Co. LTD.", + [3]byte{8, 56, 165}: "Funkwerk plettac electronic GmbH", + [3]byte{8, 58, 184}: "Shinoda Plasma Co., Ltd.", + [3]byte{8, 61, 136}: "Samsung Electronics Co.,Ltd", + [3]byte{8, 62, 12}: "ARRIS Group, Inc.", + [3]byte{8, 62, 142}: "Hon Hai Precision Ind.Co.Ltd", + [3]byte{8, 63, 62}: "WSH GmbH", + [3]byte{8, 63, 118}: "Intellian Technologies, Inc.", + [3]byte{8, 64, 39}: "Gridstore Inc.", + [3]byte{8, 70, 86}: "VODALYS Ingénierie", + [3]byte{8, 72, 44}: "Raycore Taiwan Co., LTD.", + [3]byte{8, 78, 28}: "H2A Systems, LLC", + [3]byte{8, 78, 191}: "Broad Net Mux Corporation", + [3]byte{8, 81, 46}: "Orion Diagnostica Oy", + [3]byte{8, 82, 64}: "EbV Elektronikbau- und Vertriebs GmbH", + [3]byte{8, 87, 0}: "TP-LINK TECHNOLOGIES CO.,LTD.", + [3]byte{8, 90, 224}: "Recovision Technology Co., Ltd.", + [3]byte{8, 91, 14}: "Fortinet, Inc.", + [3]byte{8, 93, 221}: "Mercury Corporation", + [3]byte{8, 96, 110}: "ASUSTek COMPUTER INC.", + [3]byte{8, 99, 97}: "Huawei Technologies Co., Ltd", + [3]byte{8, 104, 208}: "Japan System Design", + [3]byte{8, 104, 234}: "EITO ELECTRONICS CO., LTD.", + [3]byte{8, 109, 242}: "Shenzhen MIMOWAVE Technology Co.,Ltd", + [3]byte{8, 112, 69}: "Apple", + [3]byte{8, 116, 246}: "Winterhalter Gastronom GmbH", + [3]byte{8, 117, 114}: "Obelux Oy", + [3]byte{8, 118, 24}: "ViE Technologies Sdn. Bhd.", + [3]byte{8, 118, 149}: "Auto Industrial Co., Ltd.", + [3]byte{8, 118, 255}: "Thomson Telecom Belgium", + [3]byte{8, 121, 153}: "AIM GmbH", + [3]byte{8, 122, 76}: "Huawei Technologies Co., Ltd", + [3]byte{8, 123, 170}: "SVYAZKOMPLEKTSERVICE, LLC", + [3]byte{8, 124, 190}: "Quintic Corp.", + [3]byte{8, 125, 33}: "Altasec technology corporation", + [3]byte{8, 128, 57}: "Cisco SPVTG", + [3]byte{8, 129, 188}: "HongKong Ipro Technology Co., Limited", + [3]byte{8, 129, 244}: "Juniper Networks", + [3]byte{8, 134, 59}: "Belkin International, Inc.", + [3]byte{8, 141, 200}: "Ryowa Electronics Co.,Ltd", + [3]byte{8, 142, 79}: "SF Software Solutions", + [3]byte{8, 143, 44}: "Hills Sound Vision & Lighting", + [3]byte{8, 150, 215}: "AVM GmbH", + [3]byte{8, 151, 88}: "Shenzhen Strong Rising Electronics Co.,Ltd DongGuan Subsidiary", + [3]byte{8, 158, 1}: "QUANTA COMPUTER INC.", + [3]byte{8, 159, 151}: "LEROY AUTOMATION", + [3]byte{8, 161, 43}: "ShenZhen EZL Technology Co., Ltd", + [3]byte{8, 165, 200}: "Sunnovo International Limited", + [3]byte{8, 169, 90}: "Azurewave", + [3]byte{8, 172, 165}: "Benu Video, Inc.", + [3]byte{8, 175, 120}: "Totus Solutions, Inc.", + [3]byte{8, 178, 163}: "Cynny Italia S.r.L.", + [3]byte{8, 180, 207}: "Abicom International", + [3]byte{8, 183, 56}: "Lite-On Technogy Corp.", + [3]byte{8, 183, 236}: "Wireless Seismic", + [3]byte{8, 187, 204}: "AK-NORD EDV VERTRIEBSGES. mbH", + [3]byte{8, 189, 67}: "NETGEAR INC.,", + [3]byte{8, 190, 9}: "Astrol Electronic AG", + [3]byte{8, 202, 69}: "Toyou Feiji Electronics Co., Ltd.", + [3]byte{8, 204, 104}: "Cisco", + [3]byte{8, 205, 155}: "samtec automotive electronics & software GmbH", + [3]byte{8, 208, 159}: "CISCO SYSTEMS, INC.", + [3]byte{8, 210, 154}: "Proformatique", + [3]byte{8, 212, 12}: "Intel Corporate", + [3]byte{8, 212, 43}: "Samsung Electronics", + [3]byte{8, 213, 192}: "Seers Technology Co., Ltd", + [3]byte{8, 216, 51}: "Shenzhen RF Technology Co,.Ltd", + [3]byte{8, 223, 31}: "Bose Corporation", + [3]byte{8, 229, 218}: "NANJING FUJITSU COMPUTER PRODUCTS CO.,LTD.", + [3]byte{8, 230, 114}: "JEBSEE ELECTRONICS CO.,LTD.", + [3]byte{8, 232, 79}: "HUAWEI TECHNOLOGIES CO.,LTD", + [3]byte{8, 234, 68}: "Aerohive Networks, Inc.", + [3]byte{8, 235, 41}: "Jiangsu Huitong Group Co.,Ltd.", + [3]byte{8, 235, 116}: "Humax", + [3]byte{8, 235, 237}: "World Elite Technology Co.,LTD", + [3]byte{8, 237, 185}: "Hon Hai Precision Ind. Co.,Ltd.", + [3]byte{8, 238, 139}: "Samsung Elec Co.,Ltd", + [3]byte{8, 239, 59}: "MCS Logic Inc.", + [3]byte{8, 239, 171}: "SAYME WIRELESS SENSOR NETWORK", + [3]byte{8, 241, 183}: "Towerstream Corpration", + [3]byte{8, 242, 244}: "Net One Partners Co.,Ltd.", + [3]byte{8, 246, 248}: "GET Engineering", + [3]byte{8, 247, 40}: "GLOBO Multimedia Sp. z o.o. Sp.k.", + [3]byte{8, 250, 224}: "Fohhn Audio AG", + [3]byte{8, 252, 82}: "OpenXS BV", + [3]byte{8, 252, 136}: "Samsung Electronics Co.,Ltd", + [3]byte{8, 253, 14}: "Samsung Electronics Co.,Ltd", + [3]byte{12, 4, 0}: "Jantar d.o.o.", + [3]byte{12, 5, 53}: "Juniper Systems", + [3]byte{12, 17, 5}: "Ringslink (Xiamen) Network Communication Technologies Co., Ltd", + [3]byte{12, 18, 98}: "zte corporation", + [3]byte{12, 19, 11}: "Uniqoteq Ltd.", + [3]byte{12, 20, 32}: "Samsung Electronics Co.,Ltd", + [3]byte{12, 21, 197}: "SDTEC Co., Ltd.", + [3]byte{12, 23, 241}: "TELECSYS", + [3]byte{12, 25, 31}: "Inform Electronik", + [3]byte{12, 29, 175}: "Beijing Xiaomi communications co.,ltd", + [3]byte{12, 29, 194}: "SeAH Networks", + [3]byte{12, 32, 38}: "noax Technologies AG", + [3]byte{12, 39, 36}: "Cisco", + [3]byte{12, 39, 85}: "Valuable Techologies Limited", + [3]byte{12, 42, 105}: "electric imp, incorporated", + [3]byte{12, 42, 231}: "Beijing General Research Institute of Mining and Metallurgy", + [3]byte{12, 45, 137}: "QiiQ Communications Inc.", + [3]byte{12, 48, 33}: "Apple", + [3]byte{12, 55, 220}: "Huawei Technologies Co., Ltd", + [3]byte{12, 56, 62}: "Fanvil Technology Co., Ltd.", + [3]byte{12, 57, 86}: "Observator instruments", + [3]byte{12, 60, 101}: "Dome Imaging Inc", + [3]byte{12, 62, 159}: "Apple, Inc", + [3]byte{12, 70, 157}: "MS Sedco", + [3]byte{12, 71, 61}: "Hitron Technologies. Inc", + [3]byte{12, 76, 57}: "Mitrastar Technology", + [3]byte{12, 77, 233}: "Apple", + [3]byte{12, 79, 90}: "ASA-RT s.r.l.", + [3]byte{12, 81, 247}: "CHAUVIN ARNOUX", + [3]byte{12, 84, 165}: "PEGATRON CORPORATION", + [3]byte{12, 85, 33}: "Axiros GmbH", + [3]byte{12, 86, 92}: "HyBroad Vision (Hong Kong) Technology Co Ltd", + [3]byte{12, 87, 235}: "Mueller Systems", + [3]byte{12, 90, 25}: "Axtion Sdn Bhd", + [3]byte{12, 92, 216}: "DOLI Elektronik GmbH", + [3]byte{12, 96, 118}: "Hon Hai Precision Ind. Co.,Ltd.", + [3]byte{12, 99, 252}: "Nanjing Signway Technology Co., Ltd", + [3]byte{12, 104, 3}: "Cisco", + [3]byte{12, 110, 79}: "PrimeVOLT Co., Ltd.", + [3]byte{12, 113, 93}: "Samsung Electronics Co.,Ltd", + [3]byte{12, 114, 44}: "TP-LINK TECHNOLOGIES CO.,LTD.", + [3]byte{12, 116, 194}: "Apple", + [3]byte{12, 117, 35}: "BEIJING GEHUA CATV NETWORK CO.,LTD", + [3]byte{12, 119, 26}: "Apple", + [3]byte{12, 125, 124}: "Kexiang Information Technology Co, Ltd.", + [3]byte{12, 129, 18}: "PRIVATE", + [3]byte{12, 130, 48}: "SHENZHEN MAGNUS TECHNOLOGIES CO.,LTD", + [3]byte{12, 130, 104}: "TP-LINK TECHNOLOGIES CO.,LTD.", + [3]byte{12, 130, 106}: "Wuhan Huagong Genuine Optics Technology Co., Ltd", + [3]byte{12, 132, 17}: "A.O. Smith Water Products", + [3]byte{12, 132, 132}: "Zenovia Electronics Inc.", + [3]byte{12, 132, 220}: "Hon Hai Precision Ind. Co.,Ltd.", + [3]byte{12, 133, 37}: "CISCO SYSTEMS, INC.", + [3]byte{12, 137, 16}: "Samsung Electronics Co.,LTD", + [3]byte{12, 139, 253}: "Intel Corporate", + [3]byte{12, 140, 143}: "Kamo Technology Limited", + [3]byte{12, 140, 220}: "Suunto Oy", + [3]byte{12, 141, 152}: "TOP EIGHT IND CORP", + [3]byte{12, 146, 78}: "Rice Lake Weighing Systems", + [3]byte{12, 147, 1}: "PT. Prasimax Inovasi Teknologi", + [3]byte{12, 147, 251}: "BNS Solutions", + [3]byte{12, 150, 191}: "Huawei Technologies Co., Ltd", + [3]byte{12, 155, 19}: "Shanghai Magic Mobile Telecommunication Co.Ltd.", + [3]byte{12, 157, 86}: "Consort Controls Ltd", + [3]byte{12, 158, 145}: "Sankosha Corporation", + [3]byte{12, 161, 56}: "Blinq Wireless Inc.", + [3]byte{12, 162, 244}: "Chameleon Technology (UK) Limited", + [3]byte{12, 164, 2}: "Alcatel Lucent IPD", + [3]byte{12, 164, 42}: "OB Telecom Electronic Technology Co., Ltd", + [3]byte{12, 166, 148}: "Sunitec Enterprise Co.,Ltd", + [3]byte{12, 172, 5}: "Unitend Technologies Inc.", + [3]byte{12, 175, 90}: "GENUS POWER INFRASTRUCTURES LIMITED", + [3]byte{12, 179, 25}: "Samsung Elec Co.,Ltd", + [3]byte{12, 180, 239}: "Digience Co.,Ltd.", + [3]byte{12, 189, 81}: "TCT Mobile Limited", + [3]byte{12, 191, 21}: "Genetec", + [3]byte{12, 192, 192}: "MAGNETI MARELLI SISTEMAS ELECTRONICOS MEXICO", + [3]byte{12, 195, 167}: "Meritec", + [3]byte{12, 196, 122}: "Super Micro Computer, Inc.", + [3]byte{12, 196, 126}: "EUCAST Co., Ltd.", + [3]byte{12, 198, 85}: "Wuxi YSTen Technology Co.,Ltd.", + [3]byte{12, 198, 106}: "Nokia Corporation", + [3]byte{12, 198, 172}: "DAGS", + [3]byte{12, 200, 31}: "Summer Infant, Inc.", + [3]byte{12, 201, 198}: "Samwin Hong Kong Limited", + [3]byte{12, 203, 141}: "ASCO Numatics GmbH", + [3]byte{12, 205, 211}: "EASTRIVER TECHNOLOGY CO., LTD.", + [3]byte{12, 205, 251}: "EDIC Systems Inc.", + [3]byte{12, 207, 209}: "SPRINGWAVE Co., Ltd", + [3]byte{12, 210, 146}: "Intel Corporate", + [3]byte{12, 210, 181}: "Binatone Telecommunication Pvt. Ltd", + [3]byte{12, 213, 2}: "Westell", + [3]byte{12, 214, 150}: "Amimon Ltd", + [3]byte{12, 215, 194}: "Axium Technologies, Inc.", + [3]byte{12, 217, 150}: "CISCO SYSTEMS, INC.", + [3]byte{12, 217, 193}: "Visteon Corporation", + [3]byte{12, 218, 65}: "Hangzhou H3C Technologies Co., Limited", + [3]byte{12, 220, 204}: "Inala Technologies", + [3]byte{12, 221, 239}: "Nokia Corporation", + [3]byte{12, 223, 164}: "Samsung Electronics Co.,Ltd", + [3]byte{12, 224, 228}: "Plantronics, Inc", + [3]byte{12, 229, 211}: "DH electronics GmbH", + [3]byte{12, 231, 9}: "Fox Crypto B.V.", + [3]byte{12, 232, 47}: "Bonfiglioli Vectron GmbH", + [3]byte{12, 233, 54}: "ELIMOS srl", + [3]byte{12, 238, 230}: "Hon Hai Precision Ind. Co.,Ltd.", + [3]byte{12, 239, 124}: "AnaCom Inc", + [3]byte{12, 240, 25}: "Malgn Technology Co., Ltd.", + [3]byte{12, 240, 180}: "Globalsat International Technology Ltd", + [3]byte{12, 243, 97}: "Java Information", + [3]byte{12, 243, 238}: "EM Microelectronic", + [3]byte{12, 244, 5}: "Beijing Signalway Technologies Co.,Ltd", + [3]byte{12, 248, 147}: "ARRIS Group, Inc.", + [3]byte{12, 252, 131}: "Airoha Technology Corp.,", + [3]byte{16, 0, 0}: "PRIVATE", + [3]byte{16, 0, 90}: "IBM Corp", + [3]byte{16, 0, 232}: "NATIONAL SEMICONDUCTOR", + [3]byte{16, 0, 253}: "LaonPeople", + [3]byte{16, 1, 202}: "Ashley Butterworth", + [3]byte{16, 5, 202}: "Cisco", + [3]byte{16, 7, 35}: "IEEE REGISTRATION AUTHORITY - Please see MAM public listing for more information.", + [3]byte{16, 8, 177}: "Hon Hai Precision Ind. Co.,Ltd.", + [3]byte{16, 9, 12}: "Janome Sewing Machine Co., Ltd.", + [3]byte{16, 11, 169}: "Intel Corporate", + [3]byte{16, 12, 36}: "pomdevices, LLC", + [3]byte{16, 13, 47}: "Online Security Pty. Ltd.", + [3]byte{16, 13, 50}: "Embedian, Inc.", + [3]byte{16, 13, 127}: "NETGEAR INC.,", + [3]byte{16, 14, 43}: "NEC CASIO Mobile Communications", + [3]byte{16, 14, 126}: "Juniper networks", + [3]byte{16, 15, 24}: "Fu Gang Electronic(KunShan)CO.,LTD", + [3]byte{16, 16, 182}: "McCain Inc", + [3]byte{16, 18, 18}: "Vivo International Corporation Pty Ltd", + [3]byte{16, 18, 24}: "Korins Inc.", + [3]byte{16, 18, 72}: "ITG, Inc.", + [3]byte{16, 19, 238}: "Justec International Technology INC.", + [3]byte{16, 24, 158}: "Elmo Motion Control", + [3]byte{16, 27, 84}: "HUAWEI TECHNOLOGIES CO.,LTD", + [3]byte{16, 28, 12}: "Apple", + [3]byte{16, 29, 81}: "ON-Q LLC dba ON-Q Mesh Networks", + [3]byte{16, 29, 192}: "Samsung Electronics Co.,Ltd", + [3]byte{16, 31, 116}: "Hewlett-Packard Company", + [3]byte{16, 34, 121}: "ZeroDesktop, Inc.", + [3]byte{16, 39, 190}: "TVIP", + [3]byte{16, 40, 49}: "Morion Inc.", + [3]byte{16, 45, 150}: "Looxcie Inc.", + [3]byte{16, 46, 175}: "Texas Instruments", + [3]byte{16, 47, 107}: "Microsoft Corporation", + [3]byte{16, 48, 71}: "Samsung Electronics Co.,Ltd", + [3]byte{16, 51, 120}: "FLECTRON Co., LTD", + [3]byte{16, 55, 17}: "Simlink AS", + [3]byte{16, 59, 89}: "Samsung Electronics Co.,Ltd", + [3]byte{16, 61, 234}: "HFC Technology (Beijing) Ltd. Co.", + [3]byte{16, 64, 243}: "Apple", + [3]byte{16, 67, 105}: "Soundmax Electronic Limited", + [3]byte{16, 68, 90}: "Shaanxi Hitech Electronic Co., LTD", + [3]byte{16, 69, 190}: "Norphonic AS", + [3]byte{16, 69, 248}: "LNT-Automation GmbH", + [3]byte{16, 71, 128}: "HUAWEI TECHNOLOGIES CO.,LTD", + [3]byte{16, 72, 177}: "Beijing Duokan Technology Limited", + [3]byte{16, 75, 70}: "Mitsubishi Electric Corporation", + [3]byte{16, 77, 119}: "Innovative Computer Engineering", + [3]byte{16, 78, 7}: "Shanghai Genvision Industries Co.,Ltd", + [3]byte{16, 81, 114}: "HUAWEI TECHNOLOGIES CO.,LTD", + [3]byte{16, 86, 202}: "Peplink International Ltd.", + [3]byte{16, 92, 59}: "Perma-Pipe, Inc.", + [3]byte{16, 92, 191}: "DuroByte Inc", + [3]byte{16, 95, 6}: "Actiontec Electronics, Inc", + [3]byte{16, 95, 73}: "Cisco SPVTG", + [3]byte{16, 96, 75}: "Hewlett Packard", + [3]byte{16, 98, 201}: "Adatis GmbH & Co. KG", + [3]byte{16, 100, 226}: "ADFweb.com s.r.l.", + [3]byte{16, 101, 163}: "Core Brands LLC", + [3]byte{16, 101, 207}: "IQSIM", + [3]byte{16, 102, 130}: "NEC Platforms, Ltd.", + [3]byte{16, 104, 63}: "LG Electronics", + [3]byte{16, 111, 63}: "Buffalo Inc.", + [3]byte{16, 111, 239}: "Ad-Sol Nissin Corp", + [3]byte{16, 113, 249}: "Cloud Telecomputers, LLC", + [3]byte{16, 118, 138}: "EoCell", + [3]byte{16, 119, 177}: "Samsung Electronics Co.,LTD", + [3]byte{16, 120, 206}: "Hanvit SI, Inc.", + [3]byte{16, 120, 210}: "ELITEGROUP COMPUTER SYSTEM CO., LTD.", + [3]byte{16, 122, 134}: "U&U ENGINEERING INC.", + [3]byte{16, 123, 239}: "ZyXEL Communications Corp", + [3]byte{16, 131, 210}: "Microseven Systems, LLC", + [3]byte{16, 136, 15}: "Daruma Telecomunicações e Informática S.A.", + [3]byte{16, 136, 206}: "Fiberhome Telecommunication Tech.Co.,Ltd.", + [3]byte{16, 138, 27}: "RAONIX Inc.", + [3]byte{16, 140, 207}: "CISCO SYSTEMS, INC.", + [3]byte{16, 146, 102}: "Samsung Electronics Co.,Ltd", + [3]byte{16, 147, 233}: "Apple", + [3]byte{16, 154, 185}: "Tosibox Oy", + [3]byte{16, 154, 221}: "Apple", + [3]byte{16, 159, 169}: "Actiontec Electronics, Inc", + [3]byte{16, 161, 59}: "FUJIKURA RUBBER LTD.", + [3]byte{16, 165, 208}: "Murata Manufacturing Co.,Ltd.", + [3]byte{16, 167, 67}: "SK Mtek Limited", + [3]byte{16, 169, 50}: "Beijing Cyber Cloud Technology Co. ,Ltd.", + [3]byte{16, 174, 96}: "PRIVATE", + [3]byte{16, 178, 107}: "base Co.,Ltd.", + [3]byte{16, 183, 19}: "PRIVATE", + [3]byte{16, 183, 246}: "Plastoform Industries Ltd.", + [3]byte{16, 185, 254}: "Lika srl", + [3]byte{16, 186, 165}: "GANA I&C CO., LTD", + [3]byte{16, 189, 24}: "CISCO SYSTEMS, INC.", + [3]byte{16, 191, 72}: "ASUSTEK COMPUTER INC.", + [3]byte{16, 194, 186}: "UTT Co., Ltd.", + [3]byte{16, 195, 123}: "ASUSTek COMPUTER INC.", + [3]byte{16, 197, 134}: "BIO SOUND LAB CO., LTD.", + [3]byte{16, 198, 31}: "Huawei Technologies Co., Ltd", + [3]byte{16, 198, 126}: "SHENZHEN JUCHIN TECHNOLOGY CO., LTD", + [3]byte{16, 198, 252}: "Garmin International", + [3]byte{16, 199, 63}: "Midas Klark Teknik Ltd", + [3]byte{16, 202, 129}: "PRECIA", + [3]byte{16, 204, 219}: "AXIMUM PRODUITS ELECTRONIQUES", + [3]byte{16, 209, 220}: "INSTAR Deutschland GmbH", + [3]byte{16, 213, 66}: "Samsung Electronics Co.,Ltd", + [3]byte{16, 221, 177}: "Apple", + [3]byte{16, 221, 244}: "Maxway Electronics CO.,LTD", + [3]byte{16, 222, 228}: "automationNEXT GmbH", + [3]byte{16, 226, 213}: "Qi Hardware Inc.", + [3]byte{16, 227, 199}: "Seohwa Telecom", + [3]byte{16, 228, 175}: "APR, LLC", + [3]byte{16, 230, 174}: "Source Technologies, LLC", + [3]byte{16, 232, 238}: "PhaseSpace", + [3]byte{16, 234, 89}: "Cisco SPVTG", + [3]byte{16, 238, 217}: "Canoga Perkins Corporation", + [3]byte{16, 243, 17}: "Cisco", + [3]byte{16, 243, 219}: "Gridco Systems, Inc.", + [3]byte{16, 244, 154}: "T3 Innovation", + [3]byte{16, 246, 129}: "vivo Mobile Communication Co., Ltd.", + [3]byte{16, 249, 111}: "LG Electronics", + [3]byte{16, 249, 238}: "Nokia Corporation", + [3]byte{16, 250, 206}: "Reacheng Communication Technology Co.,Ltd", + [3]byte{16, 251, 240}: "KangSheng LTD.", + [3]byte{16, 252, 84}: "Shany Electronic Co., Ltd.", + [3]byte{16, 254, 237}: "TP-LINK TECHNOLOGIES CO., LTD.", + [3]byte{17, 0, 170}: "PRIVATE", + [3]byte{20, 7, 8}: "PRIVATE", + [3]byte{20, 7, 224}: "Abrantix AG", + [3]byte{20, 12, 118}: "FREEBOX SAS", + [3]byte{20, 13, 79}: "Flextronics International", + [3]byte{20, 16, 159}: "Apple", + [3]byte{20, 19, 48}: "Anakreon UK LLP", + [3]byte{20, 20, 75}: "FUJIAN STAR-NET COMMUNICATION CO.,LTD", + [3]byte{20, 26, 81}: "Treetech Sistemas Digitais", + [3]byte{20, 27, 189}: "Volex Inc.", + [3]byte{20, 27, 240}: "Intellimedia Systems Ltd", + [3]byte{20, 31, 186}: "IEEE REGISTRATION AUTHORITY - Please see MAM public listing for more information.", + [3]byte{20, 35, 215}: "EUTRONIX CO., LTD.", + [3]byte{20, 43, 210}: "Armtel Ltd.", + [3]byte{20, 43, 214}: "Guangdong Appscomm Co.,Ltd", + [3]byte{20, 45, 39}: "Hon Hai Precision Ind. Co.,Ltd.", + [3]byte{20, 45, 139}: "Incipio Technologies, Inc", + [3]byte{20, 45, 245}: "Amphitech", + [3]byte{20, 48, 122}: "Avermetrics", + [3]byte{20, 48, 198}: "Motorola Mobility LLC", + [3]byte{20, 53, 139}: "Mediabridge Products, LLC.", + [3]byte{20, 53, 179}: "Future Designs, Inc.", + [3]byte{20, 54, 5}: "Nokia Corporation", + [3]byte{20, 54, 198}: "Lenovo Mobile Communication Technology Ltd.", + [3]byte{20, 55, 59}: "PROCOM Systems", + [3]byte{20, 58, 234}: "Dynapower Company LLC", + [3]byte{20, 61, 242}: "Beijing Shidai Hongyuan Network Communication Co.,Ltd", + [3]byte{20, 62, 96}: "Alcatel-Lucent", + [3]byte{20, 65, 226}: "Monaco Enterprises, Inc.", + [3]byte{20, 67, 25}: "Creative&Link Technology Limited", + [3]byte{20, 70, 228}: "AVISTEL", + [3]byte{20, 72, 139}: "Shenzhen Doov Technology Co.,Ltd", + [3]byte{20, 73, 120}: "Digital Control Incorporated", + [3]byte{20, 73, 224}: "Samsung Electro Mechanics co.,LTD.", + [3]byte{20, 76, 26}: "Max Communication GmbH", + [3]byte{20, 84, 18}: "Entis Co., Ltd.", + [3]byte{20, 86, 69}: "Savitech Corp.", + [3]byte{20, 88, 208}: "Hewlett Packard", + [3]byte{20, 90, 5}: "Apple", + [3]byte{20, 91, 209}: "ARRIS Group, Inc.", + [3]byte{20, 96, 128}: "zte corporation", + [3]byte{20, 99, 8}: "JABIL CIRCUIT (SHANGHAI) LTD.", + [3]byte{20, 106, 11}: "Cypress Electronics Limited", + [3]byte{20, 110, 10}: "PRIVATE", + [3]byte{20, 115, 115}: "TUBITAK UEKAE", + [3]byte{20, 116, 17}: "RIM", + [3]byte{20, 117, 144}: "TP-LINK TECHNOLOGIES CO.,LTD.", + [3]byte{20, 125, 179}: "JOA TELECOM.CO.,LTD", + [3]byte{20, 125, 197}: "Murata Manufacturing Co., Ltd.", + [3]byte{20, 130, 91}: "Hefei Radio Communication Technology Co., Ltd", + [3]byte{20, 134, 146}: "TP-LINK TECHNOLOGIES CO.,LTD.", + [3]byte{20, 137, 253}: "Samsung Electronics", + [3]byte{20, 138, 112}: "ADS GmbH", + [3]byte{20, 143, 198}: "Apple", + [3]byte{20, 144, 144}: "KongTop industrial(shen zhen)CO.,LTD", + [3]byte{20, 148, 72}: "BLU CASTLE S.A.", + [3]byte{20, 153, 226}: "Apple, Inc", + [3]byte{20, 159, 232}: "Lenovo Mobile Communication Technology Ltd.", + [3]byte{20, 163, 100}: "Samsung Electronics Co.,Ltd", + [3]byte{20, 166, 44}: "S.M. Dezac S.A.", + [3]byte{20, 168, 107}: "ShenZhen Telacom Science&Technology Co., Ltd", + [3]byte{20, 169, 227}: "MST CORPORATION", + [3]byte{20, 171, 240}: "ARRIS Group, Inc.", + [3]byte{20, 177, 38}: "Industrial Software Co", + [3]byte{20, 177, 200}: "InfiniWing, Inc.", + [3]byte{20, 180, 132}: "Samsung Electronics Co.,Ltd", + [3]byte{20, 183, 61}: "ARCHEAN Technologies", + [3]byte{20, 185, 104}: "Huawei Technologies Co., Ltd", + [3]byte{20, 192, 137}: "DUNE HD LTD", + [3]byte{20, 193, 38}: "Nokia Corporation", + [3]byte{20, 194, 29}: "Sabtech Industries", + [3]byte{20, 204, 32}: "TP-LINK TECHNOLOGIES CO.,LTD", + [3]byte{20, 207, 141}: "OHSUNG ELECTRONICS CO., LTD.", + [3]byte{20, 207, 146}: "TP-LINK TECHNOLOGIES CO., LTD.", + [3]byte{20, 207, 226}: "ARRIS Group, Inc.", + [3]byte{20, 212, 254}: "Pace plc", + [3]byte{20, 214, 77}: "D-Link International", + [3]byte{20, 215, 110}: "CONCH ELECTRONIC Co.,Ltd", + [3]byte{20, 218, 233}: "ASUSTek COMPUTER INC.", + [3]byte{20, 219, 133}: "S NET MEDIA", + [3]byte{20, 228, 236}: "mLogic LLC", + [3]byte{20, 230, 228}: "TP-LINK TECHNOLOGIES CO., LTD.", + [3]byte{20, 235, 51}: "BSMediasoft Co., Ltd.", + [3]byte{20, 237, 165}: "Wächter GmbH Sicherheitssysteme", + [3]byte{20, 237, 228}: "Kaiam Corporation", + [3]byte{20, 238, 157}: "AirNav Systems LLC", + [3]byte{20, 240, 197}: "Xtremio Ltd.", + [3]byte{20, 242, 142}: "ShenYang ZhongKe-Allwin Technology Co.LTD", + [3]byte{20, 244, 42}: "Samsung Electronics", + [3]byte{20, 246, 90}: "Xiaomi inc.", + [3]byte{20, 248, 147}: "Wuhan FiberHome Digital Technology Co.,Ltd.", + [3]byte{20, 254, 175}: "SAGITTAR LIMITED", + [3]byte{20, 254, 181}: "Dell Inc", + [3]byte{24, 0, 45}: "Sony Mobile Communications AB", + [3]byte{24, 0, 219}: "Fitbit Inc.", + [3]byte{24, 1, 227}: "Elektrobit Wireless Communications Ltd", + [3]byte{24, 3, 115}: "Dell Inc", + [3]byte{24, 3, 250}: "IBT Interfaces", + [3]byte{24, 6, 117}: "DILAX Intelcom GmbH", + [3]byte{24, 11, 82}: "Nanotron Technologies GmbH", + [3]byte{24, 12, 20}: "iSonea Limited", + [3]byte{24, 12, 119}: "Westinghouse Electric Company, LLC", + [3]byte{24, 12, 172}: "CANON INC.", + [3]byte{24, 16, 78}: "CEDINT-UPM", + [3]byte{24, 20, 32}: "TEB SAS", + [3]byte{24, 20, 86}: "Nokia Corporation", + [3]byte{24, 23, 20}: "DAEWOOIS", + [3]byte{24, 23, 37}: "Cameo Communications, Inc.", + [3]byte{24, 25, 63}: "Tamtron Oy", + [3]byte{24, 27, 235}: "Actiontec Electronics, Inc", + [3]byte{24, 30, 120}: "SAGEMCOM", + [3]byte{24, 30, 176}: "Samsung Electronics Co.,Ltd", + [3]byte{24, 32, 18}: "Aztech Associates Inc.", + [3]byte{24, 32, 50}: "Apple", + [3]byte{24, 32, 166}: "Sage Co., Ltd.", + [3]byte{24, 34, 126}: "Samsung Electronics Co.,Ltd", + [3]byte{24, 38, 102}: "Samsung Electronics Co.,Ltd", + [3]byte{24, 40, 97}: "AirTies Wireless Networks", + [3]byte{24, 42, 123}: "Nintendo Co., Ltd.", + [3]byte{24, 43, 5}: "8D Technologies", + [3]byte{24, 44, 145}: "Concept Development, Inc.", + [3]byte{24, 48, 9}: "Woojin Industrial Systems Co., Ltd.", + [3]byte{24, 50, 162}: "LAON TECHNOLOGY CO., LTD.", + [3]byte{24, 51, 157}: "CISCO SYSTEMS, INC.", + [3]byte{24, 52, 81}: "Apple", + [3]byte{24, 54, 252}: "Elecsys International Corporation", + [3]byte{24, 56, 37}: "Wuhan Lingjiu High-tech Co.,Ltd.", + [3]byte{24, 57, 25}: "Unicoi Systems", + [3]byte{24, 59, 210}: "BYD Precision Manufacture Company Ltd.", + [3]byte{24, 61, 162}: "Intel Corporate", + [3]byte{24, 63, 71}: "Samsung Electronics Co.,Ltd", + [3]byte{24, 66, 29}: "PRIVATE", + [3]byte{24, 66, 47}: "Alcatel Lucent", + [3]byte{24, 68, 98}: "Riava Networks, Inc.", + [3]byte{24, 70, 23}: "Samsung Electronics", + [3]byte{24, 72, 216}: "Fastback Networks", + [3]byte{24, 74, 111}: "Alcatel-Lucent Shanghai Bell Co., Ltd", + [3]byte{24, 78, 148}: "MESSOA TECHNOLOGIES INC.", + [3]byte{24, 82, 83}: "Pixord Corporation", + [3]byte{24, 83, 224}: "Hanyang Digitech Co.Ltd", + [3]byte{24, 85, 15}: "Cisco SPVTG", + [3]byte{24, 89, 51}: "Cisco SPVTG", + [3]byte{24, 90, 232}: "Zenotech.Co.,Ltd", + [3]byte{24, 98, 44}: "SAGEMCOM SAS", + [3]byte{24, 100, 114}: "Aruba Networks", + [3]byte{24, 101, 113}: "Top Victory Electronics (Taiwan) Co., Ltd.", + [3]byte{24, 102, 227}: "Veros Systems, Inc.", + [3]byte{24, 103, 63}: "Hanover Displays Limited", + [3]byte{24, 103, 81}: "KOMEG Industrielle Messtechnik GmbH", + [3]byte{24, 103, 176}: "Samsung Electronics Co.,LTD", + [3]byte{24, 109, 153}: "Adanis Inc.", + [3]byte{24, 113, 23}: "eta plus electronic gmbh", + [3]byte{24, 121, 162}: "GMJ ELECTRIC LIMITED", + [3]byte{24, 122, 147}: "AMICCOM Electronics Corporation", + [3]byte{24, 124, 129}: "Valeo Vision Systems", + [3]byte{24, 126, 213}: "shenzhen kaism technology Co. Ltd", + [3]byte{24, 128, 206}: "Barberry Solutions Ltd", + [3]byte{24, 128, 245}: "Alcatel-Lucent Shanghai Bell Co., Ltd", + [3]byte{24, 130, 25}: "Alibaba Cloud Computing Ltd.", + [3]byte{24, 131, 49}: "Samsung Electronics Co.,Ltd", + [3]byte{24, 131, 191}: "Arcadyan Technology Corporation", + [3]byte{24, 132, 16}: "CoreTrust Inc.", + [3]byte{24, 134, 58}: "DIGITAL ART SYSTEM", + [3]byte{24, 134, 172}: "Nokia Danmark A/S", + [3]byte{24, 135, 150}: "HTC Corporation", + [3]byte{24, 136, 87}: "Beijing Jinhong Xi-Dian Information Technology Corp.", + [3]byte{24, 137, 223}: "CerebrEX Inc.", + [3]byte{24, 142, 213}: "TP Vision Belgium N.V. - innovation site Brugge", + [3]byte{24, 146, 44}: "Virtual Instruments", + [3]byte{24, 151, 255}: "TechFaith Wireless Technology Limited", + [3]byte{24, 154, 103}: "CSE-Servelec Limited", + [3]byte{24, 156, 93}: "Cisco", + [3]byte{24, 158, 252}: "Apple", + [3]byte{24, 169, 5}: "Hewlett-Packard Company", + [3]byte{24, 169, 88}: "PROVISION THAI CO., LTD.", + [3]byte{24, 169, 155}: "Dell Inc", + [3]byte{24, 170, 69}: "Fon Technology", + [3]byte{24, 171, 245}: "Ultra Electronics - Electrics", + [3]byte{24, 173, 77}: "Polostar Technology Corporation", + [3]byte{24, 174, 187}: "Siemens Convergence Creators GmbH&Co.KG", + [3]byte{24, 175, 97}: "Apple, Inc", + [3]byte{24, 175, 143}: "Apple", + [3]byte{24, 175, 159}: "DIGITRONIC Automationsanlagen GmbH", + [3]byte{24, 178, 9}: "Torrey Pines Logic, Inc", + [3]byte{24, 179, 186}: "Netlogic AB", + [3]byte{24, 180, 48}: "Nest Labs Inc.", + [3]byte{24, 181, 145}: "I-Storm", + [3]byte{24, 183, 158}: "Invoxia", + [3]byte{24, 192, 134}: "Broadcom Corporation", + [3]byte{24, 196, 81}: "Tucson Embedded Systems", + [3]byte{24, 200, 231}: "Shenzhen Hualistone Technology Co.,Ltd", + [3]byte{24, 204, 35}: "Philio Technology Corporation", + [3]byte{24, 207, 94}: "Liteon Technology Corporation", + [3]byte{24, 208, 113}: "DASAN CO., LTD.", + [3]byte{24, 213, 182}: "SMG Holdings LLC", + [3]byte{24, 214, 106}: "Inmarsat", + [3]byte{24, 214, 207}: "Kurth Electronic GmbH", + [3]byte{24, 217, 73}: "Qvis Labs, LLC", + [3]byte{24, 220, 86}: "Yulong Computer Telecommunication Scientific(shenzhen)Co.,Lt", + [3]byte{24, 226, 136}: "STT Condigi", + [3]byte{24, 226, 194}: "Samsung Electronics", + [3]byte{24, 231, 40}: "Cisco", + [3]byte{24, 231, 244}: "Apple", + [3]byte{24, 232, 15}: "Viking Electronics Inc.", + [3]byte{24, 232, 221}: "MODULETEK", + [3]byte{24, 239, 99}: "CISCO SYSTEMS, INC.", + [3]byte{24, 244, 106}: "Hon Hai Precision Ind. Co.,Ltd.", + [3]byte{24, 246, 80}: "Multimedia Pacific Limited", + [3]byte{24, 248, 122}: "i3 International Inc.", + [3]byte{24, 250, 111}: "ISC applied systems corp", + [3]byte{24, 251, 123}: "Dell Inc", + [3]byte{24, 252, 159}: "Changhe Electronics Co., Ltd.", + [3]byte{24, 254, 52}: "Espressif Inc.", + [3]byte{24, 255, 46}: "Shenzhen Rui Ying Da Technology Co., Ltd", + [3]byte{28, 6, 86}: "IDY Corporation", + [3]byte{28, 8, 193}: "Lg Innotek", + [3]byte{28, 11, 82}: "EPICOM S.A", + [3]byte{28, 15, 207}: "Sypro Optics GmbH", + [3]byte{28, 17, 225}: "Wartsila Finland Oy", + [3]byte{28, 18, 157}: "IEEE PES PSRC/SUB", + [3]byte{28, 20, 72}: "ARRIS Group, Inc.", + [3]byte{28, 23, 211}: "CISCO SYSTEMS, INC.", + [3]byte{28, 24, 74}: "ShenZhen RicherLink Technologies Co.,LTD", + [3]byte{28, 25, 222}: "eyevis GmbH", + [3]byte{28, 26, 192}: "Apple", + [3]byte{28, 27, 104}: "ARRIS Group, Inc.", + [3]byte{28, 28, 253}: "Dalian Hi-Think Computer Technology, Corp", + [3]byte{28, 29, 103}: "Shenzhen Huawei Communication Technologies Co., Ltd", + [3]byte{28, 29, 134}: "Cisco", + [3]byte{28, 51, 77}: "ITS Telecom", + [3]byte{28, 52, 119}: "Innovation Wireless", + [3]byte{28, 53, 241}: "NEW Lift Neue Elektronische Wege Steuerungsbau GmbH", + [3]byte{28, 55, 191}: "Cloudium Systems Ltd.", + [3]byte{28, 58, 79}: "AccuSpec Electronics, LLC", + [3]byte{28, 61, 231}: "Sigma Koki Co.,Ltd.", + [3]byte{28, 62, 132}: "Hon Hai Precision Ind. Co.,Ltd.", + [3]byte{28, 65, 88}: "Gemalto M2M GmbH", + [3]byte{28, 67, 236}: "JAPAN CIRCUIT CO.,LTD", + [3]byte{28, 69, 147}: "Texas Instruments", + [3]byte{28, 72, 64}: "IMS Messsysteme GmbH", + [3]byte{28, 72, 249}: "GN Netcom A/S", + [3]byte{28, 74, 247}: "AMON INC", + [3]byte{28, 75, 185}: "SMG ENTERPRISE, LLC", + [3]byte{28, 75, 214}: "AzureWave", + [3]byte{28, 81, 181}: "Techaya LTD", + [3]byte{28, 82, 22}: "DONGGUAN HELE ELECTRONICS CO., LTD", + [3]byte{28, 82, 214}: "FLAT DISPLAY TECHNOLOGY CORPORATION", + [3]byte{28, 90, 62}: "Samsung Eletronics Co., Ltd (Visual Display Divison)", + [3]byte{28, 90, 107}: "Philips Electronics Nederland BV", + [3]byte{28, 92, 85}: "PRIMA Cinema, Inc", + [3]byte{28, 92, 96}: "Shenzhen Belzon Technology Co.,LTD.", + [3]byte{28, 95, 255}: "Beijing Ereneben Information Technology Co.,Ltd Shenzhen Branch", + [3]byte{28, 98, 184}: "Samsung Electronics Co.,Ltd", + [3]byte{28, 99, 183}: "OpenProducts 237 AB", + [3]byte{28, 101, 157}: "Liteon Technology Corporation", + [3]byte{28, 102, 109}: "Hon Hai Precision Ind.Co.Ltd", + [3]byte{28, 102, 170}: "Samsung Electronics", + [3]byte{28, 105, 165}: "Research In Motion", + [3]byte{28, 106, 122}: "Cisco", + [3]byte{28, 107, 202}: "Mitsunami Co., Ltd.", + [3]byte{28, 111, 101}: "GIGA-BYTE TECHNOLOGY CO.,LTD.", + [3]byte{28, 117, 8}: "COMPAL INFORMATION (KUNSHAN) CO., LTD.", + [3]byte{28, 118, 202}: "Terasic Technologies Inc.", + [3]byte{28, 120, 57}: "Shenzhen Tencent Computer System Co., Ltd.", + [3]byte{28, 123, 33}: "Sony Mobile Communications AB", + [3]byte{28, 124, 17}: "EID", + [3]byte{28, 124, 69}: "Vitek Industrial Video Products, Inc.", + [3]byte{28, 124, 199}: "Coriant GmbH", + [3]byte{28, 126, 81}: "3bumen.com", + [3]byte{28, 126, 229}: "D-Link International", + [3]byte{28, 131, 176}: "Linked IP GmbH", + [3]byte{28, 132, 100}: "FORMOSA WIRELESS COMMUNICATION CORP.", + [3]byte{28, 134, 173}: "MCT CO., LTD.", + [3]byte{28, 142, 142}: "DB Communication & Systems Co., ltd.", + [3]byte{28, 143, 138}: "Phase Motion Control SpA", + [3]byte{28, 145, 121}: "Integrated System Technologies Ltd", + [3]byte{28, 148, 146}: "RUAG Schweiz AG", + [3]byte{28, 149, 93}: "I-LAX ELECTRONICS INC.", + [3]byte{28, 149, 159}: "Veethree Electronics And Marine LLC", + [3]byte{28, 150, 90}: "Weifang goertek Electronics CO.,LTD", + [3]byte{28, 151, 61}: "PRICOM Design", + [3]byte{28, 153, 76}: "Murata Manufactuaring Co.,Ltd.", + [3]byte{28, 156, 38}: "Zoovel Technologies", + [3]byte{28, 158, 203}: "Beijing Nari Smartchip Microelectronics Company Limited", + [3]byte{28, 162, 177}: "ruwido austria gmbh", + [3]byte{28, 167, 112}: "SHENZHEN CHUANGWEI-RGB ELECTRONICS CO.,LT", + [3]byte{28, 170, 7}: "CISCO SYSTEMS, INC.", + [3]byte{28, 171, 1}: "Innovolt", + [3]byte{28, 171, 167}: "Apple", + [3]byte{28, 175, 5}: "Samsung Electronics Co.,Ltd", + [3]byte{28, 175, 247}: "D-LINK INTERNATIONAL PTE LIMITED", + [3]byte{28, 176, 148}: "HTC Corporation", + [3]byte{28, 177, 127}: "NEC Platforms, Ltd.", + [3]byte{28, 178, 67}: "TDC A/S", + [3]byte{28, 186, 140}: "Texas Instruments", + [3]byte{28, 187, 168}: "OJSC \"Ufimskiy Zavod \"Promsvyaz\"", + [3]byte{28, 189, 14}: "Amplified Engineering Pty Ltd", + [3]byte{28, 189, 185}: "D-LINK INTERNATIONAL PTE LIMITED", + [3]byte{28, 193, 26}: "Wavetronix", + [3]byte{28, 193, 222}: "Hewlett-Packard Company", + [3]byte{28, 195, 22}: "MileSight Technology Co., Ltd.", + [3]byte{28, 198, 60}: "Arcadyan Technology Corporation", + [3]byte{28, 212, 12}: "Kriwan Industrie-Elektronik GmbH", + [3]byte{28, 222, 167}: "Cisco", + [3]byte{28, 223, 15}: "CISCO SYSTEMS, INC.", + [3]byte{28, 225, 101}: "Marshal Corporation", + [3]byte{28, 225, 146}: "Qisda Corporation", + [3]byte{28, 226, 204}: "Texas Instruments", + [3]byte{28, 230, 43}: "Apple", + [3]byte{28, 230, 199}: "Cisco", + [3]byte{28, 238, 232}: "Ilshin Elecom", + [3]byte{28, 240, 97}: "SCAPS GmbH", + [3]byte{28, 244, 202}: "PRIVATE", + [3]byte{28, 245, 231}: "Turtle Industry Co., Ltd.", + [3]byte{28, 250, 104}: "TP-LINK TECHNOLOGIES CO.,LTD.", + [3]byte{28, 252, 187}: "Realfiction ApS", + [3]byte{28, 254, 167}: "IDentytech Solutins Ltd.", + [3]byte{32, 1, 79}: "Linea Research Ltd", + [3]byte{32, 2, 175}: "Murata Manufactuaring Co.,Ltd.", + [3]byte{32, 5, 5}: "RADMAX COMMUNICATION PRIVATE LIMITED", + [3]byte{32, 5, 232}: "OOO InProMedia", + [3]byte{32, 8, 237}: "Huawei Technologies Co., Ltd", + [3]byte{32, 10, 94}: "Xiangshan Giant Eagle Technology Developing co.,LTD", + [3]byte{32, 11, 199}: "HUAWEI TECHNOLOGIES CO.,LTD", + [3]byte{32, 12, 200}: "NETGEAR INC.,", + [3]byte{32, 14, 149}: "IEC – TC9 WG43", + [3]byte{32, 16, 122}: "Gemtek Technology Co., Ltd.", + [3]byte{32, 18, 87}: "Most Lucky Trading Ltd", + [3]byte{32, 18, 213}: "Scientech Materials Corporation", + [3]byte{32, 19, 224}: "Samsung Electronics Co.,Ltd", + [3]byte{32, 22, 216}: "Liteon Technology Corporation", + [3]byte{32, 24, 14}: "Shenzhen Sunchip Technology Co., Ltd", + [3]byte{32, 26, 6}: "COMPAL INFORMATION (KUNSHAN) CO., LTD.", + [3]byte{32, 29, 3}: "Elatec GmbH", + [3]byte{32, 33, 165}: "LG Electronics Inc", + [3]byte{32, 37, 100}: "PEGATRON CORPORATION", + [3]byte{32, 37, 152}: "Teleview", + [3]byte{32, 43, 193}: "Shenzhen Huawei Communication Technologies Co., Ltd", + [3]byte{32, 44, 183}: "Kong Yue Electronics & Information Industry (Xinhui) Ltd.", + [3]byte{32, 55, 6}: "CISCO SYSTEMS, INC.", + [3]byte{32, 55, 188}: "Kuipers Electronic Engineering BV", + [3]byte{32, 58, 7}: "Cisco", + [3]byte{32, 64, 5}: "feno GmbH", + [3]byte{32, 65, 90}: "Smarteh d.o.o.", + [3]byte{32, 68, 58}: "Schneider Electric Asia Pacific Ltd", + [3]byte{32, 70, 161}: "VECOW Co., Ltd", + [3]byte{32, 70, 249}: "Advanced Network Devices (dba:AND)", + [3]byte{32, 74, 170}: "Hanscan Spain S.A.", + [3]byte{32, 76, 109}: "Hugo Brennenstuhl Gmbh & Co. KG.", + [3]byte{32, 78, 107}: "Axxana(israel) ltd", + [3]byte{32, 78, 127}: "NETGEAR", + [3]byte{32, 83, 202}: "Risk Technology Ltd", + [3]byte{32, 84, 118}: "Sony Mobile Communications AB", + [3]byte{32, 87, 33}: "Salix Technology CO., Ltd.", + [3]byte{32, 89, 160}: "Paragon Technologies Inc.", + [3]byte{32, 90, 0}: "Coval", + [3]byte{32, 91, 42}: "PRIVATE", + [3]byte{32, 91, 94}: "Shenzhen Wonhe Technology Co., Ltd", + [3]byte{32, 92, 250}: "Yangzhou ChangLian Network Technology Co,ltd.", + [3]byte{32, 100, 50}: "SAMSUNG ELECTRO MECHANICS CO.,LTD.", + [3]byte{32, 103, 177}: "Pluto inc.", + [3]byte{32, 104, 157}: "Liteon Technology Corporation", + [3]byte{32, 106, 138}: "Wistron InfoComm Manufacturing(Kunshan)Co.,Ltd.", + [3]byte{32, 106, 255}: "Atlas Elektronik UK Limited", + [3]byte{32, 110, 156}: "Samsung Electronics Co.,Ltd", + [3]byte{32, 111, 236}: "Braemac CA LLC", + [3]byte{32, 115, 85}: "ARRIS Group, Inc.", + [3]byte{32, 116, 207}: "Shenzhen Voxtech Co.,Ltd", + [3]byte{32, 118, 0}: "Actiontec Electronics, Inc", + [3]byte{32, 118, 147}: "Lenovo (Beijing) Limited.", + [3]byte{32, 124, 143}: "Quanta Microsystems,Inc.", + [3]byte{32, 125, 116}: "Apple", + [3]byte{32, 133, 140}: "Assa", + [3]byte{32, 135, 172}: "AES motomation", + [3]byte{32, 137, 132}: "COMPAL INFORMATION (KUNSHAN) CO., LTD", + [3]byte{32, 137, 134}: "zte corporation", + [3]byte{32, 145, 138}: "PROFALUX", + [3]byte{32, 145, 217}: "I'M SPA", + [3]byte{32, 147, 77}: "Fujian Star-net Communication Co., Ltd", + [3]byte{32, 154, 233}: "Volacomm Co., Ltd", + [3]byte{32, 155, 165}: "JIAXING GLEAD Electronics Co.,Ltd", + [3]byte{32, 162, 231}: "Lee-Dickens Ltd", + [3]byte{32, 167, 135}: "Bointec Taiwan Corporation Limited", + [3]byte{32, 169, 155}: "Microsoft Corporation", + [3]byte{32, 170, 37}: "IP-NET LLC", + [3]byte{32, 170, 75}: "Cisco-Linksys, LLC", + [3]byte{32, 176, 247}: "Enclustra GmbH", + [3]byte{32, 179, 153}: "Enterasys", + [3]byte{32, 181, 198}: "Mimosa Networks", + [3]byte{32, 183, 192}: "Omicron electronics GmbH", + [3]byte{32, 187, 192}: "Cisco", + [3]byte{32, 187, 198}: "Jabil Circuit Hungary Ltd.", + [3]byte{32, 191, 219}: "DVL", + [3]byte{32, 193, 175}: "i Wit Digital Co., Limited", + [3]byte{32, 195, 143}: "Texas Instruments Inc", + [3]byte{32, 198, 13}: "Shanghai annijie Information technology Co.,LTD", + [3]byte{32, 198, 235}: "Panasonic Corporation AVC Networks Company", + [3]byte{32, 200, 179}: "SHENZHEN BUL-TECH CO.,LTD.", + [3]byte{32, 201, 208}: "Apple", + [3]byte{32, 205, 57}: "Texas Instruments, Inc", + [3]byte{32, 206, 196}: "Peraso Technologies", + [3]byte{32, 207, 48}: "ASUSTek COMPUTER INC.", + [3]byte{32, 210, 31}: "Wincal Technology Corp.", + [3]byte{32, 211, 144}: "Samsung Electronics Co.,Ltd", + [3]byte{32, 213, 171}: "Korea Infocom Co.,Ltd.", + [3]byte{32, 213, 191}: "Samsung Eletronics Co., Ltd", + [3]byte{32, 214, 7}: "Nokia Corporation", + [3]byte{32, 217, 6}: "Iota, Inc.", + [3]byte{32, 220, 147}: "Cheetah Hi-Tech, Inc.", + [3]byte{32, 220, 230}: "TP-LINK TECHNOLOGIES CO., LTD.", + [3]byte{32, 223, 63}: "Nanjing SAC Power Grid Automation Co., Ltd.", + [3]byte{32, 229, 42}: "NETGEAR INC.,", + [3]byte{32, 229, 100}: "ARRIS Group, Inc.", + [3]byte{32, 231, 145}: "Siemens Healthcare Diagnostics, Inc", + [3]byte{32, 234, 199}: "SHENZHEN RIOPINE ELECTRONICS CO., LTD", + [3]byte{32, 237, 116}: "Ability enterprise co.,Ltd.", + [3]byte{32, 238, 198}: "Elefirst Science & Tech Co ., ltd", + [3]byte{32, 240, 2}: "MTData Developments Pty. Ltd.", + [3]byte{32, 243, 163}: "Huawei Technologies Co., Ltd", + [3]byte{32, 248, 94}: "Delta Electronics", + [3]byte{32, 250, 187}: "Cambridge Executive Limited", + [3]byte{32, 253, 241}: "3COM EUROPE LTD", + [3]byte{32, 254, 205}: "System In Frontier Inc.", + [3]byte{32, 254, 219}: "M2M Solution S.A.S.", + [3]byte{36, 1, 199}: "Cisco", + [3]byte{36, 5, 15}: "MTN Electronic Co. Ltd", + [3]byte{36, 9, 23}: "Devlin Electronics Limited", + [3]byte{36, 10, 17}: "TCT Mobile Limited", + [3]byte{36, 10, 100}: "AzureWaveTechnologies,Inc", + [3]byte{36, 11, 42}: "Viettel Group", + [3]byte{36, 11, 177}: "KOSTAL Industrie Elektrik GmbH", + [3]byte{36, 16, 100}: "Shenzhen Ecsino Tecnical Co. Ltd", + [3]byte{36, 17, 37}: "Hutek Co., Ltd.", + [3]byte{36, 17, 72}: "Entropix, LLC", + [3]byte{36, 17, 208}: "Chongqing Ehs Science and Technology Development Co.,Ltd.", + [3]byte{36, 26, 140}: "Squarehead Technology AS", + [3]byte{36, 27, 19}: "Shanghai Nutshell Electronic Co., Ltd.", + [3]byte{36, 31, 44}: "Calsys, Inc.", + [3]byte{36, 33, 171}: "Sony Ericsson Mobile Communications", + [3]byte{36, 38, 66}: "SHARP Corporation.", + [3]byte{36, 47, 250}: "Toshiba Global Commerce Solutions", + [3]byte{36, 51, 108}: "PRIVATE", + [3]byte{36, 55, 76}: "Cisco SPVTG", + [3]byte{36, 55, 239}: "EMC Electronic Media Communication SA", + [3]byte{36, 60, 32}: "Dynamode Group", + [3]byte{36, 66, 188}: "Alinco,incorporated", + [3]byte{36, 69, 151}: "GEMUE Gebr. Mueller Apparatebau", + [3]byte{36, 71, 14}: "PentronicAB", + [3]byte{36, 73, 123}: "Innovative Converged Devices Inc", + [3]byte{36, 79, 29}: "iRule LLC", + [3]byte{36, 95, 223}: "KYOCERA Corporation", + [3]byte{36, 98, 120}: "sysmocom - systems for mobile communications GmbH", + [3]byte{36, 100, 239}: "CYG SUNRI CO.,LTD.", + [3]byte{36, 101, 17}: "AVM GmbH", + [3]byte{36, 105, 74}: "Jasmine Systems Inc.", + [3]byte{36, 105, 165}: "Huawei Technologies Co., Ltd", + [3]byte{36, 106, 171}: "IT-IS International", + [3]byte{36, 118, 125}: "Cisco SPVTG", + [3]byte{36, 119, 3}: "Intel Corporate", + [3]byte{36, 128, 0}: "Westcontrol AS", + [3]byte{36, 129, 170}: "KSH International Co., Ltd.", + [3]byte{36, 130, 138}: "Prowave Technologies Ltd.", + [3]byte{36, 134, 244}: "Ctek, Inc.", + [3]byte{36, 135, 7}: "SEnergy Corporation", + [3]byte{36, 147, 202}: "Voxtronic Technology Computer-Systeme GmbH", + [3]byte{36, 148, 66}: "OPEN ROAD SOLUTIONS , INC.", + [3]byte{36, 149, 4}: "SFR", + [3]byte{36, 151, 237}: "Techvision Intelligent Technology Limited", + [3]byte{36, 162, 225}: "Apple, Inc", + [3]byte{36, 164, 44}: "KOUKAAM a.s.", + [3]byte{36, 164, 60}: "Ubiquiti Networks, INC", + [3]byte{36, 164, 149}: "Thales Canada Inc.", + [3]byte{36, 168, 125}: "Panasonic Automotive Systems Asia Pacific(Thailand)Co.,Ltd.", + [3]byte{36, 169, 55}: "PURE Storage", + [3]byte{36, 171, 129}: "Apple", + [3]byte{36, 175, 74}: "Alcatel-Lucent-IPD", + [3]byte{36, 175, 84}: "NEXGEN Mediatech Inc.", + [3]byte{36, 182, 87}: "CISCO SYSTEMS, INC.", + [3]byte{36, 182, 184}: "FRIEM SPA", + [3]byte{36, 182, 253}: "Dell Inc", + [3]byte{36, 184, 140}: "Crenus Co.,Ltd.", + [3]byte{36, 184, 210}: "Opzoon Technology Co.,Ltd.", + [3]byte{36, 186, 48}: "Technical Consumer Products, Inc.", + [3]byte{36, 187, 193}: "Absolute Analysis", + [3]byte{36, 188, 130}: "Dali Wireless, Inc.", + [3]byte{36, 190, 5}: "Hewlett Packard", + [3]byte{36, 191, 116}: "PRIVATE", + [3]byte{36, 192, 179}: "RSF", + [3]byte{36, 198, 150}: "Samsung Electronics Co.,Ltd", + [3]byte{36, 200, 72}: "mywerk system GmbH", + [3]byte{36, 200, 110}: "Chaney Instrument Co.", + [3]byte{36, 201, 161}: "Ruckus Wireless", + [3]byte{36, 201, 222}: "Genoray", + [3]byte{36, 203, 231}: "MYK, Inc.", + [3]byte{36, 207, 33}: "Shenzhen State Micro Technology Co., Ltd", + [3]byte{36, 209, 63}: "MEXUS CO.,LTD", + [3]byte{36, 210, 204}: "SmartDrive Systems Inc.", + [3]byte{36, 217, 33}: "Avaya, Inc", + [3]byte{36, 218, 182}: "Sistemas de Gestión Energética S.A. de C.V", + [3]byte{36, 219, 172}: "Shenzhen Huawei Communication Technologies Co., Ltd", + [3]byte{36, 219, 173}: "ShopperTrak RCT Corporation", + [3]byte{36, 219, 237}: "Samsung Electronics Co.,Ltd", + [3]byte{36, 222, 198}: "Aruba Networks", + [3]byte{36, 226, 113}: "Qingdao Hisense Communications Co.,Ltd", + [3]byte{36, 227, 20}: "Apple", + [3]byte{36, 230, 186}: "JSC Zavod im. Kozitsky", + [3]byte{36, 233, 179}: "Cisco", + [3]byte{36, 234, 64}: "Systeme Helmholz GmbH", + [3]byte{36, 235, 101}: "SAET I.S. S.r.l.", + [3]byte{36, 236, 153}: "Askey Computer Corp", + [3]byte{36, 236, 214}: "CSG Science & Technology Co.,Ltd.Hefei", + [3]byte{36, 238, 58}: "Chengdu Yingji Electronic Hi-tech Co Ltd", + [3]byte{36, 240, 255}: "GHT Co., Ltd.", + [3]byte{36, 242, 221}: "Radiant Zemax LLC", + [3]byte{36, 245, 170}: "Samsung Electronics Co.,LTD", + [3]byte{36, 253, 82}: "Liteon Technology Corporation", + [3]byte{40, 4, 224}: "FERMAX ELECTRONICA S.A.U.", + [3]byte{40, 6, 30}: "NINGBO GLOBAL USEFUL ELECTRIC CO.,LTD", + [3]byte{40, 6, 141}: "ITL, LLC", + [3]byte{40, 11, 92}: "Apple", + [3]byte{40, 12, 184}: "Mikrosay Yazilim ve Elektronik A.S.", + [3]byte{40, 13, 252}: "Sony Computer Entertainment Inc.", + [3]byte{40, 16, 123}: "D-Link International", + [3]byte{40, 20, 113}: "Lantis co., LTD.", + [3]byte{40, 22, 46}: "2Wire", + [3]byte{40, 23, 206}: "Omnisense Ltd", + [3]byte{40, 24, 120}: "Microsoft Corporation", + [3]byte{40, 24, 253}: "Aditya Infotech Ltd.", + [3]byte{40, 34, 70}: "Beijing Sinoix Communication Co., LTD", + [3]byte{40, 38, 166}: "PBR electronics GmbH", + [3]byte{40, 40, 93}: "ZyXEL Communications Corporation", + [3]byte{40, 41, 204}: "Corsa Technology Incorporated", + [3]byte{40, 41, 217}: "GlobalBeiMing technology (Beijing)Co. Ltd", + [3]byte{40, 44, 178}: "TP-LINK TECHNOLOGIES CO.,LTD.", + [3]byte{40, 49, 82}: "HUAWEI TECHNOLOGIES CO.,LTD", + [3]byte{40, 50, 197}: "Humax.co.,ltd", + [3]byte{40, 52, 16}: "Enigma Diagnostics Limited", + [3]byte{40, 52, 162}: "Cisco", + [3]byte{40, 55, 55}: "Apple", + [3]byte{40, 56, 207}: "Gen2wave", + [3]byte{40, 57, 231}: "Preceno Technology Pte.Ltd.", + [3]byte{40, 59, 150}: "Cool Control LTD", + [3]byte{40, 60, 228}: "Huawei Technologies Co., Ltd", + [3]byte{40, 64, 26}: "C8 MediSensors, Inc.", + [3]byte{40, 65, 33}: "OptiSense Network, LLC", + [3]byte{40, 68, 48}: "GenesisTechnical Systems (UK) Ltd", + [3]byte{40, 71, 170}: "Nokia Corporation", + [3]byte{40, 72, 70}: "GridCentric Inc.", + [3]byte{40, 76, 83}: "Intune Networks", + [3]byte{40, 77, 146}: "Luminator", + [3]byte{40, 78, 215}: "OutSmart Power Systems, Inc.", + [3]byte{40, 79, 206}: "Liaoning Wontel Science and Technology Development Co.,Ltd.", + [3]byte{40, 81, 50}: "Shenzhen Prayfly Technology Co.,Ltd", + [3]byte{40, 87, 103}: "Echostar Technologies Corp", + [3]byte{40, 95, 219}: "Shenzhen Huawei Communication Technologies Co., Ltd", + [3]byte{40, 96, 70}: "Lantech Communications Global, Inc.", + [3]byte{40, 96, 148}: "CAPELEC", + [3]byte{40, 99, 54}: "Siemens AG - Industrial Automation - EWA", + [3]byte{40, 101, 107}: "Keystone Microtech Corporation", + [3]byte{40, 106, 184}: "Apple", + [3]byte{40, 106, 186}: "Apple", + [3]byte{40, 109, 151}: "SAMJIN Co., Ltd.", + [3]byte{40, 110, 212}: "HUAWEI TECHNOLOGIES CO.,LTD", + [3]byte{40, 113, 132}: "Spire Payments", + [3]byte{40, 114, 197}: "Smartmatic Corp", + [3]byte{40, 114, 240}: "ATHENA", + [3]byte{40, 121, 148}: "Realplay Digital Technology(Shenzhen) Co.,Ltd", + [3]byte{40, 128, 35}: "Hewlett Packard", + [3]byte{40, 133, 45}: "Touch Networks", + [3]byte{40, 137, 21}: "CashGuard Sverige AB", + [3]byte{40, 138, 28}: "Juniper networks", + [3]byte{40, 145, 208}: "Stage Tec Entwicklungsgesellschaft für professionelle Audiotechnik mbH", + [3]byte{40, 146, 74}: "Hewlett Packard", + [3]byte{40, 147, 254}: "CISCO SYSTEMS, INC.", + [3]byte{40, 148, 15}: "CISCO SYSTEMS, INC.", + [3]byte{40, 148, 175}: "Samhwa Telecom", + [3]byte{40, 152, 123}: "Samsung Electronics Co.,Ltd", + [3]byte{40, 154, 75}: "SteelSeries ApS", + [3]byte{40, 154, 250}: "TCT Mobile Limited", + [3]byte{40, 158, 223}: "Danfoss Turbocor Compressors, Inc", + [3]byte{40, 161, 134}: "enblink", + [3]byte{40, 161, 146}: "GERP Solution", + [3]byte{40, 161, 235}: "ETEK TECHNOLOGY (SHENZHEN) CO.,LTD", + [3]byte{40, 162, 65}: "exlar corp", + [3]byte{40, 165, 116}: "Miller Electric Mfg. Co.", + [3]byte{40, 165, 238}: "Shenzhen SDGI CATV Co., Ltd", + [3]byte{40, 175, 10}: "Sirius XM Radio Inc", + [3]byte{40, 176, 204}: "Xenya d.o.o.", + [3]byte{40, 178, 189}: "Intel Corporate", + [3]byte{40, 179, 171}: "Genmark Automation", + [3]byte{40, 186, 24}: "NextNav, LLC", + [3]byte{40, 186, 181}: "Samsung Electronics Co.,Ltd", + [3]byte{40, 187, 89}: "RNET Technologies, Inc.", + [3]byte{40, 190, 155}: "Technicolor USA Inc.", + [3]byte{40, 192, 218}: "Juniper Networks", + [3]byte{40, 198, 113}: "Yota Devices OY", + [3]byte{40, 198, 142}: "NETGEAR INC.,", + [3]byte{40, 199, 24}: "Altierre", + [3]byte{40, 199, 206}: "Cisco", + [3]byte{40, 200, 37}: "DellKing Industrial Co., Ltd", + [3]byte{40, 201, 20}: "Taimag Corporation", + [3]byte{40, 203, 235}: "One", + [3]byte{40, 204, 1}: "Samsung Electronics Co.,Ltd", + [3]byte{40, 204, 255}: "Corporacion Empresarial Altra SL", + [3]byte{40, 205, 28}: "Espotel Oy", + [3]byte{40, 205, 76}: "Individual Computers GmbH", + [3]byte{40, 205, 156}: "Shenzhen Dynamax Software Development Co.,Ltd.", + [3]byte{40, 207, 218}: "Apple", + [3]byte{40, 207, 233}: "Apple", + [3]byte{40, 209, 175}: "Nokia Corporation", + [3]byte{40, 210, 68}: "LCFC(HeFei) Electronics Technology Co., Ltd.", + [3]byte{40, 213, 118}: "Premier Wireless, Inc.", + [3]byte{40, 217, 62}: "Telecor Inc.", + [3]byte{40, 217, 138}: "Hangzhou Konke Technology Co.,Ltd.", + [3]byte{40, 217, 151}: "Yuduan Mobile Co., Ltd.", + [3]byte{40, 219, 129}: "Shanghai Guao Electronic Technology Co., Ltd", + [3]byte{40, 222, 246}: "bioMerieux Inc.", + [3]byte{40, 224, 44}: "Apple", + [3]byte{40, 225, 76}: "Apple, Inc.", + [3]byte{40, 226, 151}: "Shanghai InfoTM Microelectronics Co.,Ltd.", + [3]byte{40, 227, 31}: "Xiaomi inc.", + [3]byte{40, 227, 71}: "Liteon Technology Corporation", + [3]byte{40, 230, 8}: "Tokheim", + [3]byte{40, 230, 233}: "SIS Sat Internet Services GmbH", + [3]byte{40, 231, 148}: "Microtime Computer Inc.", + [3]byte{40, 231, 207}: "Apple", + [3]byte{40, 237, 88}: "JAG Jakob AG", + [3]byte{40, 238, 44}: "Frontline Test Equipment", + [3]byte{40, 239, 1}: "PRIVATE", + [3]byte{40, 243, 88}: "2C - Trifonov & Co", + [3]byte{40, 245, 50}: "ADD-Engineering BV", + [3]byte{40, 246, 6}: "Syes srl", + [3]byte{40, 251, 211}: "Ragentek Technology Group", + [3]byte{40, 252, 81}: "The Electric Controller and Manufacturing Co., LLC", + [3]byte{40, 252, 246}: "Shenzhen Xin KingBrand enterprises Co.,Ltd", + [3]byte{44, 0, 44}: "UNOWHY", + [3]byte{44, 0, 51}: "EControls, LLC", + [3]byte{44, 0, 247}: "XOS", + [3]byte{44, 1, 11}: "NASCENT Technology, LLC - RemKon", + [3]byte{44, 6, 35}: "Win Leader Inc.", + [3]byte{44, 7, 60}: "DEVLINE LIMITED", + [3]byte{44, 16, 193}: "Nintendo Co., Ltd.", + [3]byte{44, 24, 174}: "Trend Electronics Co., Ltd.", + [3]byte{44, 25, 132}: "IDN Telecom, Inc.", + [3]byte{44, 26, 49}: "Electronics Company Limited", + [3]byte{44, 30, 234}: "AERODEV", + [3]byte{44, 33, 114}: "Juniper Networks", + [3]byte{44, 36, 95}: "Babolat VS", + [3]byte{44, 38, 197}: "zte corporation", + [3]byte{44, 39, 215}: "Hewlett-Packard Company", + [3]byte{44, 40, 45}: "BBK COMMUNICATIAO TECHNOLOGY CO.,LTD.", + [3]byte{44, 41, 151}: "Microsoft Corporation", + [3]byte{44, 45, 72}: "bct electronic GesmbH", + [3]byte{44, 48, 104}: "Pantech Co.,Ltd", + [3]byte{44, 51, 122}: "Hon Hai Precision Ind. Co.,Ltd.", + [3]byte{44, 52, 39}: "ERCO & GENER", + [3]byte{44, 53, 87}: "ELLIY Power CO..Ltd", + [3]byte{44, 54, 160}: "Capisco Limited", + [3]byte{44, 54, 248}: "CISCO SYSTEMS, INC.", + [3]byte{44, 55, 49}: "ShenZhen Yifang Digital Technology Co.,LTD", + [3]byte{44, 55, 150}: "CYBO CO.,LTD.", + [3]byte{44, 57, 150}: "SAGEMCOM", + [3]byte{44, 57, 193}: "Ciena Corporation", + [3]byte{44, 58, 40}: "Fagor Electrónica", + [3]byte{44, 59, 253}: "Netstor Technology Co., Ltd.", + [3]byte{44, 62, 207}: "Cisco", + [3]byte{44, 63, 56}: "CISCO SYSTEMS, INC.", + [3]byte{44, 63, 62}: "Alge-Timing GmbH", + [3]byte{44, 65, 56}: "Hewlett-Packard Company", + [3]byte{44, 68, 1}: "Samsung Electronics Co.,Ltd", + [3]byte{44, 68, 27}: "Spectrum Medical Limited", + [3]byte{44, 68, 253}: "Hewlett Packard", + [3]byte{44, 80, 137}: "Shenzhen Kaixuan Visual Technology Co.,Limited", + [3]byte{44, 83, 74}: "Shenzhen Winyao Electronic Limited", + [3]byte{44, 84, 45}: "CISCO SYSTEMS, INC.", + [3]byte{44, 84, 207}: "LG Electronics", + [3]byte{44, 85, 60}: "Gainspeed, Inc.", + [3]byte{44, 89, 229}: "Hewlett Packard", + [3]byte{44, 90, 5}: "Nokia Corporation", + [3]byte{44, 90, 163}: "PROMATE ELECTRONIC CO.LTD", + [3]byte{44, 91, 225}: "Centripetal Networks, Inc", + [3]byte{44, 93, 147}: "Ruckus Wireless", + [3]byte{44, 95, 243}: "Pertronic Industries", + [3]byte{44, 96, 12}: "QUANTA COMPUTER INC.", + [3]byte{44, 98, 90}: "Finest Security Systems Co., Ltd", + [3]byte{44, 98, 137}: "Regenersis (Glenrothes) Ltd", + [3]byte{44, 103, 251}: "ShenZhen Zhengjili Electronics Co., LTD", + [3]byte{44, 105, 186}: "RF Controls, LLC", + [3]byte{44, 107, 245}: "Juniper networks", + [3]byte{44, 113, 85}: "HiveMotion", + [3]byte{44, 114, 195}: "Soundmatters", + [3]byte{44, 117, 15}: "Shanghai Dongzhou-Lawton Communication Technology Co. Ltd.", + [3]byte{44, 118, 138}: "Hewlett-Packard Company", + [3]byte{44, 123, 90}: "Milper Ltd", + [3]byte{44, 123, 132}: "OOO Petr Telegin", + [3]byte{44, 126, 207}: "Onzo Ltd", + [3]byte{44, 128, 101}: "HARTING Inc. of North America", + [3]byte{44, 129, 88}: "Hon Hai Precision Ind. Co.,Ltd", + [3]byte{44, 138, 114}: "HTC Corporation", + [3]byte{44, 139, 242}: "Hitachi Metals America Ltd", + [3]byte{44, 145, 39}: "Eintechno Corporation", + [3]byte{44, 146, 44}: "Kishu Giken Kogyou Company Ltd,.", + [3]byte{44, 148, 100}: "Cincoze Co., Ltd.", + [3]byte{44, 149, 127}: "zte corporation", + [3]byte{44, 151, 23}: "I.C.Y. B.V.", + [3]byte{44, 154, 164}: "NGI SpA", + [3]byte{44, 158, 95}: "ARRIS Group, Inc.", + [3]byte{44, 158, 252}: "CANON INC.", + [3]byte{44, 161, 87}: "acromate, Inc.", + [3]byte{44, 163, 14}: "POWER DRAGON DEVELOPMENT LIMITED", + [3]byte{44, 167, 128}: "True Technologies Inc.", + [3]byte{44, 168, 53}: "RIM", + [3]byte{44, 171, 37}: "Shenzhen Gongjin Electronics Co.,Ltd", + [3]byte{44, 171, 164}: "Cisco SPVTG", + [3]byte{44, 176, 93}: "NETGEAR", + [3]byte{44, 176, 223}: "Soliton Technologies Pvt Ltd", + [3]byte{44, 180, 58}: "Apple", + [3]byte{44, 182, 147}: "Radware", + [3]byte{44, 182, 157}: "RED Digital Cinema", + [3]byte{44, 190, 8}: "Apple", + [3]byte{44, 190, 151}: "Ingenieurbuero Bickele und Buehler GmbH", + [3]byte{44, 194, 96}: "Ravello Systems", + [3]byte{44, 204, 21}: "Nokia Corporation", + [3]byte{44, 205, 39}: "Precor Inc", + [3]byte{44, 205, 67}: "Summit Technology Group", + [3]byte{44, 205, 105}: "Aqavi.com", + [3]byte{44, 208, 90}: "Liteon Technology Corporation", + [3]byte{44, 209, 218}: "Sanjole, Inc.", + [3]byte{44, 210, 231}: "Nokia Corporation", + [3]byte{44, 212, 68}: "Fujitsu Limited", + [3]byte{44, 221, 12}: "Discovergy GmbH", + [3]byte{44, 226, 168}: "DeviceDesign", + [3]byte{44, 228, 18}: "SAGEMCOM SAS", + [3]byte{44, 230, 204}: "Ruckus Wireless", + [3]byte{44, 232, 113}: "Alert Metalguard ApS", + [3]byte{44, 237, 235}: "Alpheus Digital Company Limited", + [3]byte{44, 238, 38}: "Petroleum Geo-Services", + [3]byte{44, 240, 238}: "Apple", + [3]byte{44, 242, 3}: "EMKO ELEKTRONIK SAN VE TIC AS", + [3]byte{44, 244, 197}: "Avaya, Inc", + [3]byte{44, 247, 241}: "Seeed Technology Inc.", + [3]byte{44, 250, 162}: "Alcatel-Lucent", + [3]byte{48, 5, 92}: "Brother industries, LTD.", + [3]byte{48, 11, 156}: "Delta Mobile Systems, Inc.", + [3]byte{48, 13, 42}: "Zhejiang Wellcom Technology Co.,Ltd.", + [3]byte{48, 14, 213}: "Hon Hai Precision Ind.Co.Ltd", + [3]byte{48, 16, 179}: "Liteon Technology Corporation", + [3]byte{48, 16, 228}: "Apple, Inc.", + [3]byte{48, 20, 45}: "Piciorgros GmbH", + [3]byte{48, 20, 74}: "Wistron Neweb Corp.", + [3]byte{48, 21, 24}: "Ubiquitous Communication Co. ltd.", + [3]byte{48, 22, 141}: "ProLon", + [3]byte{48, 23, 200}: "Sony Ericsson Mobile Communications AB", + [3]byte{48, 24, 207}: "DEOS control systems GmbH", + [3]byte{48, 25, 102}: "Samsung Electronics Co.,Ltd", + [3]byte{48, 26, 40}: "Mako Networks Ltd", + [3]byte{48, 33, 91}: "Shenzhen Ostar Display Electronic Co.,Ltd", + [3]byte{48, 45, 232}: "JDA, LLC (JDA Systems)", + [3]byte{48, 50, 148}: "W-IE-NE-R Plein & Baus GmbH", + [3]byte{48, 50, 212}: "Hanilstm Co., Ltd.", + [3]byte{48, 51, 53}: "Boosty", + [3]byte{48, 55, 166}: "CISCO SYSTEMS, INC.", + [3]byte{48, 56, 85}: "Nokia Corporation", + [3]byte{48, 57, 38}: "Sony Ericsson Mobile Communications AB", + [3]byte{48, 57, 85}: "Shenzhen Jinhengjia Electronic Co., Ltd.", + [3]byte{48, 57, 242}: "ADB Broadband Italia", + [3]byte{48, 58, 100}: "Intel Corporate", + [3]byte{48, 61, 8}: "GLINTT TES S.A.", + [3]byte{48, 62, 173}: "Sonavox Canada Inc", + [3]byte{48, 65, 116}: "ALTEC LANSING LLC", + [3]byte{48, 66, 37}: "BURG-WÄCHTER KG", + [3]byte{48, 68, 73}: "PLATH GmbH", + [3]byte{48, 70, 154}: "NETGEAR", + [3]byte{48, 73, 59}: "Nanjing Z-Com Wireless Co.,Ltd", + [3]byte{48, 76, 126}: "Panasonic Electric Works Automation Controls Techno Co.,Ltd.", + [3]byte{48, 78, 195}: "Tianjin Techua Technology Co., Ltd.", + [3]byte{48, 81, 248}: "BYK-Gardner GmbH", + [3]byte{48, 82, 90}: "NST Co., LTD", + [3]byte{48, 85, 237}: "Trex Network LLC", + [3]byte{48, 87, 172}: "IRLAB LTD.", + [3]byte{48, 89, 91}: "streamnow AG", + [3]byte{48, 89, 183}: "Microsoft", + [3]byte{48, 93, 56}: "Beissbarth", + [3]byte{48, 96, 35}: "ARRIS Group, Inc.", + [3]byte{48, 97, 18}: "PAV GmbH", + [3]byte{48, 97, 24}: "Paradom Inc.", + [3]byte{48, 101, 236}: "Wistron (ChongQing)", + [3]byte{48, 104, 140}: "Reach Technology Inc.", + [3]byte{48, 105, 75}: "RIM", + [3]byte{48, 108, 190}: "Skymotion Technology (HK) Limited", + [3]byte{48, 110, 92}: "Validus Technologies", + [3]byte{48, 113, 178}: "Hangzhou Prevail Optoelectronic Equipment Co.,LTD.", + [3]byte{48, 115, 80}: "Inpeco SA", + [3]byte{48, 117, 18}: "Sony Mobile Communications AB", + [3]byte{48, 118, 111}: "LG Electronics", + [3]byte{48, 119, 203}: "Maike Industry(Shenzhen)CO.,LTD", + [3]byte{48, 120, 107}: "TIANJIN Golden Pentagon Electronics Co., Ltd.", + [3]byte{48, 120, 194}: "Innowireless, Co. Ltd.", + [3]byte{48, 124, 48}: "RIM", + [3]byte{48, 126, 203}: "SFR", + [3]byte{48, 133, 169}: "Asustek Computer Inc", + [3]byte{48, 135, 48}: "Shenzhen Huawei Communication Technologies Co., Ltd", + [3]byte{48, 137, 153}: "Guangdong East Power Co.,", + [3]byte{48, 140, 251}: "Dropcam", + [3]byte{48, 144, 171}: "Apple", + [3]byte{48, 145, 143}: "Technicolor", + [3]byte{48, 146, 246}: "SHANGHAI SUNMON COMMUNICATION TECHNOGY CO.,LTD", + [3]byte{48, 155, 173}: "BBK Electronics Corp., Ltd.,", + [3]byte{48, 168, 219}: "Sony Mobile Communications AB", + [3]byte{48, 170, 189}: "Shanghai Reallytek Information Technology Co.,Ltd", + [3]byte{48, 174, 123}: "Deqing Dusun Electron CO., LTD", + [3]byte{48, 174, 246}: "Radio Mobile Access", + [3]byte{48, 178, 22}: "Hytec Geraetebau GmbH", + [3]byte{48, 179, 162}: "Shenzhen Heguang Measurement & Control Technology Co.,Ltd", + [3]byte{48, 181, 194}: "TP-LINK TECHNOLOGIES CO.,LTD.", + [3]byte{48, 181, 241}: "Aitexin Technology Co., Ltd", + [3]byte{48, 199, 80}: "MIC Technology Group", + [3]byte{48, 199, 174}: "Samsung Electronics Co.,Ltd", + [3]byte{48, 200, 42}: "Wi-Next s.r.l.", + [3]byte{48, 205, 167}: "Samsung Electronics ITS, Printer division", + [3]byte{48, 209, 126}: "HUAWEI TECHNOLOGIES CO.,LTD", + [3]byte{48, 211, 87}: "Logosol, Inc.", + [3]byte{48, 212, 106}: "Autosales Incorporated", + [3]byte{48, 213, 135}: "Samsung Electronics Co.,Ltd", + [3]byte{48, 214, 201}: "Samsung Electronics Co.,Ltd", + [3]byte{48, 222, 134}: "Cedac Software S.r.l.", + [3]byte{48, 228, 142}: "Vodafone UK", + [3]byte{48, 228, 219}: "CISCO SYSTEMS, INC.", + [3]byte{48, 235, 37}: "INTEK DIGITAL", + [3]byte{48, 239, 209}: "Alstom Strongwish (Shenzhen) Co., Ltd.", + [3]byte{48, 243, 29}: "zte corporation", + [3]byte{48, 243, 58}: "+plugg srl", + [3]byte{48, 244, 47}: "ESP", + [3]byte{48, 247, 13}: "Cisco Systems", + [3]byte{48, 247, 197}: "Apple", + [3]byte{48, 247, 215}: "Thread Technology Co., Ltd", + [3]byte{48, 249, 237}: "Sony Corporation", + [3]byte{48, 250, 183}: "Tunai Creative", + [3]byte{48, 253, 17}: "MACROTECH (USA) INC.", + [3]byte{52, 0, 163}: "HUAWEI TECHNOLOGIES CO.,LTD", + [3]byte{52, 2, 134}: "Intel Corporate", + [3]byte{52, 2, 155}: "CloudBerry Technologies Private Limited", + [3]byte{52, 7, 251}: "Ericsson AB", + [3]byte{52, 8, 4}: "D-Link Corporation", + [3]byte{52, 10, 255}: "Qingdao Hisense Communications Co.,Ltd", + [3]byte{52, 19, 168}: "Mediplan Limited", + [3]byte{52, 19, 232}: "Intel Corporate", + [3]byte{52, 21, 158}: "Apple", + [3]byte{52, 23, 235}: "Dell Inc", + [3]byte{52, 26, 76}: "SHENZHEN WEIBU ELECTRONICS CO.,LTD.", + [3]byte{52, 27, 34}: "Grandbeing Technology Co., Ltd", + [3]byte{52, 33, 9}: "Jensen Scandinavia AS", + [3]byte{52, 35, 135}: "Hon Hai Precision Ind. Co.,Ltd.", + [3]byte{52, 35, 186}: "Samsung Electro Mechanics co.,LTD.", + [3]byte{52, 37, 93}: "Shenzhen Loadcom Technology Co.,Ltd", + [3]byte{52, 40, 240}: "ATN International Limited", + [3]byte{52, 41, 234}: "MCD ELECTRONICS SP. Z O.O.", + [3]byte{52, 47, 110}: "Anywire corporation", + [3]byte{52, 49, 17}: "Samsung Electronics Co.,Ltd", + [3]byte{52, 49, 196}: "AVM GmbH", + [3]byte{52, 56, 175}: "Inlab Software GmbH", + [3]byte{52, 64, 181}: "IBM", + [3]byte{52, 70, 111}: "HiTEM Engineering", + [3]byte{52, 75, 61}: "Fiberhome Telecommunication Tech.Co.,Ltd.", + [3]byte{52, 75, 80}: "ZTE Corporation", + [3]byte{52, 77, 234}: "zte corporation", + [3]byte{52, 77, 247}: "LG Electronics", + [3]byte{52, 79, 63}: "IO-Power Technology Co., Ltd.", + [3]byte{52, 79, 92}: "R&M AG", + [3]byte{52, 79, 105}: "EKINOPS SAS", + [3]byte{52, 81, 170}: "JID GLOBAL", + [3]byte{52, 81, 201}: "Apple", + [3]byte{52, 91, 17}: "EVI HEAT AB", + [3]byte{52, 92, 64}: "Cargt Holdings LLC", + [3]byte{52, 93, 16}: "Wytek", + [3]byte{52, 97, 120}: "The Boeing Company", + [3]byte{52, 98, 136}: "Cisco", + [3]byte{52, 100, 169}: "Hewlett Packard", + [3]byte{52, 104, 74}: "Teraworks Co., Ltd.", + [3]byte{52, 107, 211}: "Huawei Technologies Co., Ltd", + [3]byte{52, 110, 138}: "Ecosense", + [3]byte{52, 111, 144}: "Cisco", + [3]byte{52, 111, 146}: "White Rodgers Division", + [3]byte{52, 117, 199}: "Avaya, Inc", + [3]byte{52, 118, 197}: "I-O DATA DEVICE, INC.", + [3]byte{52, 120, 119}: "O-NET Communications(Shenzhen) Limited", + [3]byte{52, 126, 57}: "Nokia Danmark A/S", + [3]byte{52, 129, 55}: "UNICARD SA", + [3]byte{52, 129, 196}: "AVM GmbH", + [3]byte{52, 130, 222}: "Kayo Technology, Inc.", + [3]byte{52, 131, 2}: "iFORCOM Co., Ltd", + [3]byte{52, 132, 70}: "Ericsson AB", + [3]byte{52, 134, 42}: "Heinz Lackmann GmbH & Co KG", + [3]byte{52, 136, 93}: "Logitech Far East", + [3]byte{52, 138, 174}: "SAGEMCOM SAS", + [3]byte{52, 149, 219}: "Logitec Corporation", + [3]byte{52, 151, 251}: "ADVANCED RF TECHNOLOGIES INC", + [3]byte{52, 153, 111}: "VPI Engineering", + [3]byte{52, 153, 215}: "Universal Flow Monitors, Inc.", + [3]byte{52, 154, 13}: "ZBD Displays Ltd", + [3]byte{52, 157, 144}: "Heinzmann GmbH & CO. KG", + [3]byte{52, 161, 131}: "AWare, Inc", + [3]byte{52, 163, 191}: "Terewave. Inc.", + [3]byte{52, 165, 93}: "TECHNOSOFT INTERNATIONAL SRL", + [3]byte{52, 165, 225}: "Sensorist ApS", + [3]byte{52, 166, 140}: "Shine Profit Development Limited", + [3]byte{52, 167, 9}: "Trevil srl", + [3]byte{52, 167, 186}: "Fischer International Systems Corporation", + [3]byte{52, 168, 67}: "KYOCERA Display Corporation", + [3]byte{52, 168, 78}: "Cisco", + [3]byte{52, 170, 139}: "Samsung Electronics Co.,Ltd", + [3]byte{52, 170, 153}: "Alcatel-Lucent", + [3]byte{52, 170, 238}: "Mikrovisatos Servisas UAB", + [3]byte{52, 173, 228}: "Shanghai Chint Power Systems Co., Ltd.", + [3]byte{52, 175, 44}: "Nintendo Co., Ltd.", + [3]byte{52, 177, 247}: "Texas Instruments", + [3]byte{52, 181, 113}: "PLDS", + [3]byte{52, 183, 253}: "Guangzhou Younghead Electronic Technology Co.,Ltd", + [3]byte{52, 186, 81}: "Se-Kure Controls, Inc.", + [3]byte{52, 186, 154}: "Asiatelco Technologies Co.", + [3]byte{52, 187, 31}: "Research In Motion", + [3]byte{52, 187, 38}: "Motorola Mobility LLC", + [3]byte{52, 188, 166}: "Beijing Ding Qing Technology, Ltd.", + [3]byte{52, 189, 200}: "Cisco Systems", + [3]byte{52, 189, 249}: "Shanghai WDK Industrial Co.,Ltd.", + [3]byte{52, 189, 250}: "Cisco SPVTG", + [3]byte{52, 190, 0}: "Samsung Electronics Co.,Ltd", + [3]byte{52, 191, 144}: "Fiberhome Telecommunication Tech.Co.,Ltd.", + [3]byte{52, 192, 89}: "Apple", + [3]byte{52, 195, 172}: "Samsung Electronics", + [3]byte{52, 197, 208}: "Hagleitner Hygiene International GmbH", + [3]byte{52, 198, 154}: "Enecsys Ltd", + [3]byte{52, 199, 49}: "ALPS Co,. Ltd.", + [3]byte{52, 200, 3}: "Nokia Corporation", + [3]byte{52, 201, 157}: "EIDOLON COMMUNICATIONS TECHNOLOGY CO. LTD.", + [3]byte{52, 205, 109}: "CommSky Technologies", + [3]byte{52, 205, 190}: "Huawei Technologies Co., Ltd", + [3]byte{52, 206, 148}: "Parsec (Pty) Ltd", + [3]byte{52, 208, 155}: "MobilMAX Technology Inc.", + [3]byte{52, 210, 196}: "RENA GmbH Print Systeme", + [3]byte{52, 215, 180}: "Tributary Systems, Inc.", + [3]byte{52, 219, 253}: "Cisco", + [3]byte{52, 222, 26}: "Intel Corporate", + [3]byte{52, 222, 52}: "zte corporation", + [3]byte{52, 223, 42}: "Fujikon Industrial Co.,Limited", + [3]byte{52, 224, 207}: "zte corporation", + [3]byte{52, 224, 215}: "DONGGUAN QISHENG ELECTRONICS INDUSTRIAL CO., LTD", + [3]byte{52, 226, 253}: "Apple", + [3]byte{52, 228, 42}: "Automatic Bar Controls Inc.", + [3]byte{52, 230, 173}: "Intel Corporate", + [3]byte{52, 230, 215}: "Dell Inc.", + [3]byte{52, 239, 68}: "2Wire", + [3]byte{52, 239, 139}: "NTT Communications Corporation", + [3]byte{52, 240, 202}: "Shenzhen Linghangyuan Digital Technology Co.,Ltd.", + [3]byte{52, 243, 155}: "WizLAN Ltd.", + [3]byte{52, 246, 45}: "SHARP Corporation", + [3]byte{52, 246, 210}: "Panasonic Taiwan Co.,Ltd.", + [3]byte{52, 249, 104}: "ATEK Products, LLC", + [3]byte{52, 250, 64}: "Guangzhou Robustel Technologies Co., Limited", + [3]byte{52, 252, 111}: "ALCEA", + [3]byte{56, 1, 151}: "Toshiba Samsung Storage Technolgoy Korea Corporation", + [3]byte{56, 6, 180}: "A.D.C. GmbH", + [3]byte{56, 8, 253}: "Silca Spa", + [3]byte{56, 10, 10}: "Sky-City Communication and Electronics Limited Company", + [3]byte{56, 10, 148}: "Samsung Electronics Co.,Ltd", + [3]byte{56, 11, 64}: "Samsung Electronics Co.,Ltd", + [3]byte{56, 13, 212}: "Primax Electronics LTD.", + [3]byte{56, 14, 123}: "V.P.S. Thai Co., Ltd", + [3]byte{56, 15, 74}: "Apple", + [3]byte{56, 15, 228}: "Dedicated Network Partners Oy", + [3]byte{56, 22, 209}: "Samsung Electronics Co.,Ltd", + [3]byte{56, 23, 102}: "PROMZAKAZ LTD.", + [3]byte{56, 25, 47}: "Nokia Corporation", + [3]byte{56, 28, 26}: "Cisco", + [3]byte{56, 28, 74}: "SIMCom Wireless Solutions Co.,Ltd.", + [3]byte{56, 34, 157}: "Pirelli Tyre S.p.A.", + [3]byte{56, 34, 214}: "H3C Technologies Co., Limited", + [3]byte{56, 38, 43}: "UTran Technology", + [3]byte{56, 38, 205}: "ANDTEK", + [3]byte{56, 40, 234}: "Fujian Netcom Technology Co., LTD", + [3]byte{56, 44, 74}: "ASUSTek COMPUTER INC.", + [3]byte{56, 45, 209}: "Samsung Electronics Co.,Ltd", + [3]byte{56, 49, 172}: "WEG", + [3]byte{56, 59, 200}: "2wire", + [3]byte{56, 63, 16}: "DBL Technology Ltd.", + [3]byte{56, 66, 51}: "Wildeboer Bauteile GmbH", + [3]byte{56, 66, 166}: "Ingenieurbuero Stahlkopf", + [3]byte{56, 67, 105}: "Patrol Products Consortium LLC", + [3]byte{56, 69, 140}: "MyCloud Technology corporation", + [3]byte{56, 70, 8}: "ZTE Corporation", + [3]byte{56, 72, 76}: "Apple", + [3]byte{56, 75, 118}: "AIRTAME ApS", + [3]byte{56, 79, 240}: "Azurewave Technologies, Inc.", + [3]byte{56, 82, 26}: "Alcatel-Lucent 7705", + [3]byte{56, 88, 12}: "Panaccess Systems GmbH", + [3]byte{56, 89, 248}: "MindMade sp. z o.o.", + [3]byte{56, 89, 249}: "Hon Hai Precision Ind. Co.,Ltd.", + [3]byte{56, 90, 168}: "Beijing Zhongdun Security Technology Development Co.", + [3]byte{56, 95, 195}: "Yu Jeong System, Co.Ltd", + [3]byte{56, 96, 119}: "PEGATRON CORPORATION", + [3]byte{56, 99, 187}: "Hewlett Packard", + [3]byte{56, 99, 246}: "3NOD MULTIMEDIA(SHENZHEN)CO.,LTD", + [3]byte{56, 102, 69}: "OOSIC Technology CO.,Ltd", + [3]byte{56, 103, 147}: "Asia Optical Co., Inc.", + [3]byte{56, 107, 187}: "ARRIS Group, Inc.", + [3]byte{56, 108, 155}: "Ivy Biomedical", + [3]byte{56, 110, 33}: "Wasion Group Ltd.", + [3]byte{56, 114, 192}: "COMTREND", + [3]byte{56, 123, 71}: "AKELA, Inc.", + [3]byte{56, 131, 69}: "TP-LINK TECHNOLOGIES CO., LTD.", + [3]byte{56, 137, 220}: "Opticon Sensors Europe B.V.", + [3]byte{56, 138, 183}: "ITC Networks", + [3]byte{56, 142, 231}: "Fanhattan LLC", + [3]byte{56, 145, 251}: "Xenox Holding BV", + [3]byte{56, 148, 150}: "Samsung Elec Co.,Ltd", + [3]byte{56, 149, 146}: "Beijing Tendyron Corporation", + [3]byte{56, 159, 131}: "OTN Systems N.V.", + [3]byte{56, 165, 60}: "Veenstra Instruments", + [3]byte{56, 165, 182}: "SHENZHEN MEGMEET ELECTRICAL CO.,LTD", + [3]byte{56, 168, 81}: "Moog, Ing", + [3]byte{56, 168, 107}: "Orga BV", + [3]byte{56, 169, 95}: "Actifio Inc", + [3]byte{56, 170, 60}: "SAMSUNG ELECTRO-MECHANICS", + [3]byte{56, 177, 45}: "Sonotronic Nagel GmbH", + [3]byte{56, 177, 219}: "Hon Hai Precision Ind. Co.,Ltd.", + [3]byte{56, 181, 189}: "E.G.O. Elektro-Ger", + [3]byte{56, 183, 77}: "Fijowave Limited", + [3]byte{56, 187, 35}: "OzVision America LLC", + [3]byte{56, 187, 60}: "Avaya, Inc", + [3]byte{56, 188, 26}: "Meizu technology co.,ltd", + [3]byte{56, 191, 47}: "Espec Corp.", + [3]byte{56, 191, 51}: "NEC CASIO Mobile Communications", + [3]byte{56, 192, 150}: "ALPS ELECTRIC CO.,LTD.", + [3]byte{56, 199, 186}: "CS Services Co.,Ltd.", + [3]byte{56, 200, 92}: "Cisco SPVTG", + [3]byte{56, 201, 169}: "SMART High Reliability Solutions, Inc.", + [3]byte{56, 202, 151}: "Contour Design LLC", + [3]byte{56, 209, 53}: "EasyIO Corporation Sdn. Bhd.", + [3]byte{56, 219, 187}: "Sunbow Telecom Co., Ltd.", + [3]byte{56, 222, 96}: "Mohlenhoff GmbH", + [3]byte{56, 224, 142}: "Mitsubishi Electric Corporation", + [3]byte{56, 229, 149}: "Shenzhen Gongjin Electronics Co.,Ltd", + [3]byte{56, 231, 216}: "HTC Corporation", + [3]byte{56, 232, 223}: "b gmbh medien + datenbanken", + [3]byte{56, 233, 140}: "Reco S.p.A.", + [3]byte{56, 234, 167}: "Hewlett Packard", + [3]byte{56, 236, 17}: "Novatek Microelectronics Corp.", + [3]byte{56, 236, 228}: "Samsung Electronics", + [3]byte{56, 238, 157}: "Anedo Ltd.", + [3]byte{56, 240, 152}: "Vapor Stone Rail Systems", + [3]byte{56, 243, 63}: "TATSUNO CORPORATION", + [3]byte{56, 245, 151}: "home2net GmbH", + [3]byte{56, 247, 8}: "National Resource Management, Inc.", + [3]byte{56, 248, 137}: "Huawei Technologies Co., Ltd", + [3]byte{56, 248, 183}: "V2COM PARTICIPACOES S.A.", + [3]byte{56, 254, 197}: "Ellips B.V.", + [3]byte{60, 2, 177}: "Creation Technologies LP", + [3]byte{60, 4, 191}: "PRAVIS SYSTEMS Co.Ltd.,", + [3]byte{60, 5, 171}: "Product Creation Studio", + [3]byte{60, 7, 84}: "Apple", + [3]byte{60, 7, 113}: "Sony Corporation", + [3]byte{60, 8, 30}: "Beijing Yupont Electric Power Technology Co.,Ltd", + [3]byte{60, 8, 246}: "Cisco", + [3]byte{60, 9, 109}: "Powerhouse Dynamics", + [3]byte{60, 12, 72}: "Servergy, Inc.", + [3]byte{60, 14, 35}: "Cisco", + [3]byte{60, 15, 193}: "KBC Networks", + [3]byte{60, 16, 64}: "daesung network", + [3]byte{60, 16, 111}: "ALBAHITH TECHNOLOGIES", + [3]byte{60, 21, 194}: "Apple", + [3]byte{60, 21, 234}: "TESCOM CO., LTD.", + [3]byte{60, 24, 159}: "Nokia Corporation", + [3]byte{60, 24, 160}: "Luxshare Precision Industry Co.,Ltd.", + [3]byte{60, 25, 21}: "GFI Chrono Time", + [3]byte{60, 25, 125}: "Ericsson AB", + [3]byte{60, 26, 87}: "Cardiopulmonary Corp", + [3]byte{60, 26, 121}: "Huayuan Technology CO.,LTD", + [3]byte{60, 28, 190}: "JADAK LLC", + [3]byte{60, 30, 19}: "HANGZHOU SUNRISE TECHNOLOGY CO., LTD", + [3]byte{60, 37, 215}: "Nokia Corporation", + [3]byte{60, 38, 213}: "Sotera Wireless", + [3]byte{60, 39, 99}: "SLE quality engineering GmbH & Co. KG", + [3]byte{60, 45, 183}: "Texas Instruments", + [3]byte{60, 47, 58}: "SFORZATO Corp.", + [3]byte{60, 48, 12}: "Dewar Electronics Pty Ltd", + [3]byte{60, 54, 61}: "Nokia Corporation", + [3]byte{60, 54, 228}: "Arris Group, Inc.", + [3]byte{60, 56, 136}: "ConnectQuest, llc", + [3]byte{60, 57, 195}: "JW Electronics Co., Ltd.", + [3]byte{60, 57, 231}: "IEEE REGISTRATION AUTHORITY - Please see MAM public listing for more information.", + [3]byte{60, 58, 115}: "Avaya, Inc", + [3]byte{60, 64, 79}: "Guangdong Pisen Electronics Co. Ltd.", + [3]byte{60, 67, 142}: "ARRIS Group, Inc.", + [3]byte{60, 70, 216}: "TP-LINK TECHNOLOGIES CO.,LTD.", + [3]byte{60, 73, 55}: "ASSMANN Electronic GmbH", + [3]byte{60, 74, 146}: "Hewlett-Packard Company", + [3]byte{60, 76, 105}: "Infinity System S.L.", + [3]byte{60, 78, 71}: "Etronic A/S", + [3]byte{60, 87, 189}: "Kessler Crane Inc.", + [3]byte{60, 87, 213}: "FiveCo", + [3]byte{60, 90, 55}: "Samsung Electronics", + [3]byte{60, 90, 180}: "Google", + [3]byte{60, 95, 1}: "Synerchip Co., Ltd.", + [3]byte{60, 97, 4}: "Juniper Networks", + [3]byte{60, 98, 0}: "Samsung electronics CO., LTD", + [3]byte{60, 98, 120}: "SHENZHEN JETNET TECHNOLOGY CO.,LTD.", + [3]byte{60, 103, 44}: "Sciovid Inc.", + [3]byte{60, 106, 125}: "Niigata Power Systems Co., Ltd.", + [3]byte{60, 110, 99}: "Mitron OY", + [3]byte{60, 111, 69}: "Fiberpro Inc.", + [3]byte{60, 111, 247}: "EnTek Systems, Inc.", + [3]byte{60, 112, 89}: "MakerBot Industries", + [3]byte{60, 116, 55}: "RIM", + [3]byte{60, 117, 74}: "ARRIS Group, Inc.", + [3]byte{60, 119, 230}: "Hon Hai Precision Ind. Co.,Ltd.", + [3]byte{60, 125, 177}: "Texas Instruments", + [3]byte{60, 129, 216}: "SAGEMCOM SAS", + [3]byte{60, 131, 181}: "Advance Vision Electronics Co. Ltd.", + [3]byte{60, 134, 168}: "Sangshin elecom .co,, LTD", + [3]byte{60, 137, 166}: "KAPELSE", + [3]byte{60, 138, 176}: "Juniper Networks", + [3]byte{60, 138, 229}: "Tensun Information Technology(Hangzhou) Co.,LTD", + [3]byte{60, 139, 254}: "Samsung Electronics", + [3]byte{60, 145, 87}: "Hangzhou Yulong Conmunication Co.,Ltd", + [3]byte{60, 145, 116}: "ALONG COMMUNICATION TECHNOLOGY", + [3]byte{60, 148, 213}: "Juniper Networks", + [3]byte{60, 151, 14}: "Wistron InfoComm(Kunshan)Co.,Ltd.", + [3]byte{60, 151, 126}: "IPS Technology Limited", + [3]byte{60, 152, 191}: "Quest Controls, Inc.", + [3]byte{60, 153, 247}: "Lansentechnology AB", + [3]byte{60, 159, 129}: "Shenzhen CATIC Bit Communications Technology Co.,Ltd", + [3]byte{60, 161, 13}: "Samsung Electronics Co.,Ltd", + [3]byte{60, 163, 21}: "Bless Information & Communications Co., Ltd", + [3]byte{60, 167, 43}: "MRV Communications (Networks) LTD", + [3]byte{60, 169, 244}: "Intel Corporate", + [3]byte{60, 170, 63}: "iKey, Ltd.", + [3]byte{60, 171, 142}: "Apple", + [3]byte{60, 174, 105}: "ESA Elektroschaltanlagen Grimma GmbH", + [3]byte{60, 177, 91}: "Avaya, Inc", + [3]byte{60, 177, 127}: "Wattwatchers Pty Ld", + [3]byte{60, 184, 122}: "PRIVATE", + [3]byte{60, 185, 166}: "Belden Deutschland GmbH", + [3]byte{60, 189, 216}: "LG ELECTRONICS INC", + [3]byte{60, 192, 198}: "d&b audiotechnik GmbH", + [3]byte{60, 193, 44}: "AES Corporation", + [3]byte{60, 193, 246}: "Melange Systems Pvt. Ltd.", + [3]byte{60, 194, 67}: "Nokia Corporation", + [3]byte{60, 201, 158}: "Huiyang Technology Co., Ltd", + [3]byte{60, 202, 135}: "Iders Incorporated", + [3]byte{60, 205, 90}: "Technische Alternative GmbH", + [3]byte{60, 205, 147}: "LG ELECTRONICS INC", + [3]byte{60, 206, 115}: "CISCO SYSTEMS, INC.", + [3]byte{60, 208, 248}: "Apple", + [3]byte{60, 209, 110}: "Telepower Communication Co., Ltd", + [3]byte{60, 212, 214}: "WirelessWERX, Inc", + [3]byte{60, 215, 218}: "SK Mtek microelectronics(shenzhen)limited", + [3]byte{60, 217, 43}: "Hewlett-Packard Company", + [3]byte{60, 217, 206}: "Eclipse WiFi", + [3]byte{60, 223, 30}: "CISCO SYSTEMS, INC.", + [3]byte{60, 223, 189}: "Huawei Technologies Co., Ltd", + [3]byte{60, 224, 114}: "Apple", + [3]byte{60, 229, 166}: "Hangzhou H3C Technologies Co., Ltd.", + [3]byte{60, 229, 180}: "KIDASEN INDUSTRIA E COMERCIO DE ANTENAS LTDA", + [3]byte{60, 230, 36}: "LG Display", + [3]byte{60, 234, 79}: "2Wire", + [3]byte{60, 234, 251}: "NSE AG", + [3]byte{60, 243, 146}: "Virtualtek. Co. Ltd", + [3]byte{60, 245, 44}: "DSPECIALISTS GmbH", + [3]byte{60, 247, 42}: "Nokia Corporation", + [3]byte{60, 247, 72}: "Shenzhen Linsn Technology Development Co.,Ltd", + [3]byte{60, 248, 8}: "HUAWEI TECHNOLOGIES CO.,LTD", + [3]byte{60, 251, 150}: "Emcraft Systems LLC", + [3]byte{64, 1, 7}: "Arista Corp", + [3]byte{64, 1, 198}: "3COM EUROPE LTD", + [3]byte{64, 4, 12}: "A&T", + [3]byte{64, 7, 192}: "Railtec Systems GmbH", + [3]byte{64, 14, 103}: "Tremol Ltd.", + [3]byte{64, 14, 133}: "Samsung Electro Mechanics co.,LTD.", + [3]byte{64, 18, 228}: "Compass-EOS", + [3]byte{64, 19, 217}: "Global ES", + [3]byte{64, 21, 151}: "Protect America, Inc.", + [3]byte{64, 22, 126}: "ASUSTek COMPUTER INC.", + [3]byte{64, 22, 159}: "TP-LINK TECHNOLOGIES CO., LTD.", + [3]byte{64, 22, 250}: "EKM Metering", + [3]byte{64, 24, 177}: "Aerohive Networks Inc.", + [3]byte{64, 24, 215}: "Wyle Telemetry and Data Systems", + [3]byte{64, 29, 89}: "Biometric Associates, LP", + [3]byte{64, 34, 237}: "Digital Projection Ltd", + [3]byte{64, 37, 194}: "Intel Corporate", + [3]byte{64, 39, 11}: "Mobileeco Co., Ltd", + [3]byte{64, 43, 161}: "Sony Ericsson Mobile Communications AB", + [3]byte{64, 44, 244}: "Universal Global Scientific Industrial Co., Ltd.", + [3]byte{64, 48, 4}: "Apple", + [3]byte{64, 48, 103}: "Conlog (Pty) Ltd", + [3]byte{64, 51, 108}: "Godrej & Boyce Mfg. co. ltd", + [3]byte{64, 55, 173}: "Macro Image Technology, Inc.", + [3]byte{64, 60, 252}: "Apple", + [3]byte{64, 64, 34}: "ZIV", + [3]byte{64, 64, 107}: "Icomera", + [3]byte{64, 69, 218}: "Spreadtrum Communications (Shanghai) Co., Ltd.", + [3]byte{64, 74, 3}: "ZyXEL Communications Corporation", + [3]byte{64, 74, 24}: "Addrek Smart Solutions", + [3]byte{64, 77, 142}: "Shenzhen Huawei Communication Technologies Co., Ltd", + [3]byte{64, 78, 235}: "Higher Way Electronic Co., Ltd.", + [3]byte{64, 80, 224}: "Milton Security Group LLC", + [3]byte{64, 81, 108}: "Grandex International Corporation", + [3]byte{64, 82, 13}: "Pico Technology", + [3]byte{64, 85, 57}: "CISCO SYSTEMS, INC.", + [3]byte{64, 86, 12}: "In Home Displays Ltd", + [3]byte{64, 90, 155}: "ANOVO", + [3]byte{64, 95, 190}: "RIM", + [3]byte{64, 95, 194}: "Texas Instruments", + [3]byte{64, 96, 90}: "Hawkeye Tech Co. Ltd", + [3]byte{64, 97, 134}: "MICRO-STAR INT'L CO.,LTD", + [3]byte{64, 97, 142}: "Stella-Green Co", + [3]byte{64, 102, 122}: "mediola - connected living AG", + [3]byte{64, 104, 38}: "Thales UK Limited", + [3]byte{64, 106, 171}: "RIM", + [3]byte{64, 108, 143}: "Apple", + [3]byte{64, 111, 42}: "Research In Motion", + [3]byte{64, 112, 9}: "ARRIS Group, Inc.", + [3]byte{64, 112, 74}: "Power Idea Technology Limited", + [3]byte{64, 112, 116}: "Life Technology (China) Co., Ltd", + [3]byte{64, 116, 150}: "aFUN TECHNOLOGY INC.", + [3]byte{64, 120, 106}: "Motorola Mobility LLC", + [3]byte{64, 120, 117}: "IMBEL - Industria de Material Belico do Brasil", + [3]byte{64, 122, 128}: "Nokia Corporation", + [3]byte{64, 123, 27}: "Mettle Networks Inc.", + [3]byte{64, 130, 86}: "Continental Automotive GmbH", + [3]byte{64, 131, 222}: "Motorola", + [3]byte{64, 132, 147}: "Clavister AB", + [3]byte{64, 136, 224}: "Beijing Ereneben Information Technology Limited Shenzhen Branch", + [3]byte{64, 138, 154}: "TITENG CO., Ltd.", + [3]byte{64, 139, 7}: "Actiontec Electronics, Inc", + [3]byte{64, 139, 246}: "Shenzhen TCL New Technology Co; Ltd.", + [3]byte{64, 149, 88}: "Aisino Corporation", + [3]byte{64, 151, 209}: "BK Electronics cc", + [3]byte{64, 152, 76}: "Casacom Solutions AG", + [3]byte{64, 152, 78}: "Texas Instruments", + [3]byte{64, 152, 123}: "Aisino Corporation", + [3]byte{64, 155, 13}: "Shenzhen Yourf Kwan Industrial Co., Ltd", + [3]byte{64, 159, 199}: "BAEKCHUN I&C Co., Ltd.", + [3]byte{64, 166, 164}: "PassivSystems Ltd", + [3]byte{64, 166, 217}: "Apple", + [3]byte{64, 168, 240}: "Hewlett Packard", + [3]byte{64, 172, 141}: "Data Management, Inc.", + [3]byte{64, 176, 250}: "LG Electronics", + [3]byte{64, 178, 200}: "Nortel Networks", + [3]byte{64, 179, 149}: "Apple", + [3]byte{64, 179, 205}: "Chiyoda Electronics Co.,Ltd.", + [3]byte{64, 179, 252}: "Logital Co. Limited", + [3]byte{64, 180, 240}: "Juniper Networks", + [3]byte{64, 182, 177}: "SUNGSAM CO,.Ltd", + [3]byte{64, 183, 243}: "ARRIS Group, Inc.", + [3]byte{64, 186, 97}: "Arima Communications Corp.", + [3]byte{64, 188, 115}: "Cronoplast S.L.", + [3]byte{64, 188, 139}: "itelio GmbH", + [3]byte{64, 189, 158}: "Physio-Control, Inc", + [3]byte{64, 191, 23}: "Digistar Telecom. SA", + [3]byte{64, 194, 69}: "Shenzhen Hexicom Technology Co., Ltd.", + [3]byte{64, 196, 214}: "ChongQing Camyu Technology Development Co.,Ltd.", + [3]byte{64, 198, 42}: "Shanghai Jing Ren Electronic Technology Co., Ltd.", + [3]byte{64, 199, 201}: "Naviit Inc.", + [3]byte{64, 203, 168}: "Huawei Technologies Co., Ltd", + [3]byte{64, 205, 58}: "Z3 Technology", + [3]byte{64, 211, 45}: "Apple", + [3]byte{64, 212, 14}: "Biodata Ltd", + [3]byte{64, 213, 89}: "MICRO S.E.R.I.", + [3]byte{64, 216, 85}: "IEEE REGISTRATION AUTHORITY", + [3]byte{64, 226, 48}: "AzureWave Technologies, Inc.", + [3]byte{64, 231, 48}: "DEY Storage Systems, Inc.", + [3]byte{64, 231, 147}: "Shenzhen Siviton Technology Co.,Ltd", + [3]byte{64, 234, 206}: "FOUNDER BROADBAND NETWORK SERVICE CO.,LTD", + [3]byte{64, 236, 248}: "Siemens AG", + [3]byte{64, 239, 76}: "Fihonest communication co.,Ltd", + [3]byte{64, 240, 47}: "Liteon Technology Corporation", + [3]byte{64, 241, 76}: "ISE Europe SPRL", + [3]byte{64, 242, 1}: "SAGEMCOM", + [3]byte{64, 242, 233}: "IBM", + [3]byte{64, 243, 8}: "Murata Manufactuaring Co.,Ltd.", + [3]byte{64, 244, 7}: "Nintendo Co., Ltd.", + [3]byte{64, 244, 236}: "CISCO SYSTEMS, INC.", + [3]byte{64, 245, 46}: "Leica Microsystems (Schweiz) AG", + [3]byte{64, 252, 137}: "ARRIS Group, Inc.", + [3]byte{68, 3, 167}: "Cisco", + [3]byte{68, 12, 253}: "NetMan Co., Ltd.", + [3]byte{68, 17, 194}: "Telegartner Karl Gartner GmbH", + [3]byte{68, 19, 25}: "WKK TECHNOLOGY LTD.", + [3]byte{68, 24, 79}: "Fitview", + [3]byte{68, 25, 182}: "Hangzhou Hikvision Digital Technology Co.,Ltd.", + [3]byte{68, 30, 145}: "ARVIDA Intelligent Electronics Technology Co.,Ltd.", + [3]byte{68, 30, 161}: "Hewlett-Packard Company", + [3]byte{68, 35, 170}: "Farmage Co., Ltd.", + [3]byte{68, 37, 187}: "Bamboo Entertainment Corporation", + [3]byte{68, 41, 56}: "NietZsche enterprise Co.Ltd.", + [3]byte{68, 42, 96}: "Apple", + [3]byte{68, 42, 255}: "E3 Technology, Inc.", + [3]byte{68, 43, 3}: "CISCO SYSTEMS, INC.", + [3]byte{68, 49, 146}: "Hewlett Packard", + [3]byte{68, 50, 42}: "Avaya, Inc", + [3]byte{68, 50, 200}: "Technicolor USA Inc.", + [3]byte{68, 51, 76}: "Shenzhen Bilian electronic CO.,LTD", + [3]byte{68, 52, 143}: "MXT INDUSTRIAL LTDA", + [3]byte{68, 55, 25}: "2 Save Energy Ltd", + [3]byte{68, 55, 111}: "Young Electric Sign Co", + [3]byte{68, 55, 230}: "Hon Hai Precision Ind.Co.Ltd", + [3]byte{68, 56, 57}: "Cumulus Networks, inc", + [3]byte{68, 57, 196}: "Universal Global Scientific Industrial Co.,Ltd", + [3]byte{68, 60, 156}: "Pintsch Tiefenbach GmbH", + [3]byte{68, 61, 33}: "Nuvolt", + [3]byte{68, 62, 178}: "DEOTRON Co., LTD.", + [3]byte{68, 72, 145}: "HDMI Licensing, LLC", + [3]byte{68, 74, 101}: "Silverflare Ltd.", + [3]byte{68, 76, 12}: "Apple", + [3]byte{68, 78, 26}: "Samsung Electronics Co.,Ltd", + [3]byte{68, 79, 94}: "Pan Studios Co.,Ltd.", + [3]byte{68, 81, 219}: "Raytheon BBN Technologies", + [3]byte{68, 84, 192}: "Thompson Aerospace", + [3]byte{68, 86, 141}: "PNC Technologies Co., Ltd.", + [3]byte{68, 86, 183}: "Spawn Labs, Inc", + [3]byte{68, 88, 41}: "Cisco SPVTG", + [3]byte{68, 89, 159}: "Criticare Systems, Inc", + [3]byte{68, 94, 243}: "Tonalite Holding B.V.", + [3]byte{68, 95, 122}: "Shihlin Electric & Engineering Corp.", + [3]byte{68, 97, 50}: "ecobee inc", + [3]byte{68, 97, 156}: "FONsystem co. ltd.", + [3]byte{68, 102, 110}: "IP-LINE", + [3]byte{68, 103, 85}: "Orbit Irrigation", + [3]byte{68, 104, 171}: "JUIN COMPANY, LIMITED", + [3]byte{68, 108, 36}: "Reallin Electronic Co.,Ltd", + [3]byte{68, 109, 87}: "Liteon Technology Corporation", + [3]byte{68, 109, 108}: "Samsung Elec Co.,Ltd", + [3]byte{68, 112, 11}: "IFFU", + [3]byte{68, 112, 152}: "MING HONG TECHNOLOGY (SHEN ZHEN) LIMITED", + [3]byte{68, 116, 108}: "Sony Mobile Communications AB", + [3]byte{68, 123, 196}: "DualShine Technology(SZ)Co.,Ltd", + [3]byte{68, 124, 127}: "Innolight Technology Corporation", + [3]byte{68, 125, 165}: "VTION INFORMATION TECHNOLOGY (FUJIAN) CO.,LTD", + [3]byte{68, 126, 118}: "Trek Technology (S) Pte Ltd", + [3]byte{68, 126, 149}: "Alpha and Omega, Inc", + [3]byte{68, 131, 18}: "Star-Net", + [3]byte{68, 133, 0}: "Intel Corporate", + [3]byte{68, 134, 193}: "Siemens Low Voltage & Products", + [3]byte{68, 135, 252}: "ELITEGROUP COMPUTER SYSTEM CO., LTD.", + [3]byte{68, 136, 203}: "Camco Technologies NV", + [3]byte{68, 138, 91}: "Micro-Star INT'L CO., LTD.", + [3]byte{68, 140, 82}: "KTIS CO., Ltd", + [3]byte{68, 142, 18}: "DT Research, Inc.", + [3]byte{68, 142, 129}: "VIG", + [3]byte{68, 145, 219}: "Shanghai Huaqin Telecom Technology Co.,Ltd", + [3]byte{68, 148, 252}: "NETGEAR INC.,", + [3]byte{68, 149, 250}: "Qingdao Santong Digital Technology Co.Ltd", + [3]byte{68, 155, 120}: "The Now Factory", + [3]byte{68, 156, 181}: "Alcomp, Inc", + [3]byte{68, 164, 45}: "TCT Mobile Limited", + [3]byte{68, 166, 137}: "PROMAX ELECTRONICA SA", + [3]byte{68, 166, 229}: "THINKING TECHNOLOGY CO.,LTD", + [3]byte{68, 167, 207}: "Murata Manufacturing Co., Ltd.", + [3]byte{68, 168, 194}: "SEWOO TECH CO., LTD", + [3]byte{68, 170, 39}: "udworks Co., Ltd.", + [3]byte{68, 170, 232}: "Nanotec Electronic GmbH & Co. KG", + [3]byte{68, 173, 217}: "Cisco", + [3]byte{68, 179, 130}: "Kuang-chi Institute of Advanced Technology", + [3]byte{68, 193, 92}: "Texas Instruments", + [3]byte{68, 194, 51}: "Guangzhou Comet Technology Development Co.Ltd", + [3]byte{68, 195, 6}: "SIFROM Inc.", + [3]byte{68, 195, 155}: "OOO RUBEZH NPO", + [3]byte{68, 196, 169}: "Opticom Communication, LLC", + [3]byte{68, 197, 111}: "NGN Easy Satfinder (Tianjin) Electronic Co., Ltd", + [3]byte{68, 201, 162}: "Greenwald Industries", + [3]byte{68, 206, 125}: "SFR", + [3]byte{68, 209, 94}: "Shanghai Kingto Information Technology Ltd", + [3]byte{68, 210, 202}: "Anvia TV Oy", + [3]byte{68, 211, 202}: "CISCO SYSTEMS, INC.", + [3]byte{68, 212, 224}: "Sony Mobile Communications AB", + [3]byte{68, 214, 61}: "Talari Networks", + [3]byte{68, 216, 50}: "Azurewave Technologies, Inc.", + [3]byte{68, 216, 132}: "Apple", + [3]byte{68, 220, 145}: "PLANEX COMMUNICATIONS INC.", + [3]byte{68, 220, 203}: "SEMINDIA SYSTEMS PVT LTD", + [3]byte{68, 224, 142}: "Cisco SPVTG", + [3]byte{68, 225, 55}: "ARRIS Group, Inc.", + [3]byte{68, 228, 154}: "OMNITRONICS PTY LTD", + [3]byte{68, 228, 217}: "CISCO SYSTEMS, INC.", + [3]byte{68, 232, 165}: "Myreka Technologies Sdn. Bhd.", + [3]byte{68, 237, 87}: "Longicorn, inc.", + [3]byte{68, 238, 48}: "Budelmann Elektronik GmbH", + [3]byte{68, 244, 89}: "Samsung Electronics", + [3]byte{68, 248, 73}: "Union Pacific Railroad", + [3]byte{68, 251, 66}: "Apple", + [3]byte{72, 2, 42}: "B-Link Electronic Limited", + [3]byte{72, 3, 98}: "DESAY ELECTRONICS(HUIZHOU)CO.,LTD", + [3]byte{72, 12, 73}: "NAKAYO TELECOMMUNICATIONS,INC", + [3]byte{72, 18, 73}: "Luxcom Technologies Inc.", + [3]byte{72, 19, 243}: "BBK Electronics Corp., Ltd.", + [3]byte{72, 23, 76}: "MicroPower technologies", + [3]byte{72, 24, 66}: "Shanghai Winaas Co. Equipment Co. Ltd.", + [3]byte{72, 26, 132}: "Pointer Telocation Ltd", + [3]byte{72, 27, 210}: "Intron Scientific co., ltd.", + [3]byte{72, 38, 232}: "Tek-Air Systems, Inc.", + [3]byte{72, 40, 47}: "ZTE Corporation", + [3]byte{72, 44, 234}: "Motorola Inc Business Light Radios", + [3]byte{72, 51, 221}: "ZENNIO AVANCE Y TECNOLOGIA, S.L.", + [3]byte{72, 52, 61}: "IEP GmbH", + [3]byte{72, 61, 50}: "Syscor Controls & Automation", + [3]byte{72, 68, 135}: "Cisco SPVTG", + [3]byte{72, 68, 247}: "Samsung Electronics Co., LTD", + [3]byte{72, 70, 241}: "Uros Oy", + [3]byte{72, 70, 251}: "HUAWEI TECHNOLOGIES CO.,LTD", + [3]byte{72, 81, 183}: "Intel Corporate", + [3]byte{72, 82, 97}: "SOREEL", + [3]byte{72, 87, 221}: "Facebook", + [3]byte{72, 89, 41}: "LG Electronics", + [3]byte{72, 90, 63}: "WISOL", + [3]byte{72, 90, 182}: "Hon Hai Precision Ind. Co.,Ltd.", + [3]byte{72, 91, 57}: "ASUSTek COMPUTER INC.", + [3]byte{72, 93, 96}: "Azurewave Technologies, Inc.", + [3]byte{72, 96, 188}: "Apple", + [3]byte{72, 97, 163}: "Concern \"Axion\" JSC", + [3]byte{72, 98, 118}: "HUAWEI TECHNOLOGIES CO.,LTD", + [3]byte{72, 107, 44}: "BBK Electronics Corp., Ltd.,", + [3]byte{72, 107, 145}: "Fleetwood Group Inc.", + [3]byte{72, 110, 115}: "Pica8, Inc.", + [3]byte{72, 111, 210}: "StorSimple Inc", + [3]byte{72, 113, 25}: "SGB GROUP LTD.", + [3]byte{72, 116, 110}: "Apple", + [3]byte{72, 118, 4}: "PRIVATE", + [3]byte{72, 130, 68}: "Life Fitness / Div. of Brunswick", + [3]byte{72, 142, 66}: "DIGALOG GmbH", + [3]byte{72, 145, 83}: "Weinmann Geräte für Medizin GmbH + Co. KG", + [3]byte{72, 145, 246}: "Shenzhen Reach software technology CO.,LTD", + [3]byte{72, 155, 226}: "SCI Innovations Ltd", + [3]byte{72, 157, 24}: "Flashbay Limited", + [3]byte{72, 157, 36}: "Research In Motion", + [3]byte{72, 162, 45}: "Shenzhen Huaxuchang Telecom Technology Co.,Ltd", + [3]byte{72, 162, 183}: "Kodofon JSC", + [3]byte{72, 166, 210}: "GJsun Optical Science and Tech Co.,Ltd.", + [3]byte{72, 170, 93}: "Store Electronic Systems", + [3]byte{72, 178, 83}: "Marketaxess Corporation", + [3]byte{72, 181, 167}: "Glory Horse Industries Ltd.", + [3]byte{72, 184, 222}: "HOMEWINS TECHNOLOGY CO.,LTD.", + [3]byte{72, 185, 119}: "PulseOn Oy", + [3]byte{72, 185, 194}: "Teletics Inc.", + [3]byte{72, 190, 45}: "Symanitron", + [3]byte{72, 193, 172}: "PLANTRONICS, INC.", + [3]byte{72, 200, 98}: "Simo Wireless,Inc.", + [3]byte{72, 200, 182}: "SysTec GmbH", + [3]byte{72, 203, 110}: "Cello Electronics (UK) Ltd", + [3]byte{72, 208, 207}: "Universal Electronics, Inc.", + [3]byte{72, 209, 142}: "Metis Communication Co.,Ltd", + [3]byte{72, 210, 36}: "Liteon Technology Corporation", + [3]byte{72, 213, 76}: "Jeda Networks", + [3]byte{72, 215, 5}: "Apple", + [3]byte{72, 215, 255}: "BLANKOM Antennentechnik GmbH", + [3]byte{72, 216, 85}: "Telvent", + [3]byte{72, 216, 254}: "ClarIDy Solutions, Inc.", + [3]byte{72, 220, 251}: "Nokia Corporation", + [3]byte{72, 223, 28}: "Wuhan NEC Fibre Optic Communications industry Co. Ltd", + [3]byte{72, 225, 175}: "Vity", + [3]byte{72, 234, 99}: "Zhejiang Uniview Technologies Co., Ltd.", + [3]byte{72, 235, 48}: "ETERNA TECHNOLOGY, INC.", + [3]byte{72, 237, 128}: "daesung eltec", + [3]byte{72, 238, 7}: "Silver Palm Technologies LLC", + [3]byte{72, 238, 134}: "UTStarcom (China) Co.,Ltd", + [3]byte{72, 242, 48}: "Ubizcore Co.,LTD", + [3]byte{72, 243, 23}: "PRIVATE", + [3]byte{72, 244, 125}: "TechVision Holding Internation Limited", + [3]byte{72, 247, 241}: "Alcatel-Lucent", + [3]byte{72, 248, 179}: "Cisco-Linksys, LLC", + [3]byte{72, 248, 225}: "Alcatel Lucent WT", + [3]byte{72, 249, 37}: "Maestronic", + [3]byte{72, 252, 184}: "Woodstream Corporation", + [3]byte{72, 254, 234}: "HOMA B.V.", + [3]byte{76, 0, 130}: "Cisco", + [3]byte{76, 2, 46}: "CMR KOREA CO., LTD", + [3]byte{76, 2, 137}: "LEX COMPUTECH CO., LTD", + [3]byte{76, 6, 138}: "Basler Electric Company", + [3]byte{76, 7, 201}: "COMPUTER OFFICE Co.,Ltd.", + [3]byte{76, 9, 180}: "zte corporation", + [3]byte{76, 11, 58}: "TCT Mobile Limited", + [3]byte{76, 11, 190}: "Microsoft", + [3]byte{76, 13, 238}: "JABIL CIRCUIT (SHANGHAI) LTD.", + [3]byte{76, 15, 110}: "Hon Hai Precision Ind. Co.,Ltd.", + [3]byte{76, 15, 199}: "Earda Electronics Co.,Ltd", + [3]byte{76, 17, 191}: "ZHEJIANG DAHUA TECHNOLOGY CO.,LTD.", + [3]byte{76, 20, 128}: "NOREGON SYSTEMS, INC", + [3]byte{76, 20, 163}: "TCL Technoly Electronics (Huizhou) Co., Ltd.", + [3]byte{76, 22, 241}: "zte corporation", + [3]byte{76, 23, 235}: "SAGEMCOM", + [3]byte{76, 26, 58}: "PRIMA Research And Production Enterprise Ltd.", + [3]byte{76, 26, 149}: "Novakon Co., Ltd.", + [3]byte{76, 31, 204}: "HUAWEI TECHNOLOGIES CO.,LTD", + [3]byte{76, 33, 208}: "Sony Mobile Communications AB", + [3]byte{76, 34, 88}: "cozybit, Inc.", + [3]byte{76, 37, 120}: "Nokia Corporation", + [3]byte{76, 38, 231}: "Welgate Co., Ltd.", + [3]byte{76, 44, 128}: "Beijing Skyway Technologies Co.,Ltd", + [3]byte{76, 44, 131}: "Zhejiang KaNong Network Technology Co.,Ltd.", + [3]byte{76, 47, 157}: "ICM Controls", + [3]byte{76, 48, 137}: "Thales Transportation Systems GmbH", + [3]byte{76, 50, 45}: "TELEDATA NETWORKS", + [3]byte{76, 50, 217}: "M Rutty Holdings Pty. Ltd.", + [3]byte{76, 57, 9}: "HPL Electric & Power Private Limited", + [3]byte{76, 57, 16}: "Newtek Electronics co., Ltd.", + [3]byte{76, 59, 116}: "VOGTEC(H.K.) Co., Ltd", + [3]byte{76, 60, 22}: "Samsung Electronics Co.,Ltd", + [3]byte{76, 72, 218}: "Beijing Autelan Technology Co.,Ltd", + [3]byte{76, 75, 104}: "Mobile Device, Inc.", + [3]byte{76, 78, 53}: "Cisco", + [3]byte{76, 84, 39}: "Linepro Sp. z o.o.", + [3]byte{76, 84, 153}: "Shenzhen Huawei Communication Technologies Co., Ltd", + [3]byte{76, 85, 133}: "Hamilton Systems", + [3]byte{76, 85, 184}: "Turkcell Teknoloji", + [3]byte{76, 85, 204}: "ACKme Networks Pty Ltd", + [3]byte{76, 93, 205}: "Oy Finnish Electric Vehicle Technologies Ltd", + [3]byte{76, 94, 12}: "Routerboard.com", + [3]byte{76, 95, 210}: "Alcatel-Lucent", + [3]byte{76, 96, 213}: "airPointe of New Hampshire", + [3]byte{76, 96, 222}: "NETGEAR", + [3]byte{76, 98, 85}: "SANMINA-SCI SYSTEM DE MEXICO S.A. DE C.V.", + [3]byte{76, 99, 235}: "Application Solutions (Electronics and Vision) Ltd", + [3]byte{76, 100, 217}: "Guangdong Leawin Group Co., Ltd", + [3]byte{76, 110, 110}: "Comnect Technology CO.,LTD", + [3]byte{76, 114, 185}: "Pegatron Corporation", + [3]byte{76, 115, 103}: "Genius Bytes Software Solutions GmbH", + [3]byte{76, 115, 165}: "KOVE", + [3]byte{76, 116, 3}: "Mundo Reader (bq)", + [3]byte{76, 119, 79}: "Embedded Wireless Labs", + [3]byte{76, 120, 151}: "Arrowhead Alarm Products Ltd", + [3]byte{76, 121, 186}: "Intel Corporate", + [3]byte{76, 127, 98}: "Nokia Corporation", + [3]byte{76, 128, 79}: "Armstrong Monitoring Corp", + [3]byte{76, 128, 147}: "Intel Corporate", + [3]byte{76, 130, 207}: "Echostar Technologies", + [3]byte{76, 131, 222}: "Cisco SPVTG", + [3]byte{76, 139, 48}: "Actiontec Electronics, Inc", + [3]byte{76, 139, 85}: "Grupo Digicon", + [3]byte{76, 139, 239}: "Huawei Technologies Co., Ltd", + [3]byte{76, 141, 121}: "Apple", + [3]byte{76, 143, 165}: "Jastec", + [3]byte{76, 150, 20}: "Juniper Networks", + [3]byte{76, 152, 239}: "Zeo", + [3]byte{76, 158, 128}: "KYOKKO ELECTRIC Co., Ltd.", + [3]byte{76, 158, 228}: "Hanyang Navicom Co.,Ltd.", + [3]byte{76, 158, 255}: "ZyXEL Communications Corp", + [3]byte{76, 165, 109}: "Samsung Electronics Co.,Ltd", + [3]byte{76, 167, 75}: "Alcatel Lucent", + [3]byte{76, 170, 22}: "AzureWave Technologies (Shanghai) Inc.", + [3]byte{76, 171, 51}: "KST technology", + [3]byte{76, 172, 10}: "ZTE Corporation", + [3]byte{76, 177, 108}: "HUAWEI TECHNOLOGIES CO.,LTD", + [3]byte{76, 177, 153}: "Apple", + [3]byte{76, 180, 234}: "HRD (S) PTE., LTD.", + [3]byte{76, 184, 28}: "SAM Electronics GmbH", + [3]byte{76, 185, 200}: "CONET CO., LTD.", + [3]byte{76, 186, 163}: "Bison Electronics Inc.", + [3]byte{76, 187, 88}: "Chicony Electronics Co., Ltd.", + [3]byte{76, 188, 66}: "Shenzhen Hangsheng Electronics Co.,Ltd.", + [3]byte{76, 188, 165}: "Samsung Electronics Co.,Ltd", + [3]byte{76, 196, 82}: "Shang Hai Tyd. Electon Technology Ltd.", + [3]byte{76, 198, 2}: "Radios, Inc.", + [3]byte{76, 201, 79}: "Alcatel-Lucent", + [3]byte{76, 202, 83}: "Skyera, Inc.", + [3]byte{76, 203, 245}: "zte corporation", + [3]byte{76, 204, 52}: "Motorola Solutions Inc.", + [3]byte{76, 214, 55}: "Qsono Electronics Co., Ltd", + [3]byte{76, 215, 182}: "Helmer Scientific", + [3]byte{76, 217, 196}: "Magneti Marelli Automotive Electronics (Guangzhou) Co. Ltd", + [3]byte{76, 223, 61}: "TEAM ENGINEERS ADVANCE TECHNOLOGIES INDIA PVT LTD", + [3]byte{76, 225, 187}: "Zhuhai HiFocus Technology Co., Ltd.", + [3]byte{76, 226, 241}: "sclak srl", + [3]byte{76, 230, 118}: "Buffalo Inc.", + [3]byte{76, 233, 51}: "RailComm, LLC", + [3]byte{76, 235, 66}: "Intel Corporate", + [3]byte{76, 237, 222}: "Askey Computer Corp", + [3]byte{76, 240, 46}: "Vifa Denmark A/S", + [3]byte{76, 242, 191}: "Cambridge Industries(Group) Co.,Ltd.", + [3]byte{76, 244, 91}: "Blue Clover Devices", + [3]byte{76, 245, 160}: "Scalable Network Technologies Inc", + [3]byte{76, 247, 55}: "SamJi Electronics Co., Ltd", + [3]byte{80, 0, 140}: "Hong Kong Telecommunications (HKT) Limited", + [3]byte{80, 1, 187}: "Samsung Electronics", + [3]byte{80, 5, 61}: "CyWee Group Ltd", + [3]byte{80, 6, 4}: "Cisco", + [3]byte{80, 11, 50}: "Foxda Technology Industrial(ShenZhen)Co.,LTD", + [3]byte{80, 14, 109}: "TrafficCast International", + [3]byte{80, 17, 235}: "SilverNet Ltd", + [3]byte{80, 20, 181}: "Richfit Information Technology Co., Ltd", + [3]byte{80, 23, 255}: "Cisco", + [3]byte{80, 26, 197}: "Microsoft", + [3]byte{80, 28, 191}: "Cisco", + [3]byte{80, 32, 107}: "Emerson Climate Technologies Transportation Solutions", + [3]byte{80, 34, 103}: "PixeLINK", + [3]byte{80, 37, 43}: "Nethra Imaging Incorporated", + [3]byte{80, 38, 144}: "Fujitsu Limited", + [3]byte{80, 39, 199}: "TECHNART Co.,Ltd", + [3]byte{80, 41, 77}: "NANJING IOT SENSOR TECHNOLOGY CO,LTD", + [3]byte{80, 42, 126}: "Smart electronic GmbH", + [3]byte{80, 42, 139}: "Telekom Research and Development Sdn Bhd", + [3]byte{80, 45, 29}: "Nokia Corporation", + [3]byte{80, 45, 162}: "Intel Corporate", + [3]byte{80, 45, 244}: "Phytec Messtechnik GmbH", + [3]byte{80, 46, 92}: "HTC Corporation", + [3]byte{80, 46, 206}: "Asahi Electronics Co.,Ltd", + [3]byte{80, 50, 117}: "Samsung Electronics Co.,Ltd", + [3]byte{80, 57, 85}: "Cisco SPVTG", + [3]byte{80, 60, 196}: "Lenovo Mobile Communication Technology Ltd.", + [3]byte{80, 61, 229}: "CISCO SYSTEMS, INC.", + [3]byte{80, 63, 86}: "Syncmold Enterprise Corp", + [3]byte{80, 70, 93}: "ASUSTek COMPUTER INC.", + [3]byte{80, 72, 235}: "BEIJING HAIHEJINSHENG NETWORK TECHNOLOGY CO. LTD.", + [3]byte{80, 74, 94}: "Masimo Corporation", + [3]byte{80, 74, 110}: "NETGEAR INC.,", + [3]byte{80, 79, 148}: "Loxone Electronics GmbH", + [3]byte{80, 80, 101}: "TAKT Corporation", + [3]byte{80, 86, 99}: "Texas Instruments", + [3]byte{80, 86, 168}: "Jolla Ltd", + [3]byte{80, 86, 191}: "Samsung Electronics Co.,LTD", + [3]byte{80, 87, 168}: "CISCO SYSTEMS, INC.", + [3]byte{80, 88, 0}: "WyTec International, Inc.", + [3]byte{80, 90, 198}: "GUANGDONG SUPER TELECOM CO.,LTD.", + [3]byte{80, 96, 40}: "Xirrus Inc.", + [3]byte{80, 97, 132}: "Avaya, Inc", + [3]byte{80, 97, 214}: "Indu-Sol GmbH", + [3]byte{80, 99, 19}: "Hon Hai Precision Ind. Co.,Ltd.", + [3]byte{80, 100, 65}: "Greenlee", + [3]byte{80, 103, 135}: "iTellus", + [3]byte{80, 103, 174}: "Cisco", + [3]byte{80, 103, 240}: "ZyXEL Communications Corporation", + [3]byte{80, 111, 154}: "Wi-Fi Alliance", + [3]byte{80, 112, 229}: "He Shan World Fair Electronics Technology Limited", + [3]byte{80, 114, 77}: "BEG Brueck Electronic GmbH", + [3]byte{80, 118, 145}: "Tekpea, Inc.", + [3]byte{80, 118, 166}: "Ecil Informatica Ind. Com. Ltda", + [3]byte{80, 121, 91}: "Interexport Telecomunicaciones S.A.", + [3]byte{80, 125, 2}: "BIODIT", + [3]byte{80, 126, 93}: "Arcadyan Technology Corporation", + [3]byte{80, 133, 105}: "Samsung Electronics Co.,LTD", + [3]byte{80, 135, 137}: "Cisco", + [3]byte{80, 135, 184}: "Nuvyyo Inc", + [3]byte{80, 138, 66}: "Uptmate Technology Co., LTD", + [3]byte{80, 138, 203}: "SHENZHEN MAXMADE TECHNOLOGY CO., LTD.", + [3]byte{80, 140, 119}: "DIRMEIER Schanktechnik GmbH &Co KG", + [3]byte{80, 141, 111}: "CHAHOO Limited", + [3]byte{80, 147, 79}: "Gradual Tecnologia Ltda.", + [3]byte{80, 151, 114}: "Westinghouse Digital", + [3]byte{80, 152, 113}: "Inventum Technologies Private Limited", + [3]byte{80, 159, 39}: "Huawei Technologies Co., Ltd", + [3]byte{80, 160, 84}: "Actineon", + [3]byte{80, 160, 191}: "Alba Fiber Systems Inc.", + [3]byte{80, 164, 200}: "Samsung Electronics Co.,Ltd", + [3]byte{80, 166, 227}: "David Clark Company", + [3]byte{80, 167, 21}: "Aboundi, Inc.", + [3]byte{80, 167, 51}: "Ruckus Wireless", + [3]byte{80, 171, 191}: "Hoseo Telecom", + [3]byte{80, 173, 213}: "Dynalec Corporation", + [3]byte{80, 175, 115}: "Shenzhen Bitland Information Technology Co., Ltd.", + [3]byte{80, 182, 149}: "Micropoint Biotechnologies,Inc.", + [3]byte{80, 183, 195}: "Samsung Electronics CO., LTD", + [3]byte{80, 184, 136}: "wi2be Tecnologia S/A", + [3]byte{80, 184, 162}: "ImTech Technologies LLC,", + [3]byte{80, 189, 95}: "TP-LINK TECHNOLOGIES CO.,LTD.", + [3]byte{80, 192, 6}: "Carmanah Signs", + [3]byte{80, 194, 113}: "SECURETECH INC", + [3]byte{80, 197, 141}: "Juniper Networks", + [3]byte{80, 199, 191}: "TP-LINK TECHNOLOGIES CO.,LTD.", + [3]byte{80, 201, 113}: "GN Netcom A/S", + [3]byte{80, 201, 160}: "SKIPPER Electronics AS", + [3]byte{80, 204, 248}: "Samsung Electro Mechanics", + [3]byte{80, 205, 50}: "NanJing Chaoran Science & Technology Co.,Ltd.", + [3]byte{80, 206, 117}: "Measy Electronics Ltd", + [3]byte{80, 210, 116}: "Steffes Corporation", + [3]byte{80, 214, 215}: "Takahata Precision", + [3]byte{80, 224, 199}: "TurControlSystme AG", + [3]byte{80, 225, 74}: "PRIVATE", + [3]byte{80, 229, 73}: "GIGA-BYTE TECHNOLOGY CO.,LTD.", + [3]byte{80, 234, 214}: "Apple", + [3]byte{80, 235, 26}: "Brocade Communications Systems, Inc.", + [3]byte{80, 237, 120}: "Changzhou Yongse Infotech Co.,Ltd", + [3]byte{80, 237, 148}: "Egatel SL", + [3]byte{80, 240, 3}: "Open Stack, Inc.", + [3]byte{80, 244, 60}: "Leeo Inc", + [3]byte{80, 245, 32}: "Samsung Electronics Co.,Ltd", + [3]byte{80, 246, 26}: "Kunshan JADE Technologies co., Ltd.", + [3]byte{80, 250, 171}: "L-tek d.o.o.", + [3]byte{80, 252, 48}: "Treehouse Labs", + [3]byte{80, 252, 159}: "Samsung Electronics Co.,Ltd", + [3]byte{80, 254, 242}: "Sify Technologies Ltd", + [3]byte{84, 3, 245}: "EBN Technology Corp.", + [3]byte{84, 4, 150}: "Gigawave LTD", + [3]byte{84, 4, 166}: "ASUSTek COMPUTER INC.", + [3]byte{84, 5, 54}: "Vivago Oy", + [3]byte{84, 5, 95}: "Alcatel Lucent", + [3]byte{84, 9, 141}: "deister electronic GmbH", + [3]byte{84, 17, 47}: "Sulzer Pump Solutions Finland Oy", + [3]byte{84, 17, 95}: "Atamo Pty Ltd", + [3]byte{84, 27, 93}: "Techno-Innov", + [3]byte{84, 29, 251}: "Freestyle Energy Ltd", + [3]byte{84, 31, 213}: "Advantage Electronics", + [3]byte{84, 32, 24}: "Tely Labs", + [3]byte{84, 33, 96}: "Resolution Products", + [3]byte{84, 34, 248}: "zte corporation", + [3]byte{84, 38, 150}: "Apple", + [3]byte{84, 39, 30}: "AzureWave Technonloies, Inc.", + [3]byte{84, 42, 156}: "LSY Defense, LLC.", + [3]byte{84, 42, 162}: "Alpha Networks Inc.", + [3]byte{84, 44, 234}: "PROTECTRON", + [3]byte{84, 47, 137}: "Euclid Laboratories, Inc.", + [3]byte{84, 49, 49}: "Raster Vision Ltd", + [3]byte{84, 53, 48}: "Hon Hai Precision Ind. Co.,Ltd.", + [3]byte{84, 53, 223}: "Symeo GmbH", + [3]byte{84, 57, 104}: "Edgewater Networks Inc", + [3]byte{84, 57, 223}: "HUAWEI TECHNOLOGIES CO.,LTD", + [3]byte{84, 61, 55}: "Ruckus Wireless", + [3]byte{84, 66, 73}: "Sony Corporation", + [3]byte{84, 68, 8}: "Nokia Corporation", + [3]byte{84, 70, 107}: "Shenzhen CZTIC Electronic Technology Co., Ltd", + [3]byte{84, 74, 0}: "Cisco", + [3]byte{84, 74, 5}: "wenglor sensoric gmbh", + [3]byte{84, 74, 22}: "Texas Instruments", + [3]byte{84, 81, 70}: "AMG Systems Ltd.", + [3]byte{84, 83, 237}: "Sony Corporation", + [3]byte{84, 84, 20}: "Digital RF Corea, Inc", + [3]byte{84, 94, 189}: "NL Technologies", + [3]byte{84, 95, 169}: "Teracom Limited", + [3]byte{84, 97, 234}: "Zaplox AB", + [3]byte{84, 114, 79}: "Apple", + [3]byte{84, 115, 152}: "Toyo Electronics Corporation", + [3]byte{84, 116, 230}: "Webtech Wireless", + [3]byte{84, 117, 208}: "CISCO SYSTEMS, INC.", + [3]byte{84, 120, 26}: "Cisco", + [3]byte{84, 121, 117}: "Nokia Corporation", + [3]byte{84, 127, 84}: "INGENICO", + [3]byte{84, 127, 168}: "TELCO systems, s.r.o.", + [3]byte{84, 127, 238}: "CISCO SYSTEMS, INC.", + [3]byte{84, 129, 173}: "Eagle Research Corporation", + [3]byte{84, 132, 123}: "Digital Devices GmbH", + [3]byte{84, 136, 14}: "Samsung Electro Mechanics co., LTD.", + [3]byte{84, 137, 34}: "Zelfy Inc", + [3]byte{84, 137, 152}: "HUAWEI TECHNOLOGIES CO.,LTD", + [3]byte{84, 146, 190}: "Samsung Electronics Co.,Ltd", + [3]byte{84, 147, 89}: "SHENZHEN TWOWING TECHNOLOGIES CO.,LTD.", + [3]byte{84, 148, 120}: "Silvershore Technology Partners", + [3]byte{84, 154, 22}: "Uzushio Electric Co.,Ltd.", + [3]byte{84, 155, 18}: "Samsung Electronics", + [3]byte{84, 157, 133}: "EnerAccess inc", + [3]byte{84, 159, 53}: "Dell Inc.", + [3]byte{84, 160, 79}: "t-mac Technologies Ltd", + [3]byte{84, 160, 80}: "ASUSTek COMPUTER INC.", + [3]byte{84, 163, 27}: "Shenzhen Linkworld Technology Co,.LTD", + [3]byte{84, 165, 27}: "Shenzhen Huawei Communication Technologies Co., Ltd", + [3]byte{84, 165, 75}: "NSC Communications Siberia Ltd", + [3]byte{84, 166, 25}: "Alcatel-Lucent Shanghai Bell Co., Ltd", + [3]byte{84, 169, 212}: "Minibar Systems", + [3]byte{84, 174, 39}: "Apple", + [3]byte{84, 182, 32}: "SUHDOL E&C Co.Ltd.", + [3]byte{84, 183, 83}: "Hunan Fenghui Yinjia Science And Technology Co.,Ltd", + [3]byte{84, 190, 247}: "PEGATRON CORPORATION", + [3]byte{84, 200, 15}: "TP-LINK TECHNOLOGIES CO.,LTD.", + [3]byte{84, 205, 167}: "Fujian Shenzhou Electronic Co.,Ltd", + [3]byte{84, 205, 238}: "ShenZhen Apexis Electronic Co.,Ltd", + [3]byte{84, 208, 237}: "AXIM Communications", + [3]byte{84, 209, 99}: "MAX-TECH,INC", + [3]byte{84, 209, 176}: "Universal Laser Systems, Inc", + [3]byte{84, 212, 111}: "Cisco SPVTG", + [3]byte{84, 223, 0}: "Ulterius Technologies, LLC", + [3]byte{84, 223, 99}: "Intrakey technologies GmbH", + [3]byte{84, 224, 50}: "Juniper Networks", + [3]byte{84, 226, 224}: "Pace plc", + [3]byte{84, 227, 176}: "JVL Industri Elektronik", + [3]byte{84, 228, 58}: "Apple, Inc.", + [3]byte{84, 228, 189}: "FN-LINK TECHNOLOGY LIMITED", + [3]byte{84, 230, 63}: "ShenZhen LingKeWeiEr Technology Co., Ltd.", + [3]byte{84, 230, 252}: "TP-LINK TECHNOLOGIES CO., LTD.", + [3]byte{84, 234, 168}: "Apple, Inc.", + [3]byte{84, 238, 117}: "Wistron InfoComm(Kunshan)Co.,Ltd.", + [3]byte{84, 239, 146}: "Shenzhen Elink Technology Co., LTD", + [3]byte{84, 245, 182}: "ORIENTAL PACIFIC INTERNATIONAL LIMITED", + [3]byte{84, 246, 102}: "Berthold Technologies GmbH and Co.KG", + [3]byte{84, 248, 118}: "ABB AG", + [3]byte{84, 250, 62}: "Samsung Electronics Co.,LTD", + [3]byte{84, 251, 88}: "WISEWARE, Lda", + [3]byte{84, 253, 191}: "Scheidt & Bachmann GmbH", + [3]byte{84, 255, 207}: "Mopria Alliance", + [3]byte{88, 5, 40}: "LABRIS NETWORKS", + [3]byte{88, 5, 86}: "Elettronica GF S.r.L.", + [3]byte{88, 8, 250}: "Fiber Optic & telecommunication INC.", + [3]byte{88, 9, 67}: "PRIVATE", + [3]byte{88, 9, 229}: "Kivic Inc.", + [3]byte{88, 10, 32}: "Cisco", + [3]byte{88, 16, 140}: "Intelbras", + [3]byte{88, 18, 67}: "AcSiP Technology Corp.", + [3]byte{88, 22, 38}: "Avaya, Inc", + [3]byte{88, 23, 12}: "Sony Ericsson Mobile Communications AB", + [3]byte{88, 28, 189}: "Affinegy", + [3]byte{88, 29, 145}: "Advanced Mobile Telecom co.,ltd.", + [3]byte{88, 31, 103}: "Open-m technology limited", + [3]byte{88, 31, 170}: "Apple", + [3]byte{88, 31, 239}: "Tuttnaer LTD", + [3]byte{88, 33, 54}: "KMB systems, s.r.o.", + [3]byte{88, 35, 140}: "Technicolor CH USA", + [3]byte{88, 46, 254}: "Lighting Science Group", + [3]byte{88, 47, 66}: "Universal Electric Corporation", + [3]byte{88, 52, 59}: "Glovast Technology Ltd.", + [3]byte{88, 53, 217}: "CISCO SYSTEMS, INC.", + [3]byte{88, 60, 198}: "Omneality Ltd.", + [3]byte{88, 66, 228}: "Sigma International General Medical Apparatus, LLC.", + [3]byte{88, 70, 143}: "Koncar Electronics and Informatics", + [3]byte{88, 70, 225}: "Baxter Healthcare", + [3]byte{88, 72, 192}: "COFLEC", + [3]byte{88, 73, 59}: "Palo Alto Networks", + [3]byte{88, 73, 186}: "Chitai Electronic Corp.", + [3]byte{88, 76, 25}: "Chongqing Guohong Technology Development Company Limited", + [3]byte{88, 76, 238}: "Digital One Technologies, Limited", + [3]byte{88, 80, 118}: "Linear Equipamentos Eletronicos SA", + [3]byte{88, 80, 171}: "TLS Corporation", + [3]byte{88, 80, 230}: "Best Buy Corporation", + [3]byte{88, 85, 202}: "Apple", + [3]byte{88, 86, 232}: "ARRIS Group, Inc.", + [3]byte{88, 87, 13}: "Danfoss Solar Inverters", + [3]byte{88, 99, 154}: "TPL SYSTEMES", + [3]byte{88, 101, 230}: "INFOMARK CO., LTD.", + [3]byte{88, 102, 186}: "Hangzhou H3C Technologies Co., Limited", + [3]byte{88, 103, 26}: "BARNES&NOBLE.COM", + [3]byte{88, 103, 127}: "Clare Controls Inc.", + [3]byte{88, 105, 108}: "Fujian Ruijie Networks co, ltd", + [3]byte{88, 105, 249}: "Fusion Transactive Ltd.", + [3]byte{88, 106, 177}: "Hangzhou H3C Technologies Co., Limited", + [3]byte{88, 109, 143}: "Cisco-Linksys, LLC", + [3]byte{88, 110, 214}: "PRIVATE", + [3]byte{88, 117, 33}: "CJSC RTSoft", + [3]byte{88, 118, 117}: "Beijing ECHO Technologies Co.,Ltd", + [3]byte{88, 118, 197}: "DIGI I'S LTD", + [3]byte{88, 122, 77}: "Stonesoft Corporation", + [3]byte{88, 123, 233}: "AirPro Technology India Pvt. Ltd", + [3]byte{88, 126, 97}: "Hisense Electric Co., Ltd", + [3]byte{88, 127, 183}: "SONAR INDUSTRIAL CO., LTD.", + [3]byte{88, 127, 200}: "S2M", + [3]byte{88, 132, 228}: "IP500 Alliance e.V.", + [3]byte{88, 135, 76}: "LITE-ON CLEAN ENERGY TECHNOLOGY CORP.", + [3]byte{88, 135, 226}: "Shenzhen Coship Electronics Co., Ltd.", + [3]byte{88, 141, 9}: "CISCO SYSTEMS, INC.", + [3]byte{88, 145, 207}: "Intel Corporate", + [3]byte{88, 146, 13}: "Kinetic Avionics Limited", + [3]byte{88, 147, 150}: "Ruckus Wireless", + [3]byte{88, 148, 107}: "Intel Corporate", + [3]byte{88, 148, 207}: "Vertex Standard LMR, Inc.", + [3]byte{88, 151, 30}: "Cisco", + [3]byte{88, 152, 53}: "Technicolor", + [3]byte{88, 152, 111}: "Revolution Display", + [3]byte{88, 156, 252}: "FreeBSD Foundation", + [3]byte{88, 162, 181}: "LG Electronics", + [3]byte{88, 167, 111}: "iD corporation", + [3]byte{88, 176, 53}: "Apple", + [3]byte{88, 176, 212}: "ZuniData Systems Inc.", + [3]byte{88, 185, 97}: "SOLEM Electronique", + [3]byte{88, 185, 225}: "Crystalfontz America, Inc.", + [3]byte{88, 188, 39}: "CISCO SYSTEMS, INC.", + [3]byte{88, 189, 163}: "Nintendo Co., Ltd.", + [3]byte{88, 189, 249}: "Sigrand", + [3]byte{88, 191, 234}: "CISCO SYSTEMS, INC.", + [3]byte{88, 194, 50}: "NEC Corporation", + [3]byte{88, 195, 139}: "Samsung Electronics", + [3]byte{88, 207, 75}: "Lufkin Industries", + [3]byte{88, 208, 113}: "BW Broadcast", + [3]byte{88, 208, 143}: "IEEE 1904.1 Working Group", + [3]byte{88, 214, 211}: "Dairy Cheq Inc", + [3]byte{88, 219, 141}: "Fast Co., Ltd.", + [3]byte{88, 224, 44}: "Micro Technic A/S", + [3]byte{88, 227, 38}: "Compass Technologies Inc.", + [3]byte{88, 228, 118}: "CENTRON COMMUNICATIONS TECHNOLOGIES FUJIAN CO.,LTD", + [3]byte{88, 230, 54}: "EVRsafe Technologies", + [3]byte{88, 231, 71}: "Deltanet AG", + [3]byte{88, 232, 8}: "AUTONICS CORPORATION", + [3]byte{88, 235, 20}: "Proteus Digital Health", + [3]byte{88, 236, 225}: "Newport Corporation", + [3]byte{88, 238, 206}: "Icon Time Systems", + [3]byte{88, 243, 135}: "HCCP", + [3]byte{88, 243, 156}: "Cisco", + [3]byte{88, 246, 123}: "Xia Men UnionCore Technology LTD.", + [3]byte{88, 246, 191}: "Kyoto University", + [3]byte{88, 249, 142}: "SECUDOS GmbH", + [3]byte{88, 252, 219}: "IEEE REGISTRATION AUTHORITY - Please see MAM public listing for more information.", + [3]byte{88, 253, 32}: "Bravida Sakerhet AB", + [3]byte{92, 2, 106}: "Applied Vision Corporation", + [3]byte{92, 7, 111}: "Thought Creator", + [3]byte{92, 10, 91}: "SAMSUNG ELECTRO-MECHANICS CO., LTD.", + [3]byte{92, 12, 187}: "CELIZION Inc.", + [3]byte{92, 14, 139}: "Motorola", + [3]byte{92, 17, 147}: "Seal One AG", + [3]byte{92, 20, 55}: "Thyssenkrupp Aufzugswerke GmbH", + [3]byte{92, 21, 21}: "ADVAN", + [3]byte{92, 21, 225}: "AIDC TECHNOLOGY (S) PTE LTD", + [3]byte{92, 22, 199}: "Big Switch Networks", + [3]byte{92, 23, 55}: "I-View Now, LLC.", + [3]byte{92, 23, 211}: "LGE", + [3]byte{92, 24, 181}: "Talon Communications", + [3]byte{92, 32, 208}: "Asoni Communication Co., Ltd.", + [3]byte{92, 34, 196}: "DAE EUN ELETRONICS CO., LTD", + [3]byte{92, 36, 121}: "Baltech AG", + [3]byte{92, 37, 76}: "Avire Global Pte Ltd", + [3]byte{92, 38, 10}: "Dell Inc.", + [3]byte{92, 42, 239}: "Open Access Pty Ltd", + [3]byte{92, 43, 245}: "Vivint", + [3]byte{92, 46, 89}: "Samsung Electronics Co.,Ltd", + [3]byte{92, 46, 210}: "ABC(XiSheng) Electronics Co.,Ltd", + [3]byte{92, 49, 62}: "Texas Instruments", + [3]byte{92, 51, 39}: "Spazio Italia srl", + [3]byte{92, 51, 92}: "Swissphone Telecom AG", + [3]byte{92, 51, 142}: "Alpha Networkc Inc.", + [3]byte{92, 53, 59}: "Compal Broadband Networks Inc.", + [3]byte{92, 53, 218}: "There Corporation Oy", + [3]byte{92, 54, 184}: "TCL King Electrical Appliances (Huizhou) Ltd.", + [3]byte{92, 56, 224}: "Shanghai Super Electronics Technology Co.,LTD", + [3]byte{92, 60, 39}: "Samsung Electronics Co.,Ltd", + [3]byte{92, 64, 88}: "Jefferson Audio Video Systems, Inc.", + [3]byte{92, 67, 210}: "HAZEMEYER", + [3]byte{92, 74, 38}: "Enguity Technology Corp", + [3]byte{92, 76, 169}: "Shenzhen Huawei Communication Technologies Co., Ltd", + [3]byte{92, 80, 21}: "CISCO SYSTEMS, INC.", + [3]byte{92, 81, 79}: "Intel Corporate", + [3]byte{92, 86, 237}: "3pleplay Electronics Private Limited", + [3]byte{92, 87, 26}: "ARRIS Group, Inc.", + [3]byte{92, 87, 200}: "Nokia Corporation", + [3]byte{92, 89, 72}: "Apple", + [3]byte{92, 91, 194}: "YIK Corporation", + [3]byte{92, 94, 171}: "Juniper Networks", + [3]byte{92, 99, 191}: "TP-LINK TECHNOLOGIES CO., LTD.", + [3]byte{92, 105, 132}: "NUVICO", + [3]byte{92, 106, 125}: "KENTKART EGE ELEKTRONIK SAN. VE TIC. LTD. STI.", + [3]byte{92, 107, 50}: "Texas Instruments", + [3]byte{92, 109, 32}: "Hon Hai Precision Ind. Co.,Ltd.", + [3]byte{92, 111, 79}: "S.A. SISTEL", + [3]byte{92, 119, 87}: "Haivision Network Video", + [3]byte{92, 125, 94}: "Huawei Technologies Co., Ltd", + [3]byte{92, 132, 134}: "Brightsource Industries Israel LTD", + [3]byte{92, 134, 74}: "Secret Labs LLC", + [3]byte{92, 135, 120}: "Cybertelbridge co.,ltd", + [3]byte{92, 137, 212}: "Beijing Banner Electric Co.,Ltd", + [3]byte{92, 141, 78}: "Apple", + [3]byte{92, 143, 224}: "ARRIS Group, Inc.", + [3]byte{92, 147, 162}: "Liteon Technology Corporation", + [3]byte{92, 149, 174}: "Apple", + [3]byte{92, 150, 106}: "RTNET", + [3]byte{92, 150, 157}: "Apple", + [3]byte{92, 151, 243}: "Apple", + [3]byte{92, 154, 216}: "Fujitsu Limited", + [3]byte{92, 163, 157}: "SAMSUNG ELECTRO-MECHANICS CO., LTD.", + [3]byte{92, 163, 235}: "Lokel s.r.o.", + [3]byte{92, 164, 138}: "Cisco", + [3]byte{92, 170, 253}: "Sonos, Inc.", + [3]byte{92, 172, 76}: "Hon Hai Precision Ind. Co.,Ltd.", + [3]byte{92, 181, 36}: "Sony Ericsson Mobile Communications AB", + [3]byte{92, 182, 204}: "NovaComm Technologies Inc.", + [3]byte{92, 184, 203}: "Allis Communications", + [3]byte{92, 189, 158}: "HONGKONG MIRACLE EAGLE TECHNOLOGY(GROUP) LIMITED", + [3]byte{92, 194, 19}: "Fr. Sauter AG", + [3]byte{92, 197, 212}: "Intel Corporate", + [3]byte{92, 198, 208}: "Skyworth Digital technology(shenzhen)co.ltd.", + [3]byte{92, 201, 211}: "PALLADIUM ENERGY ELETRONICA DA AMAZONIA LTDA", + [3]byte{92, 202, 50}: "Theben AG", + [3]byte{92, 206, 173}: "CDYNE Corporation", + [3]byte{92, 209, 53}: "Xtreme Power Systems", + [3]byte{92, 210, 228}: "Intel Corporate", + [3]byte{92, 212, 27}: "UCZOON Technology Co., LTD", + [3]byte{92, 212, 171}: "Zektor", + [3]byte{92, 214, 31}: "Qardio, Inc", + [3]byte{92, 217, 152}: "D-Link Corporation", + [3]byte{92, 218, 212}: "Murata Manufacturing Co., Ltd.", + [3]byte{92, 221, 112}: "Hangzhou H3C Technologies Co., Limited", + [3]byte{92, 224, 197}: "Intel Corporate", + [3]byte{92, 224, 202}: "FeiTian United (Beijing) System Technology Co., Ltd.", + [3]byte{92, 224, 246}: "NIC.br- Nucleo de Informacao e Coordenacao do Ponto BR", + [3]byte{92, 226, 35}: "Delphin Technology AG", + [3]byte{92, 226, 134}: "Nortel Networks", + [3]byte{92, 226, 244}: "AcSiP Technology Corp.", + [3]byte{92, 231, 191}: "New Singularity International Technical Development Co.,Ltd", + [3]byte{92, 232, 235}: "Samsung Electronics", + [3]byte{92, 235, 78}: "R. STAHL HMI Systems GmbH", + [3]byte{92, 238, 121}: "Global Digitech Co LTD", + [3]byte{92, 242, 7}: "Speco Technologies", + [3]byte{92, 243, 112}: "CC&C Technologies, Inc", + [3]byte{92, 243, 252}: "IBM Corp", + [3]byte{92, 244, 171}: "ZyXEL Communications Corp", + [3]byte{92, 245, 13}: "Institute of microelectronic applications", + [3]byte{92, 246, 220}: "Samsung Electronics Co.,LTD", + [3]byte{92, 248, 161}: "Murata Manufactuaring Co.,Ltd.", + [3]byte{92, 249, 56}: "Apple, Inc", + [3]byte{92, 249, 106}: "Huawei Technologies Co., Ltd", + [3]byte{92, 249, 221}: "Dell Inc", + [3]byte{92, 249, 240}: "Atomos Engineering P/L", + [3]byte{92, 255, 53}: "Wistron Corporation", + [3]byte{92, 255, 255}: "Shenzhen Kezhonglong Optoelectronic Technology Co., Ltd", + [3]byte{96, 2, 146}: "PEGATRON CORPORATION", + [3]byte{96, 2, 180}: "Wistron NeWeb Corp.", + [3]byte{96, 3, 8}: "Apple", + [3]byte{96, 3, 71}: "Billion Electric Co. Ltd.", + [3]byte{96, 4, 23}: "POSBANK CO.,LTD", + [3]byte{96, 15, 119}: "SilverPlus, Inc", + [3]byte{96, 17, 153}: "Siama Systems Inc", + [3]byte{96, 18, 131}: "Soluciones Tecnologicas para la Salud y el Bienestar SA", + [3]byte{96, 21, 199}: "IdaTech", + [3]byte{96, 25, 12}: "RRAMAC", + [3]byte{96, 25, 41}: "VOLTRONIC POWER TECHNOLOGY(SHENZHEN) CORP.", + [3]byte{96, 29, 15}: "Midnite Solar", + [3]byte{96, 30, 2}: "EltexAlatau", + [3]byte{96, 33, 3}: "STCUBE.INC", + [3]byte{96, 33, 192}: "Murata Manufactuaring Co.,Ltd.", + [3]byte{96, 36, 193}: "Jiangsu Zhongxun Electronic Technology Co., Ltd", + [3]byte{96, 42, 84}: "CardioTek B.V.", + [3]byte{96, 42, 208}: "Cisco SPVTG", + [3]byte{96, 50, 240}: "Mplus technology", + [3]byte{96, 51, 75}: "Apple", + [3]byte{96, 53, 83}: "Buwon Technology", + [3]byte{96, 54, 150}: "The Sapling Company", + [3]byte{96, 54, 221}: "Intel Corporate", + [3]byte{96, 56, 14}: "Alps Electric Co.,", + [3]byte{96, 57, 31}: "ABB Ltd", + [3]byte{96, 63, 197}: "COX CO., LTD", + [3]byte{96, 68, 245}: "Easy Digital Ltd.", + [3]byte{96, 69, 94}: "Liptel s.r.o.", + [3]byte{96, 69, 189}: "Microsoft", + [3]byte{96, 70, 22}: "XIAMEN VANN INTELLIGENT CO., LTD", + [3]byte{96, 71, 212}: "FORICS Electronic Technology Co., Ltd.", + [3]byte{96, 72, 38}: "Newbridge Technologies Int. Ltd.", + [3]byte{96, 74, 28}: "SUYIN Corporation", + [3]byte{96, 80, 193}: "Kinetek Sports", + [3]byte{96, 81, 44}: "TCT mobile limited", + [3]byte{96, 82, 208}: "FACTS Engineering", + [3]byte{96, 84, 100}: "Eyedro Green Solutions Inc.", + [3]byte{96, 87, 24}: "Intel Corporate", + [3]byte{96, 96, 31}: "SZ DJI TECHNOLOGY CO.,LTD", + [3]byte{96, 99, 253}: "Transcend Communication Beijing Co.,Ltd.", + [3]byte{96, 100, 161}: "RADiflow Ltd.", + [3]byte{96, 103, 32}: "Intel Corporate", + [3]byte{96, 105, 68}: "Apple, Inc", + [3]byte{96, 105, 155}: "isepos GmbH", + [3]byte{96, 107, 189}: "Samsung Electronics Co., LTD", + [3]byte{96, 108, 102}: "Intel Corporate", + [3]byte{96, 115, 92}: "Cisco", + [3]byte{96, 116, 141}: "Atmaca Elektronik", + [3]byte{96, 118, 136}: "Velodyne", + [3]byte{96, 119, 226}: "Samsung Electronics Co.,Ltd", + [3]byte{96, 129, 43}: "Custom Control Concepts", + [3]byte{96, 129, 249}: "Helium Systems, Inc", + [3]byte{96, 131, 178}: "GkWare e.K.", + [3]byte{96, 132, 59}: "Soladigm, Inc.", + [3]byte{96, 134, 69}: "Avery Weigh-Tronix, LLC", + [3]byte{96, 137, 60}: "Thermo Fisher Scientific P.O.A.", + [3]byte{96, 137, 177}: "Key Digital Systems", + [3]byte{96, 137, 183}: "KAEL MÜHENDİSLİK ELEKTRONİK TİCARET SANAYİ LİMİTED ŞİRKETİ", + [3]byte{96, 140, 43}: "Hanson Technology", + [3]byte{96, 141, 23}: "Sentrus Government Systems Division, Inc", + [3]byte{96, 143, 92}: "Samsung Electronics Co.,Ltd", + [3]byte{96, 144, 132}: "DSSD Inc", + [3]byte{96, 146, 23}: "Apple", + [3]byte{96, 150, 32}: "PRIVATE", + [3]byte{96, 153, 209}: "Vuzix / Lenovo", + [3]byte{96, 154, 164}: "GVI SECURITY INC.", + [3]byte{96, 158, 100}: "Vivonic GmbH", + [3]byte{96, 159, 157}: "CloudSwitch", + [3]byte{96, 161, 10}: "Samsung Electronics Co.,Ltd", + [3]byte{96, 164, 76}: "ASUSTek COMPUTER INC.", + [3]byte{96, 168, 254}: "Nokia Solutions and Networks", + [3]byte{96, 169, 176}: "Merchandising Technologies, Inc", + [3]byte{96, 177, 133}: "ATH system", + [3]byte{96, 179, 196}: "Elber Srl", + [3]byte{96, 182, 6}: "Phorus", + [3]byte{96, 182, 23}: "Fiberhome Telecommunication Tech.Co.,Ltd.", + [3]byte{96, 185, 51}: "Deutron Electronics Corp.", + [3]byte{96, 185, 130}: "RO.VE.R. Laboratories S.p.A.", + [3]byte{96, 187, 12}: "Beijing HuaqinWorld Technology Co,Ltd", + [3]byte{96, 188, 76}: "EWM Hightec Welding GmbH", + [3]byte{96, 189, 145}: "Move Innovation", + [3]byte{96, 190, 181}: "Motorola Mobility LLC", + [3]byte{96, 193, 203}: "Fujian Great Power PLC Equipment Co.,Ltd", + [3]byte{96, 195, 151}: "2Wire Inc", + [3]byte{96, 197, 71}: "Apple", + [3]byte{96, 197, 168}: "Beijing LT Honway Technology Co.,Ltd", + [3]byte{96, 199, 152}: "Verifone, Inc.", + [3]byte{96, 201, 128}: "Trymus", + [3]byte{96, 203, 251}: "AirScape Inc.", + [3]byte{96, 205, 169}: "Abloomy", + [3]byte{96, 205, 197}: "Taiwan Carol Electronics., Ltd", + [3]byte{96, 208, 169}: "Samsung Electronics Co.,Ltd", + [3]byte{96, 209, 170}: "Vishal Telecommunications Pvt Ltd", + [3]byte{96, 210, 185}: "REALAND BIO CO., LTD.", + [3]byte{96, 211, 10}: "Quatius Limited", + [3]byte{96, 216, 25}: "Hon Hai Precision Ind. Co.,Ltd.", + [3]byte{96, 217, 199}: "Apple", + [3]byte{96, 218, 35}: "Estech Co.,Ltd", + [3]byte{96, 219, 42}: "HNS", + [3]byte{96, 222, 68}: "HUAWEI TECHNOLOGIES CO.,LTD", + [3]byte{96, 224, 14}: "SHINSEI ELECTRONICS CO LTD", + [3]byte{96, 227, 39}: "TP-LINK TECHNOLOGIES CO.,LTD.", + [3]byte{96, 231, 1}: "Huawei Technologies Co., Ltd", + [3]byte{96, 233, 86}: "Ayla Networks, Inc", + [3]byte{96, 235, 105}: "Quanta computer Inc.", + [3]byte{96, 241, 61}: "JABLOCOM s.r.o.", + [3]byte{96, 242, 129}: "TRANWO TECHNOLOGY CO., LTD.", + [3]byte{96, 242, 239}: "VisionVera International Co., Ltd.", + [3]byte{96, 243, 218}: "Logic Way GmbH", + [3]byte{96, 244, 148}: "Hon Hai Precision Ind. Co.,Ltd.", + [3]byte{96, 245, 156}: "CRU-Dataport", + [3]byte{96, 246, 115}: "TERUMO CORPORATION", + [3]byte{96, 250, 205}: "Apple", + [3]byte{96, 251, 66}: "Apple", + [3]byte{96, 254, 30}: "China Palms Telecom.Ltd", + [3]byte{96, 254, 32}: "2 Wire", + [3]byte{96, 254, 197}: "Apple", + [3]byte{96, 254, 249}: "Thomas & Betts", + [3]byte{96, 255, 221}: "C.E. ELECTRONICS, INC", + [3]byte{100, 0, 45}: "Powerlinq Co., LTD", + [3]byte{100, 0, 241}: "CISCO SYSTEMS, INC.", + [3]byte{100, 5, 190}: "NEW LIGHT LED", + [3]byte{100, 9, 76}: "Beijing Superbee Wireless Technology Co.,Ltd", + [3]byte{100, 9, 128}: "XIAOMI Electronics,CO.,LTD", + [3]byte{100, 11, 74}: "Digital Telecom Technology Limited", + [3]byte{100, 14, 54}: "TAZTAG", + [3]byte{100, 14, 148}: "Pluribus Networks, Inc.", + [3]byte{100, 15, 40}: "2wire", + [3]byte{100, 16, 132}: "HEXIUM Technical Development Co., Ltd.", + [3]byte{100, 18, 37}: "Cisco", + [3]byte{100, 22, 141}: "CISCO SYSTEMS, INC.", + [3]byte{100, 22, 240}: "Shehzhen Huawei Communication Technologies Co., Ltd.", + [3]byte{100, 26, 34}: "Heliospectra/Woodhill Investments", + [3]byte{100, 28, 103}: "DIGIBRAS INDUSTRIA DO BRASILS/A", + [3]byte{100, 30, 129}: "Dowslake Microsystems", + [3]byte{100, 32, 12}: "Apple", + [3]byte{100, 33, 132}: "Nippon Denki Kagaku Co.,LTD", + [3]byte{100, 34, 22}: "Shandong Taixin Electronic co.,Ltd", + [3]byte{100, 36, 0}: "Xorcom Ltd.", + [3]byte{100, 39, 55}: "Hon Hai Precision Ind. Co.,Ltd.", + [3]byte{100, 45, 183}: "SEUNGIL ELECTRONICS", + [3]byte{100, 49, 80}: "Hewlett-Packard Company", + [3]byte{100, 49, 126}: "Dexin Corporation", + [3]byte{100, 52, 9}: "BITwave Pte Ltd", + [3]byte{100, 62, 140}: "HUAWEI TECHNOLOGIES CO.,LTD", + [3]byte{100, 63, 95}: "Exablaze", + [3]byte{100, 66, 20}: "Swisscom Energy Solutions AG", + [3]byte{100, 67, 70}: "GuangDong Quick Network Computer CO.,LTD", + [3]byte{100, 75, 195}: "Shanghai WOASiS Telecommunications Ltd., Co.", + [3]byte{100, 75, 240}: "CalDigit, Inc", + [3]byte{100, 77, 112}: "dSPACE GmbH", + [3]byte{100, 79, 116}: "LENUS Co., Ltd.", + [3]byte{100, 79, 176}: "Hyunjin.com", + [3]byte{100, 81, 6}: "Hewlett Packard", + [3]byte{100, 81, 126}: "LONG BEN (DONGGUAN) ELECTRONIC TECHNOLOGY CO.,LTD.", + [3]byte{100, 82, 153}: "The Chamberlain Group, Inc", + [3]byte{100, 83, 93}: "Frauscher Sensortechnik", + [3]byte{100, 84, 34}: "Equinox Payments", + [3]byte{100, 85, 99}: "Intelight Inc.", + [3]byte{100, 85, 127}: "NSFOCUS Information Technology Co., Ltd.", + [3]byte{100, 85, 177}: "ARRIS Group, Inc.", + [3]byte{100, 86, 1}: "TP-LINK TECHNOLOGIES CO.,LTD", + [3]byte{100, 90, 4}: "Chicony Electronics Co., Ltd.", + [3]byte{100, 93, 215}: "Shenzhen Lifesense Medical Electronics Co., Ltd.", + [3]byte{100, 94, 190}: "Yahoo! JAPAN", + [3]byte{100, 95, 255}: "Nicolet Neuro", + [3]byte{100, 98, 35}: "Cellient Co., Ltd.", + [3]byte{100, 100, 155}: "juniper networks", + [3]byte{100, 101, 192}: "Nuvon, Inc", + [3]byte{100, 102, 179}: "TP-LINK TECHNOLOGIES CO., LTD.", + [3]byte{100, 103, 7}: "Beijing Omnific Technology, Ltd.", + [3]byte{100, 104, 12}: "COMTREND", + [3]byte{100, 105, 188}: "Hytera Communications Co .,ltd", + [3]byte{100, 108, 178}: "Samsung Electronics Co.,Ltd", + [3]byte{100, 110, 108}: "Radio Datacom LLC", + [3]byte{100, 110, 234}: "Iskratel d.o.o.", + [3]byte{100, 112, 2}: "TP-LINK TECHNOLOGIES CO., LTD.", + [3]byte{100, 114, 216}: "GooWi Technology Co.,Limited", + [3]byte{100, 115, 226}: "Arbiter Systems, Inc.", + [3]byte{100, 118, 87}: "Innovative Security Designs", + [3]byte{100, 118, 186}: "Apple", + [3]byte{100, 119, 145}: "Samsung Electronics Co.,Ltd", + [3]byte{100, 123, 212}: "Texas Instruments", + [3]byte{100, 124, 52}: "Ubee Interactive Corp.", + [3]byte{100, 125, 129}: "YOKOTA INDUSTRIAL CO,.LTD", + [3]byte{100, 127, 218}: "TEKTELIC Communications Inc.", + [3]byte{100, 128, 139}: "VG Controls, Inc.", + [3]byte{100, 128, 153}: "Intel Corporate", + [3]byte{100, 129, 37}: "Alphatron Marine BV", + [3]byte{100, 135, 136}: "Juniper Networks", + [3]byte{100, 135, 215}: "Pirelli Tyre S.p.A.", + [3]byte{100, 136, 255}: "Sichuan Changhong Electric Ltd.", + [3]byte{100, 137, 154}: "LG Electronics", + [3]byte{100, 141, 158}: "IVT Electronic Co.,Ltd", + [3]byte{100, 153, 93}: "LGE", + [3]byte{100, 153, 104}: "Elentec", + [3]byte{100, 153, 160}: "AG Elektronik AB", + [3]byte{100, 155, 36}: "V Technology Co., Ltd.", + [3]byte{100, 156, 129}: "Qualcomm iSkoot, Inc.", + [3]byte{100, 156, 142}: "Texas Instruments", + [3]byte{100, 158, 243}: "CISCO SYSTEMS, INC.", + [3]byte{100, 159, 247}: "Kone OYj", + [3]byte{100, 160, 231}: "CISCO SYSTEMS, INC.", + [3]byte{100, 162, 50}: "OOO Samlight", + [3]byte{100, 163, 65}: "Wonderlan (Beijing) Technology Co., Ltd.", + [3]byte{100, 163, 203}: "Apple", + [3]byte{100, 167, 105}: "HTC Corporation", + [3]byte{100, 167, 221}: "Avaya, Inc", + [3]byte{100, 168, 55}: "Juni Korea Co., Ltd", + [3]byte{100, 174, 12}: "CISCO SYSTEMS, INC.", + [3]byte{100, 174, 136}: "Polytec GmbH", + [3]byte{100, 178, 29}: "Chengdu Phycom Tech Co., Ltd.", + [3]byte{100, 179, 16}: "Samsung Electronics Co.,Ltd", + [3]byte{100, 179, 112}: "PowerComm Solutons LLC", + [3]byte{100, 180, 115}: "Xiaomi inc.", + [3]byte{100, 182, 74}: "ViVOtech, Inc.", + [3]byte{100, 184, 83}: "Samsung Elec Co.,Ltd", + [3]byte{100, 185, 232}: "Apple", + [3]byte{100, 186, 189}: "SDJ Technologies, Inc.", + [3]byte{100, 188, 17}: "CombiQ AB", + [3]byte{100, 197, 170}: "South African Broadcasting Corporation", + [3]byte{100, 198, 103}: "Barnes&Noble", + [3]byte{100, 198, 175}: "AXERRA Networks Ltd", + [3]byte{100, 201, 68}: "LARK Technologies, Inc", + [3]byte{100, 208, 45}: "Next Generation Integration (NGI)", + [3]byte{100, 209, 163}: "Sitecom Europe BV", + [3]byte{100, 210, 65}: "Keith & Koep GmbH", + [3]byte{100, 212, 189}: "ALPS ELECTRIC CO.,LTD.", + [3]byte{100, 212, 218}: "Intel Corporate", + [3]byte{100, 216, 20}: "CISCO SYSTEMS, INC.", + [3]byte{100, 217, 18}: "Solidica, Inc.", + [3]byte{100, 217, 84}: "TAICANG AND W ELECTRONICS CO LTD", + [3]byte{100, 217, 137}: "CISCO SYSTEMS, INC.", + [3]byte{100, 219, 24}: "OpenPattern", + [3]byte{100, 220, 1}: "Static Systems Group PLC", + [3]byte{100, 222, 28}: "Kingnetic Pte Ltd", + [3]byte{100, 225, 97}: "DEP Corp.", + [3]byte{100, 229, 153}: "EFM Networks", + [3]byte{100, 230, 37}: "Woxu Wireless Co., Ltd", + [3]byte{100, 230, 130}: "Apple", + [3]byte{100, 232, 79}: "Serialway Communication Technology Co. Ltd", + [3]byte{100, 232, 146}: "Morio Denki Co., Ltd.", + [3]byte{100, 232, 230}: "global moisture management system", + [3]byte{100, 233, 80}: "Cisco", + [3]byte{100, 234, 197}: "SiboTech Automation Co., Ltd.", + [3]byte{100, 235, 140}: "Seiko Epson Corporation", + [3]byte{100, 237, 87}: "ARRIS Group, Inc.", + [3]byte{100, 237, 98}: "WOORI SYSTEMS Co., Ltd", + [3]byte{100, 242, 66}: "Gerdes Aktiengesellschaft", + [3]byte{100, 245, 14}: "Kinion Technology Company Limited", + [3]byte{100, 249, 112}: "Kenade Electronics Technology Co.,LTD.", + [3]byte{100, 249, 135}: "Avvasi Inc.", + [3]byte{100, 252, 140}: "Zonar Systems", + [3]byte{104, 5, 113}: "Samsung Electronics Co.,Ltd", + [3]byte{104, 5, 202}: "Intel Corporate", + [3]byte{104, 9, 39}: "Apple", + [3]byte{104, 10, 215}: "Yancheng Kecheng Optoelectronic Technology Co., Ltd", + [3]byte{104, 18, 45}: "Special Instrument Development Co., Ltd.", + [3]byte{104, 21, 144}: "SAGEMCOM SAS", + [3]byte{104, 21, 211}: "Zaklady Elektroniki i Mechaniki Precyzyjnej R&G S.A.", + [3]byte{104, 22, 5}: "Systems And Electronic Development FZCO", + [3]byte{104, 23, 41}: "Intel Corporate", + [3]byte{104, 25, 63}: "Digital Airways", + [3]byte{104, 26, 178}: "zte corporation", + [3]byte{104, 28, 162}: "Rosewill Inc.", + [3]byte{104, 29, 100}: "Sunwave Communications Co., Ltd", + [3]byte{104, 30, 139}: "InfoSight Corporation", + [3]byte{104, 31, 216}: "Advanced Telemetry", + [3]byte{104, 35, 75}: "Nihon Dengyo Kousaku", + [3]byte{104, 40, 186}: "Dejai", + [3]byte{104, 45, 220}: "Wuhan Changjiang Electro-Communication Equipment CO.,LTD", + [3]byte{104, 54, 181}: "DriveScale, Inc.", + [3]byte{104, 59, 30}: "Countwise LTD", + [3]byte{104, 62, 236}: "ERECA", + [3]byte{104, 67, 82}: "Bhuu Limited", + [3]byte{104, 72, 152}: "Samsung Electronics Co.,Ltd", + [3]byte{104, 75, 136}: "Galtronics Telemetry Inc.", + [3]byte{104, 76, 168}: "Shenzhen Herotel Tech. Co., Ltd.", + [3]byte{104, 81, 183}: "PowerCloud Systems, Inc.", + [3]byte{104, 84, 237}: "Alcatel-Lucent - Nuage", + [3]byte{104, 84, 245}: "enLighted Inc", + [3]byte{104, 89, 127}: "Alcatel Lucent", + [3]byte{104, 91, 53}: "Apple", + [3]byte{104, 91, 54}: "POWERTECH INDUSTRIAL CO., LTD.", + [3]byte{104, 93, 67}: "Intel Corporate", + [3]byte{104, 94, 107}: "PowerRay Co., Ltd.", + [3]byte{104, 99, 89}: "Advanced Digital Broadcast SA", + [3]byte{104, 105, 46}: "Zycoo Co.,Ltd", + [3]byte{104, 105, 242}: "ComAp s.r.o.", + [3]byte{104, 110, 35}: "Wi3 Inc.", + [3]byte{104, 110, 72}: "Prophet Electronic Technology Corp.,Ltd", + [3]byte{104, 114, 81}: "Ubiquiti Networks", + [3]byte{104, 114, 220}: "CETORY.TV Company Limited", + [3]byte{104, 118, 79}: "Sony Mobile Communications AB", + [3]byte{104, 120, 72}: "Westunitis Co., Ltd.", + [3]byte{104, 120, 76}: "Nortel Networks", + [3]byte{104, 121, 36}: "ELS-GmbH & Co. KG", + [3]byte{104, 121, 237}: "SHARP Corporation", + [3]byte{104, 124, 200}: "Measurement Systems S. de R.L.", + [3]byte{104, 124, 213}: "Y Soft Corporation, a.s.", + [3]byte{104, 127, 116}: "Cisco-Linksys, LLC", + [3]byte{104, 131, 26}: "Pandora Mobility Corporation", + [3]byte{104, 132, 112}: "eSSys Co.,Ltd", + [3]byte{104, 133, 64}: "IGI Mobile, Inc.", + [3]byte{104, 133, 106}: "OuterLink Corporation", + [3]byte{104, 134, 167}: "Cisco", + [3]byte{104, 134, 231}: "Orbotix, Inc.", + [3]byte{104, 135, 107}: "INQ Mobile Limited", + [3]byte{104, 138, 181}: "EDP Servicos", + [3]byte{104, 146, 52}: "Ruckus Wireless", + [3]byte{104, 148, 35}: "Hon Hai Precision Ind. Co.,Ltd.", + [3]byte{104, 150, 123}: "Apple", + [3]byte{104, 151, 75}: "Shenzhen Costar Electronics Co. Ltd.", + [3]byte{104, 151, 232}: "Society of Motion Picture & Television Engineers", + [3]byte{104, 153, 205}: "Cisco", + [3]byte{104, 156, 94}: "AcSiP Technology Corp.", + [3]byte{104, 156, 112}: "Apple", + [3]byte{104, 160, 246}: "Huawei Technologies Co., Ltd", + [3]byte{104, 161, 183}: "Honghao Mingchuan Technology (Beijing) CO.,Ltd.", + [3]byte{104, 163, 196}: "Liteon Technology Corporation", + [3]byte{104, 164, 14}: "BSH Bosch and Siemens Home Appliances GmbH", + [3]byte{104, 168, 109}: "Apple", + [3]byte{104, 170, 210}: "DATECS LTD.,", + [3]byte{104, 171, 138}: "RF IDeas", + [3]byte{104, 174, 32}: "Apple", + [3]byte{104, 175, 19}: "Futura Mobility", + [3]byte{104, 176, 148}: "INESA ELECTRON CO.,LTD", + [3]byte{104, 180, 58}: "WaterFurnace International, Inc.", + [3]byte{104, 181, 153}: "Hewlett-Packard Company", + [3]byte{104, 182, 252}: "Hitron Technologies. Inc", + [3]byte{104, 184, 217}: "Act KDE, Inc.", + [3]byte{104, 188, 12}: "CISCO SYSTEMS, INC.", + [3]byte{104, 189, 171}: "CISCO SYSTEMS, INC.", + [3]byte{104, 201, 11}: "Texas Instruments", + [3]byte{104, 202, 0}: "Octopus Systems Limited", + [3]byte{104, 204, 156}: "Mine Site Technologies", + [3]byte{104, 205, 15}: "U Tek Company Limited", + [3]byte{104, 206, 78}: "L-3 Communications Infrared Products", + [3]byte{104, 209, 253}: "Shenzhen Trimax Technology Co.,Ltd", + [3]byte{104, 210, 71}: "Portalis LC", + [3]byte{104, 217, 37}: "ProSys Development Services", + [3]byte{104, 217, 60}: "Apple", + [3]byte{104, 219, 103}: "Nantong Coship Electronics Co., Ltd", + [3]byte{104, 219, 150}: "OPWILL Technologies CO .,LTD", + [3]byte{104, 220, 232}: "PacketStorm Communications", + [3]byte{104, 223, 221}: "Xiaomi inc.", + [3]byte{104, 225, 102}: "PRIVATE", + [3]byte{104, 228, 31}: "Unglaube Identech GmbH", + [3]byte{104, 235, 174}: "Samsung Electronics Co.,Ltd", + [3]byte{104, 235, 197}: "Angstrem Telecom", + [3]byte{104, 236, 98}: "YODO Technology Corp. Ltd.", + [3]byte{104, 237, 67}: "Research In Motion", + [3]byte{104, 238, 150}: "Cisco SPVTG", + [3]byte{104, 239, 189}: "CISCO SYSTEMS, INC.", + [3]byte{104, 240, 109}: "ALONG INDUSTRIAL CO., LIMITED", + [3]byte{104, 241, 37}: "Data Controls Inc.", + [3]byte{104, 247, 40}: "LCFC(HeFei) Electronics Technology co., ltd", + [3]byte{104, 248, 149}: "Redflow Limited", + [3]byte{104, 251, 149}: "Generalplus Technology Inc.", + [3]byte{104, 252, 179}: "Next Level Security Systems, Inc.", + [3]byte{108, 2, 115}: "Shenzhen Jin Yun Video Equipment Co., Ltd.", + [3]byte{108, 4, 96}: "RBH Access Technologies Inc.", + [3]byte{108, 9, 214}: "Digiquest Electronics LTD", + [3]byte{108, 11, 132}: "Universal Global Scientific Industrial Co.,Ltd.", + [3]byte{108, 14, 13}: "Sony Ericsson Mobile Communications AB", + [3]byte{108, 15, 106}: "JDC Tech Co., Ltd.", + [3]byte{108, 20, 247}: "Erhardt+Leimer GmbH", + [3]byte{108, 21, 249}: "Nautronix Limited", + [3]byte{108, 24, 17}: "Decatur Electronics", + [3]byte{108, 25, 143}: "D-Link International", + [3]byte{108, 32, 86}: "Cisco", + [3]byte{108, 34, 171}: "Ainsworth Game Technology", + [3]byte{108, 35, 185}: "Sony Ericsson Mobile Communications AB", + [3]byte{108, 37, 185}: "BBK Electronics Corp., Ltd.,", + [3]byte{108, 41, 149}: "Intel Corporate", + [3]byte{108, 44, 6}: "OOO NPP Systemotechnika-NN", + [3]byte{108, 46, 51}: "Accelink Technologies Co.,Ltd.", + [3]byte{108, 46, 133}: "SAGEMCOM", + [3]byte{108, 47, 44}: "Samsung Electronics Co.,Ltd", + [3]byte{108, 50, 222}: "Indieon Technologies Pvt. Ltd.", + [3]byte{108, 51, 169}: "Magicjack LP", + [3]byte{108, 57, 29}: "Beijing ZhongHuaHun Network Information center", + [3]byte{108, 58, 132}: "Shenzhen Aero-Startech. Co.Ltd", + [3]byte{108, 59, 229}: "Hewlett Packard", + [3]byte{108, 60, 83}: "SoundHawk Corp", + [3]byte{108, 62, 109}: "Apple", + [3]byte{108, 62, 156}: "KE Knestel Elektronik GmbH", + [3]byte{108, 64, 8}: "Apple", + [3]byte{108, 64, 198}: "Nimbus Data Systems, Inc.", + [3]byte{108, 65, 106}: "Cisco", + [3]byte{108, 75, 127}: "Vossloh-Schwabe Deutschland GmbH", + [3]byte{108, 80, 77}: "CISCO SYSTEMS, INC.", + [3]byte{108, 87, 121}: "Aclima, Inc.", + [3]byte{108, 90, 52}: "Shenzhen Haitianxiong Electronic Co., Ltd.", + [3]byte{108, 90, 181}: "TCL Technoly Electronics (Huizhou) Co., Ltd.", + [3]byte{108, 92, 222}: "SunReports, Inc.", + [3]byte{108, 93, 99}: "ShenZhen Rapoo Technology Co., Ltd.", + [3]byte{108, 94, 122}: "Ubiquitous Internet Telecom Co., Ltd", + [3]byte{108, 95, 28}: "Lenovo Mobile Communication Technology Ltd.", + [3]byte{108, 97, 38}: "Rinicom Holdings", + [3]byte{108, 98, 109}: "Micro-Star INT'L CO., LTD", + [3]byte{108, 100, 26}: "Penguin Computing", + [3]byte{108, 110, 254}: "Core Logic Inc.", + [3]byte{108, 111, 24}: "Stereotaxis, Inc.", + [3]byte{108, 112, 57}: "Novar GmbH", + [3]byte{108, 112, 159}: "Apple", + [3]byte{108, 113, 217}: "AzureWave Technologies, Inc", + [3]byte{108, 118, 96}: "KYOCERA Corporation", + [3]byte{108, 129, 254}: "Mitsuba Corporation", + [3]byte{108, 131, 54}: "Samsung Electronics Co.,Ltd", + [3]byte{108, 131, 102}: "Nanjing SAC Power Grid Automation Co., Ltd.", + [3]byte{108, 134, 134}: "Technonia", + [3]byte{108, 136, 20}: "Intel Corporate", + [3]byte{108, 139, 47}: "zte corporation", + [3]byte{108, 140, 219}: "Otus Technologies Ltd", + [3]byte{108, 141, 101}: "Wireless Glue Networks, Inc.", + [3]byte{108, 144, 177}: "SanLogic Inc", + [3]byte{108, 146, 191}: "Inspur Electronic Information Industry Co.,Ltd.", + [3]byte{108, 148, 248}: "Apple", + [3]byte{108, 152, 235}: "Ocedo GmbH", + [3]byte{108, 153, 137}: "Cisco", + [3]byte{108, 154, 201}: "Valentine Research, Inc.", + [3]byte{108, 155, 2}: "Nokia Corporation", + [3]byte{108, 156, 233}: "Nimble Storage", + [3]byte{108, 156, 237}: "CISCO SYSTEMS, INC.", + [3]byte{108, 166, 130}: "EDAM information & communications", + [3]byte{108, 167, 128}: "Nokia Corporation", + [3]byte{108, 169, 6}: "Telefield Ltd", + [3]byte{108, 169, 111}: "TransPacket AS", + [3]byte{108, 170, 179}: "Ruckus Wireless", + [3]byte{108, 171, 77}: "Digital Payment Technologies", + [3]byte{108, 172, 96}: "Venetex Corp", + [3]byte{108, 173, 63}: "Hubbell Building Automation, Inc.", + [3]byte{108, 173, 239}: "KZ Broadband Technologies, Ltd.", + [3]byte{108, 173, 248}: "Azurewave Technologies, Inc.", + [3]byte{108, 174, 139}: "IBM Corporation", + [3]byte{108, 176, 206}: "NETGEAR", + [3]byte{108, 179, 17}: "Shenzhen Lianrui Electronics Co.,Ltd", + [3]byte{108, 179, 80}: "Anhui comhigher tech co.,ltd", + [3]byte{108, 183, 244}: "Samsung Electronics Co.,Ltd", + [3]byte{108, 190, 233}: "Alcatel-Lucent-IPD", + [3]byte{108, 191, 181}: "Noon Technology Co., Ltd", + [3]byte{108, 193, 210}: "ARRIS Group, Inc.", + [3]byte{108, 194, 23}: "Hewlett Packard", + [3]byte{108, 194, 107}: "Apple", + [3]byte{108, 208, 50}: "LG Electronics", + [3]byte{108, 209, 70}: "Smartek d.o.o.", + [3]byte{108, 209, 176}: "WING SING ELECTRONICS HONG KONG LIMITED", + [3]byte{108, 214, 138}: "LG Electronics Inc", + [3]byte{108, 220, 106}: "Promethean Limited", + [3]byte{108, 224, 176}: "SOUND4", + [3]byte{108, 228, 206}: "Villiger Security Solutions AG", + [3]byte{108, 232, 115}: "TP-LINK TECHNOLOGIES CO., LTD.", + [3]byte{108, 233, 7}: "Nokia Corporation", + [3]byte{108, 233, 131}: "Gastron Co., LTD.", + [3]byte{108, 236, 161}: "SHENZHEN CLOU ELECTRONICS CO. LTD.", + [3]byte{108, 236, 235}: "Texas Instruments", + [3]byte{108, 240, 73}: "GIGA-BYTE TECHNOLOGY CO.,LTD.", + [3]byte{108, 243, 115}: "Samsung Electronics Co.,Ltd", + [3]byte{108, 243, 127}: "Aruba Networks", + [3]byte{108, 249, 124}: "Nanoptix Inc.", + [3]byte{108, 250, 88}: "Avaya, Inc", + [3]byte{108, 250, 137}: "Cisco", + [3]byte{108, 250, 167}: "AMPAK Technology Inc.", + [3]byte{108, 253, 185}: "Proware Technologies Co Ltd.", + [3]byte{108, 255, 190}: "MPB Communications Inc.", + [3]byte{112, 2, 88}: "01DB-METRAVIB", + [3]byte{112, 5, 20}: "LG Electronics", + [3]byte{112, 11, 192}: "Dewav Technology Company", + [3]byte{112, 15, 199}: "SHENZHEN IKINLOOP TECHNOLOGY CO.,LTD.", + [3]byte{112, 15, 236}: "Poindus Systems Corp.", + [3]byte{112, 16, 92}: "Cisco", + [3]byte{112, 17, 36}: "Apple", + [3]byte{112, 20, 4}: "Limited Liability Company", + [3]byte{112, 24, 139}: "Hon Hai Precision Ind. Co.,Ltd.", + [3]byte{112, 26, 4}: "Liteon Tech Corp.", + [3]byte{112, 26, 237}: "ADVAS CO., LTD.", + [3]byte{112, 29, 127}: "Comtech Technology Co., Ltd.", + [3]byte{112, 35, 147}: "fos4X GmbH", + [3]byte{112, 37, 38}: "Alcatel-Lucent", + [3]byte{112, 37, 89}: "CyberTAN Technology, Inc.", + [3]byte{112, 43, 29}: "E-Domus International Limited", + [3]byte{112, 44, 31}: "Wisol", + [3]byte{112, 45, 209}: "Newings Communication CO., LTD.", + [3]byte{112, 47, 75}: "PolyVision Inc.", + [3]byte{112, 47, 151}: "Aava Mobile Oy", + [3]byte{112, 48, 24}: "Avaya, Inc", + [3]byte{112, 48, 93}: "Ubiquoss Inc", + [3]byte{112, 48, 94}: "Nanjing Zhongke Menglian Information Technology Co.,LTD", + [3]byte{112, 49, 135}: "ACX GmbH", + [3]byte{112, 50, 213}: "Athena Wireless Communications Inc", + [3]byte{112, 56, 17}: "Invensys Rail", + [3]byte{112, 56, 180}: "Low Tech Solutions", + [3]byte{112, 56, 238}: "Avaya, Inc", + [3]byte{112, 58, 216}: "Shenzhen Afoundry Electronic Co., Ltd", + [3]byte{112, 60, 57}: "SEAWING Kft", + [3]byte{112, 62, 172}: "Apple", + [3]byte{112, 65, 183}: "Edwards Lifesciences LLC", + [3]byte{112, 70, 66}: "CHYNG HONG ELECTRONIC CO., LTD.", + [3]byte{112, 74, 174}: "Xstream Flow (Pty) Ltd", + [3]byte{112, 74, 228}: "Rinstrum Pty Ltd", + [3]byte{112, 76, 237}: "TMRG, Inc.", + [3]byte{112, 78, 1}: "KWANGWON TECH CO., LTD.", + [3]byte{112, 82, 197}: "Avaya, Inc.", + [3]byte{112, 83, 63}: "Alfa Instrumentos Eletronicos Ltda.", + [3]byte{112, 84, 210}: "PEGATRON CORPORATION", + [3]byte{112, 84, 245}: "HUAWEI TECHNOLOGIES CO.,LTD", + [3]byte{112, 86, 129}: "Apple", + [3]byte{112, 88, 18}: "Panasonic AVC Networks Company", + [3]byte{112, 89, 87}: "Medallion Instrumentation Systems", + [3]byte{112, 89, 134}: "OOO TTV", + [3]byte{112, 90, 182}: "COMPAL INFORMATION (KUNSHAN) CO., LTD.", + [3]byte{112, 91, 46}: "M2Communication Inc.", + [3]byte{112, 92, 173}: "Konami Gaming Inc", + [3]byte{112, 94, 170}: "Action Target, Inc.", + [3]byte{112, 96, 222}: "LaVision GmbH", + [3]byte{112, 97, 115}: "Calantec GmbH", + [3]byte{112, 98, 184}: "D-Link International", + [3]byte{112, 100, 23}: "ORBIS TECNOLOGIA ELECTRICA S.A.", + [3]byte{112, 101, 130}: "Suzhou Hanming Technologies Co., Ltd.", + [3]byte{112, 111, 129}: "PRIVATE", + [3]byte{112, 112, 76}: "Purple Communications, Inc", + [3]byte{112, 113, 179}: "Brain Corporation", + [3]byte{112, 113, 188}: "PEGATRON CORPORATION", + [3]byte{112, 114, 13}: "Lenovo Mobile Communication Technology Ltd.", + [3]byte{112, 114, 60}: "Huawei Technologies Co., Ltd", + [3]byte{112, 114, 207}: "EdgeCore Networks", + [3]byte{112, 115, 203}: "Apple", + [3]byte{112, 118, 48}: "Pace plc.", + [3]byte{112, 118, 221}: "Oxyguard International A/S", + [3]byte{112, 118, 240}: "LevelOne Communications (India) Private Limited", + [3]byte{112, 118, 255}: "KERLINK", + [3]byte{112, 123, 232}: "HUAWEI TECHNOLOGIES CO.,LTD", + [3]byte{112, 124, 24}: "ADATA Technology Co., Ltd", + [3]byte{112, 126, 67}: "ARRIS Group, Inc.", + [3]byte{112, 126, 222}: "NASTEC LTD.", + [3]byte{112, 129, 5}: "CISCO SYSTEMS, INC.", + [3]byte{112, 130, 14}: "as electronics GmbH", + [3]byte{112, 130, 142}: "OleumTech Corporation", + [3]byte{112, 133, 198}: "Pace plc.", + [3]byte{112, 139, 120}: "citygrow technology co., ltd", + [3]byte{112, 141, 9}: "Nokia Corporation", + [3]byte{112, 147, 131}: "Intelligent Optical Network High Tech CO.,LTD.", + [3]byte{112, 147, 248}: "Space Monkey, Inc.", + [3]byte{112, 151, 86}: "Happyelectronics Co.,Ltd", + [3]byte{112, 154, 11}: "Italian Institute of Technology", + [3]byte{112, 155, 165}: "Shenzhen Y&D Electronics Co.,LTD.", + [3]byte{112, 155, 252}: "Bryton Inc.", + [3]byte{112, 158, 41}: "Sony Computer Entertainment Inc.", + [3]byte{112, 158, 134}: "X6D Limited", + [3]byte{112, 161, 145}: "Trendsetter Medical, LLC", + [3]byte{112, 164, 28}: "Advanced Wireless Dynamics S.L.", + [3]byte{112, 166, 106}: "Prox Dynamics AS", + [3]byte{112, 168, 227}: "HUAWEI TECHNOLOGIES CO.,LTD", + [3]byte{112, 170, 178}: "Research In Motion", + [3]byte{112, 175, 37}: "Nishiyama Industry Co.,LTD.", + [3]byte{112, 176, 53}: "Shenzhen Zowee Technology Co., Ltd", + [3]byte{112, 176, 140}: "Shenou Communication Equipment Co.,Ltd", + [3]byte{112, 177, 78}: "Pace plc", + [3]byte{112, 178, 101}: "Hiltron s.r.l.", + [3]byte{112, 179, 213}: "IEEE REGISTRATION AUTHORITY - Please see OUI36 public listing for more information.", + [3]byte{112, 181, 153}: "Embedded Technologies s.r.o.", + [3]byte{112, 185, 33}: "FiberHome Telecommunication Technologies CO.,LTD", + [3]byte{112, 186, 239}: "Hangzhou H3C Technologies Co., Limited", + [3]byte{112, 198, 172}: "Bosch Automotive Aftermarket", + [3]byte{112, 202, 155}: "CISCO SYSTEMS, INC.", + [3]byte{112, 205, 96}: "Apple", + [3]byte{112, 212, 242}: "RIM", + [3]byte{112, 213, 126}: "Scalar Corporation", + [3]byte{112, 213, 231}: "Wellcore Corporation", + [3]byte{112, 214, 182}: "Metrum Technologies", + [3]byte{112, 216, 128}: "Upos System sp. z o.o.", + [3]byte{112, 221, 161}: "Tellabs", + [3]byte{112, 222, 226}: "Apple", + [3]byte{112, 224, 39}: "HONGYU COMMUNICATION TECHNOLOGY LIMITED", + [3]byte{112, 225, 57}: "3view Ltd", + [3]byte{112, 226, 76}: "SAE IT-systems GmbH & Co. KG", + [3]byte{112, 226, 132}: "Wistron InfoComm(Zhongshan) Corporation", + [3]byte{112, 232, 67}: "Beijing C&W Optical Communication Technology Co.,Ltd.", + [3]byte{112, 238, 80}: "Netatmo", + [3]byte{112, 241, 118}: "Data Modul AG", + [3]byte{112, 241, 150}: "Actiontec Electronics, Inc", + [3]byte{112, 241, 161}: "Liteon Technology Corporation", + [3]byte{112, 241, 229}: "Xetawave LLC", + [3]byte{112, 243, 149}: "Universal Global Scientific Industrial Co., Ltd.", + [3]byte{112, 249, 39}: "Samsung Electronics", + [3]byte{112, 249, 109}: "Hangzhou H3C Technologies Co., Limited", + [3]byte{112, 252, 140}: "OneAccess SA", + [3]byte{112, 255, 92}: "Cheerzing Communication(Xiamen)Technology Co.,Ltd", + [3]byte{112, 255, 118}: "Texas Instruments", + [3]byte{116, 10, 188}: "JSJS Designs (Europe) Limited", + [3]byte{116, 14, 219}: "Optowiz Co., Ltd", + [3]byte{116, 20, 137}: "SRT Wireless", + [3]byte{116, 21, 226}: "Tri-Sen Systems Corporation", + [3]byte{116, 25, 248}: "IEEE REGISTRATION AUTHORITY - Please see MAM public listing for more information.", + [3]byte{116, 30, 147}: "Fiberhome Telecommunication Tech.Co.,Ltd.", + [3]byte{116, 37, 138}: "Hangzhou H3C Technologies Co., Limited", + [3]byte{116, 38, 172}: "Cisco", + [3]byte{116, 39, 60}: "ChangYang Technology (Nanjing) Co., LTD", + [3]byte{116, 39, 234}: "Elitegroup Computer Systems Co., Ltd.", + [3]byte{116, 41, 175}: "Hon Hai Precision Ind. Co.,Ltd.", + [3]byte{116, 43, 15}: "Infinidat Ltd.", + [3]byte{116, 43, 98}: "Fujitsu Limited", + [3]byte{116, 45, 10}: "Norfolk Elektronik AG", + [3]byte{116, 47, 104}: "Azurewave Technologies, Inc.", + [3]byte{116, 49, 112}: "Arcadyan Technology Corporation", + [3]byte{116, 50, 86}: "NT-ware Systemprg GmbH", + [3]byte{116, 55, 47}: "Tongfang Shenzhen Cloudcomputing Technology Co.,Ltd", + [3]byte{116, 56, 137}: "ANNAX Anzeigesysteme GmbH", + [3]byte{116, 62, 203}: "Gentrice tech", + [3]byte{116, 68, 1}: "NETGEAR", + [3]byte{116, 69, 138}: "Samsung Electronics Co.,Ltd", + [3]byte{116, 70, 160}: "Hewlett Packard", + [3]byte{116, 75, 233}: "EXPLORER HYPERTECH CO.,LTD", + [3]byte{116, 77, 121}: "Arrive Systems Inc.", + [3]byte{116, 83, 39}: "COMMSEN CO., LIMITED", + [3]byte{116, 84, 125}: "Cisco SPVTG", + [3]byte{116, 86, 18}: "ARRIS Group, Inc.", + [3]byte{116, 87, 152}: "TRUMPF Laser GmbH + Co. KG", + [3]byte{116, 92, 159}: "TCT mobile ltd.", + [3]byte{116, 94, 28}: "PIONEER CORPORATION", + [3]byte{116, 95, 0}: "Samsung Semiconductor Inc.", + [3]byte{116, 95, 174}: "TSL PPL", + [3]byte{116, 99, 223}: "VTS GmbH", + [3]byte{116, 101, 209}: "Atlinks", + [3]byte{116, 102, 48}: "T:mi Ytti", + [3]byte{116, 106, 137}: "Rezolt Corporation", + [3]byte{116, 106, 143}: "VS Vision Systems GmbH", + [3]byte{116, 107, 130}: "MOVEK", + [3]byte{116, 111, 61}: "Contec GmbH", + [3]byte{116, 114, 242}: "Chipsip Technology Co., Ltd.", + [3]byte{116, 117, 72}: "Amazon Technologies Inc.", + [3]byte{116, 120, 24}: "ServiceAssure", + [3]byte{116, 123, 122}: "ETH Inc.", + [3]byte{116, 125, 182}: "Aliwei Communications, Inc", + [3]byte{116, 126, 26}: "Red Embedded Design Limited", + [3]byte{116, 126, 45}: "Beijing Thomson CITIC Digital Technology Co. LTD.", + [3]byte{116, 134, 122}: "Dell Inc", + [3]byte{116, 136, 42}: "HUAWEI TECHNOLOGIES CO.,LTD", + [3]byte{116, 136, 139}: "ADB Broadband Italia", + [3]byte{116, 142, 8}: "Bestek Corp.", + [3]byte{116, 142, 248}: "Brocade Communications Systems, Inc.", + [3]byte{116, 143, 27}: "MasterImage 3D", + [3]byte{116, 143, 77}: "MEN Mikro Elektronik GmbH", + [3]byte{116, 144, 80}: "Renesas Electronics Corporation", + [3]byte{116, 145, 26}: "Ruckus Wireless", + [3]byte{116, 147, 164}: "Zebra Technologies Corp.", + [3]byte{116, 148, 61}: "AgJunction", + [3]byte{116, 153, 117}: "IBM Corporation", + [3]byte{116, 156, 82}: "Huizhou Desay SV Automotive Co., Ltd.", + [3]byte{116, 157, 220}: "2Wire", + [3]byte{116, 164, 167}: "QRS Music Technologies, Inc.", + [3]byte{116, 164, 181}: "Powerleader Science and Technology Co. Ltd.", + [3]byte{116, 167, 34}: "LG Electronics", + [3]byte{116, 173, 183}: "China Mobile Group Device Co.,Ltd.", + [3]byte{116, 174, 118}: "iNovo Broadband, Inc.", + [3]byte{116, 176, 12}: "Network Video Technologies, Inc", + [3]byte{116, 185, 235}: "Fujian JinQianMao Electronic Technology Co.,Ltd", + [3]byte{116, 186, 219}: "Longconn Electornics(shenzhen)Co.,Ltd", + [3]byte{116, 190, 8}: "ATEK Products, LLC", + [3]byte{116, 191, 161}: "HYUNTECK", + [3]byte{116, 198, 33}: "Zhejiang Hite Renewable Energy Co.,LTD", + [3]byte{116, 201, 154}: "Ericsson AB", + [3]byte{116, 202, 37}: "Calxeda, Inc.", + [3]byte{116, 205, 12}: "Smith Myers Communications Ltd.", + [3]byte{116, 206, 86}: "Packet Force Technology Limited Company", + [3]byte{116, 208, 43}: "ASUSTek COMPUTER INC.", + [3]byte{116, 208, 220}: "ERICSSON AB", + [3]byte{116, 212, 53}: "GIGA-BYTE TECHNOLOGY CO.,LTD.", + [3]byte{116, 214, 117}: "WYMA Tecnologia", + [3]byte{116, 216, 80}: "Evrisko Systems", + [3]byte{116, 218, 56}: "Edimax Technology Co. Ltd.", + [3]byte{116, 219, 209}: "Ebay Inc", + [3]byte{116, 222, 43}: "Liteon Technology Corporation", + [3]byte{116, 224, 110}: "Ergophone GmbH", + [3]byte{116, 225, 74}: "IEEE REGISTRATION AUTHORITY - Please see MAM public listing for more information.", + [3]byte{116, 225, 182}: "Apple", + [3]byte{116, 226, 245}: "Apple", + [3]byte{116, 228, 36}: "APISTE CORPORATION", + [3]byte{116, 229, 11}: "Intel Corporate", + [3]byte{116, 229, 55}: "RADSPIN", + [3]byte{116, 229, 67}: "Liteon Technology Corporation", + [3]byte{116, 230, 226}: "Dell Inc.", + [3]byte{116, 231, 198}: "ARRIS Group, Inc.", + [3]byte{116, 234, 58}: "TP-LINK Technologies Co.,Ltd.", + [3]byte{116, 236, 241}: "Acumen", + [3]byte{116, 240, 109}: "AzureWave Technologies, Inc.", + [3]byte{116, 240, 125}: "BnCOM Co.,Ltd", + [3]byte{116, 241, 2}: "Beijing HCHCOM Technology Co., Ltd", + [3]byte{116, 244, 19}: "Maxwell Forest", + [3]byte{116, 246, 18}: "ARRIS Group, Inc.", + [3]byte{116, 247, 38}: "Neuron Robotics", + [3]byte{116, 248, 93}: "Berkeley Nucleonics Corp", + [3]byte{116, 253, 160}: "Compupal (Group) Corporation", + [3]byte{116, 254, 72}: "ADVANTECH CO., LTD.", + [3]byte{116, 255, 125}: "Wren Sound Systems, LLC", + [3]byte{120, 2, 143}: "Adaptive Spectrum and Signal Alignment (ASSIA), Inc.", + [3]byte{120, 7, 56}: "Z.U.K. Elzab S.A.", + [3]byte{120, 17, 133}: "NBS Payment Solutions Inc.", + [3]byte{120, 18, 184}: "ORANTEK LIMITED", + [3]byte{120, 24, 129}: "AzureWave Technologies, Inc.", + [3]byte{120, 25, 46}: "NASCENT Technology", + [3]byte{120, 25, 247}: "Juniper Networks", + [3]byte{120, 28, 90}: "SHARP Corporation", + [3]byte{120, 29, 186}: "HUAWEI TECHNOLOGIES CO.,LTD", + [3]byte{120, 29, 253}: "Jabil Inc", + [3]byte{120, 31, 219}: "Samsung Electronics Co.,Ltd", + [3]byte{120, 34, 61}: "Affirmed Networks", + [3]byte{120, 36, 175}: "ASUSTek COMPUTER INC.", + [3]byte{120, 37, 68}: "Omnima Limited", + [3]byte{120, 37, 173}: "SAMSUNG ELECTRONICS CO., LTD.", + [3]byte{120, 43, 203}: "Dell Inc", + [3]byte{120, 46, 239}: "Nokia Corporation", + [3]byte{120, 48, 59}: "Stephen Technologies Co.,Limited", + [3]byte{120, 48, 225}: "UltraClenz, LLC", + [3]byte{120, 49, 43}: "zte corporation", + [3]byte{120, 49, 193}: "Apple", + [3]byte{120, 50, 79}: "Millennium Group, Inc.", + [3]byte{120, 58, 132}: "Apple", + [3]byte{120, 60, 227}: "Kai-EE", + [3]byte{120, 61, 91}: "TELNET Redes Inteligentes S.A.", + [3]byte{120, 62, 83}: "BSkyB Ltd", + [3]byte{120, 63, 21}: "EasySYNC Ltd.", + [3]byte{120, 68, 5}: "FUJITU(HONG KONG) ELECTRONIC Co.,LTD.", + [3]byte{120, 68, 118}: "Zioncom technology co.,ltd", + [3]byte{120, 69, 97}: "CyberTAN Technology Inc.", + [3]byte{120, 69, 196}: "Dell Inc", + [3]byte{120, 70, 196}: "DAEHAP HYPER-TECH", + [3]byte{120, 71, 29}: "Samsung Electronics Co.,Ltd", + [3]byte{120, 72, 89}: "Hewlett Packard", + [3]byte{120, 73, 29}: "The Will-Burt Company", + [3]byte{120, 75, 8}: "f.robotics acquisitions ltd", + [3]byte{120, 75, 135}: "Murata Manufacturing Co.,Ltd.", + [3]byte{120, 81, 12}: "LiveU Ltd.", + [3]byte{120, 82, 26}: "Samsung Electronics Co.,Ltd", + [3]byte{120, 82, 98}: "Shenzhen Hojy Software Co., Ltd.", + [3]byte{120, 84, 46}: "D-Link International", + [3]byte{120, 85, 23}: "SankyuElectronics", + [3]byte{120, 87, 18}: "Mobile Integration Workgroup", + [3]byte{120, 89, 62}: "RAFI GmbH & Co.KG", + [3]byte{120, 89, 94}: "Samsung Electronics Co.,Ltd", + [3]byte{120, 89, 104}: "Hon Hai Precision Ind.Co.,Ltd.", + [3]byte{120, 92, 114}: "Hioso Technology Co., Ltd.", + [3]byte{120, 97, 124}: "MITSUMI ELECTRIC CO.,LTD", + [3]byte{120, 102, 174}: "ZTEC Instruments, Inc.", + [3]byte{120, 106, 137}: "Huawei Technologies Co., Ltd", + [3]byte{120, 108, 28}: "Apple", + [3]byte{120, 127, 98}: "GiK mbH", + [3]byte{120, 129, 143}: "Server Racks Australia Pty Ltd", + [3]byte{120, 132, 60}: "Sony Corporation", + [3]byte{120, 132, 238}: "INDRA ESPACIO S.A.", + [3]byte{120, 137, 115}: "CMC", + [3]byte{120, 140, 84}: "Eltek Technologies LTD", + [3]byte{120, 141, 247}: "Hitron Technologies. Inc", + [3]byte{120, 146, 62}: "Nokia Corporation", + [3]byte{120, 146, 156}: "Intel Corporate", + [3]byte{120, 150, 132}: "ARRIS Group, Inc.", + [3]byte{120, 152, 253}: "Q9 Networks Inc.", + [3]byte{120, 153, 92}: "Nationz Technologies Inc", + [3]byte{120, 153, 102}: "Musilab Electronics (DongGuan)Co.,Ltd.", + [3]byte{120, 153, 143}: "MEDILINE ITALIA SRL", + [3]byte{120, 156, 231}: "Shenzhen Aikede Technology Co., Ltd", + [3]byte{120, 158, 208}: "Samsung Electronics", + [3]byte{120, 159, 76}: "HOERBIGER Elektronik GmbH", + [3]byte{120, 159, 135}: "Siemens AG I IA PP PRM", + [3]byte{120, 160, 81}: "iiNet Labs Pty Ltd", + [3]byte{120, 161, 6}: "TP-LINK TECHNOLOGIES CO.,LTD.", + [3]byte{120, 161, 131}: "Advidia", + [3]byte{120, 162, 160}: "Nintendo Co., Ltd.", + [3]byte{120, 163, 228}: "Apple", + [3]byte{120, 165, 4}: "Texas Instruments", + [3]byte{120, 165, 221}: "Shenzhen Smarteye Digital Electronics Co., Ltd", + [3]byte{120, 166, 131}: "Precidata", + [3]byte{120, 166, 189}: "DAEYEON Control&Instrument Co,.Ltd", + [3]byte{120, 167, 20}: "Amphenol", + [3]byte{120, 168, 115}: "Samsung Electronics Co.,Ltd", + [3]byte{120, 171, 96}: "ABB Australia", + [3]byte{120, 171, 187}: "Samsung Electronics Co.,LTD", + [3]byte{120, 172, 192}: "Hewlett-Packard Company", + [3]byte{120, 174, 12}: "Far South Networks", + [3]byte{120, 179, 185}: "ShangHai sunup lighting CO.,LTD", + [3]byte{120, 179, 206}: "Elo touch solutions", + [3]byte{120, 181, 210}: "Ever Treasure Industrial Limited", + [3]byte{120, 182, 193}: "AOBO Telecom Co.,Ltd", + [3]byte{120, 184, 26}: "INTER SALES A/S", + [3]byte{120, 186, 208}: "Shinybow Technology Co. Ltd.", + [3]byte{120, 190, 182}: "Enhanced Vision", + [3]byte{120, 190, 189}: "STULZ GmbH", + [3]byte{120, 196, 14}: "H&D Wireless", + [3]byte{120, 196, 171}: "Shenzhen Runsil Technology Co.,Ltd", + [3]byte{120, 197, 229}: "Texas Instruments", + [3]byte{120, 198, 187}: "Innovasic, Inc.", + [3]byte{120, 202, 4}: "Nokia Corporation", + [3]byte{120, 202, 57}: "Apple", + [3]byte{120, 202, 94}: "ELNO", + [3]byte{120, 203, 51}: "DHC Software Co.,Ltd", + [3]byte{120, 205, 142}: "SMC Networks Inc", + [3]byte{120, 208, 4}: "Neousys Technology Inc.", + [3]byte{120, 209, 41}: "Vicos", + [3]byte{120, 211, 79}: "Pace-O-Matic, Inc.", + [3]byte{120, 211, 141}: "HONGKONG YUNLINK TECHNOLOGY LIMITED", + [3]byte{120, 213, 181}: "NAVIELEKTRO KY", + [3]byte{120, 214, 111}: "Aristocrat Technologies Australia Pty. Ltd.", + [3]byte{120, 214, 240}: "Samsung Electro Mechanics", + [3]byte{120, 215, 82}: "HUAWEI TECHNOLOGIES CO.,LTD", + [3]byte{120, 217, 159}: "NuCom HK Ltd.", + [3]byte{120, 218, 110}: "Cisco", + [3]byte{120, 218, 179}: "GBO Technology", + [3]byte{120, 221, 8}: "Hon Hai Precision Ind. Co.,Ltd.", + [3]byte{120, 221, 214}: "c-scape", + [3]byte{120, 222, 228}: "Texas Instruments", + [3]byte{120, 227, 181}: "Hewlett-Packard Company", + [3]byte{120, 228, 0}: "Hon Hai Precision Ind. Co.,Ltd.", + [3]byte{120, 231, 209}: "Hewlett-Packard Company", + [3]byte{120, 232, 182}: "zte corporation", + [3]byte{120, 235, 20}: "SHENZHEN FAST TECHNOLOGIES CO.,LTD", + [3]byte{120, 236, 34}: "Shanghai Qihui Telecom Technology Co., LTD", + [3]byte{120, 236, 116}: "Kyland-USA", + [3]byte{120, 239, 76}: "Unetconvergence Co., Ltd.", + [3]byte{120, 245, 229}: "BEGA Gantenbrink-Leuchten KG", + [3]byte{120, 245, 253}: "Huawei Technologies Co., Ltd", + [3]byte{120, 247, 190}: "Samsung Electronics Co.,Ltd", + [3]byte{120, 247, 208}: "Silverbrook Research", + [3]byte{120, 253, 148}: "Apple", + [3]byte{120, 254, 61}: "Juniper Networks", + [3]byte{120, 254, 65}: "Socus networks", + [3]byte{120, 254, 226}: "Shanghai Diveo Technology Co., Ltd", + [3]byte{120, 255, 87}: "Intel Corporate", + [3]byte{124, 1, 135}: "Curtis Instruments, Inc.", + [3]byte{124, 2, 188}: "Hansung Electronics Co. LTD", + [3]byte{124, 3, 76}: "SAGEMCOM", + [3]byte{124, 3, 216}: "SAGEMCOM SAS", + [3]byte{124, 5, 7}: "PEGATRON CORPORATION", + [3]byte{124, 5, 30}: "RAFAEL LTD.", + [3]byte{124, 6, 35}: "Ultra Electronics, CIS", + [3]byte{124, 8, 217}: "Shanghai B-Star Technology Co", + [3]byte{124, 9, 43}: "Bekey A/S", + [3]byte{124, 10, 80}: "J-MEX Inc.", + [3]byte{124, 14, 206}: "Cisco", + [3]byte{124, 17, 190}: "Apple", + [3]byte{124, 20, 118}: "Damall Technologies SAS", + [3]byte{124, 22, 13}: "Saia-Burgess Controls AG", + [3]byte{124, 26, 3}: "8Locations Co., Ltd.", + [3]byte{124, 26, 252}: "Dalian Co-Edifice Video Technology Co., Ltd", + [3]byte{124, 30, 82}: "Microsoft", + [3]byte{124, 30, 179}: "2N TELEKOMUNIKACE a.s.", + [3]byte{124, 32, 72}: "KoamTac", + [3]byte{124, 32, 100}: "Alcatel Lucent IPD", + [3]byte{124, 37, 135}: "chaowifi.com", + [3]byte{124, 44, 243}: "Secure Electrans Ltd", + [3]byte{124, 46, 13}: "Blackmagic Design", + [3]byte{124, 47, 128}: "Gigaset Communications GmbH", + [3]byte{124, 51, 110}: "MEG Electronics Inc.", + [3]byte{124, 56, 108}: "Real Time Logic", + [3]byte{124, 57, 32}: "SSOMA SECURITY", + [3]byte{124, 59, 213}: "Imago Group", + [3]byte{124, 62, 157}: "PATECH", + [3]byte{124, 67, 143}: "E-Band Communications Corp.", + [3]byte{124, 68, 76}: "Entertainment Solutions, S.L.", + [3]byte{124, 73, 185}: "Plexus Manufacturing Sdn Bhd", + [3]byte{124, 74, 130}: "Portsmith LLC", + [3]byte{124, 74, 168}: "MindTree Wireless PVT Ltd", + [3]byte{124, 75, 120}: "Red Sun Synthesis Pte Ltd", + [3]byte{124, 76, 88}: "Scale Computing, Inc.", + [3]byte{124, 76, 165}: "BSkyB Ltd", + [3]byte{124, 79, 181}: "Arcadyan Technology Corporation", + [3]byte{124, 85, 231}: "YSI, Inc.", + [3]byte{124, 96, 151}: "HUAWEI TECHNOLOGIES CO.,LTD", + [3]byte{124, 97, 147}: "HTC Corporation", + [3]byte{124, 102, 157}: "Texas Instruments", + [3]byte{124, 105, 246}: "Cisco", + [3]byte{124, 106, 179}: "IBC TECHNOLOGIES INC.", + [3]byte{124, 106, 195}: "GatesAir, Inc", + [3]byte{124, 106, 219}: "SafeTone Technology Co.,Ltd", + [3]byte{124, 107, 51}: "Tenyu Tech Co. Ltd.", + [3]byte{124, 107, 82}: "Tigaro Wireless", + [3]byte{124, 108, 57}: "PIXSYS SRL", + [3]byte{124, 108, 143}: "AMS NEVE LTD", + [3]byte{124, 109, 98}: "Apple", + [3]byte{124, 109, 248}: "Apple", + [3]byte{124, 111, 6}: "Caterpillar Trimble Control Technologies", + [3]byte{124, 111, 248}: "ShenZhen ACTO Digital Video Technology Co.,Ltd.", + [3]byte{124, 112, 188}: "IEEE REGISTRATION AUTHORITY - Please see MAM public listing for more information.", + [3]byte{124, 114, 228}: "Unikey Technologies", + [3]byte{124, 118, 115}: "ENMAS GmbH", + [3]byte{124, 122, 145}: "Intel Corporate", + [3]byte{124, 123, 228}: "Z'SEDAI KENKYUSHO CORPORATION", + [3]byte{124, 125, 65}: "Jinmuyu Electronics Co., Ltd.", + [3]byte{124, 130, 45}: "Nortec", + [3]byte{124, 131, 6}: "Glen Dimplex Nordic as", + [3]byte{124, 141, 145}: "Shanghai Hongzhuo Information Technology co.,LTD", + [3]byte{124, 142, 228}: "Texas Instruments", + [3]byte{124, 148, 178}: "Philips Healthcare PCCI", + [3]byte{124, 149, 243}: "Cisco", + [3]byte{124, 151, 99}: "Openmatics s.r.o.", + [3]byte{124, 154, 155}: "VSE valencia smart energy", + [3]byte{124, 161, 93}: "GN ReSound A/S", + [3]byte{124, 162, 155}: "D.SignT GmbH & Co. KG", + [3]byte{124, 166, 29}: "MHL, LLC", + [3]byte{124, 172, 178}: "Bosch Software Innovations GmbH", + [3]byte{124, 173, 116}: "Cisco", + [3]byte{124, 176, 62}: "OSRAM GmbH", + [3]byte{124, 177, 119}: "Satelco AG", + [3]byte{124, 178, 27}: "Cisco SPVTG", + [3]byte{124, 178, 50}: "TCL King High Frequency EI,Co.,LTD", + [3]byte{124, 181, 66}: "ACES Technology", + [3]byte{124, 183, 51}: "ASKEY COMPUTER CORP", + [3]byte{124, 183, 123}: "Paradigm Electronics Inc", + [3]byte{124, 187, 111}: "Cosco Electronics Co., Ltd.", + [3]byte{124, 189, 6}: "AE REFUsol", + [3]byte{124, 191, 136}: "Mobilicom LTD", + [3]byte{124, 191, 177}: "ARRIS Group, Inc.", + [3]byte{124, 195, 161}: "Apple", + [3]byte{124, 196, 239}: "Devialet", + [3]byte{124, 197, 55}: "Apple", + [3]byte{124, 200, 171}: "Acro Associates, Inc.", + [3]byte{124, 200, 208}: "TIANJIN YAAN TECHNOLOGY CO., LTD.", + [3]byte{124, 200, 215}: "Damalisk", + [3]byte{124, 203, 13}: "Antaira Technologies, LLC", + [3]byte{124, 204, 184}: "Intel Corporate", + [3]byte{124, 205, 17}: "MS-Magnet", + [3]byte{124, 205, 60}: "Guangzhou Juzing Technology Co., Ltd", + [3]byte{124, 207, 207}: "Shanghai SEARI Intelligent System Co., Ltd", + [3]byte{124, 209, 195}: "Apple", + [3]byte{124, 211, 10}: "INVENTEC Corporation", + [3]byte{124, 215, 98}: "Freestyle Technology Pty Ltd", + [3]byte{124, 216, 68}: "Enmotus Inc", + [3]byte{124, 217, 254}: "New Cosmos Electric Co., Ltd.", + [3]byte{124, 218, 132}: "Dongnian Networks Inc.", + [3]byte{124, 221, 17}: "Chongqing MAS SCI&TECH.Co.,Ltd", + [3]byte{124, 221, 32}: "IOXOS Technologies S.A.", + [3]byte{124, 221, 144}: "Shenzhen Ogemray Technology Co., Ltd.", + [3]byte{124, 224, 68}: "NEON Inc", + [3]byte{124, 225, 255}: "Computer Performance, Inc. DBA Digital Loggers, Inc.", + [3]byte{124, 228, 170}: "PRIVATE", + [3]byte{124, 229, 36}: "Quirky, Inc.", + [3]byte{124, 229, 107}: "ESEN Optoelectronics Technology Co.,Ltd.", + [3]byte{124, 233, 211}: "Hon Hai Precision Ind. Co.,Ltd.", + [3]byte{124, 235, 234}: "ASCT", + [3]byte{124, 237, 141}: "MICROSOFT", + [3]byte{124, 239, 24}: "Creative Product Design Pty. Ltd.", + [3]byte{124, 239, 138}: "Inhon International Ltd.", + [3]byte{124, 240, 95}: "Apple", + [3]byte{124, 240, 152}: "Bee Beans Technologies, Inc.", + [3]byte{124, 240, 186}: "Linkwell Telesystems Pvt Ltd", + [3]byte{124, 244, 41}: "NUUO Inc.", + [3]byte{124, 250, 223}: "Apple", + [3]byte{124, 254, 40}: "Salutron Inc.", + [3]byte{124, 254, 78}: "Shenzhen Safe vision Technology Co.,LTD", + [3]byte{124, 255, 98}: "Huizhou Super Electron Technology Co.,Ltd.", + [3]byte{128, 0, 11}: "Intel Corporate", + [3]byte{128, 0, 16}: "ATT BELL LABORATORIES", + [3]byte{128, 0, 110}: "Apple", + [3]byte{128, 5, 223}: "Montage Technology Group Limited", + [3]byte{128, 7, 162}: "Esson Technology Inc.", + [3]byte{128, 9, 2}: "Keysight Technologies, Inc.", + [3]byte{128, 10, 6}: "COMTEC co.,ltd", + [3]byte{128, 14, 36}: "ForgetBox", + [3]byte{128, 20, 64}: "Sunlit System Technology Corp", + [3]byte{128, 20, 168}: "Guangzhou V-SOLUTION Electronic Technology Co., Ltd.", + [3]byte{128, 22, 183}: "Brunel University", + [3]byte{128, 23, 125}: "Nortel Networks", + [3]byte{128, 24, 167}: "Samsung Eletronics Co., Ltd", + [3]byte{128, 25, 52}: "Intel Corporate", + [3]byte{128, 25, 103}: "Shanghai Reallytek Information Technology Co.,Ltd", + [3]byte{128, 29, 170}: "Avaya Inc", + [3]byte{128, 31, 2}: "Edimax Technology Co. Ltd.", + [3]byte{128, 32, 175}: "Trade FIDES, a.s.", + [3]byte{128, 34, 117}: "Beijing Beny Wave Technology Co Ltd", + [3]byte{128, 42, 250}: "Germaneers GmbH", + [3]byte{128, 45, 225}: "Solarbridge Technologies", + [3]byte{128, 46, 20}: "azeti Networks AG", + [3]byte{128, 47, 222}: "Zurich Instruments AG", + [3]byte{128, 52, 87}: "OT Systems Limited", + [3]byte{128, 55, 115}: "Netgear Inc", + [3]byte{128, 56, 253}: "LeapFrog Enterprises, Inc.", + [3]byte{128, 57, 229}: "PATLITE CORPORATION", + [3]byte{128, 59, 154}: "ghe-ces electronic ag", + [3]byte{128, 63, 93}: "Winstars Technology Ltd", + [3]byte{128, 63, 214}: "bytes at work AG", + [3]byte{128, 65, 78}: "BBK Electronics Corp., Ltd.,", + [3]byte{128, 66, 124}: "Adolf Tedsen GmbH & Co. KG", + [3]byte{128, 71, 49}: "Packet Design, Inc.", + [3]byte{128, 72, 165}: "SICHUAN TIANYI COMHEART TELECOM CO.,LTD", + [3]byte{128, 73, 113}: "Apple", + [3]byte{128, 75, 32}: "Ventilation Control", + [3]byte{128, 79, 88}: "ThinkEco, Inc.", + [3]byte{128, 80, 27}: "Nokia Corporation", + [3]byte{128, 86, 242}: "Hon Hai Precision Ind. Co.,Ltd.", + [3]byte{128, 87, 25}: "Samsung Electronics Co.,Ltd", + [3]byte{128, 88, 197}: "NovaTec Kommunikationstechnik GmbH", + [3]byte{128, 89, 253}: "Noviga", + [3]byte{128, 96, 7}: "RIM", + [3]byte{128, 97, 143}: "Shenzhen sangfei consumer communications co.,ltd", + [3]byte{128, 100, 89}: "Nimbus Inc.", + [3]byte{128, 101, 233}: "BenQ Corporation", + [3]byte{128, 102, 41}: "Prescope Technologies CO.,LTD.", + [3]byte{128, 108, 27}: "Motorola Mobility LLC", + [3]byte{128, 108, 139}: "KAESER KOMPRESSOREN AG", + [3]byte{128, 108, 188}: "NET New Electronic Technology GmbH", + [3]byte{128, 113, 31}: "Juniper Networks", + [3]byte{128, 113, 122}: "Huawei Technologies Co., Ltd", + [3]byte{128, 118, 147}: "Newag SA", + [3]byte{128, 121, 174}: "ShanDong Tecsunrise Co.,Ltd", + [3]byte{128, 122, 127}: "ABB Genway Xiamen Electrical Equipment CO., LTD", + [3]byte{128, 123, 30}: "Corsair Components", + [3]byte{128, 125, 27}: "Neosystem Co. Ltd.", + [3]byte{128, 125, 227}: "Chongqing Sichuan Instrument Microcircuit Co.LTD.", + [3]byte{128, 129, 165}: "TONGQING COMMUNICATION EQUIPMENT (SHENZHEN) Co.,Ltd", + [3]byte{128, 130, 135}: "ATCOM Technology Co.Ltd.", + [3]byte{128, 134, 152}: "Netronics Technologies Inc.", + [3]byte{128, 134, 242}: "Intel Corporate", + [3]byte{128, 139, 92}: "Shenzhen Runhuicheng Technology Co., Ltd", + [3]byte{128, 145, 42}: "Lih Rong electronic Enterprise Co., Ltd.", + [3]byte{128, 145, 192}: "AgileMesh, Inc.", + [3]byte{128, 146, 159}: "Apple", + [3]byte{128, 147, 147}: "Xapt GmbH", + [3]byte{128, 148, 108}: "TOKYO RADAR CORPORATION", + [3]byte{128, 150, 177}: "ARRIS Group, Inc.", + [3]byte{128, 150, 202}: "Hon Hai Precision Ind Co.,Ltd", + [3]byte{128, 151, 27}: "Altenergy Power System,Inc.", + [3]byte{128, 155, 32}: "Intel Corporate", + [3]byte{128, 161, 215}: "Shanghai DareGlobal Technologies Co.,Ltd", + [3]byte{128, 170, 164}: "USAG", + [3]byte{128, 173, 103}: "Kasda Digital Technology Co.,Ltd", + [3]byte{128, 178, 25}: "ELEKTRON TECHNOLOGY UK LIMITED", + [3]byte{128, 178, 137}: "Forworld Electronics Ltd.", + [3]byte{128, 179, 42}: "Alstom Grid", + [3]byte{128, 182, 134}: "Huawei Technologies Co., Ltd", + [3]byte{128, 185, 92}: "ELFTECH Co., Ltd.", + [3]byte{128, 186, 172}: "TeleAdapt Ltd", + [3]byte{128, 186, 230}: "Neets", + [3]byte{128, 187, 235}: "Satmap Systems Ltd", + [3]byte{128, 190, 5}: "Apple", + [3]byte{128, 193, 110}: "Hewlett Packard", + [3]byte{128, 198, 63}: "Remec Broadband Wireless , LLC", + [3]byte{128, 198, 171}: "Technicolor USA Inc.", + [3]byte{128, 198, 202}: "Endian s.r.l.", + [3]byte{128, 200, 98}: "Openpeak, Inc", + [3]byte{128, 206, 177}: "Theissen Training Systems GmbH", + [3]byte{128, 207, 65}: "Lenovo Mobile Communication Technology Ltd.", + [3]byte{128, 208, 25}: "Embed, Inc", + [3]byte{128, 209, 139}: "Hangzhou I'converge Technology Co.,Ltd", + [3]byte{128, 210, 29}: "AzureWave Technologies, Inc", + [3]byte{128, 212, 51}: "LzLabs GmbH", + [3]byte{128, 215, 51}: "QSR Automations, Inc.", + [3]byte{128, 219, 49}: "Power Quotient International Co., Ltd.", + [3]byte{128, 230, 80}: "Apple", + [3]byte{128, 234, 150}: "Apple", + [3]byte{128, 234, 202}: "Dialog Semiconductor Hellas SA", + [3]byte{128, 238, 115}: "Shuttle Inc.", + [3]byte{128, 242, 94}: "Kyynel", + [3]byte{128, 245, 147}: "IRCO Sistemas de Telecomunicación S.A.", + [3]byte{128, 246, 46}: "Hangzhou H3C Technologies Co., Limited", + [3]byte{128, 248, 235}: "RayTight", + [3]byte{128, 250, 91}: "CLEVO CO.", + [3]byte{128, 251, 6}: "HUAWEI TECHNOLOGIES CO.,LTD", + [3]byte{128, 255, 168}: "UNIDIS", + [3]byte{132, 0, 210}: "Sony Ericsson Mobile Communications AB", + [3]byte{132, 1, 167}: "Greyware Automation Products, Inc", + [3]byte{132, 11, 45}: "SAMSUNG ELECTRO-MECHANICS CO., LTD", + [3]byte{132, 15, 69}: "Shanghai GMT Digital Technologies Co., Ltd", + [3]byte{132, 23, 21}: "GP Electronics (HK) Ltd.", + [3]byte{132, 23, 102}: "Weifang GoerTek Electronics Co., Ltd", + [3]byte{132, 24, 38}: "Osram GmbH", + [3]byte{132, 24, 58}: "Ruckus Wireless", + [3]byte{132, 24, 136}: "Juniper Networks", + [3]byte{132, 27, 56}: "Shenzhen Excelsecu Data Technology Co.,Ltd", + [3]byte{132, 27, 94}: "NETGEAR", + [3]byte{132, 30, 38}: "KERNEL-I Co.,LTD", + [3]byte{132, 33, 65}: "Shenzhen Ginwave Technologies Ltd.", + [3]byte{132, 36, 141}: "Motorola Solutions Inc", + [3]byte{132, 37, 63}: "Silex Technology, Inc", + [3]byte{132, 37, 164}: "Tariox Limited", + [3]byte{132, 37, 219}: "Samsung Electronics Co.,Ltd", + [3]byte{132, 38, 21}: "ADB Broadband Italia", + [3]byte{132, 38, 43}: "Alcatel-Lucent", + [3]byte{132, 38, 144}: "BEIJING THOUGHT SCIENCE CO.,LTD.", + [3]byte{132, 39, 206}: "Corporation of the Presiding Bishop of The Church of Jesus Christ of Latter-day Saints", + [3]byte{132, 41, 20}: "EMPORIA TELECOM Produktions- und VertriebsgesmbH & Co KG", + [3]byte{132, 41, 153}: "Apple", + [3]byte{132, 43, 43}: "Dell Inc.", + [3]byte{132, 43, 80}: "Huria Co.,Ltd.", + [3]byte{132, 43, 188}: "Modelleisenbahn GmbH", + [3]byte{132, 47, 117}: "Innokas Group", + [3]byte{132, 48, 229}: "SkyHawke Technologies, LLC", + [3]byte{132, 50, 234}: "ANHUI WANZTEN P&T CO., LTD", + [3]byte{132, 52, 151}: "Hewlett Packard", + [3]byte{132, 54, 17}: "hyungseul publishing networks", + [3]byte{132, 56, 53}: "Apple", + [3]byte{132, 56, 56}: "Samsung Electro Mechanics co., LTD.", + [3]byte{132, 58, 75}: "Intel Corporate", + [3]byte{132, 63, 78}: "Tri-Tech Manufacturing, Inc.", + [3]byte{132, 68, 100}: "ServerU Inc", + [3]byte{132, 72, 35}: "WOXTER TECHNOLOGY Co. Ltd", + [3]byte{132, 73, 21}: "vArmour Networks, Inc.", + [3]byte{132, 75, 245}: "Hon Hai Precision Ind. Co.,Ltd.", + [3]byte{132, 79, 3}: "Ablelink Electronics Ltd", + [3]byte{132, 81, 129}: "Samsung Electronics Co.,Ltd", + [3]byte{132, 85, 165}: "Samsung Elec Co.,Ltd", + [3]byte{132, 86, 156}: "Coho Data, Inc.,", + [3]byte{132, 87, 135}: "DVR C&C Co., Ltd.", + [3]byte{132, 92, 147}: "Chabrier Services", + [3]byte{132, 93, 215}: "Shenzhen Netcom Electronics Co.,Ltd", + [3]byte{132, 98, 35}: "Shenzhen Coship Electronics Co., Ltd.", + [3]byte{132, 98, 166}: "EuroCB (Phils), Inc.", + [3]byte{132, 99, 214}: "Microsoft Corporation", + [3]byte{132, 106, 237}: "Wireless Tsukamoto.,co.LTD", + [3]byte{132, 110, 177}: "Park Assist LLC", + [3]byte{132, 114, 7}: "I&C Technology", + [3]byte{132, 116, 42}: "zte corporation", + [3]byte{132, 118, 22}: "Addat S.r.o.", + [3]byte{132, 120, 139}: "Apple", + [3]byte{132, 120, 172}: "Cisco", + [3]byte{132, 122, 136}: "HTC Corporation", + [3]byte{132, 126, 64}: "Texas Instruments", + [3]byte{132, 130, 244}: "Beijing Huasun Unicreate Technology Co., Ltd", + [3]byte{132, 131, 54}: "Newrun", + [3]byte{132, 131, 113}: "Avaya, Inc", + [3]byte{132, 132, 51}: "Paradox Engineering SA", + [3]byte{132, 133, 6}: "Apple", + [3]byte{132, 133, 10}: "Hella Sonnen- und Wetterschutztechnik GmbH", + [3]byte{132, 134, 243}: "Greenvity Communications", + [3]byte{132, 141, 132}: "Rajant Corporation", + [3]byte{132, 141, 199}: "Cisco SPVTG", + [3]byte{132, 142, 12}: "Apple", + [3]byte{132, 142, 150}: "Embertec Pty Ltd", + [3]byte{132, 142, 223}: "Sony Mobile Communications AB", + [3]byte{132, 143, 105}: "Dell Inc.", + [3]byte{132, 144, 0}: "Arnold & Richter Cine Technik", + [3]byte{132, 147, 12}: "InCoax Networks Europe AB", + [3]byte{132, 148, 140}: "Hitron Technologies. Inc", + [3]byte{132, 150, 129}: "Cathay Communication Co.,Ltd", + [3]byte{132, 150, 216}: "Pace plc", + [3]byte{132, 151, 184}: "Memjet Inc.", + [3]byte{132, 156, 166}: "Arcadyan Technology Corporation", + [3]byte{132, 157, 197}: "Centera Photonics Inc.", + [3]byte{132, 164, 102}: "Samsung Electronics Co.,Ltd", + [3]byte{132, 166, 200}: "Intel Corporate", + [3]byte{132, 167, 131}: "Alcatel Lucent", + [3]byte{132, 168, 228}: "Shenzhen Huawei Communication Technologies Co., Ltd", + [3]byte{132, 169, 145}: "Cyber Trans Japan Co.,Ltd.", + [3]byte{132, 172, 164}: "Beijing Novel Super Digital TV Technology Co., Ltd", + [3]byte{132, 175, 31}: "Beat System Service Co,. Ltd.", + [3]byte{132, 177, 83}: "Apple", + [3]byte{132, 181, 156}: "Juniper networks", + [3]byte{132, 194, 228}: "Jiangsu Qinheng Co., Ltd.", + [3]byte{132, 199, 39}: "Gnodal Ltd", + [3]byte{132, 199, 169}: "C3PO S.A.", + [3]byte{132, 200, 177}: "Incognito Software Inc.", + [3]byte{132, 201, 178}: "D-Link International", + [3]byte{132, 211, 42}: "IEEE 1905.1", + [3]byte{132, 217, 200}: "Unipattern Co.,", + [3]byte{132, 219, 47}: "Sierra Wireless Inc", + [3]byte{132, 221, 32}: "Texas Instruments", + [3]byte{132, 221, 183}: "Cilag GmbH International", + [3]byte{132, 222, 61}: "Crystal Vision Ltd", + [3]byte{132, 223, 12}: "NET2GRID BV", + [3]byte{132, 224, 88}: "Pace plc", + [3]byte{132, 228, 217}: "Shenzhen NEED technology Ltd.", + [3]byte{132, 230, 41}: "Bluwan SA", + [3]byte{132, 231, 20}: "Liang Herng Enterprise,Co.Ltd.", + [3]byte{132, 234, 153}: "Vieworks", + [3]byte{132, 235, 24}: "Texas Instruments", + [3]byte{132, 237, 51}: "BBMC Co.,Ltd", + [3]byte{132, 244, 147}: "OMS spol. s.r.o.", + [3]byte{132, 246, 76}: "Cross Point BV", + [3]byte{132, 252, 254}: "Apple", + [3]byte{132, 254, 158}: "RTC Industries, Inc.", + [3]byte{136, 3, 85}: "Arcadyan Technology Corp.", + [3]byte{136, 9, 5}: "MTMCommunications", + [3]byte{136, 15, 16}: "Huami Information Technology Co.,Ltd.", + [3]byte{136, 15, 182}: "Jabil Circuits India Pvt Ltd,-EHTP unit", + [3]byte{136, 16, 54}: "Panodic(ShenZhen) Electronics Limted", + [3]byte{136, 18, 78}: "Qualcomm Atheros", + [3]byte{136, 20, 43}: "Protonic Holland", + [3]byte{136, 21, 68}: "Meraki, Inc.", + [3]byte{136, 24, 174}: "Tamron Co., Ltd", + [3]byte{136, 29, 252}: "Cisco", + [3]byte{136, 31, 161}: "Apple", + [3]byte{136, 32, 18}: "LMI Technologies", + [3]byte{136, 33, 227}: "Nebusens, S.L.", + [3]byte{136, 35, 100}: "Watchnet DVR Inc", + [3]byte{136, 35, 254}: "TTTech Computertechnik AG", + [3]byte{136, 37, 44}: "Arcadyan Technology Corporation", + [3]byte{136, 41, 80}: "Dalian Netmoon Tech Develop Co.,Ltd", + [3]byte{136, 46, 90}: "storONE", + [3]byte{136, 48, 138}: "Murata Manufactuaring Co.,Ltd.", + [3]byte{136, 50, 155}: "Samsung Electro Mechanics co.,LTD.", + [3]byte{136, 51, 20}: "Texas Instruments", + [3]byte{136, 53, 76}: "Transics", + [3]byte{136, 54, 18}: "SRC Computers, LLC", + [3]byte{136, 65, 193}: "ORBISAT DA AMAZONIA IND E AEROL SA", + [3]byte{136, 65, 252}: "AirTies Wireless Netowrks", + [3]byte{136, 67, 225}: "CISCO SYSTEMS, INC.", + [3]byte{136, 68, 246}: "Nokia Corporation", + [3]byte{136, 70, 42}: "Telechips Inc.", + [3]byte{136, 75, 57}: "Siemens AG, Healthcare Sector", + [3]byte{136, 81, 251}: "Hewlett Packard", + [3]byte{136, 83, 46}: "Intel Corporate", + [3]byte{136, 83, 149}: "Apple", + [3]byte{136, 83, 212}: "Huawei Technologies Co., Ltd", + [3]byte{136, 87, 109}: "XTA Electronics Ltd", + [3]byte{136, 90, 146}: "Cisco", + [3]byte{136, 91, 221}: "Aerohive Networks Inc.", + [3]byte{136, 92, 71}: "Alcatel Lucent", + [3]byte{136, 97, 90}: "Siano Mobile Silicon Ltd.", + [3]byte{136, 99, 223}: "Apple", + [3]byte{136, 104, 92}: "Shenzhen ChuangDao & Perpetual Eternal Technology Co.,Ltd", + [3]byte{136, 107, 118}: "CHINA HOPEFUL GROUP HOPEFUL ELECTRIC CO.,LTD", + [3]byte{136, 112, 140}: "Lenovo Mobile Communication Technology Ltd.", + [3]byte{136, 112, 239}: "SC Professional Trading Co., Ltd.", + [3]byte{136, 115, 152}: "K2E Tekpoint", + [3]byte{136, 117, 86}: "Cisco", + [3]byte{136, 120, 156}: "Game Technologies SA", + [3]byte{136, 134, 3}: "HUAWEI TECHNOLOGIES CO.,LTD", + [3]byte{136, 134, 160}: "Simton Technologies, Ltd.", + [3]byte{136, 135, 23}: "CANON INC.", + [3]byte{136, 135, 221}: "DarbeeVision Inc.", + [3]byte{136, 137, 20}: "All Components Incorporated", + [3]byte{136, 137, 100}: "GSI Electronics Inc.", + [3]byte{136, 139, 93}: "Storage Appliance Corporation", + [3]byte{136, 140, 25}: "Brady Corp Asia Pacific Ltd", + [3]byte{136, 145, 102}: "Viewcooper Corp.", + [3]byte{136, 145, 221}: "Racktivity", + [3]byte{136, 148, 113}: "Brocade Communications Systems, Inc.", + [3]byte{136, 148, 249}: "Gemicom Technology, Inc.", + [3]byte{136, 149, 185}: "Unified Packet Systems Crop", + [3]byte{136, 150, 118}: "TTC MARCONI s.r.o.", + [3]byte{136, 151, 223}: "Entrypass Corporation Sdn. Bhd.", + [3]byte{136, 152, 33}: "TERAON", + [3]byte{136, 155, 57}: "Samsung Electronics Co.,Ltd", + [3]byte{136, 156, 166}: "BTB Korea INC", + [3]byte{136, 159, 250}: "Hon Hai Precision Ind. Co.,Ltd.", + [3]byte{136, 163, 204}: "Amatis Controls", + [3]byte{136, 165, 189}: "QPCOM INC.", + [3]byte{136, 167, 60}: "Ragentek Technology Group", + [3]byte{136, 172, 193}: "Generiton Co., Ltd.", + [3]byte{136, 174, 29}: "COMPAL INFORMATION(KUNSHAN)CO.,LTD", + [3]byte{136, 177, 104}: "Delta Control GmbH", + [3]byte{136, 177, 225}: "AirTight Networks, Inc.", + [3]byte{136, 182, 39}: "Gembird Europe BV", + [3]byte{136, 186, 127}: "Qfiednet Co., Ltd.", + [3]byte{136, 191, 213}: "Simple Audio Ltd", + [3]byte{136, 195, 110}: "Beijing Ereneben lnformation Technology Limited", + [3]byte{136, 198, 38}: "Logitech - Ultimate Ears", + [3]byte{136, 198, 99}: "Apple", + [3]byte{136, 201, 208}: "LG Electronics", + [3]byte{136, 203, 135}: "Apple", + [3]byte{136, 215, 188}: "DEP Company", + [3]byte{136, 217, 98}: "Canopus Systems US LLC", + [3]byte{136, 220, 150}: "SENAO Networks, Inc.", + [3]byte{136, 221, 121}: "Voltaire", + [3]byte{136, 224, 160}: "Shenzhen VisionSTOR Technologies Co., Ltd", + [3]byte{136, 224, 243}: "Juniper Networks", + [3]byte{136, 227, 171}: "Huawei Technologies Co., Ltd", + [3]byte{136, 231, 18}: "Whirlpool Corporation", + [3]byte{136, 231, 166}: "iKnowledge Integration Corp.", + [3]byte{136, 232, 248}: "YONG TAI ELECTRONIC (DONGGUAN) LTD.", + [3]byte{136, 233, 23}: "Tamaggo", + [3]byte{136, 237, 28}: "Cudo Communication Co., Ltd.", + [3]byte{136, 240, 49}: "Cisco", + [3]byte{136, 240, 119}: "CISCO SYSTEMS, INC.", + [3]byte{136, 244, 136}: "cellon communications technology(shenzhen)Co.,Ltd.", + [3]byte{136, 244, 144}: "Jetmobile Pte Ltd", + [3]byte{136, 247, 199}: "Technicolor USA Inc.", + [3]byte{136, 253, 21}: "LINEEYE CO., LTD", + [3]byte{136, 254, 214}: "ShangHai WangYong Software Co., Ltd.", + [3]byte{140, 0, 109}: "Apple", + [3]byte{140, 4, 255}: "Technicolor USA Inc.", + [3]byte{140, 5, 81}: "Koubachi AG", + [3]byte{140, 7, 140}: "FLOW DATA INC", + [3]byte{140, 8, 139}: "Remote Solution", + [3]byte{140, 9, 244}: "ARRIS Group, Inc.", + [3]byte{140, 12, 144}: "Ruckus Wireless", + [3]byte{140, 12, 163}: "Amper", + [3]byte{140, 14, 227}: "GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD.", + [3]byte{140, 17, 203}: "ABUS Security-Center GmbH & Co. KG", + [3]byte{140, 24, 217}: "Shenzhen RF Technology Co., Ltd", + [3]byte{140, 31, 148}: "RF Surgical System Inc.", + [3]byte{140, 33, 10}: "TP-LINK TECHNOLOGIES CO., LTD.", + [3]byte{140, 39, 29}: "QuantHouse", + [3]byte{140, 39, 138}: "Vocollect Inc", + [3]byte{140, 41, 55}: "Apple", + [3]byte{140, 45, 170}: "Apple", + [3]byte{140, 47, 57}: "IBA Dosimetry GmbH", + [3]byte{140, 51, 48}: "EmFirst Co., Ltd.", + [3]byte{140, 51, 87}: "HiteVision Digital Media Technology Co.,Ltd.", + [3]byte{140, 58, 227}: "LG Electronics", + [3]byte{140, 60, 7}: "Skiva Technologies, Inc.", + [3]byte{140, 60, 74}: "NAKAYO TELECOMMUNICATIONS,INC.", + [3]byte{140, 65, 242}: "RDA Technologies Ltd.", + [3]byte{140, 68, 53}: "Shanghai BroadMobi Communication Technology Co., Ltd.", + [3]byte{140, 74, 238}: "GIGA TMS INC", + [3]byte{140, 75, 89}: "3D Imaging & Simulations Corp", + [3]byte{140, 76, 220}: "PLANEX COMMUNICATIONS INC.", + [3]byte{140, 77, 185}: "Unmonday Ltd", + [3]byte{140, 77, 234}: "Cerio Corporation", + [3]byte{140, 81, 5}: "Shenzhen ireadygo Information Technology CO.,LTD.", + [3]byte{140, 83, 247}: "A&D ENGINEERING CO., LTD.", + [3]byte{140, 84, 29}: "LGE", + [3]byte{140, 86, 157}: "Imaging Solutions Group", + [3]byte{140, 86, 197}: "Nintendo Co., Ltd.", + [3]byte{140, 87, 253}: "LVX Western", + [3]byte{140, 88, 119}: "Apple", + [3]byte{140, 89, 139}: "C Technologies AB", + [3]byte{140, 90, 240}: "Exeltech Solar Products", + [3]byte{140, 92, 161}: "d-broad,INC", + [3]byte{140, 93, 96}: "UCI Corporation Co.,Ltd.", + [3]byte{140, 95, 223}: "Beijing Railway Signal Factory", + [3]byte{140, 96, 79}: "CISCO SYSTEMS, INC.", + [3]byte{140, 100, 11}: "Beyond Devices d.o.o.", + [3]byte{140, 100, 34}: "Sony Ericsson Mobile Communications AB", + [3]byte{140, 104, 120}: "Nortek-AS", + [3]byte{140, 106, 228}: "Viogem Limited", + [3]byte{140, 112, 90}: "Intel Corporate", + [3]byte{140, 113, 248}: "Samsung Electronics Co.,Ltd", + [3]byte{140, 115, 110}: "Fujitsu Limited", + [3]byte{140, 118, 193}: "Goden Tech Limited", + [3]byte{140, 119, 18}: "Samsung Electronics Co.,Ltd", + [3]byte{140, 119, 22}: "LONGCHEER TELECOMMUNICATION LIMITED", + [3]byte{140, 123, 157}: "Apple", + [3]byte{140, 124, 146}: "Apple", + [3]byte{140, 124, 181}: "Hon Hai Precision Ind. Co.,Ltd.", + [3]byte{140, 124, 255}: "Brocade Communications Systems, Inc.", + [3]byte{140, 126, 179}: "Lytro, Inc.", + [3]byte{140, 127, 59}: "ARRIS Group, Inc.", + [3]byte{140, 130, 168}: "Insigma Technology Co.,Ltd", + [3]byte{140, 132, 1}: "PRIVATE", + [3]byte{140, 137, 165}: "Micro-Star INT'L CO., LTD", + [3]byte{140, 138, 110}: "ESTUN AUTOMATION TECHNOLOY CO., LTD", + [3]byte{140, 142, 118}: "taskit GmbH", + [3]byte{140, 144, 211}: "Alcatel Lucent", + [3]byte{140, 145, 9}: "Toyoshima Electric Technoeogy(Suzhou) Co.,Ltd.", + [3]byte{140, 146, 54}: "Aus.Linx Technology Co., Ltd.", + [3]byte{140, 148, 207}: "Encell Technology, Inc.", + [3]byte{140, 160, 72}: "Beijing NeTopChip Technology Co.,LTD", + [3]byte{140, 169, 130}: "Intel Corporate", + [3]byte{140, 174, 76}: "Plugable Technologies", + [3]byte{140, 174, 137}: "Y-cam Solutions Ltd", + [3]byte{140, 176, 148}: "Airtech I&C Co., Ltd", + [3]byte{140, 182, 79}: "CISCO SYSTEMS, INC.", + [3]byte{140, 183, 247}: "Shenzhen UniStrong Science & Technology Co., Ltd", + [3]byte{140, 184, 44}: "IPitomy Communications", + [3]byte{140, 184, 100}: "AcSiP Technology Corp.", + [3]byte{140, 190, 190}: "Xiaomi Technology Co.,Ltd", + [3]byte{140, 191, 157}: "Shanghai Xinyou Information Technology Ltd. Co.", + [3]byte{140, 193, 33}: "Panasonic Corporation AVC Networks Company", + [3]byte{140, 197, 225}: "ShenZhen Konka Telecommunication Technology Co.,Ltd", + [3]byte{140, 199, 170}: "Radinet Communications Inc.", + [3]byte{140, 199, 208}: "zhejiang ebang communication co.,ltd", + [3]byte{140, 200, 205}: "Samsung Electronics Co., LTD", + [3]byte{140, 205, 162}: "ACTP, Inc.", + [3]byte{140, 205, 232}: "Nintendo Co., Ltd.", + [3]byte{140, 207, 92}: "BEFEGA GmbH", + [3]byte{140, 209, 123}: "CG Mobile", + [3]byte{140, 211, 162}: "VisSim AS", + [3]byte{140, 214, 40}: "Ikor Metering", + [3]byte{140, 219, 37}: "ESG Solutions", + [3]byte{140, 220, 212}: "Hewlett Packard", + [3]byte{140, 221, 141}: "Wifly-City System Inc.", + [3]byte{140, 222, 82}: "ISSC Technologies Corp.", + [3]byte{140, 222, 153}: "Comlab Inc.", + [3]byte{140, 223, 157}: "NEC Corporation", + [3]byte{140, 224, 129}: "zte corporation", + [3]byte{140, 231, 72}: "PRIVATE", + [3]byte{140, 231, 140}: "DK Networks", + [3]byte{140, 231, 179}: "Sonardyne International Ltd", + [3]byte{140, 238, 198}: "Precepscion Pty. Ltd.", + [3]byte{140, 248, 19}: "ORANGE POLSKA", + [3]byte{140, 249, 69}: "Power Automation pte Ltd", + [3]byte{140, 249, 201}: "MESADA Technology Co.,Ltd.", + [3]byte{140, 250, 186}: "Apple", + [3]byte{140, 253, 240}: "QUALCOMM Incorporated", + [3]byte{144, 0, 78}: "Hon Hai Precision Ind. Co.,Ltd.", + [3]byte{144, 1, 59}: "SAGEMCOM", + [3]byte{144, 2, 138}: "Shenzhen Shidean Legrand Electronic Products Co.,Ltd", + [3]byte{144, 2, 169}: "ZHEJIANG DAHUA TECHNOLOGY CO.,LTD", + [3]byte{144, 3, 183}: "PARROT", + [3]byte{144, 9, 23}: "Far-sighted mobile", + [3]byte{144, 10, 58}: "PSG Plastic Service GmbH", + [3]byte{144, 12, 180}: "Alinket Electronic Technology Co., Ltd", + [3]byte{144, 13, 102}: "Digimore Electronics Co., Ltd", + [3]byte{144, 13, 203}: "ARRIS Group, Inc.", + [3]byte{144, 23, 155}: "Nanomegas", + [3]byte{144, 23, 172}: "HUAWEI TECHNOLOGIES CO.,LTD", + [3]byte{144, 24, 94}: "Apex Tool Group GmbH & Co OHG", + [3]byte{144, 24, 124}: "Samsung Electro Mechanics co., LTD.", + [3]byte{144, 24, 174}: "Shanghai Meridian Technologies, Co. Ltd.", + [3]byte{144, 25, 0}: "SCS SA", + [3]byte{144, 26, 202}: "ARRIS Group, Inc.", + [3]byte{144, 27, 14}: "Fujitsu Technology Solutions GmbH", + [3]byte{144, 29, 39}: "zte corporation", + [3]byte{144, 30, 221}: "GREAT COMPUTER CORPORATION", + [3]byte{144, 32, 58}: "BYD Precision Manufacture Co.,Ltd", + [3]byte{144, 32, 131}: "General Engine Management Systems Ltd.", + [3]byte{144, 33, 85}: "HTC Corporation", + [3]byte{144, 33, 129}: "Shanghai Huaqin Telecom Technology Co.,Ltd", + [3]byte{144, 39, 228}: "Apple", + [3]byte{144, 43, 52}: "GIGA-BYTE TECHNOLOGY CO.,LTD.", + [3]byte{144, 44, 199}: "C-MAX Asia Limited", + [3]byte{144, 46, 135}: "LabJack", + [3]byte{144, 49, 205}: "Onyx Healthcare Inc.", + [3]byte{144, 52, 43}: "Gatekeeper Systems, Inc.", + [3]byte{144, 52, 252}: "Hon Hai Precision Ind. Co.,Ltd.", + [3]byte{144, 53, 110}: "Vodafone Omnitel N.V.", + [3]byte{144, 56, 223}: "Changzhou Tiannengbo System Co. Ltd.", + [3]byte{144, 58, 160}: "Alcatel-Lucent", + [3]byte{144, 60, 174}: "Yunnan KSEC Digital Technology Co.,Ltd.", + [3]byte{144, 61, 90}: "Shenzhen Wision Technology Holding Limited", + [3]byte{144, 61, 107}: "Zicon Technology Corp.", + [3]byte{144, 62, 171}: "ARRIS Group, Inc.", + [3]byte{144, 70, 183}: "Vadaro Pte Ltd", + [3]byte{144, 71, 22}: "RORZE CORPORATION", + [3]byte{144, 72, 154}: "Hon Hai Precision Ind. Co.,Ltd.", + [3]byte{144, 73, 250}: "Intel Corporation", + [3]byte{144, 76, 229}: "Hon Hai Precision Ind. Co.,Ltd.", + [3]byte{144, 78, 43}: "Huawei Technologies Co., Ltd", + [3]byte{144, 80, 123}: "Advanced PANMOBIL Systems GmbH & Co. KG", + [3]byte{144, 81, 63}: "Elettronica Santerno", + [3]byte{144, 84, 70}: "TES ELECTRONIC SOLUTIONS", + [3]byte{144, 85, 174}: "Ericsson, EAB/RWI/K", + [3]byte{144, 86, 130}: "Lenbrook Industries Limited", + [3]byte{144, 86, 146}: "Autotalks Ltd.", + [3]byte{144, 89, 175}: "Texas Instruments", + [3]byte{144, 95, 46}: "TCT Mobile Limited", + [3]byte{144, 95, 141}: "modas GmbH", + [3]byte{144, 97, 12}: "Fida International (S) Pte Ltd", + [3]byte{144, 103, 23}: "Alphion India Private Limited", + [3]byte{144, 103, 181}: "Alcatel-Lucent", + [3]byte{144, 103, 243}: "Alcatel Lucent", + [3]byte{144, 104, 195}: "Motorola Mobility LLC", + [3]byte{144, 109, 200}: "DLG Automação Industrial Ltda", + [3]byte{144, 110, 187}: "Hon Hai Precision Ind. Co.,Ltd.", + [3]byte{144, 112, 37}: "Garea Microsys Co.,Ltd.", + [3]byte{144, 114, 64}: "Apple", + [3]byte{144, 121, 144}: "Benchmark Electronics Romania SRL", + [3]byte{144, 122, 10}: "Gebr. Bode GmbH & Co KG", + [3]byte{144, 122, 40}: "Beijing Morncloud Information And Technology Co. Ltd.", + [3]byte{144, 122, 241}: "SNUPI Technologies", + [3]byte{144, 126, 186}: "UTEK TECHNOLOGY (SHENZHEN) CO.,LTD", + [3]byte{144, 127, 97}: "Chicony Electronics Co., Ltd.", + [3]byte{144, 130, 96}: "IEEE 1904.1 Working Group", + [3]byte{144, 131, 122}: "General Electric Water & Process Technologies", + [3]byte{144, 132, 13}: "Apple", + [3]byte{144, 136, 162}: "IONICS TECHNOLOGY ME LTDA", + [3]byte{144, 140, 9}: "Total Phase", + [3]byte{144, 140, 68}: "H.K ZONGMU TECHNOLOGY CO., LTD.", + [3]byte{144, 140, 99}: "GZ Weedong Networks Technology Co. , Ltd", + [3]byte{144, 141, 29}: "GH Technologies", + [3]byte{144, 143, 207}: "UNO System Co., Ltd", + [3]byte{144, 144, 60}: "TRISON TECHNOLOGY CORPORATION", + [3]byte{144, 144, 96}: "RSI VIDEO TECHNOLOGIES", + [3]byte{144, 146, 180}: "Diehl BGT Defence GmbH & Co. KG", + [3]byte{144, 148, 228}: "D-Link International", + [3]byte{144, 152, 100}: "Impex-Sat GmbH&Co KG", + [3]byte{144, 153, 22}: "ELVEES NeoTek OJSC", + [3]byte{144, 157, 224}: "Newland Design + Assoc. Inc.", + [3]byte{144, 159, 51}: "EFM Networks", + [3]byte{144, 159, 67}: "Accutron Instruments Inc.", + [3]byte{144, 162, 218}: "GHEO SA", + [3]byte{144, 164, 222}: "Wistron Neweb Corp.", + [3]byte{144, 167, 131}: "JSW PACIFIC CORPORATION", + [3]byte{144, 167, 193}: "Pakedge Device and Software Inc.", + [3]byte{144, 172, 63}: "BrightSign LLC", + [3]byte{144, 174, 27}: "TP-LINK TECHNOLOGIES CO.,LTD.", + [3]byte{144, 177, 28}: "Dell Inc.", + [3]byte{144, 177, 52}: "ARRIS Group, Inc.", + [3]byte{144, 178, 31}: "Apple", + [3]byte{144, 182, 134}: "Murata Manufacturing Co., Ltd.", + [3]byte{144, 184, 208}: "Joyent, Inc.", + [3]byte{144, 185, 49}: "Apple, Inc", + [3]byte{144, 185, 125}: "Johnson Outdoors Marine Electronics d/b/a Minnkota", + [3]byte{144, 193, 21}: "Sony Ericsson Mobile Communications AB", + [3]byte{144, 199, 146}: "ARRIS Group, Inc.", + [3]byte{144, 204, 36}: "Synaptics, Inc", + [3]byte{144, 207, 21}: "Nokia Corporation", + [3]byte{144, 207, 111}: "Dlogixs Co Ltd", + [3]byte{144, 207, 125}: "Qingdao Hisense Electric Co.,Ltd.", + [3]byte{144, 209, 27}: "Palomar Medical Technologies", + [3]byte{144, 215, 79}: "Bookeen", + [3]byte{144, 215, 235}: "Texas Instruments", + [3]byte{144, 216, 82}: "Comtec Co., Ltd.", + [3]byte{144, 217, 44}: "HUG-WITSCHI AG", + [3]byte{144, 218, 78}: "AVANU", + [3]byte{144, 218, 106}: "FOCUS H&S Co., Ltd.", + [3]byte{144, 219, 70}: "E-LEAD ELECTRONIC CO., LTD", + [3]byte{144, 223, 183}: "s.m.s smart microwave sensors GmbH", + [3]byte{144, 224, 240}: "IEEE 1722a Working Group", + [3]byte{144, 226, 186}: "Intel Corporate", + [3]byte{144, 230, 186}: "ASUSTek COMPUTER INC.", + [3]byte{144, 234, 96}: "SPI Lasers Ltd", + [3]byte{144, 239, 104}: "ZyXEL Communications Corporation", + [3]byte{144, 241, 170}: "Samsung Electronics Co.,LTD", + [3]byte{144, 241, 176}: "Hangzhou Anheng Info&Tech CO.,LTD", + [3]byte{144, 242, 120}: "Radius Gateway", + [3]byte{144, 243, 183}: "Kirisun Communications Co., Ltd.", + [3]byte{144, 244, 193}: "Rand McNally", + [3]byte{144, 246, 82}: "TP-LINK TECHNOLOGIES CO., LTD.", + [3]byte{144, 247, 47}: "Phillips Machine & Welding Co., Inc.", + [3]byte{144, 251, 91}: "Avaya, Inc", + [3]byte{144, 251, 166}: "Hon Hai Precision Ind.Co.Ltd", + [3]byte{144, 253, 97}: "Apple", + [3]byte{144, 255, 121}: "Metro Ethernet Forum", + [3]byte{148, 0, 112}: "Nokia Corporation", + [3]byte{148, 1, 73}: "AutoHotBox", + [3]byte{148, 1, 194}: "Samsung Electronics Co.,Ltd", + [3]byte{148, 5, 182}: "Liling FullRiver Electronics & Technology Ltd", + [3]byte{148, 11, 45}: "NetView Technologies(Shenzhen) Co., Ltd", + [3]byte{148, 11, 213}: "Himax Technologies, Inc", + [3]byte{148, 12, 109}: "TP-LINK Technologies Co.,Ltd.", + [3]byte{148, 16, 62}: "Belkin International Inc.", + [3]byte{148, 17, 218}: "ITF Fröschl GmbH", + [3]byte{148, 22, 115}: "Point Core SARL", + [3]byte{148, 29, 28}: "TLab West Systems AB", + [3]byte{148, 32, 83}: "Nokia Corporation", + [3]byte{148, 33, 151}: "Stalmart Technology Limited", + [3]byte{148, 35, 110}: "Shenzhen Junlan Electronic Ltd", + [3]byte{148, 46, 23}: "Schneider Electric Canada Inc", + [3]byte{148, 46, 99}: "Finsécur", + [3]byte{148, 49, 155}: "Alphatronics BV", + [3]byte{148, 51, 221}: "Taco Electronic Solutions, Inc.", + [3]byte{148, 53, 10}: "Samsung Electronics Co.,Ltd", + [3]byte{148, 54, 224}: "Sichuan Bihong Broadcast & Television New Technologies Co.,Ltd", + [3]byte{148, 57, 229}: "Hon Hai Precision Ind. Co.,Ltd.", + [3]byte{148, 58, 240}: "Nokia Corporation", + [3]byte{148, 59, 177}: "KAONMEDIA", + [3]byte{148, 64, 162}: "Anywave Communication Technologies, Inc.", + [3]byte{148, 68, 68}: "LG Innotek", + [3]byte{148, 68, 82}: "Belkin International Inc.", + [3]byte{148, 70, 150}: "BaudTec Corporation", + [3]byte{148, 74, 9}: "BitWise Controls", + [3]byte{148, 80, 71}: "Rechnerbetriebsgruppe", + [3]byte{148, 81, 3}: "Samsung Electronics", + [3]byte{148, 81, 191}: "Hyundai ESG", + [3]byte{148, 84, 147}: "Rigado, LLC", + [3]byte{148, 89, 45}: "EKE Building Technology Systems Ltd", + [3]byte{148, 91, 126}: "TRILOBIT LTDA.", + [3]byte{148, 97, 36}: "Pason Systems", + [3]byte{148, 98, 105}: "Arris Group, Inc.", + [3]byte{148, 99, 209}: "Samsung Electronics Co.,Ltd", + [3]byte{148, 112, 210}: "WINFIRM TECHNOLOGY", + [3]byte{148, 113, 172}: "TCT Mobile Limited", + [3]byte{148, 117, 110}: "QinetiQ North America", + [3]byte{148, 124, 62}: "Polewall Norge AS", + [3]byte{148, 129, 164}: "Azuray Technologies", + [3]byte{148, 133, 122}: "Evantage Industries Corp", + [3]byte{148, 134, 212}: "Surveillance Pro Corporation", + [3]byte{148, 135, 124}: "ARRIS Group, Inc.", + [3]byte{148, 136, 84}: "Texas Instruments", + [3]byte{148, 139, 3}: "EAGET Innovation and Technology Co., Ltd.", + [3]byte{148, 141, 80}: "Beamex Oy Ab", + [3]byte{148, 142, 137}: "INDUSTRIAS UNIDAS SA DE CV", + [3]byte{148, 143, 238}: "Hughes Telematics, Inc.", + [3]byte{148, 148, 38}: "Apple", + [3]byte{148, 152, 162}: "Shanghai LISTEN TECH.LTD", + [3]byte{148, 155, 253}: "Trans New Technology, Inc.", + [3]byte{148, 156, 85}: "Alta Data Technologies", + [3]byte{148, 159, 63}: "Optek Digital Technology company limited", + [3]byte{148, 159, 180}: "ChengDu JiaFaAnTai Technology Co.,Ltd", + [3]byte{148, 167, 188}: "BodyMedia, Inc.", + [3]byte{148, 170, 184}: "Joview(Beijing) Technology Co. Ltd.", + [3]byte{148, 172, 202}: "trivum technologies GmbH", + [3]byte{148, 174, 97}: "Alcatel Lucent", + [3]byte{148, 174, 227}: "Belden Hirschmann Industries (Suzhou) Ltd.", + [3]byte{148, 180, 15}: "Aruba Networks", + [3]byte{148, 184, 197}: "RuggedCom Inc.", + [3]byte{148, 185, 180}: "Aptos Technology", + [3]byte{148, 186, 49}: "Visiontec da Amazônia Ltda.", + [3]byte{148, 186, 86}: "Shenzhen Coship Electronics Co., Ltd.", + [3]byte{148, 191, 30}: "eflow Inc. / Smart Device Planning and Development Division", + [3]byte{148, 191, 149}: "Shenzhen Coship Electronics Co., Ltd", + [3]byte{148, 192, 20}: "Sorter Sp. j. Konrad Grzeszczyk MichaA, Ziomek", + [3]byte{148, 192, 56}: "Tallac Networks", + [3]byte{148, 193, 80}: "2Wire Inc", + [3]byte{148, 195, 228}: "SCA Schucker Gmbh & Co KG", + [3]byte{148, 196, 233}: "PowerLayer Microsystems HongKong Limited", + [3]byte{148, 198, 235}: "NOVA electronics, Inc.", + [3]byte{148, 199, 175}: "Raylios Technology", + [3]byte{148, 201, 98}: "Teseq AG", + [3]byte{148, 202, 15}: "Honeywell Analytics", + [3]byte{148, 204, 185}: "ARRIS Group, Inc.", + [3]byte{148, 205, 172}: "Creowave Oy", + [3]byte{148, 206, 44}: "Sony Mobile Communications AB", + [3]byte{148, 206, 49}: "CTS Limited", + [3]byte{148, 208, 25}: "Cydle Corp.", + [3]byte{148, 214, 14}: "shenzhen yunmao information technologies co., ltd", + [3]byte{148, 215, 35}: "Shanghai DareGlobal Technologies Co., Ltd", + [3]byte{148, 215, 113}: "Samsung Electronics Co.,Ltd", + [3]byte{148, 217, 60}: "ENELPS", + [3]byte{148, 219, 73}: "SITCORP", + [3]byte{148, 219, 201}: "Azurewave", + [3]byte{148, 221, 63}: "A+V Link Technologies, Corp.", + [3]byte{148, 222, 14}: "SmartOptics AS", + [3]byte{148, 222, 128}: "GIGA-BYTE TECHNOLOGY CO.,LTD.", + [3]byte{148, 223, 78}: "Wistron InfoComm(Kunshan)Co.,Ltd.", + [3]byte{148, 223, 88}: "IJ Electron CO.,Ltd.", + [3]byte{148, 224, 208}: "HealthStream Taiwan Inc.", + [3]byte{148, 226, 38}: "D. ORtiz Consulting, LLC", + [3]byte{148, 231, 17}: "Xirka Dama Persada PT", + [3]byte{148, 232, 72}: "FYLDE MICRO LTD", + [3]byte{148, 233, 140}: "Alcatel-Lucent", + [3]byte{148, 235, 44}: "Google Inc.", + [3]byte{148, 235, 205}: "Research In Motion Limited", + [3]byte{148, 246, 146}: "Geminico co.,Ltd.", + [3]byte{148, 247, 32}: "Tianjin Deviser Electronics Instrument Co., Ltd", + [3]byte{148, 250, 232}: "Shenzhen Eycom Technology Co., Ltd", + [3]byte{148, 251, 178}: "Shenzhen Gongjin Electronics Co.,Ltd", + [3]byte{148, 253, 29}: "WhereWhen Corp", + [3]byte{148, 253, 46}: "Shanghai Uniscope Technologies Co.,Ltd", + [3]byte{148, 254, 244}: "SAGEMCOM", + [3]byte{152, 2, 132}: "Theobroma Systems GmbH", + [3]byte{152, 3, 160}: "ABB n.v. Power Quality Products", + [3]byte{152, 3, 216}: "Apple", + [3]byte{152, 12, 130}: "Samsung Electro Mechanics", + [3]byte{152, 13, 46}: "HTC Corporation", + [3]byte{152, 14, 228}: "PRIVATE", + [3]byte{152, 16, 148}: "Shenzhen Vsun communication technology Co.,ltd", + [3]byte{152, 22, 236}: "IC Intracom", + [3]byte{152, 32, 142}: "Definium Technologies", + [3]byte{152, 38, 42}: "Applied Research Associates, Inc", + [3]byte{152, 41, 29}: "Jaguar de Mexico, SA de CV", + [3]byte{152, 41, 63}: "Fujian Start Computer Equipment Co.,Ltd", + [3]byte{152, 44, 190}: "2Wire", + [3]byte{152, 45, 86}: "Resolution Audio", + [3]byte{152, 47, 60}: "Sichuan Changhong Electric Ltd.", + [3]byte{152, 48, 0}: "Beijing KEMACOM Technologies Co., Ltd.", + [3]byte{152, 48, 113}: "DAIKYUNG VASCOM", + [3]byte{152, 52, 157}: "Krauss Maffei Technologies GmbH", + [3]byte{152, 53, 113}: "Sub10 Systems Ltd", + [3]byte{152, 53, 184}: "Assembled Products Corporation", + [3]byte{152, 55, 19}: "PT.Navicom Indonesia", + [3]byte{152, 59, 22}: "AMPAK Technology Inc", + [3]byte{152, 63, 159}: "China SSJ (Suzhou) Network Technology Inc.", + [3]byte{152, 66, 70}: "SOL INDUSTRY PTE., LTD", + [3]byte{152, 67, 218}: "INTERTECH", + [3]byte{152, 71, 60}: "SHANGHAI SUNMON COMMUNICATION TECHNOGY CO.,LTD", + [3]byte{152, 74, 71}: "CHG Hospital Beds", + [3]byte{152, 75, 74}: "ARRIS Group, Inc.", + [3]byte{152, 75, 225}: "Hewlett-Packard Company", + [3]byte{152, 76, 4}: "Zhangzhou Keneng Electrical Equipment Co Ltd", + [3]byte{152, 76, 211}: "Mantis Deposition", + [3]byte{152, 78, 151}: "Starlight Marketing (H. K.) Ltd.", + [3]byte{152, 79, 238}: "Intel Corporate", + [3]byte{152, 82, 177}: "Samsung Electronics", + [3]byte{152, 87, 211}: "HON HAI-CCPBG PRECISION IND.CO.,LTD.", + [3]byte{152, 88, 138}: "SYSGRATION Ltd.", + [3]byte{152, 89, 69}: "Texas Instruments", + [3]byte{152, 92, 147}: "SBG Systems SAS", + [3]byte{152, 93, 70}: "PeopleNet Communication", + [3]byte{152, 94, 27}: "ConversDigital Co., Ltd.", + [3]byte{152, 96, 34}: "EMW Co., Ltd.", + [3]byte{152, 102, 234}: "Industrial Control Communications, Inc.", + [3]byte{152, 107, 61}: "ARRIS Group, Inc.", + [3]byte{152, 108, 245}: "zte corporation", + [3]byte{152, 109, 200}: "TOSHIBA MITSUBISHI-ELECTRIC INDUSTRIAL SYSTEMS CORPORATION", + [3]byte{152, 115, 196}: "Sage Electronic Engineering LLC", + [3]byte{152, 118, 182}: "Adafruit", + [3]byte{152, 119, 112}: "Pep Digital Technology (Guangzhou) Co., Ltd", + [3]byte{152, 126, 70}: "Emizon Networks Limited", + [3]byte{152, 130, 23}: "Disruptive Ltd", + [3]byte{152, 134, 177}: "Flyaudio corporation (China)", + [3]byte{152, 137, 237}: "Anadem Information Inc.", + [3]byte{152, 139, 93}: "SAGEM COMMUNICATION", + [3]byte{152, 139, 173}: "Corintech Ltd.", + [3]byte{152, 142, 52}: "ZHEJIANG BOXSAM ELECTRONIC CO.,LTD", + [3]byte{152, 142, 74}: "NOXUS(BEIJING) TECHNOLOGY CO.,LTD", + [3]byte{152, 142, 221}: "TE Connectivity Limerick", + [3]byte{152, 144, 128}: "Linkpower Network System Inc Ltd.", + [3]byte{152, 144, 150}: "Dell Inc", + [3]byte{152, 147, 204}: "LG Electronics Inc.", + [3]byte{152, 148, 73}: "Skyworth Wireless Technology Ltd.", + [3]byte{152, 167, 176}: "MCST ZAO", + [3]byte{152, 170, 215}: "BLUE WAVE NETWORKING CO LTD", + [3]byte{152, 176, 57}: "Alcatel-Lucent", + [3]byte{152, 184, 227}: "Apple", + [3]byte{152, 188, 87}: "SVA TECHNOLOGIES CO.LTD", + [3]byte{152, 188, 153}: "Edeltech Co.,Ltd.", + [3]byte{152, 190, 148}: "IBM", + [3]byte{152, 192, 235}: "Global Regency Ltd", + [3]byte{152, 200, 69}: "PacketAccess", + [3]byte{152, 205, 180}: "Virident Systems, Inc.", + [3]byte{152, 211, 49}: "Shenzhen Bolutek Technology Co.,Ltd.", + [3]byte{152, 214, 134}: "Chyi Lee industry Co., ltd.", + [3]byte{152, 214, 187}: "Apple", + [3]byte{152, 214, 247}: "LG Electronics", + [3]byte{152, 216, 140}: "Nortel Networks", + [3]byte{152, 218, 146}: "Vuzix Corporation", + [3]byte{152, 220, 217}: "UNITEC Co., Ltd.", + [3]byte{152, 225, 101}: "Accutome", + [3]byte{152, 231, 154}: "Foxconn(NanJing) Communication Co.,Ltd.", + [3]byte{152, 236, 101}: "Cosesy ApS", + [3]byte{152, 240, 171}: "Apple", + [3]byte{152, 241, 112}: "Murata Manufacturing Co., Ltd.", + [3]byte{152, 245, 55}: "zte corporation", + [3]byte{152, 248, 193}: "IDT Technology Limited", + [3]byte{152, 248, 219}: "Marini Impianti Industriali s.r.l.", + [3]byte{152, 250, 227}: "Xiaomi inc.", + [3]byte{152, 251, 18}: "Grand Electronics (HK) Ltd", + [3]byte{152, 252, 17}: "Cisco-Linksys, LLC", + [3]byte{152, 254, 3}: "Ericsson - North America", + [3]byte{152, 254, 148}: "Apple", + [3]byte{152, 255, 106}: "OTEC(Shanghai)Technology Co.,Ltd.", + [3]byte{152, 255, 208}: "Lenovo Mobile Communication Technology Ltd.", + [3]byte{156, 1, 17}: "Shenzhen Newabel Electronic Co., Ltd.", + [3]byte{156, 2, 152}: "Samsung Electronics Co.,Ltd", + [3]byte{156, 3, 158}: "Beijing Winchannel Software Technology Co., Ltd", + [3]byte{156, 4, 115}: "Tecmobile (International) Ltd.", + [3]byte{156, 4, 235}: "Apple", + [3]byte{156, 6, 110}: "Hytera Communications Corporation Limited", + [3]byte{156, 13, 172}: "Tymphany HK Limited", + [3]byte{156, 20, 101}: "Edata Elektronik San. ve Tic. A.Ş.", + [3]byte{156, 24, 116}: "Nokia Danmark A/S", + [3]byte{156, 28, 18}: "Aruba Networks", + [3]byte{156, 31, 221}: "Accupix Inc.", + [3]byte{156, 32, 123}: "Apple", + [3]byte{156, 33, 106}: "TP-LINK TECHNOLOGIES CO.,LTD.", + [3]byte{156, 34, 14}: "TASCAN Service GmbH", + [3]byte{156, 40, 64}: "Discovery Technology,LTD..", + [3]byte{156, 40, 191}: "Continental Automotive Czech Republic s.r.o.", + [3]byte{156, 40, 239}: "HUAWEI TECHNOLOGIES CO.,LTD", + [3]byte{156, 42, 112}: "Hon Hai Precision Ind. Co.,Ltd.", + [3]byte{156, 49, 120}: "Foshan Huadian Intelligent Communications Teachnologies Co.,Ltd", + [3]byte{156, 49, 182}: "Kulite Semiconductor Products Inc", + [3]byte{156, 53, 131}: "Nipro Diagnostics, Inc", + [3]byte{156, 58, 175}: "Samsung Electronics Co.,Ltd", + [3]byte{156, 62, 170}: "EnvyLogic Co.,Ltd.", + [3]byte{156, 65, 124}: "Hame Technology Co., Limited", + [3]byte{156, 68, 61}: "CHENGDU XUGUANG TECHNOLOGY CO, LTD", + [3]byte{156, 68, 166}: "SwiftTest, Inc.", + [3]byte{156, 69, 99}: "DIMEP Sistemas", + [3]byte{156, 74, 123}: "Nokia Corporation", + [3]byte{156, 76, 174}: "Mesa Labs", + [3]byte{156, 78, 32}: "CISCO SYSTEMS, INC.", + [3]byte{156, 78, 54}: "Intel Corporate", + [3]byte{156, 78, 142}: "ALT Systems Ltd", + [3]byte{156, 78, 191}: "BoxCast", + [3]byte{156, 83, 205}: "ENGICAM s.r.l.", + [3]byte{156, 84, 28}: "Shenzhen My-power Technology Co.,Ltd", + [3]byte{156, 84, 202}: "Zhengzhou VCOM Science and Technology Co.,Ltd", + [3]byte{156, 85, 180}: "I.S.E. S.r.l.", + [3]byte{156, 87, 17}: "Feitian Xunda(Beijing) Aeronautical Information Technology Co., Ltd.", + [3]byte{156, 91, 150}: "NMR Corporation", + [3]byte{156, 92, 141}: "FIREMAX INDÚSTRIA E COMÉRCIO DE PRODUTOS ELETRÔNICOS LTDA", + [3]byte{156, 93, 18}: "Aerohive Networks Inc", + [3]byte{156, 93, 149}: "VTC Electronics Corp.", + [3]byte{156, 94, 115}: "Calibre UK Ltd", + [3]byte{156, 97, 29}: "Omni-ID USA, Inc.", + [3]byte{156, 100, 94}: "Harman Consumer Group", + [3]byte{156, 101, 176}: "Samsung Electronics Co.,Ltd", + [3]byte{156, 101, 249}: "AcSiP Technology Corp.", + [3]byte{156, 102, 80}: "Glodio Technolies Co.,Ltd Tianjin Branch", + [3]byte{156, 106, 190}: "QEES ApS.", + [3]byte{156, 117, 20}: "Wildix srl", + [3]byte{156, 119, 170}: "NADASNV", + [3]byte{156, 121, 172}: "Suntec Software(Shanghai) Co., Ltd.", + [3]byte{156, 123, 210}: "NEOLAB Convergence", + [3]byte{156, 128, 125}: "SYSCABLE Korea Inc.", + [3]byte{156, 128, 223}: "Arcadyan Technology Corporation", + [3]byte{156, 134, 218}: "Phoenix Geophysics Ltd.", + [3]byte{156, 136, 136}: "Simac Techniek NV", + [3]byte{156, 139, 241}: "The Warehouse Limited", + [3]byte{156, 141, 26}: "INTEG process group inc", + [3]byte{156, 142, 153}: "Hewlett-Packard Company", + [3]byte{156, 142, 220}: "Teracom Limited", + [3]byte{156, 147, 78}: "Xerox Corporation", + [3]byte{156, 147, 228}: "PRIVATE", + [3]byte{156, 149, 248}: "SmartDoor Systems, LLC", + [3]byte{156, 151, 38}: "Technicolor", + [3]byte{156, 152, 17}: "Guangzhou Sunrise Electronics Development Co., Ltd", + [3]byte{156, 156, 29}: "Starkey Labs Inc.", + [3]byte{156, 161, 10}: "SCLE SFE", + [3]byte{156, 161, 52}: "Nike, Inc.", + [3]byte{156, 163, 186}: "SAKURA Internet Inc.", + [3]byte{156, 165, 119}: "Osorno Enterprises Inc.", + [3]byte{156, 169, 228}: "zte corporation", + [3]byte{156, 173, 151}: "Hon Hai Precision Ind. Co.,Ltd.", + [3]byte{156, 173, 239}: "Obihai Technology, Inc.", + [3]byte{156, 175, 202}: "CISCO SYSTEMS, INC.", + [3]byte{156, 176, 8}: "Ubiquitous Computing Technology Corporation", + [3]byte{156, 178, 6}: "PROCENTEC", + [3]byte{156, 182, 84}: "Hewlett Packard", + [3]byte{156, 183, 13}: "Liteon Technology Corporation", + [3]byte{156, 183, 147}: "Creatcomm Technology Inc.", + [3]byte{156, 187, 152}: "Shen Zhen RND Electronic Co.,LTD", + [3]byte{156, 189, 157}: "SkyDisk, Inc.", + [3]byte{156, 192, 119}: "PrintCounts, LLC", + [3]byte{156, 192, 210}: "Conductix-Wampfler AG", + [3]byte{156, 193, 114}: "Huawei Technologies Co., Ltd", + [3]byte{156, 199, 166}: "AVM GmbH", + [3]byte{156, 199, 209}: "SHARP Corporation", + [3]byte{156, 202, 217}: "Nokia Corporation", + [3]byte{156, 205, 130}: "CHENG UEI PRECISION INDUSTRY CO.,LTD", + [3]byte{156, 210, 30}: "Hon Hai Precision Ind. Co.,Ltd.", + [3]byte{156, 210, 75}: "zte corporation", + [3]byte{156, 211, 109}: "NETGEAR INC.,", + [3]byte{156, 214, 67}: "D-Link International", + [3]byte{156, 217, 23}: "Motorola Mobility LLC", + [3]byte{156, 223, 3}: "Harman/Becker Automotive Systems GmbH", + [3]byte{156, 225, 14}: "NCTech Ltd", + [3]byte{156, 225, 214}: "Junger Audio-Studiotechnik GmbH", + [3]byte{156, 230, 53}: "Nintendo Co., Ltd.", + [3]byte{156, 230, 231}: "Samsung Electronics Co.,Ltd", + [3]byte{156, 231, 189}: "Winduskorea co., Ltd", + [3]byte{156, 235, 232}: "BizLink (Kunshan) Co.,Ltd", + [3]byte{156, 246, 26}: "UTC Fire and Security", + [3]byte{156, 246, 125}: "Ricardo Prague, s.r.o.", + [3]byte{156, 248, 219}: "shenzhen eyunmei technology co,.ltd", + [3]byte{156, 249, 56}: "AREVA NP GmbH", + [3]byte{156, 251, 241}: "MESOMATIC GmbH & Co.KG", + [3]byte{156, 255, 190}: "OTSL Inc.", + [3]byte{160, 2, 220}: "Amazon Technologies Inc.", + [3]byte{160, 3, 99}: "Robert Bosch Healthcare GmbH", + [3]byte{160, 6, 39}: "NEXPA System", + [3]byte{160, 7, 152}: "Samsung Electronics", + [3]byte{160, 7, 182}: "Advanced Technical Support, Inc.", + [3]byte{160, 10, 191}: "Wieson Technologies Co., Ltd.", + [3]byte{160, 11, 186}: "SAMSUNG ELECTRO-MECHANICS", + [3]byte{160, 12, 161}: "SKTB SKiT", + [3]byte{160, 18, 144}: "Avaya, Inc", + [3]byte{160, 18, 219}: "TABUCHI ELECTRIC CO.,LTD", + [3]byte{160, 19, 59}: "Copyright © HiTi Digital, Inc.", + [3]byte{160, 20, 61}: "PARROT SA", + [3]byte{160, 22, 92}: "Triteka LTD", + [3]byte{160, 24, 89}: "Shenzhen Yidashi Electronics Co Ltd", + [3]byte{160, 25, 23}: "Bertel S.p.a.", + [3]byte{160, 28, 5}: "NIMAX TELECOM CO.,LTD.", + [3]byte{160, 29, 72}: "Hewlett Packard", + [3]byte{160, 33, 149}: "Samsung Electronics Digital Imaging", + [3]byte{160, 33, 183}: "NETGEAR", + [3]byte{160, 35, 27}: "TeleComp R&D Corp.", + [3]byte{160, 43, 184}: "Hewlett Packard", + [3]byte{160, 46, 243}: "United Integrated Services Co., Led.", + [3]byte{160, 54, 159}: "Intel Corporate", + [3]byte{160, 54, 240}: "Comprehensive Power", + [3]byte{160, 54, 250}: "Ettus Research LLC", + [3]byte{160, 58, 117}: "PSS Belgium N.V.", + [3]byte{160, 59, 27}: "Inspire Tech", + [3]byte{160, 64, 37}: "Actioncable, Inc.", + [3]byte{160, 64, 65}: "SAMWONFA Co.,Ltd.", + [3]byte{160, 65, 167}: "NL Ministry of Defense", + [3]byte{160, 66, 63}: "Tyan Computer Corp", + [3]byte{160, 72, 28}: "Hewlett Packard", + [3]byte{160, 76, 193}: "Helixtech Corp.", + [3]byte{160, 78, 4}: "Nokia Corporation", + [3]byte{160, 81, 198}: "Avaya, Inc", + [3]byte{160, 85, 222}: "Pace plc", + [3]byte{160, 86, 178}: "Harman/Becker Automotive Systems GmbH", + [3]byte{160, 89, 58}: "V.D.S. Video Display Systems srl", + [3]byte{160, 90, 164}: "Grand Products Nevada, Inc.", + [3]byte{160, 91, 33}: "ENVINET GmbH", + [3]byte{160, 93, 193}: "TMCT Co., LTD.", + [3]byte{160, 93, 231}: "DIRECTV, Inc.", + [3]byte{160, 94, 107}: "MELPER Co., Ltd.", + [3]byte{160, 101, 24}: "VNPT TECHNOLOGY", + [3]byte{160, 103, 190}: "Sicon s.r.l.", + [3]byte{160, 105, 134}: "Wellav Technologies Ltd", + [3]byte{160, 106, 0}: "Verilink Corporation", + [3]byte{160, 108, 236}: "RIM", + [3]byte{160, 109, 9}: "Intelcan Technosystems Inc.", + [3]byte{160, 110, 80}: "Nanotek Elektronik Sistemler Ltd. Sti.", + [3]byte{160, 113, 169}: "Nokia Corporation", + [3]byte{160, 115, 50}: "Cashmaster International Limited", + [3]byte{160, 115, 252}: "Rancore Technologies Private Limited", + [3]byte{160, 117, 145}: "Samsung Electronics Co.,Ltd", + [3]byte{160, 119, 113}: "Vialis BV", + [3]byte{160, 120, 186}: "Pantech Co., Ltd.", + [3]byte{160, 130, 31}: "Samsung Electronics Co.,Ltd", + [3]byte{160, 130, 199}: "P.T.I Co.,LTD", + [3]byte{160, 134, 29}: "Chengdu Fuhuaxin Technology co.,Ltd", + [3]byte{160, 134, 236}: "SAEHAN HITEC Co., Ltd", + [3]byte{160, 136, 105}: "Intel Corporate", + [3]byte{160, 136, 180}: "Intel Corporate", + [3]byte{160, 137, 228}: "Skyworth Digital Technology(Shenzhen) Co.,Ltd", + [3]byte{160, 138, 135}: "HuiZhou KaiYue Electronic Co.,Ltd", + [3]byte{160, 140, 21}: "Gerhard D. Wempe KG", + [3]byte{160, 140, 155}: "Xtreme Technologies Corp", + [3]byte{160, 144, 222}: "VEEDIMS,LLC", + [3]byte{160, 147, 71}: "GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD.", + [3]byte{160, 152, 5}: "OpenVox Communication Co Ltd", + [3]byte{160, 152, 237}: "Shandong Intelligent Optical Communication Development Co., Ltd.", + [3]byte{160, 154, 90}: "Time Domain", + [3]byte{160, 155, 189}: "Total Aviation Solutions Pty Ltd", + [3]byte{160, 161, 48}: "DLI Taiwan Branch office", + [3]byte{160, 162, 60}: "GPMS", + [3]byte{160, 163, 226}: "Actiontec Electronics, Inc", + [3]byte{160, 167, 99}: "Polytron Vertrieb GmbH", + [3]byte{160, 168, 205}: "Intel Corporate", + [3]byte{160, 170, 253}: "EraThink Technologies Corp.", + [3]byte{160, 177, 0}: "ShenZhen Cando Electronics Co.,Ltd", + [3]byte{160, 179, 204}: "Hewlett Packard", + [3]byte{160, 180, 165}: "Samsung Elec Co.,Ltd", + [3]byte{160, 181, 218}: "HongKong THTF Co., Ltd", + [3]byte{160, 182, 98}: "Acutvista Innovation Co., Ltd.", + [3]byte{160, 185, 237}: "Skytap", + [3]byte{160, 186, 184}: "Pixon Imaging", + [3]byte{160, 191, 80}: "S.C. ADD-PRODUCTION S.R.L.", + [3]byte{160, 191, 165}: "CORESYS", + [3]byte{160, 195, 222}: "Triton Electronic Systems Ltd.", + [3]byte{160, 198, 236}: "ShenZhen ANYK Technology Co.,LTD", + [3]byte{160, 206, 200}: "CE LINK LIMITED", + [3]byte{160, 207, 91}: "CISCO SYSTEMS, INC.", + [3]byte{160, 209, 42}: "AXPRO Technology Inc.", + [3]byte{160, 211, 193}: "Hewlett Packard", + [3]byte{160, 218, 146}: "Nanjing Glarun Atten Technology Co. Ltd.", + [3]byte{160, 220, 4}: "Becker-Antriebe GmbH", + [3]byte{160, 221, 151}: "PolarLink Technologies, Ltd", + [3]byte{160, 221, 229}: "SHARP Corporation", + [3]byte{160, 222, 5}: "JSC \"Irbis-T\"", + [3]byte{160, 226, 1}: "AVTrace Ltd.(China)", + [3]byte{160, 226, 90}: "Amicus SK, s.r.o.", + [3]byte{160, 226, 149}: "DAT System Co.,Ltd", + [3]byte{160, 228, 83}: "Sony Mobile Communications AB", + [3]byte{160, 229, 52}: "Stratec Biomedical AG", + [3]byte{160, 229, 233}: "enimai Inc", + [3]byte{160, 230, 248}: "Texas Instruments Inc", + [3]byte{160, 233, 219}: "Ningbo FreeWings Technologies Co.,Ltd", + [3]byte{160, 235, 118}: "AirCUVE Inc.", + [3]byte{160, 236, 128}: "zte corporation", + [3]byte{160, 237, 205}: "Apple", + [3]byte{160, 239, 132}: "Seine Image Int'l Co., Ltd", + [3]byte{160, 242, 23}: "GE Medical System(China) Co., Ltd.", + [3]byte{160, 243, 193}: "TP-LINK TECHNOLOGIES CO., LTD.", + [3]byte{160, 243, 228}: "Alcatel Lucent IPD", + [3]byte{160, 244, 25}: "Nokia Corporation", + [3]byte{160, 244, 80}: "HTC Corporation", + [3]byte{160, 244, 89}: "FN-LINK TECHNOLOGY LIMITED", + [3]byte{160, 252, 110}: "Telegrafia a.s.", + [3]byte{160, 254, 145}: "AVAT Automation GmbH", + [3]byte{164, 1, 48}: "ABIsystems Co., LTD", + [3]byte{164, 5, 158}: "STA Infinity LLP", + [3]byte{164, 9, 203}: "Alfred Kaercher GmbH & Co KG", + [3]byte{164, 11, 237}: "Carry Technology Co.,Ltd", + [3]byte{164, 12, 195}: "CISCO SYSTEMS, INC.", + [3]byte{164, 18, 66}: "NEC Platforms, Ltd.", + [3]byte{164, 19, 78}: "Luxul", + [3]byte{164, 21, 102}: "Wei Fang Goertek Electronics Co.,Ltd", + [3]byte{164, 23, 49}: "Hon Hai Precision Ind. Co.,Ltd.", + [3]byte{164, 24, 117}: "CISCO SYSTEMS, INC.", + [3]byte{164, 27, 192}: "Fastec Imaging Corporation", + [3]byte{164, 31, 114}: "Dell Inc.", + [3]byte{164, 33, 138}: "Nortel Networks", + [3]byte{164, 35, 5}: "Open Networking Laboratory", + [3]byte{164, 36, 179}: "FlatFrog Laboratories AB", + [3]byte{164, 37, 27}: "Avaya, Inc", + [3]byte{164, 41, 64}: "Shenzhen YOUHUA Technology Co., Ltd", + [3]byte{164, 41, 183}: "bluesky", + [3]byte{164, 44, 8}: "Masterwork Automodules", + [3]byte{164, 51, 209}: "Fibrlink Communications Co.,Ltd.", + [3]byte{164, 56, 252}: "Plastic Logic", + [3]byte{164, 58, 105}: "Vers Inc", + [3]byte{164, 59, 250}: "IEEE REGISTRATION AUTHORITY - Please see MAM public listing for more information.", + [3]byte{164, 61, 120}: "GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD", + [3]byte{164, 70, 107}: "EOC Technology", + [3]byte{164, 70, 250}: "AmTRAN Video Corporation", + [3]byte{164, 74, 211}: "ST Electronics(Shanghai) Co.,Ltd", + [3]byte{164, 75, 21}: "Sun Cupid Technology (HK) LTD", + [3]byte{164, 76, 17}: "CISCO SYSTEMS, INC.", + [3]byte{164, 78, 45}: "Adaptive Wireless Solutions, LLC", + [3]byte{164, 78, 49}: "Intel Corporate", + [3]byte{164, 80, 85}: "busware.de", + [3]byte{164, 82, 111}: "ADB Broadband Italia", + [3]byte{164, 86, 27}: "MCOT Corporation", + [3]byte{164, 86, 48}: "CISCO SYSTEMS, INC.", + [3]byte{164, 90, 28}: "smart-electronic GmbH", + [3]byte{164, 92, 39}: "Nintendo Co., Ltd.", + [3]byte{164, 93, 54}: "Hewlett Packard", + [3]byte{164, 93, 161}: "ADB Broadband Italia", + [3]byte{164, 96, 50}: "MRV Communications (Networks) LTD", + [3]byte{164, 103, 6}: "Apple", + [3]byte{164, 108, 193}: "LTi REEnergy GmbH", + [3]byte{164, 110, 121}: "DFT System Co.Ltd", + [3]byte{164, 112, 214}: "Motorola Mobility LLC", + [3]byte{164, 119, 51}: "Google", + [3]byte{164, 119, 96}: "Nokia Corporation", + [3]byte{164, 121, 228}: "KLINFO Corp", + [3]byte{164, 122, 164}: "ARRIS Group, Inc.", + [3]byte{164, 122, 207}: "VIBICOM COMMUNICATIONS INC.", + [3]byte{164, 124, 20}: "ChargeStorm AB", + [3]byte{164, 124, 31}: "Cobham plc", + [3]byte{164, 126, 57}: "zte corporation", + [3]byte{164, 129, 238}: "Nokia Corporation", + [3]byte{164, 133, 107}: "Q Electronics Ltd", + [3]byte{164, 137, 91}: "ARK INFOSOLUTIONS PVT LTD", + [3]byte{164, 144, 5}: "CHINA GREATWALL COMPUTER SHENZHEN CO.,LTD", + [3]byte{164, 147, 76}: "CISCO SYSTEMS, INC.", + [3]byte{164, 151, 187}: "Hitachi Industrial Equipment Systems Co.,Ltd", + [3]byte{164, 153, 71}: "Huawei Technologies Co., Ltd", + [3]byte{164, 153, 129}: "FuJian Elite Power Tech CO.,LTD.", + [3]byte{164, 154, 88}: "Samsung Electronics Co.,Ltd", + [3]byte{164, 155, 19}: "Burroughs Payment Systems, Inc.", + [3]byte{164, 157, 73}: "Ketra, Inc.", + [3]byte{164, 158, 219}: "AutoCrib, Inc.", + [3]byte{164, 159, 133}: "Lyve Minds, Inc", + [3]byte{164, 159, 137}: "Shanghai Rui Rui Communication Technology Co.Ltd.", + [3]byte{164, 161, 194}: "Ericsson AB (EAB)", + [3]byte{164, 162, 74}: "Cisco SPVTG", + [3]byte{164, 164, 211}: "Bluebank Communication Technology Co.Ltd", + [3]byte{164, 168, 15}: "Shenzhen Coship Electronics Co., Ltd.", + [3]byte{164, 173, 0}: "Ragsdale Technology", + [3]byte{164, 173, 184}: "Vitec Group, Camera Dynamics Ltd", + [3]byte{164, 174, 154}: "Maestro Wireless Solutions ltd.", + [3]byte{164, 177, 33}: "Arantia 2010 S.L.", + [3]byte{164, 177, 151}: "Apple", + [3]byte{164, 177, 233}: "Technicolor", + [3]byte{164, 177, 238}: "H. ZANDER GmbH & Co. KG", + [3]byte{164, 178, 167}: "Adaxys Solutions AG", + [3]byte{164, 179, 106}: "JSC SDO Chromatec", + [3]byte{164, 184, 24}: "PENTA Gesellschaft für elektronische Industriedatenverarbeitung mbH", + [3]byte{164, 185, 128}: "Parking BOXX Inc.", + [3]byte{164, 186, 219}: "Dell Inc.", + [3]byte{164, 187, 175}: "Lime Instruments", + [3]byte{164, 190, 97}: "EutroVision System, Inc.", + [3]byte{164, 192, 199}: "ShenZhen Hitom Communication Technology Co..LTD", + [3]byte{164, 192, 225}: "Nintendo Co., Ltd.", + [3]byte{164, 194, 171}: "Hangzhou LEAD-IT Information & Technology Co.,Ltd", + [3]byte{164, 195, 97}: "Apple", + [3]byte{164, 199, 222}: "Cambridge Industries(Group) Co.,Ltd.", + [3]byte{164, 208, 148}: "Erwin Peters Systemtechnik GmbH", + [3]byte{164, 209, 143}: "Shenzhen Skyee Optical Fiber Communication Technology Ltd.", + [3]byte{164, 209, 209}: "ECOtality North America", + [3]byte{164, 209, 210}: "Apple", + [3]byte{164, 211, 181}: "GLITEL Stropkov, s.r.o.", + [3]byte{164, 216, 86}: "Gimbal, Inc", + [3]byte{164, 218, 63}: "Bionics Corp.", + [3]byte{164, 219, 46}: "Kingspan Environmental Ltd", + [3]byte{164, 219, 48}: "Liteon Technology Corporation", + [3]byte{164, 222, 80}: "Total Walther GmbH", + [3]byte{164, 224, 230}: "FILIZOLA S.A. PESAGEM E AUTOMACAO", + [3]byte{164, 227, 46}: "Silicon & Software Systems Ltd.", + [3]byte{164, 227, 145}: "DENY FONTAINE", + [3]byte{164, 228, 184}: "BlackBerry Limited", + [3]byte{164, 231, 49}: "Nokia Corporation", + [3]byte{164, 231, 228}: "Connex GmbH", + [3]byte{164, 233, 145}: "SISTEMAS AUDIOVISUALES ITELSIS S.L.", + [3]byte{164, 233, 163}: "Honest Technology Co., Ltd", + [3]byte{164, 235, 211}: "Samsung Electronics Co.,Ltd", + [3]byte{164, 237, 78}: "ARRIS Group, Inc.", + [3]byte{164, 238, 87}: "SEIKO EPSON CORPORATION", + [3]byte{164, 239, 82}: "Telewave Co., Ltd.", + [3]byte{164, 243, 193}: "Open Source Robotics Foundation, Inc.", + [3]byte{164, 245, 34}: "CHOFU SEISAKUSHO CO.,LTD", + [3]byte{164, 247, 208}: "LAN Accessories Co., Ltd.", + [3]byte{164, 251, 141}: "Hangzhou Dunchong Technology Co.Ltd", + [3]byte{164, 252, 206}: "Security Expert Ltd.", + [3]byte{168, 1, 128}: "IMAGO Technologies GmbH", + [3]byte{168, 6, 0}: "Samsung Electronics Co.,Ltd", + [3]byte{168, 12, 13}: "Cisco", + [3]byte{168, 19, 116}: "Panasonic Corporation AVC Networks Company", + [3]byte{168, 21, 77}: "TP-LINK TECHNOLOGIES CO.,LTD.", + [3]byte{168, 22, 178}: "LG Electronics", + [3]byte{168, 23, 88}: "Elektronik System i Umeå AB", + [3]byte{168, 27, 24}: "XTS CORP", + [3]byte{168, 27, 93}: "Foxtel Management Pty Ltd", + [3]byte{168, 29, 22}: "AzureWave Technologies, Inc", + [3]byte{168, 31, 175}: "KRYPTON POLSKA", + [3]byte{168, 32, 102}: "Apple", + [3]byte{168, 36, 235}: "ZAO NPO Introtest", + [3]byte{168, 38, 217}: "HTC Corporation", + [3]byte{168, 41, 76}: "Precision Optical Transceivers, Inc.", + [3]byte{168, 43, 214}: "Shina System Co., Ltd", + [3]byte{168, 48, 173}: "Wei Fang Goertek Electronics Co.,Ltd", + [3]byte{168, 50, 154}: "Digicom Futuristic Technologies Ltd.", + [3]byte{168, 57, 68}: "Actiontec Electronics, Inc", + [3]byte{168, 64, 65}: "Dragino Technology Co., Limited", + [3]byte{168, 68, 129}: "Nokia Corporation", + [3]byte{168, 69, 233}: "Firich Enterprises CO., LTD.", + [3]byte{168, 73, 165}: "Lisantech Co., Ltd.", + [3]byte{168, 84, 178}: "Wistron Neweb Corp.", + [3]byte{168, 85, 106}: "Pocketnet Technology Inc.", + [3]byte{168, 87, 78}: "TP-LINK TECHNOLOGIES CO.,LTD.", + [3]byte{168, 91, 176}: "Shenzhen Dehoo Technology Co.,Ltd", + [3]byte{168, 91, 243}: "Audivo GmbH", + [3]byte{168, 97, 170}: "Cloudview Limited", + [3]byte{168, 98, 162}: "JIWUMEDIA CO., LTD.", + [3]byte{168, 99, 223}: "DISPLAIRE CORPORATION", + [3]byte{168, 99, 242}: "Texas Instruments", + [3]byte{168, 100, 5}: "nimbus 9, Inc", + [3]byte{168, 101, 178}: "DONGGUAN YISHANG ELECTRONIC TECHNOLOGY CO., LIMITED", + [3]byte{168, 106, 111}: "RIM", + [3]byte{168, 112, 165}: "UniComm Inc.", + [3]byte{168, 117, 214}: "FreeTek International Co., Ltd.", + [3]byte{168, 117, 226}: "Aventura Technologies, Inc.", + [3]byte{168, 119, 111}: "Zonoff", + [3]byte{168, 123, 57}: "Nokia Corporation", + [3]byte{168, 124, 1}: "Samsung Elec Co.,Ltd", + [3]byte{168, 126, 51}: "Nokia Danmark A/S", + [3]byte{168, 129, 241}: "BMEYE B.V.", + [3]byte{168, 134, 221}: "Apple, Inc.", + [3]byte{168, 135, 146}: "Broadband Antenna Tracking Systems", + [3]byte{168, 135, 237}: "ARC Wireless LLC", + [3]byte{168, 136, 8}: "Apple", + [3]byte{168, 140, 238}: "MicroMade Galka i Drozdz sp.j.", + [3]byte{168, 141, 123}: "SunDroid Global limited.", + [3]byte{168, 142, 36}: "Apple", + [3]byte{168, 146, 44}: "LG Electronics", + [3]byte{168, 147, 230}: "JIANGXI JINGGANGSHAN CKING COMMUNICATION TECHNOLOGY CO.,LTD", + [3]byte{168, 149, 176}: "Aker Subsea Ltd", + [3]byte{168, 150, 138}: "Apple", + [3]byte{168, 151, 220}: "IBM", + [3]byte{168, 152, 198}: "Shinbo Co., Ltd.", + [3]byte{168, 153, 92}: "aizo ag", + [3]byte{168, 155, 16}: "inMotion Ltd.", + [3]byte{168, 157, 210}: "Shanghai DareGlobal Technologies Co., Ltd", + [3]byte{168, 166, 104}: "zte corporation", + [3]byte{168, 173, 61}: "Alcatel-Lucent Shanghai Bell Co., Ltd", + [3]byte{168, 176, 174}: "LEONI", + [3]byte{168, 177, 212}: "CISCO SYSTEMS, INC.", + [3]byte{168, 185, 179}: "ESSYS", + [3]byte{168, 187, 207}: "Apple", + [3]byte{168, 189, 26}: "Honey Bee (Hong Kong) Limited", + [3]byte{168, 189, 58}: "UNIONMAN TECHNOLOGY CO.,LTD", + [3]byte{168, 194, 34}: "TM-Research Inc.", + [3]byte{168, 203, 149}: "EAST BEST CO., LTD.", + [3]byte{168, 204, 197}: "Saab AB (publ)", + [3]byte{168, 206, 144}: "CVC", + [3]byte{168, 208, 227}: "Systech Electronics Ltd.", + [3]byte{168, 208, 229}: "Juniper Networks", + [3]byte{168, 210, 54}: "Lightware Visual Engineering", + [3]byte{168, 211, 200}: "Wachendorff Elektronik GmbH & Co. KG", + [3]byte{168, 216, 138}: "Wyconn", + [3]byte{168, 224, 24}: "Nokia Corporation", + [3]byte{168, 227, 238}: "Sony Computer Entertainment Inc.", + [3]byte{168, 229, 57}: "Moimstone Co.,Ltd", + [3]byte{168, 239, 38}: "Tritonwave", + [3]byte{168, 242, 116}: "Samsung Electronics", + [3]byte{168, 244, 112}: "Fujian Newland Communication Science Technologies Co.,Ltd.", + [3]byte{168, 247, 224}: "PLANET Technology Corporation", + [3]byte{168, 249, 75}: "Eltex Enterprise Ltd.", + [3]byte{168, 250, 216}: "Apple", + [3]byte{168, 251, 112}: "WiseSec L.t.d", + [3]byte{168, 252, 183}: "Consolidated Resource Imaging", + [3]byte{170, 0, 0}: "DIGITAL EQUIPMENT CORPORATION", + [3]byte{170, 0, 1}: "DIGITAL EQUIPMENT CORPORATION", + [3]byte{170, 0, 2}: "DIGITAL EQUIPMENT CORPORATION", + [3]byte{170, 0, 3}: "DIGITAL EQUIPMENT CORPORATION", + [3]byte{170, 0, 4}: "DIGITAL EQUIPMENT CORPORATION", + [3]byte{172, 1, 66}: "Uriel Technologies SIA", + [3]byte{172, 2, 202}: "HI Solutions, Inc.", + [3]byte{172, 2, 207}: "RW Tecnologia Industria e Comercio Ltda", + [3]byte{172, 2, 239}: "Comsis", + [3]byte{172, 6, 19}: "Senselogix Ltd", + [3]byte{172, 10, 97}: "Labor S.r.L.", + [3]byte{172, 13, 254}: "Ekon GmbH - myGEKKO", + [3]byte{172, 17, 211}: "Suzhou HOTEK Video Technology Co. Ltd", + [3]byte{172, 20, 97}: "ATAW Co., Ltd.", + [3]byte{172, 20, 210}: "wi-daq, inc.", + [3]byte{172, 22, 45}: "Hewlett Packard", + [3]byte{172, 23, 2}: "Fibar Group sp. z o.o.", + [3]byte{172, 24, 38}: "SEIKO EPSON CORPORATION", + [3]byte{172, 25, 159}: "SUNGROW POWER SUPPLY CO.,LTD.", + [3]byte{172, 32, 170}: "DMATEK Co., Ltd.", + [3]byte{172, 34, 11}: "ASUSTek COMPUTER INC.", + [3]byte{172, 45, 163}: "TXTR GmbH", + [3]byte{172, 47, 168}: "Humannix Co.,Ltd.", + [3]byte{172, 49, 157}: "Shenzhen TG-NET Botone Technology Co.,Ltd.", + [3]byte{172, 52, 203}: "Shanhai GBCOM Communication Technology Co. Ltd", + [3]byte{172, 54, 19}: "Samsung Electronics Co.,Ltd", + [3]byte{172, 56, 112}: "Lenovo Mobile Communication Technology Ltd.", + [3]byte{172, 58, 122}: "Roku", + [3]byte{172, 60, 11}: "Apple", + [3]byte{172, 60, 180}: "Nilan A/S", + [3]byte{172, 61, 5}: "Instorescreen Aisa", + [3]byte{172, 61, 117}: "HANGZHOU ZHIWAY TECHNOLOGIES CO.,LTD.", + [3]byte{172, 63, 164}: "TAIYO YUDEN CO.,LTD", + [3]byte{172, 64, 234}: "C&T Solution Inc.", + [3]byte{172, 65, 34}: "Eclipse Electronic Systems Inc.", + [3]byte{172, 68, 242}: "Revolabs Inc", + [3]byte{172, 71, 35}: "Genelec", + [3]byte{172, 74, 254}: "Hisense Broadband Multimedia Technology Co.,Ltd.", + [3]byte{172, 75, 200}: "Juniper Networks", + [3]byte{172, 78, 145}: "HUAWEI TECHNOLOGIES CO.,LTD", + [3]byte{172, 79, 252}: "SVS-VISTEK GmbH", + [3]byte{172, 80, 54}: "Pi-Coral Inc", + [3]byte{172, 81, 53}: "MPI TECH", + [3]byte{172, 81, 238}: "Cambridge Communication Systems Ltd", + [3]byte{172, 84, 236}: "IEEE P1823 Standards Working Group", + [3]byte{172, 88, 59}: "Human Assembler, Inc.", + [3]byte{172, 93, 16}: "Pace Americas", + [3]byte{172, 94, 140}: "Utillink", + [3]byte{172, 97, 35}: "Drivven, Inc.", + [3]byte{172, 103, 6}: "Ruckus Wireless", + [3]byte{172, 107, 172}: "Jenny Science AG", + [3]byte{172, 110, 26}: "Shenzhen Gongjin Electronics Co.,Ltd", + [3]byte{172, 111, 79}: "Enspert Inc", + [3]byte{172, 111, 187}: "TATUNG Technology Inc.", + [3]byte{172, 111, 217}: "Valueplus Inc.", + [3]byte{172, 114, 54}: "Lexking Technology Co., Ltd.", + [3]byte{172, 114, 137}: "Intel Corporate", + [3]byte{172, 122, 66}: "iConnectivity", + [3]byte{172, 123, 161}: "Intel Corporate", + [3]byte{172, 127, 62}: "Apple", + [3]byte{172, 128, 214}: "Hexatronic AB", + [3]byte{172, 129, 18}: "Gemtek Technology Co., Ltd.", + [3]byte{172, 129, 243}: "Nokia Corporation", + [3]byte{172, 131, 23}: "Shenzhen Furtunetel Communication Co., Ltd", + [3]byte{172, 131, 240}: "ImmediaTV Corporation", + [3]byte{172, 133, 61}: "HUAWEI TECHNOLOGIES CO.,LTD", + [3]byte{172, 134, 116}: "Open Mesh, Inc.", + [3]byte{172, 134, 126}: "Create New Technology (HK) Limited Company", + [3]byte{172, 135, 163}: "Apple", + [3]byte{172, 138, 205}: "ROGER D.Wensker, G.Wensker sp.j.", + [3]byte{172, 141, 20}: "Smartrove Inc", + [3]byte{172, 147, 47}: "Nokia Corporation", + [3]byte{172, 148, 3}: "Envision Peripherals Inc", + [3]byte{172, 154, 150}: "Lantiq Deutschland GmbH", + [3]byte{172, 155, 132}: "Smak Tecnologia e Automacao", + [3]byte{172, 156, 228}: "Alcatel-Lucent Shanghai Bell Co., Ltd", + [3]byte{172, 160, 22}: "CISCO SYSTEMS, INC.", + [3]byte{172, 162, 19}: "Shenzhen Bilian electronic CO.,LTD", + [3]byte{172, 162, 44}: "Baycity Technologies Ltd", + [3]byte{172, 163, 30}: "Aruba Networks", + [3]byte{172, 164, 48}: "Peerless AV", + [3]byte{172, 169, 25}: "TrekStor GmbH", + [3]byte{172, 169, 160}: "Audioengine, Ltd.", + [3]byte{172, 171, 141}: "Lyngso Marine A/S", + [3]byte{172, 179, 19}: "ARRIS Group, Inc.", + [3]byte{172, 183, 79}: "METEL s.r.o.", + [3]byte{172, 184, 89}: "Uniband Electronic Corp,", + [3]byte{172, 189, 11}: "IMAC CO.,LTD", + [3]byte{172, 190, 117}: "Ufine Technologies Co.,Ltd.", + [3]byte{172, 190, 182}: "Visualedge Technology Co., Ltd.", + [3]byte{172, 194, 236}: "CLT INT'L IND. CORP.", + [3]byte{172, 197, 149}: "Graphite Systems", + [3]byte{172, 198, 152}: "Kohzu Precision Co., Ltd.", + [3]byte{172, 201, 53}: "Ness Corporation", + [3]byte{172, 202, 84}: "Telldus Technologies AB", + [3]byte{172, 202, 142}: "ODA Technologies", + [3]byte{172, 202, 186}: "Midokura Co., Ltd.", + [3]byte{172, 203, 9}: "Hefcom Metering (Pty) Ltd", + [3]byte{172, 204, 142}: "Axis Communications AB", + [3]byte{172, 206, 143}: "HWA YAO TECHNOLOGIES CO., LTD", + [3]byte{172, 207, 35}: "Hi-flying electronics technology Co.,Ltd", + [3]byte{172, 207, 92}: "Apple", + [3]byte{172, 209, 128}: "Crexendo Business Solutions, Inc.", + [3]byte{172, 211, 100}: "ABB SPA, ABB SACE DIV.", + [3]byte{172, 214, 87}: "Shaanxi Guolian Digital TV Technology Co., Ltd.", + [3]byte{172, 217, 214}: "tci GmbH", + [3]byte{172, 219, 218}: "Shenzhen Geniatech Inc, Ltd", + [3]byte{172, 222, 72}: "PRIVATE", + [3]byte{172, 224, 105}: "ISAAC Instruments", + [3]byte{172, 226, 21}: "Huawei Technologies Co., Ltd", + [3]byte{172, 227, 72}: "MadgeTech, Inc", + [3]byte{172, 228, 46}: "SK hynix", + [3]byte{172, 230, 75}: "Shenzhen Baojia Battery Technology Co., Ltd.", + [3]byte{172, 232, 123}: "Huawei Technologies Co., Ltd", + [3]byte{172, 232, 126}: "Bytemark Computer Consulting Ltd", + [3]byte{172, 233, 127}: "IoT Tech Limited", + [3]byte{172, 233, 170}: "Hay Systems Ltd", + [3]byte{172, 234, 106}: "GENIX INFOCOMM CO., LTD.", + [3]byte{172, 238, 59}: "6harmonics Inc", + [3]byte{172, 240, 178}: "Becker Electronics Taiwan Ltd.", + [3]byte{172, 241, 223}: "D-Link International", + [3]byte{172, 242, 197}: "Cisco", + [3]byte{172, 247, 243}: "XIAOMI CORPORATION", + [3]byte{172, 249, 126}: "ELESYS INC.", + [3]byte{172, 253, 206}: "Intel Corporate", + [3]byte{172, 253, 236}: "Apple, Inc", + [3]byte{176, 0, 180}: "Cisco", + [3]byte{176, 5, 148}: "Liteon Technology Corporation", + [3]byte{176, 9, 211}: "Avizia", + [3]byte{176, 16, 65}: "Hon Hai Precision Ind. Co.,Ltd.", + [3]byte{176, 18, 3}: "Dynamics Hong Kong Limited", + [3]byte{176, 18, 102}: "Futaba-Kikaku", + [3]byte{176, 20, 8}: "LIGHTSPEED INTERNATIONAL CO.", + [3]byte{176, 23, 67}: "EDISON GLOBAL CIRCUITS LLC", + [3]byte{176, 27, 124}: "Ontrol A.S.", + [3]byte{176, 28, 145}: "Elim Co", + [3]byte{176, 31, 129}: "IEEE REGISTRATION AUTHORITY - Please see MAM public listing for more information.", + [3]byte{176, 36, 243}: "Progeny Systems", + [3]byte{176, 37, 170}: "PRIVATE", + [3]byte{176, 52, 149}: "Apple", + [3]byte{176, 53, 141}: "Nokia Corporation", + [3]byte{176, 56, 41}: "Siliconware Precision Industries Co., Ltd.", + [3]byte{176, 56, 80}: "Nanjing CAS-ZDC IOT SYSTEM CO.,LTD", + [3]byte{176, 67, 93}: "NuLEDs, Inc.", + [3]byte{176, 69, 21}: "mira fitness,LLC.", + [3]byte{176, 69, 25}: "TCT mobile ltd", + [3]byte{176, 69, 69}: "YACOUB Automation GmbH", + [3]byte{176, 70, 252}: "MitraStar Technology Corp.", + [3]byte{176, 72, 122}: "TP-LINK TECHNOLOGIES CO., LTD.", + [3]byte{176, 76, 5}: "Fresenius Medical Care Deutschland GmbH", + [3]byte{176, 80, 188}: "SHENZHEN BASICOM ELECTRONIC CO.,LTD.", + [3]byte{176, 81, 142}: "Holl technology CO.Ltd.", + [3]byte{176, 87, 6}: "Vallox Oy", + [3]byte{176, 88, 196}: "Broadcast Microwave Services, Inc", + [3]byte{176, 91, 31}: "THERMO FISHER SCIENTIFIC S.P.A.", + [3]byte{176, 91, 103}: "Huawei Technologies Co., Ltd", + [3]byte{176, 92, 229}: "Nokia Corporation", + [3]byte{176, 97, 199}: "Ericsson-LG Enterprise", + [3]byte{176, 101, 99}: "Shanghai Railway Communication Factory", + [3]byte{176, 101, 189}: "Apple", + [3]byte{176, 104, 182}: "Hangzhou OYE Technology Co. Ltd", + [3]byte{176, 105, 113}: "DEI Sales, Inc.", + [3]byte{176, 108, 191}: "3ality Digital Systems GmbH", + [3]byte{176, 117, 12}: "QA Cafe", + [3]byte{176, 117, 77}: "Alcatel-Lucent", + [3]byte{176, 117, 213}: "ZTE Corporation", + [3]byte{176, 119, 172}: "ARRIS Group, Inc.", + [3]byte{176, 121, 8}: "Cummings Engineering", + [3]byte{176, 121, 60}: "Revolv Inc", + [3]byte{176, 121, 148}: "Motorola Mobility LLC", + [3]byte{176, 125, 98}: "Dipl.-Ing. H. Horstmann GmbH", + [3]byte{176, 128, 140}: "Laser Light Engines", + [3]byte{176, 129, 216}: "I-sys Corp", + [3]byte{176, 131, 254}: "Dell Inc", + [3]byte{176, 134, 158}: "Chloride S.r.L", + [3]byte{176, 136, 7}: "Strata Worldwide", + [3]byte{176, 137, 145}: "LGE", + [3]byte{176, 142, 26}: "URadio Systems Co., Ltd", + [3]byte{176, 144, 116}: "Fulan Electronics Limited", + [3]byte{176, 145, 52}: "Taleo", + [3]byte{176, 145, 55}: "ISis ImageStream Internet Solutions, Inc", + [3]byte{176, 151, 58}: "E-Fuel Corporation", + [3]byte{176, 152, 159}: "LG CNS", + [3]byte{176, 153, 40}: "Fujitsu Limited", + [3]byte{176, 154, 226}: "STEMMER IMAGING GmbH", + [3]byte{176, 155, 212}: "GNH Software India Private Limited", + [3]byte{176, 159, 186}: "Apple", + [3]byte{176, 161, 10}: "Pivotal Systems Corporation", + [3]byte{176, 163, 126}: "Qingdao Haier Electronics Co.,Ltd", + [3]byte{176, 167, 42}: "Ensemble Designs, Inc.", + [3]byte{176, 167, 55}: "Roku, Inc.", + [3]byte{176, 168, 110}: "Juniper Networks", + [3]byte{176, 170, 54}: "GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD.", + [3]byte{176, 172, 250}: "Fujitsu Limited", + [3]byte{176, 173, 170}: "Avaya, Inc", + [3]byte{176, 178, 220}: "Zyxel Communications Corporation", + [3]byte{176, 179, 43}: "Slican Sp. z o.o.", + [3]byte{176, 180, 72}: "Texas Instruments", + [3]byte{176, 184, 213}: "Nanjing Nengrui Auto Equipment CO.,Ltd", + [3]byte{176, 189, 109}: "Echostreams Innovative Solutions", + [3]byte{176, 189, 161}: "ZAKLAD ELEKTRONICZNY SIMS", + [3]byte{176, 191, 153}: "WIZITDONGDO", + [3]byte{176, 196, 231}: "Samsung Electronics", + [3]byte{176, 197, 84}: "D-Link International", + [3]byte{176, 198, 154}: "Juniper Networks", + [3]byte{176, 199, 69}: "Buffalo Inc.", + [3]byte{176, 200, 63}: "Jiangsu Cynray IOT Co., Ltd.", + [3]byte{176, 200, 173}: "People Power Company", + [3]byte{176, 201, 91}: "Beijing Symtech CO.,LTD", + [3]byte{176, 206, 24}: "Zhejiang shenghui lighting co.,Ltd", + [3]byte{176, 207, 77}: "MI-Zone Technology Ireland", + [3]byte{176, 208, 156}: "Samsung Electronics Co.,Ltd", + [3]byte{176, 210, 245}: "Vello Systems, Inc.", + [3]byte{176, 213, 157}: "Shenzhen Zowee Technology Co., Ltd", + [3]byte{176, 215, 197}: "STP KFT", + [3]byte{176, 218, 0}: "CERA ELECTRONIQUE", + [3]byte{176, 223, 58}: "Samsung Electronics Co.,Ltd", + [3]byte{176, 227, 157}: "CAT SYSTEM CO.,LTD.", + [3]byte{176, 229, 14}: "NRG SYSTEMS INC", + [3]byte{176, 231, 84}: "2Wire", + [3]byte{176, 232, 146}: "SEIKO EPSON CORPORATION", + [3]byte{176, 233, 126}: "Advanced Micro Peripherals", + [3]byte{176, 236, 113}: "Samsung Electronics Co.,Ltd", + [3]byte{176, 236, 143}: "GMX SAS", + [3]byte{176, 238, 69}: "AzureWave Technologies, Inc.", + [3]byte{176, 241, 188}: "Dhemax Ingenieros Ltda", + [3]byte{176, 250, 235}: "Cisco", + [3]byte{176, 254, 189}: "PRIVATE", + [3]byte{180, 0, 156}: "CableWorld Ltd.", + [3]byte{180, 1, 66}: "GCI Science & Technology Co.,LTD", + [3]byte{180, 4, 24}: "Smartchip Integrated Inc.", + [3]byte{180, 7, 249}: "SAMSUNG ELECTRO-MECHANICS", + [3]byte{180, 8, 50}: "TC Communications", + [3]byte{180, 10, 198}: "DEXON Systems Ltd.", + [3]byte{180, 11, 68}: "Smartisan Technology Co., Ltd.", + [3]byte{180, 11, 122}: "Brusa Elektronik AG", + [3]byte{180, 12, 37}: "Palo Alto Networks", + [3]byte{180, 14, 150}: "HERAN", + [3]byte{180, 14, 220}: "LG-Ericsson Co.,Ltd.", + [3]byte{180, 20, 137}: "CISCO SYSTEMS, INC.", + [3]byte{180, 21, 19}: "HUAWEI TECHNOLOGIES CO.,LTD", + [3]byte{180, 23, 128}: "DTI Group Ltd", + [3]byte{180, 24, 209}: "Apple", + [3]byte{180, 29, 239}: "Internet Laboratories, Inc.", + [3]byte{180, 33, 29}: "Beijing GuangXin Technology Co., Ltd", + [3]byte{180, 33, 138}: "Dog Hunter LLC", + [3]byte{180, 36, 231}: "Codetek Technology Co.,Ltd", + [3]byte{180, 40, 241}: "E-Prime Co., Ltd.", + [3]byte{180, 42, 57}: "ORBIT MERRET, spol. s r. o.", + [3]byte{180, 44, 146}: "Zhejiang Weirong Electronic Co., Ltd", + [3]byte{180, 44, 190}: "Direct Payment Solutions Limited", + [3]byte{180, 49, 184}: "Aviwest", + [3]byte{180, 52, 108}: "MATSUNICHI DIGITAL TECHNOLOGY (HONG KONG) LIMITED", + [3]byte{180, 53, 100}: "Fujian Tian Cheng Electron Science & Technical Development Co.,Ltd.", + [3]byte{180, 53, 247}: "Zhejiang Pearmain Electronics Co.ltd.", + [3]byte{180, 55, 65}: "Consert, Inc.", + [3]byte{180, 57, 52}: "Pen Generations, Inc.", + [3]byte{180, 57, 214}: "ProCurve Networking by HP", + [3]byte{180, 58, 40}: "Samsung Electronics Co.,Ltd", + [3]byte{180, 61, 178}: "Degreane Horizon", + [3]byte{180, 62, 59}: "Viableware, Inc", + [3]byte{180, 65, 122}: "ShenZhen Gongjin Electronics Co.,Ltd", + [3]byte{180, 67, 13}: "Broadlink Pty Ltd", + [3]byte{180, 71, 94}: "Avaya, Inc", + [3]byte{180, 76, 194}: "NR ELECTRIC CO., LTD", + [3]byte{180, 81, 249}: "NB Software", + [3]byte{180, 82, 83}: "Seagate Technology", + [3]byte{180, 82, 125}: "Sony Mobile Communications AB", + [3]byte{180, 82, 126}: "Sony Mobile Communications AB", + [3]byte{180, 85, 112}: "Borea", + [3]byte{180, 88, 97}: "CRemote, LLC", + [3]byte{180, 92, 164}: "Thing-talk Wireless Communication Technologies Corporation Limited", + [3]byte{180, 97, 255}: "Lumigon A/S", + [3]byte{180, 98, 56}: "Exablox", + [3]byte{180, 98, 147}: "Samsung Electronics Co.,Ltd", + [3]byte{180, 98, 173}: "raytest GmbH", + [3]byte{180, 102, 152}: "Zealabs srl", + [3]byte{180, 103, 233}: "Qingdao GoerTek Technology Co., Ltd.", + [3]byte{180, 116, 159}: "askey computer corp", + [3]byte{180, 117, 14}: "Belkin International Inc.", + [3]byte{180, 121, 167}: "Samsung Electro Mechanics co., LTD.", + [3]byte{180, 124, 41}: "Shenzhen Guzidi Technology Co.,Ltd", + [3]byte{180, 127, 94}: "Foresight Manufacture (S) Pte Ltd", + [3]byte{180, 130, 85}: "Research Products Corporation", + [3]byte{180, 130, 123}: "AKG Acoustics GmbH", + [3]byte{180, 130, 197}: "Relay2, Inc.", + [3]byte{180, 130, 254}: "Askey Computer Corp", + [3]byte{180, 133, 71}: "Amptown System Company GmbH", + [3]byte{180, 137, 16}: "Coster T.E. S.P.A.", + [3]byte{180, 148, 78}: "WeTelecom Co., Ltd.", + [3]byte{180, 152, 66}: "zte corporation", + [3]byte{180, 153, 76}: "Texas Instruments", + [3]byte{180, 153, 186}: "Hewlett-Packard Company", + [3]byte{180, 157, 180}: "Axion Technologies Inc.", + [3]byte{180, 158, 172}: "Imagik Int'l Corp", + [3]byte{180, 158, 230}: "SHENZHEN TECHNOLOGY CO LTD", + [3]byte{180, 164, 181}: "Zen Eye Co.,Ltd", + [3]byte{180, 164, 227}: "CISCO SYSTEMS, INC.", + [3]byte{180, 165, 169}: "MODI GmbH", + [3]byte{180, 168, 40}: "Shenzhen Concox Information Technology Co., Ltd", + [3]byte{180, 168, 43}: "Histar Digital Electronics Co., Ltd.", + [3]byte{180, 169, 90}: "Avaya, Inc", + [3]byte{180, 170, 77}: "Ensequence, Inc.", + [3]byte{180, 171, 44}: "MtM Technology Corporation", + [3]byte{180, 174, 111}: "Circle Reliance, Inc.", + [3]byte{180, 176, 23}: "Avaya, Inc", + [3]byte{180, 179, 98}: "ZTE Corporation", + [3]byte{180, 181, 47}: "Hewlett Packard", + [3]byte{180, 181, 66}: "Hubbell Power Systems, Inc.", + [3]byte{180, 181, 175}: "Minsung Electronics", + [3]byte{180, 182, 118}: "Intel Corporate", + [3]byte{180, 184, 89}: "Texa Spa", + [3]byte{180, 184, 141}: "Thuh Company", + [3]byte{180, 196, 78}: "VXL eTech Pvt Ltd", + [3]byte{180, 199, 153}: "Motorola Solutions Inc.", + [3]byte{180, 200, 16}: "UMPI Elettronica", + [3]byte{180, 204, 233}: "PROSYST", + [3]byte{180, 206, 246}: "HTC Corporation", + [3]byte{180, 207, 219}: "Shenzhen Jiuzhou Electric Co.,LTD", + [3]byte{180, 216, 169}: "BetterBots", + [3]byte{180, 216, 222}: "iota Computing, Inc.", + [3]byte{180, 221, 21}: "ControlThings Oy Ab", + [3]byte{180, 223, 59}: "Chromlech", + [3]byte{180, 223, 250}: "Litemax Electronics Inc.", + [3]byte{180, 224, 205}: "Fusion-io, Inc", + [3]byte{180, 225, 235}: "PRIVATE", + [3]byte{180, 233, 176}: "Cisco", + [3]byte{180, 237, 25}: "Pie Digital, Inc.", + [3]byte{180, 237, 84}: "Wohler Technologies", + [3]byte{180, 238, 180}: "ASKEY COMPUTER CORP", + [3]byte{180, 238, 212}: "Texas Instruments", + [3]byte{180, 240, 171}: "Apple", + [3]byte{180, 242, 232}: "Pace plc", + [3]byte{180, 243, 35}: "PETATEL INC.", + [3]byte{180, 252, 117}: "SEMA Electronics(HK) CO.,LTD", + [3]byte{180, 254, 140}: "Centro Sicurezza Italia SpA", + [3]byte{184, 3, 5}: "Intel Corporate", + [3]byte{184, 4, 21}: "Bayan Audio", + [3]byte{184, 8, 207}: "Intel Corporate", + [3]byte{184, 11, 157}: "ROPEX Industrie-Elektronik GmbH", + [3]byte{184, 20, 19}: "Keen High Holding(HK) Ltd.", + [3]byte{184, 22, 25}: "ARRIS Group, Inc.", + [3]byte{184, 23, 194}: "Apple", + [3]byte{184, 24, 111}: "ORIENTAL MOTOR CO., LTD.", + [3]byte{184, 25, 153}: "Nesys", + [3]byte{184, 32, 231}: "Guangzhou Horizontal Information & Network Integration Co. Ltd", + [3]byte{184, 36, 16}: "Magneti Marelli Slovakia s.r.o.", + [3]byte{184, 36, 26}: "SWEDA INFORMATICA LTDA", + [3]byte{184, 38, 108}: "ANOV France", + [3]byte{184, 38, 212}: "Furukawa Industrial S.A. Produtos Elétricos", + [3]byte{184, 39, 235}: "Raspberry Pi Foundation", + [3]byte{184, 40, 139}: "Parker Hannifin", + [3]byte{184, 41, 247}: "Blaster Tech", + [3]byte{184, 42, 114}: "Dell Inc", + [3]byte{184, 42, 220}: "EFR Europäische Funk-Rundsteuerung GmbH", + [3]byte{184, 44, 160}: "Honeywell HomMed", + [3]byte{184, 48, 168}: "Road-Track Telematics Development", + [3]byte{184, 54, 216}: "Videoswitch", + [3]byte{184, 56, 97}: "Cisco", + [3]byte{184, 56, 202}: "Kyokko Tsushin System CO.,LTD", + [3]byte{184, 58, 123}: "Worldplay (Canada) Inc.", + [3]byte{184, 61, 78}: "Shenzhen Cultraview Digital Technology Co.,Ltd Shanghai Branch", + [3]byte{184, 62, 89}: "Roku, Inc", + [3]byte{184, 65, 95}: "ASP AG", + [3]byte{184, 67, 228}: "Vlatacom", + [3]byte{184, 71, 198}: "SanJet Technology Corp.", + [3]byte{184, 79, 213}: "Microsoft Corporation", + [3]byte{184, 85, 16}: "Zioncom Electronics (Shenzhen) Ltd.", + [3]byte{184, 88, 16}: "NUMERA, INC.", + [3]byte{184, 90, 247}: "Ouya, Inc", + [3]byte{184, 90, 254}: "Handaer Communication Technology (Beijing) Co., Ltd", + [3]byte{184, 94, 123}: "Samsung Electronics Co.,Ltd", + [3]byte{184, 96, 145}: "Onnet Technologies and Innovations LLC", + [3]byte{184, 97, 111}: "Accton Wireless Broadband(AWB), Corp.", + [3]byte{184, 98, 31}: "CISCO SYSTEMS, INC.", + [3]byte{184, 99, 188}: "ROBOTIS, Co, Ltd", + [3]byte{184, 100, 145}: "CK Telecom Ltd", + [3]byte{184, 101, 59}: "Bolymin, Inc.", + [3]byte{184, 107, 35}: "Toshiba", + [3]byte{184, 108, 232}: "Samsung Electronics Co.,Ltd", + [3]byte{184, 112, 244}: "COMPAL INFORMATION (KUNSHAN) CO., LTD.", + [3]byte{184, 116, 36}: "Viessmann Elektronik GmbH", + [3]byte{184, 116, 71}: "Convergence Technologies", + [3]byte{184, 117, 192}: "PayPal, Inc.", + [3]byte{184, 118, 63}: "Hon Hai Precision Ind. Co.,Ltd.", + [3]byte{184, 119, 195}: "Decagon Devices, Inc.", + [3]byte{184, 120, 46}: "Apple", + [3]byte{184, 121, 126}: "Secure Meters (UK) Limited", + [3]byte{184, 122, 201}: "Siemens Ltd.", + [3]byte{184, 124, 242}: "Aerohive Networks Inc.", + [3]byte{184, 135, 30}: "Good Mind Industries Co., Ltd.", + [3]byte{184, 135, 168}: "Step Ahead Innovations Inc.", + [3]byte{184, 136, 227}: "COMPAL INFORMATION (KUNSHAN) CO., LTD", + [3]byte{184, 137, 202}: "ILJIN ELECTRIC Co., Ltd.", + [3]byte{184, 138, 96}: "Intel Corporate", + [3]byte{184, 141, 18}: "Apple", + [3]byte{184, 142, 58}: "Infinite Technologies JLT", + [3]byte{184, 143, 20}: "Analytica GmbH", + [3]byte{184, 146, 29}: "BG T&A", + [3]byte{184, 148, 210}: "Retail Innovation HTT AB", + [3]byte{184, 150, 116}: "AllDSP GmbH & Co. KG", + [3]byte{184, 151, 90}: "BIOSTAR Microtech Int'l Corp.", + [3]byte{184, 152, 176}: "Atlona Inc.", + [3]byte{184, 152, 247}: "Gionee Communication Equipment Co,Ltd.ShenZhen", + [3]byte{184, 153, 25}: "7signal Solutions, Inc", + [3]byte{184, 154, 237}: "OceanServer Technology, Inc", + [3]byte{184, 155, 201}: "SMC Networks Inc", + [3]byte{184, 155, 228}: "ABB Power Systems Power Generation", + [3]byte{184, 163, 134}: "D-Link International", + [3]byte{184, 163, 224}: "BenRui Technology Co.,Ltd", + [3]byte{184, 168, 175}: "Logic S.p.A.", + [3]byte{184, 172, 111}: "Dell Inc", + [3]byte{184, 173, 62}: "BLUECOM", + [3]byte{184, 174, 110}: "Nintendo Co., Ltd.", + [3]byte{184, 174, 237}: "Elitegroup Computer Systems Co., Ltd.", + [3]byte{184, 175, 103}: "Hewlett-Packard Company", + [3]byte{184, 177, 199}: "BT&COM CO.,LTD", + [3]byte{184, 180, 46}: "Gionee Communication Equipment Co,Ltd.ShenZhen", + [3]byte{184, 183, 215}: "2GIG Technologies", + [3]byte{184, 185, 78}: "Shenzhen iBaby Labs, Inc.", + [3]byte{184, 186, 104}: "Xi'an Jizhong Digital Communication Co.,Ltd", + [3]byte{184, 186, 114}: "Cynove", + [3]byte{184, 187, 109}: "ENERES Co.,Ltd.", + [3]byte{184, 189, 121}: "TrendPoint Systems", + [3]byte{184, 190, 191}: "CISCO SYSTEMS, INC.", + [3]byte{184, 191, 131}: "Intel Corporate", + [3]byte{184, 193, 162}: "Dragon Path Technologies Co., Limited", + [3]byte{184, 196, 111}: "PRIMMCON INDUSTRIES INC", + [3]byte{184, 198, 142}: "Samsung Electronics Co.,Ltd", + [3]byte{184, 199, 22}: "Fiberhome Telecommunication Technologies Co.,LTD", + [3]byte{184, 199, 93}: "Apple", + [3]byte{184, 200, 85}: "Shanghai GBCOM Communication Technology Co.,Ltd.", + [3]byte{184, 202, 58}: "Dell Inc", + [3]byte{184, 205, 147}: "Penetek, Inc", + [3]byte{184, 205, 167}: "Maxeler Technologies Ltd.", + [3]byte{184, 208, 111}: "GUANGZHOU HKUST FOK YING TUNG RESEARCH INSTITUTE", + [3]byte{184, 212, 157}: "M Seven System Ltd.", + [3]byte{184, 216, 18}: "IEEE REGISTRATION AUTHORITY - Please see MAM public listing for more information.", + [3]byte{184, 217, 206}: "Samsung Electronics", + [3]byte{184, 218, 241}: "Strahlenschutz- Entwicklungs- und Ausruestungsgesellschaft mbH", + [3]byte{184, 218, 247}: "Advanced Photonics, Inc.", + [3]byte{184, 220, 135}: "IAI Corporation", + [3]byte{184, 223, 107}: "SpotCam Co., Ltd.", + [3]byte{184, 229, 137}: "Payter BV", + [3]byte{184, 230, 37}: "2Wire", + [3]byte{184, 231, 121}: "9Solutions Oy", + [3]byte{184, 232, 86}: "Apple", + [3]byte{184, 233, 55}: "Sonos, Inc.", + [3]byte{184, 238, 101}: "Liteon Technology Corporation", + [3]byte{184, 238, 121}: "YWire Technologies, Inc.", + [3]byte{184, 243, 23}: "iSun Smasher Communications Private Limited", + [3]byte{184, 244, 208}: "Herrmann Ultraschalltechnik GmbH & Co. Kg", + [3]byte{184, 245, 231}: "WayTools, LLC", + [3]byte{184, 246, 177}: "Apple", + [3]byte{184, 247, 50}: "Aryaka Networks Inc", + [3]byte{184, 248, 40}: "Changshu Gaoshida Optoelectronic Technology Co. Ltd.", + [3]byte{184, 249, 52}: "Sony Ericsson Mobile Communications AB", + [3]byte{184, 253, 50}: "Zhejiang ROICX Microelectronics", + [3]byte{184, 255, 97}: "Apple", + [3]byte{184, 255, 111}: "Shanghai Typrotech Technology Co.Ltd", + [3]byte{184, 255, 254}: "Texas Instruments", + [3]byte{188, 2, 0}: "Stewart Audio", + [3]byte{188, 5, 67}: "AVM GmbH", + [3]byte{188, 13, 165}: "Texas Instruments", + [3]byte{188, 15, 43}: "FORTUNE TECHGROUP CO.,LTD", + [3]byte{188, 18, 94}: "Beijing WisVideo INC.", + [3]byte{188, 20, 1}: "Hitron Technologies. Inc", + [3]byte{188, 20, 239}: "ITON Technology Limited", + [3]byte{188, 21, 166}: "Taiwan Jantek Electronics,Ltd.", + [3]byte{188, 22, 101}: "Cisco", + [3]byte{188, 22, 245}: "Cisco", + [3]byte{188, 26, 103}: "YF Technology Co., Ltd", + [3]byte{188, 32, 164}: "Samsung Electronics", + [3]byte{188, 32, 186}: "Inspur (Shandong) Electronic Information Co., Ltd", + [3]byte{188, 37, 240}: "3D Display Technologies Co., Ltd.", + [3]byte{188, 38, 29}: "HONG KONG TECON TECHNOLOGY", + [3]byte{188, 40, 70}: "NextBIT Computing Pvt. Ltd.", + [3]byte{188, 40, 214}: "Rowley Associates Limited", + [3]byte{188, 43, 107}: "Beijing Haier IC Design Co.,Ltd", + [3]byte{188, 43, 215}: "Revogi Innovation Co., Ltd.", + [3]byte{188, 44, 85}: "Bear Flag Design, Inc.", + [3]byte{188, 45, 152}: "ThinGlobal LLC", + [3]byte{188, 48, 91}: "Dell Inc.", + [3]byte{188, 48, 125}: "Wistron Neweb Corp.", + [3]byte{188, 52, 0}: "IEEE REGISTRATION AUTHORITY - Please see MAM public listing for more information.", + [3]byte{188, 53, 229}: "Hydro Systems Company", + [3]byte{188, 56, 210}: "Pandachip Limited", + [3]byte{188, 57, 166}: "CSUN System Technology Co.,LTD", + [3]byte{188, 59, 175}: "Apple", + [3]byte{188, 62, 19}: "Accordance Systems Inc.", + [3]byte{188, 65, 0}: "Codaco Electronic s.r.o.", + [3]byte{188, 67, 119}: "Hang Zhou Huite Technology Co.,ltd.", + [3]byte{188, 68, 134}: "Samsung Electronics Co.,Ltd", + [3]byte{188, 71, 96}: "Samsung Electronics Co.,Ltd", + [3]byte{188, 75, 121}: "SensingTek", + [3]byte{188, 77, 251}: "Hitron Technologies. Inc", + [3]byte{188, 78, 60}: "CORE STAFF CO., LTD.", + [3]byte{188, 78, 93}: "ZhongMiao Technology Co., Ltd.", + [3]byte{188, 81, 254}: "Swann Communications Pty Ltd", + [3]byte{188, 82, 180}: "Alcatel-Lucent", + [3]byte{188, 82, 183}: "Apple", + [3]byte{188, 95, 244}: "ASRock Incorporation", + [3]byte{188, 98, 159}: "Telenet Systems P. Ltd.", + [3]byte{188, 102, 65}: "IEEE REGISTRATION AUTHORITY - Please see MAM public listing for more information.", + [3]byte{188, 103, 28}: "Cisco", + [3]byte{188, 103, 120}: "Apple", + [3]byte{188, 103, 132}: "Environics Oy", + [3]byte{188, 106, 22}: "tdvine", + [3]byte{188, 106, 41}: "Texas Instruments", + [3]byte{188, 107, 77}: "Alcatel-Lucent", + [3]byte{188, 110, 118}: "Green Energy Options Ltd", + [3]byte{188, 113, 193}: "XTrillion, Inc.", + [3]byte{188, 114, 177}: "Samsung Electronics Co.,Ltd", + [3]byte{188, 116, 215}: "HangZhou JuRu Technology CO.,LTD", + [3]byte{188, 118, 78}: "Rackspace US, Inc.", + [3]byte{188, 118, 112}: "Shenzhen Huawei Communication Technologies Co., Ltd", + [3]byte{188, 119, 55}: "Intel Corporate", + [3]byte{188, 119, 159}: "SBM Co., Ltd.", + [3]byte{188, 121, 173}: "Samsung Electronics Co.,Ltd", + [3]byte{188, 125, 209}: "Radio Data Comms", + [3]byte{188, 129, 31}: "Ingate Systems", + [3]byte{188, 129, 153}: "BASIC Co.,Ltd.", + [3]byte{188, 131, 167}: "SHENZHEN CHUANGWEI-RGB ELECTRONICS CO.,LT", + [3]byte{188, 133, 31}: "Samsung Electronics", + [3]byte{188, 133, 86}: "Hon Hai Precision Ind. Co.,Ltd.", + [3]byte{188, 136, 147}: "VILLBAU Ltd.", + [3]byte{188, 139, 85}: "NPP ELIKS America Inc. DBA T&M Atlantic", + [3]byte{188, 140, 205}: "Samsung Electro Mechanics co.,LTD.", + [3]byte{188, 141, 14}: "Alcatel-Lucent", + [3]byte{188, 146, 107}: "Apple", + [3]byte{188, 150, 128}: "Shenzhen Gongjin Electronics Co.,Ltd", + [3]byte{188, 152, 137}: "Fiberhome Telecommunication Tech.Co.,Ltd.", + [3]byte{188, 153, 188}: "FonSee Technology Inc.", + [3]byte{188, 156, 197}: "Beijing Huafei Technology Co., Ltd.", + [3]byte{188, 157, 165}: "DASCOM Europe GmbH", + [3]byte{188, 164, 225}: "Nabto", + [3]byte{188, 169, 214}: "Cyber-Rain, Inc.", + [3]byte{188, 174, 197}: "ASUSTek COMPUTER INC.", + [3]byte{188, 177, 129}: "SHARP CORPORATION", + [3]byte{188, 177, 243}: "Samsung Electronics", + [3]byte{188, 184, 82}: "Cybera, Inc.", + [3]byte{188, 186, 225}: "AREC Inc.", + [3]byte{188, 187, 201}: "Kellendonk Elektronik GmbH", + [3]byte{188, 188, 70}: "SKS Welding Systems GmbH", + [3]byte{188, 193, 104}: "DinBox Sverige AB", + [3]byte{188, 194, 58}: "Thomson Video Networks", + [3]byte{188, 195, 66}: "Panasonic System Networks Co., Ltd.", + [3]byte{188, 198, 26}: "SPECTRA EMBEDDED SYSTEMS", + [3]byte{188, 198, 219}: "Nokia Corporation", + [3]byte{188, 200, 16}: "Cisco SPVTG", + [3]byte{188, 202, 181}: "ARRIS Group, Inc.", + [3]byte{188, 205, 69}: "VOISMART", + [3]byte{188, 207, 204}: "HTC Corporation", + [3]byte{188, 209, 119}: "TP-LINK TECHNOLOGIES CO.,LTD.", + [3]byte{188, 209, 211}: "Tinno Mobile Technology Corp", + [3]byte{188, 213, 182}: "d2d technologies", + [3]byte{188, 217, 64}: "ASR Co,.Ltd.", + [3]byte{188, 224, 157}: "Eoslink", + [3]byte{188, 229, 159}: "WATERWORLD Technology Co.,LTD", + [3]byte{188, 234, 43}: "CityCom GmbH", + [3]byte{188, 234, 250}: "Hewlett Packard", + [3]byte{188, 238, 123}: "ASUSTek COMPUTER INC.", + [3]byte{188, 242, 175}: "devolo AG", + [3]byte{188, 245, 172}: "LG Electronics", + [3]byte{188, 246, 28}: "Geomodeling Wuxi Technology Co. Ltd.", + [3]byte{188, 246, 133}: "D-Link International", + [3]byte{188, 254, 140}: "Altronic, LLC", + [3]byte{188, 255, 172}: "TOPCON CORPORATION", + [3]byte{192, 13, 126}: "Additech, Inc.", + [3]byte{192, 17, 166}: "Fort-Telecom ltd.", + [3]byte{192, 18, 66}: "Alpha Security Products", + [3]byte{192, 20, 61}: "Hon Hai Precision Ind. Co.,Ltd.", + [3]byte{192, 24, 133}: "Hon Hai Precision Ind. Co.,Ltd.", + [3]byte{192, 30, 155}: "Pixavi AS", + [3]byte{192, 34, 80}: "PRIVATE", + [3]byte{192, 37, 6}: "AVM GmbH", + [3]byte{192, 37, 92}: "Cisco", + [3]byte{192, 39, 185}: "Beijing National Railway Research & Design Institute of Signal & Communication Co., Ltd.", + [3]byte{192, 41, 115}: "Audyssey Laboratories Inc.", + [3]byte{192, 41, 243}: "XySystem", + [3]byte{192, 43, 252}: "iNES. applied informatics GmbH", + [3]byte{192, 44, 122}: "Shen Zhen Horn audio Co., Ltd.", + [3]byte{192, 52, 180}: "Gigastone Corporation", + [3]byte{192, 53, 128}: "A&R TECH", + [3]byte{192, 53, 189}: "Velocytech Aps", + [3]byte{192, 53, 197}: "Prosoft Systems LTD", + [3]byte{192, 56, 150}: "Hon Hai Precision Ind. Co.,Ltd.", + [3]byte{192, 56, 249}: "Nokia Danmark A/S", + [3]byte{192, 59, 143}: "Minicom Digital Signage", + [3]byte{192, 61, 70}: "Shanghai Mochui Network Technology Co., Ltd", + [3]byte{192, 62, 15}: "BSkyB Ltd", + [3]byte{192, 63, 14}: "NETGEAR", + [3]byte{192, 63, 42}: "Biscotti, Inc.", + [3]byte{192, 63, 213}: "Elitegroup Computer Systems Co., LTD", + [3]byte{192, 65, 246}: "LG Electronics Inc", + [3]byte{192, 67, 1}: "Epec Oy", + [3]byte{192, 68, 227}: "Shenzhen Sinkna Electronics Co., LTD", + [3]byte{192, 73, 61}: "MAITRISE TECHNOLOGIQUE", + [3]byte{192, 74, 0}: "TP-LINK TECHNOLOGIES CO.,LTD.", + [3]byte{192, 77, 247}: "SERELEC", + [3]byte{192, 86, 227}: "Hangzhou Hikvision Digital Technology Co.,Ltd.", + [3]byte{192, 87, 188}: "Avaya, Inc", + [3]byte{192, 88, 167}: "Pico Systems Co., Ltd.", + [3]byte{192, 94, 111}: "V. Stonkaus firma \"Kodinis Raktas\"", + [3]byte{192, 94, 121}: "SHENZHEN HUAXUN ARK TECHNOLOGIES CO.,LTD", + [3]byte{192, 97, 24}: "TP-LINK TECHNOLOGIES CO.,LTD.", + [3]byte{192, 98, 107}: "CISCO SYSTEMS, INC.", + [3]byte{192, 99, 148}: "Apple", + [3]byte{192, 100, 198}: "Nokia Corporation", + [3]byte{192, 101, 153}: "Samsung Electronics Co.,Ltd", + [3]byte{192, 103, 175}: "Cisco", + [3]byte{192, 108, 15}: "Dobbs Stanford", + [3]byte{192, 108, 109}: "MagneMotion, Inc.", + [3]byte{192, 123, 188}: "Cisco", + [3]byte{192, 126, 64}: "SHENZHEN XDK COMMUNICATION EQUIPMENT CO.,LTD", + [3]byte{192, 129, 112}: "Effigis GeoSolutions", + [3]byte{192, 131, 10}: "2Wire", + [3]byte{192, 132, 122}: "Apple", + [3]byte{192, 136, 91}: "SnD Tech Co., Ltd.", + [3]byte{192, 138, 222}: "Ruckus Wireless", + [3]byte{192, 139, 111}: "S I Sistemas Inteligentes Eletrônicos Ltda", + [3]byte{192, 140, 96}: "Cisco", + [3]byte{192, 145, 50}: "Patriot Memory", + [3]byte{192, 145, 52}: "ProCurve Networking by HP", + [3]byte{192, 152, 121}: "Acer Inc.", + [3]byte{192, 152, 229}: "University of Michigan", + [3]byte{192, 156, 146}: "COBY", + [3]byte{192, 157, 38}: "Topicon HK Lmd.", + [3]byte{192, 159, 66}: "Apple", + [3]byte{192, 160, 187}: "D-Link International", + [3]byte{192, 160, 199}: "FAIRFIELD INDUSTRIES", + [3]byte{192, 160, 222}: "Multi Touch Oy", + [3]byte{192, 160, 226}: "Eden Innovations", + [3]byte{192, 162, 109}: "Abbott Point of Care", + [3]byte{192, 163, 100}: "3D Systems Massachusetts", + [3]byte{192, 163, 158}: "EarthCam, Inc.", + [3]byte{192, 170, 104}: "OSASI Technos Inc.", + [3]byte{192, 172, 84}: "SAGEMCOM", + [3]byte{192, 179, 57}: "Comigo Ltd.", + [3]byte{192, 179, 87}: "Yoshiki Electronics Industry Ltd.", + [3]byte{192, 184, 177}: "BitBox Ltd", + [3]byte{192, 186, 230}: "Application Solutions (Electronics and Vision) Ltd", + [3]byte{192, 189, 66}: "ZPA Smart Energy a.s.", + [3]byte{192, 193, 192}: "Cisco-Linksys, LLC", + [3]byte{192, 195, 182}: "Automatic Systems", + [3]byte{192, 197, 32}: "Ruckus Wireless", + [3]byte{192, 197, 105}: "SHANGHAI LYNUC CNC TECHNOLOGY CO.,LTD", + [3]byte{192, 198, 135}: "Cisco SPVTG", + [3]byte{192, 201, 70}: "MITSUYA LABORATORIES INC.", + [3]byte{192, 203, 56}: "Hon Hai Precision Ind. Co.,Ltd.", + [3]byte{192, 207, 163}: "Creative Electronics & Software, Inc.", + [3]byte{192, 208, 68}: "SAGEMCOM", + [3]byte{192, 217, 98}: "Askey Computer Corp.", + [3]byte{192, 218, 116}: "Hangzhou Sunyard Technology Co., Ltd.", + [3]byte{192, 223, 119}: "Conrad Electronic SE", + [3]byte{192, 228, 34}: "Texas Instruments", + [3]byte{192, 229, 78}: "DENX Computer Systems GmbH", + [3]byte{192, 234, 228}: "Sonicwall", + [3]byte{192, 238, 251}: "OnePlus Tech (Shenzhen) Ltd", + [3]byte{192, 241, 196}: "Pacidal Corporation Ltd.", + [3]byte{192, 242, 251}: "Apple", + [3]byte{192, 247, 157}: "Powercode", + [3]byte{192, 248, 218}: "Hon Hai Precision Ind. Co.,Ltd.", + [3]byte{192, 249, 145}: "GME Standard Communications P/L", + [3]byte{196, 0, 6}: "Lipi Data Systems Ltd.", + [3]byte{196, 1, 66}: "MaxMedia Technology Limited", + [3]byte{196, 1, 124}: "Ruckus Wireless", + [3]byte{196, 1, 177}: "SeekTech INC", + [3]byte{196, 1, 206}: "PRESITION (2000) CO., LTD.", + [3]byte{196, 4, 21}: "NETGEAR INC.,", + [3]byte{196, 5, 40}: "Huawei Technologies Co., Ltd", + [3]byte{196, 8, 74}: "Alcatel-Lucent", + [3]byte{196, 8, 128}: "Shenzhen UTEPO Tech Co., Ltd.", + [3]byte{196, 9, 56}: "Fujian Star-net Communication Co., Ltd", + [3]byte{196, 10, 203}: "CISCO SYSTEMS, INC.", + [3]byte{196, 14, 69}: "ACK Networks,Inc.", + [3]byte{196, 15, 9}: "Hermes electronic GmbH", + [3]byte{196, 16, 138}: "Ruckus Wireless", + [3]byte{196, 20, 60}: "Cisco", + [3]byte{196, 22, 250}: "Prysm Inc", + [3]byte{196, 23, 254}: "Hon Hai Precision Ind. Co.,Ltd.", + [3]byte{196, 25, 139}: "Dominion Voting Systems Corporation", + [3]byte{196, 25, 236}: "Qualisys AB", + [3]byte{196, 30, 206}: "HMI Sources Ltd.", + [3]byte{196, 33, 200}: "KYOCERA Corporation", + [3]byte{196, 35, 122}: "WhizNets Inc.", + [3]byte{196, 36, 46}: "Galvanic Applied Sciences Inc", + [3]byte{196, 38, 40}: "Airo Wireless", + [3]byte{196, 39, 149}: "Technicolor USA Inc.", + [3]byte{196, 41, 29}: "KLEMSAN ELEKTRIK ELEKTRONIK SAN.VE TIC.AS.", + [3]byte{196, 44, 3}: "Apple", + [3]byte{196, 52, 107}: "Hewlett Packard", + [3]byte{196, 54, 218}: "Rusteletech Ltd.", + [3]byte{196, 56, 211}: "TAGATEC CO.,LTD", + [3]byte{196, 57, 58}: "SMC Networks Inc", + [3]byte{196, 58, 159}: "Siconix Inc.", + [3]byte{196, 60, 60}: "CYBELEC SA", + [3]byte{196, 61, 199}: "NETGEAR", + [3]byte{196, 66, 2}: "Samsung Electronics Co.,Ltd", + [3]byte{196, 67, 143}: "LG Electronics", + [3]byte{196, 69, 103}: "SAMBON PRECISON and ELECTRONICS", + [3]byte{196, 69, 236}: "Shanghai Yali Electron Co.,LTD", + [3]byte{196, 70, 25}: "Hon Hai Precision Ind. Co.,Ltd.", + [3]byte{196, 72, 56}: "Satcom Direct, Inc.", + [3]byte{196, 74, 208}: "FIREFLIES SYSTEMS", + [3]byte{196, 75, 68}: "Omniprint Inc.", + [3]byte{196, 75, 209}: "Wallys Communications Teachnologies Co.,Ltd.", + [3]byte{196, 78, 31}: "BlueN", + [3]byte{196, 78, 172}: "Shenzhen Shiningworth Technology Co., Ltd.", + [3]byte{196, 80, 6}: "Samsung Electronics Co.,Ltd", + [3]byte{196, 84, 68}: "QUANTA COMPUTER INC.", + [3]byte{196, 85, 166}: "Cadac Holdings Ltd", + [3]byte{196, 85, 194}: "Bach-Simpson", + [3]byte{196, 86, 0}: "Galleon Embedded Computing", + [3]byte{196, 86, 254}: "Lava International Ltd.", + [3]byte{196, 87, 110}: "Samsung Electronics Co.,LTD", + [3]byte{196, 88, 194}: "Shenzhen TATFOOK Technology Co., Ltd.", + [3]byte{196, 89, 118}: "Fugoo Coorporation", + [3]byte{196, 93, 216}: "HDMI Forum", + [3]byte{196, 96, 68}: "Everex Electronics Limited", + [3]byte{196, 98, 107}: "ZPT Vigantice", + [3]byte{196, 98, 234}: "Samsung Electronics Co.,Ltd", + [3]byte{196, 99, 84}: "U-Raku, Inc.", + [3]byte{196, 100, 19}: "CISCO SYSTEMS, INC.", + [3]byte{196, 103, 181}: "Libratone A/S", + [3]byte{196, 106, 183}: "Xiaomi Technology,Inc.", + [3]byte{196, 107, 180}: "myIDkey", + [3]byte{196, 109, 241}: "DataGravity", + [3]byte{196, 110, 31}: "TP-LINK TECHNOLOGIES CO.,LTD", + [3]byte{196, 113, 48}: "Fon Technology S.L.", + [3]byte{196, 113, 254}: "CISCO SYSTEMS, INC.", + [3]byte{196, 115, 30}: "Samsung Eletronics Co., Ltd", + [3]byte{196, 123, 47}: "Beijing JoinHope Image Technology Ltd.", + [3]byte{196, 123, 163}: "NAVIS Inc.", + [3]byte{196, 125, 79}: "CISCO SYSTEMS, INC.", + [3]byte{196, 125, 204}: "Motorola Solutions Inc.", + [3]byte{196, 125, 254}: "A.N. Solutions GmbH", + [3]byte{196, 127, 81}: "Inventek Systems", + [3]byte{196, 130, 63}: "Fujian Newland Auto-ID Tech. Co,.Ltd.", + [3]byte{196, 130, 78}: "Changzhou Uchip Electronics Co., LTD.", + [3]byte{196, 133, 8}: "Intel Corporate", + [3]byte{196, 136, 229}: "Samsung Electronics Co.,Ltd", + [3]byte{196, 145, 58}: "Shenzhen Sanland Electronic Co., ltd.", + [3]byte{196, 147, 0}: "8Devices", + [3]byte{196, 147, 19}: "100fio networks technology llc", + [3]byte{196, 147, 128}: "Speedytel technology", + [3]byte{196, 149, 162}: "SHENZHEN WEIJIU INDUSTRY AND TRADE DEVELOPMENT CO., LTD", + [3]byte{196, 152, 5}: "Minieum Networks, Inc", + [3]byte{196, 168, 29}: "D-Link International", + [3]byte{196, 170, 161}: "SUMMIT DEVELOPMENT, spol.s r.o.", + [3]byte{196, 173, 33}: "MEDIAEDGE Corporation", + [3]byte{196, 181, 18}: "General Electric Digital Energy", + [3]byte{196, 186, 153}: "I+ME Actia Informatik und Mikro-Elektronik GmbH", + [3]byte{196, 189, 106}: "SKF GmbH", + [3]byte{196, 190, 132}: "Texas Instruments.", + [3]byte{196, 192, 174}: "MIDORI ELECTRONIC CO., LTD.", + [3]byte{196, 193, 159}: "National Oilwell Varco Instrumentation, Monitoring, and Optimization (NOV IMO)", + [3]byte{196, 199, 85}: "Beijing HuaqinWorld Technology Co.,Ltd", + [3]byte{196, 201, 25}: "Energy Imports Ltd", + [3]byte{196, 201, 236}: "D&D GROUP sp. z o.o.", + [3]byte{196, 202, 217}: "Hangzhou H3C Technologies Co., Limited", + [3]byte{196, 205, 69}: "Beijing Boomsense Technology CO.,LTD.", + [3]byte{196, 212, 137}: "JiangSu Joyque Information Industry Co.,Ltd", + [3]byte{196, 214, 85}: "Tercel technology co.,ltd", + [3]byte{196, 217, 135}: "Intel Corporate", + [3]byte{196, 218, 38}: "NOBLEX SA", + [3]byte{196, 224, 50}: "IEEE 1904.1 Working Group", + [3]byte{196, 225, 124}: "U2S co.", + [3]byte{196, 231, 190}: "SCSpro Co.,Ltd", + [3]byte{196, 233, 47}: "AB Sciex", + [3]byte{196, 233, 132}: "TP-LINK TECHNOLOGIES CO.,LTD.", + [3]byte{196, 235, 227}: "RRCN SAS", + [3]byte{196, 237, 186}: "Texas Instruments", + [3]byte{196, 238, 174}: "VSS Monitoring", + [3]byte{196, 238, 245}: "Oclaro, Inc.", + [3]byte{196, 244, 100}: "Spica international", + [3]byte{196, 245, 124}: "Brocade Communications Systems, Inc.", + [3]byte{196, 252, 228}: "DishTV NZ Ltd", + [3]byte{200, 2, 16}: "LG Innotek", + [3]byte{200, 2, 88}: "ITW GSE ApS", + [3]byte{200, 2, 166}: "Beijing Newmine Technology", + [3]byte{200, 7, 24}: "TDSi", + [3]byte{200, 10, 169}: "Quanta Computer Inc.", + [3]byte{200, 14, 119}: "Le Shi Zhi Xin Electronic Technology (Tianjin) Co.,Ltd", + [3]byte{200, 14, 149}: "OmniLync Inc.", + [3]byte{200, 20, 121}: "Samsung Electronics Co.,Ltd", + [3]byte{200, 22, 189}: "HISENSE ELECTRIC CO.,LTD.", + [3]byte{200, 25, 247}: "Samsung Electronics Co.,Ltd", + [3]byte{200, 26, 254}: "DLOGIC GmbH", + [3]byte{200, 27, 107}: "Innova Security", + [3]byte{200, 30, 142}: "ADV Security (S) Pte Ltd", + [3]byte{200, 31, 102}: "Dell Inc", + [3]byte{200, 32, 142}: "Storagedata", + [3]byte{200, 41, 42}: "Barun Electronics", + [3]byte{200, 42, 20}: "Apple", + [3]byte{200, 46, 148}: "Halfa Enterprise Co., Ltd.", + [3]byte{200, 49, 104}: "eZEX corporation", + [3]byte{200, 50, 50}: "Hunting Innova", + [3]byte{200, 51, 75}: "Apple", + [3]byte{200, 53, 184}: "Ericsson, EAB/RWI/K", + [3]byte{200, 58, 53}: "Tenda Technology Co., Ltd.", + [3]byte{200, 59, 69}: "JRI-Maxant", + [3]byte{200, 61, 151}: "Nokia Corporation", + [3]byte{200, 62, 153}: "Texas Instruments", + [3]byte{200, 62, 167}: "KUNBUS GmbH", + [3]byte{200, 69, 41}: "IMK Networks Co.,Ltd", + [3]byte{200, 69, 68}: "Shanghai Enlogic Electric Technology Co., Ltd.", + [3]byte{200, 72, 245}: "MEDISON Xray Co., Ltd", + [3]byte{200, 76, 117}: "CISCO SYSTEMS, INC.", + [3]byte{200, 86, 69}: "Intermas France", + [3]byte{200, 86, 99}: "Sunflex Europe GmbH", + [3]byte{200, 96, 0}: "ASUSTek COMPUTER INC.", + [3]byte{200, 100, 199}: "zte corporation", + [3]byte{200, 108, 30}: "Display Systems Ltd", + [3]byte{200, 108, 135}: "Zyxel Communications Corp", + [3]byte{200, 108, 182}: "Optcom Co., Ltd.", + [3]byte{200, 111, 29}: "Apple", + [3]byte{200, 114, 72}: "Aplicom Oy", + [3]byte{200, 123, 91}: "zte corporation", + [3]byte{200, 124, 188}: "Valink Co., Ltd.", + [3]byte{200, 125, 119}: "Shenzhen Kingtech Communication Equipment Co.,Ltd", + [3]byte{200, 126, 117}: "Samsung Electronics Co.,Ltd", + [3]byte{200, 132, 57}: "Sunrise Technologies", + [3]byte{200, 132, 71}: "Beautiful Enterprise Co., Ltd", + [3]byte{200, 133, 80}: "Apple", + [3]byte{200, 135, 59}: "Net Optics", + [3]byte{200, 138, 131}: "Dongguan HuaHong Electronics Co.,Ltd", + [3]byte{200, 139, 71}: "Nolangroup S.P.A con Socio Unico", + [3]byte{200, 144, 62}: "Pakton Technologies", + [3]byte{200, 145, 249}: "SAGEMCOM", + [3]byte{200, 147, 70}: "MXCHIP Company Limited", + [3]byte{200, 147, 131}: "Embedded Automation, Inc.", + [3]byte{200, 148, 210}: "Jiangsu Datang Electronic Products Co., Ltd", + [3]byte{200, 151, 159}: "Nokia Corporation", + [3]byte{200, 156, 29}: "CISCO SYSTEMS, INC.", + [3]byte{200, 156, 220}: "ELITEGROUP COMPUTER SYSTEM CO., LTD.", + [3]byte{200, 159, 29}: "SHENZHEN COMMUNICATION TECHNOLOGIES CO.,LTD", + [3]byte{200, 159, 66}: "VDII Innovation AB", + [3]byte{200, 160, 48}: "Texas Instruments", + [3]byte{200, 161, 182}: "Shenzhen Longway Technologies Co., Ltd", + [3]byte{200, 161, 186}: "Neul Ltd", + [3]byte{200, 166, 32}: "Nebula, Inc", + [3]byte{200, 167, 10}: "Verizon Business", + [3]byte{200, 167, 41}: "SYStronics Co., Ltd.", + [3]byte{200, 170, 33}: "ARRIS Group, Inc.", + [3]byte{200, 170, 204}: "PRIVATE", + [3]byte{200, 174, 156}: "Shanghai TYD Elecronic Technology Co. Ltd", + [3]byte{200, 175, 64}: "marco Systemanalyse und Entwicklung GmbH", + [3]byte{200, 179, 115}: "Cisco-Linksys, LLC", + [3]byte{200, 181, 183}: "Apple", + [3]byte{200, 186, 148}: "Samsung Electro Mechanics co., LTD.", + [3]byte{200, 187, 211}: "Embrane", + [3]byte{200, 188, 200}: "Apple", + [3]byte{200, 190, 25}: "D-Link International", + [3]byte{200, 193, 38}: "ZPM Industria e Comercio Ltda", + [3]byte{200, 193, 60}: "RuggedTek Hangzhou Co., Ltd", + [3]byte{200, 199, 145}: "Zero1.tv GmbH", + [3]byte{200, 203, 184}: "Hewlett Packard", + [3]byte{200, 205, 114}: "SAGEMCOM", + [3]byte{200, 208, 25}: "Shanghai Tigercel Communication Technology Co.,Ltd", + [3]byte{200, 209, 11}: "Nokia Corporation", + [3]byte{200, 209, 94}: "Huawei Technologies Co., Ltd", + [3]byte{200, 209, 209}: "AGAiT Technology Corporation", + [3]byte{200, 210, 193}: "Jetlun (Shenzhen) Corporation", + [3]byte{200, 211, 163}: "D-Link International", + [3]byte{200, 212, 41}: "Muehlbauer AG", + [3]byte{200, 213, 144}: "FLIGHT DATA SYSTEMS", + [3]byte{200, 213, 254}: "Shenzhen Zowee Technology Co., Ltd", + [3]byte{200, 215, 25}: "Cisco Consumer Products, LLC", + [3]byte{200, 221, 201}: "Lenovo Mobile Communication Technology Ltd.", + [3]byte{200, 222, 81}: "Integra Networks, Inc.", + [3]byte{200, 223, 124}: "Nokia Corporation", + [3]byte{200, 224, 235}: "Apple", + [3]byte{200, 225, 167}: "Vertu Corporation Limited", + [3]byte{200, 228, 47}: "Technical Research Design and Development", + [3]byte{200, 231, 216}: "SHENZHEN MERCURY COMMUNICATION TECHNOLOGIES CO.,LTD.", + [3]byte{200, 238, 8}: "TANGTOP TECHNOLOGY CO.,LTD", + [3]byte{200, 238, 117}: "Pishion International Co. Ltd", + [3]byte{200, 238, 166}: "Shenzhen SHX Technology Co., Ltd", + [3]byte{200, 239, 46}: "Beijing Gefei Tech. Co., Ltd", + [3]byte{200, 243, 107}: "Yamato Scale Co.,Ltd.", + [3]byte{200, 243, 134}: "Shenzhen Xiaoniao Technology Co.,Ltd", + [3]byte{200, 244, 6}: "Avaya, Inc", + [3]byte{200, 246, 80}: "Apple", + [3]byte{200, 246, 141}: "S.E.TECHNOLOGIES LIMITED", + [3]byte{200, 247, 4}: "Building Block Video", + [3]byte{200, 247, 51}: "Intel Corporate", + [3]byte{200, 249, 129}: "Seneca s.r.l.", + [3]byte{200, 249, 249}: "CISCO SYSTEMS, INC.", + [3]byte{200, 251, 38}: "Cisco SPVTG", + [3]byte{200, 254, 48}: "Bejing DAYO Mobile Communication Technology Ltd.", + [3]byte{200, 255, 119}: "Dyson Limited", + [3]byte{204, 0, 128}: "BETTINI SRL", + [3]byte{204, 3, 250}: "Technicolor CH USA", + [3]byte{204, 4, 124}: "G-WAY Microwave", + [3]byte{204, 4, 180}: "Select Comfort", + [3]byte{204, 5, 27}: "Samsung Electronics Co.,Ltd", + [3]byte{204, 7, 171}: "Samsung Electronics Co.,Ltd", + [3]byte{204, 7, 228}: "Lenovo Mobile Communication Technology Ltd.", + [3]byte{204, 8, 224}: "Apple", + [3]byte{204, 9, 200}: "IMAQLIQ LTD", + [3]byte{204, 12, 218}: "Miljovakt AS", + [3]byte{204, 13, 236}: "Cisco SPVTG", + [3]byte{204, 16, 163}: "Beijing Nan Bao Technology Co., Ltd.", + [3]byte{204, 20, 166}: "Yichun MyEnergy Domain, Inc", + [3]byte{204, 24, 123}: "Manzanita Systems, Inc.", + [3]byte{204, 26, 250}: "zte corporation", + [3]byte{204, 30, 255}: "Metrological Group BV", + [3]byte{204, 34, 24}: "InnoDigital Co., Ltd.", + [3]byte{204, 38, 45}: "Verifi, LLC", + [3]byte{204, 42, 128}: "Micro-Biz intelligence solutions Co.,Ltd", + [3]byte{204, 45, 140}: "LG ELECTRONICS INC", + [3]byte{204, 48, 128}: "VAIO Corporation", + [3]byte{204, 51, 187}: "SAGEMCOM SAS", + [3]byte{204, 52, 41}: "TP-LINK TECHNOLOGIES CO.,LTD.", + [3]byte{204, 52, 215}: "GEWISS S.P.A.", + [3]byte{204, 53, 64}: "Technicolor USA Inc.", + [3]byte{204, 57, 140}: "Shiningtek", + [3]byte{204, 58, 97}: "SAMSUNG ELECTRO MECHANICS CO., LTD.", + [3]byte{204, 60, 63}: "SA.S.S. Datentechnik AG", + [3]byte{204, 61, 130}: "Intel Corporate", + [3]byte{204, 62, 95}: "Hewlett Packard", + [3]byte{204, 63, 29}: "Intesis Software SL", + [3]byte{204, 67, 227}: "Trump s.a.", + [3]byte{204, 71, 3}: "Intercon Systems Co., Ltd.", + [3]byte{204, 74, 225}: "Fourtec -Fourier Technologies", + [3]byte{204, 75, 251}: "Hellberg Safety AB", + [3]byte{204, 78, 36}: "Brocade Communications Systems, Inc.", + [3]byte{204, 80, 28}: "KVH Industries, Inc.", + [3]byte{204, 80, 118}: "Ocom Communications, Inc.", + [3]byte{204, 82, 175}: "Universal Global Scientific Industrial Co., Ltd.", + [3]byte{204, 83, 181}: "HUAWEI TECHNOLOGIES CO.,LTD", + [3]byte{204, 84, 89}: "OnTime Networks AS", + [3]byte{204, 85, 173}: "RIM", + [3]byte{204, 89, 62}: "TOUMAZ LTD", + [3]byte{204, 92, 117}: "Weightech Com. Imp. Exp. Equip. Pesagem Ltda", + [3]byte{204, 93, 78}: "ZyXEL Communications Corporation", + [3]byte{204, 93, 87}: "Information System Research Institute,Inc.", + [3]byte{204, 96, 187}: "Empower RF Systems", + [3]byte{204, 101, 173}: "ARRIS Group, Inc.", + [3]byte{204, 105, 176}: "Global Traffic Technologies, LLC", + [3]byte{204, 107, 152}: "Minetec Wireless Technologies", + [3]byte{204, 107, 241}: "Sound Masking Inc.", + [3]byte{204, 109, 160}: "Roku, Inc.", + [3]byte{204, 109, 239}: "TJK Tietolaite Oy", + [3]byte{204, 114, 15}: "Viscount Systems Inc.", + [3]byte{204, 116, 152}: "Filmetrics Inc.", + [3]byte{204, 118, 105}: "SEETECH", + [3]byte{204, 120, 95}: "Apple", + [3]byte{204, 122, 48}: "CMAX Wireless Co., Ltd.", + [3]byte{204, 123, 53}: "zte corporation", + [3]byte{204, 125, 55}: "ARRIS Group, Inc.", + [3]byte{204, 126, 231}: "Panasonic AVC Networks Company", + [3]byte{204, 133, 108}: "SHENZHEN MDK DIGITAL TECHNOLOGY CO.,LTD", + [3]byte{204, 137, 253}: "Nokia Corporation", + [3]byte{204, 140, 227}: "Texas Instruments", + [3]byte{204, 144, 147}: "Hansong Tehnologies", + [3]byte{204, 145, 43}: "TE Connectivity Touch Solutions", + [3]byte{204, 148, 74}: "Pfeiffer Vacuum GmbH", + [3]byte{204, 149, 215}: "VIZIO, Inc", + [3]byte{204, 150, 160}: "Shenzhen Huawei Communication Technologies Co., Ltd", + [3]byte{204, 158, 0}: "Nintendo Co., Ltd.", + [3]byte{204, 159, 53}: "Transbit Sp. z o.o.", + [3]byte{204, 160, 229}: "DZG Metering GmbH", + [3]byte{204, 162, 35}: "Huawei Technologies Co., Ltd", + [3]byte{204, 163, 116}: "Guangdong Guanglian Electronic Technology Co.Ltd", + [3]byte{204, 164, 98}: "ARRIS Group, Inc.", + [3]byte{204, 166, 20}: "AIFA TECHNOLOGY CORP.", + [3]byte{204, 175, 120}: "Hon Hai Precision Ind. Co.,Ltd.", + [3]byte{204, 178, 85}: "D-Link International", + [3]byte{204, 179, 248}: "FUJITSU ISOTEC LIMITED", + [3]byte{204, 181, 90}: "Fraunhofer ITWM", + [3]byte{204, 182, 145}: "NECMagnusCommunications", + [3]byte{204, 184, 136}: "AnB Securite s.a.", + [3]byte{204, 184, 241}: "EAGLE KINGDOM TECHNOLOGIES LIMITED", + [3]byte{204, 189, 53}: "Steinel GmbH", + [3]byte{204, 189, 211}: "Ultimaker B.V.", + [3]byte{204, 190, 113}: "OptiLogix BV", + [3]byte{204, 193, 4}: "Applied Technical Systems", + [3]byte{204, 195, 234}: "Motorola Mobility LLC", + [3]byte{204, 197, 10}: "SHENZHEN DAJIAHAO TECHNOLOGY CO.,LTD", + [3]byte{204, 198, 43}: "Tri-Systems Corporation", + [3]byte{204, 200, 215}: "CIAS Elettronica srl", + [3]byte{204, 204, 78}: "Sun Fountainhead USA. Corp", + [3]byte{204, 204, 129}: "HUAWEI TECHNOLOGIES CO.,LTD", + [3]byte{204, 205, 100}: "SM-Electronic GmbH", + [3]byte{204, 206, 64}: "Janteq Corp", + [3]byte{204, 210, 155}: "Shenzhen Bopengfa Elec&Technology CO.,Ltd", + [3]byte{204, 213, 57}: "Cisco", + [3]byte{204, 216, 17}: "Aiconn Technology Corporation", + [3]byte{204, 216, 193}: "Cisco", + [3]byte{204, 217, 233}: "SCR Engineers Ltd.", + [3]byte{204, 225, 127}: "juniper networks", + [3]byte{204, 225, 213}: "Buffalo Inc.", + [3]byte{204, 231, 152}: "My Social Stuff", + [3]byte{204, 231, 223}: "American Magnetics, Inc.", + [3]byte{204, 232, 172}: "SOYEA Technology Co.,Ltd.", + [3]byte{204, 234, 28}: "DCONWORKS Co., Ltd", + [3]byte{204, 238, 217}: "Deto Mechatronic GmbH", + [3]byte{204, 239, 72}: "CISCO SYSTEMS, INC.", + [3]byte{204, 243, 165}: "Chi Mei Communication Systems, Inc", + [3]byte{204, 244, 7}: "EUKREA ELECTROMATIQUE SARL", + [3]byte{204, 245, 56}: "3isysnetworks", + [3]byte{204, 246, 122}: "Ayecka Communication Systems LTD", + [3]byte{204, 248, 65}: "Lumewave", + [3]byte{204, 248, 240}: "Xi'an HISU Multimedia Technology Co.,Ltd.", + [3]byte{204, 249, 84}: "Avaya, Inc", + [3]byte{204, 249, 232}: "Samsung Electronics Co.,Ltd", + [3]byte{204, 250, 0}: "LG Electronics", + [3]byte{204, 251, 101}: "Nintendo Co., Ltd.", + [3]byte{204, 252, 109}: "RIZ TRANSMITTERS", + [3]byte{204, 252, 177}: "Wireless Technology, Inc.", + [3]byte{204, 254, 60}: "Samsung Electronics", + [3]byte{208, 7, 144}: "Texas Instruments", + [3]byte{208, 10, 171}: "Yokogawa Digital Computer Corporation", + [3]byte{208, 14, 164}: "Porsche Cars North America", + [3]byte{208, 18, 66}: "BIOS Corporation", + [3]byte{208, 19, 30}: "Sunrex Technology Corp", + [3]byte{208, 21, 74}: "zte corporation", + [3]byte{208, 23, 106}: "Samsung Electronics Co.,Ltd", + [3]byte{208, 26, 167}: "UniPrint", + [3]byte{208, 28, 187}: "Beijing Ctimes Digital Technology Co., Ltd.", + [3]byte{208, 34, 18}: "IEEE REGISTRATION AUTHORITY - Please see MAM public listing for more information.", + [3]byte{208, 34, 190}: "Samsung Electro Mechanics co.,LTD.", + [3]byte{208, 35, 219}: "Apple", + [3]byte{208, 39, 136}: "Hon Hai Precision Ind.Co.Ltd", + [3]byte{208, 44, 69}: "littleBits Electronics, Inc.", + [3]byte{208, 45, 179}: "Huawei Technologies Co., Ltd", + [3]byte{208, 49, 16}: "Ingenic Semiconductor Co.,Ltd", + [3]byte{208, 55, 97}: "Texas Instruments", + [3]byte{208, 57, 114}: "Texas Instruments", + [3]byte{208, 57, 179}: "ARRIS Group, Inc.", + [3]byte{208, 70, 220}: "Southwest Research Institute", + [3]byte{208, 76, 193}: "SINTRONES Technology Corp.", + [3]byte{208, 79, 126}: "Apple", + [3]byte{208, 80, 153}: "ASRock Incorporation", + [3]byte{208, 81, 98}: "Sony Mobile Communications AB", + [3]byte{208, 82, 168}: "Physical Graph Corporation", + [3]byte{208, 84, 45}: "Cambridge Industries(Group) Co.,Ltd.", + [3]byte{208, 87, 76}: "CISCO SYSTEMS, INC.", + [3]byte{208, 87, 133}: "Pantech Co., Ltd.", + [3]byte{208, 87, 161}: "Werma Signaltechnik GmbH & Co. KG", + [3]byte{208, 88, 117}: "Active Control Technology Inc.", + [3]byte{208, 89, 195}: "CeraMicro Technology Corporation", + [3]byte{208, 89, 228}: "Samsung Electronics Co.,Ltd", + [3]byte{208, 90, 15}: "I-BT DIGITAL CO.,LTD", + [3]byte{208, 90, 241}: "Shenzhen Pulier Tech CO.,Ltd", + [3]byte{208, 91, 168}: "zte corporation", + [3]byte{208, 95, 184}: "Texas Instruments", + [3]byte{208, 95, 206}: "Hitachi Data Systems", + [3]byte{208, 98, 160}: "China Essence Technology (Zhumadian) Co., Ltd.", + [3]byte{208, 99, 77}: "Meiko Maschinenbau GmbH & Co. KG", + [3]byte{208, 99, 180}: "SolidRun Ltd.", + [3]byte{208, 102, 123}: "Samsung Electronics Co., LTD", + [3]byte{208, 103, 229}: "Dell Inc", + [3]byte{208, 105, 158}: "LUMINEX Lighting Control Equipment", + [3]byte{208, 105, 208}: "Verto Medical Solutions, LLC", + [3]byte{208, 114, 220}: "Cisco", + [3]byte{208, 115, 127}: "Mini-Circuits", + [3]byte{208, 115, 142}: "DONG OH PRECISION CO., LTD.", + [3]byte{208, 115, 213}: "LIFI LABS MANAGEMENT PTY LTD", + [3]byte{208, 117, 190}: "Reno A&E", + [3]byte{208, 118, 80}: "IEEE REGISTRATION AUTHORITY - Please see MAM public listing for more information.", + [3]byte{208, 122, 181}: "Huawei Technologies Co., Ltd", + [3]byte{208, 125, 229}: "Forward Pay Systems, Inc.", + [3]byte{208, 126, 40}: "Hewlett Packard", + [3]byte{208, 126, 53}: "Intel Corporate", + [3]byte{208, 132, 176}: "Sagemcom", + [3]byte{208, 137, 153}: "APCON, Inc.", + [3]byte{208, 138, 85}: "Skullcandy", + [3]byte{208, 139, 126}: "Passif Semiconductor", + [3]byte{208, 140, 181}: "Texas Instruments", + [3]byte{208, 140, 255}: "UPWIS AB", + [3]byte{208, 147, 248}: "Stonestreet One LLC", + [3]byte{208, 149, 199}: "Pantech Co., Ltd.", + [3]byte{208, 155, 5}: "Emtronix", + [3]byte{208, 156, 48}: "Foster Electric Company, Limited", + [3]byte{208, 157, 10}: "LINKCOM", + [3]byte{208, 160, 214}: "Chengdu TD Tech Ltd.", + [3]byte{208, 163, 17}: "Neuberger Gebäudeautomation GmbH", + [3]byte{208, 174, 236}: "Alpha Networks Inc.", + [3]byte{208, 175, 182}: "Linktop Technology Co., LTD", + [3]byte{208, 179, 63}: "SHENZHEN TINNO MOBILE TECHNOLOGY CO.,LTD.", + [3]byte{208, 180, 152}: "Robert Bosch LLC Automotive Electronics", + [3]byte{208, 181, 35}: "Bestcare Cloucal Corp.", + [3]byte{208, 181, 61}: "SEPRO ROBOTIQUE", + [3]byte{208, 187, 128}: "SHL Telemedicine International Ltd.", + [3]byte{208, 189, 1}: "DS International", + [3]byte{208, 190, 44}: "CNSLink Co., Ltd.", + [3]byte{208, 193, 177}: "Samsung Electronics Co.,Ltd", + [3]byte{208, 194, 130}: "CISCO SYSTEMS, INC.", + [3]byte{208, 196, 47}: "Tamagawa Seiki Co.,Ltd.", + [3]byte{208, 199, 137}: "Cisco", + [3]byte{208, 199, 192}: "TP-LINK TECHNOLOGIES CO.,LTD.", + [3]byte{208, 205, 225}: "Scientech Electronics", + [3]byte{208, 207, 94}: "Energy Micro AS", + [3]byte{208, 208, 253}: "CISCO SYSTEMS, INC.", + [3]byte{208, 210, 18}: "K2NET Co.,Ltd.", + [3]byte{208, 210, 134}: "Beckman Coulter K.K.", + [3]byte{208, 211, 252}: "Mios, Ltd.", + [3]byte{208, 212, 18}: "ADB Broadband Italia", + [3]byte{208, 212, 113}: "MVTECH co., Ltd", + [3]byte{208, 214, 204}: "Wintop", + [3]byte{208, 219, 50}: "Nokia Corporation", + [3]byte{208, 223, 154}: "Liteon Technology Corporation", + [3]byte{208, 223, 178}: "Genie Networks Limited", + [3]byte{208, 223, 199}: "Samsung Electronics Co.,Ltd", + [3]byte{208, 225, 64}: "Apple, Inc", + [3]byte{208, 227, 71}: "Yoga", + [3]byte{208, 228, 11}: "Wearable Inc.", + [3]byte{208, 229, 77}: "Pace plc", + [3]byte{208, 231, 130}: "Azurewave Technologies, Inc.", + [3]byte{208, 235, 3}: "Zhehua technology limited", + [3]byte{208, 235, 158}: "Seowoo Inc.", + [3]byte{208, 240, 219}: "Ericsson", + [3]byte{208, 242, 127}: "SteadyServ Technoligies, LLC", + [3]byte{208, 247, 59}: "Helmut Mauell GmbH", + [3]byte{208, 250, 29}: "Qihoo 360 Technology Co.,Ltd", + [3]byte{208, 255, 80}: "Texas Instruments, Inc", + [3]byte{212, 0, 13}: "Phoenix Broadband Technologies, LLC.", + [3]byte{212, 0, 87}: "MC Technologies GmbH", + [3]byte{212, 1, 41}: "Broadcom Corporation", + [3]byte{212, 1, 109}: "TP-LINK TECHNOLOGIES CO.,LTD.", + [3]byte{212, 2, 74}: "Delphian Systems LLC", + [3]byte{212, 11, 185}: "Solid Semecs bv.", + [3]byte{212, 15, 178}: "Applied Micro Electronics AME bv", + [3]byte{212, 16, 144}: "iNFORM Systems AG", + [3]byte{212, 16, 207}: "Huanshun Network Science and Technology Co., Ltd.", + [3]byte{212, 17, 214}: "ShotSpotter, Inc.", + [3]byte{212, 18, 150}: "Anobit Technologies Ltd.", + [3]byte{212, 18, 187}: "Quadrant Components Inc. Ltd", + [3]byte{212, 19, 111}: "Asia Pacific Brands", + [3]byte{212, 28, 28}: "RCF S.P.A.", + [3]byte{212, 30, 53}: "TOHO Electronics INC.", + [3]byte{212, 31, 12}: "TVI Vision Oy", + [3]byte{212, 32, 109}: "HTC Corporation", + [3]byte{212, 33, 34}: "Sercomm Corporation", + [3]byte{212, 34, 63}: "Lenovo Mobile Communication Technology Ltd.", + [3]byte{212, 34, 78}: "Alcatel Lucent", + [3]byte{212, 39, 81}: "Infopia Co., Ltd", + [3]byte{212, 40, 178}: "ioBridge, Inc.", + [3]byte{212, 41, 234}: "Zimory GmbH", + [3]byte{212, 44, 61}: "Sky Light Digital Limited", + [3]byte{212, 47, 35}: "Akenori PTE Ltd", + [3]byte{212, 49, 157}: "Sinwatec", + [3]byte{212, 50, 102}: "Fike Corporation", + [3]byte{212, 55, 215}: "zte corporation", + [3]byte{212, 58, 101}: "IGRS Engineering Lab Ltd.", + [3]byte{212, 58, 233}: "DONGGUAN ipt INDUSTRIAL CO., LTD", + [3]byte{212, 61, 103}: "Carma Industries Inc.", + [3]byte{212, 61, 126}: "Micro-Star Int'l Co, Ltd", + [3]byte{212, 67, 168}: "Changzhou Haojie Electric Co., Ltd.", + [3]byte{212, 75, 94}: "TAIYO YUDEN CO., LTD.", + [3]byte{212, 76, 36}: "Vuppalamritha Magnetic Components LTD", + [3]byte{212, 76, 156}: "Shenzhen YOOBAO Technology Co.Ltd", + [3]byte{212, 76, 167}: "Informtekhnika & Communication, LLC", + [3]byte{212, 79, 128}: "Kemper Digital GmbH", + [3]byte{212, 80, 122}: "CEIVA Logic, Inc", + [3]byte{212, 82, 81}: "IBT Ingenieurbureau Broennimann Thun", + [3]byte{212, 82, 151}: "nSTREAMS Technologies, Inc.", + [3]byte{212, 83, 175}: "VIGO System S.A.", + [3]byte{212, 90, 178}: "Galleon Systems", + [3]byte{212, 92, 112}: "Wi-Fi Alliance", + [3]byte{212, 93, 66}: "Nokia Corporation", + [3]byte{212, 97, 50}: "Pro Concept Manufacturer Co.,Ltd.", + [3]byte{212, 100, 247}: "CHENGDU USEE DIGITAL TECHNOLOGY CO., LTD", + [3]byte{212, 102, 168}: "Riedo Networks GmbH", + [3]byte{212, 103, 97}: "SAHAB TECHNOLOGY", + [3]byte{212, 103, 231}: "Fiberhome Telecommunication Tech.Co.,Ltd.", + [3]byte{212, 104, 103}: "Neoventus Design Group", + [3]byte{212, 106, 145}: "Snap AV", + [3]byte{212, 106, 168}: "HUAWEI TECHNOLOGIES CO.,LTD", + [3]byte{212, 108, 191}: "Goodrich ISR", + [3]byte{212, 108, 218}: "CSM GmbH", + [3]byte{212, 110, 92}: "Huawei Technologies Co., Ltd", + [3]byte{212, 111, 66}: "WAXESS USA Inc", + [3]byte{212, 121, 195}: "Cameronet GmbH & Co. KG", + [3]byte{212, 123, 53}: "NEO Monitors AS", + [3]byte{212, 123, 117}: "HARTING Electronics GmbH", + [3]byte{212, 129, 202}: "iDevices, LLC", + [3]byte{212, 130, 62}: "Argosy Technologies, Ltd.", + [3]byte{212, 133, 100}: "Hewlett-Packard Company", + [3]byte{212, 135, 216}: "Samsung Electronics", + [3]byte{212, 136, 144}: "Samsung Electronics Co.,Ltd", + [3]byte{212, 140, 181}: "CISCO SYSTEMS, INC.", + [3]byte{212, 141, 217}: "Meld Technology, Inc", + [3]byte{212, 143, 51}: "Microsoft Corporation", + [3]byte{212, 143, 170}: "Sogecam Industrial, S.A.", + [3]byte{212, 145, 175}: "Electroacustica General Iberica, S.A.", + [3]byte{212, 147, 152}: "Nokia Corporation", + [3]byte{212, 147, 160}: "Fidelix Oy", + [3]byte{212, 148, 90}: "COSMO CO., LTD", + [3]byte{212, 148, 161}: "Texas Instruments", + [3]byte{212, 149, 36}: "Clover Network, Inc.", + [3]byte{212, 150, 223}: "SUNGJIN C&T CO.,LTD", + [3]byte{212, 151, 11}: "XIAOMI CORPORATION", + [3]byte{212, 154, 32}: "Apple", + [3]byte{212, 156, 40}: "JayBird Gear LLC", + [3]byte{212, 156, 142}: "University of FUKUI", + [3]byte{212, 158, 109}: "Wuhan Zhongyuan Huadian Science & Technology Co.,", + [3]byte{212, 160, 42}: "CISCO SYSTEMS, INC.", + [3]byte{212, 164, 37}: "SMAX Technology Co., Ltd.", + [3]byte{212, 164, 153}: "InView Technology Corporation", + [3]byte{212, 169, 40}: "GreenWave Reality Inc", + [3]byte{212, 170, 255}: "MICRO WORLD", + [3]byte{212, 172, 78}: "BODi rS, LLC", + [3]byte{212, 173, 45}: "Fiberhome Telecommunication Tech.Co.,Ltd.", + [3]byte{212, 174, 82}: "Dell Inc", + [3]byte{212, 177, 16}: "HUAWEI TECHNOLOGIES CO.,LTD", + [3]byte{212, 180, 62}: "Messcomp Datentechnik GmbH", + [3]byte{212, 190, 217}: "Dell Inc", + [3]byte{212, 191, 45}: "SE Controls Asia Pacific Ltd", + [3]byte{212, 191, 127}: "UPVEL", + [3]byte{212, 193, 252}: "Nokia Corporation", + [3]byte{212, 199, 102}: "Acentic GmbH", + [3]byte{212, 201, 239}: "Hewlett Packard", + [3]byte{212, 202, 109}: "Routerboard.com", + [3]byte{212, 202, 110}: "u-blox AG", + [3]byte{212, 203, 175}: "Nokia Corporation", + [3]byte{212, 206, 184}: "Enatel LTD", + [3]byte{212, 207, 249}: "Shenzhen Sen5 Technology Co., Ltd.", + [3]byte{212, 209, 132}: "ADB Broadband Italia", + [3]byte{212, 210, 73}: "Power Ethernet", + [3]byte{212, 213, 13}: "Southwest Microwave, Inc", + [3]byte{212, 215, 72}: "CISCO SYSTEMS, INC.", + [3]byte{212, 216, 152}: "Korea CNO Tech Co., Ltd", + [3]byte{212, 217, 25}: "GoPro", + [3]byte{212, 223, 87}: "Alpinion Medical Systems", + [3]byte{212, 224, 142}: "ValueHD Corporation", + [3]byte{212, 227, 44}: "S. Siedle & Sohne", + [3]byte{212, 227, 63}: "Alcatel-Lucent", + [3]byte{212, 232, 178}: "Samsung Electronics", + [3]byte{212, 234, 14}: "Avaya, Inc", + [3]byte{212, 236, 12}: "Harley-Davidson Motor Company", + [3]byte{212, 236, 134}: "LinkedHope Intelligent Technologies Co., Ltd", + [3]byte{212, 238, 7}: "HIWIFI Co., Ltd.", + [3]byte{212, 240, 39}: "Navetas Energy Management", + [3]byte{212, 240, 180}: "Napco Security Technologies", + [3]byte{212, 241, 67}: "IPROAD.,Inc", + [3]byte{212, 244, 111}: "Apple", + [3]byte{212, 245, 19}: "Texas Instruments", + [3]byte{212, 246, 63}: "IEA S.R.L.", + [3]byte{216, 0, 77}: "Apple", + [3]byte{216, 5, 46}: "Skyviia Corporation", + [3]byte{216, 6, 209}: "Honeywell Fire System (Shanghai) Co,. Ltd.", + [3]byte{216, 8, 245}: "Arcadia Networks Co. Ltd.", + [3]byte{216, 9, 195}: "Cercacor Labs", + [3]byte{216, 12, 207}: "C.G.V. S.A.S.", + [3]byte{216, 13, 227}: "FXI TECHNOLOGIES AS", + [3]byte{216, 21, 13}: "TP-LINK TECHNOLOGIES CO.,LTD.", + [3]byte{216, 22, 10}: "Nippon Electro-Sensory Devices", + [3]byte{216, 24, 43}: "Conti Temic Microelectronic GmbH", + [3]byte{216, 25, 206}: "Telesquare", + [3]byte{216, 27, 254}: "TWINLINX CORPORATION", + [3]byte{216, 28, 20}: "Compacta International, Ltd.", + [3]byte{216, 30, 222}: "B&W Group Ltd", + [3]byte{216, 36, 189}: "CISCO SYSTEMS, INC.", + [3]byte{216, 37, 34}: "Pace plc", + [3]byte{216, 38, 185}: "Guangdong Coagent Electronics S &T Co., Ltd.", + [3]byte{216, 39, 12}: "MaxTronic International Co., Ltd.", + [3]byte{216, 40, 201}: "General Electric Consumer and Industrial", + [3]byte{216, 41, 22}: "Ascent Communication Technology", + [3]byte{216, 41, 134}: "Best Wish Technology LTD", + [3]byte{216, 42, 21}: "Leitner SpA", + [3]byte{216, 42, 126}: "Nokia Corporation", + [3]byte{216, 45, 155}: "Shenzhen G.Credit Communication Technology Co., Ltd", + [3]byte{216, 45, 225}: "Tricascade Inc.", + [3]byte{216, 48, 98}: "Apple", + [3]byte{216, 49, 207}: "Samsung Electronics Co.,Ltd", + [3]byte{216, 51, 127}: "Office FA.com Co.,Ltd.", + [3]byte{216, 60, 105}: "Tinno Mobile Technology Corp", + [3]byte{216, 66, 172}: "Shanghai Feixun Communication Co.,Ltd.", + [3]byte{216, 70, 6}: "Silicon Valley Global Marketing", + [3]byte{216, 73, 11}: "HUAWEI TECHNOLOGIES CO.,LTD", + [3]byte{216, 73, 47}: "CANON INC.", + [3]byte{216, 74, 135}: "OI ELECTRIC CO.,LTD", + [3]byte{216, 75, 42}: "Cognitas Technologies, Inc.", + [3]byte{216, 80, 230}: "ASUSTek COMPUTER INC.", + [3]byte{216, 84, 58}: "Texas Instruments", + [3]byte{216, 87, 239}: "Samsung Electronics", + [3]byte{216, 88, 215}: "CZ.NIC, z.s.p.o.", + [3]byte{216, 93, 76}: "TP-LINK Technologies Co.,Ltd.", + [3]byte{216, 93, 132}: "CAx soft GmbH", + [3]byte{216, 93, 251}: "PRIVATE", + [3]byte{216, 97, 148}: "Objetivos y Sevicios de Valor Añadido", + [3]byte{216, 98, 219}: "Eno Inc.", + [3]byte{216, 101, 149}: "Toy's Myth Inc.", + [3]byte{216, 102, 198}: "Shenzhen Daystar Technology Co.,ltd", + [3]byte{216, 102, 238}: "BOXIN COMMUNICATION CO.,LTD.", + [3]byte{216, 103, 217}: "CISCO SYSTEMS, INC.", + [3]byte{216, 105, 96}: "Steinsvik", + [3]byte{216, 107, 247}: "Nintendo Co., Ltd.", + [3]byte{216, 108, 233}: "SAGEMCOM SAS", + [3]byte{216, 113, 87}: "Lenovo Mobile Communication Technology Ltd.", + [3]byte{216, 117, 51}: "Nokia Corporation", + [3]byte{216, 118, 10}: "Escort, Inc.", + [3]byte{216, 120, 229}: "KUHN SA", + [3]byte{216, 121, 136}: "Hon Hai Precision Ind. Co., Ltd.", + [3]byte{216, 124, 221}: "SANIX INCORPORATED", + [3]byte{216, 126, 177}: "x.o.ware, inc.", + [3]byte{216, 128, 57}: "Microchip Technology Inc.", + [3]byte{216, 129, 206}: "AHN INC.", + [3]byte{216, 132, 102}: "Extreme Networks", + [3]byte{216, 138, 59}: "UNIT-EM", + [3]byte{216, 144, 232}: "Samsung Electronics Co.,Ltd", + [3]byte{216, 149, 47}: "Texas Instruments", + [3]byte{216, 150, 133}: "GoPro", + [3]byte{216, 150, 149}: "Apple", + [3]byte{216, 150, 224}: "Alibaba Cloud Computing Ltd.", + [3]byte{216, 151, 59}: "Artesyn Embedded Technologies", + [3]byte{216, 151, 96}: "C2 Development, Inc.", + [3]byte{216, 151, 124}: "Grey Innovation", + [3]byte{216, 151, 186}: "PEGATRON CORPORATION", + [3]byte{216, 157, 103}: "Hewlett Packard", + [3]byte{216, 157, 185}: "eMegatech International Corp.", + [3]byte{216, 158, 63}: "Apple", + [3]byte{216, 162, 94}: "Apple", + [3]byte{216, 174, 144}: "Itibia Technologies", + [3]byte{216, 175, 59}: "Hangzhou Bigbright Integrated communications system Co.,Ltd", + [3]byte{216, 175, 241}: "Panasonic Appliances Company", + [3]byte{216, 176, 46}: "Guangzhou Zonerich Business Machine Co., Ltd", + [3]byte{216, 176, 76}: "Jinan USR IOT Technology Co., Ltd.", + [3]byte{216, 177, 42}: "Panasonic Mobile Communications Co., Ltd.", + [3]byte{216, 179, 119}: "HTC Corporation", + [3]byte{216, 182, 183}: "Comtrend Corporation", + [3]byte{216, 182, 193}: "NetworkAccountant, Inc.", + [3]byte{216, 182, 214}: "Blu Tether Limited", + [3]byte{216, 184, 246}: "Nantworks", + [3]byte{216, 185, 14}: "Triple Domain Vision Co.,Ltd.", + [3]byte{216, 187, 44}: "Apple", + [3]byte{216, 191, 76}: "Victory Concept Electronics Limited", + [3]byte{216, 192, 104}: "Netgenetech.co.,ltd.", + [3]byte{216, 195, 251}: "DETRACOM", + [3]byte{216, 198, 145}: "Hichan Technology Corp.", + [3]byte{216, 199, 200}: "Aruba Networks", + [3]byte{216, 201, 157}: "EA DISPLAY LIMITED", + [3]byte{216, 203, 138}: "Micro-Star INTL CO., LTD.", + [3]byte{216, 207, 156}: "Apple", + [3]byte{216, 209, 203}: "Apple", + [3]byte{216, 210, 124}: "JEMA ENERGY, SA", + [3]byte{216, 211, 133}: "Hewlett-Packard Company", + [3]byte{216, 212, 60}: "Sony Corporation", + [3]byte{216, 213, 185}: "Rainforest Automation, Inc.", + [3]byte{216, 214, 126}: "GSK CNC EQUIPMENT CO.,LTD", + [3]byte{216, 218, 82}: "APATOR S.A.", + [3]byte{216, 220, 233}: "Kunshan Erlab ductless filtration system Co.,Ltd", + [3]byte{216, 221, 95}: "BALMUDA Inc.", + [3]byte{216, 221, 253}: "Texas Instruments", + [3]byte{216, 222, 206}: "ISUNG CO.,LTD", + [3]byte{216, 223, 13}: "beroNet GmbH", + [3]byte{216, 227, 174}: "CIRTEC MEDICAL SYSTEMS", + [3]byte{216, 229, 109}: "TCT Mobile Limited", + [3]byte{216, 231, 43}: "NetScout Systems, Inc.", + [3]byte{216, 231, 67}: "Wush, Inc", + [3]byte{216, 233, 82}: "KEOPSYS", + [3]byte{216, 235, 151}: "TRENDnet, Inc.", + [3]byte{216, 238, 120}: "Moog Protokraft", + [3]byte{216, 240, 242}: "Zeebo Inc", + [3]byte{216, 247, 16}: "Libre Wireless Technologies Inc.", + [3]byte{216, 251, 17}: "AXACORE", + [3]byte{216, 252, 147}: "Intel Corporate", + [3]byte{216, 254, 143}: "IDFone Co., Ltd.", + [3]byte{216, 254, 227}: "D-Link International", + [3]byte{220, 2, 101}: "Meditech Kft", + [3]byte{220, 2, 142}: "zte corporation", + [3]byte{220, 5, 47}: "National Products Inc.", + [3]byte{220, 5, 117}: "SIEMENS ENERGY AUTOMATION", + [3]byte{220, 5, 237}: "Nabtesco Corporation", + [3]byte{220, 7, 193}: "HangZhou QiYang Technology Co.,Ltd.", + [3]byte{220, 11, 26}: "ADB Broadband Italia", + [3]byte{220, 14, 161}: "COMPAL INFORMATION (KUNSHAN) CO., LTD", + [3]byte{220, 22, 162}: "Medtronic Diabetes", + [3]byte{220, 23, 90}: "Hitachi High-Technologies Corporation", + [3]byte{220, 23, 146}: "Captivate Network", + [3]byte{220, 29, 159}: "U & B tech", + [3]byte{220, 29, 212}: "Microstep-MIS spol. s r.o.", + [3]byte{220, 30, 163}: "Accensus LLC", + [3]byte{220, 32, 8}: "ASD Electronics Ltd", + [3]byte{220, 42, 20}: "Shanghai Longjing Technology Co.", + [3]byte{220, 43, 97}: "Apple", + [3]byte{220, 43, 102}: "InfoBLOCK S.A. de C.V.", + [3]byte{220, 43, 202}: "Zera GmbH", + [3]byte{220, 44, 38}: "Iton Technology Limited", + [3]byte{220, 46, 106}: "HCT. Co., Ltd.", + [3]byte{220, 47, 3}: "Step forward Group Co., Ltd.", + [3]byte{220, 48, 156}: "Heyrex Limited", + [3]byte{220, 51, 80}: "TechSAT GmbH", + [3]byte{220, 55, 210}: "Hunan HKT Electronic Technology Co., Ltd", + [3]byte{220, 56, 225}: "Juniper networks", + [3]byte{220, 57, 121}: "Skyport Systems", + [3]byte{220, 58, 94}: "Roku, Inc", + [3]byte{220, 60, 46}: "Manufacturing System Insights, Inc.", + [3]byte{220, 60, 132}: "Ticom Geomatics, Inc.", + [3]byte{220, 62, 81}: "Solberg & Andersen AS", + [3]byte{220, 62, 248}: "Nokia Corporation", + [3]byte{220, 69, 23}: "ARRIS Group, Inc.", + [3]byte{220, 73, 201}: "CASCO SIGNAL LTD", + [3]byte{220, 78, 222}: "SHINYEI TECHNOLOGY CO., LTD.", + [3]byte{220, 83, 124}: "Compal Broadband Networks, Inc.", + [3]byte{220, 87, 38}: "Power-One", + [3]byte{220, 94, 54}: "Paterson Technology", + [3]byte{220, 100, 124}: "C.R.S. iiMotion GmbH", + [3]byte{220, 102, 58}: "Apacer Technology Inc.", + [3]byte{220, 111, 0}: "Livescribe, Inc.", + [3]byte{220, 111, 8}: "Bay Storage Technology", + [3]byte{220, 112, 20}: "PRIVATE", + [3]byte{220, 113, 68}: "Samsung Electro Mechanics", + [3]byte{220, 123, 148}: "CISCO SYSTEMS, INC.", + [3]byte{220, 130, 91}: "JANUS, spol. s r.o.", + [3]byte{220, 133, 222}: "Azurewave Technologies., inc.", + [3]byte{220, 134, 216}: "Apple, Inc", + [3]byte{220, 155, 30}: "Intercom, Inc.", + [3]byte{220, 155, 156}: "Apple", + [3]byte{220, 156, 82}: "Sapphire Technology Limited.", + [3]byte{220, 159, 164}: "Nokia Corporation", + [3]byte{220, 159, 219}: "Ubiquiti Networks, Inc.", + [3]byte{220, 165, 244}: "Cisco", + [3]byte{220, 166, 189}: "Beijing Lanbo Technology Co., Ltd.", + [3]byte{220, 167, 217}: "Compressor Controls Corp", + [3]byte{220, 168, 207}: "New Spin Golf, LLC.", + [3]byte{220, 169, 113}: "Intel Corporate", + [3]byte{220, 169, 137}: "MACANDC", + [3]byte{220, 173, 158}: "GreenPriz", + [3]byte{220, 174, 4}: "CELOXICA Ltd", + [3]byte{220, 176, 88}: "Burkert Werke GmbH", + [3]byte{220, 180, 196}: "Microsoft XCG", + [3]byte{220, 191, 144}: "HUIZHOU QIAOXING TELECOMMUNICATION INDUSTRY CO.,LTD.", + [3]byte{220, 192, 219}: "Shenzhen Kaiboer Technology Co., Ltd.", + [3]byte{220, 193, 1}: "SOLiD Technologies, Inc.", + [3]byte{220, 196, 34}: "Systembase Limited", + [3]byte{220, 198, 34}: "BUHEUNG SYSTEM", + [3]byte{220, 199, 147}: "Nokia Corporation", + [3]byte{220, 203, 168}: "Explora Technologies Inc", + [3]byte{220, 206, 65}: "FE GLOBAL HONG KONG LIMITED", + [3]byte{220, 206, 188}: "Shenzhen JSR Technology Co.,Ltd.", + [3]byte{220, 207, 148}: "Beijing Rongcheng Hutong Technology Co., Ltd.", + [3]byte{220, 208, 247}: "Bentek Systems Ltd.", + [3]byte{220, 210, 252}: "HUAWEI TECHNOLOGIES CO.,LTD", + [3]byte{220, 211, 33}: "HUMAX co.,tld", + [3]byte{220, 213, 42}: "Sunny Heart Limited", + [3]byte{220, 216, 127}: "Shenzhen JoinCyber Telecom Equipment Ltd", + [3]byte{220, 218, 79}: "GETCK TECHNOLOGY, INC", + [3]byte{220, 222, 202}: "Akyllor", + [3]byte{220, 226, 172}: "Lumens Digital Optics Inc.", + [3]byte{220, 229, 120}: "Experimental Factory of Scientific Engineering and Special Design Department", + [3]byte{220, 231, 28}: "AUG Elektronik GmbH", + [3]byte{220, 236, 6}: "Heimi Network Technology Co., Ltd.", + [3]byte{220, 240, 93}: "Letta Teknoloji", + [3]byte{220, 241, 16}: "Nokia Corporation", + [3]byte{220, 247, 85}: "SITRONIK", + [3]byte{220, 248, 88}: "Lorent Networks, Inc.", + [3]byte{220, 250, 213}: "STRONG Ges.m.b.H.", + [3]byte{220, 251, 2}: "Buffalo Inc.", + [3]byte{224, 5, 197}: "TP-LINK Technologies Co.,Ltd.", + [3]byte{224, 6, 230}: "Hon Hai Precision Ind. Co.,Ltd.", + [3]byte{224, 11, 40}: "Inovonics", + [3]byte{224, 12, 127}: "Nintendo Co., Ltd.", + [3]byte{224, 13, 185}: "PRIVATE", + [3]byte{224, 16, 127}: "Ruckus Wireless", + [3]byte{224, 20, 62}: "Modoosis Inc.", + [3]byte{224, 24, 119}: "Fujitsu Limited", + [3]byte{224, 28, 65}: "Aerohive Networks Inc.", + [3]byte{224, 28, 238}: "Bravo Tech, Inc.", + [3]byte{224, 29, 56}: "Beijing HuaqinWorld Technology Co.,Ltd", + [3]byte{224, 29, 59}: "Cambridge Industries(Group) Co.,Ltd", + [3]byte{224, 30, 7}: "Anite Telecoms US. Inc", + [3]byte{224, 31, 10}: "Xslent Energy Technologies. LLC", + [3]byte{224, 36, 127}: "HUAWEI TECHNOLOGIES CO.,LTD", + [3]byte{224, 37, 56}: "Titan Pet Products", + [3]byte{224, 38, 48}: "Intrigue Technologies, Inc.", + [3]byte{224, 38, 54}: "Nortel Networks", + [3]byte{224, 39, 26}: "TTC Next-generation Home Network System WG", + [3]byte{224, 42, 130}: "Universal Global Scientific Industrial Co., Ltd.", + [3]byte{224, 47, 109}: "Cisco", + [3]byte{224, 48, 5}: "Alcatel-Lucent Shanghai Bell Co., Ltd", + [3]byte{224, 49, 208}: "SZ Telstar CO., LTD", + [3]byte{224, 54, 227}: "Stage One International Co., Ltd.", + [3]byte{224, 57, 215}: "Plexxi, Inc.", + [3]byte{224, 60, 91}: "SHENZHEN JIAXINJIE ELECTRON CO.,LTD", + [3]byte{224, 62, 68}: "Broadcom Corporation", + [3]byte{224, 62, 74}: "Cavanagh Group International", + [3]byte{224, 62, 125}: "data-complex GmbH", + [3]byte{224, 63, 73}: "ASUSTek COMPUTER INC.", + [3]byte{224, 70, 154}: "NETGEAR", + [3]byte{224, 85, 151}: "Emergent Vision Technologies Inc.", + [3]byte{224, 86, 244}: "AxesNetwork Solutions inc.", + [3]byte{224, 88, 158}: "Laerdal Medical", + [3]byte{224, 91, 112}: "Innovid, Co., Ltd.", + [3]byte{224, 93, 166}: "Detlef Fink Elektronik & Softwareentwicklung", + [3]byte{224, 95, 185}: "CISCO SYSTEMS, INC.", + [3]byte{224, 97, 178}: "HANGZHOU ZENOINTEL TECHNOLOGY CO., LTD", + [3]byte{224, 98, 144}: "Jinan Jovision Science & Technology Co., Ltd.", + [3]byte{224, 99, 229}: "Sony Mobile Communications AB", + [3]byte{224, 100, 187}: "DigiView S.r.l.", + [3]byte{224, 102, 120}: "Apple", + [3]byte{224, 103, 179}: "C-Data Technology Co., Ltd", + [3]byte{224, 105, 149}: "PEGATRON CORPORATION", + [3]byte{224, 117, 10}: "ALPS ERECTORIC CO.,LTD.", + [3]byte{224, 117, 125}: "Motorola Mobility LLC", + [3]byte{224, 124, 98}: "Whistle Labs, Inc.", + [3]byte{224, 127, 83}: "TECHBOARD SRL", + [3]byte{224, 127, 136}: "EVIDENCE Network SIA", + [3]byte{224, 129, 119}: "GreenBytes, Inc.", + [3]byte{224, 135, 177}: "Nata-Info Ltd.", + [3]byte{224, 136, 93}: "Technicolor CH USA Inc", + [3]byte{224, 138, 126}: "Exponent", + [3]byte{224, 143, 236}: "REPOTEC CO., LTD.", + [3]byte{224, 145, 83}: "XAVi Technologies Corp.", + [3]byte{224, 145, 245}: "NETGEAR", + [3]byte{224, 148, 103}: "Intel Corporate", + [3]byte{224, 149, 121}: "ORTHOsoft inc, d/b/a Zimmer CAS", + [3]byte{224, 151, 150}: "HUAWEI TECHNOLOGIES CO.,LTD", + [3]byte{224, 151, 242}: "Atomax Inc.", + [3]byte{224, 157, 49}: "Intel Corporate", + [3]byte{224, 157, 184}: "PLANEX COMMUNICATIONS INC.", + [3]byte{224, 161, 152}: "NOJA Power Switchgear Pty Ltd", + [3]byte{224, 161, 215}: "SFR", + [3]byte{224, 163, 15}: "Pevco", + [3]byte{224, 166, 112}: "Nokia Corporation", + [3]byte{224, 170, 176}: "GENERAL VISION ELECTRONICS CO. LTD.", + [3]byte{224, 171, 254}: "Orb Networks, Inc.", + [3]byte{224, 172, 241}: "Cisco", + [3]byte{224, 174, 94}: "ALPS Co,. Ltd.", + [3]byte{224, 174, 178}: "Bender GmbH & Co.KG", + [3]byte{224, 174, 237}: "LOENK", + [3]byte{224, 175, 75}: "Pluribus Networks, Inc.", + [3]byte{224, 178, 241}: "FN-LINK TECHNOLOGY LIMITED", + [3]byte{224, 181, 45}: "Apple", + [3]byte{224, 183, 177}: "Pace plc", + [3]byte{224, 185, 165}: "Azurewave", + [3]byte{224, 185, 186}: "Apple", + [3]byte{224, 188, 67}: "C2 Microsystems, Inc.", + [3]byte{224, 194, 134}: "Aisai Communication Technology Co., Ltd.", + [3]byte{224, 194, 183}: "Masimo Corporation", + [3]byte{224, 195, 243}: "ZTE Corporation", + [3]byte{224, 198, 179}: "MilDef AB", + [3]byte{224, 199, 157}: "Texas Instruments", + [3]byte{224, 200, 106}: "SHENZHEN TW-SCIE Co., Ltd", + [3]byte{224, 201, 34}: "Jireh Energy Tech., Ltd.", + [3]byte{224, 201, 122}: "Apple", + [3]byte{224, 202, 77}: "Shenzhen Unistar Communication Co.,LTD", + [3]byte{224, 202, 148}: "Askey Computer", + [3]byte{224, 203, 29}: "PRIVATE", + [3]byte{224, 203, 78}: "ASUSTek COMPUTER INC.", + [3]byte{224, 203, 238}: "Samsung Electronics Co.,Ltd", + [3]byte{224, 206, 195}: "ASKEY COMPUTER CORP", + [3]byte{224, 207, 45}: "Gemintek Corporation", + [3]byte{224, 209, 10}: "Katoudenkikougyousyo co ltd", + [3]byte{224, 209, 230}: "Aliph dba Jawbone", + [3]byte{224, 211, 26}: "EQUES Technology Co., Limited", + [3]byte{224, 215, 186}: "Texas Instruments", + [3]byte{224, 217, 162}: "Hippih aps", + [3]byte{224, 218, 220}: "JVC KENWOOD Corporation", + [3]byte{224, 219, 85}: "Dell Inc", + [3]byte{224, 219, 136}: "Open Standard Digital-IF Interface for SATCOM Systems", + [3]byte{224, 220, 160}: "Siemens Electrical Apparatus Ltd., Suzhou Chengdu Branch", + [3]byte{224, 230, 49}: "SNB TECHNOLOGIES LIMITED", + [3]byte{224, 231, 81}: "Nintendo Co., Ltd.", + [3]byte{224, 232, 232}: "Olive Telecommunication Pvt. Ltd", + [3]byte{224, 237, 26}: "vastriver Technology Co., Ltd", + [3]byte{224, 237, 199}: "Shenzhen Friendcom Technology Development Co., Ltd", + [3]byte{224, 238, 27}: "Panasonic Automotive Systems Company of America", + [3]byte{224, 239, 37}: "Lintes Technology Co., Ltd.", + [3]byte{224, 242, 17}: "Digitalwatt", + [3]byte{224, 243, 121}: "Vaddio", + [3]byte{224, 245, 198}: "Apple", + [3]byte{224, 245, 202}: "CHENG UEI PRECISION INDUSTRY CO.,LTD.", + [3]byte{224, 248, 71}: "Apple", + [3]byte{224, 249, 190}: "Cloudena Corp.", + [3]byte{224, 250, 236}: "Platan sp. z o.o. sp. k.", + [3]byte{228, 4, 57}: "TomTom Software Ltd", + [3]byte{228, 17, 91}: "Hewlett Packard", + [3]byte{228, 18, 24}: "ShenZhen Rapoo Technology Co., Ltd.", + [3]byte{228, 18, 29}: "Samsung Electronics Co.,Ltd", + [3]byte{228, 18, 137}: "topsystem Systemhaus GmbH", + [3]byte{228, 28, 75}: "V2 TECHNOLOGY, INC.", + [3]byte{228, 29, 45}: "Mellanox Technologies, Inc.", + [3]byte{228, 31, 19}: "IBM Corp", + [3]byte{228, 35, 84}: "SHENZHEN FUZHI SOFTWARE TECHNOLOGY CO.,LTD", + [3]byte{228, 37, 231}: "Apple", + [3]byte{228, 37, 233}: "Color-Chip", + [3]byte{228, 39, 113}: "Smartlabs", + [3]byte{228, 42, 211}: "Magneti Marelli S.p.A. Powertrain", + [3]byte{228, 44, 86}: "Lilee Systems, Ltd.", + [3]byte{228, 45, 2}: "TCT Mobile Limited", + [3]byte{228, 47, 38}: "Fiberhome Telecommunication Tech.Co.,Ltd.", + [3]byte{228, 47, 246}: "Unicore communication Inc.", + [3]byte{228, 50, 203}: "Samsung Electronics Co.,Ltd", + [3]byte{228, 53, 147}: "Hangzhou GoTo technology Co.Ltd", + [3]byte{228, 53, 251}: "Sabre Technology (Hull) Ltd", + [3]byte{228, 55, 215}: "HENRI DEPAEPE S.A.S.", + [3]byte{228, 56, 242}: "Advantage Controls", + [3]byte{228, 63, 162}: "Wuxi DSP Technologies Inc.", + [3]byte{228, 64, 226}: "Samsung Electronics Co.,Ltd", + [3]byte{228, 65, 230}: "Ottec Technology GmbH", + [3]byte{228, 70, 189}: "C&C TECHNIC TAIWAN CO., LTD.", + [3]byte{228, 72, 199}: "Cisco SPVTG", + [3]byte{228, 76, 108}: "Shenzhen Guo Wei Electronic Co,. Ltd.", + [3]byte{228, 78, 24}: "Gardasoft VisionLimited", + [3]byte{228, 79, 41}: "MA Lighting Technology GmbH", + [3]byte{228, 79, 95}: "EDS Elektronik Destek San.Tic.Ltd.Sti", + [3]byte{228, 85, 234}: "Dedicated Computing", + [3]byte{228, 86, 20}: "Suttle Apparatus", + [3]byte{228, 87, 168}: "Stuart Manufacturing, Inc.", + [3]byte{228, 93, 82}: "Avaya, Inc", + [3]byte{228, 100, 73}: "ARRIS Group, Inc.", + [3]byte{228, 103, 186}: "Danish Interpretation Systems A/S", + [3]byte{228, 104, 163}: "HUAWEI TECHNOLOGIES CO.,LTD", + [3]byte{228, 108, 33}: "messMa GmbH", + [3]byte{228, 113, 133}: "Securifi Ltd", + [3]byte{228, 117, 30}: "Getinge Sterilization AB", + [3]byte{228, 119, 35}: "zte corporation", + [3]byte{228, 119, 107}: "AARTESYS AG", + [3]byte{228, 119, 212}: "Minrray Industry Co.,Ltd", + [3]byte{228, 124, 249}: "Samsung Electronics Co., LTD", + [3]byte{228, 125, 90}: "Beijing Hanbang Technology Corp.", + [3]byte{228, 127, 178}: "Fujitsu Limited", + [3]byte{228, 129, 132}: "Alcatel-Lucent", + [3]byte{228, 129, 179}: "Shenzhen ACT Industrial Co.,Ltd.", + [3]byte{228, 131, 153}: "ARRIS Group, Inc.", + [3]byte{228, 138, 213}: "RF WINDOW CO., LTD.", + [3]byte{228, 139, 127}: "Apple", + [3]byte{228, 140, 15}: "Discovery Insure", + [3]byte{228, 144, 105}: "Rockwell Automation", + [3]byte{228, 146, 231}: "Gridlink Tech. Co.,Ltd.", + [3]byte{228, 146, 251}: "Samsung Electronics Co.,Ltd", + [3]byte{228, 149, 110}: "IEEE REGISTRATION AUTHORITY - Please see MAM public listing for more information.", + [3]byte{228, 150, 174}: "ALTOGRAPHICS Inc.", + [3]byte{228, 151, 240}: "Shanghai VLC Technologies Ltd. Co.", + [3]byte{228, 152, 214}: "Apple, Inc", + [3]byte{228, 165, 239}: "TRON LINK ELECTRONICS CO., LTD.", + [3]byte{228, 167, 253}: "Cellco Partnership", + [3]byte{228, 171, 70}: "UAB Selteka", + [3]byte{228, 173, 125}: "SCL Elements", + [3]byte{228, 175, 161}: "HES-SO", + [3]byte{228, 176, 33}: "Samsung Electronics Co.,Ltd", + [3]byte{228, 186, 217}: "360 Fly Inc.", + [3]byte{228, 193, 70}: "Objetivos y Servicios de Valor A", + [3]byte{228, 198, 43}: "Airware", + [3]byte{228, 198, 61}: "Apple, Inc.", + [3]byte{228, 198, 230}: "Mophie, LLC", + [3]byte{228, 199, 34}: "Cisco", + [3]byte{228, 200, 6}: "Ceiec Electric Technology Inc.", + [3]byte{228, 206, 143}: "Apple", + [3]byte{228, 211, 50}: "TP-LINK TECHNOLOGIES CO.,LTD.", + [3]byte{228, 211, 241}: "Cisco", + [3]byte{228, 213, 61}: "Hon Hai Precision Ind. Co.,Ltd.", + [3]byte{228, 215, 29}: "Oraya Therapeutics", + [3]byte{228, 221, 121}: "En-Vision America, Inc.", + [3]byte{228, 224, 197}: "Samsung Electronics Co., LTD", + [3]byte{228, 228, 9}: "LEIFHEIT AG", + [3]byte{228, 236, 16}: "Nokia Corporation", + [3]byte{228, 238, 253}: "MR&D Manufacturing", + [3]byte{228, 243, 101}: "Time-O-Matic, Inc.", + [3]byte{228, 243, 227}: "Shanghai iComhome Co.,Ltd.", + [3]byte{228, 244, 198}: "NETGEAR", + [3]byte{228, 247, 161}: "Datafox GmbH", + [3]byte{228, 248, 239}: "Samsung Elec Co.,Ltd", + [3]byte{228, 250, 29}: "PAD Peripheral Advanced Design Inc.", + [3]byte{228, 255, 221}: "ELECTRON INDIA", + [3]byte{232, 3, 154}: "Samsung Electronics CO., LTD", + [3]byte{232, 4, 11}: "Apple", + [3]byte{232, 4, 16}: "PRIVATE", + [3]byte{232, 4, 98}: "CISCO SYSTEMS, INC.", + [3]byte{232, 4, 243}: "Throughtek Co., Ltd.", + [3]byte{232, 5, 109}: "Nortel Networks", + [3]byte{232, 6, 136}: "Apple", + [3]byte{232, 8, 139}: "Huawei Technologies Co., Ltd", + [3]byte{232, 11, 19}: "Akib Systems Taiwan, INC", + [3]byte{232, 12, 56}: "DAEYOUNG INFORMATION SYSTEM CO., LTD", + [3]byte{232, 12, 117}: "Syncbak, Inc.", + [3]byte{232, 16, 46}: "Really Simple Software, Inc", + [3]byte{232, 17, 50}: "Samsung Electronics CO., LTD", + [3]byte{232, 19, 36}: "GuangZhou Bonsoninfo System CO.,LTD", + [3]byte{232, 21, 14}: "Nokia Corporation", + [3]byte{232, 23, 252}: "NIFTY Corporation", + [3]byte{232, 24, 99}: "IEEE REGISTRATION AUTHORITY - Please see MAM public listing for more information.", + [3]byte{232, 40, 119}: "TMY Co., Ltd.", + [3]byte{232, 40, 213}: "Cots Technology", + [3]byte{232, 42, 234}: "Intel Corporate", + [3]byte{232, 46, 36}: "Out of the Fog Research LLC", + [3]byte{232, 51, 129}: "ARRIS Group, Inc.", + [3]byte{232, 57, 53}: "Hewlett Packard", + [3]byte{232, 57, 223}: "Askey Computer", + [3]byte{232, 58, 151}: "OCZ Technology Group", + [3]byte{232, 62, 182}: "RIM", + [3]byte{232, 62, 251}: "GEODESIC LTD.", + [3]byte{232, 62, 252}: "ARRIS Group, Inc.", + [3]byte{232, 64, 64}: "CISCO SYSTEMS, INC.", + [3]byte{232, 64, 242}: "PEGATRON CORPORATION", + [3]byte{232, 67, 182}: "QNAP Systems, Inc.", + [3]byte{232, 72, 31}: "Advanced Automotive Antennas", + [3]byte{232, 78, 6}: "EDUP INTERNATIONAL (HK) CO., LTD", + [3]byte{232, 78, 132}: "Samsung Electronics Co.,Ltd", + [3]byte{232, 78, 206}: "Nintendo Co., Ltd.", + [3]byte{232, 81, 110}: "TSMART Inc.", + [3]byte{232, 81, 157}: "Yeonhab Precision Co.,LTD", + [3]byte{232, 84, 132}: "NEO INFORMATION SYSTEMS CO., LTD.", + [3]byte{232, 86, 214}: "NCTech Ltd", + [3]byte{232, 90, 167}: "LLC Emzior", + [3]byte{232, 91, 91}: "LG ELECTRONICS INC", + [3]byte{232, 91, 240}: "Imaging Diagnostics", + [3]byte{232, 93, 107}: "Luminate Wireless", + [3]byte{232, 94, 83}: "Infratec Datentechnik GmbH", + [3]byte{232, 97, 31}: "Dawning Information Industry Co.,Ltd", + [3]byte{232, 97, 126}: "Liteon Technology Corporation", + [3]byte{232, 97, 131}: "Black Diamond Advanced Technology, LLC", + [3]byte{232, 108, 218}: "Supercomputers and Neurocomputers Research Center", + [3]byte{232, 109, 82}: "ARRIS Group, Inc.", + [3]byte{232, 109, 84}: "Digit Mobile Inc", + [3]byte{232, 109, 110}: "Control & Display Systems Ltd t/a CDSRail", + [3]byte{232, 113, 141}: "Elsys Equipamentos Eletronicos Ltda", + [3]byte{232, 117, 127}: "FIRS Technologies(Shenzhen) Co., Ltd", + [3]byte{232, 120, 161}: "BEOVIEW INTERCOM DOO", + [3]byte{232, 122, 243}: "S5 Tech S.r.l.", + [3]byte{232, 128, 46}: "Apple", + [3]byte{232, 128, 216}: "GNTEK Electronics Co.,Ltd.", + [3]byte{232, 135, 163}: "Loxley Public Company Limited", + [3]byte{232, 137, 44}: "ARRIS Group, Inc.", + [3]byte{232, 141, 40}: "Apple", + [3]byte{232, 141, 245}: "ZNYX Networks, Inc.", + [3]byte{232, 142, 96}: "NSD Corporation", + [3]byte{232, 146, 24}: "Arcontia International AB", + [3]byte{232, 146, 164}: "LG Electronics", + [3]byte{232, 148, 76}: "Cogent Healthcare Systems Ltd", + [3]byte{232, 148, 246}: "TP-LINK TECHNOLOGIES CO.,LTD.", + [3]byte{232, 150, 6}: "testo Instruments (Shenzhen) Co., Ltd.", + [3]byte{232, 153, 90}: "PiiGAB, Processinformation i Goteborg AB", + [3]byte{232, 153, 196}: "HTC Corporation", + [3]byte{232, 154, 143}: "Quanta Computer Inc.", + [3]byte{232, 154, 255}: "Fujian Landi Commercial Equipment Co.,Ltd", + [3]byte{232, 157, 135}: "Toshiba", + [3]byte{232, 163, 100}: "Signal Path International / Peachtree Audio", + [3]byte{232, 164, 193}: "Deep Sea Electronics PLC", + [3]byte{232, 171, 250}: "Shenzhen Reecam Tech.Ltd.", + [3]byte{232, 177, 252}: "Intel Corporate", + [3]byte{232, 180, 174}: "Shenzhen C&D Electronics Co.,Ltd", + [3]byte{232, 183, 72}: "CISCO SYSTEMS, INC.", + [3]byte{232, 186, 112}: "CISCO SYSTEMS, INC.", + [3]byte{232, 187, 61}: "Sino Prime-Tech Limited", + [3]byte{232, 187, 168}: "GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD.", + [3]byte{232, 190, 129}: "SAGEMCOM", + [3]byte{232, 194, 41}: "H-Displays (MSC) Bhd", + [3]byte{232, 195, 32}: "Austco Communication Systems Pty Ltd", + [3]byte{232, 203, 161}: "Nokia Corporation", + [3]byte{232, 204, 24}: "D-Link International", + [3]byte{232, 204, 50}: "Micronet LTD", + [3]byte{232, 205, 45}: "Huawei Technologies Co., Ltd", + [3]byte{232, 206, 6}: "SkyHawke Technologies, LLC.", + [3]byte{232, 208, 250}: "MKS Instruments Deutschland GmbH", + [3]byte{232, 212, 131}: "ULTIMATE Europe Transportation Equipment GmbH", + [3]byte{232, 212, 224}: "Beijing BenyWave Technology Co., Ltd.", + [3]byte{232, 218, 150}: "Zhuhai Tianrui Electrical Power Tech. Co., Ltd.", + [3]byte{232, 218, 170}: "VideoHome Technology Corp.", + [3]byte{232, 222, 39}: "TP-LINK TECHNOLOGIES CO.,LTD.", + [3]byte{232, 223, 242}: "PRF Co., Ltd.", + [3]byte{232, 224, 143}: "GRAVOTECH MARKING SAS", + [3]byte{232, 224, 183}: "Toshiba", + [3]byte{232, 225, 226}: "Energotest", + [3]byte{232, 229, 214}: "Samsung Electronics Co.,Ltd", + [3]byte{232, 231, 50}: "Alcatel-Lucent", + [3]byte{232, 231, 112}: "Warp9 Tech Design, Inc.", + [3]byte{232, 231, 118}: "Shenzhen Kootion Technology Co., Ltd", + [3]byte{232, 232, 117}: "iS5 Communications Inc.", + [3]byte{232, 234, 106}: "StarTech.com", + [3]byte{232, 234, 218}: "Denkovi Assembly Electroncs LTD", + [3]byte{232, 237, 5}: "ARRIS Group, Inc.", + [3]byte{232, 237, 243}: "Cisco", + [3]byte{232, 239, 137}: "OPMEX Tech.", + [3]byte{232, 241, 176}: "SAGEMCOM SAS", + [3]byte{232, 242, 38}: "MILLSON CUSTOM SOLUTIONS INC.", + [3]byte{232, 249, 40}: "RFTECH SRL", + [3]byte{232, 252, 96}: "ELCOM Innovations Private Limited", + [3]byte{232, 252, 175}: "NETGEAR INC.,", + [3]byte{236, 14, 196}: "Hon Hai Precision Ind. Co.,Ltd.", + [3]byte{236, 14, 214}: "ITECH INSTRUMENTS SAS", + [3]byte{236, 17, 32}: "FloDesign Wind Turbine Corporation", + [3]byte{236, 19, 178}: "Netonix", + [3]byte{236, 20, 246}: "BioControl AS", + [3]byte{236, 23, 47}: "TP-LINK TECHNOLOGIES CO., LTD.", + [3]byte{236, 23, 102}: "Research Centre Module", + [3]byte{236, 26, 89}: "Belkin International Inc.", + [3]byte{236, 29, 127}: "zte corporation", + [3]byte{236, 33, 159}: "VidaBox LLC", + [3]byte{236, 34, 87}: "JiangSu NanJing University Electronic Information Technology Co.,Ltd", + [3]byte{236, 34, 128}: "D-Link International", + [3]byte{236, 35, 61}: "Huawei Technologies Co., Ltd", + [3]byte{236, 35, 104}: "IntelliVoice Co.,Ltd.", + [3]byte{236, 36, 184}: "Texas Instruments", + [3]byte{236, 42, 240}: "Ypsomed AG", + [3]byte{236, 44, 73}: "University of Tokyo", + [3]byte{236, 46, 78}: "HITACHI-LG DATA STORAGE INC", + [3]byte{236, 48, 145}: "CISCO SYSTEMS, INC.", + [3]byte{236, 53, 134}: "Apple", + [3]byte{236, 59, 240}: "NovelSat", + [3]byte{236, 60, 90}: "SHEN ZHEN HENG SHENG HUI DIGITAL TECHNOLOGY CO.,LTD", + [3]byte{236, 62, 9}: "PERFORMANCE DESIGNED PRODUCTS, LLC", + [3]byte{236, 63, 5}: "Institute 706, The Second Academy China Aerospace Science & Industry Corp", + [3]byte{236, 66, 240}: "ADL Embedded Solutions, Inc.", + [3]byte{236, 67, 230}: "AWCER Ltd.", + [3]byte{236, 67, 246}: "ZyXEL Communications Corporation", + [3]byte{236, 68, 118}: "CISCO SYSTEMS, INC.", + [3]byte{236, 70, 68}: "TTK SAS", + [3]byte{236, 70, 112}: "Meinberg Funkuhren GmbH & Co. KG", + [3]byte{236, 71, 60}: "Redwire, LLC", + [3]byte{236, 73, 147}: "Qihan Technology Co., Ltd", + [3]byte{236, 76, 77}: "ZAO NPK RoTeK", + [3]byte{236, 84, 46}: "Shanghai XiMei Electronic Technology Co. Ltd", + [3]byte{236, 85, 249}: "Hon Hai Precision Ind. Co.,Ltd.", + [3]byte{236, 89, 231}: "Microsoft Corporation", + [3]byte{236, 92, 105}: "MITSUBISHI HEAVY INDUSTRIES MECHATRONICS SYSTEMS,LTD.", + [3]byte{236, 98, 100}: "Global411 Internet Services, LLC", + [3]byte{236, 99, 229}: "ePBoard Design LLC", + [3]byte{236, 102, 209}: "B&W Group LTD", + [3]byte{236, 108, 159}: "Chengdu Volans Technology CO.,LTD", + [3]byte{236, 113, 219}: "Shenzhen Baichuan Digital Technology Co., Ltd.", + [3]byte{236, 124, 116}: "Justone Technologies Co., Ltd.", + [3]byte{236, 125, 157}: "MEI", + [3]byte{236, 128, 9}: "NovaSparks", + [3]byte{236, 131, 108}: "RM Tech Co., Ltd.", + [3]byte{236, 133, 47}: "Apple", + [3]byte{236, 136, 143}: "TP-LINK TECHNOLOGIES CO., LTD.", + [3]byte{236, 137, 245}: "Lenovo Mobile Communication Technology Ltd.", + [3]byte{236, 138, 76}: "zte corporation", + [3]byte{236, 142, 173}: "DLX", + [3]byte{236, 146, 51}: "Eddyfi NDT Inc", + [3]byte{236, 147, 39}: "MEMMERT GmbH + Co. KG", + [3]byte{236, 150, 129}: "2276427 Ontario Inc", + [3]byte{236, 152, 108}: "Lufft Mess- und Regeltechnik GmbH", + [3]byte{236, 152, 193}: "Beijing Risbo Network Technology Co.,Ltd", + [3]byte{236, 154, 116}: "Hewlett Packard", + [3]byte{236, 155, 91}: "Nokia Corporation", + [3]byte{236, 158, 205}: "Artesyn Embedded Technologies", + [3]byte{236, 162, 155}: "Kemppi Oy", + [3]byte{236, 168, 107}: "ELITEGROUP COMPUTER SYSTEMS CO., LTD.", + [3]byte{236, 177, 6}: "Acuro Networks, Inc", + [3]byte{236, 181, 65}: "SHINANO E and E Co.Ltd.", + [3]byte{236, 185, 7}: "CloudGenix Inc", + [3]byte{236, 187, 174}: "Digivoice Tecnologia em Eletronica Ltda", + [3]byte{236, 189, 9}: "FUSION Electronics Ltd", + [3]byte{236, 195, 138}: "Accuenergy (CANADA) Inc", + [3]byte{236, 200, 130}: "CISCO SYSTEMS, INC.", + [3]byte{236, 203, 48}: "Huawei Technologies Co., Ltd", + [3]byte{236, 205, 109}: "Allied Telesis, Inc.", + [3]byte{236, 208, 14}: "MiraeRecognition Co., Ltd.", + [3]byte{236, 208, 64}: "GEA Farm Technologies GmbH", + [3]byte{236, 209, 154}: "Zhuhai Liming Industries Co., Ltd", + [3]byte{236, 217, 37}: "RAMI", + [3]byte{236, 217, 80}: "IRT SA", + [3]byte{236, 217, 209}: "Shenzhen TG-NET Botone Technology Co.,Ltd.", + [3]byte{236, 222, 61}: "Lamprey Networks, Inc.", + [3]byte{236, 224, 155}: "Samsung electronics CO., LTD", + [3]byte{236, 225, 169}: "Cisco", + [3]byte{236, 229, 18}: "tado GmbH", + [3]byte{236, 229, 85}: "Hirschmann Automation", + [3]byte{236, 231, 68}: "Omntec mfg. inc", + [3]byte{236, 233, 11}: "SISTEMA SOLUCOES ELETRONICAS LTDA - EASYTECH", + [3]byte{236, 233, 21}: "STI Ltd", + [3]byte{236, 233, 248}: "Guang Zhou TRI-SUN Electronics Technology Co., Ltd", + [3]byte{236, 234, 3}: "DARFON LIGHTING CORP", + [3]byte{236, 240, 14}: "Abocom", + [3]byte{236, 242, 54}: "NEOMONTANA ELECTRONICS", + [3]byte{236, 243, 91}: "Nokia Corporation", + [3]byte{236, 244, 187}: "Dell Inc", + [3]byte{236, 247, 43}: "HD DIGITAL TECH CO., LTD.", + [3]byte{236, 250, 170}: "The IMS Company", + [3]byte{236, 252, 85}: "A. Eberle GmbH & Co. KG", + [3]byte{236, 254, 126}: "BlueRadios, Inc.", + [3]byte{240, 0, 127}: "Janz - Contadores de Energia, SA", + [3]byte{240, 2, 43}: "Chrontel", + [3]byte{240, 2, 72}: "SmarteBuilding", + [3]byte{240, 7, 134}: "Shandong Bittel Electronics Co., Ltd", + [3]byte{240, 8, 241}: "Samsung Electronics Co.,Ltd", + [3]byte{240, 19, 195}: "SHENZHEN FENDA TECHNOLOGY CO., LTD", + [3]byte{240, 21, 160}: "KyungDong One Co., Ltd.", + [3]byte{240, 28, 19}: "LG Electronics", + [3]byte{240, 28, 45}: "Juniper Networks", + [3]byte{240, 31, 175}: "Dell Inc", + [3]byte{240, 33, 157}: "Cal-Comp Electronics & Communications Company Ltd.", + [3]byte{240, 35, 41}: "SHOWA DENKI CO.,LTD.", + [3]byte{240, 36, 5}: "OPUS High Technology Corporation", + [3]byte{240, 36, 8}: "Talaris (Sweden) AB", + [3]byte{240, 37, 114}: "CISCO SYSTEMS, INC.", + [3]byte{240, 37, 183}: "Samsung Electro Mechanics co., LTD.", + [3]byte{240, 38, 76}: "Dr. Sigrist AG", + [3]byte{240, 39, 101}: "Murata Manufactuaring Co.,Ltd.", + [3]byte{240, 41, 41}: "Cisco", + [3]byte{240, 42, 97}: "Waldo Networks, Inc.", + [3]byte{240, 47, 216}: "Bi2-Vision", + [3]byte{240, 50, 26}: "Mita-Teknik A/S", + [3]byte{240, 55, 161}: "Huike Electronics (SHENZHEN) CO., LTD.", + [3]byte{240, 58, 75}: "Bloombase, Inc.", + [3]byte{240, 58, 85}: "Omega Elektronik AS", + [3]byte{240, 61, 41}: "Actility", + [3]byte{240, 63, 248}: "R L Drake", + [3]byte{240, 67, 53}: "DVN(Shanghai)Ltd.", + [3]byte{240, 74, 43}: "PYRAMID Computer GmbH", + [3]byte{240, 75, 106}: "Scientific Production Association Siberian Arsenal, Ltd.", + [3]byte{240, 75, 242}: "JTECH Communications, Inc.", + [3]byte{240, 77, 162}: "Dell Inc.", + [3]byte{240, 79, 124}: "PRIVATE", + [3]byte{240, 88, 73}: "CareView Communications", + [3]byte{240, 90, 9}: "Samsung Electronics Co.,Ltd", + [3]byte{240, 93, 137}: "Dycon Limited", + [3]byte{240, 93, 200}: "Duracell Powermat", + [3]byte{240, 95, 90}: "Getriebebau NORD GmbH and Co. KG", + [3]byte{240, 97, 48}: "Advantage Pharmacy Services, LLC", + [3]byte{240, 98, 13}: "Shenzhen Egreat Tech Corp.,Ltd", + [3]byte{240, 98, 129}: "ProCurve Networking by HP", + [3]byte{240, 101, 221}: "Primax Electronics Ltd.", + [3]byte{240, 104, 83}: "Integrated Corporation", + [3]byte{240, 107, 202}: "Samsung Electronics Co.,Ltd", + [3]byte{240, 114, 140}: "Samsung Electronics Co.,Ltd", + [3]byte{240, 115, 174}: "PEAK-System Technik", + [3]byte{240, 118, 28}: "COMPAL INFORMATION (KUNSHAN) CO., LTD.", + [3]byte{240, 119, 101}: "Sourcefire, Inc", + [3]byte{240, 119, 208}: "Xcellen", + [3]byte{240, 123, 203}: "Hon Hai Precision Ind. Co.,Ltd.", + [3]byte{240, 125, 104}: "D-Link Corporation", + [3]byte{240, 127, 6}: "Cisco", + [3]byte{240, 127, 12}: "Leopold Kostal GmbH &Co. KG", + [3]byte{240, 129, 175}: "IRZ AUTOMATION TECHNOLOGIES LTD", + [3]byte{240, 130, 97}: "SAGEMCOM", + [3]byte{240, 132, 47}: "ADB Broadband Italia", + [3]byte{240, 132, 201}: "zte corporation", + [3]byte{240, 138, 40}: "JIANGSU HENGSION ELECTRONIC S and T CO.,LTD", + [3]byte{240, 139, 254}: "COSTEL.,CO.LTD", + [3]byte{240, 140, 251}: "Fiberhome Telecommunication Tech.Co.,Ltd.", + [3]byte{240, 142, 219}: "VeloCloud Networks", + [3]byte{240, 146, 28}: "Hewlett Packard", + [3]byte{240, 147, 58}: "NxtConect", + [3]byte{240, 147, 197}: "Garland Technology", + [3]byte{240, 156, 187}: "RaonThink Inc.", + [3]byte{240, 156, 233}: "Aerohive Networks Inc", + [3]byte{240, 158, 99}: "Cisco", + [3]byte{240, 162, 37}: "PRIVATE", + [3]byte{240, 167, 100}: "GST Co., Ltd.", + [3]byte{240, 172, 164}: "HBC-radiomatic", + [3]byte{240, 173, 78}: "Globalscale Technologies, Inc.", + [3]byte{240, 174, 81}: "Xi3 Corp", + [3]byte{240, 180, 121}: "Apple", + [3]byte{240, 182, 235}: "Poslab Technology Co., Ltd.", + [3]byte{240, 188, 200}: "MaxID (Pty) Ltd", + [3]byte{240, 189, 241}: "Sipod Inc.", + [3]byte{240, 191, 151}: "Sony Corporation", + [3]byte{240, 193, 241}: "Apple, Inc.", + [3]byte{240, 194, 76}: "Zhejiang FeiYue Digital Technology Co., Ltd", + [3]byte{240, 194, 124}: "Mianyang Netop Telecom Equipment Co.,Ltd.", + [3]byte{240, 200, 140}: "LeddarTech Inc.", + [3]byte{240, 203, 161}: "Apple", + [3]byte{240, 209, 79}: "LINEAR LLC", + [3]byte{240, 209, 169}: "Apple", + [3]byte{240, 211, 167}: "CobaltRay Co., Ltd", + [3]byte{240, 211, 231}: "Sensometrix SA", + [3]byte{240, 215, 103}: "Axema Passagekontroll AB", + [3]byte{240, 218, 124}: "RLH INDUSTRIES,INC.", + [3]byte{240, 219, 48}: "Yottabyte", + [3]byte{240, 219, 248}: "Apple", + [3]byte{240, 220, 226}: "Apple", + [3]byte{240, 222, 113}: "Shanghai EDO Technologies Co.,Ltd.", + [3]byte{240, 222, 185}: "ShangHai Y&Y Electronics Co., Ltd", + [3]byte{240, 222, 241}: "Wistron InfoComm (Kunshan)Co", + [3]byte{240, 229, 195}: "Drägerwerk AG & Co. KG aA", + [3]byte{240, 231, 126}: "Samsung Electronics Co.,Ltd", + [3]byte{240, 235, 208}: "Shanghai Feixun Communication Co.,Ltd.", + [3]byte{240, 236, 57}: "Essec", + [3]byte{240, 237, 30}: "Bilkon Bilgisayar Kontrollu Cih. Im.Ltd.", + [3]byte{240, 238, 187}: "VIPAR GmbH", + [3]byte{240, 240, 2}: "Hon Hai Precision Ind. Co.,Ltd.", + [3]byte{240, 242, 96}: "Mobitec AB", + [3]byte{240, 243, 54}: "TP-LINK TECHNOLOGIES CO.,LTD", + [3]byte{240, 245, 174}: "Adaptrum Inc.", + [3]byte{240, 246, 28}: "Apple", + [3]byte{240, 246, 68}: "Whitesky Science & Technology Co.,Ltd.", + [3]byte{240, 246, 105}: "Motion Analysis Corporation", + [3]byte{240, 247, 85}: "CISCO SYSTEMS, INC.", + [3]byte{240, 247, 179}: "Phorm", + [3]byte{240, 248, 66}: "KEEBOX, Inc.", + [3]byte{240, 249, 247}: "IES GmbH & Co. KG", + [3]byte{240, 253, 160}: "Acurix Networks LP", + [3]byte{240, 254, 107}: "Shanghai High-Flying Electronics Technology Co., Ltd", + [3]byte{244, 3, 33}: "BeNeXt B.V.", + [3]byte{244, 4, 76}: "ValenceTech Limited", + [3]byte{244, 6, 105}: "Intel Corporate", + [3]byte{244, 6, 141}: "devolo AG", + [3]byte{244, 6, 165}: "Hangzhou Bianfeng Networking Technology Co., Ltd.", + [3]byte{244, 9, 216}: "Samsung Electro Mechanics co., LTD.", + [3]byte{244, 11, 147}: "Research In Motion", + [3]byte{244, 14, 17}: "IEEE REGISTRATION AUTHORITY - Please see MAM public listing for more information.", + [3]byte{244, 15, 27}: "Cisco", + [3]byte{244, 15, 155}: "WAVELINK", + [3]byte{244, 21, 253}: "Shanghai Pateo Electronic Equipment Manufacturing Co., Ltd.", + [3]byte{244, 27, 161}: "Apple", + [3]byte{244, 30, 38}: "Simon-Kaloi Engineering", + [3]byte{244, 31, 11}: "YAMABISHI Corporation", + [3]byte{244, 31, 194}: "Cisco", + [3]byte{244, 32, 18}: "Cuciniale GmbH", + [3]byte{244, 40, 51}: "MMPC Inc.", + [3]byte{244, 40, 83}: "Zioncom Electronics (Shenzhen) Ltd.", + [3]byte{244, 40, 150}: "SPECTO PAINEIS ELETRONICOS LTDA", + [3]byte{244, 54, 225}: "Abilis Systems SARL", + [3]byte{244, 55, 183}: "Apple", + [3]byte{244, 56, 20}: "Shanghai Howell Electronic Co.,Ltd", + [3]byte{244, 61, 128}: "FAG Industrial Services GmbH", + [3]byte{244, 62, 97}: "Shenzhen Gongjin Electronics Co., Ltd", + [3]byte{244, 62, 157}: "Benu Networks, Inc.", + [3]byte{244, 66, 39}: "S & S Research Inc.", + [3]byte{244, 68, 80}: "BND Co., Ltd.", + [3]byte{244, 69, 237}: "Portable Innovation Technology Ltd.", + [3]byte{244, 71, 42}: "Nanjing Rousing Sci. and Tech. Industrial Co., Ltd", + [3]byte{244, 72, 72}: "Amscreen Group Ltd", + [3]byte{244, 78, 5}: "Cisco", + [3]byte{244, 78, 253}: "Actions Semiconductor Co.,Ltd.(Cayman Islands)", + [3]byte{244, 80, 235}: "Telechips Inc", + [3]byte{244, 82, 20}: "Mellanox Technologies, Inc.", + [3]byte{244, 84, 51}: "Rockwell Automation", + [3]byte{244, 85, 149}: "HENGBAO Corporation LTD.", + [3]byte{244, 85, 156}: "Huawei Technologies Co., Ltd", + [3]byte{244, 85, 224}: "Niceway CNC Technology Co.,Ltd.Hunan Province", + [3]byte{244, 88, 66}: "Boxx TV Ltd", + [3]byte{244, 95, 105}: "Matsufu Electronics distribution Company", + [3]byte{244, 95, 212}: "Cisco SPVTG", + [3]byte{244, 95, 247}: "DQ Technology Inc.", + [3]byte{244, 96, 13}: "Panoptic Technology, Inc", + [3]byte{244, 99, 73}: "Diffon Corporation", + [3]byte{244, 106, 188}: "Adonit Corp. Ltd.", + [3]byte{244, 109, 4}: "ASUSTek COMPUTER INC.", + [3]byte{244, 109, 226}: "zte corporation", + [3]byte{244, 115, 202}: "Conversion Sound Inc.", + [3]byte{244, 118, 38}: "Viltechmeda UAB", + [3]byte{244, 122, 78}: "Woojeon&Handan", + [3]byte{244, 122, 204}: "SolidFire, Inc.", + [3]byte{244, 123, 94}: "Samsung Eletronics Co., Ltd", + [3]byte{244, 127, 53}: "CISCO SYSTEMS, INC.", + [3]byte{244, 129, 57}: "CANON INC.", + [3]byte{244, 135, 113}: "Infoblox", + [3]byte{244, 142, 9}: "Nokia Corporation", + [3]byte{244, 144, 202}: "Tensorcom", + [3]byte{244, 144, 234}: "Deciso B.V.", + [3]byte{244, 148, 97}: "NexGen Storage", + [3]byte{244, 148, 102}: "CountMax, ltd", + [3]byte{244, 153, 172}: "WEBER Schraubautomaten GmbH", + [3]byte{244, 159, 84}: "Samsung Electronics", + [3]byte{244, 159, 243}: "Huawei Technologies Co., Ltd", + [3]byte{244, 162, 148}: "EAGLE WORLD DEVELOPMENT CO., LIMITED", + [3]byte{244, 165, 42}: "Hawa Technologies Inc", + [3]byte{244, 172, 193}: "CISCO SYSTEMS, INC.", + [3]byte{244, 177, 100}: "Lightning Telecommunications Technology Co. Ltd", + [3]byte{244, 179, 129}: "WindowMaster A/S", + [3]byte{244, 181, 47}: "Juniper networks", + [3]byte{244, 181, 73}: "Yeastar Technology Co., Ltd.", + [3]byte{244, 182, 229}: "TerraSem Co.,Ltd", + [3]byte{244, 183, 42}: "TIME INTERCONNECT LTD", + [3]byte{244, 183, 226}: "Hon Hai Precision Ind. Co.,Ltd.", + [3]byte{244, 184, 94}: "Texas INstruments", + [3]byte{244, 189, 124}: "Chengdu jinshi communication Co., LTD", + [3]byte{244, 196, 71}: "Coagent International Enterprise Limited", + [3]byte{244, 198, 215}: "blackned GmbH", + [3]byte{244, 199, 20}: "Shenzhen Huawei Communication Technologies Co., Ltd", + [3]byte{244, 199, 149}: "WEY Elektronik AG", + [3]byte{244, 202, 229}: "FREEBOX SA", + [3]byte{244, 205, 144}: "Vispiron Rotec GmbH", + [3]byte{244, 206, 70}: "Hewlett-Packard Company", + [3]byte{244, 207, 226}: "Cisco", + [3]byte{244, 208, 50}: "Yunnan Ideal Information&Technology.,Ltd", + [3]byte{244, 210, 97}: "SEMOCON Co., Ltd", + [3]byte{244, 217, 251}: "Samsung Electronics CO., LTD", + [3]byte{244, 220, 77}: "Beijing CCD Digital Technology Co., Ltd", + [3]byte{244, 220, 218}: "Zhuhai Jiahe Communication Technology Co., limited", + [3]byte{244, 220, 249}: "Huawei Technologies Co., Ltd", + [3]byte{244, 221, 158}: "GoPro", + [3]byte{244, 225, 66}: "Delta Elektronika BV", + [3]byte{244, 230, 215}: "Solar Power Technologies, Inc.", + [3]byte{244, 234, 103}: "CISCO SYSTEMS, INC.", + [3]byte{244, 236, 56}: "TP-LINK TECHNOLOGIES CO., LTD.", + [3]byte{244, 238, 20}: "SHENZHEN MERCURY COMMUNICATION TECHNOLOGIES CO.,LTD.", + [3]byte{244, 241, 90}: "Apple", + [3]byte{244, 241, 225}: "Motorola Mobility LLC", + [3]byte{244, 242, 109}: "TP-LINK TECHNOLOGIES CO.,LTD.", + [3]byte{244, 245, 165}: "Nokia corporation", + [3]byte{244, 245, 232}: "Google", + [3]byte{244, 246, 70}: "Dediprog Technology Co. Ltd.", + [3]byte{244, 249, 81}: "Apple", + [3]byte{244, 252, 50}: "Texas Instruments", + [3]byte{244, 253, 43}: "ZOYI Company", + [3]byte{248, 1, 19}: "Huawei Technologies Co., Ltd", + [3]byte{248, 3, 50}: "Khomp", + [3]byte{248, 5, 28}: "DRS Imaging and Targeting Solutions", + [3]byte{248, 11, 190}: "ARRIS Group, Inc.", + [3]byte{248, 11, 208}: "Datang Telecom communication terminal (Tianjin) Co., Ltd.", + [3]byte{248, 12, 243}: "LG Electronics", + [3]byte{248, 13, 67}: "Hon Hai Precision Ind. Co., Ltd.", + [3]byte{248, 13, 234}: "ZyCast Technology Inc.", + [3]byte{248, 15, 65}: "Wistron InfoComm(ZhongShan) Corporation", + [3]byte{248, 15, 132}: "Natural Security SAS", + [3]byte{248, 16, 55}: "Atopia Systems, LP", + [3]byte{248, 21, 71}: "Avaya, Inc", + [3]byte{248, 22, 84}: "Intel Corporate", + [3]byte{248, 26, 103}: "TP-LINK TECHNOLOGIES CO., LTD.", + [3]byte{248, 28, 229}: "Telefonbau Behnke GmbH", + [3]byte{248, 29, 147}: "Longdhua(Beijing) Controls Technology Co.,Ltd", + [3]byte{248, 30, 223}: "Apple", + [3]byte{248, 34, 133}: "Cypress Technology CO., LTD.", + [3]byte{248, 36, 65}: "Yeelink", + [3]byte{248, 39, 147}: "Apple, Inc", + [3]byte{248, 43, 200}: "Jiangsu Switter Co., Ltd", + [3]byte{248, 46, 219}: "RTW GmbH & Co. KG", + [3]byte{248, 47, 91}: "eGauge Systems LLC", + [3]byte{248, 47, 168}: "Hon Hai Precision Ind. Co.,Ltd.", + [3]byte{248, 48, 148}: "Alcatel-Lucent Telecom Limited", + [3]byte{248, 49, 62}: "endeavour GmbH", + [3]byte{248, 51, 118}: "Good Mind Innovation Co., Ltd.", + [3]byte{248, 53, 83}: "Magenta Research Ltd.", + [3]byte{248, 53, 221}: "Gemtek Technology Co., Ltd.", + [3]byte{248, 61, 78}: "Softlink Automation System Co., Ltd", + [3]byte{248, 61, 255}: "Huawei Technologies Co., Ltd", + [3]byte{248, 66, 251}: "Yasuda Joho Co.,ltd.", + [3]byte{248, 67, 96}: "INGENICO", + [3]byte{248, 69, 173}: "Konka Group Co., Ltd.", + [3]byte{248, 70, 45}: "SYNTEC Incorporation", + [3]byte{248, 71, 45}: "X2gen Digital Corp. Ltd", + [3]byte{248, 72, 151}: "Hitachi, Ltd.", + [3]byte{248, 74, 115}: "EUMTECH CO., LTD", + [3]byte{248, 74, 127}: "Innometriks Inc", + [3]byte{248, 74, 191}: "HUAWEI TECHNOLOGIES CO.,LTD", + [3]byte{248, 79, 87}: "Cisco", + [3]byte{248, 80, 99}: "Verathon", + [3]byte{248, 81, 109}: "Denwa Technology Corp.", + [3]byte{248, 82, 223}: "VNL Europe AB", + [3]byte{248, 84, 175}: "ECI Telecom Ltd.", + [3]byte{248, 87, 46}: "Core Brands, LLC", + [3]byte{248, 91, 201}: "M-Cube Spa", + [3]byte{248, 92, 69}: "IC Nexus Co. Ltd.", + [3]byte{248, 95, 42}: "Nokia Corporation", + [3]byte{248, 98, 170}: "xn systems", + [3]byte{248, 102, 1}: "Suzhou Chi-tek information technology Co., Ltd", + [3]byte{248, 102, 209}: "Hon Hai Precision Ind. Co., Ltd.", + [3]byte{248, 102, 242}: "CISCO SYSTEMS, INC.", + [3]byte{248, 105, 113}: "Seibu Electric Co.,", + [3]byte{248, 110, 207}: "Arcx Inc", + [3]byte{248, 113, 254}: "The Goldman Sachs Group, Inc.", + [3]byte{248, 114, 234}: "Cisco", + [3]byte{248, 115, 148}: "NETGEAR INC.,", + [3]byte{248, 118, 155}: "Neopis Co., Ltd.", + [3]byte{248, 123, 98}: "FASTWEL INTERNATIONAL CO., LTD. Taiwan Branch", + [3]byte{248, 123, 122}: "ARRIS Group, Inc.", + [3]byte{248, 123, 140}: "Amped Wireless", + [3]byte{248, 129, 26}: "OVERKIZ", + [3]byte{248, 132, 121}: "Yaojin Technology(Shenzhen)Co.,Ltd", + [3]byte{248, 132, 242}: "Samsung Electronics Co.,Ltd", + [3]byte{248, 140, 28}: "KAISHUN ELECTRONIC TECHNOLOGY CO., LTD. BEIJING", + [3]byte{248, 141, 239}: "Tenebraex", + [3]byte{248, 142, 133}: "COMTREND CORPORATION", + [3]byte{248, 143, 202}: "Google Fiber, Inc", + [3]byte{248, 145, 42}: "GLP German Light Products GmbH", + [3]byte{248, 147, 243}: "VOLANS", + [3]byte{248, 149, 80}: "Proton Products Chengdu Ltd", + [3]byte{248, 151, 207}: "DAESHIN-INFORMATION TECHNOLOGY CO., LTD.", + [3]byte{248, 153, 85}: "Fortress Technology Inc", + [3]byte{248, 157, 13}: "Control Technology Inc.", + [3]byte{248, 159, 184}: "YAZAKI Energy System Corporation", + [3]byte{248, 160, 61}: "Dinstar Technologies Co., Ltd.", + [3]byte{248, 162, 180}: "RHEWA-WAAGENFABRIK August Freudewald GmbH &Co. KG", + [3]byte{248, 164, 95}: "Beijing Xiaomi communications co.,ltd", + [3]byte{248, 169, 99}: "COMPAL INFORMATION (KUNSHAN) CO., LTD.", + [3]byte{248, 169, 208}: "LG Electronics", + [3]byte{248, 169, 222}: "PUISSANCE PLUS", + [3]byte{248, 170, 138}: "Axview Technology (Shenzhen) Co.,Ltd", + [3]byte{248, 172, 109}: "Deltenna Ltd", + [3]byte{248, 177, 86}: "Dell Inc", + [3]byte{248, 178, 243}: "GUANGZHOU BOSMA TECHNOLOGY CO.,LTD", + [3]byte{248, 181, 153}: "Guangzhou CHNAVS Digital Technology Co.,Ltd", + [3]byte{248, 188, 18}: "Dell Inc", + [3]byte{248, 188, 65}: "Rosslare Enterprises Limited", + [3]byte{248, 192, 1}: "Juniper Networks", + [3]byte{248, 192, 145}: "Highgates Technology", + [3]byte{248, 194, 136}: "Cisco", + [3]byte{248, 198, 120}: "Carefusion", + [3]byte{248, 208, 172}: "Sony Computer Entertainment Inc.", + [3]byte{248, 208, 189}: "Samsung Electronics Co.,Ltd", + [3]byte{248, 209, 17}: "TP-LINK TECHNOLOGIES CO., LTD.", + [3]byte{248, 211, 169}: "AXAN Networks", + [3]byte{248, 212, 98}: "Pumatronix Equipamentos Eletronicos Ltda.", + [3]byte{248, 215, 86}: "Simm Tronic Limited", + [3]byte{248, 215, 191}: "REV Ritter GmbH", + [3]byte{248, 218, 223}: "EcoTech, Inc.", + [3]byte{248, 218, 226}: "Beta LaserMike", + [3]byte{248, 218, 244}: "Taishan Online Technology Co., Ltd.", + [3]byte{248, 219, 76}: "PNY Technologies, INC.", + [3]byte{248, 219, 127}: "HTC Corporation", + [3]byte{248, 219, 136}: "Dell Inc", + [3]byte{248, 220, 122}: "Variscite LTD", + [3]byte{248, 223, 168}: "ZTE Corporation", + [3]byte{248, 224, 121}: "Motorola Mobility LLC", + [3]byte{248, 228, 251}: "Actiontec Electronics, Inc", + [3]byte{248, 231, 181}: "µTech Tecnologia LTDA", + [3]byte{248, 232, 17}: "HUAWEI TECHNOLOGIES CO.,LTD", + [3]byte{248, 233, 3}: "D-Link International", + [3]byte{248, 233, 104}: "Egker Kft.", + [3]byte{248, 234, 10}: "Dipl.-Math. Michael Rauch", + [3]byte{248, 237, 165}: "ARRIS Group, Inc.", + [3]byte{248, 240, 5}: "Newport Media Inc.", + [3]byte{248, 240, 20}: "RackWare Inc.", + [3]byte{248, 240, 130}: "Orion Networks International, Inc", + [3]byte{248, 241, 182}: "Motorola Mobility LLC", + [3]byte{248, 242, 90}: "G-Lab GmbH", + [3]byte{248, 247, 211}: "International Communications Corporation", + [3]byte{248, 247, 255}: "SYN-TECH SYSTEMS INC", + [3]byte{248, 251, 47}: "Santur Corporation", + [3]byte{248, 254, 92}: "Reciprocal Labs Corp", + [3]byte{248, 254, 168}: "Technico Japan Corporation", + [3]byte{248, 255, 95}: "Shenzhen Communication Technology Co.,Ltd", + [3]byte{252, 0, 18}: "Toshiba Samsung Storage Technolgoy Korea Corporation", + [3]byte{252, 1, 158}: "VIEVU", + [3]byte{252, 1, 205}: "FUNDACION TEKNIKER", + [3]byte{252, 6, 71}: "Cortland Research, LLC", + [3]byte{252, 7, 160}: "LRE Medical GmbH", + [3]byte{252, 8, 119}: "Prentke Romich Company", + [3]byte{252, 9, 216}: "ACTEON Group", + [3]byte{252, 9, 246}: "GUANGDONG TONZE ELECTRIC CO.,LTD", + [3]byte{252, 10, 129}: "Motorola Solutions Inc.", + [3]byte{252, 15, 230}: "Sony Computer Entertainment Inc.", + [3]byte{252, 16, 189}: "Control Sistematizado S.A.", + [3]byte{252, 17, 134}: "Logic3 plc", + [3]byte{252, 19, 73}: "Global Apps Corp.", + [3]byte{252, 21, 180}: "Hewlett Packard", + [3]byte{252, 22, 7}: "Taian Technology(Wuxi) Co.,Ltd.", + [3]byte{252, 23, 148}: "InterCreative Co., Ltd", + [3]byte{252, 25, 16}: "Samsung Electronics Co.,Ltd", + [3]byte{252, 25, 208}: "Cloud Vision Networks Technology Co.,Ltd.", + [3]byte{252, 27, 255}: "V-ZUG AG", + [3]byte{252, 29, 89}: "I Smart Cities HK Ltd", + [3]byte{252, 29, 132}: "Autobase", + [3]byte{252, 30, 22}: "IPEVO corp", + [3]byte{252, 31, 25}: "SAMSUNG ELECTRO-MECHANICS CO., LTD.", + [3]byte{252, 31, 192}: "EURECAM", + [3]byte{252, 34, 156}: "Han Kyung I Net Co.,Ltd.", + [3]byte{252, 35, 37}: "EosTek (Shenzhen) Co., Ltd.", + [3]byte{252, 37, 63}: "Apple", + [3]byte{252, 39, 162}: "TRANS ELECTRIC CO., LTD.", + [3]byte{252, 42, 84}: "Connected Data, Inc.", + [3]byte{252, 46, 45}: "Lorom Industrial Co.LTD.", + [3]byte{252, 47, 64}: "Calxeda, Inc.", + [3]byte{252, 53, 152}: "Favite Inc.", + [3]byte{252, 53, 230}: "Visteon corp", + [3]byte{252, 63, 171}: "Henan Lanxin Technology Co., Ltd", + [3]byte{252, 68, 99}: "Universal Audio, Inc", + [3]byte{252, 68, 153}: "Swarco LEA d.o.o.", + [3]byte{252, 69, 95}: "JIANGXI SHANSHUI OPTOELECTRONIC TECHNOLOGY CO.,LTD", + [3]byte{252, 72, 239}: "HUAWEI TECHNOLOGIES CO.,LTD", + [3]byte{252, 74, 233}: "Castlenet Technology Inc.", + [3]byte{252, 75, 28}: "INTERSENSOR S.R.L.", + [3]byte{252, 75, 188}: "Sunplus Technology Co., Ltd.", + [3]byte{252, 77, 212}: "Universal Global Scientific Industrial Co., Ltd.", + [3]byte{252, 80, 144}: "SIMEX Sp. z o.o.", + [3]byte{252, 82, 206}: "Control iD", + [3]byte{252, 88, 250}: "Shen Zhen Shi Xin Zhong Xin Technology Co.,Ltd.", + [3]byte{252, 91, 36}: "Weibel Scientific A/S", + [3]byte{252, 91, 38}: "MikroBits", + [3]byte{252, 91, 57}: "Cisco", + [3]byte{252, 96, 24}: "Zhejiang Kangtai Electric Co., Ltd.", + [3]byte{252, 97, 152}: "NEC Personal Products, Ltd", + [3]byte{252, 98, 110}: "Beijing MDC Telecom", + [3]byte{252, 98, 185}: "ALPS ERECTRIC CO.,LTD", + [3]byte{252, 104, 62}: "Directed Perception, Inc", + [3]byte{252, 108, 49}: "LXinstruments GmbH", + [3]byte{252, 109, 192}: "BME CORPORATION", + [3]byte{252, 117, 22}: "D-Link International", + [3]byte{252, 117, 230}: "Handreamnet", + [3]byte{252, 121, 11}: "Hitachi High Technologies America, Inc.", + [3]byte{252, 124, 231}: "FCI USA LLC", + [3]byte{252, 131, 41}: "Trei technics", + [3]byte{252, 131, 153}: "Avaya, Inc", + [3]byte{252, 139, 151}: "Shenzhen Gongjin Electronics Co.,Ltd", + [3]byte{252, 142, 126}: "Pace plc", + [3]byte{252, 143, 196}: "Intelligent Technology Inc.", + [3]byte{252, 146, 59}: "Nokia Corporation", + [3]byte{252, 148, 108}: "UBIVELOX", + [3]byte{252, 148, 227}: "Technicolor USA Inc.", + [3]byte{252, 153, 71}: "Cisco", + [3]byte{252, 159, 174}: "Fidus Systems Inc", + [3]byte{252, 159, 225}: "CONWIN.Tech. Ltd", + [3]byte{252, 161, 62}: "Samsung Electronics", + [3]byte{252, 168, 65}: "Avaya, Inc", + [3]byte{252, 169, 176}: "MIARTECH (SHANGHAI),INC.", + [3]byte{252, 170, 20}: "GIGA-BYTE TECHNOLOGY CO.,LTD.", + [3]byte{252, 173, 15}: "QTS NETWORKS", + [3]byte{252, 175, 106}: "Conemtech AB", + [3]byte{252, 176, 196}: "Shanghai DareGlobal Technologies Co., Ltd", + [3]byte{252, 187, 161}: "Shenzhen Minicreate Technology Co.,Ltd", + [3]byte{252, 194, 61}: "Atmel Corporation", + [3]byte{252, 194, 222}: "Murata Manufacturing Co., Ltd.", + [3]byte{252, 199, 52}: "Samsung Electronics Co.,Ltd", + [3]byte{252, 200, 151}: "ZTE Corporation", + [3]byte{252, 204, 228}: "Ascon Ltd.", + [3]byte{252, 207, 98}: "IBM Corp", + [3]byte{252, 212, 242}: "The Coca Cola Company", + [3]byte{252, 212, 246}: "Messana Air.Ray Conditioning s.r.l.", + [3]byte{252, 213, 217}: "Shenzhen SDMC Technology Co., Ltd.", + [3]byte{252, 214, 189}: "Robert Bosch GmbH", + [3]byte{252, 216, 23}: "Beijing Hesun Technologies Co.Ltd.", + [3]byte{252, 219, 150}: "ENERVALLEY CO., LTD", + [3]byte{252, 219, 179}: "Murata Manufacturing Co., Ltd.", + [3]byte{252, 221, 85}: "Shenzhen WeWins wireless Co.,Ltd", + [3]byte{252, 225, 134}: "A3M Co., LTD", + [3]byte{252, 225, 146}: "Sichuan Jinwangtong Electronic Science&Technology Co,.Ltd", + [3]byte{252, 225, 217}: "Stable Imaging Solutions LLC", + [3]byte{252, 226, 63}: "CLAY PAKY SPA", + [3]byte{252, 229, 87}: "Nokia Corporation", + [3]byte{252, 232, 146}: "Hangzhou Lancable Technology Co.,Ltd", + [3]byte{252, 237, 185}: "Arrayent", + [3]byte{252, 241, 82}: "Sony Corporation", + [3]byte{252, 241, 205}: "OPTEX-FA CO.,LTD.", + [3]byte{252, 245, 40}: "ZyXEL Communications Corporation", + [3]byte{252, 246, 71}: "Fiberhome Telecommunication Tech.Co.,Ltd.", + [3]byte{252, 248, 174}: "Intel Corporate", + [3]byte{252, 248, 183}: "TRONTEQ Electronic", + [3]byte{252, 250, 247}: "Shanghai Baud Data Communication Co.,Ltd.", + [3]byte{252, 251, 251}: "CISCO SYSTEMS, INC.", + [3]byte{252, 254, 119}: "Hitachi Reftechno, Inc.", + [3]byte{252, 255, 170}: "IEEE REGISTRATION AUTHORITY - Please see MAL public listing for more information.", +} diff --git a/vendor/github.com/google/gopacket/packet.go b/vendor/github.com/google/gopacket/packet.go new file mode 100644 index 0000000..d7df656 --- /dev/null +++ b/vendor/github.com/google/gopacket/packet.go @@ -0,0 +1,821 @@ +// 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" + "os" + "reflect" + "runtime/debug" + "strings" + "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 +} + +// 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 + + // recoverPanics is true if we should recover from panics we see while + // decoding and set a DecodeFailure layer. + recoverPanics bool + + // 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) 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.recoverPanics { + 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 LayerType=%d\t%s", l.LayerType(), l.LayerType(), layerString(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(i interface{}, anonymous bool, writeSpace bool) string { + // feb 2016: + // issue: https://github.com/google/gopacket/issues/175 + // packet.Dump() - fails in Go 1.6 https://golang.org/doc/go1.6#reflect + // var bb bytes.Buffer + // fmt.Fprintf(&bb, "BROKEN: layerString: i=%T=%#v anonymous=%v writeSpace=%v", i, i, anonymous, writeSpace) + // return bb.String() + + // Let String() functions take precedence. + if s, ok := i.(fmt.Stringer); ok { + return s.String() + } + // Reflect, and spit out all the exported fields as key=value. + v := reflect.ValueOf(i) + switch v.Type().Kind() { + case reflect.Interface, reflect.Ptr: + if v.IsNil() { + return "nil" + } + r := v.Elem() + return layerString(r.Interface(), anonymous, writeSpace) + case reflect.Struct: + var b bytes.Buffer + typ := v.Type() + if !anonymous { + // b.WriteByte('{') + 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.Interface(), true, writeSpace) + + // this seems to only affect output like: + // "Contents=[..20..] Payload=[..1389..]" + // which appears to be "type BaseLayer struct" + // we can live without this in unifiedbeat, so + // just use an empty string when it's anonymous + anonStr := layerString("", 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.Interface(), false, writeSpace)) + } + } + if !anonymous { + // b.WriteByte('}') + 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).Interface(), 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 '{ ... ( 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('{') + b.WriteByte(' ') + for i := 0; i < v.NumField(); i += 1 { + 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('}') + 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 nilDecoderError = errors.New("NextDecoder passed nil decoder, probably an unsupported decode type") + +func (p *eagerPacket) NextDecoder(next Decoder) error { + if next == nil { + return nilDecoderError + } + 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 nilDecoderError + } + 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 +} + +// 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 = DecodeOptions{} + +// Lazy is a DecodeOptions with just Lazy set. +var Lazy DecodeOptions = DecodeOptions{Lazy: true} + +// NoCopy is a DecodeOptions with just NoCopy set. +var NoCopy DecodeOptions = DecodeOptions{NoCopy: 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}, + next: firstLayerDecoder, + } + p.layers = p.initialLayers[:0] + p.recoverPanics = !options.SkipDecodeRecovery + // 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}, + } + p.layers = p.initialLayers[:0] + p.recoverPanics = !options.SkipDecodeRecovery + 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) +} + +// 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. When it receives an error, it ignores it. When it +// receives an io.EOF, it closes the channel. +func (p *PacketSource) packetsToChannel() { + defer close(p.c) + for { + packet, err := p.NextPacket() + if err == io.EOF { + return + } else if err == nil { + p.c <- packet + } + } +} + +// 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 +} diff --git a/vendor/github.com/google/gopacket/packet.go.ORIGINAL b/vendor/github.com/google/gopacket/packet.go.ORIGINAL new file mode 100644 index 0000000..f2a576d --- /dev/null +++ b/vendor/github.com/google/gopacket/packet.go.ORIGINAL @@ -0,0 +1,802 @@ +// 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" + "os" + "reflect" + "runtime/debug" + "strings" + "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 +} + +// 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 + + // recoverPanics is true if we should recover from panics we see while + // decoding and set a DecodeFailure layer. + recoverPanics bool + + // 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) 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.recoverPanics { + 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(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(i interface{}, anonymous bool, writeSpace bool) string { + // Let String() functions take precedence. + if s, ok := i.(fmt.Stringer); ok { + return s.String() + } + // Reflect, and spit out all the exported fields as key=value. + v := reflect.ValueOf(i) + switch v.Type().Kind() { + case reflect.Interface, reflect.Ptr: + if v.IsNil() { + return "nil" + } + r := v.Elem() + return layerString(r.Interface(), 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.Interface(), 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.Interface(), 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).Interface(), 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 '{ ... ( 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 += 1 { + 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 nilDecoderError = errors.New("NextDecoder passed nil decoder, probably an unsupported decode type") + +func (p *eagerPacket) NextDecoder(next Decoder) error { + if next == nil { + return nilDecoderError + } + 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 nilDecoderError + } + 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 +} + +// 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 = DecodeOptions{} + +// Lazy is a DecodeOptions with just Lazy set. +var Lazy DecodeOptions = DecodeOptions{Lazy: true} + +// NoCopy is a DecodeOptions with just NoCopy set. +var NoCopy DecodeOptions = DecodeOptions{NoCopy: 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}, + next: firstLayerDecoder, + } + p.layers = p.initialLayers[:0] + p.recoverPanics = !options.SkipDecodeRecovery + // 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}, + } + p.layers = p.initialLayers[:0] + p.recoverPanics = !options.SkipDecodeRecovery + 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) +} + +// 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. When it receives an error, it ignores it. When it +// receives an io.EOF, it closes the channel. +func (p *PacketSource) packetsToChannel() { + defer close(p.c) + for { + packet, err := p.NextPacket() + if err == io.EOF { + return + } else if err == nil { + p.c <- packet + } + } +} + +// 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 +} diff --git a/vendor/github.com/google/gopacket/parser.go b/vendor/github.com/google/gopacket/parser.go new file mode 100644 index 0000000..f786834 --- /dev/null +++ b/vendor/github.com/google/gopacket/parser.go @@ -0,0 +1,198 @@ +// 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" +) + +// 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 +} + +// DecodingLayerParser parses a given set of layer types. See DecodeLayers for +// more information on how DecodingLayerParser should be used. +type DecodingLayerParser struct { + // DecodingLayerParserOptions is the set of options available to the + // user to define the parser's behavior. + DecodingLayerParserOptions + first LayerType + decoders map[LayerType]DecodingLayer + df DecodeFeedback + // 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) { + for _, typ := range d.CanDecode().LayerTypes() { + l.decoders[typ] = 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. +func NewDecodingLayerParser(first LayerType, decoders ...DecodingLayer) *DecodingLayerParser { + dlp := &DecodingLayerParser{ + decoders: make(map[LayerType]DecodingLayer), + first: first, + } + dlp.df = dlp // Cast this once to the interface + for _, d := range decoders { + dlp.AddDecodingLayer(d) + } + return dlp +} + +// 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 := l.first + *decoded = (*decoded)[:0] // Truncated decoded layers. + for len(data) > 0 { + decoder, ok := l.decoders[typ] + if !ok { + return UnsupportedLayerType(typ) + } else if err = decoder.DecodeFromBytes(data, l.df); err != nil { + return err + } + *decoded = append(*decoded, typ) + typ = decoder.NextLayerType() + data = decoder.LayerPayload() + } + return nil +} + +// 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 +} diff --git a/vendor/github.com/google/gopacket/pcap/doc.go b/vendor/github.com/google/gopacket/pcap/doc.go new file mode 100644 index 0000000..6289b2f --- /dev/null +++ b/vendor/github.com/google/gopacket/pcap/doc.go @@ -0,0 +1,100 @@ +// 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 pcap allows users of gopacket to read packets off the wire or from +pcap files. + +This package is meant to be used with its parent, +http://github.com/google/gopacket, although it can also be used independently +if you just want to get packet data from the wire. + +Reading PCAP Files + +The following code can be used to read in data from a pcap file. + + if handle, err := pcap.OpenOffline("/path/to/my/file"); err != nil { + panic(err) + } else { + packetSource := gopacket.NewPacketSource(handle, handle.LinkType()) + for packet := range packetSource.Packets() { + handlePacket(packet) // Do something with a packet here. + } + } + +Reading Live Packets + +The following code can be used to read in data from a live device, in this case +"eth0". + + if handle, err := pcap.OpenLive("eth0", 1600, true, pcap.BlockForever); err != nil { + panic(err) + } else if err := handle.SetBPFFilter("tcp and port 80"); err != nil { // optional + panic(err) + } else { + packetSource := gopacket.NewPacketSource(handle, handle.LinkType()) + for packet := range packetSource.Packets() { + handlePacket(packet) // Do something with a packet here. + } + } + +Inactive Handles + +Newer PCAP functionality requires the concept of an 'inactive' PCAP handle. +Instead of constantly adding new arguments to pcap_open_live, users now call +pcap_create to create a handle, set it up with a bunch of optional function +calls, then call pcap_activate to activate it. This library mirrors that +mechanism, for those that want to expose/use these new features: + + inactive, err := pcap.NewInactiveHandle(deviceName) + if err != nil { + log.Fatal(err) + } + defer inactive.CleanUp() + + // Call various functions on inactive to set it up the way you'd like: + if err = inactive.SetTimeout(time.Minute); err != nil { + log.Fatal(err) + } else if err = inactive.SetTimestampSource("foo"); err != nil { + log.Fatal(err) + } + + // Finally, create the actual handle by calling Activate: + handle, err := inactive.Activate() // after this, inactive is no longer valid + if err != nil { + log.Fatal(err) + } + defer handle.Close() + + // Now use your handle as you see fit. + +PCAP Timeouts + +pcap.OpenLive and pcap.SetTimeout both take timeouts. +If you don't care about timeouts, just pass in BlockForever, +which should do what you expect with minimal fuss. + +A timeout of 0 is not recommended. Some platforms, like Macs +(http://www.manpages.info/macosx/pcap.3.html) say: + The read timeout is used to arrange that the read not necessarily return + immediately when a packet is seen, but that it wait for some amount of time + to allow more packets to arrive and to read multiple packets from the OS + kernel in one operation. +This means that if you only capture one packet, the kernel might decide to wait +'timeout' for more packets to batch with it before returning. A timeout of +0, then, means 'wait forever for more packets', which is... not good. + +To get around this, we've introduced the following behavior: if a negative +timeout is passed in, we set the positive timeout in the handle, then loop +internally in ReadPacketData/ZeroCopyReadPacketData when we see timeout +errors. + +PCAP File Writing + +This package does not implement PCAP file writing. However, gopacket/pcapgo +does! Look there if you'd like to write PCAP files. +*/ +package pcap diff --git a/vendor/github.com/google/gopacket/pcap/gopacket_benchmark/benchmark.go b/vendor/github.com/google/gopacket/pcap/gopacket_benchmark/benchmark.go new file mode 100644 index 0000000..cbcae17 --- /dev/null +++ b/vendor/github.com/google/gopacket/pcap/gopacket_benchmark/benchmark.go @@ -0,0 +1,247 @@ +// 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. + +// This benchmark reads in file /gopacket_benchmark.pcap and measures +// the time it takes to decode all packets from that file. If the file doesn't +// exist, it's pulled down from a publicly available location. However, you can +// feel free to substitute your own file at that location, in which case the +// benchmark will run on your own data. +// +// It's also useful for figuring out which packets may be causing errors. Pass +// in the --printErrors flag, and it'll print out error layers for each packet +// that has them. This includes any packets that it's just unable to decode, +// which is a great way to find new protocols to decode, and get test packets to +// write tests for them. +package main + +import ( + "compress/gzip" + "encoding/hex" + "flag" + "fmt" + "github.com/google/gopacket" + "github.com/google/gopacket/layers" + "github.com/google/gopacket/pcap" + "github.com/google/gopacket/tcpassembly" + "io" + "io/ioutil" + "net/http" + "os" + "runtime" + "runtime/pprof" + "time" +) + +var decodeLazy *bool = flag.Bool("lazy", false, "If true, use lazy decoding") +var decodeNoCopy *bool = flag.Bool("nocopy", true, "If true, avoid an extra copy when decoding packets") +var printErrors *bool = flag.Bool("printErrors", false, "If true, check for and print error layers.") +var printLayers *bool = flag.Bool("printLayers", false, "If true, print out the layers of each packet") +var repeat *int = flag.Int("repeat", 5, "Read over the file N times") +var cpuProfile *string = flag.String("cpuprofile", "", "If set, write CPU profile to filename") +var url *string = flag.String("url", "http://www.ll.mit.edu/mission/communications/cyber/CSTcorpora/ideval/data/1999/training/week1/tuesday/inside.tcpdump.gz", "URL to gzip'd pcap file") + +type BufferPacketSource struct { + index int + data [][]byte + ci []gopacket.CaptureInfo +} + +func NewBufferPacketSource(p gopacket.PacketDataSource) *BufferPacketSource { + start := time.Now() + b := &BufferPacketSource{} + for { + data, ci, err := p.ReadPacketData() + if err == io.EOF { + break + } + b.data = append(b.data, data) + b.ci = append(b.ci, ci) + } + duration := time.Since(start) + fmt.Printf("Reading packet data into memory: %d packets in %v, %v per packet\n", len(b.data), duration, duration/time.Duration(len(b.data))) + return b +} + +func (b *BufferPacketSource) ReadPacketData() (data []byte, ci gopacket.CaptureInfo, err error) { + if b.index >= len(b.data) { + err = io.EOF + return + } + data = b.data[b.index] + ci = b.ci[b.index] + b.index++ + return +} + +func (b *BufferPacketSource) Reset() { + runtime.GC() + b.index = 0 +} + +func main() { + flag.Parse() + filename := os.TempDir() + string(os.PathSeparator) + "gopacket_benchmark.pcap" + if _, err := os.Stat(filename); err != nil { + // This URL points to a publicly available packet data set from a DARPA + // intrusion detection evaluation. See + // http://www.ll.mit.edu/mission/communications/cyber/CSTcorpora/ideval/data/1999/training/week1/index.html + // for more details. + fmt.Println("Local pcap file", filename, "doesn't exist, reading from", *url) + if resp, err := http.Get(*url); err != nil { + panic(err) + } else if out, err := os.Create(filename); err != nil { + panic(err) + } else if gz, err := gzip.NewReader(resp.Body); err != nil { + panic(err) + } else if n, err := io.Copy(out, gz); err != nil { + panic(err) + } else if err := gz.Close(); err != nil { + panic(err) + } else if err := out.Close(); err != nil { + panic(err) + } else { + fmt.Println("Successfully read", n, "bytes from url, unzipped to local storage") + } + } + fmt.Println("Reading file once through to hopefully cache most of it") + if f, err := os.Open(filename); err != nil { + panic(err) + } else if n, err := io.Copy(ioutil.Discard, f); err != nil { + panic(err) + } else if err := f.Close(); err != nil { + panic(err) + } else { + fmt.Println("Read in file", filename, ", total of", n, "bytes") + } + if *cpuProfile != "" { + if cpu, err := os.Create(*cpuProfile); err != nil { + panic(err) + } else if err := pprof.StartCPUProfile(cpu); err != nil { + panic(err) + } else { + defer func() { + pprof.StopCPUProfile() + cpu.Close() + }() + } + } + var packetDataSource *BufferPacketSource + var packetSource *gopacket.PacketSource + fmt.Printf("Opening file %q for read\n", filename) + if h, err := pcap.OpenOffline(filename); err != nil { + panic(err) + } else { + fmt.Println("Reading all packets into memory with BufferPacketSource.") + start := time.Now() + packetDataSource = NewBufferPacketSource(h) + duration := time.Since(start) + fmt.Printf("Time to read packet data into memory from file: %v\n", duration) + packetSource = gopacket.NewPacketSource(packetDataSource, h.LinkType()) + packetSource.DecodeOptions.Lazy = *decodeLazy + packetSource.DecodeOptions.NoCopy = *decodeNoCopy + } + fmt.Println() + for i := 0; i < *repeat; i++ { + packetDataSource.Reset() + fmt.Printf("Benchmarking decode %d/%d\n", i+1, *repeat) + benchmarkPacketDecode(packetSource) + } + fmt.Println() + for i := 0; i < *repeat; i++ { + packetDataSource.Reset() + fmt.Printf("Benchmarking decoding layer parser %d/%d\n", i+1, *repeat) + benchmarkLayerDecode(packetDataSource, false) + } + fmt.Println() + for i := 0; i < *repeat; i++ { + packetDataSource.Reset() + fmt.Printf("Benchmarking decoding layer parser with assembly %d/%d\n", i+1, *repeat) + benchmarkLayerDecode(packetDataSource, true) + } +} + +func benchmarkPacketDecode(packetSource *gopacket.PacketSource) { + count, errors := 0, 0 + start := time.Now() + for packet, err := packetSource.NextPacket(); err != io.EOF; packet, err = packetSource.NextPacket() { + if err != nil { + fmt.Println("Error reading in packet:", err) + continue + } + count++ + var hasError bool + if *printErrors && packet.ErrorLayer() != nil { + fmt.Println("\n\n\nError decoding packet:", packet.ErrorLayer().Error()) + fmt.Println(hex.Dump(packet.Data())) + fmt.Printf("%#v\n", packet.Data()) + errors++ + hasError = true + } + if *printLayers || hasError { + fmt.Printf("\n=== PACKET %d ===\n", count) + for _, l := range packet.Layers() { + fmt.Printf("--- LAYER %v ---\n%#v\n\n", l.LayerType(), l) + } + fmt.Println() + } + } + duration := time.Since(start) + fmt.Printf("\tRead in %v packets in %v, %v per packet\n", count, duration, duration/time.Duration(count)) + if *printErrors { + fmt.Printf("%v errors, successfully decoded %.02f%%\n", errors, float64(count-errors)*100.0/float64(count)) + } +} + +type streamFactory struct { +} + +func (s *streamFactory) New(netFlow, tcpFlow gopacket.Flow) tcpassembly.Stream { + return s +} +func (s *streamFactory) Reassembled([]tcpassembly.Reassembly) { +} +func (s *streamFactory) ReassemblyComplete() { +} + +func benchmarkLayerDecode(source *BufferPacketSource, assemble bool) { + var tcp layers.TCP + var ip layers.IPv4 + var eth layers.Ethernet + var udp layers.UDP + var icmp layers.ICMPv4 + var payload gopacket.Payload + parser := gopacket.NewDecodingLayerParser( + layers.LayerTypeEthernet, + ð, &ip, &icmp, &tcp, &udp, &payload) + pool := tcpassembly.NewStreamPool(&streamFactory{}) + assembler := tcpassembly.NewAssembler(pool) + var decoded []gopacket.LayerType + start := time.Now() + packets, decodedlayers, assembled := 0, 0, 0 + for { + packets++ + data, ci, err := source.ReadPacketData() + if err == io.EOF { + break + } else if err != nil { + fmt.Println("Error reading packet: ", err) + continue + } + err = parser.DecodeLayers(data, &decoded) + for _, typ := range decoded { + decodedlayers++ + if typ == layers.LayerTypeTCP && assemble { + assembled++ + assembler.AssembleWithTimestamp(ip.NetworkFlow(), &tcp, ci.Timestamp) + } + } + } + if assemble { + assembler.FlushAll() + } + duration := time.Since(start) + fmt.Printf("\tRead in %d packets in %v, decoded %v layers, assembled %v packets: %v per packet\n", packets, duration, decodedlayers, assembled, duration/time.Duration(packets)) +} diff --git a/vendor/github.com/google/gopacket/pcap/pcap.go b/vendor/github.com/google/gopacket/pcap/pcap.go new file mode 100644 index 0000000..b8eb666 --- /dev/null +++ b/vendor/github.com/google/gopacket/pcap/pcap.go @@ -0,0 +1,911 @@ +// 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 pcap + +/* +#cgo solaris LDFLAGS: -L /opt/local/lib -lpcap +#cgo linux LDFLAGS: -lpcap +#cgo dragonfly LDFLAGS: -lpcap +#cgo freebsd LDFLAGS: -lpcap +#cgo openbsd LDFLAGS: -lpcap +#cgo darwin LDFLAGS: -lpcap +#cgo windows CFLAGS: -I C:/WpdPack/Include +#cgo windows,386 LDFLAGS: -L C:/WpdPack/Lib -lwpcap +#cgo windows,amd64 LDFLAGS: -L C:/WpdPack/Lib/x64 -lwpcap +#include +#include + +// Some old versions of pcap don't define this constant. +#ifndef PCAP_NETMASK_UNKNOWN +#define PCAP_NETMASK_UNKNOWN 0xffffffff +#endif + +// libpcap doesn't actually export its version in a #define-guardable way, +// so we have to use other defined things to differentiate versions. +// We assume at least libpcap v1.1 at the moment. +// See http://upstream-tracker.org/versions/libpcap.html + +#ifndef PCAP_ERROR_TSTAMP_PRECISION_NOTSUP // < v1.5 + +int pcap_set_immediate_mode(pcap_t *p, int mode) { + return PCAP_ERROR; +} + +#ifndef PCAP_TSTAMP_HOST // < v1.2 + +int pcap_set_tstamp_type(pcap_t* p, int t) { return -1; } +int pcap_list_tstamp_types(pcap_t* p, int** t) { return 0; } +void pcap_free_tstamp_types(int *tstamp_types) {} +const char* pcap_tstamp_type_val_to_name(int t) { + return "pcap timestamp types not supported"; +} +int pcap_tstamp_type_name_to_val(const char* t) { + return PCAP_ERROR; +} + +#endif // < v1.2 +#endif // < v1.5 + +#ifndef PCAP_ERROR_PROMISC_PERM_DENIED +#define PCAP_ERROR_PROMISC_PERM_DENIED -11 +#endif + +// WinPcap doesn't export a pcap_statustostr, so use the less-specific +// pcap_strerror. Note that linking against something like cygwin libpcap +// may result is less-specific error messages. +#ifdef WIN32 +#define pcap_statustostr pcap_strerror + +// WinPcap also doesn't export pcap_can_set_rfmon and pcap_set_rfmon, +// as those are handled by separate libraries (airpcap). +// https://www.winpcap.org/docs/docs_412/html/group__wpcapfunc.html +// Stub out those functions here, returning values that indicate rfmon +// setting is unavailable/unsuccessful. +int pcap_can_set_rfmon(pcap_t *p) { + return 0; +} + +int pcap_set_rfmon(pcap_t *p, int rfmon) { + return PCAP_ERROR; +} +#endif + +// Windows, Macs, and Linux all use different time types. Joy. +#ifdef WIN32 +#define gopacket_time_secs_t long +#define gopacket_time_usecs_t long +#elif __APPLE__ +#define gopacket_time_secs_t __darwin_time_t +#define gopacket_time_usecs_t __darwin_suseconds_t +#elif __GLIBC__ +#define gopacket_time_secs_t __time_t +#define gopacket_time_usecs_t __suseconds_t +#else +#define gopacket_time_secs_t time_t +#define gopacket_time_usecs_t suseconds_t +#endif +*/ +import "C" + +import ( + "errors" + "fmt" + "io" + "net" + "reflect" + "runtime" + "strconv" + "sync" + "syscall" + "time" + "unsafe" + + "github.com/google/gopacket" + "github.com/google/gopacket/layers" +) + +const errorBufferSize = 256 + +// Maximum number of BPF instructions supported (BPF_MAXINSNS), +// taken from Linux kernel: include/uapi/linux/bpf_common.h +// +// https://github.com/torvalds/linux/blob/master/include/uapi/linux/bpf_common.h +const MaxBpfInstructions = 4096 + +// 8 bytes per instruction, max 4096 instructions +const bpfInstructionBufferSize = 8 * MaxBpfInstructions + +// Handle provides a connection to a pcap handle, allowing users to read packets +// off the wire (Next), inject packets onto the wire (Inject), and +// perform a number of other functions to affect and understand packet output. +// +// Handles are already pcap_activate'd +type Handle struct { + // cptr is the handle for the actual pcap C object. + cptr *C.pcap_t + blockForever bool + device string + mu sync.Mutex + // Since pointers to these objects are passed into a C function, if + // they're declared locally then the Go compiler thinks they may have + // escaped into C-land, so it allocates them on the heap. This causes a + // huge memory hit, so to handle that we store them here instead. + pkthdr *C.struct_pcap_pkthdr + buf_ptr *C.u_char +} + +// Stats contains statistics on how many packets were handled by a pcap handle, +// and what was done with those packets. +type Stats struct { + PacketsReceived int + PacketsDropped int + PacketsIfDropped int +} + +// Interface describes a single network interface on a machine. +type Interface struct { + Name string + Description string + Addresses []InterfaceAddress + // TODO: add more elements +} + +// Datalink describes the datalink +type Datalink struct { + Name string + Description string +} + +// InterfaceAddress describes an address associated with an Interface. +// Currently, it's IPv4/6 specific. +type InterfaceAddress struct { + IP net.IP + Netmask net.IPMask // Netmask may be nil if we were unable to retrieve it. + // TODO: add broadcast + PtP dst ? +} + +// BPF is a compiled filter program, useful for offline packet matching. +type BPF struct { + orig string + bpf _Ctype_struct_bpf_program // takes a finalizer, not overriden by outsiders +} + +// BPFInstruction is a byte encoded structure holding a BPF instruction +type BPFInstruction struct { + Code uint16 + Jt uint8 + Jf uint8 + K uint32 +} + +// BlockForever, when passed into OpenLive/SetTimeout, causes it to block forever +// waiting for packets, while still returning incoming packets to userland relatively +// quickly. +const BlockForever = -time.Millisecond * 10 + +func timeoutMillis(timeout time.Duration) C.int { + // Flip sign if necessary. See package docs on timeout for reasoning behind this. + if timeout < 0 { + timeout *= -1 + } + // Round up + if timeout != 0 && timeout < time.Millisecond { + timeout = time.Millisecond + } + return C.int(timeout / time.Millisecond) +} + +// OpenLive opens a device and returns a *Handle. +// It takes as arguments the name of the device ("eth0"), the maximum size to +// read for each packet (snaplen), whether to put the interface in promiscuous +// mode, and a timeout. +// +// See the package documentation for important details regarding 'timeout'. +func OpenLive(device string, snaplen int32, promisc bool, timeout time.Duration) (handle *Handle, _ error) { + buf := (*C.char)(C.calloc(errorBufferSize, 1)) + defer C.free(unsafe.Pointer(buf)) + var pro C.int + if promisc { + pro = 1 + } + p := &Handle{} + p.blockForever = timeout < 0 + p.device = device + + dev := C.CString(device) + defer C.free(unsafe.Pointer(dev)) + + p.cptr = C.pcap_open_live(dev, C.int(snaplen), pro, timeoutMillis(timeout), buf) + if p.cptr == nil { + return nil, errors.New(C.GoString(buf)) + } + return p, nil +} + +// OpenOffline opens a file and returns its contents as a *Handle. +func OpenOffline(file string) (handle *Handle, err error) { + buf := (*C.char)(C.calloc(errorBufferSize, 1)) + defer C.free(unsafe.Pointer(buf)) + cf := C.CString(file) + defer C.free(unsafe.Pointer(cf)) + + cptr := C.pcap_open_offline(cf, buf) + if cptr == nil { + return nil, errors.New(C.GoString(buf)) + } + return &Handle{cptr: cptr}, nil +} + +// NextError is the return code from a call to Next. +type NextError int32 + +// NextError implements the error interface. +func (n NextError) Error() string { + switch n { + case NextErrorOk: + return "OK" + case NextErrorTimeoutExpired: + return "Timeout Expired" + case NextErrorReadError: + return "Read Error" + case NextErrorNoMorePackets: + return "No More Packets In File" + case NextErrorNotActivated: + return "Not Activated" + } + return strconv.Itoa(int(n)) +} + +const ( + NextErrorOk NextError = 1 + NextErrorTimeoutExpired NextError = 0 + NextErrorReadError NextError = -1 + // NextErrorNoMorePackets is returned when reading from a file (OpenOffline) and + // EOF is reached. When this happens, Next() returns io.EOF instead of this. + NextErrorNoMorePackets NextError = -2 + NextErrorNotActivated NextError = -3 +) + +// NextError returns the next packet read from the pcap handle, along with an error +// code associated with that packet. If the packet is read successfully, the +// returned error is nil. +func (p *Handle) ReadPacketData() (data []byte, ci gopacket.CaptureInfo, err error) { + p.mu.Lock() + err = p.getNextBufPtrLocked(&ci) + if err == nil { + data = C.GoBytes(unsafe.Pointer(p.buf_ptr), C.int(ci.CaptureLength)) + } + p.mu.Unlock() + return +} + +type activateError C.int + +const ( + aeNoError = 0 + aeActivated = C.PCAP_ERROR_ACTIVATED + aePromisc = C.PCAP_WARNING_PROMISC_NOTSUP + aeNoSuchDevice = C.PCAP_ERROR_NO_SUCH_DEVICE + aeDenied = C.PCAP_ERROR_PERM_DENIED + aeNotUp = C.PCAP_ERROR_IFACE_NOT_UP +) + +func (a activateError) Error() string { + switch a { + case aeNoError: + return "No Error" + case aeActivated: + return "Already Activated" + case aePromisc: + return "Cannot set as promisc" + case aeNoSuchDevice: + return "No Such Device" + case aeDenied: + return "Permission Denied" + case aeNotUp: + return "Interface Not Up" + default: + return fmt.Sprintf("unknown activated error: %d", a) + } +} + +// getNextBufPtrLocked is shared code for ReadPacketData and +// ZeroCopyReadPacketData. +func (p *Handle) getNextBufPtrLocked(ci *gopacket.CaptureInfo) error { + if p.cptr == nil { + return io.EOF + } + var result NextError + for { + result = NextError(C.pcap_next_ex(p.cptr, &p.pkthdr, &p.buf_ptr)) + if p.blockForever && result == NextErrorTimeoutExpired { + continue + } + break + } + if result != NextErrorOk { + if result == NextErrorNoMorePackets { + return io.EOF + } else { + return result + } + } + ci.Timestamp = time.Unix(int64(p.pkthdr.ts.tv_sec), + int64(p.pkthdr.ts.tv_usec)*1000) // convert micros to nanos + ci.CaptureLength = int(p.pkthdr.caplen) + ci.Length = int(p.pkthdr.len) + return nil +} + +// ZeroCopyReadPacketData reads the next packet off the wire, and returns its data. +// The slice returned by ZeroCopyReadPacketData points to bytes owned by the +// the Handle. Each call to ZeroCopyReadPacketData invalidates any data previously +// returned by ZeroCopyReadPacketData. Care must be taken not to keep pointers +// to old bytes when using ZeroCopyReadPacketData... if you need to keep data past +// the next time you call ZeroCopyReadPacketData, use ReadPacketData, which copies +// the bytes into a new buffer for you. +// data1, _, _ := handle.ZeroCopyReadPacketData() +// // do everything you want with data1 here, copying bytes out of it if you'd like to keep them around. +// data2, _, _ := handle.ZeroCopyReadPacketData() // invalidates bytes in data1 +func (p *Handle) ZeroCopyReadPacketData() (data []byte, ci gopacket.CaptureInfo, err error) { + p.mu.Lock() + err = p.getNextBufPtrLocked(&ci) + if err == nil { + slice := (*reflect.SliceHeader)(unsafe.Pointer(&data)) + slice.Data = uintptr(unsafe.Pointer(p.buf_ptr)) + slice.Len = ci.CaptureLength + slice.Cap = ci.CaptureLength + } + p.mu.Unlock() + return +} + +// Close closes the underlying pcap handle. +func (p *Handle) Close() { + p.mu.Lock() + if p.cptr == nil { + return + } + C.pcap_close(p.cptr) + p.cptr = nil + p.mu.Unlock() +} + +// Error returns the current error associated with a pcap handle (pcap_geterr). +func (p *Handle) Error() error { + return errors.New(C.GoString(C.pcap_geterr(p.cptr))) +} + +// Stats returns statistics on the underlying pcap handle. +func (p *Handle) Stats() (stat *Stats, err error) { + var cstats _Ctype_struct_pcap_stat + if -1 == C.pcap_stats(p.cptr, &cstats) { + return nil, p.Error() + } + return &Stats{ + PacketsReceived: int(cstats.ps_recv), + PacketsDropped: int(cstats.ps_drop), + PacketsIfDropped: int(cstats.ps_ifdrop), + }, nil +} + +// Obtains a list of all possible data link types supported for an interface. +func (p *Handle) ListDataLinks() (datalinks []Datalink, err error) { + var dlt_buf *C.int + + n := int(C.pcap_list_datalinks(p.cptr, &dlt_buf)) + if -1 == n { + return nil, p.Error() + } + + defer C.pcap_free_datalinks(dlt_buf) + + datalinks = make([]Datalink, n) + + dltArray := (*[100]C.int)(unsafe.Pointer(dlt_buf)) + + for i := 0; i < n; i++ { + expr := C.pcap_datalink_val_to_name((*dltArray)[i]) + datalinks[i].Name = C.GoString(expr) + + expr = C.pcap_datalink_val_to_description((*dltArray)[i]) + datalinks[i].Description = C.GoString(expr) + } + + return datalinks, nil +} + +// compileBPFFilter always returns an allocated _Ctype_struct_bpf_program +// It is the callers responsibility to free the memory again, e.g. +// +// C.pcap_freecode(&bpf) +// +func (p *Handle) compileBPFFilter(expr string) (_Ctype_struct_bpf_program, error) { + errorBuf := (*C.char)(C.calloc(errorBufferSize, 1)) + defer C.free(unsafe.Pointer(errorBuf)) + + var netp uint32 + var maskp uint32 + + // Only do the lookup on network interfaces. + // No device indicates we're handling a pcap file. + if len(p.device) > 0 { + dev := C.CString(p.device) + defer C.free(unsafe.Pointer(dev)) + if -1 == C.pcap_lookupnet( + dev, + (*C.bpf_u_int32)(unsafe.Pointer(&netp)), + (*C.bpf_u_int32)(unsafe.Pointer(&maskp)), + errorBuf, + ) { + // We can't lookup the network, but that could be because the interface + // doesn't have an IPv4. + } + } + + var bpf _Ctype_struct_bpf_program + cexpr := C.CString(expr) + defer C.free(unsafe.Pointer(cexpr)) + + if -1 == C.pcap_compile(p.cptr, &bpf, cexpr, 1, C.bpf_u_int32(maskp)) { + return bpf, p.Error() + } + + return bpf, nil +} + +// CompileBPFFilter compiles and returns a BPF filter for the pcap handle. +func (p *Handle) CompileBPFFilter(expr string) ([]BPFInstruction, error) { + bpf, err := p.compileBPFFilter(expr) + defer C.pcap_freecode(&bpf) + if err != nil { + return nil, err + } + + bpfInsn := (*[bpfInstructionBufferSize]_Ctype_struct_bpf_insn)(unsafe.Pointer(bpf.bf_insns))[0:bpf.bf_len:bpf.bf_len] + bpfInstruction := make([]BPFInstruction, len(bpfInsn), len(bpfInsn)) + + for i, v := range bpfInsn { + bpfInstruction[i].Code = uint16(v.code) + bpfInstruction[i].Jt = uint8(v.jt) + bpfInstruction[i].Jf = uint8(v.jf) + bpfInstruction[i].K = uint32(v.k) + } + + return bpfInstruction, nil +} + +// SetBPFFilter compiles and sets a BPF filter for the pcap handle. +func (p *Handle) SetBPFFilter(expr string) (err error) { + bpf, err := p.compileBPFFilter(expr) + defer C.pcap_freecode(&bpf) + if err != nil { + return err + } + + if -1 == C.pcap_setfilter(p.cptr, &bpf) { + C.pcap_freecode(&bpf) + return p.Error() + } + + return nil +} + +// SetBPFInstructionFilter may be used to apply a filter in BPF asm byte code format. +// +// Simplest way to generate BPF asm byte code is with tcpdump: +// tcpdump -dd 'udp' +// +// The output may be used directly to add a filter, e.g.: +// bpfInstructions := []pcap.BpfInstruction{ +// {0x28, 0, 0, 0x0000000c}, +// {0x15, 0, 9, 0x00000800}, +// {0x30, 0, 0, 0x00000017}, +// {0x15, 0, 7, 0x00000006}, +// {0x28, 0, 0, 0x00000014}, +// {0x45, 5, 0, 0x00001fff}, +// {0xb1, 0, 0, 0x0000000e}, +// {0x50, 0, 0, 0x0000001b}, +// {0x54, 0, 0, 0x00000012}, +// {0x15, 0, 1, 0x00000012}, +// {0x6, 0, 0, 0x0000ffff}, +// {0x6, 0, 0, 0x00000000}, +// } +// +// An other posibility is to write the bpf code in bpf asm. +// Documentation: https://www.kernel.org/doc/Documentation/networking/filter.txt +// +// To compile the code use bpf_asm from +// https://github.com/torvalds/linux/tree/master/tools/net +// +// The following command may be used to convert bpf_asm output to c/go struct, usable for SetBPFFilterByte: +// bpf_asm -c tcp.bpf +func (p *Handle) SetBPFInstructionFilter(bpfInstructions []BPFInstruction) (err error) { + bpf, err := bpfInstructionFilter(bpfInstructions) + if err != nil { + return err + } + + if -1 == C.pcap_setfilter(p.cptr, &bpf) { + C.pcap_freecode(&bpf) + return p.Error() + } + + C.pcap_freecode(&bpf) + + return nil +} +func bpfInstructionFilter(bpfInstructions []BPFInstruction) (bpf _Ctype_struct_bpf_program, err error) { + if len(bpfInstructions) < 1 { + return bpf, errors.New("bpfInstructions must not be empty") + } + + if len(bpfInstructions) > MaxBpfInstructions { + return bpf, fmt.Errorf("bpfInstructions must not be larger than %d", MaxBpfInstructions) + } + + bpf.bf_len = C.u_int(len(bpfInstructions)) + cbpfInsns := C.calloc(C.size_t(len(bpfInstructions)), C.size_t(unsafe.Sizeof(bpfInstructions[0]))) + + copy((*[bpfInstructionBufferSize]BPFInstruction)(cbpfInsns)[0:len(bpfInstructions)], bpfInstructions) + bpf.bf_insns = (*_Ctype_struct_bpf_insn)(cbpfInsns) + + return +} + +// NewBPF compiles the given string into a new filter program. +// +// BPF filters need to be created from activated handles, because they need to +// know the underlying link type to correctly compile their offsets. +func (p *Handle) NewBPF(expr string) (*BPF, error) { + bpf := &BPF{orig: expr} + cexpr := C.CString(expr) + defer C.free(unsafe.Pointer(cexpr)) + + if C.pcap_compile(p.cptr, &bpf.bpf, cexpr /* optimize */, 1, C.PCAP_NETMASK_UNKNOWN) != 0 { + return nil, p.Error() + } + + runtime.SetFinalizer(bpf, destroyBPF) + return bpf, nil +} + +// NewBPFInstructionFilter sets the given BPFInstructions as new filter program. +// +// More details see func SetBPFInstructionFilter +// +// BPF filters need to be created from activated handles, because they need to +// know the underlying link type to correctly compile their offsets. +func (p *Handle) NewBPFInstructionFilter(bpfInstructions []BPFInstruction) (*BPF, error) { + var err error + bpf := &BPF{orig: "BPF Instruction Filter"} + + bpf.bpf, err = bpfInstructionFilter(bpfInstructions) + if err != nil { + return nil, err + } + + runtime.SetFinalizer(bpf, destroyBPF) + return bpf, nil +} +func destroyBPF(bpf *BPF) { + C.pcap_freecode(&bpf.bpf) +} + +// String returns the original string this BPF filter was compiled from. +func (b *BPF) String() string { + return b.orig +} + +// Matches returns true if the given packet data matches this filter. +func (b *BPF) Matches(ci gopacket.CaptureInfo, data []byte) bool { + var hdr C.struct_pcap_pkthdr + hdr.ts.tv_sec = C.gopacket_time_secs_t(ci.Timestamp.Unix()) + hdr.ts.tv_usec = C.gopacket_time_usecs_t(ci.Timestamp.Nanosecond() / 1000) + hdr.caplen = C.bpf_u_int32(len(data)) // Trust actual length over ci.Length. + hdr.len = C.bpf_u_int32(ci.Length) + dataptr := (*C.u_char)(unsafe.Pointer(&data[0])) + return C.pcap_offline_filter(&b.bpf, &hdr, dataptr) != 0 +} + +// Version returns pcap_lib_version. +func Version() string { + return C.GoString(C.pcap_lib_version()) +} + +// LinkType returns pcap_datalink, as a layers.LinkType. +func (p *Handle) LinkType() layers.LinkType { + return layers.LinkType(C.pcap_datalink(p.cptr)) +} + +// SetLinkType calls pcap_set_datalink on the pcap handle. +func (p *Handle) SetLinkType(dlt layers.LinkType) error { + if -1 == C.pcap_set_datalink(p.cptr, C.int(dlt)) { + return p.Error() + } + return nil +} + +// FindAllDevs attempts to enumerate all interfaces on the current machine. +func FindAllDevs() (ifs []Interface, err error) { + var buf *C.char + buf = (*C.char)(C.calloc(errorBufferSize, 1)) + defer C.free(unsafe.Pointer(buf)) + var alldevsp *C.pcap_if_t + + if -1 == C.pcap_findalldevs((**C.pcap_if_t)(&alldevsp), buf) { + return nil, errors.New(C.GoString(buf)) + } + defer C.pcap_freealldevs((*C.pcap_if_t)(alldevsp)) + dev := alldevsp + var i uint32 + for i = 0; dev != nil; dev = (*C.pcap_if_t)(dev.next) { + i++ + } + ifs = make([]Interface, i) + dev = alldevsp + for j := uint32(0); dev != nil; dev = (*C.pcap_if_t)(dev.next) { + var iface Interface + iface.Name = C.GoString(dev.name) + iface.Description = C.GoString(dev.description) + iface.Addresses = findalladdresses(dev.addresses) + // TODO: add more elements + ifs[j] = iface + j++ + } + return +} + +func findalladdresses(addresses *_Ctype_struct_pcap_addr) (retval []InterfaceAddress) { + // TODO - make it support more than IPv4 and IPv6? + retval = make([]InterfaceAddress, 0, 1) + for curaddr := addresses; curaddr != nil; curaddr = (*_Ctype_struct_pcap_addr)(curaddr.next) { + // Strangely, it appears that in some cases, we get a pcap address back from + // pcap_findalldevs with a nil .addr. It appears that we can skip over + // these. + if curaddr.addr == nil { + continue + } + var a InterfaceAddress + var err error + if a.IP, err = sockaddr_to_IP((*syscall.RawSockaddr)(unsafe.Pointer(curaddr.addr))); err != nil { + continue + } + // To be safe, we'll also check for netmask. + if curaddr.netmask == nil { + continue + } + if a.Netmask, err = sockaddr_to_IP((*syscall.RawSockaddr)(unsafe.Pointer(curaddr.netmask))); err != nil { + // If we got an IP address but we can't get a netmask, just return the IP + // address. + a.Netmask = nil + } + retval = append(retval, a) + } + return +} + +func sockaddr_to_IP(rsa *syscall.RawSockaddr) (IP []byte, err error) { + switch rsa.Family { + case syscall.AF_INET: + pp := (*syscall.RawSockaddrInet4)(unsafe.Pointer(rsa)) + IP = make([]byte, 4) + for i := 0; i < len(IP); i++ { + IP[i] = pp.Addr[i] + } + return + case syscall.AF_INET6: + pp := (*syscall.RawSockaddrInet6)(unsafe.Pointer(rsa)) + IP = make([]byte, 16) + for i := 0; i < len(IP); i++ { + IP[i] = pp.Addr[i] + } + return + } + err = errors.New("Unsupported address type") + return +} + +// WritePacketData calls pcap_sendpacket, injecting the given data into the pcap handle. +func (p *Handle) WritePacketData(data []byte) (err error) { + if -1 == C.pcap_sendpacket(p.cptr, (*C.u_char)(&data[0]), (C.int)(len(data))) { + err = p.Error() + } + return +} + +// Direction is used by Handle.SetDirection. +type Direction uint8 + +const ( + DirectionIn Direction = C.PCAP_D_IN + DirectionOut Direction = C.PCAP_D_OUT + DirectionInOut Direction = C.PCAP_D_INOUT +) + +// SetDirection sets the direction for which packets will be captured. +func (p *Handle) SetDirection(direction Direction) error { + if direction != DirectionIn && direction != DirectionOut && direction != DirectionInOut { + return fmt.Errorf("Invalid direction: %v", direction) + } + if status := C.pcap_setdirection(p.cptr, (C.pcap_direction_t)(direction)); status < 0 { + return statusError(status) + } + return nil +} + +// TimestampSource tells PCAP which type of timestamp to use for packets. +type TimestampSource C.int + +// String returns the timestamp type as a human-readable string. +func (t TimestampSource) String() string { + return C.GoString(C.pcap_tstamp_type_val_to_name(C.int(t))) +} + +// TimestampSourceFromString translates a string into a timestamp type, case +// insensitive. +func TimestampSourceFromString(s string) (TimestampSource, error) { + t := C.pcap_tstamp_type_name_to_val(C.CString(s)) + if t < 0 { + return 0, statusError(t) + } + return TimestampSource(t), nil +} + +func statusError(status C.int) error { + return errors.New(C.GoString(C.pcap_statustostr(status))) +} + +// InactiveHandle allows you to call pre-pcap_activate functions on your pcap +// handle to set it up just the way you'd like. +type InactiveHandle struct { + // cptr is the handle for the actual pcap C object. + cptr *C.pcap_t + device string + blockForever bool +} + +// Activate activates the handle. The current InactiveHandle becomes invalid +// and all future function calls on it will fail. +func (p *InactiveHandle) Activate() (*Handle, error) { + err := activateError(C.pcap_activate(p.cptr)) + if err != aeNoError { + return nil, err + } + h := &Handle{cptr: p.cptr, device: p.device, blockForever: p.blockForever} + p.cptr = nil + return h, nil +} + +// CleanUp cleans up any stuff left over from a successful or failed building +// of a handle. +func (p *InactiveHandle) CleanUp() { + if p.cptr != nil { + C.pcap_close(p.cptr) + } +} + +// NewInactiveHandle creates a new InactiveHandle, which wraps an un-activated PCAP handle. +// Callers of NewInactiveHandle should immediately defer 'CleanUp', as in: +// inactive := NewInactiveHandle("eth0") +// defer inactive.CleanUp() +func NewInactiveHandle(device string) (*InactiveHandle, error) { + buf := (*C.char)(C.calloc(errorBufferSize, 1)) + defer C.free(unsafe.Pointer(buf)) + dev := C.CString(device) + defer C.free(unsafe.Pointer(dev)) + + // This copies a bunch of the pcap_open_live implementation from pcap.c: + cptr := C.pcap_create(dev, buf) + if cptr == nil { + return nil, errors.New(C.GoString(buf)) + } + return &InactiveHandle{cptr: cptr, device: device}, nil +} + +// SetSnapLen sets the snap length (max bytes per packet to capture). +func (p *InactiveHandle) SetSnapLen(snaplen int) error { + if status := C.pcap_set_snaplen(p.cptr, C.int(snaplen)); status < 0 { + return statusError(status) + } + return nil +} + +// SetPromisc sets the handle to either be promiscuous (capture packets +// unrelated to this host) or not. +func (p *InactiveHandle) SetPromisc(promisc bool) error { + var pro C.int + if promisc { + pro = 1 + } + if status := C.pcap_set_promisc(p.cptr, pro); status < 0 { + return statusError(status) + } + return nil +} + +// SetTimeout sets the read timeout for the handle. +// +// See the package documentation for important details regarding 'timeout'. +func (p *InactiveHandle) SetTimeout(timeout time.Duration) error { + p.blockForever = timeout < 0 + if status := C.pcap_set_timeout(p.cptr, timeoutMillis(timeout)); status < 0 { + return statusError(status) + } + return nil +} + +// SupportedTimestamps returns a list of supported timstamp types for this +// handle. +func (p *InactiveHandle) SupportedTimestamps() (out []TimestampSource) { + var types *C.int + n := int(C.pcap_list_tstamp_types(p.cptr, &types)) + defer C.pcap_free_tstamp_types(types) + typesArray := (*[100]C.int)(unsafe.Pointer(types)) + for i := 0; i < n; i++ { + out = append(out, TimestampSource((*typesArray)[i])) + } + return +} + +// SetTimestampSource sets the type of timestamp generator PCAP uses when +// attaching timestamps to packets. +func (p *InactiveHandle) SetTimestampSource(t TimestampSource) error { + if status := C.pcap_set_tstamp_type(p.cptr, C.int(t)); status < 0 { + return statusError(status) + } + return nil +} + +// CannotSetRFMon is returned by SetRFMon if the handle does not allow +// setting RFMon because pcap_can_set_rfmon returns 0. +var CannotSetRFMon = errors.New("Cannot set rfmon for this handle") + +// SetRFMon turns on radio monitoring mode, similar to promiscuous mode but for +// wireless networks. If this mode is enabled, the interface will not need to +// associate with an access point before it can receive traffic. +func (p *InactiveHandle) SetRFMon(monitor bool) error { + var mon C.int + if monitor { + mon = 1 + } + switch canset := C.pcap_can_set_rfmon(p.cptr); canset { + case 0: + return CannotSetRFMon + case 1: + // success + default: + return statusError(canset) + } + if status := C.pcap_set_rfmon(p.cptr, mon); status != 0 { + return statusError(status) + } + return nil +} + +// SetBufferSize sets the buffer size (in bytes) of the handle. +func (p *InactiveHandle) SetBufferSize(bufferSize int) error { + if status := C.pcap_set_buffer_size(p.cptr, C.int(bufferSize)); status < 0 { + return statusError(status) + } + return nil +} + +// SetImmediateMode sets (or unsets) the immediate mode of the +// handle. In immediate mode, packets are delivered to the application +// as soon as they arrive. In other words, this overrides SetTimeout. +func (p *InactiveHandle) SetImmediateMode(mode bool) error { + var md C.int + if mode { + md = 1 + } + if status := C.pcap_set_immediate_mode(p.cptr, md); status < 0 { + return statusError(status) + } + return nil +} diff --git a/vendor/github.com/google/gopacket/pcap/pcap_tester.go b/vendor/github.com/google/gopacket/pcap/pcap_tester.go new file mode 100644 index 0000000..e04da37 --- /dev/null +++ b/vendor/github.com/google/gopacket/pcap/pcap_tester.go @@ -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. + +// +build ignore + +// This binary tests that PCAP packet capture is working correctly by issuing +// HTTP requests, then making sure we actually capture data off the wire. +package main + +import ( + "flag" + "fmt" + "github.com/google/gopacket/pcap" + "log" + "net" + "net/http" + "os" + "time" +) + +var mode = flag.String("mode", "basic", "One of: basic,filtered,timestamp") + +func generatePackets() { + if resp, err := http.Get("http://code.google.com"); err != nil { + log.Printf("Could not get HTTP: %v", err) + } else { + resp.Body.Close() + } +} + +func main() { + flag.Parse() + ifaces, err := net.Interfaces() + if err != nil { + log.Fatal(err) + } + for _, iface := range ifaces { + log.Printf("Trying capture on %q", iface.Name) + if err := tryCapture(iface); err != nil { + log.Printf("Error capturing on %q: %v", iface.Name, err) + } else { + log.Printf("Successfully captured on %q", iface.Name) + return + } + } + os.Exit(1) +} + +func tryCapture(iface net.Interface) error { + if iface.Name[:2] == "lo" { + return fmt.Errorf("skipping loopback") + } + var h *pcap.Handle + var err error + switch *mode { + case "basic": + h, err = pcap.OpenLive(iface.Name, 65536, false, time.Second*3) + if err != nil { + return fmt.Errorf("openlive: %v", err) + } + defer h.Close() + case "filtered": + h, err = pcap.OpenLive(iface.Name, 65536, false, time.Second*3) + if err != nil { + return fmt.Errorf("openlive: %v", err) + } + defer h.Close() + if err := h.SetBPFFilter("port 80 or port 443"); err != nil { + return fmt.Errorf("setbpf: %v", err) + } + case "timestamp": + u, err := pcap.NewInactiveHandle(iface.Name) + if err != nil { + return err + } + defer u.CleanUp() + if err = u.SetSnapLen(65536); err != nil { + return err + } else if err = u.SetPromisc(false); err != nil { + return err + } else if err = u.SetTimeout(time.Second * 3); err != nil { + return err + } + sources := u.SupportedTimestamps() + if len(sources) == 0 { + return fmt.Errorf("no supported timestamp sources") + } else if err := u.SetTimestampSource(sources[0]); err != nil { + return fmt.Errorf("settimestampsource(%v): %v", sources[0], err) + } else if h, err = u.Activate(); err != nil { + return fmt.Errorf("could not activate: %v", err) + } + defer h.Close() + default: + panic("Invalid --mode: " + *mode) + } + go generatePackets() + h.ReadPacketData() // Do one dummy read to clear any timeouts. + data, ci, err := h.ReadPacketData() + if err != nil { + return fmt.Errorf("readpacketdata: %v", err) + } + log.Printf("Read packet, %v bytes, CI: %+v", len(data), ci) + return nil +} diff --git a/vendor/github.com/google/gopacket/pcap/test_dns.pcap b/vendor/github.com/google/gopacket/pcap/test_dns.pcap new file mode 100644 index 0000000..3a79f92 Binary files /dev/null and b/vendor/github.com/google/gopacket/pcap/test_dns.pcap differ diff --git a/vendor/github.com/google/gopacket/pcap/test_ethernet.pcap b/vendor/github.com/google/gopacket/pcap/test_ethernet.pcap new file mode 100644 index 0000000..1f8a87c Binary files /dev/null and b/vendor/github.com/google/gopacket/pcap/test_ethernet.pcap differ diff --git a/vendor/github.com/google/gopacket/pcap/test_loopback.pcap b/vendor/github.com/google/gopacket/pcap/test_loopback.pcap new file mode 100644 index 0000000..ddeb82c Binary files /dev/null and b/vendor/github.com/google/gopacket/pcap/test_loopback.pcap differ diff --git a/vendor/github.com/google/gopacket/pcapgo/read.go b/vendor/github.com/google/gopacket/pcapgo/read.go new file mode 100644 index 0000000..922d4a1 --- /dev/null +++ b/vendor/github.com/google/gopacket/pcapgo/read.go @@ -0,0 +1,135 @@ +// Copyright 2014 Damjan Cvetko. 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 pcapgo + +import ( + "encoding/binary" + "errors" + "fmt" + "io" + "time" + + "github.com/google/gopacket" + "github.com/google/gopacket/layers" +) + +// Reader wraps an underlying io.Reader to read packet data in PCAP +// format. See http://wiki.wireshark.org/Development/LibpcapFileFormat +// for information on the file format. +// +// We currenty read v2.4 file format with nanosecond and microsecdond +// timestamp resolution in little-endian and big-endian encoding. +type Reader struct { + r io.Reader + byteOrder binary.ByteOrder + nanoSecsFactor uint32 + versionMajor uint16 + versionMinor uint16 + // timezone + // sigfigs + snaplen uint32 + linkType layers.LinkType + // reusable buffer + buf []byte +} + +const magicNanoseconds = 0xA1B23C4D +const magicMicrosecondsBigendian = 0xD4C3B2A1 +const magicNanosecondsBigendian = 0x4D3CB2A1 + +// NewReader returns a new reader object, for reading packet data from +// the given reader. The reader must be open and header data is +// read from it at this point. +// If the file format is not supported an error is returned +// +// // Create new reader: +// f, _ := os.Open("/tmp/file.pcap") +// defer f.Close() +// r, err := NewReader(f) +// data, ci, err := r.ReadPacketData() +func NewReader(r io.Reader) (*Reader, error) { + ret := Reader{r: r} + if err := ret.readHeader(); err != nil { + return nil, err + } + return &ret, nil +} + +func (r *Reader) readHeader() error { + buf := make([]byte, 24) + if n, err := io.ReadFull(r.r, buf); err != nil { + return err + } else if n < 24 { + return errors.New("Not enough data for read") + } + if magic := binary.LittleEndian.Uint32(buf[0:4]); magic == magicNanoseconds { + r.byteOrder = binary.LittleEndian + r.nanoSecsFactor = 1 + } else if magic == magicNanosecondsBigendian { + r.byteOrder = binary.BigEndian + r.nanoSecsFactor = 1 + } else if magic == magicMicroseconds { + r.byteOrder = binary.LittleEndian + r.nanoSecsFactor = 1000 + } else if magic == magicMicrosecondsBigendian { + r.byteOrder = binary.BigEndian + r.nanoSecsFactor = 1000 + } else { + return errors.New(fmt.Sprintf("Unknown maigc %x", magic)) + } + if r.versionMajor = r.byteOrder.Uint16(buf[4:6]); r.versionMajor != versionMajor { + return errors.New(fmt.Sprintf("Unknown major version %d", r.versionMajor)) + } + if r.versionMinor = r.byteOrder.Uint16(buf[6:8]); r.versionMinor != versionMinor { + return errors.New(fmt.Sprintf("Unknown minor version %d", r.versionMinor)) + } + // ignore timezone 8:12 and sigfigs 12:16 + r.snaplen = r.byteOrder.Uint32(buf[16:20]) + r.buf = make([]byte, r.snaplen+16) + r.linkType = layers.LinkType(r.byteOrder.Uint32(buf[20:24])) + return nil +} + +// Read next packet from file +func (r *Reader) ReadPacketData() (data []byte, ci gopacket.CaptureInfo, err error) { + if ci, err = r.readPacketHeader(); err != nil { + return + } + + var n int + data = r.buf[16 : 16+ci.CaptureLength] + if n, err = io.ReadFull(r.r, data); err != nil { + return + } else if n < ci.CaptureLength { + err = io.ErrUnexpectedEOF + } + return +} + +func (r *Reader) readPacketHeader() (ci gopacket.CaptureInfo, err error) { + var n int + if n, err = io.ReadFull(r.r, r.buf[0:16]); err != nil { + return + } else if n < 16 { + err = io.ErrUnexpectedEOF + return + } + ci.Timestamp = time.Unix(int64(r.byteOrder.Uint32(r.buf[0:4])), int64(r.byteOrder.Uint32(r.buf[4:8])*r.nanoSecsFactor)).UTC() + ci.CaptureLength = int(r.byteOrder.Uint32(r.buf[8:12])) + ci.Length = int(r.byteOrder.Uint32(r.buf[12:16])) + return +} + +// LinkType returns network, as a layers.LinkType. +func (r *Reader) LinkType() layers.LinkType { + return r.linkType +} + +// Reader formater +func (r *Reader) String() string { + return fmt.Sprintf("PcapFile maj: %x min: %x snaplen: %d linktype: %s", r.versionMajor, r.versionMinor, r.snaplen, r.linkType) +} diff --git a/vendor/github.com/google/gopacket/pcapgo/write.go b/vendor/github.com/google/gopacket/pcapgo/write.go new file mode 100644 index 0000000..bfc312f --- /dev/null +++ b/vendor/github.com/google/gopacket/pcapgo/write.go @@ -0,0 +1,103 @@ +// 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 pcapgo provides some native PCAP support, not requiring +// C libpcap to be installed. +package pcapgo + +import ( + "encoding/binary" + "fmt" + "io" + "time" + + "github.com/google/gopacket" + "github.com/google/gopacket/layers" +) + +// Writer wraps an underlying io.Writer to write packet data in PCAP +// format. See http://wiki.wireshark.org/Development/LibpcapFileFormat +// for information on the file format. +// +// For those that care, we currently write v2.4 files with nanosecond +// timestamp resolution and little-endian encoding. +type Writer struct { + w io.Writer +} + +const magicMicroseconds = 0xA1B2C3D4 +const versionMajor = 2 +const versionMinor = 4 + +// NewWriter returns a new writer object, for writing packet data out +// to the given writer. If this is a new empty writer (as opposed to +// an append), you must call WriteFileHeader before WritePacket. +// +// // Write a new file: +// f, _ := os.Create("/tmp/file.pcap") +// w := pcapgo.NewWriter(f) +// w.WriteFileHeader(65536, layers.LinkTypeEthernet) // new file, must do this. +// w.WritePacket(gopacket.CaptureInfo{...}, data1) +// f.Close() +// // Append to existing file (must have same snaplen and linktype) +// f2, _ := os.OpenFile("/tmp/file.pcap", os.O_APPEND, 0700) +// w2 := pcapgo.NewWriter(f2) +// // no need for file header, it's already written. +// w2.WritePacket(gopacket.CaptureInfo{...}, data2) +// f2.Close() +func NewWriter(w io.Writer) *Writer { + return &Writer{w: w} +} + +// WriteFileHeader writes a file header out to the writer. +// This must be called exactly once per output. +func (w *Writer) WriteFileHeader(snaplen uint32, linktype layers.LinkType) error { + var buf [24]byte + binary.LittleEndian.PutUint32(buf[0:4], magicMicroseconds) + binary.LittleEndian.PutUint16(buf[4:6], versionMajor) + binary.LittleEndian.PutUint16(buf[6:8], versionMinor) + // bytes 8:12 stay 0 (timezone = UTC) + // bytes 12:16 stay 0 (sigfigs is always set to zero, according to + // http://wiki.wireshark.org/Development/LibpcapFileFormat + binary.LittleEndian.PutUint32(buf[16:20], snaplen) + binary.LittleEndian.PutUint32(buf[20:24], uint32(linktype)) + _, err := w.w.Write(buf[:]) + return err +} + +const nanosPerMicro = 1000 + +func (w *Writer) writePacketHeader(ci gopacket.CaptureInfo) error { + var buf [16]byte + + t := ci.Timestamp + if t.IsZero() { + t = time.Now() + } + secs := t.Unix() + usecs := t.Nanosecond() / nanosPerMicro + binary.LittleEndian.PutUint32(buf[0:4], uint32(secs)) + binary.LittleEndian.PutUint32(buf[4:8], uint32(usecs)) + binary.LittleEndian.PutUint32(buf[8:12], uint32(ci.CaptureLength)) + binary.LittleEndian.PutUint32(buf[12:16], uint32(ci.Length)) + _, err := w.w.Write(buf[:]) + return err +} + +// WritePacket writes the given packet data out to the file. +func (w *Writer) WritePacket(ci gopacket.CaptureInfo, data []byte) error { + if ci.CaptureLength != len(data) { + return fmt.Errorf("capture length %d does not match data length %d", ci.CaptureLength, len(data)) + } + if ci.CaptureLength > ci.Length { + return fmt.Errorf("invalid capture info %+v: capture length > length", ci) + } + if err := w.writePacketHeader(ci); err != nil { + return fmt.Errorf("error writing packet header: %v", err) + } + _, err := w.w.Write(data) + return err +} diff --git a/vendor/github.com/google/gopacket/pfring/doc.go b/vendor/github.com/google/gopacket/pfring/doc.go new file mode 100644 index 0000000..a7fbcb8 --- /dev/null +++ b/vendor/github.com/google/gopacket/pfring/doc.go @@ -0,0 +1,58 @@ +// 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 pfring wraps the PF_RING C library for Go. + +PF_RING is a high-performance packet capture library written by ntop.org (see +http://www.ntop.org/products/pf_ring/). This library allows you to utilize the +PF_RING library with gopacket to read packet data and decode it. + +This package is meant to be used with its parent, +http://github.com/google/gopacket, although it can also be used independently +if you just want to get packet data from the wire. + +Simple Example + +This is probably the simplest code you can use to start getting packets through +pfring: + + if ring, err := pfring.NewRing("eth0", 65536, pfring.FlagPromisc); err != nil { + panic(err) + } else if err := ring.SetBPFFilter("tcp and port 80"); err != nil { // optional + panic(err) + } else if err := ring.Enable(); err != nil { // Must do this!, or you get no packets! + panic(err) + } else { + packetSource := gopacket.NewPacketSource(ring, layers.LinkTypeEthernet) + for packet := range packetSource.Packets() { + handlePacket(packet) // Do something with a packet here. + } + } + +Pfring Tweaks + +PF_RING has a ton of optimizations and tweaks to make sure you get just the +packets you want. For example, if you're only using pfring to read packets, +consider running: + + ring.SetSocketMode(pfring.ReadOnly) + +If you only care about packets received on your interface (not those transmitted +by the interface), you can run: + + ring.SetDirection(pfring.ReceiveOnly) + +Pfring Clusters + +PF_RING has an idea of 'clusters', where multiple applications can all read from +the same cluster, and PF_RING will multiplex packets over that cluster such that +only one application receives each packet. We won't discuss this mechanism in +too much more detail (see the ntop.org docs for more info), but here's how to +utilize this with the pfring go library: + + ring.SetCluster(1, pfring.ClusterPerFlow5Tuple) +*/ +package pfring diff --git a/vendor/github.com/google/gopacket/pfring/pfring.go b/vendor/github.com/google/gopacket/pfring/pfring.go new file mode 100644 index 0000000..34269b6 --- /dev/null +++ b/vendor/github.com/google/gopacket/pfring/pfring.go @@ -0,0 +1,304 @@ +// 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 pfring + +/* +#cgo LDFLAGS: -lpfring -lpcap +#include +#include +#include +*/ +import "C" + +// NOTE: If you install PF_RING with non-standard options, you may also need +// to use LDFLAGS -lnuma and/or -lrt. Both have been reported necessary if +// PF_RING is configured with --disable-bpf. + +import ( + "fmt" + "github.com/google/gopacket" + "os" + "strconv" + "sync" + "time" + "unsafe" +) + +const errorBufferSize = 256 + +// Ring provides a handle to a pf_ring. +type Ring struct { + // cptr is the handle for the actual pcap C object. + cptr *C.pfring + snaplen int + + mu sync.Mutex + // Since pointers to these objects are passed into a C function, if + // they're declared locally then the Go compiler thinks they may have + // escaped into C-land, so it allocates them on the heap. This causes a + // huge memory hit, so to handle that we store them here instead. + pkthdr C.struct_pfring_pkthdr + buf_ptr *C.u_char +} + +type Flag uint32 + +const ( + FlagReentrant Flag = C.PF_RING_REENTRANT + FlagLongHeader Flag = C.PF_RING_LONG_HEADER + FlagPromisc Flag = C.PF_RING_PROMISC + FlagDNASymmetricRSS Flag = C.PF_RING_DNA_SYMMETRIC_RSS + FlagTimestamp Flag = C.PF_RING_TIMESTAMP + FlagHWTimestamp Flag = C.PF_RING_HW_TIMESTAMP +) + +// NewRing creates a new PFRing. Note that when the ring is initially created, +// it is disabled. The caller must call Enable to start receiving packets. +// The caller should call Close on the given ring when finished with it. +func NewRing(device string, snaplen uint32, flags Flag) (ring *Ring, _ error) { + dev := C.CString(device) + defer C.free(unsafe.Pointer(dev)) + + cptr, err := C.pfring_open(dev, C.u_int32_t(snaplen), C.u_int32_t(flags)) + if cptr == nil || err != nil { + return nil, fmt.Errorf("pfring NewRing error: %v", err) + } + ring = &Ring{cptr: cptr, snaplen: int(snaplen)} + ring.SetApplicationName(os.Args[0]) + return +} + +// Close closes the given Ring. After this call, the Ring should no longer be +// used. +func (r *Ring) Close() { + C.pfring_close(r.cptr) +} + +// NextResult is the return code from a call to Next. +type NextResult int32 + +const ( + NextNoPacketNonblocking NextResult = 0 + NextError NextResult = -1 + NextOk NextResult = 1 + NextNotEnabled NextResult = -7 +) + +// NextResult implements the error interface. +func (n NextResult) Error() string { + switch n { + case NextNoPacketNonblocking: + return "No packet available, nonblocking socket" + case NextError: + return "Generic error" + case NextOk: + return "Success (not an error)" + case NextNotEnabled: + return "Ring not enabled" + } + return strconv.Itoa(int(n)) +} + +// ReadPacketDataTo reads packet data into a user-supplied buffer. +// This function ignores snaplen and instead reads up to the length of the +// passed-in slice. +// The number of bytes read into data will be returned in ci.CaptureLength. +func (r *Ring) ReadPacketDataTo(data []byte) (ci gopacket.CaptureInfo, err error) { + // This tricky buf_ptr points to the start of our slice data, so pfring_recv + // will actually write directly into our Go slice. Nice! + r.mu.Lock() + r.buf_ptr = (*C.u_char)(unsafe.Pointer(&data[0])) + result := NextResult(C.pfring_recv(r.cptr, &r.buf_ptr, C.u_int(len(data)), &r.pkthdr, 1)) + if result != NextOk { + err = result + r.mu.Unlock() + return + } + ci.Timestamp = time.Unix(int64(r.pkthdr.ts.tv_sec), + int64(r.pkthdr.ts.tv_usec)*1000) // convert micros to nanos + ci.CaptureLength = int(r.pkthdr.caplen) + ci.Length = int(r.pkthdr.len) + r.mu.Unlock() + return +} + +// ReadPacketData returns the next packet read from the pcap handle, along with an error +// code associated with that packet. If the packet is read successfully, the +// returned error is nil. +func (r *Ring) ReadPacketData() (data []byte, ci gopacket.CaptureInfo, err error) { + data = make([]byte, r.snaplen) + ci, err = r.ReadPacketDataTo(data) + if err != nil { + data = nil + return + } + data = data[:ci.CaptureLength] + return +} + +type ClusterType C.cluster_type + +const ( + // ClusterPerFlow clusters by + ClusterPerFlow ClusterType = C.cluster_per_flow + // ClusterRoundRobin round-robins packets between applications, ignoring + // packet information. + ClusterRoundRobin ClusterType = C.cluster_round_robin + // ClusterPerFlow2Tuple clusters by + ClusterPerFlow2Tuple ClusterType = C.cluster_per_flow_2_tuple + // ClusterPerFlow4Tuple clusters by + ClusterPerFlow4Tuple ClusterType = C.cluster_per_flow_4_tuple + // ClusterPerFlow5Tuple clusters by + ClusterPerFlow5Tuple ClusterType = C.cluster_per_flow_5_tuple + // ClusterPerFlowTCP5Tuple acts like ClusterPerFlow5Tuple for TCP packets and + // like ClusterPerFlow2Tuple for all other packets. + ClusterPerFlowTCP5Tuple ClusterType = C.cluster_per_flow_tcp_5_tuple +) + +// SetCluster sets which cluster the ring should be part of, and the cluster +// type to use. +func (r *Ring) SetCluster(cluster int, typ ClusterType) error { + if rv := C.pfring_set_cluster(r.cptr, C.u_int(cluster), C.cluster_type(typ)); rv != 0 { + return fmt.Errorf("Unable to set cluster, got error code %d", rv) + } + return nil +} + +// RemoveFromCluster removes the ring from the cluster it was put in with +// SetCluster. +func (r *Ring) RemoveFromCluster() error { + if rv := C.pfring_remove_from_cluster(r.cptr); rv != 0 { + return fmt.Errorf("Unable to remove from cluster, got error code %d", rv) + } + return nil +} + +// SetSamplingRate sets the sampling rate to 1/. +func (r *Ring) SetSamplingRate(rate int) error { + if rv := C.pfring_set_sampling_rate(r.cptr, C.u_int32_t(rate)); rv != 0 { + return fmt.Errorf("Unable to set sampling rate, got error code %d", rv) + } + return nil +} + +// SetBPFFilter sets the BPF filter for the ring. +func (r *Ring) SetBPFFilter(bpf_filter string) error { + filter := C.CString(bpf_filter) + defer C.free(unsafe.Pointer(filter)) + if rv := C.pfring_set_bpf_filter(r.cptr, filter); rv != 0 { + return fmt.Errorf("Unable to set BPF filter, got error code %d", rv) + } + return nil +} + +// RemoveBPFFilter removes the BPF filter from the ring. +func (r *Ring) RemoveBPFFilter() error { + if rv := C.pfring_remove_bpf_filter(r.cptr); rv != 0 { + return fmt.Errorf("Unable to remove BPF filter, got error code %d", rv) + } + return nil +} + +// WritePacketData uses the ring to send raw packet data to the interface. +func (r *Ring) WritePacketData(data []byte) error { + buf := (*C.char)(unsafe.Pointer(&data[0])) + if rv := C.pfring_send(r.cptr, buf, C.u_int(len(data)), 1); rv != 0 { + return fmt.Errorf("Unable to send packet data, got error code %d", rv) + } + return nil +} + +// Enable enables the given ring. This function MUST be called on each new +// ring after it has been set up, or that ring will NOT receive packets. +func (r *Ring) Enable() error { + if rv := C.pfring_enable_ring(r.cptr); rv != 0 { + return fmt.Errorf("Unable to enable ring, got error code %d", rv) + } + return nil +} + +// Disable disables the given ring. After this call, it will no longer receive +// packets. +func (r *Ring) Disable() error { + if rv := C.pfring_disable_ring(r.cptr); rv != 0 { + return fmt.Errorf("Unable to disable ring, got error code %d", rv) + } + return nil +} + +type Stats struct { + Received, Dropped uint64 +} + +// Stats returns statistsics for the ring. +func (r *Ring) Stats() (s Stats, err error) { + var stats C.pfring_stat + if rv := C.pfring_stats(r.cptr, &stats); rv != 0 { + err = fmt.Errorf("Unable to get ring stats, got error code %d", rv) + return + } + s.Received = uint64(stats.recv) + s.Dropped = uint64(stats.drop) + return +} + +type Direction C.packet_direction + +const ( + // TransmitOnly will only capture packets transmitted by the ring's + // interface(s). + TransmitOnly Direction = C.tx_only_direction + // ReceiveOnly will only capture packets received by the ring's + // interface(s). + ReceiveOnly Direction = C.rx_only_direction + // ReceiveAndTransmit will capture both received and transmitted packets on + // the ring's interface(s). + ReceiveAndTransmit Direction = C.rx_and_tx_direction +) + +// SetDirection sets which packets should be captured by the ring. +func (r *Ring) SetDirection(d Direction) error { + if rv := C.pfring_set_direction(r.cptr, C.packet_direction(d)); rv != 0 { + return fmt.Errorf("Unable to set ring direction, got error code %d", rv) + } + return nil +} + +type SocketMode C.socket_mode + +const ( + // WriteOnly sets up the ring to only send packets (Inject), not read them. + WriteOnly SocketMode = C.send_only_mode + // ReadOnly sets up the ring to only receive packets (ReadPacketData), not + // send them. + ReadOnly SocketMode = C.recv_only_mode + // WriteAndRead sets up the ring to both send and receive packets. + WriteAndRead SocketMode = C.send_and_recv_mode +) + +// SetSocketMode sets the mode of the ring socket to send, receive, or both. +func (r *Ring) SetSocketMode(s SocketMode) error { + if rv := C.pfring_set_socket_mode(r.cptr, C.socket_mode(s)); rv != 0 { + return fmt.Errorf("Unable to set socket mode, got error code %d", rv) + } + return nil +} + +// SetApplicationName sets a string name to the ring. This name is available in +// /proc stats for pf_ring. By default, NewRing automatically calls this with +// argv[0]. +func (r *Ring) SetApplicationName(name string) error { + buf := C.CString(name) + defer C.free(unsafe.Pointer(buf)) + if rv := C.pfring_set_application_name(r.cptr, buf); rv != 0 { + return fmt.Errorf("Unable to set ring application name, got error code %d", rv) + } + return nil +} diff --git a/vendor/github.com/google/gopacket/routing/common.go b/vendor/github.com/google/gopacket/routing/common.go new file mode 100644 index 0000000..a6746d4 --- /dev/null +++ b/vendor/github.com/google/gopacket/routing/common.go @@ -0,0 +1,36 @@ +// 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 routing + +import ( + "net" +) + +// Router implements simple IPv4/IPv6 routing based on the kernel's routing +// table. This routing library has very few features and may actually route +// incorrectly in some cases, but it should work the majority of the time. +type Router interface { + // Route returns where to route a packet based on the packet's source + // and destination IP address. + // + // Callers may pass in nil for src, in which case the src is treated as + // either 0.0.0.0 or ::, depending on whether dst is a v4 or v6 address. + // + // It returns the interface on which to send the packet, the gateway IP + // to send the packet to (if necessary), the preferred src IP to use (if + // available). If the preferred src address is not given in the routing + // table, the first IP address of the interface is provided. + // + // If an error is encountered, iface, geteway, and + // preferredSrc will be nil, and err will be set. + Route(dst net.IP) (iface *net.Interface, gateway, preferredSrc net.IP, err error) + + // RouteWithSrc routes based on source information as well as destination + // information. Either or both of input/src can be nil. If both are, this + // should behave exactly like Route(dst) + RouteWithSrc(input net.HardwareAddr, src, dst net.IP) (iface *net.Interface, gateway, preferredSrc net.IP, err error) +} diff --git a/vendor/github.com/google/gopacket/routing/other.go b/vendor/github.com/google/gopacket/routing/other.go new file mode 100644 index 0000000..b53fea9 --- /dev/null +++ b/vendor/github.com/google/gopacket/routing/other.go @@ -0,0 +1,15 @@ +// 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 !linux + +// Package routing is currently only supported in Linux, but the build system requires a valid go file for all architectures. + +package routing + +func New() (Router, error) { + panic("router only implemented in linux") +} diff --git a/vendor/github.com/google/gopacket/routing/routing.go b/vendor/github.com/google/gopacket/routing/routing.go new file mode 100644 index 0000000..7271cb6 --- /dev/null +++ b/vendor/github.com/google/gopacket/routing/routing.go @@ -0,0 +1,241 @@ +// 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 linux + +// Package routing provides a very basic but mostly functional implementation of +// a routing table for IPv4/IPv6 addresses. It uses a routing table pulled from +// the kernel via netlink to find the correct interface, gateway, and preferred +// source IP address for packets destined to a particular location. +// +// The routing package is meant to be used with applications that are sending +// raw packet data, which don't have the benefit of having the kernel route +// packets for them. +package routing + +import ( + "bytes" + "fmt" + "net" + "sort" + "strings" + "syscall" + "unsafe" +) + +// Pulled from http://man7.org/linux/man-pages/man7/rtnetlink.7.html +// See the section on RTM_NEWROUTE, specifically 'struct rtmsg'. +type routeInfoInMemory struct { + Family byte + DstLen byte + SrcLen byte + TOS byte + + Table byte + Protocol byte + Scope byte + Type byte + + Flags uint32 +} + +// rtInfo contains information on a single route. +type rtInfo struct { + Src, Dst *net.IPNet + Gateway, PrefSrc net.IP + // We currently ignore the InputIface. + InputIface, OutputIface uint32 + Priority uint32 +} + +// routeSlice implements sort.Interface to sort routes by Priority. +type routeSlice []*rtInfo + +func (r routeSlice) Len() int { + return len(r) +} +func (r routeSlice) Less(i, j int) bool { + return r[i].Priority < r[j].Priority +} +func (r routeSlice) Swap(i, j int) { + r[i], r[j] = r[j], r[i] +} + +type router struct { + ifaces []net.Interface + addrs []ipAddrs + v4, v6 routeSlice +} + +func (r *router) String() string { + strs := []string{"ROUTER", "--- V4 ---"} + for _, route := range r.v4 { + strs = append(strs, fmt.Sprintf("%+v", *route)) + } + strs = append(strs, "--- V6 ---") + for _, route := range r.v6 { + strs = append(strs, fmt.Sprintf("%+v", *route)) + } + return strings.Join(strs, "\n") +} + +type ipAddrs struct { + v4, v6 net.IP +} + +func (r *router) Route(dst net.IP) (iface *net.Interface, gateway, preferredSrc net.IP, err error) { + return r.RouteWithSrc(nil, nil, dst) +} + +func (r *router) RouteWithSrc(input net.HardwareAddr, src, dst net.IP) (iface *net.Interface, gateway, preferredSrc net.IP, err error) { + length := len(dst) + var ifaceIndex int + switch length { + case 4: + ifaceIndex, gateway, preferredSrc, err = r.route(r.v4, input, src, dst) + case 16: + ifaceIndex, gateway, preferredSrc, err = r.route(r.v6, input, src, dst) + default: + err = fmt.Errorf("IP length is not 4 or 16") + return + } + + // Interfaces are 1-indexed, but we store them in a 0-indexed array. + ifaceIndex-- + + iface = &r.ifaces[ifaceIndex] + if preferredSrc == nil { + switch length { + case 4: + preferredSrc = r.addrs[ifaceIndex].v4 + case 16: + preferredSrc = r.addrs[ifaceIndex].v6 + } + } + return +} + +func (r *router) route(routes routeSlice, input net.HardwareAddr, src, dst net.IP) (iface int, gateway, preferredSrc net.IP, err error) { + var inputIndex uint32 + if input != nil { + for i, iface := range r.ifaces { + if bytes.Equal(input, iface.HardwareAddr) { + // Convert from zero- to one-indexed. + inputIndex = uint32(i + 1) + break + } + } + } + for _, rt := range routes { + if rt.InputIface != 0 && rt.InputIface != inputIndex { + continue + } + if rt.Src != nil && !rt.Src.Contains(src) { + continue + } + if rt.Dst != nil && !rt.Dst.Contains(dst) { + continue + } + return int(rt.OutputIface), rt.Gateway, rt.PrefSrc, nil + } + err = fmt.Errorf("no route found for %v", dst) + return +} + +// New creates a new router object. The router returned by New currently does +// not update its routes after construction... care should be taken for +// long-running programs to call New() regularly to take into account any +// changes to the routing table which have occurred since the last New() call. +func New() (Router, error) { + rtr := &router{} + tab, err := syscall.NetlinkRIB(syscall.RTM_GETROUTE, syscall.AF_UNSPEC) + if err != nil { + return nil, err + } + msgs, err := syscall.ParseNetlinkMessage(tab) + if err != nil { + return nil, err + } +loop: + for _, m := range msgs { + switch m.Header.Type { + case syscall.NLMSG_DONE: + break loop + case syscall.RTM_NEWROUTE: + rt := (*routeInfoInMemory)(unsafe.Pointer(&m.Data[0])) + routeInfo := rtInfo{} + attrs, err := syscall.ParseNetlinkRouteAttr(&m) + if err != nil { + return nil, err + } + switch rt.Family { + case syscall.AF_INET: + rtr.v4 = append(rtr.v4, &routeInfo) + case syscall.AF_INET6: + rtr.v6 = append(rtr.v6, &routeInfo) + default: + continue loop + } + for _, attr := range attrs { + switch attr.Attr.Type { + case syscall.RTA_DST: + routeInfo.Dst = &net.IPNet{ + IP: net.IP(attr.Value), + Mask: net.CIDRMask(int(rt.DstLen), len(attr.Value)*8), + } + case syscall.RTA_SRC: + routeInfo.Src = &net.IPNet{ + IP: net.IP(attr.Value), + Mask: net.CIDRMask(int(rt.SrcLen), len(attr.Value)*8), + } + case syscall.RTA_GATEWAY: + routeInfo.Gateway = net.IP(attr.Value) + case syscall.RTA_PREFSRC: + routeInfo.PrefSrc = net.IP(attr.Value) + case syscall.RTA_IIF: + routeInfo.InputIface = *(*uint32)(unsafe.Pointer(&attr.Value[0])) + case syscall.RTA_OIF: + routeInfo.OutputIface = *(*uint32)(unsafe.Pointer(&attr.Value[0])) + case syscall.RTA_PRIORITY: + routeInfo.Priority = *(*uint32)(unsafe.Pointer(&attr.Value[0])) + } + } + } + } + sort.Sort(rtr.v4) + sort.Sort(rtr.v6) + if ifaces, err := net.Interfaces(); err != nil { + return nil, err + } else { + for i, iface := range ifaces { + if i != iface.Index-1 { + return nil, fmt.Errorf("out of order iface %d = %v", i, iface) + } + rtr.ifaces = append(rtr.ifaces, iface) + var addrs ipAddrs + if ifaceAddrs, err := iface.Addrs(); err != nil { + return nil, err + } else { + for _, addr := range ifaceAddrs { + if inet, ok := addr.(*net.IPNet); ok { + // Go has a nasty habit of giving you IPv4s as ::ffff:1.2.3.4 instead of 1.2.3.4. + // We want to use mapped v4 addresses as v4 preferred addresses, never as v6 + // preferred addresses. + if v4 := inet.IP.To4(); v4 != nil { + if addrs.v4 == nil { + addrs.v4 = v4 + } + } else if addrs.v6 == nil { + addrs.v6 = inet.IP + } + } + } + } + rtr.addrs = append(rtr.addrs, addrs) + } + } + return rtr, nil +} diff --git a/vendor/github.com/google/gopacket/tcpassembly/assembly.go b/vendor/github.com/google/gopacket/tcpassembly/assembly.go new file mode 100644 index 0000000..03f43d3 --- /dev/null +++ b/vendor/github.com/google/gopacket/tcpassembly/assembly.go @@ -0,0 +1,773 @@ +// 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 tcpassembly provides TCP stream re-assembly. +// +// The tcpassembly package implements uni-directional TCP reassembly, for use in +// packet-sniffing applications. The caller reads packets off the wire, then +// presents them to an Assembler in the form of gopacket layers.TCP packets +// (github.com/google/gopacket, github.com/google/gopacket/layers). +// +// The Assembler uses a user-supplied +// StreamFactory to create a user-defined Stream interface, then passes packet +// data in stream order to that object. A concurrency-safe StreamPool keeps +// track of all current Streams being reassembled, so multiple Assemblers may +// run at once to assemble packets while taking advantage of multiple cores. +package tcpassembly + +import ( + "flag" + "fmt" + "github.com/google/gopacket" + "github.com/google/gopacket/layers" + "log" + "sync" + "time" +) + +var memLog = flag.Bool("assembly_memuse_log", false, "If true, the github.com/google/gopacket/tcpassembly library will log information regarding its memory use every once in a while.") +var debugLog = flag.Bool("assembly_debug_log", false, "If true, the github.com/google/gopacket/tcpassembly library will log verbose debugging information (at least one line per packet)") + +const invalidSequence = -1 +const uint32Max = 0xFFFFFFFF + +// Sequence is a TCP sequence number. It provides a few convenience functions +// for handling TCP wrap-around. The sequence should always be in the range +// [0,0xFFFFFFFF]... its other bits are simply used in wrap-around calculations +// and should never be set. +type Sequence int64 + +// Difference defines an ordering for comparing TCP sequences that's safe for +// roll-overs. It returns: +// > 0 : if t comes after s +// < 0 : if t comes before s +// 0 : if t == s +// The number returned is the sequence difference, so 4.Difference(8) will +// return 4. +// +// It handles rollovers by considering any sequence in the first quarter of the +// uint32 space to be after any sequence in the last quarter of that space, thus +// wrapping the uint32 space. +func (s Sequence) Difference(t Sequence) int { + if s > uint32Max-uint32Max/4 && t < uint32Max/4 { + t += uint32Max + } else if t > uint32Max-uint32Max/4 && s < uint32Max/4 { + s += uint32Max + } + return int(t - s) +} + +// Add adds an integer to a sequence and returns the resulting sequence. +func (s Sequence) Add(t int) Sequence { + return (s + Sequence(t)) & uint32Max +} + +// Reassembly objects are passed by an Assembler into Streams using the +// Reassembled call. Callers should not need to create these structs themselves +// except for testing. +type Reassembly struct { + // Bytes is the next set of bytes in the stream. May be empty. + Bytes []byte + // Skip is set to non-zero if bytes were skipped between this and the + // last Reassembly. If this is the first packet in a connection and we + // didn't see the start, we have no idea how many bytes we skipped, so + // we set it to -1. Otherwise, it's set to the number of bytes skipped. + Skip int + // Start is set if this set of bytes has a TCP SYN accompanying it. + Start bool + // End is set if this set of bytes has a TCP FIN or RST accompanying it. + End bool + // Seen is the timestamp this set of bytes was pulled off the wire. + Seen time.Time +} + +const pageBytes = 1900 + +// page is used to store TCP data we're not ready for yet (out-of-order +// packets). Unused pages are stored in and returned from a pageCache, which +// avoids memory allocation. Used pages are stored in a doubly-linked list in +// a connection. +type page struct { + Reassembly + seq Sequence + index int + prev, next *page + buf [pageBytes]byte +} + +// pageCache is a concurrency-unsafe store of page objects we use to avoid +// memory allocation as much as we can. It grows but never shrinks. +type pageCache struct { + free []*page + pcSize int + size, used int + pages [][]page + pageRequests int64 +} + +const initialAllocSize = 1024 + +func newPageCache() *pageCache { + pc := &pageCache{ + free: make([]*page, 0, initialAllocSize), + pcSize: initialAllocSize, + } + pc.grow() + return pc +} + +// grow exponentially increases the size of our page cache as much as necessary. +func (c *pageCache) grow() { + pages := make([]page, c.pcSize) + c.pages = append(c.pages, pages) + c.size += c.pcSize + for i, _ := range pages { + c.free = append(c.free, &pages[i]) + } + if *memLog { + log.Println("PageCache: created", c.pcSize, "new pages") + } + c.pcSize *= 2 +} + +// next returns a clean, ready-to-use page object. +func (c *pageCache) next(ts time.Time) (p *page) { + if *memLog { + c.pageRequests++ + if c.pageRequests&0xFFFF == 0 { + log.Println("PageCache:", c.pageRequests, "requested,", c.used, "used,", len(c.free), "free") + } + } + if len(c.free) == 0 { + c.grow() + } + i := len(c.free) - 1 + p, c.free = c.free[i], c.free[:i] + p.prev = nil + p.next = nil + p.Seen = ts + p.Bytes = p.buf[:0] + c.used++ + return p +} + +// replace replaces a page into the pageCache. +func (c *pageCache) replace(p *page) { + c.used-- + c.free = append(c.free, p) +} + +// Stream is implemented by the caller to handle incoming reassembled +// TCP data. Callers create a StreamFactory, then StreamPool uses +// it to create a new Stream for every TCP stream. +// +// assembly will, in order: +// 1) Create the stream via StreamFactory.New +// 2) Call Reassembled 0 or more times, passing in reassembled TCP data in order +// 3) Call ReassemblyComplete one time, after which the stream is dereferenced by assembly. +type Stream interface { + // Reassembled is called zero or more times. assembly guarantees + // that the set of all Reassembly objects passed in during all + // calls are presented in the order they appear in the TCP stream. + // Reassembly objects are reused after each Reassembled call, + // so it's important to copy anything you need out of them + // (specifically out of Reassembly.Bytes) that you need to stay + // around after you return from the Reassembled call. + Reassembled([]Reassembly) + // ReassemblyComplete is called when assembly decides there is + // no more data for this Stream, either because a FIN or RST packet + // was seen, or because the stream has timed out without any new + // packet data (due to a call to FlushOlderThan). + ReassemblyComplete() +} + +// StreamFactory is used by assembly to create a new stream for each +// new TCP session. +type StreamFactory interface { + // New should return a new stream for the given TCP key. + New(netFlow, tcpFlow gopacket.Flow) Stream +} + +func (p *StreamPool) connections() []*connection { + p.mu.RLock() + conns := make([]*connection, 0, len(p.conns)) + for _, conn := range p.conns { + conns = append(conns, conn) + } + p.mu.RUnlock() + return conns +} + +// FlushOlderThan finds any streams waiting for packets older than +// the given time, and pushes through the data they have (IE: tells +// them to stop waiting and skip the data they're waiting for). +// +// Each Stream maintains a list of zero or more sets of bytes it has received +// out-of-order. For example, if it has processed up through sequence number +// 10, it might have bytes [15-20), [20-25), [30,50) in its list. Each set of +// bytes also has the timestamp it was originally viewed. A flush call will +// look at the smallest subsequent set of bytes, in this case [15-20), and if +// its timestamp is older than the passed-in time, it will push it and all +// contiguous byte-sets out to the Stream's Reassembled function. In this case, +// it will push [15-20), but also [20-25), since that's contiguous. It will +// only push [30-50) if its timestamp is also older than the passed-in time, +// otherwise it will wait until the next FlushOlderThan to see if bytes [25-30) +// come in. +// +// If it pushes all bytes (or there were no sets of bytes to begin with) +// AND the connection has not received any bytes since the passed-in time, +// the connection will be closed. +// +// Returns the number of connections flushed, and of those, the number closed +// because of the flush. +func (a *Assembler) FlushOlderThan(t time.Time) (flushed, closed int) { + conns := a.connPool.connections() + closes := 0 + flushes := 0 + for _, conn := range conns { + flushed := false + conn.mu.Lock() + if conn.closed { + // Already closed connection, nothing to do here. + conn.mu.Unlock() + continue + } + for conn.first != nil && conn.first.Seen.Before(t) { + a.skipFlush(conn) + flushed = true + if conn.closed { + closes++ + break + } + } + if !conn.closed && conn.first == nil && conn.lastSeen.Before(t) { + flushed = true + a.closeConnection(conn) + closes++ + } + if flushed { + flushes++ + } + conn.mu.Unlock() + } + return flushes, closes +} + +// FlushAll flushes all remaining data into all remaining connections, closing +// those connections. It returns the total number of connections flushed/closed +// by the call. +func (a *Assembler) FlushAll() (closed int) { + conns := a.connPool.connections() + closed = len(conns) + for _, conn := range conns { + conn.mu.Lock() + for !conn.closed { + a.skipFlush(conn) + } + conn.mu.Unlock() + } + return +} + +type key [2]gopacket.Flow + +func (k *key) String() string { + return fmt.Sprintf("%s:%s", k[0], k[1]) +} + +// StreamPool stores all streams created by Assemblers, allowing multiple +// assemblers to work together on stream processing while enforcing the fact +// that a single stream receives its data serially. It is safe +// for concurrency, usable by multiple Assemblers at once. +// +// StreamPool handles the creation and storage of Stream objects used by one or +// more Assembler objects. When a new TCP stream is found by an Assembler, it +// creates an associated Stream by calling its StreamFactory's New method. +// Thereafter (until the stream is closed), that Stream object will receive +// assembled TCP data via Assembler's calls to the stream's Reassembled +// function. +// +// Like the Assembler, StreamPool attempts to minimize allocation. Unlike the +// Assembler, though, it does have to do some locking to make sure that the +// connection objects it stores are accessible to multiple Assemblers. +type StreamPool struct { + conns map[key]*connection + users int + mu sync.RWMutex + factory StreamFactory + free []*connection + all [][]connection + nextAlloc int + newConnectionCount int64 +} + +func (p *StreamPool) grow() { + conns := make([]connection, p.nextAlloc) + p.all = append(p.all, conns) + for i, _ := range conns { + p.free = append(p.free, &conns[i]) + } + if *memLog { + log.Println("StreamPool: created", p.nextAlloc, "new connections") + } + p.nextAlloc *= 2 +} + +// NewStreamPool creates a new connection pool. Streams will +// be created as necessary using the passed-in StreamFactory. +func NewStreamPool(factory StreamFactory) *StreamPool { + return &StreamPool{ + conns: make(map[key]*connection, initialAllocSize), + free: make([]*connection, 0, initialAllocSize), + factory: factory, + nextAlloc: initialAllocSize, + } +} + +const assemblerReturnValueInitialSize = 16 + +// NewAssembler creates a new assembler. Pass in the StreamPool +// to use, may be shared across assemblers. +// +// This sets some sane defaults for the assembler options, +// see DefaultAssemblerOptions for details. +func NewAssembler(pool *StreamPool) *Assembler { + pool.mu.Lock() + pool.users++ + pool.mu.Unlock() + return &Assembler{ + ret: make([]Reassembly, assemblerReturnValueInitialSize), + pc: newPageCache(), + connPool: pool, + AssemblerOptions: DefaultAssemblerOptions, + } +} + +// DefaultAssemblerOptions provides default options for an assembler. +// These options are used by default when calling NewAssembler, so if +// modified before a NewAssembler call they'll affect the resulting Assembler. +// +// Note that the default options can result in ever-increasing memory usage +// unless one of the Flush* methods is called on a regular basis. +var DefaultAssemblerOptions = AssemblerOptions{ + MaxBufferedPagesPerConnection: 0, // unlimited + MaxBufferedPagesTotal: 0, // unlimited +} + +type connection struct { + key key + pages int + first, last *page + nextSeq Sequence + created, lastSeen time.Time + stream Stream + closed bool + mu sync.Mutex +} + +func (c *connection) reset(k key, s Stream, ts time.Time) { + c.key = k + c.pages = 0 + c.first, c.last = nil, nil + c.nextSeq = invalidSequence + c.created = ts + c.stream = s + c.closed = false +} + +// AssemblerOptions controls the behavior of each assembler. Modify the +// options of each assembler you create to change their behavior. +type AssemblerOptions struct { + // MaxBufferedPagesTotal is an upper limit on the total number of pages to + // buffer while waiting for out-of-order packets. Once this limit is + // reached, the assembler will degrade to flushing every connection it + // gets a packet for. If <= 0, this is ignored. + MaxBufferedPagesTotal int + // MaxBufferedPagesPerConnection is an upper limit on the number of pages + // buffered for a single connection. Should this limit be reached for a + // particular connection, the smallest sequence number will be flushed, along + // with any contiguous data. If <= 0, this is ignored. + MaxBufferedPagesPerConnection int +} + +// Assembler handles reassembling TCP streams. It is not safe for +// concurrency... after passing a packet in via the Assemble call, the caller +// must wait for that call to return before calling Assemble again. Callers can +// get around this by creating multiple assemblers that share a StreamPool. In +// that case, each individual stream will still be handled serially (each stream +// has an individual mutex associated with it), however multiple assemblers can +// assemble different connections concurrently. +// +// The Assembler provides (hopefully) fast TCP stream re-assembly for sniffing +// applications written in Go. The Assembler uses the following methods to be +// as fast as possible, to keep packet processing speedy: +// +// Avoids Lock Contention +// +// Assemblers locks connections, but each connection has an individual lock, and +// rarely will two Assemblers be looking at the same connection. Assemblers +// lock the StreamPool when looking up connections, but they use Reader +// locks initially, and only force a write lock if they need to create a new +// connection or close one down. These happen much less frequently than +// individual packet handling. +// +// Each assembler runs in its own goroutine, and the only state shared between +// goroutines is through the StreamPool. Thus all internal Assembler state +// can be handled without any locking. +// +// NOTE: If you can guarantee that packets going to a set of Assemblers will +// contain information on different connections per Assembler (for example, +// they're already hashed by PF_RING hashing or some other hashing mechanism), +// then we recommend you use a seperate StreamPool per Assembler, thus +// avoiding all lock contention. Only when different Assemblers could receive +// packets for the same Stream should a StreamPool be shared between them. +// +// Avoids Memory Copying +// +// In the common case, handling of a single TCP packet should result in zero +// memory allocations. The Assembler will look up the connection, figure out +// that the packet has arrived in order, and immediately pass that packet on to +// the appropriate connection's handling code. Only if a packet arrives out of +// order is its contents copied and stored in memory for later. +// +// Avoids Memory Allocation +// +// Assemblers try very hard to not use memory allocation unless absolutely +// necessary. Packet data for sequential packets is passed directly to streams +// with no copying or allocation. Packet data for out-of-order packets is +// copied into reusable pages, and new pages are only allocated rarely when the +// page cache runs out. Page caches are Assembler-specific, thus not used +// concurrently and requiring no locking. +// +// Internal representations for connection objects are also reused over time. +// Because of this, the most common memory allocation done by the Assembler is +// generally what's done by the caller in StreamFactory.New. If no allocation +// is done there, then very little allocation is done ever, mostly to handle +// large increases in bandwidth or numbers of connections. +// +// TODO: The page caches used by an Assembler will grow to the size necessary +// to handle a workload, and currently will never shrink. This means that +// traffic spikes can result in large memory usage which isn't garbage +// collected when typical traffic levels return. +type Assembler struct { + AssemblerOptions + ret []Reassembly + pc *pageCache + connPool *StreamPool +} + +func (p *StreamPool) newConnection(k key, s Stream, ts time.Time) (c *connection) { + if *memLog { + p.newConnectionCount++ + if p.newConnectionCount&0x7FFF == 0 { + log.Println("StreamPool:", p.newConnectionCount, "requests,", len(p.conns), "used,", len(p.free), "free") + } + } + if len(p.free) == 0 { + p.grow() + } + index := len(p.free) - 1 + c, p.free = p.free[index], p.free[:index] + c.reset(k, s, ts) + return c +} + +// getConnection returns a connection. If end is true and a connection +// does not already exist, returns nil. This allows us to check for a +// connection without actually creating one if it doesn't already exist. +func (p *StreamPool) getConnection(k key, end bool, ts time.Time) *connection { + p.mu.RLock() + conn := p.conns[k] + p.mu.RUnlock() + if end || conn != nil { + return conn + } + s := p.factory.New(k[0], k[1]) + p.mu.Lock() + conn = p.newConnection(k, s, ts) + if conn2 := p.conns[k]; conn2 != nil { + p.mu.Unlock() + return conn2 + } + p.conns[k] = conn + p.mu.Unlock() + return conn +} + +// Assemble calls AssembleWithTimestamp with the current timestamp, useful for +// packets being read directly off the wire. +func (a *Assembler) Assemble(netFlow gopacket.Flow, t *layers.TCP) { + a.AssembleWithTimestamp(netFlow, t, time.Now()) +} + +// AssembleWithTimestamp reassembles the given TCP packet into its appropriate +// stream. +// +// The timestamp passed in must be the timestamp the packet was seen. +// For packets read off the wire, time.Now() should be fine. For packets read +// from PCAP files, CaptureInfo.Timestamp should be passed in. This timestamp +// will affect which streams are flushed by a call to FlushOlderThan. +// +// Each Assemble call results in, in order: +// +// zero or one calls to StreamFactory.New, creating a stream +// zero or one calls to Reassembled on a single stream +// zero or one calls to ReassemblyComplete on the same stream +func (a *Assembler) AssembleWithTimestamp(netFlow gopacket.Flow, t *layers.TCP, timestamp time.Time) { + // Ignore empty TCP packets + if !t.SYN && !t.FIN && !t.RST && len(t.LayerPayload()) == 0 { + if *debugLog { + log.Println("ignoring useless packet") + } + return + } + + a.ret = a.ret[:0] + key := key{netFlow, t.TransportFlow()} + var conn *connection + // This for loop handles a race condition where a connection will close, lock + // the connection pool, and remove itself, but before it locked the connection + // pool it's returned to another Assemble statement. This should loop 0-1 + // times for the VAST majority of cases. + for { + conn = a.connPool.getConnection( + key, !t.SYN && len(t.LayerPayload()) == 0, timestamp) + if conn == nil { + if *debugLog { + log.Printf("%v got empty packet on otherwise empty connection", key) + } + return + } + conn.mu.Lock() + if !conn.closed { + break + } + conn.mu.Unlock() + } + if conn.lastSeen.Before(timestamp) { + conn.lastSeen = timestamp + } + seq, bytes := Sequence(t.Seq), t.Payload + if conn.nextSeq == invalidSequence { + if t.SYN { + if *debugLog { + log.Printf("%v saw first SYN packet, returning immediately, seq=%v", key, seq) + } + a.ret = append(a.ret, Reassembly{ + Bytes: bytes, + Skip: 0, + Start: true, + Seen: timestamp, + }) + conn.nextSeq = seq.Add(len(bytes) + 1) + } else { + if *debugLog { + log.Printf("%v waiting for start, storing into connection", key) + } + a.insertIntoConn(t, conn, timestamp) + } + } else if diff := conn.nextSeq.Difference(seq); diff > 0 { + if *debugLog { + log.Printf("%v gap in sequence numbers (%v, %v) diff %v, storing into connection", key, conn.nextSeq, seq, diff) + } + a.insertIntoConn(t, conn, timestamp) + } else { + bytes, conn.nextSeq = byteSpan(conn.nextSeq, seq, bytes) + if *debugLog { + log.Printf("%v found contiguous data (%v, %v), returning immediately", key, seq, conn.nextSeq) + } + a.ret = append(a.ret, Reassembly{ + Bytes: bytes, + Skip: 0, + End: t.RST || t.FIN, + Seen: timestamp, + }) + } + if len(a.ret) > 0 { + a.sendToConnection(conn) + } + conn.mu.Unlock() +} + +func byteSpan(expected, received Sequence, bytes []byte) (toSend []byte, next Sequence) { + if expected == invalidSequence { + return bytes, received.Add(len(bytes)) + } + span := int(received.Difference(expected)) + if span <= 0 { + return bytes, received.Add(len(bytes)) + } else if len(bytes) < span { + return nil, expected + } + return bytes[span:], expected.Add(len(bytes) - span) +} + +// sendToConnection sends the current values in a.ret to the connection, closing +// the connection if the last thing sent had End set. +func (a *Assembler) sendToConnection(conn *connection) { + a.addContiguous(conn) + if conn.stream == nil { + panic("why?") + } + conn.stream.Reassembled(a.ret) + if a.ret[len(a.ret)-1].End { + a.closeConnection(conn) + } +} + +// addContiguous adds contiguous byte-sets to a connection. +func (a *Assembler) addContiguous(conn *connection) { + for conn.first != nil && conn.nextSeq.Difference(conn.first.seq) <= 0 { + a.addNextFromConn(conn) + } +} + +// skipFlush skips the first set of bytes we're waiting for and returns the +// first set of bytes we have. If we have no bytes pending, it closes the +// connection. +func (a *Assembler) skipFlush(conn *connection) { + if *debugLog { + log.Printf("%v skipFlush %v", conn.key, conn.nextSeq) + } + if conn.first == nil { + a.closeConnection(conn) + return + } + a.ret = a.ret[:0] + a.addNextFromConn(conn) + a.addContiguous(conn) + a.sendToConnection(conn) +} + +func (p *StreamPool) remove(conn *connection) { + p.mu.Lock() + delete(p.conns, conn.key) + p.free = append(p.free, conn) + p.mu.Unlock() +} + +func (a *Assembler) closeConnection(conn *connection) { + if *debugLog { + log.Printf("%v closing", conn.key) + } + conn.stream.ReassemblyComplete() + conn.closed = true + a.connPool.remove(conn) + for p := conn.first; p != nil; p = p.next { + a.pc.replace(p) + } +} + +// traverseConn traverses our doubly-linked list of pages for the correct +// position to put the given sequence number. Note that it traverses backwards, +// starting at the highest sequence number and going down, since we assume the +// common case is that TCP packets for a stream will appear in-order, with +// minimal loss or packet reordering. +func (conn *connection) traverseConn(seq Sequence) (prev, current *page) { + prev = conn.last + for prev != nil && prev.seq.Difference(seq) < 0 { + current = prev + prev = current.prev + } + return +} + +// pushBetween inserts the doubly-linked list first-...-last in between the +// nodes prev-next in another doubly-linked list. If prev is nil, makes first +// the new first page in the connection's list. If next is nil, makes last the +// new last page in the list. first/last may point to the same page. +func (conn *connection) pushBetween(prev, next, first, last *page) { + // Maintain our doubly linked list + if next == nil || conn.last == nil { + conn.last = last + } else { + last.next = next + next.prev = last + } + if prev == nil || conn.first == nil { + conn.first = first + } else { + first.prev = prev + prev.next = first + } +} + +func (a *Assembler) insertIntoConn(t *layers.TCP, conn *connection, ts time.Time) { + if conn.first != nil && conn.first.seq == conn.nextSeq { + panic("wtf") + } + p, p2, numPages := a.pagesFromTcp(t, ts) + prev, current := conn.traverseConn(Sequence(t.Seq)) + conn.pushBetween(prev, current, p, p2) + conn.pages += numPages + if (a.MaxBufferedPagesPerConnection > 0 && conn.pages >= a.MaxBufferedPagesPerConnection) || + (a.MaxBufferedPagesTotal > 0 && a.pc.used >= a.MaxBufferedPagesTotal) { + if *debugLog { + log.Printf("%v hit max buffer size: %+v, %v, %v", conn.key, a.AssemblerOptions, conn.pages, a.pc.used) + } + a.addNextFromConn(conn) + } +} + +// pagesFromTcp creates a page (or set of pages) from a TCP packet. Note that +// it should NEVER receive a SYN packet, as it doesn't handle sequences +// correctly. +// +// It returns the first and last page in its doubly-linked list of new pages. +func (a *Assembler) pagesFromTcp(t *layers.TCP, ts time.Time) (p, p2 *page, numPages int) { + first := a.pc.next(ts) + current := first + numPages++ + seq, bytes := Sequence(t.Seq), t.Payload + for { + length := min(len(bytes), pageBytes) + current.Bytes = current.buf[:length] + copy(current.Bytes, bytes) + current.seq = seq + bytes = bytes[length:] + if len(bytes) == 0 { + break + } + seq = seq.Add(length) + current.next = a.pc.next(ts) + current.next.prev = current + current = current.next + numPages++ + } + current.End = t.RST || t.FIN + return first, current, numPages +} + +// addNextFromConn pops the first page from a connection off and adds it to the +// return array. +func (a *Assembler) addNextFromConn(conn *connection) { + if conn.nextSeq == invalidSequence { + conn.first.Skip = -1 + } else if diff := conn.nextSeq.Difference(conn.first.seq); diff > 0 { + conn.first.Skip = int(diff) + } + conn.first.Bytes, conn.nextSeq = byteSpan(conn.nextSeq, conn.first.seq, conn.first.Bytes) + if *debugLog { + log.Printf("%v adding from conn (%v, %v)", conn.key, conn.first.seq, conn.nextSeq) + } + a.ret = append(a.ret, conn.first.Reassembly) + a.pc.replace(conn.first) + if conn.first == conn.last { + conn.first = nil + conn.last = nil + } else { + conn.first = conn.first.next + conn.first.prev = nil + } + conn.pages-- +} + +func min(a, b int) int { + if a < b { + return a + } + return b +} diff --git a/vendor/github.com/google/gopacket/tcpassembly/tcpreader/reader.go b/vendor/github.com/google/gopacket/tcpassembly/tcpreader/reader.go new file mode 100644 index 0000000..91d30f9 --- /dev/null +++ b/vendor/github.com/google/gopacket/tcpassembly/tcpreader/reader.go @@ -0,0 +1,209 @@ +// 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 tcpreader provides an implementation for tcpassembly.Stream which presents +// the caller with an io.Reader for easy processing. +// +// The assembly package handles packet data reordering, but its output is +// library-specific, thus not usable by the majority of external Go libraries. +// The io.Reader interface, on the other hand, is used throughout much of Go +// code as an easy mechanism for reading in data streams and decoding them. For +// example, the net/http package provides the ReadRequest function, which can +// parase an HTTP request from a live data stream, just what we'd want when +// sniffing HTTP traffic. Using ReaderStream, this is relatively easy to set +// up: +// +// // Create our StreamFactory +// type httpStreamFactory struct {} +// func (f *httpStreamFactory) New(a, b gopacket.Flow) { +// r := tcpreader.NewReaderStream(false) +// go printRequests(r) +// return &r +// } +// func printRequests(r io.Reader) { +// // Convert to bufio, since that's what ReadRequest wants. +// buf := bufio.NewReader(r) +// for { +// if req, err := http.ReadRequest(buf); err == io.EOF { +// return +// } else if err != nil { +// log.Println("Error parsing HTTP requests:", err) +// } else { +// fmt.Println("HTTP REQUEST:", req) +// fmt.Println("Body contains", tcpreader.DiscardBytesToEOF(req.Body), "bytes") +// } +// } +// } +// +// Using just this code, we're able to reference a powerful, built-in library +// for HTTP request parsing to do all the dirty-work of parsing requests from +// the wire in real-time. Pass this stream factory to an tcpassembly.StreamPool, +// start up an tcpassembly.Assembler, and you're good to go! +package tcpreader + +import ( + "errors" + "github.com/google/gopacket/tcpassembly" + "io" +) + +var discardBuffer = make([]byte, 4096) + +// DiscardBytesToFirstError will read in all bytes up to the first error +// reported by the given reader, then return the number of bytes discarded +// and the error encountered. +func DiscardBytesToFirstError(r io.Reader) (discarded int, err error) { + for { + n, e := r.Read(discardBuffer) + discarded += n + if e != nil { + return discarded, e + } + } +} + +// DiscardBytesToEOF will read in all bytes from a Reader until it +// encounters an io.EOF, then return the number of bytes. Be careful +// of this... if used on a Reader that returns a non-io.EOF error +// consistently, this will loop forever discarding that error while +// it waits for an EOF. +func DiscardBytesToEOF(r io.Reader) (discarded int) { + for { + n, e := DiscardBytesToFirstError(r) + discarded += n + if e == io.EOF { + return + } + } +} + +// ReaderStream implements both tcpassembly.Stream and io.Reader. You can use it +// as a building block to make simple, easy stream handlers. +// +// IMPORTANT: If you use a ReaderStream, you MUST read ALL BYTES from it, +// quickly. Not reading available bytes will block TCP stream reassembly. It's +// a common pattern to do this by starting a goroutine in the factory's New +// method: +// +// type myStreamHandler struct { +// r ReaderStream +// } +// func (m *myStreamHandler) run() { +// // Do something here that reads all of the ReaderStream, or your assembly +// // will block. +// fmt.Println(tcpreader.DiscardBytesToEOF(&m.r)) +// } +// func (f *myStreamFactory) New(a, b gopacket.Flow) tcpassembly.Stream { +// s := &myStreamHandler{} +// go s.run() +// // Return the ReaderStream as the stream that assembly should populate. +// return &s.r +// } +type ReaderStream struct { + ReaderStreamOptions + reassembled chan []tcpassembly.Reassembly + done chan bool + current []tcpassembly.Reassembly + closed bool + lossReported bool + first bool + initiated bool +} + +type ReaderStreamOptions struct { + // LossErrors determines whether this stream will return + // ReaderStreamDataLoss errors from its Read function whenever it + // determines data has been lost. + LossErrors bool +} + +// NewReaderStream returns a new ReaderStream object. +func NewReaderStream() ReaderStream { + r := ReaderStream{ + reassembled: make(chan []tcpassembly.Reassembly), + done: make(chan bool), + first: true, + initiated: true, + } + return r +} + +// Reassembled implements tcpassembly.Stream's Reassembled function. +func (r *ReaderStream) Reassembled(reassembly []tcpassembly.Reassembly) { + if !r.initiated { + panic("ReaderStream not created via NewReaderStream") + } + r.reassembled <- reassembly + <-r.done +} + +// ReassemblyComplete implements tcpassembly.Stream's ReassemblyComplete function. +func (r *ReaderStream) ReassemblyComplete() { + close(r.reassembled) + close(r.done) +} + +// stripEmpty strips empty reassembly slices off the front of its current set of +// slices. +func (r *ReaderStream) stripEmpty() { + for len(r.current) > 0 && len(r.current[0].Bytes) == 0 { + r.current = r.current[1:] + r.lossReported = false + } +} + +// DataLost is returned by the ReaderStream's Read function when it encounters +// a Reassembly with Skip != 0. +var DataLost error = errors.New("lost data") + +// Read implements io.Reader's Read function. +// Given a byte slice, it will either copy a non-zero number of bytes into +// that slice and return the number of bytes and a nil error, or it will +// leave slice p as is and return 0, io.EOF. +func (r *ReaderStream) Read(p []byte) (int, error) { + if !r.initiated { + panic("ReaderStream not created via NewReaderStream") + } + var ok bool + r.stripEmpty() + for !r.closed && len(r.current) == 0 { + if r.first { + r.first = false + } else { + r.done <- true + } + if r.current, ok = <-r.reassembled; ok { + r.stripEmpty() + } else { + r.closed = true + } + } + if len(r.current) > 0 { + current := &r.current[0] + if r.LossErrors && !r.lossReported && current.Skip != 0 { + r.lossReported = true + return 0, DataLost + } + length := copy(p, current.Bytes) + current.Bytes = current.Bytes[length:] + return length, nil + } + return 0, io.EOF +} + +// Close implements io.Closer's Close function, making ReaderStream a +// io.ReadCloser. It discards all remaining bytes in the reassembly in a +// manner that's safe for the assembler (IE: it doesn't block). +func (r *ReaderStream) Close() error { + r.current = nil + r.closed = true + for { + if _, ok := <-r.reassembled; !ok { + return nil + } + r.done <- true + } +} diff --git a/vendor/github.com/google/gopacket/writer.go b/vendor/github.com/google/gopacket/writer.go new file mode 100644 index 0000000..dff8bf2 --- /dev/null +++ b/vendor/github.com/google/gopacket/writer.go @@ -0,0 +1,196 @@ +// 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 () + +// SerializableLayer allows its implementations to be written out as a set of bytes, +// so those bytes may be sent on the wire or otherwise used by the caller. +// SerializableLayer is implemented by certain Layer types, and can be encoded to +// bytes using the LayerWriter object. +type SerializableLayer interface { + // SerializeTo writes this layer to a slice, growing that slice if necessary + // to make it fit the layer's data. + // Args: + // b: SerializeBuffer to write this layer on to. When called, b.Bytes() + // is the payload this layer should wrap, if any. Note that this + // layer can either prepend itself (common), append itself + // (uncommon), or both (sometimes padding or footers are required at + // the end of packet data). It's also possible (though probably very + // rarely needed) to overwrite any bytes in the current payload. + // After this call, b.Bytes() should return the byte encoding of + // this layer wrapping the original b.Bytes() payload. + // opts: options to use while writing out data. + // Returns: + // error if a problem was encountered during encoding. If an error is + // returned, the bytes in data should be considered invalidated, and + // not used. + // + // SerializeTo calls SHOULD entirely ignore LayerContents and + // LayerPayload. It just serializes based on struct fields, neither + // modifying nor using contents/payload. + SerializeTo(b SerializeBuffer, opts SerializeOptions) error +} + +// SerializeOptions provides options for behaviors that SerializableLayers may want to +// implement. +type SerializeOptions struct { + // FixLengths determines whether, during serialization, layers should fix + // the values for any length field that depends on the payload. + FixLengths bool + // ComputeChecksums determines whether, during serialization, layers + // should recompute checksums based on their payloads. + ComputeChecksums bool +} + +// SerializeBuffer is a helper used by gopacket for writing out packet layers. +// SerializeBuffer starts off as an empty []byte. Subsequent calls to PrependBytes +// return byte slices before the current Bytes(), AppendBytes returns byte +// slices after. +// +// Byte slices returned by PrependBytes/AppendBytes are NOT zero'd out, so if +// you want to make sure they're all zeros, set them as such. +// +// SerializeBuffer is specifically designed to handle packet writing, where unlike +// with normal writes it's easier to start writing at the inner-most layer and +// work out, meaning that we often need to prepend bytes. This runs counter to +// typical writes to byte slices using append(), where we only write at the end +// of the buffer. +// +// It can be reused via Clear. Note, however, that a Clear call will invalidate the +// byte slices returned by any previous Bytes() call (the same buffer is +// reused). +// +// 1) Reusing a write buffer is generally much faster than creating a new one, +// and with the default implementation it avoids additional memory allocations. +// 2) If a byte slice from a previous Bytes() call will continue to be used, +// it's better to create a new SerializeBuffer. +// +// The Clear method is specifically designed to minimize memory allocations for +// similar later workloads on the SerializeBuffer. IE: if you make a set of +// Prepend/Append calls, then clear, then make the same calls with the same +// sizes, the second round (and all future similar rounds) shouldn't allocate +// any new memory. +type SerializeBuffer interface { + // Bytes returns the contiguous set of bytes collected so far by Prepend/Append + // calls. The slice returned by Bytes will be modified by future Clear calls, + // so if you're planning on clearing this SerializeBuffer, you may want to copy + // Bytes somewhere safe first. + Bytes() []byte + // PrependBytes returns a set of bytes which prepends the current bytes in this + // buffer. These bytes start in an indeterminate state, so they should be + // overwritten by the caller. The caller must only call PrependBytes if they + // know they're going to immediately overwrite all bytes returned. + PrependBytes(num int) ([]byte, error) + // AppendBytes returns a set of bytes which prepends the current bytes in this + // buffer. These bytes start in an indeterminate state, so they should be + // overwritten by the caller. The caller must only call AppendBytes if they + // know they're going to immediately overwrite all bytes returned. + AppendBytes(num int) ([]byte, error) + // Clear resets the SerializeBuffer to a new, empty buffer. After a call to clear, + // the byte slice returned by any previous call to Bytes() for this buffer + // should be considered invalidated. + Clear() error +} + +type serializeBuffer struct { + data []byte + start int + prepended, appended int +} + +// NewSerializeBuffer creates a new instance of the default implementation of +// the SerializeBuffer interface. +func NewSerializeBuffer() SerializeBuffer { + return &serializeBuffer{} +} + +// NewSerializeBufferExpectedSize creates a new buffer for serialization, optimized for an +// expected number of bytes prepended/appended. This tends to decrease the +// number of memory allocations made by the buffer during writes. +func NewSerializeBufferExpectedSize(expectedPrependLength, expectedAppendLength int) SerializeBuffer { + return &serializeBuffer{ + data: make([]byte, expectedPrependLength, expectedPrependLength+expectedAppendLength), + start: expectedPrependLength, + prepended: expectedPrependLength, + appended: expectedAppendLength, + } +} + +func (w *serializeBuffer) Bytes() []byte { + return w.data[w.start:] +} + +func (w *serializeBuffer) PrependBytes(num int) ([]byte, error) { + if num < 0 { + panic("num < 0") + } + if w.start < num { + toPrepend := w.prepended + if toPrepend < num { + toPrepend = num + } + w.prepended += toPrepend + length := cap(w.data) + toPrepend + newData := make([]byte, length) + newStart := w.start + toPrepend + copy(newData[newStart:], w.data[w.start:]) + w.start = newStart + w.data = newData[:toPrepend+len(w.data)] + } + w.start -= num + return w.data[w.start : w.start+num], nil +} + +func (w *serializeBuffer) AppendBytes(num int) ([]byte, error) { + if num < 0 { + panic("num < 0") + } + initialLength := len(w.data) + if cap(w.data)-initialLength < num { + toAppend := w.appended + if toAppend < num { + toAppend = num + } + w.appended += toAppend + newData := make([]byte, cap(w.data)+toAppend) + copy(newData[w.start:], w.data[w.start:]) + w.data = newData[:initialLength] + } + // Grow the buffer. We know it'll be under capacity given above. + w.data = w.data[:initialLength+num] + return w.data[initialLength:], nil +} + +func (w *serializeBuffer) Clear() error { + w.start = w.prepended + w.data = w.data[:w.start] + return nil +} + +// SerializeLayers clears the given write buffer, then writes all layers into it so +// they correctly wrap each other. Note that by clearing the buffer, it +// invalidates all slices previously returned by w.Bytes() +// +// Example: +// buf := gopacket.NewSerializeBuffer() +// opts := gopacket.SerializeOptions{} +// gopacket.SerializeLayers(buf, opts, a, b, c) +// firstPayload := buf.Bytes() // contains byte representation of a(b(c)) +// gopacket.SerializeLayers(buf, opts, d, e, f) +// secondPayload := buf.Bytes() // contains byte representation of d(e(f)). firstPayload is now invalidated, since the SerializeLayers call Clears buf. +func SerializeLayers(w SerializeBuffer, opts SerializeOptions, layers ...SerializableLayer) error { + w.Clear() + for i := len(layers) - 1; i >= 0; i-- { + layer := layers[i] + err := layer.SerializeTo(w, opts) + if err != nil { + return err + } + } + return nil +} diff --git a/vendor/github.com/klauspost/crc32/.gitignore b/vendor/github.com/klauspost/crc32/.gitignore new file mode 100644 index 0000000..daf913b --- /dev/null +++ b/vendor/github.com/klauspost/crc32/.gitignore @@ -0,0 +1,24 @@ +# 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 +*.test +*.prof diff --git a/vendor/github.com/klauspost/crc32/.travis.yml b/vendor/github.com/klauspost/crc32/.travis.yml new file mode 100644 index 0000000..9771799 --- /dev/null +++ b/vendor/github.com/klauspost/crc32/.travis.yml @@ -0,0 +1,12 @@ +language: go + +go: + - 1.3 + - 1.4 + - 1.5 + - 1.6 + - tip + +script: + - go test -v . + - go test -v -race . diff --git a/vendor/github.com/klauspost/crc32/LICENSE b/vendor/github.com/klauspost/crc32/LICENSE new file mode 100644 index 0000000..4fd5963 --- /dev/null +++ b/vendor/github.com/klauspost/crc32/LICENSE @@ -0,0 +1,28 @@ +Copyright (c) 2012 The Go Authors. All rights reserved. +Copyright (c) 2015 Klaus Post + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/klauspost/crc32/README.md b/vendor/github.com/klauspost/crc32/README.md new file mode 100644 index 0000000..440541c --- /dev/null +++ b/vendor/github.com/klauspost/crc32/README.md @@ -0,0 +1,84 @@ +# crc32 +CRC32 hash with x64 optimizations + +This package is a drop-in replacement for the standard library `hash/crc32` package, that features SSE 4.2 optimizations on x64 platforms, for a 10x speedup. + +[![Build Status](https://travis-ci.org/klauspost/crc32.svg?branch=master)](https://travis-ci.org/klauspost/crc32) + +# usage + +Install using `go get github.com/klauspost/crc32`. This library is based on Go 1.5 code and requires Go 1.3 or newer. + +Replace `import "hash/crc32"` with `import "github.com/klauspost/crc32"` and you are good to go. + +# changes + +* Dec 4, 2015: Uses the "slice-by-8" trick more extensively, which gives a 1.5 to 2.5x speedup if assembler is unavailable. + + +# performance + +For IEEE tables (the most common), there is approximately a factor 10 speedup with "CLMUL" (Carryless multiplication) instruction: +``` +benchmark old ns/op new ns/op delta +BenchmarkCrc32KB 99955 10258 -89.74% + +benchmark old MB/s new MB/s speedup +BenchmarkCrc32KB 327.83 3194.20 9.74x +``` + +For other tables and "CLMUL" capable machines the performance is the same as the standard library. + +Here are some detailed benchmarks, comparing to go 1.5 standard library with and without assembler enabled. + +``` +Std: Standard Go 1.5 library +Crc: Indicates IEEE type CRC. +40B: Size of each slice encoded. +NoAsm: Assembler was disabled (ie. not an AMD64 or SSE 4.2+ capable machine). +Castagnoli: Castagnoli CRC type. + +BenchmarkStdCrc40B-4 10000000 158 ns/op 252.88 MB/s +BenchmarkCrc40BNoAsm-4 20000000 105 ns/op 377.38 MB/s (slice8) +BenchmarkCrc40B-4 20000000 105 ns/op 378.77 MB/s (slice8) + +BenchmarkStdCrc1KB-4 500000 3604 ns/op 284.10 MB/s +BenchmarkCrc1KBNoAsm-4 1000000 1463 ns/op 699.79 MB/s (slice8) +BenchmarkCrc1KB-4 3000000 396 ns/op 2583.69 MB/s (asm) + +BenchmarkStdCrc8KB-4 200000 11417 ns/op 717.48 MB/s (slice8) +BenchmarkCrc8KBNoAsm-4 200000 11317 ns/op 723.85 MB/s (slice8) +BenchmarkCrc8KB-4 500000 2919 ns/op 2805.73 MB/s (asm) + +BenchmarkStdCrc32KB-4 30000 45749 ns/op 716.24 MB/s (slice8) +BenchmarkCrc32KBNoAsm-4 30000 45109 ns/op 726.42 MB/s (slice8) +BenchmarkCrc32KB-4 100000 11497 ns/op 2850.09 MB/s (asm) + +BenchmarkStdNoAsmCastagnol40B-4 10000000 161 ns/op 246.94 MB/s +BenchmarkStdCastagnoli40B-4 50000000 28.4 ns/op 1410.69 MB/s (asm) +BenchmarkCastagnoli40BNoAsm-4 20000000 100 ns/op 398.01 MB/s (slice8) +BenchmarkCastagnoli40B-4 50000000 28.2 ns/op 1419.54 MB/s (asm) + +BenchmarkStdNoAsmCastagnoli1KB-4 500000 3622 ns/op 282.67 MB/s +BenchmarkStdCastagnoli1KB-4 10000000 144 ns/op 7099.78 MB/s (asm) +BenchmarkCastagnoli1KBNoAsm-4 1000000 1475 ns/op 694.14 MB/s (slice8) +BenchmarkCastagnoli1KB-4 10000000 146 ns/op 6993.35 MB/s (asm) + +BenchmarkStdNoAsmCastagnoli8KB-4 50000 28781 ns/op 284.63 MB/s +BenchmarkStdCastagnoli8KB-4 1000000 1029 ns/op 7957.89 MB/s (asm) +BenchmarkCastagnoli8KBNoAsm-4 200000 11410 ns/op 717.94 MB/s (slice8) +BenchmarkCastagnoli8KB-4 1000000 1000 ns/op 8188.71 MB/s (asm) + +BenchmarkStdNoAsmCastagnoli32KB-4 10000 115426 ns/op 283.89 MB/s +BenchmarkStdCastagnoli32KB-4 300000 4065 ns/op 8059.13 MB/s (asm) +BenchmarkCastagnoli32KBNoAsm-4 30000 45171 ns/op 725.41 MB/s (slice8) +BenchmarkCastagnoli32KB-4 500000 4077 ns/op 8035.89 MB/s (asm) +``` + +The IEEE assembler optimizations has been submitted and will be part of the Go 1.6 standard library. + +However, the improved use of slice-by-8 has not, but will probably be submitted for Go 1.7. + +# license + +Standard Go license. Changes are Copyright (c) 2015 Klaus Post under same conditions. diff --git a/vendor/github.com/klauspost/crc32/crc32.go b/vendor/github.com/klauspost/crc32/crc32.go new file mode 100644 index 0000000..8d6ba5d --- /dev/null +++ b/vendor/github.com/klauspost/crc32/crc32.go @@ -0,0 +1,186 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package crc32 implements the 32-bit cyclic redundancy check, or CRC-32, +// checksum. See http://en.wikipedia.org/wiki/Cyclic_redundancy_check for +// information. +// +// Polynomials are represented in LSB-first form also known as reversed representation. +// +// See http://en.wikipedia.org/wiki/Mathematics_of_cyclic_redundancy_checks#Reversed_representations_and_reciprocal_polynomials +// for information. +package crc32 + +import ( + "hash" + "sync" +) + +// The size of a CRC-32 checksum in bytes. +const Size = 4 + +// Predefined polynomials. +const ( + // IEEE is by far and away the most common CRC-32 polynomial. + // Used by ethernet (IEEE 802.3), v.42, fddi, gzip, zip, png, ... + IEEE = 0xedb88320 + + // Castagnoli's polynomial, used in iSCSI. + // Has better error detection characteristics than IEEE. + // http://dx.doi.org/10.1109/26.231911 + Castagnoli = 0x82f63b78 + + // Koopman's polynomial. + // Also has better error detection characteristics than IEEE. + // http://dx.doi.org/10.1109/DSN.2002.1028931 + Koopman = 0xeb31d82e +) + +// Table is a 256-word table representing the polynomial for efficient processing. +type Table [256]uint32 + +// castagnoliTable points to a lazily initialized Table for the Castagnoli +// polynomial. MakeTable will always return this value when asked to make a +// Castagnoli table so we can compare against it to find when the caller is +// using this polynomial. +var castagnoliTable *Table +var castagnoliTable8 *slicing8Table +var castagnoliOnce sync.Once + +func castagnoliInit() { + castagnoliTable = makeTable(Castagnoli) + castagnoliTable8 = makeTable8(Castagnoli) +} + +// IEEETable is the table for the IEEE polynomial. +var IEEETable = makeTable(IEEE) + +// slicing8Table is array of 8 Tables +type slicing8Table [8]Table + +// ieeeTable8 is the slicing8Table for IEEE +var ieeeTable8 *slicing8Table +var ieeeTable8Once sync.Once + +// MakeTable returns a Table constructed from the specified polynomial. +// The contents of this Table must not be modified. +func MakeTable(poly uint32) *Table { + switch poly { + case IEEE: + return IEEETable + case Castagnoli: + castagnoliOnce.Do(castagnoliInit) + return castagnoliTable + } + return makeTable(poly) +} + +// makeTable returns the Table constructed from the specified polynomial. +func makeTable(poly uint32) *Table { + t := new(Table) + for i := 0; i < 256; i++ { + crc := uint32(i) + for j := 0; j < 8; j++ { + if crc&1 == 1 { + crc = (crc >> 1) ^ poly + } else { + crc >>= 1 + } + } + t[i] = crc + } + return t +} + +// makeTable8 returns slicing8Table constructed from the specified polynomial. +func makeTable8(poly uint32) *slicing8Table { + t := new(slicing8Table) + t[0] = *makeTable(poly) + for i := 0; i < 256; i++ { + crc := t[0][i] + for j := 1; j < 8; j++ { + crc = t[0][crc&0xFF] ^ (crc >> 8) + t[j][i] = crc + } + } + return t +} + +// digest represents the partial evaluation of a checksum. +type digest struct { + crc uint32 + tab *Table +} + +// New creates a new hash.Hash32 computing the CRC-32 checksum +// using the polynomial represented by the Table. +// Its Sum method will lay the value out in big-endian byte order. +func New(tab *Table) hash.Hash32 { return &digest{0, tab} } + +// NewIEEE creates a new hash.Hash32 computing the CRC-32 checksum +// using the IEEE polynomial. +// Its Sum method will lay the value out in big-endian byte order. +func NewIEEE() hash.Hash32 { return New(IEEETable) } + +func (d *digest) Size() int { return Size } + +func (d *digest) BlockSize() int { return 1 } + +func (d *digest) Reset() { d.crc = 0 } + +func update(crc uint32, tab *Table, p []byte) uint32 { + crc = ^crc + for _, v := range p { + crc = tab[byte(crc)^v] ^ (crc >> 8) + } + return ^crc +} + +// updateSlicingBy8 updates CRC using Slicing-by-8 +func updateSlicingBy8(crc uint32, tab *slicing8Table, p []byte) uint32 { + crc = ^crc + for len(p) > 8 { + crc ^= uint32(p[0]) | uint32(p[1])<<8 | uint32(p[2])<<16 | uint32(p[3])<<24 + crc = tab[0][p[7]] ^ tab[1][p[6]] ^ tab[2][p[5]] ^ tab[3][p[4]] ^ + tab[4][crc>>24] ^ tab[5][(crc>>16)&0xFF] ^ + tab[6][(crc>>8)&0xFF] ^ tab[7][crc&0xFF] + p = p[8:] + } + crc = ^crc + if len(p) == 0 { + return crc + } + return update(crc, &tab[0], p) +} + +// Update returns the result of adding the bytes in p to the crc. +func Update(crc uint32, tab *Table, p []byte) uint32 { + if tab == castagnoliTable { + return updateCastagnoli(crc, p) + } + if tab == IEEETable { + return updateIEEE(crc, p) + } + return update(crc, tab, p) +} + +func (d *digest) Write(p []byte) (n int, err error) { + d.crc = Update(d.crc, d.tab, p) + return len(p), nil +} + +func (d *digest) Sum32() uint32 { return d.crc } + +func (d *digest) Sum(in []byte) []byte { + s := d.Sum32() + return append(in, byte(s>>24), byte(s>>16), byte(s>>8), byte(s)) +} + +// Checksum returns the CRC-32 checksum of data +// using the polynomial represented by the Table. +func Checksum(data []byte, tab *Table) uint32 { return Update(0, tab, data) } + +// ChecksumIEEE returns the CRC-32 checksum of data +// using the IEEE polynomial. +func ChecksumIEEE(data []byte) uint32 { return updateIEEE(0, data) } diff --git a/vendor/github.com/klauspost/crc32/crc32_amd64.go b/vendor/github.com/klauspost/crc32/crc32_amd64.go new file mode 100644 index 0000000..4827128 --- /dev/null +++ b/vendor/github.com/klauspost/crc32/crc32_amd64.go @@ -0,0 +1,62 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build !appengine,!gccgo + +package crc32 + +// This file contains the code to call the SSE 4.2 version of the Castagnoli +// and IEEE CRC. + +// haveSSE41/haveSSE42/haveCLMUL are defined in crc_amd64.s and use +// CPUID to test for SSE 4.1, 4.2 and CLMUL support. +func haveSSE41() bool +func haveSSE42() bool +func haveCLMUL() bool + +// castagnoliSSE42 is defined in crc_amd64.s and uses the SSE4.2 CRC32 +// instruction. +//go:noescape +func castagnoliSSE42(crc uint32, p []byte) uint32 + +// ieeeCLMUL is defined in crc_amd64.s and uses the PCLMULQDQ +// instruction as well as SSE 4.1. +//go:noescape +func ieeeCLMUL(crc uint32, p []byte) uint32 + +var sse42 = haveSSE42() +var useFastIEEE = haveCLMUL() && haveSSE41() + +func updateCastagnoli(crc uint32, p []byte) uint32 { + if sse42 { + return castagnoliSSE42(crc, p) + } + // only use slicing-by-8 when input is >= 16 Bytes + if len(p) >= 16 { + return updateSlicingBy8(crc, castagnoliTable8, p) + } + return update(crc, castagnoliTable, p) +} + +func updateIEEE(crc uint32, p []byte) uint32 { + if useFastIEEE && len(p) >= 64 { + left := len(p) & 15 + do := len(p) - left + crc = ^ieeeCLMUL(^crc, p[:do]) + if left > 0 { + crc = update(crc, IEEETable, p[do:]) + } + return crc + } + + // only use slicing-by-8 when input is >= 16 Bytes + if len(p) >= 16 { + ieeeTable8Once.Do(func() { + ieeeTable8 = makeTable8(IEEE) + }) + return updateSlicingBy8(crc, ieeeTable8, p) + } + + return update(crc, IEEETable, p) +} diff --git a/vendor/github.com/klauspost/crc32/crc32_amd64.s b/vendor/github.com/klauspost/crc32/crc32_amd64.s new file mode 100644 index 0000000..9bf05d8 --- /dev/null +++ b/vendor/github.com/klauspost/crc32/crc32_amd64.s @@ -0,0 +1,237 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build gc + +#define NOSPLIT 4 +#define RODATA 8 + +// func castagnoliSSE42(crc uint32, p []byte) uint32 +TEXT ·castagnoliSSE42(SB), NOSPLIT, $0 + MOVL crc+0(FP), AX // CRC value + MOVQ p+8(FP), SI // data pointer + MOVQ p_len+16(FP), CX // len(p) + + NOTL AX + + // If there's less than 8 bytes to process, we do it byte-by-byte. + CMPQ CX, $8 + JL cleanup + + // Process individual bytes until the input is 8-byte aligned. +startup: + MOVQ SI, BX + ANDQ $7, BX + JZ aligned + + CRC32B (SI), AX + DECQ CX + INCQ SI + JMP startup + +aligned: + // The input is now 8-byte aligned and we can process 8-byte chunks. + CMPQ CX, $8 + JL cleanup + + CRC32Q (SI), AX + ADDQ $8, SI + SUBQ $8, CX + JMP aligned + +cleanup: + // We may have some bytes left over that we process one at a time. + CMPQ CX, $0 + JE done + + CRC32B (SI), AX + INCQ SI + DECQ CX + JMP cleanup + +done: + NOTL AX + MOVL AX, ret+32(FP) + RET + +// func haveSSE42() bool +TEXT ·haveSSE42(SB), NOSPLIT, $0 + XORQ AX, AX + INCL AX + CPUID + SHRQ $20, CX + ANDQ $1, CX + MOVB CX, ret+0(FP) + RET + +// func haveCLMUL() bool +TEXT ·haveCLMUL(SB), NOSPLIT, $0 + XORQ AX, AX + INCL AX + CPUID + SHRQ $1, CX + ANDQ $1, CX + MOVB CX, ret+0(FP) + RET + +// func haveSSE41() bool +TEXT ·haveSSE41(SB), NOSPLIT, $0 + XORQ AX, AX + INCL AX + CPUID + SHRQ $19, CX + ANDQ $1, CX + MOVB CX, ret+0(FP) + RET + +// CRC32 polynomial data +// +// These constants are lifted from the +// Linux kernel, since they avoid the costly +// PSHUFB 16 byte reversal proposed in the +// original Intel paper. +DATA r2r1kp<>+0(SB)/8, $0x154442bd4 +DATA r2r1kp<>+8(SB)/8, $0x1c6e41596 +DATA r4r3kp<>+0(SB)/8, $0x1751997d0 +DATA r4r3kp<>+8(SB)/8, $0x0ccaa009e +DATA rupolykp<>+0(SB)/8, $0x1db710641 +DATA rupolykp<>+8(SB)/8, $0x1f7011641 +DATA r5kp<>+0(SB)/8, $0x163cd6124 + +GLOBL r2r1kp<>(SB), RODATA, $16 +GLOBL r4r3kp<>(SB), RODATA, $16 +GLOBL rupolykp<>(SB), RODATA, $16 +GLOBL r5kp<>(SB), RODATA, $8 + +// Based on http://www.intel.com/content/dam/www/public/us/en/documents/white-papers/fast-crc-computation-generic-polynomials-pclmulqdq-paper.pdf +// len(p) must be at least 64, and must be a multiple of 16. + +// func ieeeCLMUL(crc uint32, p []byte) uint32 +TEXT ·ieeeCLMUL(SB), NOSPLIT, $0 + MOVL crc+0(FP), X0 // Initial CRC value + MOVQ p+8(FP), SI // data pointer + MOVQ p_len+16(FP), CX // len(p) + + MOVOU (SI), X1 + MOVOU 16(SI), X2 + MOVOU 32(SI), X3 + MOVOU 48(SI), X4 + PXOR X0, X1 + ADDQ $64, SI // buf+=64 + SUBQ $64, CX // len-=64 + CMPQ CX, $64 // Less than 64 bytes left + JB remain64 + + MOVOA r2r1kp<>+0(SB), X0 + +loopback64: + MOVOA X1, X5 + MOVOA X2, X6 + MOVOA X3, X7 + MOVOA X4, X8 + + PCLMULQDQ $0, X0, X1 + PCLMULQDQ $0, X0, X2 + PCLMULQDQ $0, X0, X3 + PCLMULQDQ $0, X0, X4 + + // Load next early + MOVOU (SI), X11 + MOVOU 16(SI), X12 + MOVOU 32(SI), X13 + MOVOU 48(SI), X14 + + PCLMULQDQ $0x11, X0, X5 + PCLMULQDQ $0x11, X0, X6 + PCLMULQDQ $0x11, X0, X7 + PCLMULQDQ $0x11, X0, X8 + + PXOR X5, X1 + PXOR X6, X2 + PXOR X7, X3 + PXOR X8, X4 + + PXOR X11, X1 + PXOR X12, X2 + PXOR X13, X3 + PXOR X14, X4 + + ADDQ $0x40, DI + ADDQ $64, SI // buf+=64 + SUBQ $64, CX // len-=64 + CMPQ CX, $64 // Less than 64 bytes left? + JGE loopback64 + + // Fold result into a single register (X1) +remain64: + MOVOA r4r3kp<>+0(SB), X0 + + MOVOA X1, X5 + PCLMULQDQ $0, X0, X1 + PCLMULQDQ $0x11, X0, X5 + PXOR X5, X1 + PXOR X2, X1 + + MOVOA X1, X5 + PCLMULQDQ $0, X0, X1 + PCLMULQDQ $0x11, X0, X5 + PXOR X5, X1 + PXOR X3, X1 + + MOVOA X1, X5 + PCLMULQDQ $0, X0, X1 + PCLMULQDQ $0x11, X0, X5 + PXOR X5, X1 + PXOR X4, X1 + + // More than 16 bytes left? + CMPQ CX, $16 + JB finish + + // Encode 16 bytes +remain16: + MOVOU (SI), X10 + MOVOA X1, X5 + PCLMULQDQ $0, X0, X1 + PCLMULQDQ $0x11, X0, X5 + PXOR X5, X1 + PXOR X10, X1 + SUBQ $16, CX + ADDQ $16, SI + CMPQ CX, $16 + JGE remain16 + +finish: + // Fold final result into 32 bits and return it + PCMPEQB X3, X3 + PCLMULQDQ $1, X1, X0 + PSRLDQ $8, X1 + PXOR X0, X1 + + MOVOA X1, X2 + MOVQ r5kp<>+0(SB), X0 + + // Creates 32 bit mask. Note that we don't care about upper half. + PSRLQ $32, X3 + + PSRLDQ $4, X2 + PAND X3, X1 + PCLMULQDQ $0, X0, X1 + PXOR X2, X1 + + MOVOA rupolykp<>+0(SB), X0 + + MOVOA X1, X2 + PAND X3, X1 + PCLMULQDQ $0x10, X0, X1 + PAND X3, X1 + PCLMULQDQ $0, X0, X1 + PXOR X2, X1 + + // PEXTRD $1, X1, AX (SSE 4.1) + BYTE $0x66; BYTE $0x0f; BYTE $0x3a + BYTE $0x16; BYTE $0xc8; BYTE $0x01 + MOVL AX, ret+32(FP) + + RET diff --git a/vendor/github.com/klauspost/crc32/crc32_amd64p32.go b/vendor/github.com/klauspost/crc32/crc32_amd64p32.go new file mode 100644 index 0000000..926473e --- /dev/null +++ b/vendor/github.com/klauspost/crc32/crc32_amd64p32.go @@ -0,0 +1,40 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build !appengine,!gccgo + +package crc32 + +// This file contains the code to call the SSE 4.2 version of the Castagnoli +// CRC. + +// haveSSE42 is defined in crc_amd64p32.s and uses CPUID to test for SSE 4.2 +// support. +func haveSSE42() bool + +// castagnoliSSE42 is defined in crc_amd64.s and uses the SSE4.2 CRC32 +// instruction. +//go:noescape +func castagnoliSSE42(crc uint32, p []byte) uint32 + +var sse42 = haveSSE42() + +func updateCastagnoli(crc uint32, p []byte) uint32 { + if sse42 { + return castagnoliSSE42(crc, p) + } + return update(crc, castagnoliTable, p) +} + +func updateIEEE(crc uint32, p []byte) uint32 { + // only use slicing-by-8 when input is >= 4KB + if len(p) >= 4096 { + ieeeTable8Once.Do(func() { + ieeeTable8 = makeTable8(IEEE) + }) + return updateSlicingBy8(crc, ieeeTable8, p) + } + + return update(crc, IEEETable, p) +} diff --git a/vendor/github.com/klauspost/crc32/crc32_amd64p32.s b/vendor/github.com/klauspost/crc32/crc32_amd64p32.s new file mode 100644 index 0000000..a578d68 --- /dev/null +++ b/vendor/github.com/klauspost/crc32/crc32_amd64p32.s @@ -0,0 +1,67 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build gc + +#define NOSPLIT 4 +#define RODATA 8 + +// func castagnoliSSE42(crc uint32, p []byte) uint32 +TEXT ·castagnoliSSE42(SB), NOSPLIT, $0 + MOVL crc+0(FP), AX // CRC value + MOVL p+4(FP), SI // data pointer + MOVL p_len+8(FP), CX // len(p) + + NOTL AX + + // If there's less than 8 bytes to process, we do it byte-by-byte. + CMPQ CX, $8 + JL cleanup + + // Process individual bytes until the input is 8-byte aligned. +startup: + MOVQ SI, BX + ANDQ $7, BX + JZ aligned + + CRC32B (SI), AX + DECQ CX + INCQ SI + JMP startup + +aligned: + // The input is now 8-byte aligned and we can process 8-byte chunks. + CMPQ CX, $8 + JL cleanup + + CRC32Q (SI), AX + ADDQ $8, SI + SUBQ $8, CX + JMP aligned + +cleanup: + // We may have some bytes left over that we process one at a time. + CMPQ CX, $0 + JE done + + CRC32B (SI), AX + INCQ SI + DECQ CX + JMP cleanup + +done: + NOTL AX + MOVL AX, ret+16(FP) + RET + +// func haveSSE42() bool +TEXT ·haveSSE42(SB), NOSPLIT, $0 + XORQ AX, AX + INCL AX + CPUID + SHRQ $20, CX + ANDQ $1, CX + MOVB CX, ret+0(FP) + RET + diff --git a/vendor/github.com/klauspost/crc32/crc32_generic.go b/vendor/github.com/klauspost/crc32/crc32_generic.go new file mode 100644 index 0000000..a53cf96 --- /dev/null +++ b/vendor/github.com/klauspost/crc32/crc32_generic.go @@ -0,0 +1,29 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build !amd64,!amd64p32 appengine gccgo + +package crc32 + +// This file contains the generic version of updateCastagnoli which does +// slicing-by-8, or uses the fallback for very small sizes. + +func updateCastagnoli(crc uint32, p []byte) uint32 { + // only use slicing-by-8 when input is >= 16 Bytes + if len(p) >= 16 { + return updateSlicingBy8(crc, castagnoliTable8, p) + } + return update(crc, castagnoliTable, p) +} + +func updateIEEE(crc uint32, p []byte) uint32 { + // only use slicing-by-8 when input is >= 16 Bytes + if len(p) >= 16 { + ieeeTable8Once.Do(func() { + ieeeTable8 = makeTable8(IEEE) + }) + return updateSlicingBy8(crc, ieeeTable8, p) + } + return update(crc, IEEETable, p) +} diff --git a/vendor/github.com/nranchev/go-libGeoIP/LICENSE.txt b/vendor/github.com/nranchev/go-libGeoIP/LICENSE.txt new file mode 100644 index 0000000..5a0cb2d --- /dev/null +++ b/vendor/github.com/nranchev/go-libGeoIP/LICENSE.txt @@ -0,0 +1,24 @@ +Copyright (c) 2010, Nikola Ranchev +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/nranchev/go-libGeoIP/README.textile b/vendor/github.com/nranchev/go-libGeoIP/README.textile new file mode 100644 index 0000000..2e449b8 --- /dev/null +++ b/vendor/github.com/nranchev/go-libGeoIP/README.textile @@ -0,0 +1,46 @@ +h2. General Description + +p{width:500px}. This is the Go implementation of the "Maxmind":http://www.maxmind.com/app/ip-location GeoIP API. It is incomplete and work in progress the initial goal is support only two of the database types - the City Lite and Country Lite. The only supported method is loading the full db on startup into memory (memory cache). + +h3. Supported Access Methods + +* In Memory (Load(string)) + +h3. Supported Database Formats + +* Country Edition (dbType=1) +* City Edition REV 0 (dbType=6) +* City Edition REV 1 (dbType=2) + +h3. Supported Lookups + +* By IP Address (GetLocationByIP(string)) +* By IP Number (GetLocationByIPNum(uint32)) + +h3. Supported Responses + +* CountryCode string (available in all databases) +* CountryName string (available in all databases) +* City string +* Region string +* PostalCode string +* Latitude float32 +* Longitude float32 + +h3. To Do +* Implement better error handling (report the error on load and lookups) +* Better returns, country edition has only code and name (perhaps use interfaces) +* Add test cases and benchmarking +* Add support for more database formats + +h3. Build + +make (See Makefile for more details) + +h3. Example + +./example DBFILE IPADDRESS (i.e. ./example GeoIP.dat 1.1.1.1) + +h3. Usage + +Please see example.go for a complete example of how to use this library. diff --git a/vendor/github.com/nranchev/go-libGeoIP/example/example.go b/vendor/github.com/nranchev/go-libGeoIP/example/example.go new file mode 100644 index 0000000..8252b62 --- /dev/null +++ b/vendor/github.com/nranchev/go-libGeoIP/example/example.go @@ -0,0 +1,39 @@ +package main + +import ( + "flag" + "fmt" + "github.com/nranchev/go-libGeoIP" +) + +func main() { + flag.Parse() + + // Check the number of arguments + if flag.NArg() < 2 { + fmt.Printf("usage: main DBFILE IPADDRESS\n") + return + } + + // Set the arguments + dbFile := flag.Arg(0) + ipAddr := flag.Arg(1) + + // Load the database file, exit on failure + gi, err := libgeo.Load(dbFile) + if err != nil { + fmt.Printf("Error: %s\n", err.Error()) + return + } + + // Lookup the IP and display the details if country is found + loc := gi.GetLocationByIP(ipAddr) + if loc != nil { + fmt.Printf("Country: %s (%s)\n", loc.CountryName, loc.CountryCode) + fmt.Printf("City: %s\n", loc.City) + fmt.Printf("Region: %s\n", loc.Region) + fmt.Printf("Postal Code: %s\n", loc.PostalCode) + fmt.Printf("Latitude: %f\n", loc.Latitude) + fmt.Printf("Longitude: %f\n", loc.Longitude) + } +} diff --git a/vendor/github.com/nranchev/go-libGeoIP/libgeo.go b/vendor/github.com/nranchev/go-libGeoIP/libgeo.go new file mode 100644 index 0000000..4794a55 --- /dev/null +++ b/vendor/github.com/nranchev/go-libGeoIP/libgeo.go @@ -0,0 +1,354 @@ +/** + * libgeo.go + * + * Copyright (c) 2010, Nikola Ranchev + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of the nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package libgeo + +// Dependencies +import ( + "errors" + "os" +) + +// Globals (const arrays that will be initialized inside init()) +var ( + countryCode = []string{ + "--", "AP", "EU", "AD", "AE", "AF", "AG", "AI", "AL", "AM", "AN", "AO", "AQ", "AR", + "AS", "AT", "AU", "AW", "AZ", "BA", "BB", "BD", "BE", "BF", "BG", "BH", "BI", "BJ", + "BM", "BN", "BO", "BR", "BS", "BT", "BV", "BW", "BY", "BZ", "CA", "CC", "CD", "CF", + "CG", "CH", "CI", "CK", "CL", "CM", "CN", "CO", "CR", "CU", "CV", "CX", "CY", "CZ", + "DE", "DJ", "DK", "DM", "DO", "DZ", "EC", "EE", "EG", "EH", "ER", "ES", "ET", "FI", + "FJ", "FK", "FM", "FO", "FR", "FX", "GA", "GB", "GD", "GE", "GF", "GH", "GI", "GL", + "GM", "GN", "GP", "GQ", "GR", "GS", "GT", "GU", "GW", "GY", "HK", "HM", "HN", "HR", + "HT", "HU", "ID", "IE", "IL", "IN", "IO", "IQ", "IR", "IS", "IT", "JM", "JO", "JP", + "KE", "KG", "KH", "KI", "KM", "KN", "KP", "KR", "KW", "KY", "KZ", "LA", "LB", "LC", + "LI", "LK", "LR", "LS", "LT", "LU", "LV", "LY", "MA", "MC", "MD", "MG", "MH", "MK", + "ML", "MM", "MN", "MO", "MP", "MQ", "MR", "MS", "MT", "MU", "MV", "MW", "MX", "MY", + "MZ", "NA", "NC", "NE", "NF", "NG", "NI", "NL", "NO", "NP", "NR", "NU", "NZ", "OM", + "PA", "PE", "PF", "PG", "PH", "PK", "PL", "PM", "PN", "PR", "PS", "PT", "PW", "PY", + "QA", "RE", "RO", "RU", "RW", "SA", "SB", "SC", "SD", "SE", "SG", "SH", "SI", "SJ", + "SK", "SL", "SM", "SN", "SO", "SR", "ST", "SV", "SY", "SZ", "TC", "TD", "TF", "TG", + "TH", "TJ", "TK", "TM", "TN", "TO", "TL", "TR", "TT", "TV", "TW", "TZ", "UA", "UG", + "UM", "US", "UY", "UZ", "VA", "VC", "VE", "VG", "VI", "VN", "VU", "WF", "WS", "YE", + "YT", "RS", "ZA", "ZM", "ME", "ZW", "A1", "A2", "O1", "AX", "GG", "IM", "JE", "BL", + "MF", "BQ", "SS", "O1"} + countryName = []string{ + "N/A", "Asia/Pacific Region", "Europe", "Andorra", "United Arab Emirates", + "Afghanistan", "Antigua and Barbuda", "Anguilla", "Albania", "Armenia", + "Netherlands Antilles", "Angola", "Antarctica", "Argentina", "American Samoa", + "Austria", "Australia", "Aruba", "Azerbaijan", "Bosnia and Herzegovina", + "Barbados", "Bangladesh", "Belgium", "Burkina Faso", "Bulgaria", "Bahrain", + "Burundi", "Benin", "Bermuda", "Brunei Darussalam", "Bolivia", "Brazil", "Bahamas", + "Bhutan", "Bouvet Island", "Botswana", "Belarus", "Belize", "Canada", + "Cocos (Keeling) Islands", "Congo, The Democratic Republic of the", + "Central African Republic", "Congo", "Switzerland", "Cote D'Ivoire", + "Cook Islands", "Chile", "Cameroon", "China", "Colombia", "Costa Rica", "Cuba", + "Cape Verde", "Christmas Island", "Cyprus", "Czech Republic", "Germany", + "Djibouti", "Denmark", "Dominica", "Dominican Republic", "Algeria", "Ecuador", + "Estonia", "Egypt", "Western Sahara", "Eritrea", "Spain", "Ethiopia", "Finland", + "Fiji", "Falkland Islands (Malvinas)", "Micronesia, Federated States of", + "Faroe Islands", "France", "France, Metropolitan", "Gabon", "United Kingdom", + "Grenada", "Georgia", "French Guiana", "Ghana", "Gibraltar", "Greenland", "Gambia", + "Guinea", "Guadeloupe", "Equatorial Guinea", "Greece", + "South Georgia and the South Sandwich Islands", "Guatemala", "Guam", + "Guinea-Bissau", "Guyana", "Hong Kong", "Heard Island and McDonald Islands", + "Honduras", "Croatia", "Haiti", "Hungary", "Indonesia", "Ireland", "Israel", "India", + "British Indian Ocean Territory", "Iraq", "Iran, Islamic Republic of", + "Iceland", "Italy", "Jamaica", "Jordan", "Japan", "Kenya", "Kyrgyzstan", "Cambodia", + "Kiribati", "Comoros", "Saint Kitts and Nevis", + "Korea, Democratic People's Republic of", "Korea, Republic of", "Kuwait", + "Cayman Islands", "Kazakhstan", "Lao People's Democratic Republic", "Lebanon", + "Saint Lucia", "Liechtenstein", "Sri Lanka", "Liberia", "Lesotho", "Lithuania", + "Luxembourg", "Latvia", "Libyan Arab Jamahiriya", "Morocco", "Monaco", + "Moldova, Republic of", "Madagascar", "Marshall Islands", + "Macedonia", "Mali", "Myanmar", "Mongolia", + "Macau", "Northern Mariana Islands", "Martinique", "Mauritania", "Montserrat", + "Malta", "Mauritius", "Maldives", "Malawi", "Mexico", "Malaysia", "Mozambique", + "Namibia", "New Caledonia", "Niger", "Norfolk Island", "Nigeria", "Nicaragua", + "Netherlands", "Norway", "Nepal", "Nauru", "Niue", "New Zealand", "Oman", "Panama", + "Peru", "French Polynesia", "Papua New Guinea", "Philippines", "Pakistan", + "Poland", "Saint Pierre and Miquelon", "Pitcairn Islands", "Puerto Rico", + "Palestinian Territory", "Portugal", "Palau", "Paraguay", "Qatar", + "Reunion", "Romania", "Russian Federation", "Rwanda", "Saudi Arabia", + "Solomon Islands", "Seychelles", "Sudan", "Sweden", "Singapore", "Saint Helena", + "Slovenia", "Svalbard and Jan Mayen", "Slovakia", "Sierra Leone", "San Marino", + "Senegal", "Somalia", "Suriname", "Sao Tome and Principe", "El Salvador", + "Syrian Arab Republic", "Swaziland", "Turks and Caicos Islands", "Chad", + "French Southern Territories", "Togo", "Thailand", "Tajikistan", "Tokelau", + "Turkmenistan", "Tunisia", "Tonga", "Timor-Leste", "Turkey", "Trinidad and Tobago", + "Tuvalu", "Taiwan", "Tanzania, United Republic of", "Ukraine", "Uganda", + "United States Minor Outlying Islands", "United States", "Uruguay", "Uzbekistan", + "Holy See (Vatican City State)", "Saint Vincent and the Grenadines", + "Venezuela", "Virgin Islands, British", "Virgin Islands, U.S.", "Vietnam", + "Vanuatu", "Wallis and Futuna", "Samoa", "Yemen", "Mayotte", "Serbia", + "South Africa", "Zambia", "Montenegro", "Zimbabwe", "Anonymous Proxy", + "Satellite Provider", "Other", "Aland Islands", "Guernsey", "Isle of Man", "Jersey", + "Saint Barthelemy", "Saint Martin", "Bonaire, Saint Eustatius and Saba", + "South Sudan", "Other"} +) + +// Constants +const ( + maxRecordLength = 4 + standardRecordLength = 3 + countryBegin = 16776960 + structureInfoMaxSize = 20 + fullRecordLength = 60 + segmentRecordLength = 3 + + // DB Types + dbCountryEdition = byte(1) + dbCityEditionRev0 = byte(6) + dbCityEditionRev1 = byte(2) +) + +// These are some structs +type GeoIP struct { + databaseSegment int // No need to make an array of size 1 + recordLength int // Set to one of the constants above + dbType byte // Store the database type + data []byte // All of the data from the DB file +} +type Location struct { + CountryCode string // If country ed. only country info is filled + CountryName string // If country ed. only country info is filled + Region string + City string + PostalCode string + Latitude float32 + Longitude float32 +} + +// Load the database file in memory, detect the db format and setup the GeoIP struct +func Load(filename string) (gi *GeoIP, err error) { + // Try to open the requested file + dbInfo, err := os.Lstat(filename) + if err != nil { + return + } + dbFile, err := os.Open(filename) + if err != nil { + return + } + + // Copy the db into memory + gi = new(GeoIP) + gi.data = make([]byte, dbInfo.Size()) + dbFile.Read(gi.data) + dbFile.Close() + + // Check the database type + gi.dbType = dbCountryEdition // Default the database to country edition + gi.databaseSegment = countryBegin // Default to country DB + gi.recordLength = standardRecordLength // Default to country DB + + // Search for the DB type headers + delim := make([]byte, 3) + for i := 0; i < structureInfoMaxSize; i++ { + delim = gi.data[len(gi.data)-i-3-1 : len(gi.data)-i-1] + if int8(delim[0]) == -1 && int8(delim[1]) == -1 && int8(delim[2]) == -1 { + gi.dbType = gi.data[len(gi.data)-i-1] + // If we detect city edition set the correct segment offset + if gi.dbType == dbCityEditionRev0 || gi.dbType == dbCityEditionRev1 { + buf := make([]byte, segmentRecordLength) + buf = gi.data[len(gi.data)-i-1+1 : len(gi.data)-i-1+4] + gi.databaseSegment = 0 + for j := 0; j < segmentRecordLength; j++ { + gi.databaseSegment += (int(buf[j]) << uint8(j*8)) + } + } + break + } + } + + // Support older formats + if gi.dbType >= 106 { + gi.dbType -= 105 + } + + // Reject unsupported formats + if gi.dbType != dbCountryEdition && gi.dbType != dbCityEditionRev0 && gi.dbType != dbCityEditionRev1 { + err = errors.New("Unsupported database format") + return + } + + return +} + +// Lookup by IP address and return location +func (gi *GeoIP) GetLocationByIP(ip string) *Location { + return gi.GetLocationByIPNum(AddrToNum(ip)) +} + +// Lookup by IP number and return location +func (gi *GeoIP) GetLocationByIPNum(ipNum uint32) *Location { + // Perform the lookup on the database to see if the record is found + offset := gi.lookupByIPNum(ipNum) + + // Check if the country was found + if gi.dbType == dbCountryEdition && offset-countryBegin == 0 || + gi.dbType != dbCountryEdition && gi.databaseSegment == offset { + return nil + } + + // Create a generic location structure + location := new(Location) + + // If the database is country + if gi.dbType == dbCountryEdition { + location.CountryCode = countryCode[offset-countryBegin] + location.CountryName = countryName[offset-countryBegin] + + return location + } + + // Find the max record length + recPointer := offset + (2*gi.recordLength-1)*gi.databaseSegment + recordEnd := recPointer + fullRecordLength + if len(gi.data)-recPointer < fullRecordLength { + recordEnd = len(gi.data) + } + + // Read the country code/name first + location.CountryCode = countryCode[gi.data[recPointer]] + location.CountryName = countryName[gi.data[recPointer]] + readLen := 1 + recPointer += 1 + + // Get the region + for readLen = 0; gi.data[recPointer+readLen] != '\000' && + recPointer+readLen < recordEnd; readLen++ { + } + if readLen != 0 { + location.Region = string(gi.data[recPointer : recPointer+readLen]) + } + recPointer += readLen + 1 + + // Get the city + for readLen = 0; gi.data[recPointer+readLen] != '\000' && + recPointer+readLen < recordEnd; readLen++ { + } + if readLen != 0 { + location.City = string(gi.data[recPointer : recPointer+readLen]) + } + recPointer += readLen + 1 + + // Get the postal code + for readLen = 0; gi.data[recPointer+readLen] != '\000' && + recPointer+readLen < recordEnd; readLen++ { + } + if readLen != 0 { + location.PostalCode = string(gi.data[recPointer : recPointer+readLen]) + } + recPointer += readLen + 1 + + // Get the latitude + coordinate := float32(0) + for j := 0; j < 3; j++ { + coordinate += float32(int32(gi.data[recPointer+j]) << uint8(j*8)) + } + location.Latitude = float32(coordinate/10000 - 180) + recPointer += 3 + + // Get the longitude + coordinate = 0 + for j := 0; j < 3; j++ { + coordinate += float32(int32(gi.data[recPointer+j]) << uint8(j*8)) + } + location.Longitude = float32(coordinate/10000 - 180) + + return location +} + +// Read the database and return record position +func (gi *GeoIP) lookupByIPNum(ip uint32) int { + buf := make([]byte, 2*maxRecordLength) + x := make([]int, 2) + offset := 0 + for depth := 31; depth >= 0; depth-- { + for i := 0; i < 2*maxRecordLength; i++ { + buf[i] = gi.data[(2*gi.recordLength*offset)+i] + } + for i := 0; i < 2; i++ { + x[i] = 0 + for j := 0; j < gi.recordLength; j++ { + var y int = int(buf[i*gi.recordLength+j]) + if y < 0 { + y += 256 + } + x[i] += (y << uint(j*8)) + } + } + if (ip & (1 << uint(depth))) > 0 { + if x[1] >= gi.databaseSegment { + return x[1] + } + offset = x[1] + } else { + if x[0] >= gi.databaseSegment { + return x[0] + } + offset = x[0] + } + } + return 0 +} + +// Convert ip address to an int representation +func AddrToNum(ip string) uint32 { + octet := uint32(0) + ipnum := uint32(0) + i := 3 + for j := 0; j < len(ip); j++ { + c := byte(ip[j]) + if c == '.' { + if octet > 255 { + return 0 + } + ipnum <<= 8 + ipnum += octet + i-- + octet = 0 + } else { + t := octet + octet <<= 3 + octet += t + octet += t + c -= '0' + if c > 9 { + return 0 + } + octet += uint32(c) + } + } + if (octet > 255) || (i != 0) { + return 0 + } + ipnum <<= 8 + return uint32(ipnum + octet) +} diff --git a/vendor/github.com/oschwald/geoip2-golang/.gitmodules b/vendor/github.com/oschwald/geoip2-golang/.gitmodules new file mode 100644 index 0000000..51779cb --- /dev/null +++ b/vendor/github.com/oschwald/geoip2-golang/.gitmodules @@ -0,0 +1,3 @@ +[submodule "test-data"] + path = test-data + url = git://github.com/maxmind/MaxMind-DB.git diff --git a/vendor/github.com/oschwald/geoip2-golang/.travis.yml b/vendor/github.com/oschwald/geoip2-golang/.travis.yml new file mode 100644 index 0000000..0d69d89 --- /dev/null +++ b/vendor/github.com/oschwald/geoip2-golang/.travis.yml @@ -0,0 +1,17 @@ +language: go + +go: + - 1.1 + - 1.2 + - 1.3 + - 1.4 + - 1.5 + - release + - tip + +install: + - go get -v ./... + # "go get" on 1.1 doesn't get test dependencies apparently. + - go get gopkg.in/check.v1 + +sudo: false diff --git a/vendor/github.com/oschwald/geoip2-golang/LICENSE b/vendor/github.com/oschwald/geoip2-golang/LICENSE new file mode 100644 index 0000000..ba53dd1 --- /dev/null +++ b/vendor/github.com/oschwald/geoip2-golang/LICENSE @@ -0,0 +1,13 @@ +Copyright (c) 2015, Gregory J. Oschwald + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THIS SOFTWARE. diff --git a/vendor/github.com/oschwald/geoip2-golang/README.md b/vendor/github.com/oschwald/geoip2-golang/README.md new file mode 100644 index 0000000..7a3c22a --- /dev/null +++ b/vendor/github.com/oschwald/geoip2-golang/README.md @@ -0,0 +1,90 @@ +# GeoIP2 Reader for Go # + +[![Build Status](https://travis-ci.org/oschwald/geoip2-golang.png?branch=master)](https://travis-ci.org/oschwald/geoip2-golang) +[![GoDoc](https://godoc.org/github.com/oschwald/geoip2-golang?status.png)](https://godoc.org/github.com/oschwald/geoip2-golang) + +This library reads MaxMind [GeoLite2](http://dev.maxmind.com/geoip/geoip2/geolite2/) +and [GeoIP2](http://www.maxmind.com/en/geolocation_landing) databases. + +This library is built using +[the Go maxminddb reader](https://github.com/oschwald/maxminddb-golang). +All data for the database record is decoded using this library. If you only +need several fields, you may get superior performance by using maxminddb's +`Lookup` directly with a result struct that only contains the required fields. +(See [example_test.go](https://github.com/oschwald/maxminddb-golang/blob/master/example_test.go) +in the maxminddb repository for an example of this.) + +## Installation ## + +``` +go get github.com/oschwald/geoip2-golang +``` + +## Usage ## + +[See GoDoc](http://godoc.org/github.com/oschwald/geoip2-golang) for +documentation and examples. + +## Example ## + +```go +package main + +import ( + "fmt" + "github.com/oschwald/geoip2-golang" + "log" + "net" +) + +func main() { + db, err := geoip2.Open("GeoIP2-City.mmdb") + if err != nil { + log.Fatal(err) + } + defer db.Close() + // If you are using strings that may be invalid, check that ip is not nil + ip := net.ParseIP("81.2.69.142") + record, err := db.City(ip) + if err != nil { + log.Fatal(err) + } + fmt.Printf("Portuguese (BR) city name: %v\n", record.City.Names["pt-BR"]) + fmt.Printf("English subdivision name: %v\n", record.Subdivisions[0].Names["en"]) + fmt.Printf("Russian country name: %v\n", record.Country.Names["ru"]) + fmt.Printf("ISO country code: %v\n", record.Country.IsoCode) + fmt.Printf("Time zone: %v\n", record.Location.TimeZone) + fmt.Printf("Coordinates: %v, %v\n", record.Location.Latitude, record.Location.Longitude) + // Output: + // Portuguese (BR) city name: Londres + // English subdivision name: England + // Russian country name: Великобритания + // ISO country code: GB + // Time zone: Europe/London + // Coordinates: 51.5142, -0.0931 +} +``` + +## Testing ## + +Make sure you checked out test data submodule: + +``` +git submodule init +git submodule update +``` + +Execute test suite: + +``` +go test +``` + +## Contributing ## + +Contributions welcome! Please fork the repository and open a pull request +with your changes. + +## License ## + +This is free software, licensed under the ISC license. diff --git a/vendor/github.com/oschwald/geoip2-golang/reader.go b/vendor/github.com/oschwald/geoip2-golang/reader.go new file mode 100644 index 0000000..45d642b --- /dev/null +++ b/vendor/github.com/oschwald/geoip2-golang/reader.go @@ -0,0 +1,202 @@ +// Package geoip2 provides a wrapper around the maxminddb package for +// easy use with the MaxMind GeoIP2 and GeoLite2 databases. The records for +// the IP address is returned from this package as well-formed structures +// that match the internal layout of data from MaxMind. +package geoip2 + +import ( + "net" + + "github.com/oschwald/maxminddb-golang" +) + +// The City structure corresponds to the data in the GeoIP2/GeoLite2 City +// databases. +type City struct { + City struct { + GeoNameID uint `maxminddb:"geoname_id"` + Names map[string]string `maxminddb:"names"` + } `maxminddb:"city"` + Continent struct { + Code string `maxminddb:"code"` + GeoNameID uint `maxminddb:"geoname_id"` + Names map[string]string `maxminddb:"names"` + } `maxminddb:"continent"` + Country struct { + GeoNameID uint `maxminddb:"geoname_id"` + IsoCode string `maxminddb:"iso_code"` + Names map[string]string `maxminddb:"names"` + } `maxminddb:"country"` + Location struct { + Latitude float64 `maxminddb:"latitude"` + Longitude float64 `maxminddb:"longitude"` + MetroCode uint `maxminddb:"metro_code"` + TimeZone string `maxminddb:"time_zone"` + } `maxminddb:"location"` + Postal struct { + Code string `maxminddb:"code"` + } `maxminddb:"postal"` + RegisteredCountry struct { + GeoNameID uint `maxminddb:"geoname_id"` + IsoCode string `maxminddb:"iso_code"` + Names map[string]string `maxminddb:"names"` + } `maxminddb:"registered_country"` + RepresentedCountry struct { + GeoNameID uint `maxminddb:"geoname_id"` + IsoCode string `maxminddb:"iso_code"` + Names map[string]string `maxminddb:"names"` + Type string `maxminddb:"type"` + } `maxminddb:"represented_country"` + Subdivisions []struct { + GeoNameID uint `maxminddb:"geoname_id"` + IsoCode string `maxminddb:"iso_code"` + Names map[string]string `maxminddb:"names"` + } `maxminddb:"subdivisions"` + Traits struct { + IsAnonymousProxy bool `maxminddb:"is_anonymous_proxy"` + IsSatelliteProvider bool `maxminddb:"is_satellite_provider"` + } `maxminddb:"traits"` +} + +// The Country structure corresponds to the data in the GeoIP2/GeoLite2 +// Country databases. +type Country struct { + Continent struct { + Code string `maxminddb:"code"` + GeoNameID uint `maxminddb:"geoname_id"` + Names map[string]string `maxminddb:"names"` + } `maxminddb:"continent"` + Country struct { + GeoNameID uint `maxminddb:"geoname_id"` + IsoCode string `maxminddb:"iso_code"` + Names map[string]string `maxminddb:"names"` + } `maxminddb:"country"` + RegisteredCountry struct { + GeoNameID uint `maxminddb:"geoname_id"` + IsoCode string `maxminddb:"iso_code"` + Names map[string]string `maxminddb:"names"` + } `maxminddb:"registered_country"` + RepresentedCountry struct { + GeoNameID uint `maxminddb:"geoname_id"` + IsoCode string `maxminddb:"iso_code"` + Names map[string]string `maxminddb:"names"` + Type string `maxminddb:"type"` + } `maxminddb:"represented_country"` + Traits struct { + IsAnonymousProxy bool `maxminddb:"is_anonymous_proxy"` + IsSatelliteProvider bool `maxminddb:"is_satellite_provider"` + } `maxminddb:"traits"` +} + +// The AnonymousIP structure corresponds to the data in the GeoIP2 +// Anonymous IP database. +type AnonymousIP struct { + IsAnonymous bool `maxminddb:"is_anonymous"` + IsAnonymousVPN bool `maxminddb:"is_anonymous_vpn"` + IsHostingProvider bool `maxminddb:"is_hosting_provider"` + IsPublicProxy bool `maxminddb:"is_public_proxy"` + IsTorExitNode bool `maxminddb:"is_tor_exit_node"` +} + +// The ConnectionType structure corresponds to the data in the GeoIP2 +// Connection-Type database. +type ConnectionType struct { + ConnectionType string `maxminddb:"connection_type"` +} + +// The Domain structure corresponds to the data in the GeoIP2 Domain database. +type Domain struct { + Domain string `maxminddb:"domain"` +} + +// The ISP structure corresponds to the data in the GeoIP2 ISP database. +type ISP struct { + AutonomousSystemNumber uint `maxminddb:"autonomous_system_number"` + AutonomousSystemOrganization string `maxminddb:"autonomous_system_organization"` + ISP string `maxminddb:"isp"` + Organization string `maxminddb:"organization"` +} + +// Reader holds the maxminddb.Reader structure. It should be created +// using the Open function. +type Reader struct { + mmdbReader *maxminddb.Reader +} + +// Open takes a string path to a file and returns a Reader structure or an +// error. The database file is opened using a memory map. Use the Close method +// on the Reader object to return the resources to the system. +func Open(file string) (*Reader, error) { + reader, err := maxminddb.Open(file) + return &Reader{mmdbReader: reader}, err +} + +// FromBytes takes a byte slice corresponding to a GeoIP2/GeoLite2 database +// file and returns a Reader structure or an error. +func FromBytes(bytes []byte) (*Reader, error) { + reader, err := maxminddb.FromBytes(bytes) + return &Reader{mmdbReader: reader}, err +} + +// City takes an IP address as a net.IP struct and returns a City struct +// and/or an error. Although this can be used with other databases, this +// method generally should be used with the GeoIP2 or GeoLite2 City databases. +func (r *Reader) City(ipAddress net.IP) (*City, error) { + var city City + err := r.mmdbReader.Lookup(ipAddress, &city) + return &city, err +} + +// Country takes an IP address as a net.IP struct and returns a Country struct +// and/or an error. Although this can be used with other databases, this +// method generally should be used with the GeoIP2 or GeoLite2 Country +// databases. +func (r *Reader) Country(ipAddress net.IP) (*Country, error) { + var country Country + err := r.mmdbReader.Lookup(ipAddress, &country) + return &country, err +} + +// AnonymousIP takes an IP address as a net.IP struct and returns a +// AnonymousIP struct and/or an error. +func (r *Reader) AnonymousIP(ipAddress net.IP) (*AnonymousIP, error) { + var anonIP AnonymousIP + err := r.mmdbReader.Lookup(ipAddress, &anonIP) + return &anonIP, err +} + +// ConnectionType takes an IP address as a net.IP struct and returns a +// ConnectionType struct and/or an error +func (r *Reader) ConnectionType(ipAddress net.IP) (*ConnectionType, error) { + var val ConnectionType + err := r.mmdbReader.Lookup(ipAddress, &val) + return &val, err +} + +// Domain takes an IP address as a net.IP struct and returns a +// Domain struct and/or an error +func (r *Reader) Domain(ipAddress net.IP) (*Domain, error) { + var val Domain + err := r.mmdbReader.Lookup(ipAddress, &val) + return &val, err +} + +// ISP takes an IP address as a net.IP struct and returns a ISP struct and/or +// an error +func (r *Reader) ISP(ipAddress net.IP) (*ISP, error) { + var val ISP + err := r.mmdbReader.Lookup(ipAddress, &val) + return &val, err +} + +// Metadata takes no arguments and returns a struct containing metadata about +// the MaxMind database in use by the Reader. +func (r *Reader) Metadata() maxminddb.Metadata { + return r.mmdbReader.Metadata +} + +// Close unmaps the database file from virtual memory and returns the +// resources to the system. +func (r *Reader) Close() error { + return r.mmdbReader.Close() +} diff --git a/vendor/github.com/oschwald/maxminddb-golang/.gitmodules b/vendor/github.com/oschwald/maxminddb-golang/.gitmodules new file mode 100644 index 0000000..51779cb --- /dev/null +++ b/vendor/github.com/oschwald/maxminddb-golang/.gitmodules @@ -0,0 +1,3 @@ +[submodule "test-data"] + path = test-data + url = git://github.com/maxmind/MaxMind-DB.git diff --git a/vendor/github.com/oschwald/maxminddb-golang/.travis.yml b/vendor/github.com/oschwald/maxminddb-golang/.travis.yml new file mode 100644 index 0000000..da06f92 --- /dev/null +++ b/vendor/github.com/oschwald/maxminddb-golang/.travis.yml @@ -0,0 +1,19 @@ +language: go + +go: + - 1.1 + - 1.2 + - 1.3 + - 1.4 + - 1.5 + - release + - tip + +install: + - go get gopkg.in/check.v1 + +script: + - go test + - go test -tags appengine + +sudo: false diff --git a/vendor/github.com/oschwald/maxminddb-golang/LICENSE b/vendor/github.com/oschwald/maxminddb-golang/LICENSE new file mode 100644 index 0000000..ba53dd1 --- /dev/null +++ b/vendor/github.com/oschwald/maxminddb-golang/LICENSE @@ -0,0 +1,13 @@ +Copyright (c) 2015, Gregory J. Oschwald + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THIS SOFTWARE. diff --git a/vendor/github.com/oschwald/maxminddb-golang/README.md b/vendor/github.com/oschwald/maxminddb-golang/README.md new file mode 100644 index 0000000..d83a276 --- /dev/null +++ b/vendor/github.com/oschwald/maxminddb-golang/README.md @@ -0,0 +1,37 @@ +# MaxMind DB Reader for Go # + +[![Build Status](https://travis-ci.org/oschwald/maxminddb-golang.png?branch=master)](https://travis-ci.org/oschwald/maxminddb-golang) +[![Windows Build Status](https://ci.appveyor.com/api/projects/status/4j2f9oep8nnfrmov/branch/master?svg=true)](https://ci.appveyor.com/project/oschwald/maxminddb-golang/branch/master) +[![GoDoc](https://godoc.org/github.com/oschwald/maxminddb-golang?status.png)](https://godoc.org/github.com/oschwald/maxminddb-golang) + + +This is a Go reader for the MaxMind DB format. This can be used to read +[GeoLite2](http://dev.maxmind.com/geoip/geoip2/geolite2/) and +[GeoIP2](http://www.maxmind.com/en/geolocation_landing) databases. + +This is not an official MaxMind API. + +## Installation ## + +``` +go get github.com/oschwald/maxminddb-golang +``` + +## Usage ## + +[See GoDoc](http://godoc.org/github.com/oschwald/maxminddb-golang) for +documentation and examples. + +## Examples ## + +See [GoDoc](http://godoc.org/github.com/oschwald/maxminddb-golang) or +`example_test.go` for examples. + +## Contributing ## + +Contributions welcome! Please fork the repository and open a pull request +with your changes. + +## License ## + +This is free software, licensed under the ISC License. diff --git a/vendor/github.com/oschwald/maxminddb-golang/appveyor.yml b/vendor/github.com/oschwald/maxminddb-golang/appveyor.yml new file mode 100644 index 0000000..e2bb9dd --- /dev/null +++ b/vendor/github.com/oschwald/maxminddb-golang/appveyor.yml @@ -0,0 +1,19 @@ +version: "{build}" + +os: Windows Server 2012 R2 + +clone_folder: c:\gopath\src\github.com\oschwald\maxminddb-golang + +environment: + GOPATH: c:\gopath + +install: + - echo %PATH% + - echo %GOPATH% + - git submodule update --init --recursive + - go version + - go env + - go get -v -t ./... + +build_script: + - go test -v ./... diff --git a/vendor/github.com/oschwald/maxminddb-golang/decoder.go b/vendor/github.com/oschwald/maxminddb-golang/decoder.go new file mode 100644 index 0000000..11a89d7 --- /dev/null +++ b/vendor/github.com/oschwald/maxminddb-golang/decoder.go @@ -0,0 +1,530 @@ +package maxminddb + +import ( + "encoding/binary" + "fmt" + "math" + "math/big" + "reflect" + "sync" +) + +type decoder struct { + buffer []byte +} + +type dataType int + +const ( + _Extended dataType = iota + _Pointer + _String + _Float64 + _Bytes + _Uint16 + _Uint32 + _Map + _Int32 + _Uint64 + _Uint128 + _Slice + _Container + _Marker + _Bool + _Float32 +) + +func (d *decoder) decode(offset uint, result reflect.Value) (uint, error) { + typeNum, size, newOffset := d.decodeCtrlData(offset) + return d.decodeFromType(typeNum, size, newOffset, result) +} + +func (d *decoder) decodeCtrlData(offset uint) (dataType, uint, uint) { + newOffset := offset + 1 + ctrlByte := d.buffer[offset] + + typeNum := dataType(ctrlByte >> 5) + if typeNum == _Extended { + typeNum = dataType(d.buffer[newOffset] + 7) + newOffset++ + } + + var size uint + size, newOffset = d.sizeFromCtrlByte(ctrlByte, newOffset, typeNum) + return typeNum, size, newOffset +} + +func (d *decoder) sizeFromCtrlByte(ctrlByte byte, offset uint, typeNum dataType) (uint, uint) { + size := uint(ctrlByte & 0x1f) + if typeNum == _Extended { + return size, offset + } + + var bytesToRead uint + if size > 28 { + bytesToRead = size - 28 + } + + newOffset := offset + bytesToRead + sizeBytes := d.buffer[offset:newOffset] + + switch { + case size == 29: + size = 29 + uint(sizeBytes[0]) + case size == 30: + size = 285 + uint(uintFromBytes(0, sizeBytes)) + case size > 30: + size = uint(uintFromBytes(0, sizeBytes)) + 65821 + } + return size, newOffset +} + +func (d *decoder) decodeFromType(dtype dataType, size uint, offset uint, result reflect.Value) (uint, error) { + if result.Kind() == reflect.Ptr { + result = reflect.Indirect(result) + } + + switch dtype { + case _Bool: + return d.unmarshalBool(size, offset, result) + case _Bytes: + return d.unmarshalBytes(size, offset, result) + case _Float32: + return d.unmarshalFloat32(size, offset, result) + case _Float64: + return d.unmarshalFloat64(size, offset, result) + case _Int32: + return d.unmarshalInt32(size, offset, result) + case _Map: + return d.unmarshalMap(size, offset, result) + case _Pointer: + return d.unmarshalPointer(size, offset, result) + case _Slice: + return d.unmarshalSlice(size, offset, result) + case _String: + return d.unmarshalString(size, offset, result) + case _Uint16: + return d.unmarshalUint(size, offset, result, 16) + case _Uint32: + return d.unmarshalUint(size, offset, result, 32) + case _Uint64: + return d.unmarshalUint(size, offset, result, 64) + case _Uint128: + return d.unmarshalUint128(size, offset, result) + default: + return 0, fmt.Errorf("unknown type: %d", dtype) + } +} + +func (d *decoder) unmarshalBool(size uint, offset uint, result reflect.Value) (uint, error) { + if size > 1 { + return 0, fmt.Errorf("the MaxMind DB file's data section contains bad data (bool size of %v)", size) + } + value, newOffset, err := d.decodeBool(size, offset) + if err != nil { + return 0, err + } + switch result.Kind() { + default: + return newOffset, fmt.Errorf("trying to unmarshal %v into %v", value, result.Type()) + case reflect.Bool: + result.SetBool(value) + return newOffset, nil + case reflect.Interface: + result.Set(reflect.ValueOf(value)) + return newOffset, nil + } +} + +func (d *decoder) unmarshalBytes(size uint, offset uint, result reflect.Value) (uint, error) { + + value, newOffset, err := d.decodeBytes(size, offset) + if err != nil { + return 0, err + } + switch result.Kind() { + default: + return newOffset, fmt.Errorf("trying to unmarshal %v into %v", value, result.Type()) + case reflect.Slice: + result.SetBytes(value) + return newOffset, nil + case reflect.Interface: + result.Set(reflect.ValueOf(value)) + return newOffset, nil + } +} + +func (d *decoder) unmarshalFloat32(size uint, offset uint, result reflect.Value) (uint, error) { + if size != 4 { + return 0, fmt.Errorf("the MaxMind DB file's data section contains bad data (float32 size of %v)", size) + } + value, newOffset, err := d.decodeFloat32(size, offset) + if err != nil { + return 0, err + } + + switch result.Kind() { + default: + return newOffset, fmt.Errorf("trying to unmarshal %v into %v", value, result.Type()) + case reflect.Float32, reflect.Float64: + result.SetFloat(float64(value)) + return newOffset, nil + case reflect.Interface: + result.Set(reflect.ValueOf(value)) + return newOffset, nil + } +} + +func (d *decoder) unmarshalFloat64(size uint, offset uint, result reflect.Value) (uint, error) { + + if size != 8 { + return 0, fmt.Errorf("the MaxMind DB file's data section contains bad data (float 64 size of %v)", size) + } + value, newOffset, err := d.decodeFloat64(size, offset) + if err != nil { + return 0, err + } + switch result.Kind() { + default: + return newOffset, fmt.Errorf("trying to unmarshal %v into %v", value, result.Type()) + case reflect.Float32, reflect.Float64: + result.SetFloat(value) + return newOffset, nil + case reflect.Interface: + result.Set(reflect.ValueOf(value)) + return newOffset, nil + } +} + +func (d *decoder) unmarshalInt32(size uint, offset uint, result reflect.Value) (uint, error) { + if size > 4 { + return 0, fmt.Errorf("the MaxMind DB file's data section contains bad data (int32 size of %v)", size) + } + value, newOffset, err := d.decodeInt(size, offset) + if err != nil { + return 0, err + } + + switch result.Kind() { + default: + return newOffset, fmt.Errorf("trying to unmarshal %v into %v", value, result.Type()) + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + result.SetInt(int64(value)) + return newOffset, nil + case reflect.Interface: + result.Set(reflect.ValueOf(value)) + return newOffset, nil + } +} + +func (d *decoder) unmarshalMap(size uint, offset uint, result reflect.Value) (uint, error) { + switch result.Kind() { + default: + return 0, fmt.Errorf("trying to unmarshal a map into %v", result.Type()) + case reflect.Struct: + return d.decodeStruct(size, offset, result) + case reflect.Map: + return d.decodeMap(size, offset, result) + case reflect.Interface: + rv := reflect.ValueOf(make(map[string]interface{}, size)) + newOffset, err := d.decodeMap(size, offset, rv) + result.Set(rv) + return newOffset, err + } +} + +func (d *decoder) unmarshalPointer(size uint, offset uint, result reflect.Value) (uint, error) { + pointer, newOffset := d.decodePointer(size, offset) + _, err := d.decode(pointer, result) + return newOffset, err +} + +func (d *decoder) unmarshalSlice(size uint, offset uint, result reflect.Value) (uint, error) { + + switch result.Kind() { + default: + return 0, fmt.Errorf("trying to unmarshal an array into %v", result.Type()) + case reflect.Slice: + return d.decodeSlice(size, offset, result) + case reflect.Interface: + a := []interface{}{} + rv := reflect.ValueOf(&a).Elem() + newOffset, err := d.decodeSlice(size, offset, rv) + result.Set(rv) + return newOffset, err + } +} + +func (d *decoder) unmarshalString(size uint, offset uint, result reflect.Value) (uint, error) { + + value, newOffset, err := d.decodeString(size, offset) + + if err != nil { + return 0, err + } + switch result.Kind() { + default: + return newOffset, fmt.Errorf("trying to unmarshal %v into %v", value, result.Type()) + case reflect.String: + result.SetString(value) + return newOffset, nil + case reflect.Interface: + result.Set(reflect.ValueOf(value)) + return newOffset, nil + } +} + +func (d *decoder) unmarshalUint(size uint, offset uint, result reflect.Value, uintType uint) (uint, error) { + if size > uintType/8 { + return 0, fmt.Errorf("the MaxMind DB file's data section contains bad data (uint%v size of %v)", uintType, size) + } + + value, newOffset, err := d.decodeUint(size, offset) + if err != nil { + return 0, err + } + + switch result.Kind() { + default: + return newOffset, fmt.Errorf("trying to unmarshal %v into %v", value, result.Type()) + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + result.SetUint(value) + return newOffset, nil + case reflect.Interface: + result.Set(reflect.ValueOf(value)) + return newOffset, nil + } +} + +func (d *decoder) unmarshalUint128(size uint, offset uint, result reflect.Value) (uint, error) { + if size > 16 { + return 0, fmt.Errorf("the MaxMind DB file's data section contains bad data (uint128 size of %v)", size) + } + value, newOffset, err := d.decodeUint128(size, offset) + if err != nil { + return 0, err + } + + // XXX - this should allow *big.Int rather than just bigInt + // Currently this is reported as invalid + switch result.Kind() { + default: + return newOffset, fmt.Errorf("trying to unmarshal %v into %v", value, result.Type()) + case reflect.Struct: + result.Set(reflect.ValueOf(*value)) + return newOffset, nil + case reflect.Interface, reflect.Ptr: + result.Set(reflect.ValueOf(value)) + return newOffset, nil + } +} + +func (d *decoder) decodeBool(size uint, offset uint) (bool, uint, error) { + return size != 0, offset, nil +} + +func (d *decoder) decodeBytes(size uint, offset uint) ([]byte, uint, error) { + newOffset := offset + size + bytes := make([]byte, size) + copy(bytes, d.buffer[offset:newOffset]) + return bytes, newOffset, nil +} + +func (d *decoder) decodeFloat64(size uint, offset uint) (float64, uint, error) { + newOffset := offset + size + bits := binary.BigEndian.Uint64(d.buffer[offset:newOffset]) + return math.Float64frombits(bits), newOffset, nil +} + +func (d *decoder) decodeFloat32(size uint, offset uint) (float32, uint, error) { + newOffset := offset + size + bits := binary.BigEndian.Uint32(d.buffer[offset:newOffset]) + return math.Float32frombits(bits), newOffset, nil +} + +func (d *decoder) decodeInt(size uint, offset uint) (int, uint, error) { + newOffset := offset + size + var val int32 + for _, b := range d.buffer[offset:newOffset] { + val = (val << 8) | int32(b) + } + return int(val), newOffset, nil +} + +func (d *decoder) decodeMap(size uint, offset uint, result reflect.Value) (uint, error) { + if result.IsNil() { + result.Set(reflect.MakeMap(result.Type())) + } + + for i := uint(0); i < size; i++ { + var key string + var err error + key, offset, err = d.decodeKeyString(offset) + + if err != nil { + return 0, err + } + + value := reflect.New(result.Type().Elem()) + offset, err = d.decode(offset, value) + if err != nil { + return 0, err + } + result.SetMapIndex(reflect.ValueOf(key), value.Elem()) + } + return offset, nil +} + +func (d *decoder) decodePointer(size uint, offset uint) (uint, uint) { + pointerSize := ((size >> 3) & 0x3) + 1 + newOffset := offset + pointerSize + pointerBytes := d.buffer[offset:newOffset] + var prefix uint64 + if pointerSize == 4 { + prefix = 0 + } else { + prefix = uint64(size & 0x7) + } + unpacked := uint(uintFromBytes(prefix, pointerBytes)) + + var pointerValueOffset uint + switch pointerSize { + case 1: + pointerValueOffset = 0 + case 2: + pointerValueOffset = 2048 + case 3: + pointerValueOffset = 526336 + case 4: + pointerValueOffset = 0 + } + + pointer := unpacked + pointerValueOffset + + return pointer, newOffset +} + +func (d *decoder) decodeSlice(size uint, offset uint, result reflect.Value) (uint, error) { + result.Set(reflect.MakeSlice(result.Type(), int(size), int(size))) + for i := 0; i < int(size); i++ { + var err error + offset, err = d.decode(offset, result.Index(i)) + if err != nil { + return 0, err + } + } + return offset, nil +} + +func (d *decoder) decodeString(size uint, offset uint) (string, uint, error) { + newOffset := offset + size + return string(d.buffer[offset:newOffset]), newOffset, nil +} + +var ( + fieldMap = map[reflect.Type]map[string]int{} + fieldMapMu sync.RWMutex +) + +func (d *decoder) decodeStruct(size uint, offset uint, result reflect.Value) (uint, error) { + resultType := result.Type() + + fieldMapMu.RLock() + fields, ok := fieldMap[resultType] + fieldMapMu.RUnlock() + if !ok { + numFields := resultType.NumField() + fields = make(map[string]int, numFields) + for i := 0; i < numFields; i++ { + fieldType := resultType.Field(i) + + fieldName := fieldType.Name + if tag := fieldType.Tag.Get("maxminddb"); tag != "" { + fieldName = tag + } + fields[fieldName] = i + } + fieldMapMu.Lock() + fieldMap[resultType] = fields + fieldMapMu.Unlock() + } + + for i := uint(0); i < size; i++ { + var ( + err error + key string + ) + key, offset, err = d.decodeStructKey(offset) + if err != nil { + return 0, err + } + i, ok := fields[key] + if !ok { + offset = d.nextValueOffset(offset, 1) + continue + } + offset, err = d.decode(offset, result.Field(i)) + if err != nil { + return 0, err + } + } + return offset, nil +} + +func (d *decoder) decodeUint(size uint, offset uint) (uint64, uint, error) { + newOffset := offset + size + val := uintFromBytes(0, d.buffer[offset:newOffset]) + + return val, newOffset, nil +} + +func (d *decoder) decodeUint128(size uint, offset uint) (*big.Int, uint, error) { + newOffset := offset + size + val := new(big.Int) + val.SetBytes(d.buffer[offset:newOffset]) + + return val, newOffset, nil +} + +func uintFromBytes(prefix uint64, uintBytes []byte) uint64 { + val := prefix + for _, b := range uintBytes { + val = (val << 8) | uint64(b) + } + return val +} + +func (d *decoder) decodeKeyString(offset uint) (string, uint, error) { + typeNum, size, newOffset := d.decodeCtrlData(offset) + if typeNum == _Pointer { + pointer, ptrOffset := d.decodePointer(size, newOffset) + key, _, err := d.decodeKeyString(pointer) + return key, ptrOffset, err + } + if typeNum != _String { + return "", 0, fmt.Errorf("unexpected type when decoding string: %v", typeNum) + } + return d.decodeString(size, newOffset) +} + +// This function is used to skip ahead to the next value without decoding +// the one at the offset passed in. The size bits have different meanings for +// different data types +func (d *decoder) nextValueOffset(offset uint, numberToSkip uint) uint { + if numberToSkip == 0 { + return offset + } + typeNum, size, offset := d.decodeCtrlData(offset) + switch typeNum { + case _Pointer: + _, offset = d.decodePointer(size, offset) + case _Map: + numberToSkip += 2 * size + case _Slice: + numberToSkip += size + case _Bool: + default: + offset += size + } + return d.nextValueOffset(offset, numberToSkip-1) +} diff --git a/vendor/github.com/oschwald/maxminddb-golang/key_appengine.go b/vendor/github.com/oschwald/maxminddb-golang/key_appengine.go new file mode 100644 index 0000000..c7dc6ef --- /dev/null +++ b/vendor/github.com/oschwald/maxminddb-golang/key_appengine.go @@ -0,0 +1,7 @@ +// +build appengine + +package maxminddb + +func (d *decoder) decodeStructKey(offset uint) (string, uint, error) { + return d.decodeKeyString(offset) +} diff --git a/vendor/github.com/oschwald/maxminddb-golang/key_other.go b/vendor/github.com/oschwald/maxminddb-golang/key_other.go new file mode 100644 index 0000000..0843d27 --- /dev/null +++ b/vendor/github.com/oschwald/maxminddb-golang/key_other.go @@ -0,0 +1,29 @@ +// +build !appengine + +package maxminddb + +import ( + "fmt" + "reflect" + "unsafe" +) + +// decodeStructKey returns a string which points into the database. Don't keep +// it around. +func (d *decoder) decodeStructKey(offset uint) (string, uint, error) { + typeNum, size, newOffset := d.decodeCtrlData(offset) + switch typeNum { + case _Pointer: + pointer, ptrOffset := d.decodePointer(size, newOffset) + s, _, err := d.decodeStructKey(pointer) + return s, ptrOffset, err + case _String: + var s string + val := (*reflect.StringHeader)(unsafe.Pointer(&s)) + val.Data = uintptr(unsafe.Pointer(&d.buffer[newOffset])) + val.Len = int(size) + return s, newOffset + size, nil + default: + return "", 0, fmt.Errorf("unexpected type when decoding structkey: %v", typeNum) + } +} diff --git a/vendor/github.com/oschwald/maxminddb-golang/mmap_unix.go b/vendor/github.com/oschwald/maxminddb-golang/mmap_unix.go new file mode 100644 index 0000000..835bc8f --- /dev/null +++ b/vendor/github.com/oschwald/maxminddb-golang/mmap_unix.go @@ -0,0 +1,15 @@ +// +build !windows,!appengine + +package maxminddb + +import ( + "syscall" +) + +func mmap(fd int, length int) (data []byte, err error) { + return syscall.Mmap(fd, 0, length, syscall.PROT_READ, syscall.MAP_SHARED) +} + +func munmap(b []byte) (err error) { + return syscall.Munmap(b) +} diff --git a/vendor/github.com/oschwald/maxminddb-golang/mmap_windows.go b/vendor/github.com/oschwald/maxminddb-golang/mmap_windows.go new file mode 100644 index 0000000..06bb998 --- /dev/null +++ b/vendor/github.com/oschwald/maxminddb-golang/mmap_windows.go @@ -0,0 +1,82 @@ +package maxminddb + +// Windows support largely borrowed from mmap-go. +// +// Copyright 2011 Evan Shaw. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +import ( + "errors" + "os" + "reflect" + "sync" + "syscall" + "unsafe" +) + +type memoryMap []byte + +// Windows +var handleLock sync.Mutex +var handleMap = map[uintptr]syscall.Handle{} + +func mmap(fd int, length int) (data []byte, err error) { + h, errno := syscall.CreateFileMapping(syscall.Handle(fd), nil, + uint32(syscall.PAGE_READONLY), 0, uint32(length), nil) + if h == 0 { + return nil, os.NewSyscallError("CreateFileMapping", errno) + } + + addr, errno := syscall.MapViewOfFile(h, uint32(syscall.FILE_MAP_READ), 0, + 0, uintptr(length)) + if addr == 0 { + return nil, os.NewSyscallError("MapViewOfFile", errno) + } + handleLock.Lock() + handleMap[addr] = h + handleLock.Unlock() + + m := memoryMap{} + dh := m.header() + dh.Data = addr + dh.Len = length + dh.Cap = dh.Len + + return m, nil +} + +func (m *memoryMap) header() *reflect.SliceHeader { + return (*reflect.SliceHeader)(unsafe.Pointer(m)) +} + +func flush(addr, len uintptr) error { + errno := syscall.FlushViewOfFile(addr, len) + return os.NewSyscallError("FlushViewOfFile", errno) +} + +func munmap(b []byte) (err error) { + m := memoryMap(b) + dh := m.header() + + addr := dh.Data + length := uintptr(dh.Len) + + flush(addr, length) + err = syscall.UnmapViewOfFile(addr) + if err != nil { + return err + } + + handleLock.Lock() + defer handleLock.Unlock() + handle, ok := handleMap[addr] + if !ok { + // should be impossible; we would've errored above + return errors.New("unknown base address") + } + delete(handleMap, addr) + + e := syscall.CloseHandle(syscall.Handle(handle)) + return os.NewSyscallError("CloseHandle", e) +} diff --git a/vendor/github.com/oschwald/maxminddb-golang/reader.go b/vendor/github.com/oschwald/maxminddb-golang/reader.go new file mode 100644 index 0000000..0bde23b --- /dev/null +++ b/vendor/github.com/oschwald/maxminddb-golang/reader.go @@ -0,0 +1,216 @@ +package maxminddb + +import ( + "bytes" + "errors" + "fmt" + "net" + "reflect" +) + +const dataSectionSeparatorSize = 16 + +var metadataStartMarker = []byte("\xAB\xCD\xEFMaxMind.com") + +// Reader holds the data corresponding to the MaxMind DB file. Its only public +// field is Metadata, which contains the metadata from the MaxMind DB file. +type Reader struct { + hasMappedFile bool + buffer []byte + decoder decoder + Metadata Metadata + ipv4Start uint +} + +// Metadata holds the metadata decoded from the MaxMind DB file. In particular +// in has the format version, the build time as Unix epoch time, the database +// type and description, the IP version supported, and a slice of the natural +// languages included. +type Metadata struct { + BinaryFormatMajorVersion uint `maxminddb:"binary_format_major_version"` + BinaryFormatMinorVersion uint `maxminddb:"binary_format_minor_version"` + BuildEpoch uint `maxminddb:"build_epoch"` + DatabaseType string `maxminddb:"database_type"` + Description map[string]string `maxminddb:"description"` + IPVersion uint `maxminddb:"ip_version"` + Languages []string `maxminddb:"languages"` + NodeCount uint `maxminddb:"node_count"` + RecordSize uint `maxminddb:"record_size"` +} + +// FromBytes takes a byte slice corresponding to a MaxMind DB file and returns +// a Reader structure or an error. +func FromBytes(buffer []byte) (*Reader, error) { + metadataStart := bytes.LastIndex(buffer, metadataStartMarker) + + if metadataStart == -1 { + return nil, fmt.Errorf("error opening database file: invalid MaxMind DB file") + } + + metadataStart += len(metadataStartMarker) + metadataDecoder := decoder{buffer[metadataStart:]} + + var metadata Metadata + + rvMetdata := reflect.ValueOf(&metadata) + _, err := metadataDecoder.decode(0, rvMetdata) + if err != nil { + return nil, err + } + + searchTreeSize := metadata.NodeCount * metadata.RecordSize / 4 + decoder := decoder{ + buffer[searchTreeSize+dataSectionSeparatorSize : metadataStart-len(metadataStartMarker)], + } + + reader := &Reader{ + buffer: buffer, + decoder: decoder, + Metadata: metadata, + ipv4Start: 0, + } + + reader.ipv4Start, err = reader.startNode() + + return reader, err +} + +func (r *Reader) startNode() (uint, error) { + if r.Metadata.IPVersion != 6 { + return 0, nil + } + + nodeCount := r.Metadata.NodeCount + + node := uint(0) + var err error + for i := 0; i < 96 && node < nodeCount; i++ { + node, err = r.readNode(node, 0) + if err != nil { + return 0, err + } + } + return node, err +} + +// Lookup takes an IP address as a net.IP structure and a pointer to the +// result value to decode into. The result value pointed to must be a data +// value that corresponds to a record in the database. This may include a +// struct representation of the data, a map capable of holding the data or an +// empty interface{} value. +// +// If result is a pointer to a struct, the struct need not include a field +// for every value that may be in the database. If a field is not present in +// the structure, the decoder will not decode that field, reducing the time +// required to decode the record. +// +// Currently the decoder expect most data types to correspond exactly (e.g., +// a uint64 database type must be decoded into a uint64 Go type). In the +// future, this may be made more flexible. +func (r *Reader) Lookup(ipAddress net.IP, result interface{}) error { + if ipAddress == nil { + return errors.New("ipAddress passed to Lookup cannot be nil") + } + + ipV4Address := ipAddress.To4() + if ipV4Address != nil { + ipAddress = ipV4Address + } + if len(ipAddress) == 16 && r.Metadata.IPVersion == 4 { + return fmt.Errorf("error looking up '%s': you attempted to look up an IPv6 address in an IPv4-only database", ipAddress.String()) + } + + pointer, err := r.findAddressInTree(ipAddress) + + if pointer == 0 { + return err + } + + return r.retrieveData(pointer, result) +} + +func (r *Reader) findAddressInTree(ipAddress net.IP) (uint, error) { + + bitCount := uint(len(ipAddress) * 8) + + var node uint + if bitCount == 32 { + node = r.ipv4Start + } + + nodeCount := r.Metadata.NodeCount + + for i := uint(0); i < bitCount && node < nodeCount; i++ { + bit := uint(1) & (uint(ipAddress[i>>3]) >> (7 - (i % 8))) + + var err error + node, err = r.readNode(node, bit) + if err != nil { + return 0, err + } + } + if node == nodeCount { + // Record is empty + return 0, nil + } else if node > nodeCount { + return node, nil + } + + return 0, errors.New("invalid node in search tree") +} + +func (r *Reader) readNode(nodeNumber uint, index uint) (uint, error) { + RecordSize := r.Metadata.RecordSize + + baseOffset := nodeNumber * RecordSize / 4 + + var nodeBytes []byte + var prefix uint64 + switch RecordSize { + case 24: + offset := baseOffset + index*3 + nodeBytes = r.buffer[offset : offset+3] + case 28: + prefix = uint64(r.buffer[baseOffset+3]) + if index != 0 { + prefix &= 0x0F + } else { + prefix = (0xF0 & prefix) >> 4 + } + offset := baseOffset + index*4 + nodeBytes = r.buffer[offset : offset+3] + case 32: + offset := baseOffset + index*4 + nodeBytes = r.buffer[offset : offset+4] + default: + return 0, fmt.Errorf("unknown record size: %d", RecordSize) + } + return uint(uintFromBytes(prefix, nodeBytes)), nil +} + +func (r *Reader) retrieveData(pointer uint, result interface{}) error { + rv := reflect.ValueOf(result) + if rv.Kind() != reflect.Ptr || rv.IsNil() { + return errors.New("result param must be a pointer") + } + + offset, err := r.resolveDataPointer(pointer) + if err != nil { + return err + } + + _, err = r.decoder.decode(offset, rv) + return err +} + +func (r *Reader) resolveDataPointer(pointer uint) (uint, error) { + nodeCount := r.Metadata.NodeCount + + resolved := pointer - nodeCount - dataSectionSeparatorSize + + if resolved > uint(len(r.buffer)) { + return 0, errors.New("the MaxMind DB file's search tree is corrupt") + } + + return resolved, nil +} diff --git a/vendor/github.com/oschwald/maxminddb-golang/reader_appengine.go b/vendor/github.com/oschwald/maxminddb-golang/reader_appengine.go new file mode 100644 index 0000000..631e195 --- /dev/null +++ b/vendor/github.com/oschwald/maxminddb-golang/reader_appengine.go @@ -0,0 +1,26 @@ +// +build appengine + +package maxminddb + +import "io/ioutil" + +// Open takes a string path to a MaxMind DB file and returns a Reader +// structure or an error. The database file is opened using a memory map, +// except on Google App Engine where mmap is not supported; there the database +// is loaded into memory. Use the Close method on the Reader object to return +// the resources to the system. +func Open(file string) (*Reader, error) { + bytes, err := ioutil.ReadFile(file) + if err != nil { + return nil, err + } + + return FromBytes(bytes) +} + +// Close unmaps the database file from virtual memory and returns the +// resources to the system. If called on a Reader opened using FromBytes +// or Open on Google App Engine, this method does nothing. +func (r *Reader) Close() error { + return nil +} diff --git a/vendor/github.com/oschwald/maxminddb-golang/reader_other.go b/vendor/github.com/oschwald/maxminddb-golang/reader_other.go new file mode 100644 index 0000000..0ef5df3 --- /dev/null +++ b/vendor/github.com/oschwald/maxminddb-golang/reader_other.go @@ -0,0 +1,56 @@ +// +build !appengine + +package maxminddb + +import "os" + +// Open takes a string path to a MaxMind DB file and returns a Reader +// structure or an error. The database file is opened using a memory map, +// except on Google App Engine where mmap is not supported; there the database +// is loaded into memory. Use the Close method on the Reader object to return +// the resources to the system. +func Open(file string) (*Reader, error) { + mapFile, err := os.Open(file) + if err != nil { + return nil, err + } + defer func() { + if rerr := mapFile.Close(); rerr != nil { + err = rerr + } + }() + + stats, err := mapFile.Stat() + if err != nil { + return nil, err + } + + fileSize := int(stats.Size()) + mmap, err := mmap(int(mapFile.Fd()), fileSize) + if err != nil { + return nil, err + } + + reader, err := FromBytes(mmap) + if err != nil { + if err2 := munmap(mmap); err2 != nil { + // failing to unmap the file is probably the more severe error + return nil, err2 + } + return nil, err + } + + reader.hasMappedFile = true + return reader, err +} + +// Close unmaps the database file from virtual memory and returns the +// resources to the system. If called on a Reader opened using FromBytes +// or Open on Google App Engine, this method does nothing. +func (r *Reader) Close() (err error) { + if r.hasMappedFile { + err = munmap(r.buffer) + r.hasMappedFile = false + } + return err +} diff --git a/vendor/github.com/oschwald/maxminddb-golang/traverse.go b/vendor/github.com/oschwald/maxminddb-golang/traverse.go new file mode 100644 index 0000000..913f1a1 --- /dev/null +++ b/vendor/github.com/oschwald/maxminddb-golang/traverse.go @@ -0,0 +1,111 @@ +package maxminddb + +import ( + "fmt" + "net" +) + +// Internal structure used to keep track of nodes we still need to visit. +type netNode struct { + ip net.IP + bit uint + pointer uint +} + +// Networks represents a set of subnets that we are iterating over. +type Networks struct { + reader *Reader + nodes []netNode // Nodes we still have to visit. + lastNode netNode + err error +} + +// Networks returns an iterator that can be used to traverse all networks in +// the database. +// +// Please note that a MaxMind DB may map IPv4 networks into several locations +// in in an IPv6 database. This iterator will iterate over all of these +// locations separately. +func (r *Reader) Networks() *Networks { + s := 4 + if r.Metadata.IPVersion == 6 { + s = 16 + } + return &Networks{ + reader: r, + nodes: []netNode{ + netNode{ + ip: make(net.IP, s), + }, + }, + } +} + +// Next prepares the next network for reading with the Network method. It +// returns true if there is another network to be processed and false if there +// are no more networks or if there is an error. +func (n *Networks) Next() bool { + for len(n.nodes) > 0 { + node := n.nodes[len(n.nodes)-1] + n.nodes = n.nodes[:len(n.nodes)-1] + + for { + if node.pointer < n.reader.Metadata.NodeCount { + ipRight := make(net.IP, len(node.ip)) + copy(ipRight, node.ip) + if len(ipRight) <= int(node.bit>>3) { + n.err = fmt.Errorf( + "invalid search tree at %v/%v", ipRight, node.bit) + return false + } + ipRight[node.bit>>3] |= 1 << uint(7-(node.bit%8)) + + rightPointer, err := n.reader.readNode(node.pointer, 1) + if err != nil { + n.err = err + return false + } + + node.bit++ + n.nodes = append(n.nodes, netNode{ + pointer: rightPointer, + ip: ipRight, + bit: node.bit, + }) + + node.pointer, err = n.reader.readNode(node.pointer, 0) + if err != nil { + n.err = err + return false + } + + } else if node.pointer > n.reader.Metadata.NodeCount { + n.lastNode = node + return true + } else { + break + } + } + } + + return false +} + +// Network returns the current network or an error if there is a problem +// decoding the data for the network. It takes a pointer to a result value to +// decode the network's data into. +func (n *Networks) Network(result interface{}) (*net.IPNet, error) { + if err := n.reader.retrieveData(n.lastNode.pointer, result); err != nil { + return nil, err + } + + return &net.IPNet{ + IP: n.lastNode.ip, + Mask: net.CIDRMask(int(n.lastNode.bit), len(n.lastNode.ip)*8), + }, nil +} + +// Err returns an error, if any, that was encountered during iteration. +func (n *Networks) Err() error { + return n.err +} diff --git a/vendor/github.com/oschwald/maxminddb-golang/verifier.go b/vendor/github.com/oschwald/maxminddb-golang/verifier.go new file mode 100644 index 0000000..c719859 --- /dev/null +++ b/vendor/github.com/oschwald/maxminddb-golang/verifier.go @@ -0,0 +1,188 @@ +package maxminddb + +import ( + "fmt" + "reflect" +) + +type verifier struct { + reader *Reader +} + +// Verify checks that the database is valid. It validates the search tree, +// the data section, and the metadata section. This verifier is stricter than +// the specification and may return errors on databases that are readable. +func (r *Reader) Verify() error { + v := verifier{r} + if err := v.verifyMetadata(); err != nil { + return err + } + + return v.verifyDatabase() +} + +func (v *verifier) verifyMetadata() error { + metadata := v.reader.Metadata + + if metadata.BinaryFormatMajorVersion != 2 { + return testError( + "binary_format_major_version", + 2, + metadata.BinaryFormatMajorVersion, + ) + } + + if metadata.BinaryFormatMinorVersion != 0 { + return testError( + "binary_format_minor_version", + 0, + metadata.BinaryFormatMinorVersion, + ) + } + + if metadata.DatabaseType == "" { + return testError( + "database_type", + "non-empty string", + metadata.DatabaseType, + ) + } + + if len(metadata.Description) == 0 { + return testError( + "description", + "non-empty slice", + metadata.Description, + ) + } + + if metadata.IPVersion != 4 && metadata.IPVersion != 6 { + return testError( + "ip_version", + "4 or 6", + metadata.IPVersion, + ) + } + + if metadata.RecordSize != 24 && + metadata.RecordSize != 28 && + metadata.RecordSize != 32 { + return testError( + "record_size", + "24, 28, or 32", + metadata.RecordSize, + ) + } + + if metadata.NodeCount == 0 { + return testError( + "node_count", + "positive integer", + metadata.NodeCount, + ) + } + return nil +} + +func (v *verifier) verifyDatabase() error { + offsets, err := v.verifySearchTree() + if err != nil { + return err + } + + if err := v.verifyDataSectionSeparator(); err != nil { + return err + } + + return v.verifyDataSection(offsets) +} + +func (v *verifier) verifySearchTree() (map[uint]bool, error) { + offsets := make(map[uint]bool) + + it := v.reader.Networks() + for it.Next() { + offset, err := v.reader.resolveDataPointer(it.lastNode.pointer) + if err != nil { + return nil, err + } + offsets[offset] = true + } + if err := it.Err(); err != nil { + return nil, err + } + return offsets, nil +} + +func (v *verifier) verifyDataSectionSeparator() error { + separatorStart := v.reader.Metadata.NodeCount * v.reader.Metadata.RecordSize / 4 + + separator := v.reader.buffer[separatorStart : separatorStart+dataSectionSeparatorSize] + + for _, b := range separator { + if b != 0 { + return fmt.Errorf("unexpected byte in data separator: %v", separator) + } + } + return nil +} + +func (v *verifier) verifyDataSection(offsets map[uint]bool) error { + pointerCount := len(offsets) + + decoder := v.reader.decoder + + var offset uint + bufferLen := uint(len(decoder.buffer)) + for offset < bufferLen { + var data interface{} + rv := reflect.ValueOf(&data) + newOffset, err := decoder.decode(offset, rv) + if err != nil { + return fmt.Errorf("received decoding error (%v) at offset of %v", err, offset) + } + if newOffset <= offset { + return fmt.Errorf("data section offset unexpectedly went from %v to %v", offset, newOffset) + } + + pointer := offset + + if _, ok := offsets[pointer]; ok { + delete(offsets, pointer) + } else { + return fmt.Errorf("found data (%v) at %v that the search tree does not point to", data, pointer) + } + + offset = newOffset + } + + if offset != bufferLen { + return fmt.Errorf( + "unexpected data at the end of the data section (last offset: %v, end: %v)", + offset, + bufferLen, + ) + } + + if len(offsets) != 0 { + return fmt.Errorf( + "found %v pointers (of %v) in the search tree that we did not see in the data section", + len(offsets), + pointerCount, + ) + } + return nil +} + +func testError( + field string, + expected interface{}, + actual interface{}, +) error { + return fmt.Errorf( + "%v - Expected: %v Actual: %v", + field, + expected, + actual, + ) +} diff --git a/vendor/github.com/satori/go.uuid/.travis.yml b/vendor/github.com/satori/go.uuid/.travis.yml new file mode 100644 index 0000000..5e21746 --- /dev/null +++ b/vendor/github.com/satori/go.uuid/.travis.yml @@ -0,0 +1,12 @@ +language: go +go: + - 1.0 + - 1.1 + - 1.2 + - 1.3 + - 1.4 + - 1.5 + - 1.6 +sudo: false +notifications: + email: false diff --git a/vendor/github.com/satori/go.uuid/LICENSE b/vendor/github.com/satori/go.uuid/LICENSE new file mode 100644 index 0000000..488357b --- /dev/null +++ b/vendor/github.com/satori/go.uuid/LICENSE @@ -0,0 +1,20 @@ +Copyright (C) 2013-2016 by Maxim Bublis + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/github.com/satori/go.uuid/README.md b/vendor/github.com/satori/go.uuid/README.md new file mode 100644 index 0000000..b6b626b --- /dev/null +++ b/vendor/github.com/satori/go.uuid/README.md @@ -0,0 +1,64 @@ +# UUID package for Go language + +[![Build Status](https://travis-ci.org/satori/go.uuid.png?branch=master)](https://travis-ci.org/satori/go.uuid) +[![GoDoc](http://godoc.org/github.com/satori/go.uuid?status.png)](http://godoc.org/github.com/satori/go.uuid) + +This package provides pure Go implementation of Universally Unique Identifier (UUID). Supported both creation and parsing of UUIDs. + +With 100% test coverage and benchmarks out of box. + +Supported versions: +* Version 1, based on timestamp and MAC address (RFC 4122) +* Version 2, based on timestamp, MAC address and POSIX UID/GID (DCE 1.1) +* Version 3, based on MD5 hashing (RFC 4122) +* Version 4, based on random numbers (RFC 4122) +* Version 5, based on SHA-1 hashing (RFC 4122) + +## Installation + +Use the `go` command: + + $ go get github.com/satori/go.uuid + +## Requirements + +UUID package requires any stable version of Go Programming Language. + +## Example + +```go +package main + +import ( + "fmt" + "github.com/satori/go.uuid" +) + +func main() { + // Creating UUID Version 4 + u1 := uuid.NewV4() + fmt.Printf("UUIDv4: %s\n", u1) + + // Parsing UUID from string input + u2, err := uuid.FromString("6ba7b810-9dad-11d1-80b4-00c04fd430c8") + if err != nil { + fmt.Printf("Something gone wrong: %s", err) + } + fmt.Printf("Successfully parsed: %s", u2) +} +``` + +## Documentation + +[Documentation](http://godoc.org/github.com/satori/go.uuid) is hosted at GoDoc project. + +## Links +* [RFC 4122](http://tools.ietf.org/html/rfc4122) +* [DCE 1.1: Authentication and Security Services](http://pubs.opengroup.org/onlinepubs/9696989899/chap5.htm#tagcjh_08_02_01_01) + +## Copyright + +Copyright (C) 2013-2016 by Maxim Bublis . + +UUID package released under MIT License. +See [LICENSE](https://github.com/satori/go.uuid/blob/master/LICENSE) for details. diff --git a/vendor/github.com/satori/go.uuid/uuid.go b/vendor/github.com/satori/go.uuid/uuid.go new file mode 100644 index 0000000..03841d8 --- /dev/null +++ b/vendor/github.com/satori/go.uuid/uuid.go @@ -0,0 +1,435 @@ +// Copyright (C) 2013-2015 by Maxim Bublis +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +// Package uuid provides implementation of Universally Unique Identifier (UUID). +// Supported versions are 1, 3, 4 and 5 (as specified in RFC 4122) and +// version 2 (as specified in DCE 1.1). +package uuid + +import ( + "bytes" + "crypto/md5" + "crypto/rand" + "crypto/sha1" + "database/sql/driver" + "encoding/binary" + "encoding/hex" + "fmt" + "hash" + "net" + "os" + "sync" + "time" +) + +// UUID layout variants. +const ( + VariantNCS = iota + VariantRFC4122 + VariantMicrosoft + VariantFuture +) + +// UUID DCE domains. +const ( + DomainPerson = iota + DomainGroup + DomainOrg +) + +// Difference in 100-nanosecond intervals between +// UUID epoch (October 15, 1582) and Unix epoch (January 1, 1970). +const epochStart = 122192928000000000 + +// Used in string method conversion +const dash byte = '-' + +// UUID v1/v2 storage. +var ( + storageMutex sync.Mutex + storageOnce sync.Once + epochFunc = unixTimeFunc + clockSequence uint16 + lastTime uint64 + hardwareAddr [6]byte + posixUID = uint32(os.Getuid()) + posixGID = uint32(os.Getgid()) +) + +// String parse helpers. +var ( + urnPrefix = []byte("urn:uuid:") + byteGroups = []int{8, 4, 4, 4, 12} +) + +func initClockSequence() { + buf := make([]byte, 2) + safeRandom(buf) + clockSequence = binary.BigEndian.Uint16(buf) +} + +func initHardwareAddr() { + interfaces, err := net.Interfaces() + if err == nil { + for _, iface := range interfaces { + if len(iface.HardwareAddr) >= 6 { + copy(hardwareAddr[:], iface.HardwareAddr) + return + } + } + } + + // Initialize hardwareAddr randomly in case + // of real network interfaces absence + safeRandom(hardwareAddr[:]) + + // Set multicast bit as recommended in RFC 4122 + hardwareAddr[0] |= 0x01 +} + +func initStorage() { + initClockSequence() + initHardwareAddr() +} + +func safeRandom(dest []byte) { + if _, err := rand.Read(dest); err != nil { + panic(err) + } +} + +// Returns difference in 100-nanosecond intervals between +// UUID epoch (October 15, 1582) and current time. +// This is default epoch calculation function. +func unixTimeFunc() uint64 { + return epochStart + uint64(time.Now().UnixNano()/100) +} + +// UUID representation compliant with specification +// described in RFC 4122. +type UUID [16]byte + +// The nil UUID is special form of UUID that is specified to have all +// 128 bits set to zero. +var Nil = UUID{} + +// Predefined namespace UUIDs. +var ( + NamespaceDNS, _ = FromString("6ba7b810-9dad-11d1-80b4-00c04fd430c8") + NamespaceURL, _ = FromString("6ba7b811-9dad-11d1-80b4-00c04fd430c8") + NamespaceOID, _ = FromString("6ba7b812-9dad-11d1-80b4-00c04fd430c8") + NamespaceX500, _ = FromString("6ba7b814-9dad-11d1-80b4-00c04fd430c8") +) + +// And returns result of binary AND of two UUIDs. +func And(u1 UUID, u2 UUID) UUID { + u := UUID{} + for i := 0; i < 16; i++ { + u[i] = u1[i] & u2[i] + } + return u +} + +// Or returns result of binary OR of two UUIDs. +func Or(u1 UUID, u2 UUID) UUID { + u := UUID{} + for i := 0; i < 16; i++ { + u[i] = u1[i] | u2[i] + } + return u +} + +// Equal returns true if u1 and u2 equals, otherwise returns false. +func Equal(u1 UUID, u2 UUID) bool { + return bytes.Equal(u1[:], u2[:]) +} + +// Version returns algorithm version used to generate UUID. +func (u UUID) Version() uint { + return uint(u[6] >> 4) +} + +// Variant returns UUID layout variant. +func (u UUID) Variant() uint { + switch { + case (u[8] & 0x80) == 0x00: + return VariantNCS + case (u[8]&0xc0)|0x80 == 0x80: + return VariantRFC4122 + case (u[8]&0xe0)|0xc0 == 0xc0: + return VariantMicrosoft + } + return VariantFuture +} + +// Bytes returns bytes slice representation of UUID. +func (u UUID) Bytes() []byte { + return u[:] +} + +// Returns canonical string representation of UUID: +// xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx. +func (u UUID) String() string { + buf := make([]byte, 36) + + hex.Encode(buf[0:8], u[0:4]) + buf[8] = dash + hex.Encode(buf[9:13], u[4:6]) + buf[13] = dash + hex.Encode(buf[14:18], u[6:8]) + buf[18] = dash + hex.Encode(buf[19:23], u[8:10]) + buf[23] = dash + hex.Encode(buf[24:], u[10:]) + + return string(buf) +} + +// SetVersion sets version bits. +func (u *UUID) SetVersion(v byte) { + u[6] = (u[6] & 0x0f) | (v << 4) +} + +// SetVariant sets variant bits as described in RFC 4122. +func (u *UUID) SetVariant() { + u[8] = (u[8] & 0xbf) | 0x80 +} + +// MarshalText implements the encoding.TextMarshaler interface. +// The encoding is the same as returned by String. +func (u UUID) MarshalText() (text []byte, err error) { + text = []byte(u.String()) + return +} + +// UnmarshalText implements the encoding.TextUnmarshaler interface. +// Following formats are supported: +// "6ba7b810-9dad-11d1-80b4-00c04fd430c8", +// "{6ba7b810-9dad-11d1-80b4-00c04fd430c8}", +// "urn:uuid:6ba7b810-9dad-11d1-80b4-00c04fd430c8" +func (u *UUID) UnmarshalText(text []byte) (err error) { + if len(text) < 32 { + err = fmt.Errorf("uuid: invalid UUID string: %s", text) + return + } + + if bytes.Equal(text[:9], urnPrefix) { + text = text[9:] + } else if text[0] == '{' { + text = text[1:] + } + + b := u[:] + + for _, byteGroup := range byteGroups { + if text[0] == '-' { + text = text[1:] + } + + _, err = hex.Decode(b[:byteGroup/2], text[:byteGroup]) + + if err != nil { + return + } + + text = text[byteGroup:] + b = b[byteGroup/2:] + } + + return +} + +// MarshalBinary implements the encoding.BinaryMarshaler interface. +func (u UUID) MarshalBinary() (data []byte, err error) { + data = u.Bytes() + return +} + +// UnmarshalBinary implements the encoding.BinaryUnmarshaler interface. +// It will return error if the slice isn't 16 bytes long. +func (u *UUID) UnmarshalBinary(data []byte) (err error) { + if len(data) != 16 { + err = fmt.Errorf("uuid: UUID must be exactly 16 bytes long, got %d bytes", len(data)) + return + } + copy(u[:], data) + + return +} + +// Value implements the driver.Valuer interface. +func (u UUID) Value() (driver.Value, error) { + return u.String(), nil +} + +// Scan implements the sql.Scanner interface. +// A 16-byte slice is handled by UnmarshalBinary, while +// a longer byte slice or a string is handled by UnmarshalText. +func (u *UUID) Scan(src interface{}) error { + switch src := src.(type) { + case []byte: + if len(src) == 16 { + return u.UnmarshalBinary(src) + } + return u.UnmarshalText(src) + + case string: + return u.UnmarshalText([]byte(src)) + } + + return fmt.Errorf("uuid: cannot convert %T to UUID", src) +} + +// FromBytes returns UUID converted from raw byte slice input. +// It will return error if the slice isn't 16 bytes long. +func FromBytes(input []byte) (u UUID, err error) { + err = u.UnmarshalBinary(input) + return +} + +// FromBytesOrNil returns UUID converted from raw byte slice input. +// Same behavior as FromBytes, but returns a Nil UUID on error. +func FromBytesOrNil(input []byte) UUID { + uuid, err := FromBytes(input) + if err != nil { + return Nil + } + return uuid +} + +// FromString returns UUID parsed from string input. +// Input is expected in a form accepted by UnmarshalText. +func FromString(input string) (u UUID, err error) { + err = u.UnmarshalText([]byte(input)) + return +} + +// FromStringOrNil returns UUID parsed from string input. +// Same behavior as FromString, but returns a Nil UUID on error. +func FromStringOrNil(input string) UUID { + uuid, err := FromString(input) + if err != nil { + return Nil + } + return uuid +} + +// Returns UUID v1/v2 storage state. +// Returns epoch timestamp, clock sequence, and hardware address. +func getStorage() (uint64, uint16, []byte) { + storageOnce.Do(initStorage) + + storageMutex.Lock() + defer storageMutex.Unlock() + + timeNow := epochFunc() + // Clock changed backwards since last UUID generation. + // Should increase clock sequence. + if timeNow <= lastTime { + clockSequence++ + } + lastTime = timeNow + + return timeNow, clockSequence, hardwareAddr[:] +} + +// NewV1 returns UUID based on current timestamp and MAC address. +func NewV1() UUID { + u := UUID{} + + timeNow, clockSeq, hardwareAddr := getStorage() + + binary.BigEndian.PutUint32(u[0:], uint32(timeNow)) + binary.BigEndian.PutUint16(u[4:], uint16(timeNow>>32)) + binary.BigEndian.PutUint16(u[6:], uint16(timeNow>>48)) + binary.BigEndian.PutUint16(u[8:], clockSeq) + + copy(u[10:], hardwareAddr) + + u.SetVersion(1) + u.SetVariant() + + return u +} + +// NewV2 returns DCE Security UUID based on POSIX UID/GID. +func NewV2(domain byte) UUID { + u := UUID{} + + timeNow, clockSeq, hardwareAddr := getStorage() + + switch domain { + case DomainPerson: + binary.BigEndian.PutUint32(u[0:], posixUID) + case DomainGroup: + binary.BigEndian.PutUint32(u[0:], posixGID) + } + + binary.BigEndian.PutUint16(u[4:], uint16(timeNow>>32)) + binary.BigEndian.PutUint16(u[6:], uint16(timeNow>>48)) + binary.BigEndian.PutUint16(u[8:], clockSeq) + u[9] = domain + + copy(u[10:], hardwareAddr) + + u.SetVersion(2) + u.SetVariant() + + return u +} + +// NewV3 returns UUID based on MD5 hash of namespace UUID and name. +func NewV3(ns UUID, name string) UUID { + u := newFromHash(md5.New(), ns, name) + u.SetVersion(3) + u.SetVariant() + + return u +} + +// NewV4 returns random generated UUID. +func NewV4() UUID { + u := UUID{} + safeRandom(u[:]) + u.SetVersion(4) + u.SetVariant() + + return u +} + +// NewV5 returns UUID based on SHA-1 hash of namespace UUID and name. +func NewV5(ns UUID, name string) UUID { + u := newFromHash(sha1.New(), ns, name) + u.SetVersion(5) + u.SetVariant() + + return u +} + +// Returns UUID based on hashing of namespace UUID and name. +func newFromHash(h hash.Hash, ns UUID, name string) UUID { + u := UUID{} + h.Write(ns[:]) + h.Write([]byte(name)) + copy(u[:], h.Sum(nil)) + + return u +} diff --git a/vendor/gopkg.in/yaml.v2/LICENSE b/vendor/gopkg.in/yaml.v2/LICENSE new file mode 100644 index 0000000..a68e67f --- /dev/null +++ b/vendor/gopkg.in/yaml.v2/LICENSE @@ -0,0 +1,188 @@ + +Copyright (c) 2011-2014 - Canonical Inc. + +This software is licensed under the LGPLv3, included below. + +As a special exception to the GNU Lesser General Public License version 3 +("LGPL3"), the copyright holders of this Library give you permission to +convey to a third party a Combined Work that links statically or dynamically +to this Library without providing any Minimal Corresponding Source or +Minimal Application Code as set out in 4d or providing the installation +information set out in section 4e, provided that you comply with the other +provisions of LGPL3 and provided that you meet, for the Application the +terms and conditions of the license(s) which apply to the Application. + +Except as stated in this special exception, the provisions of LGPL3 will +continue to comply in full to this Library. If you modify this Library, you +may apply this exception to your version of this Library, but you are not +obliged to do so. If you do not wish to do so, delete this exception +statement from your version. This exception does not (and cannot) modify any +license terms which apply to the Application, with which you must still +comply. + + + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. diff --git a/vendor/gopkg.in/yaml.v2/LICENSE.libyaml b/vendor/gopkg.in/yaml.v2/LICENSE.libyaml new file mode 100644 index 0000000..8da58fb --- /dev/null +++ b/vendor/gopkg.in/yaml.v2/LICENSE.libyaml @@ -0,0 +1,31 @@ +The following files were ported to Go from C files of libyaml, and thus +are still covered by their original copyright and license: + + apic.go + emitterc.go + parserc.go + readerc.go + scannerc.go + writerc.go + yamlh.go + yamlprivateh.go + +Copyright (c) 2006 Kirill Simonov + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/gopkg.in/yaml.v2/README.md b/vendor/gopkg.in/yaml.v2/README.md new file mode 100644 index 0000000..d6c919e --- /dev/null +++ b/vendor/gopkg.in/yaml.v2/README.md @@ -0,0 +1,128 @@ +# YAML support for the Go language + +Introduction +------------ + +The yaml package enables Go programs to comfortably encode and decode YAML +values. It was developed within [Canonical](https://www.canonical.com) as +part of the [juju](https://juju.ubuntu.com) project, and is based on a +pure Go port of the well-known [libyaml](http://pyyaml.org/wiki/LibYAML) +C library to parse and generate YAML data quickly and reliably. + +Compatibility +------------- + +The yaml package supports most of YAML 1.1 and 1.2, including support for +anchors, tags, map merging, etc. Multi-document unmarshalling is not yet +implemented, and base-60 floats from YAML 1.1 are purposefully not +supported since they're a poor design and are gone in YAML 1.2. + +Installation and usage +---------------------- + +The import path for the package is *gopkg.in/yaml.v2*. + +To install it, run: + + go get gopkg.in/yaml.v2 + +API documentation +----------------- + +If opened in a browser, the import path itself leads to the API documentation: + + * [https://gopkg.in/yaml.v2](https://gopkg.in/yaml.v2) + +API stability +------------- + +The package API for yaml v2 will remain stable as described in [gopkg.in](https://gopkg.in). + + +License +------- + +The yaml package is licensed under the LGPL with an exception that allows it to be linked statically. Please see the LICENSE file for details. + + +Example +------- + +```Go +package main + +import ( + "fmt" + "log" + + "gopkg.in/yaml.v2" +) + +var data = ` +a: Easy! +b: + c: 2 + d: [3, 4] +` + +type T struct { + A string + B struct{C int; D []int ",flow"} +} + +func main() { + t := T{} + + err := yaml.Unmarshal([]byte(data), &t) + if err != nil { + log.Fatalf("error: %v", err) + } + fmt.Printf("--- t:\n%v\n\n", t) + + d, err := yaml.Marshal(&t) + if err != nil { + log.Fatalf("error: %v", err) + } + fmt.Printf("--- t dump:\n%s\n\n", string(d)) + + m := make(map[interface{}]interface{}) + + err = yaml.Unmarshal([]byte(data), &m) + if err != nil { + log.Fatalf("error: %v", err) + } + fmt.Printf("--- m:\n%v\n\n", m) + + d, err = yaml.Marshal(&m) + if err != nil { + log.Fatalf("error: %v", err) + } + fmt.Printf("--- m dump:\n%s\n\n", string(d)) +} +``` + +This example will generate the following output: + +``` +--- t: +{Easy! {2 [3 4]}} + +--- t dump: +a: Easy! +b: + c: 2 + d: [3, 4] + + +--- m: +map[a:Easy! b:map[c:2 d:[3 4]]] + +--- m dump: +a: Easy! +b: + c: 2 + d: + - 3 + - 4 +``` + diff --git a/vendor/gopkg.in/yaml.v2/apic.go b/vendor/gopkg.in/yaml.v2/apic.go new file mode 100644 index 0000000..95ec014 --- /dev/null +++ b/vendor/gopkg.in/yaml.v2/apic.go @@ -0,0 +1,742 @@ +package yaml + +import ( + "io" + "os" +) + +func yaml_insert_token(parser *yaml_parser_t, pos int, token *yaml_token_t) { + //fmt.Println("yaml_insert_token", "pos:", pos, "typ:", token.typ, "head:", parser.tokens_head, "len:", len(parser.tokens)) + + // Check if we can move the queue at the beginning of the buffer. + if parser.tokens_head > 0 && len(parser.tokens) == cap(parser.tokens) { + if parser.tokens_head != len(parser.tokens) { + copy(parser.tokens, parser.tokens[parser.tokens_head:]) + } + parser.tokens = parser.tokens[:len(parser.tokens)-parser.tokens_head] + parser.tokens_head = 0 + } + parser.tokens = append(parser.tokens, *token) + if pos < 0 { + return + } + copy(parser.tokens[parser.tokens_head+pos+1:], parser.tokens[parser.tokens_head+pos:]) + parser.tokens[parser.tokens_head+pos] = *token +} + +// Create a new parser object. +func yaml_parser_initialize(parser *yaml_parser_t) bool { + *parser = yaml_parser_t{ + raw_buffer: make([]byte, 0, input_raw_buffer_size), + buffer: make([]byte, 0, input_buffer_size), + } + return true +} + +// Destroy a parser object. +func yaml_parser_delete(parser *yaml_parser_t) { + *parser = yaml_parser_t{} +} + +// String read handler. +func yaml_string_read_handler(parser *yaml_parser_t, buffer []byte) (n int, err error) { + if parser.input_pos == len(parser.input) { + return 0, io.EOF + } + n = copy(buffer, parser.input[parser.input_pos:]) + parser.input_pos += n + return n, nil +} + +// File read handler. +func yaml_file_read_handler(parser *yaml_parser_t, buffer []byte) (n int, err error) { + return parser.input_file.Read(buffer) +} + +// Set a string input. +func yaml_parser_set_input_string(parser *yaml_parser_t, input []byte) { + if parser.read_handler != nil { + panic("must set the input source only once") + } + parser.read_handler = yaml_string_read_handler + parser.input = input + parser.input_pos = 0 +} + +// Set a file input. +func yaml_parser_set_input_file(parser *yaml_parser_t, file *os.File) { + if parser.read_handler != nil { + panic("must set the input source only once") + } + parser.read_handler = yaml_file_read_handler + parser.input_file = file +} + +// Set the source encoding. +func yaml_parser_set_encoding(parser *yaml_parser_t, encoding yaml_encoding_t) { + if parser.encoding != yaml_ANY_ENCODING { + panic("must set the encoding only once") + } + parser.encoding = encoding +} + +// Create a new emitter object. +func yaml_emitter_initialize(emitter *yaml_emitter_t) bool { + *emitter = yaml_emitter_t{ + buffer: make([]byte, output_buffer_size), + raw_buffer: make([]byte, 0, output_raw_buffer_size), + states: make([]yaml_emitter_state_t, 0, initial_stack_size), + events: make([]yaml_event_t, 0, initial_queue_size), + } + return true +} + +// Destroy an emitter object. +func yaml_emitter_delete(emitter *yaml_emitter_t) { + *emitter = yaml_emitter_t{} +} + +// String write handler. +func yaml_string_write_handler(emitter *yaml_emitter_t, buffer []byte) error { + *emitter.output_buffer = append(*emitter.output_buffer, buffer...) + return nil +} + +// File write handler. +func yaml_file_write_handler(emitter *yaml_emitter_t, buffer []byte) error { + _, err := emitter.output_file.Write(buffer) + return err +} + +// Set a string output. +func yaml_emitter_set_output_string(emitter *yaml_emitter_t, output_buffer *[]byte) { + if emitter.write_handler != nil { + panic("must set the output target only once") + } + emitter.write_handler = yaml_string_write_handler + emitter.output_buffer = output_buffer +} + +// Set a file output. +func yaml_emitter_set_output_file(emitter *yaml_emitter_t, file io.Writer) { + if emitter.write_handler != nil { + panic("must set the output target only once") + } + emitter.write_handler = yaml_file_write_handler + emitter.output_file = file +} + +// Set the output encoding. +func yaml_emitter_set_encoding(emitter *yaml_emitter_t, encoding yaml_encoding_t) { + if emitter.encoding != yaml_ANY_ENCODING { + panic("must set the output encoding only once") + } + emitter.encoding = encoding +} + +// Set the canonical output style. +func yaml_emitter_set_canonical(emitter *yaml_emitter_t, canonical bool) { + emitter.canonical = canonical +} + +//// Set the indentation increment. +func yaml_emitter_set_indent(emitter *yaml_emitter_t, indent int) { + if indent < 2 || indent > 9 { + indent = 2 + } + emitter.best_indent = indent +} + +// Set the preferred line width. +func yaml_emitter_set_width(emitter *yaml_emitter_t, width int) { + if width < 0 { + width = -1 + } + emitter.best_width = width +} + +// Set if unescaped non-ASCII characters are allowed. +func yaml_emitter_set_unicode(emitter *yaml_emitter_t, unicode bool) { + emitter.unicode = unicode +} + +// Set the preferred line break character. +func yaml_emitter_set_break(emitter *yaml_emitter_t, line_break yaml_break_t) { + emitter.line_break = line_break +} + +///* +// * Destroy a token object. +// */ +// +//YAML_DECLARE(void) +//yaml_token_delete(yaml_token_t *token) +//{ +// assert(token); // Non-NULL token object expected. +// +// switch (token.type) +// { +// case YAML_TAG_DIRECTIVE_TOKEN: +// yaml_free(token.data.tag_directive.handle); +// yaml_free(token.data.tag_directive.prefix); +// break; +// +// case YAML_ALIAS_TOKEN: +// yaml_free(token.data.alias.value); +// break; +// +// case YAML_ANCHOR_TOKEN: +// yaml_free(token.data.anchor.value); +// break; +// +// case YAML_TAG_TOKEN: +// yaml_free(token.data.tag.handle); +// yaml_free(token.data.tag.suffix); +// break; +// +// case YAML_SCALAR_TOKEN: +// yaml_free(token.data.scalar.value); +// break; +// +// default: +// break; +// } +// +// memset(token, 0, sizeof(yaml_token_t)); +//} +// +///* +// * Check if a string is a valid UTF-8 sequence. +// * +// * Check 'reader.c' for more details on UTF-8 encoding. +// */ +// +//static int +//yaml_check_utf8(yaml_char_t *start, size_t length) +//{ +// yaml_char_t *end = start+length; +// yaml_char_t *pointer = start; +// +// while (pointer < end) { +// unsigned char octet; +// unsigned int width; +// unsigned int value; +// size_t k; +// +// octet = pointer[0]; +// width = (octet & 0x80) == 0x00 ? 1 : +// (octet & 0xE0) == 0xC0 ? 2 : +// (octet & 0xF0) == 0xE0 ? 3 : +// (octet & 0xF8) == 0xF0 ? 4 : 0; +// value = (octet & 0x80) == 0x00 ? octet & 0x7F : +// (octet & 0xE0) == 0xC0 ? octet & 0x1F : +// (octet & 0xF0) == 0xE0 ? octet & 0x0F : +// (octet & 0xF8) == 0xF0 ? octet & 0x07 : 0; +// if (!width) return 0; +// if (pointer+width > end) return 0; +// for (k = 1; k < width; k ++) { +// octet = pointer[k]; +// if ((octet & 0xC0) != 0x80) return 0; +// value = (value << 6) + (octet & 0x3F); +// } +// if (!((width == 1) || +// (width == 2 && value >= 0x80) || +// (width == 3 && value >= 0x800) || +// (width == 4 && value >= 0x10000))) return 0; +// +// pointer += width; +// } +// +// return 1; +//} +// + +// Create STREAM-START. +func yaml_stream_start_event_initialize(event *yaml_event_t, encoding yaml_encoding_t) bool { + *event = yaml_event_t{ + typ: yaml_STREAM_START_EVENT, + encoding: encoding, + } + return true +} + +// Create STREAM-END. +func yaml_stream_end_event_initialize(event *yaml_event_t) bool { + *event = yaml_event_t{ + typ: yaml_STREAM_END_EVENT, + } + return true +} + +// Create DOCUMENT-START. +func yaml_document_start_event_initialize(event *yaml_event_t, version_directive *yaml_version_directive_t, + tag_directives []yaml_tag_directive_t, implicit bool) bool { + *event = yaml_event_t{ + typ: yaml_DOCUMENT_START_EVENT, + version_directive: version_directive, + tag_directives: tag_directives, + implicit: implicit, + } + return true +} + +// Create DOCUMENT-END. +func yaml_document_end_event_initialize(event *yaml_event_t, implicit bool) bool { + *event = yaml_event_t{ + typ: yaml_DOCUMENT_END_EVENT, + implicit: implicit, + } + return true +} + +///* +// * Create ALIAS. +// */ +// +//YAML_DECLARE(int) +//yaml_alias_event_initialize(event *yaml_event_t, anchor *yaml_char_t) +//{ +// mark yaml_mark_t = { 0, 0, 0 } +// anchor_copy *yaml_char_t = NULL +// +// assert(event) // Non-NULL event object is expected. +// assert(anchor) // Non-NULL anchor is expected. +// +// if (!yaml_check_utf8(anchor, strlen((char *)anchor))) return 0 +// +// anchor_copy = yaml_strdup(anchor) +// if (!anchor_copy) +// return 0 +// +// ALIAS_EVENT_INIT(*event, anchor_copy, mark, mark) +// +// return 1 +//} + +// Create SCALAR. +func yaml_scalar_event_initialize(event *yaml_event_t, anchor, tag, value []byte, plain_implicit, quoted_implicit bool, style yaml_scalar_style_t) bool { + *event = yaml_event_t{ + typ: yaml_SCALAR_EVENT, + anchor: anchor, + tag: tag, + value: value, + implicit: plain_implicit, + quoted_implicit: quoted_implicit, + style: yaml_style_t(style), + } + return true +} + +// Create SEQUENCE-START. +func yaml_sequence_start_event_initialize(event *yaml_event_t, anchor, tag []byte, implicit bool, style yaml_sequence_style_t) bool { + *event = yaml_event_t{ + typ: yaml_SEQUENCE_START_EVENT, + anchor: anchor, + tag: tag, + implicit: implicit, + style: yaml_style_t(style), + } + return true +} + +// Create SEQUENCE-END. +func yaml_sequence_end_event_initialize(event *yaml_event_t) bool { + *event = yaml_event_t{ + typ: yaml_SEQUENCE_END_EVENT, + } + return true +} + +// Create MAPPING-START. +func yaml_mapping_start_event_initialize(event *yaml_event_t, anchor, tag []byte, implicit bool, style yaml_mapping_style_t) bool { + *event = yaml_event_t{ + typ: yaml_MAPPING_START_EVENT, + anchor: anchor, + tag: tag, + implicit: implicit, + style: yaml_style_t(style), + } + return true +} + +// Create MAPPING-END. +func yaml_mapping_end_event_initialize(event *yaml_event_t) bool { + *event = yaml_event_t{ + typ: yaml_MAPPING_END_EVENT, + } + return true +} + +// Destroy an event object. +func yaml_event_delete(event *yaml_event_t) { + *event = yaml_event_t{} +} + +///* +// * Create a document object. +// */ +// +//YAML_DECLARE(int) +//yaml_document_initialize(document *yaml_document_t, +// version_directive *yaml_version_directive_t, +// tag_directives_start *yaml_tag_directive_t, +// tag_directives_end *yaml_tag_directive_t, +// start_implicit int, end_implicit int) +//{ +// struct { +// error yaml_error_type_t +// } context +// struct { +// start *yaml_node_t +// end *yaml_node_t +// top *yaml_node_t +// } nodes = { NULL, NULL, NULL } +// version_directive_copy *yaml_version_directive_t = NULL +// struct { +// start *yaml_tag_directive_t +// end *yaml_tag_directive_t +// top *yaml_tag_directive_t +// } tag_directives_copy = { NULL, NULL, NULL } +// value yaml_tag_directive_t = { NULL, NULL } +// mark yaml_mark_t = { 0, 0, 0 } +// +// assert(document) // Non-NULL document object is expected. +// assert((tag_directives_start && tag_directives_end) || +// (tag_directives_start == tag_directives_end)) +// // Valid tag directives are expected. +// +// if (!STACK_INIT(&context, nodes, INITIAL_STACK_SIZE)) goto error +// +// if (version_directive) { +// version_directive_copy = yaml_malloc(sizeof(yaml_version_directive_t)) +// if (!version_directive_copy) goto error +// version_directive_copy.major = version_directive.major +// version_directive_copy.minor = version_directive.minor +// } +// +// if (tag_directives_start != tag_directives_end) { +// tag_directive *yaml_tag_directive_t +// if (!STACK_INIT(&context, tag_directives_copy, INITIAL_STACK_SIZE)) +// goto error +// for (tag_directive = tag_directives_start +// tag_directive != tag_directives_end; tag_directive ++) { +// assert(tag_directive.handle) +// assert(tag_directive.prefix) +// if (!yaml_check_utf8(tag_directive.handle, +// strlen((char *)tag_directive.handle))) +// goto error +// if (!yaml_check_utf8(tag_directive.prefix, +// strlen((char *)tag_directive.prefix))) +// goto error +// value.handle = yaml_strdup(tag_directive.handle) +// value.prefix = yaml_strdup(tag_directive.prefix) +// if (!value.handle || !value.prefix) goto error +// if (!PUSH(&context, tag_directives_copy, value)) +// goto error +// value.handle = NULL +// value.prefix = NULL +// } +// } +// +// DOCUMENT_INIT(*document, nodes.start, nodes.end, version_directive_copy, +// tag_directives_copy.start, tag_directives_copy.top, +// start_implicit, end_implicit, mark, mark) +// +// return 1 +// +//error: +// STACK_DEL(&context, nodes) +// yaml_free(version_directive_copy) +// while (!STACK_EMPTY(&context, tag_directives_copy)) { +// value yaml_tag_directive_t = POP(&context, tag_directives_copy) +// yaml_free(value.handle) +// yaml_free(value.prefix) +// } +// STACK_DEL(&context, tag_directives_copy) +// yaml_free(value.handle) +// yaml_free(value.prefix) +// +// return 0 +//} +// +///* +// * Destroy a document object. +// */ +// +//YAML_DECLARE(void) +//yaml_document_delete(document *yaml_document_t) +//{ +// struct { +// error yaml_error_type_t +// } context +// tag_directive *yaml_tag_directive_t +// +// context.error = YAML_NO_ERROR // Eliminate a compliler warning. +// +// assert(document) // Non-NULL document object is expected. +// +// while (!STACK_EMPTY(&context, document.nodes)) { +// node yaml_node_t = POP(&context, document.nodes) +// yaml_free(node.tag) +// switch (node.type) { +// case YAML_SCALAR_NODE: +// yaml_free(node.data.scalar.value) +// break +// case YAML_SEQUENCE_NODE: +// STACK_DEL(&context, node.data.sequence.items) +// break +// case YAML_MAPPING_NODE: +// STACK_DEL(&context, node.data.mapping.pairs) +// break +// default: +// assert(0) // Should not happen. +// } +// } +// STACK_DEL(&context, document.nodes) +// +// yaml_free(document.version_directive) +// for (tag_directive = document.tag_directives.start +// tag_directive != document.tag_directives.end +// tag_directive++) { +// yaml_free(tag_directive.handle) +// yaml_free(tag_directive.prefix) +// } +// yaml_free(document.tag_directives.start) +// +// memset(document, 0, sizeof(yaml_document_t)) +//} +// +///** +// * Get a document node. +// */ +// +//YAML_DECLARE(yaml_node_t *) +//yaml_document_get_node(document *yaml_document_t, index int) +//{ +// assert(document) // Non-NULL document object is expected. +// +// if (index > 0 && document.nodes.start + index <= document.nodes.top) { +// return document.nodes.start + index - 1 +// } +// return NULL +//} +// +///** +// * Get the root object. +// */ +// +//YAML_DECLARE(yaml_node_t *) +//yaml_document_get_root_node(document *yaml_document_t) +//{ +// assert(document) // Non-NULL document object is expected. +// +// if (document.nodes.top != document.nodes.start) { +// return document.nodes.start +// } +// return NULL +//} +// +///* +// * Add a scalar node to a document. +// */ +// +//YAML_DECLARE(int) +//yaml_document_add_scalar(document *yaml_document_t, +// tag *yaml_char_t, value *yaml_char_t, length int, +// style yaml_scalar_style_t) +//{ +// struct { +// error yaml_error_type_t +// } context +// mark yaml_mark_t = { 0, 0, 0 } +// tag_copy *yaml_char_t = NULL +// value_copy *yaml_char_t = NULL +// node yaml_node_t +// +// assert(document) // Non-NULL document object is expected. +// assert(value) // Non-NULL value is expected. +// +// if (!tag) { +// tag = (yaml_char_t *)YAML_DEFAULT_SCALAR_TAG +// } +// +// if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error +// tag_copy = yaml_strdup(tag) +// if (!tag_copy) goto error +// +// if (length < 0) { +// length = strlen((char *)value) +// } +// +// if (!yaml_check_utf8(value, length)) goto error +// value_copy = yaml_malloc(length+1) +// if (!value_copy) goto error +// memcpy(value_copy, value, length) +// value_copy[length] = '\0' +// +// SCALAR_NODE_INIT(node, tag_copy, value_copy, length, style, mark, mark) +// if (!PUSH(&context, document.nodes, node)) goto error +// +// return document.nodes.top - document.nodes.start +// +//error: +// yaml_free(tag_copy) +// yaml_free(value_copy) +// +// return 0 +//} +// +///* +// * Add a sequence node to a document. +// */ +// +//YAML_DECLARE(int) +//yaml_document_add_sequence(document *yaml_document_t, +// tag *yaml_char_t, style yaml_sequence_style_t) +//{ +// struct { +// error yaml_error_type_t +// } context +// mark yaml_mark_t = { 0, 0, 0 } +// tag_copy *yaml_char_t = NULL +// struct { +// start *yaml_node_item_t +// end *yaml_node_item_t +// top *yaml_node_item_t +// } items = { NULL, NULL, NULL } +// node yaml_node_t +// +// assert(document) // Non-NULL document object is expected. +// +// if (!tag) { +// tag = (yaml_char_t *)YAML_DEFAULT_SEQUENCE_TAG +// } +// +// if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error +// tag_copy = yaml_strdup(tag) +// if (!tag_copy) goto error +// +// if (!STACK_INIT(&context, items, INITIAL_STACK_SIZE)) goto error +// +// SEQUENCE_NODE_INIT(node, tag_copy, items.start, items.end, +// style, mark, mark) +// if (!PUSH(&context, document.nodes, node)) goto error +// +// return document.nodes.top - document.nodes.start +// +//error: +// STACK_DEL(&context, items) +// yaml_free(tag_copy) +// +// return 0 +//} +// +///* +// * Add a mapping node to a document. +// */ +// +//YAML_DECLARE(int) +//yaml_document_add_mapping(document *yaml_document_t, +// tag *yaml_char_t, style yaml_mapping_style_t) +//{ +// struct { +// error yaml_error_type_t +// } context +// mark yaml_mark_t = { 0, 0, 0 } +// tag_copy *yaml_char_t = NULL +// struct { +// start *yaml_node_pair_t +// end *yaml_node_pair_t +// top *yaml_node_pair_t +// } pairs = { NULL, NULL, NULL } +// node yaml_node_t +// +// assert(document) // Non-NULL document object is expected. +// +// if (!tag) { +// tag = (yaml_char_t *)YAML_DEFAULT_MAPPING_TAG +// } +// +// if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error +// tag_copy = yaml_strdup(tag) +// if (!tag_copy) goto error +// +// if (!STACK_INIT(&context, pairs, INITIAL_STACK_SIZE)) goto error +// +// MAPPING_NODE_INIT(node, tag_copy, pairs.start, pairs.end, +// style, mark, mark) +// if (!PUSH(&context, document.nodes, node)) goto error +// +// return document.nodes.top - document.nodes.start +// +//error: +// STACK_DEL(&context, pairs) +// yaml_free(tag_copy) +// +// return 0 +//} +// +///* +// * Append an item to a sequence node. +// */ +// +//YAML_DECLARE(int) +//yaml_document_append_sequence_item(document *yaml_document_t, +// sequence int, item int) +//{ +// struct { +// error yaml_error_type_t +// } context +// +// assert(document) // Non-NULL document is required. +// assert(sequence > 0 +// && document.nodes.start + sequence <= document.nodes.top) +// // Valid sequence id is required. +// assert(document.nodes.start[sequence-1].type == YAML_SEQUENCE_NODE) +// // A sequence node is required. +// assert(item > 0 && document.nodes.start + item <= document.nodes.top) +// // Valid item id is required. +// +// if (!PUSH(&context, +// document.nodes.start[sequence-1].data.sequence.items, item)) +// return 0 +// +// return 1 +//} +// +///* +// * Append a pair of a key and a value to a mapping node. +// */ +// +//YAML_DECLARE(int) +//yaml_document_append_mapping_pair(document *yaml_document_t, +// mapping int, key int, value int) +//{ +// struct { +// error yaml_error_type_t +// } context +// +// pair yaml_node_pair_t +// +// assert(document) // Non-NULL document is required. +// assert(mapping > 0 +// && document.nodes.start + mapping <= document.nodes.top) +// // Valid mapping id is required. +// assert(document.nodes.start[mapping-1].type == YAML_MAPPING_NODE) +// // A mapping node is required. +// assert(key > 0 && document.nodes.start + key <= document.nodes.top) +// // Valid key id is required. +// assert(value > 0 && document.nodes.start + value <= document.nodes.top) +// // Valid value id is required. +// +// pair.key = key +// pair.value = value +// +// if (!PUSH(&context, +// document.nodes.start[mapping-1].data.mapping.pairs, pair)) +// return 0 +// +// return 1 +//} +// +// diff --git a/vendor/gopkg.in/yaml.v2/decode.go b/vendor/gopkg.in/yaml.v2/decode.go new file mode 100644 index 0000000..085cddc --- /dev/null +++ b/vendor/gopkg.in/yaml.v2/decode.go @@ -0,0 +1,683 @@ +package yaml + +import ( + "encoding" + "encoding/base64" + "fmt" + "math" + "reflect" + "strconv" + "time" +) + +const ( + documentNode = 1 << iota + mappingNode + sequenceNode + scalarNode + aliasNode +) + +type node struct { + kind int + line, column int + tag string + value string + implicit bool + children []*node + anchors map[string]*node +} + +// ---------------------------------------------------------------------------- +// Parser, produces a node tree out of a libyaml event stream. + +type parser struct { + parser yaml_parser_t + event yaml_event_t + doc *node +} + +func newParser(b []byte) *parser { + p := parser{} + if !yaml_parser_initialize(&p.parser) { + panic("failed to initialize YAML emitter") + } + + if len(b) == 0 { + b = []byte{'\n'} + } + + yaml_parser_set_input_string(&p.parser, b) + + p.skip() + if p.event.typ != yaml_STREAM_START_EVENT { + panic("expected stream start event, got " + strconv.Itoa(int(p.event.typ))) + } + p.skip() + return &p +} + +func (p *parser) destroy() { + if p.event.typ != yaml_NO_EVENT { + yaml_event_delete(&p.event) + } + yaml_parser_delete(&p.parser) +} + +func (p *parser) skip() { + if p.event.typ != yaml_NO_EVENT { + if p.event.typ == yaml_STREAM_END_EVENT { + failf("attempted to go past the end of stream; corrupted value?") + } + yaml_event_delete(&p.event) + } + if !yaml_parser_parse(&p.parser, &p.event) { + p.fail() + } +} + +func (p *parser) fail() { + var where string + var line int + if p.parser.problem_mark.line != 0 { + line = p.parser.problem_mark.line + } else if p.parser.context_mark.line != 0 { + line = p.parser.context_mark.line + } + if line != 0 { + where = "line " + strconv.Itoa(line) + ": " + } + var msg string + if len(p.parser.problem) > 0 { + msg = p.parser.problem + } else { + msg = "unknown problem parsing YAML content" + } + failf("%s%s", where, msg) +} + +func (p *parser) anchor(n *node, anchor []byte) { + if anchor != nil { + p.doc.anchors[string(anchor)] = n + } +} + +func (p *parser) parse() *node { + switch p.event.typ { + case yaml_SCALAR_EVENT: + return p.scalar() + case yaml_ALIAS_EVENT: + return p.alias() + case yaml_MAPPING_START_EVENT: + return p.mapping() + case yaml_SEQUENCE_START_EVENT: + return p.sequence() + case yaml_DOCUMENT_START_EVENT: + return p.document() + case yaml_STREAM_END_EVENT: + // Happens when attempting to decode an empty buffer. + return nil + default: + panic("attempted to parse unknown event: " + strconv.Itoa(int(p.event.typ))) + } + panic("unreachable") +} + +func (p *parser) node(kind int) *node { + return &node{ + kind: kind, + line: p.event.start_mark.line, + column: p.event.start_mark.column, + } +} + +func (p *parser) document() *node { + n := p.node(documentNode) + n.anchors = make(map[string]*node) + p.doc = n + p.skip() + n.children = append(n.children, p.parse()) + if p.event.typ != yaml_DOCUMENT_END_EVENT { + panic("expected end of document event but got " + strconv.Itoa(int(p.event.typ))) + } + p.skip() + return n +} + +func (p *parser) alias() *node { + n := p.node(aliasNode) + n.value = string(p.event.anchor) + p.skip() + return n +} + +func (p *parser) scalar() *node { + n := p.node(scalarNode) + n.value = string(p.event.value) + n.tag = string(p.event.tag) + n.implicit = p.event.implicit + p.anchor(n, p.event.anchor) + p.skip() + return n +} + +func (p *parser) sequence() *node { + n := p.node(sequenceNode) + p.anchor(n, p.event.anchor) + p.skip() + for p.event.typ != yaml_SEQUENCE_END_EVENT { + n.children = append(n.children, p.parse()) + } + p.skip() + return n +} + +func (p *parser) mapping() *node { + n := p.node(mappingNode) + p.anchor(n, p.event.anchor) + p.skip() + for p.event.typ != yaml_MAPPING_END_EVENT { + n.children = append(n.children, p.parse(), p.parse()) + } + p.skip() + return n +} + +// ---------------------------------------------------------------------------- +// Decoder, unmarshals a node into a provided value. + +type decoder struct { + doc *node + aliases map[string]bool + mapType reflect.Type + terrors []string +} + +var ( + mapItemType = reflect.TypeOf(MapItem{}) + durationType = reflect.TypeOf(time.Duration(0)) + defaultMapType = reflect.TypeOf(map[interface{}]interface{}{}) + ifaceType = defaultMapType.Elem() +) + +func newDecoder() *decoder { + d := &decoder{mapType: defaultMapType} + d.aliases = make(map[string]bool) + return d +} + +func (d *decoder) terror(n *node, tag string, out reflect.Value) { + if n.tag != "" { + tag = n.tag + } + value := n.value + if tag != yaml_SEQ_TAG && tag != yaml_MAP_TAG { + if len(value) > 10 { + value = " `" + value[:7] + "...`" + } else { + value = " `" + value + "`" + } + } + d.terrors = append(d.terrors, fmt.Sprintf("line %d: cannot unmarshal %s%s into %s", n.line+1, shortTag(tag), value, out.Type())) +} + +func (d *decoder) callUnmarshaler(n *node, u Unmarshaler) (good bool) { + terrlen := len(d.terrors) + err := u.UnmarshalYAML(func(v interface{}) (err error) { + defer handleErr(&err) + d.unmarshal(n, reflect.ValueOf(v)) + if len(d.terrors) > terrlen { + issues := d.terrors[terrlen:] + d.terrors = d.terrors[:terrlen] + return &TypeError{issues} + } + return nil + }) + if e, ok := err.(*TypeError); ok { + d.terrors = append(d.terrors, e.Errors...) + return false + } + if err != nil { + fail(err) + } + return true +} + +// d.prepare initializes and dereferences pointers and calls UnmarshalYAML +// if a value is found to implement it. +// It returns the initialized and dereferenced out value, whether +// unmarshalling was already done by UnmarshalYAML, and if so whether +// its types unmarshalled appropriately. +// +// If n holds a null value, prepare returns before doing anything. +func (d *decoder) prepare(n *node, out reflect.Value) (newout reflect.Value, unmarshaled, good bool) { + if n.tag == yaml_NULL_TAG || n.kind == scalarNode && n.tag == "" && (n.value == "null" || n.value == "") { + return out, false, false + } + again := true + for again { + again = false + if out.Kind() == reflect.Ptr { + if out.IsNil() { + out.Set(reflect.New(out.Type().Elem())) + } + out = out.Elem() + again = true + } + if out.CanAddr() { + if u, ok := out.Addr().Interface().(Unmarshaler); ok { + good = d.callUnmarshaler(n, u) + return out, true, good + } + } + } + return out, false, false +} + +func (d *decoder) unmarshal(n *node, out reflect.Value) (good bool) { + switch n.kind { + case documentNode: + return d.document(n, out) + case aliasNode: + return d.alias(n, out) + } + out, unmarshaled, good := d.prepare(n, out) + if unmarshaled { + return good + } + switch n.kind { + case scalarNode: + good = d.scalar(n, out) + case mappingNode: + good = d.mapping(n, out) + case sequenceNode: + good = d.sequence(n, out) + default: + panic("internal error: unknown node kind: " + strconv.Itoa(n.kind)) + } + return good +} + +func (d *decoder) document(n *node, out reflect.Value) (good bool) { + if len(n.children) == 1 { + d.doc = n + d.unmarshal(n.children[0], out) + return true + } + return false +} + +func (d *decoder) alias(n *node, out reflect.Value) (good bool) { + an, ok := d.doc.anchors[n.value] + if !ok { + failf("unknown anchor '%s' referenced", n.value) + } + if d.aliases[n.value] { + failf("anchor '%s' value contains itself", n.value) + } + d.aliases[n.value] = true + good = d.unmarshal(an, out) + delete(d.aliases, n.value) + return good +} + +var zeroValue reflect.Value + +func resetMap(out reflect.Value) { + for _, k := range out.MapKeys() { + out.SetMapIndex(k, zeroValue) + } +} + +func (d *decoder) scalar(n *node, out reflect.Value) (good bool) { + var tag string + var resolved interface{} + if n.tag == "" && !n.implicit { + tag = yaml_STR_TAG + resolved = n.value + } else { + tag, resolved = resolve(n.tag, n.value) + if tag == yaml_BINARY_TAG { + data, err := base64.StdEncoding.DecodeString(resolved.(string)) + if err != nil { + failf("!!binary value contains invalid base64 data") + } + resolved = string(data) + } + } + if resolved == nil { + if out.Kind() == reflect.Map && !out.CanAddr() { + resetMap(out) + } else { + out.Set(reflect.Zero(out.Type())) + } + return true + } + if s, ok := resolved.(string); ok && out.CanAddr() { + if u, ok := out.Addr().Interface().(encoding.TextUnmarshaler); ok { + err := u.UnmarshalText([]byte(s)) + if err != nil { + fail(err) + } + return true + } + } + switch out.Kind() { + case reflect.String: + if tag == yaml_BINARY_TAG { + out.SetString(resolved.(string)) + good = true + } else if resolved != nil { + out.SetString(n.value) + good = true + } + case reflect.Interface: + if resolved == nil { + out.Set(reflect.Zero(out.Type())) + } else { + out.Set(reflect.ValueOf(resolved)) + } + good = true + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + switch resolved := resolved.(type) { + case int: + if !out.OverflowInt(int64(resolved)) { + out.SetInt(int64(resolved)) + good = true + } + case int64: + if !out.OverflowInt(resolved) { + out.SetInt(resolved) + good = true + } + case uint64: + if resolved <= math.MaxInt64 && !out.OverflowInt(int64(resolved)) { + out.SetInt(int64(resolved)) + good = true + } + case float64: + if resolved <= math.MaxInt64 && !out.OverflowInt(int64(resolved)) { + out.SetInt(int64(resolved)) + good = true + } + case string: + if out.Type() == durationType { + d, err := time.ParseDuration(resolved) + if err == nil { + out.SetInt(int64(d)) + good = true + } + } + } + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + switch resolved := resolved.(type) { + case int: + if resolved >= 0 && !out.OverflowUint(uint64(resolved)) { + out.SetUint(uint64(resolved)) + good = true + } + case int64: + if resolved >= 0 && !out.OverflowUint(uint64(resolved)) { + out.SetUint(uint64(resolved)) + good = true + } + case uint64: + if !out.OverflowUint(uint64(resolved)) { + out.SetUint(uint64(resolved)) + good = true + } + case float64: + if resolved <= math.MaxUint64 && !out.OverflowUint(uint64(resolved)) { + out.SetUint(uint64(resolved)) + good = true + } + } + case reflect.Bool: + switch resolved := resolved.(type) { + case bool: + out.SetBool(resolved) + good = true + } + case reflect.Float32, reflect.Float64: + switch resolved := resolved.(type) { + case int: + out.SetFloat(float64(resolved)) + good = true + case int64: + out.SetFloat(float64(resolved)) + good = true + case uint64: + out.SetFloat(float64(resolved)) + good = true + case float64: + out.SetFloat(resolved) + good = true + } + case reflect.Ptr: + if out.Type().Elem() == reflect.TypeOf(resolved) { + // TODO DOes this make sense? When is out a Ptr except when decoding a nil value? + elem := reflect.New(out.Type().Elem()) + elem.Elem().Set(reflect.ValueOf(resolved)) + out.Set(elem) + good = true + } + } + if !good { + d.terror(n, tag, out) + } + return good +} + +func settableValueOf(i interface{}) reflect.Value { + v := reflect.ValueOf(i) + sv := reflect.New(v.Type()).Elem() + sv.Set(v) + return sv +} + +func (d *decoder) sequence(n *node, out reflect.Value) (good bool) { + l := len(n.children) + + var iface reflect.Value + switch out.Kind() { + case reflect.Slice: + out.Set(reflect.MakeSlice(out.Type(), l, l)) + case reflect.Interface: + // No type hints. Will have to use a generic sequence. + iface = out + out = settableValueOf(make([]interface{}, l)) + default: + d.terror(n, yaml_SEQ_TAG, out) + return false + } + et := out.Type().Elem() + + j := 0 + for i := 0; i < l; i++ { + e := reflect.New(et).Elem() + if ok := d.unmarshal(n.children[i], e); ok { + out.Index(j).Set(e) + j++ + } + } + out.Set(out.Slice(0, j)) + if iface.IsValid() { + iface.Set(out) + } + return true +} + +func (d *decoder) mapping(n *node, out reflect.Value) (good bool) { + switch out.Kind() { + case reflect.Struct: + return d.mappingStruct(n, out) + case reflect.Slice: + return d.mappingSlice(n, out) + case reflect.Map: + // okay + case reflect.Interface: + if d.mapType.Kind() == reflect.Map { + iface := out + out = reflect.MakeMap(d.mapType) + iface.Set(out) + } else { + slicev := reflect.New(d.mapType).Elem() + if !d.mappingSlice(n, slicev) { + return false + } + out.Set(slicev) + return true + } + default: + d.terror(n, yaml_MAP_TAG, out) + return false + } + outt := out.Type() + kt := outt.Key() + et := outt.Elem() + + mapType := d.mapType + if outt.Key() == ifaceType && outt.Elem() == ifaceType { + d.mapType = outt + } + + if out.IsNil() { + out.Set(reflect.MakeMap(outt)) + } + l := len(n.children) + for i := 0; i < l; i += 2 { + if isMerge(n.children[i]) { + d.merge(n.children[i+1], out) + continue + } + k := reflect.New(kt).Elem() + if d.unmarshal(n.children[i], k) { + kkind := k.Kind() + if kkind == reflect.Interface { + kkind = k.Elem().Kind() + } + if kkind == reflect.Map || kkind == reflect.Slice { + failf("invalid map key: %#v", k.Interface()) + } + e := reflect.New(et).Elem() + if d.unmarshal(n.children[i+1], e) { + out.SetMapIndex(k, e) + } + } + } + d.mapType = mapType + return true +} + +func (d *decoder) mappingSlice(n *node, out reflect.Value) (good bool) { + outt := out.Type() + if outt.Elem() != mapItemType { + d.terror(n, yaml_MAP_TAG, out) + return false + } + + mapType := d.mapType + d.mapType = outt + + var slice []MapItem + var l = len(n.children) + for i := 0; i < l; i += 2 { + if isMerge(n.children[i]) { + d.merge(n.children[i+1], out) + continue + } + item := MapItem{} + k := reflect.ValueOf(&item.Key).Elem() + if d.unmarshal(n.children[i], k) { + v := reflect.ValueOf(&item.Value).Elem() + if d.unmarshal(n.children[i+1], v) { + slice = append(slice, item) + } + } + } + out.Set(reflect.ValueOf(slice)) + d.mapType = mapType + return true +} + +func (d *decoder) mappingStruct(n *node, out reflect.Value) (good bool) { + sinfo, err := getStructInfo(out.Type()) + if err != nil { + panic(err) + } + name := settableValueOf("") + l := len(n.children) + + var inlineMap reflect.Value + var elemType reflect.Type + if sinfo.InlineMap != -1 { + inlineMap = out.Field(sinfo.InlineMap) + inlineMap.Set(reflect.New(inlineMap.Type()).Elem()) + elemType = inlineMap.Type().Elem() + } + + for i := 0; i < l; i += 2 { + ni := n.children[i] + if isMerge(ni) { + d.merge(n.children[i+1], out) + continue + } + if !d.unmarshal(ni, name) { + continue + } + if info, ok := sinfo.FieldsMap[name.String()]; ok { + var field reflect.Value + if info.Inline == nil { + field = out.Field(info.Num) + } else { + field = out.FieldByIndex(info.Inline) + } + d.unmarshal(n.children[i+1], field) + } else if sinfo.InlineMap != -1 { + if inlineMap.IsNil() { + inlineMap.Set(reflect.MakeMap(inlineMap.Type())) + } + value := reflect.New(elemType).Elem() + d.unmarshal(n.children[i+1], value) + inlineMap.SetMapIndex(name, value) + } + } + return true +} + +func failWantMap() { + failf("map merge requires map or sequence of maps as the value") +} + +func (d *decoder) merge(n *node, out reflect.Value) { + switch n.kind { + case mappingNode: + d.unmarshal(n, out) + case aliasNode: + an, ok := d.doc.anchors[n.value] + if ok && an.kind != mappingNode { + failWantMap() + } + d.unmarshal(n, out) + case sequenceNode: + // Step backwards as earlier nodes take precedence. + for i := len(n.children) - 1; i >= 0; i-- { + ni := n.children[i] + if ni.kind == aliasNode { + an, ok := d.doc.anchors[ni.value] + if ok && an.kind != mappingNode { + failWantMap() + } + } else if ni.kind != mappingNode { + failWantMap() + } + d.unmarshal(ni, out) + } + default: + failWantMap() + } +} + +func isMerge(n *node) bool { + return n.kind == scalarNode && n.value == "<<" && (n.implicit == true || n.tag == yaml_MERGE_TAG) +} diff --git a/vendor/gopkg.in/yaml.v2/emitterc.go b/vendor/gopkg.in/yaml.v2/emitterc.go new file mode 100644 index 0000000..2befd55 --- /dev/null +++ b/vendor/gopkg.in/yaml.v2/emitterc.go @@ -0,0 +1,1685 @@ +package yaml + +import ( + "bytes" +) + +// Flush the buffer if needed. +func flush(emitter *yaml_emitter_t) bool { + if emitter.buffer_pos+5 >= len(emitter.buffer) { + return yaml_emitter_flush(emitter) + } + return true +} + +// Put a character to the output buffer. +func put(emitter *yaml_emitter_t, value byte) bool { + if emitter.buffer_pos+5 >= len(emitter.buffer) && !yaml_emitter_flush(emitter) { + return false + } + emitter.buffer[emitter.buffer_pos] = value + emitter.buffer_pos++ + emitter.column++ + return true +} + +// Put a line break to the output buffer. +func put_break(emitter *yaml_emitter_t) bool { + if emitter.buffer_pos+5 >= len(emitter.buffer) && !yaml_emitter_flush(emitter) { + return false + } + switch emitter.line_break { + case yaml_CR_BREAK: + emitter.buffer[emitter.buffer_pos] = '\r' + emitter.buffer_pos += 1 + case yaml_LN_BREAK: + emitter.buffer[emitter.buffer_pos] = '\n' + emitter.buffer_pos += 1 + case yaml_CRLN_BREAK: + emitter.buffer[emitter.buffer_pos+0] = '\r' + emitter.buffer[emitter.buffer_pos+1] = '\n' + emitter.buffer_pos += 2 + default: + panic("unknown line break setting") + } + emitter.column = 0 + emitter.line++ + return true +} + +// Copy a character from a string into buffer. +func write(emitter *yaml_emitter_t, s []byte, i *int) bool { + if emitter.buffer_pos+5 >= len(emitter.buffer) && !yaml_emitter_flush(emitter) { + return false + } + p := emitter.buffer_pos + w := width(s[*i]) + switch w { + case 4: + emitter.buffer[p+3] = s[*i+3] + fallthrough + case 3: + emitter.buffer[p+2] = s[*i+2] + fallthrough + case 2: + emitter.buffer[p+1] = s[*i+1] + fallthrough + case 1: + emitter.buffer[p+0] = s[*i+0] + default: + panic("unknown character width") + } + emitter.column++ + emitter.buffer_pos += w + *i += w + return true +} + +// Write a whole string into buffer. +func write_all(emitter *yaml_emitter_t, s []byte) bool { + for i := 0; i < len(s); { + if !write(emitter, s, &i) { + return false + } + } + return true +} + +// Copy a line break character from a string into buffer. +func write_break(emitter *yaml_emitter_t, s []byte, i *int) bool { + if s[*i] == '\n' { + if !put_break(emitter) { + return false + } + *i++ + } else { + if !write(emitter, s, i) { + return false + } + emitter.column = 0 + emitter.line++ + } + return true +} + +// Set an emitter error and return false. +func yaml_emitter_set_emitter_error(emitter *yaml_emitter_t, problem string) bool { + emitter.error = yaml_EMITTER_ERROR + emitter.problem = problem + return false +} + +// Emit an event. +func yaml_emitter_emit(emitter *yaml_emitter_t, event *yaml_event_t) bool { + emitter.events = append(emitter.events, *event) + for !yaml_emitter_need_more_events(emitter) { + event := &emitter.events[emitter.events_head] + if !yaml_emitter_analyze_event(emitter, event) { + return false + } + if !yaml_emitter_state_machine(emitter, event) { + return false + } + yaml_event_delete(event) + emitter.events_head++ + } + return true +} + +// Check if we need to accumulate more events before emitting. +// +// We accumulate extra +// - 1 event for DOCUMENT-START +// - 2 events for SEQUENCE-START +// - 3 events for MAPPING-START +// +func yaml_emitter_need_more_events(emitter *yaml_emitter_t) bool { + if emitter.events_head == len(emitter.events) { + return true + } + var accumulate int + switch emitter.events[emitter.events_head].typ { + case yaml_DOCUMENT_START_EVENT: + accumulate = 1 + break + case yaml_SEQUENCE_START_EVENT: + accumulate = 2 + break + case yaml_MAPPING_START_EVENT: + accumulate = 3 + break + default: + return false + } + if len(emitter.events)-emitter.events_head > accumulate { + return false + } + var level int + for i := emitter.events_head; i < len(emitter.events); i++ { + switch emitter.events[i].typ { + case yaml_STREAM_START_EVENT, yaml_DOCUMENT_START_EVENT, yaml_SEQUENCE_START_EVENT, yaml_MAPPING_START_EVENT: + level++ + case yaml_STREAM_END_EVENT, yaml_DOCUMENT_END_EVENT, yaml_SEQUENCE_END_EVENT, yaml_MAPPING_END_EVENT: + level-- + } + if level == 0 { + return false + } + } + return true +} + +// Append a directive to the directives stack. +func yaml_emitter_append_tag_directive(emitter *yaml_emitter_t, value *yaml_tag_directive_t, allow_duplicates bool) bool { + for i := 0; i < len(emitter.tag_directives); i++ { + if bytes.Equal(value.handle, emitter.tag_directives[i].handle) { + if allow_duplicates { + return true + } + return yaml_emitter_set_emitter_error(emitter, "duplicate %TAG directive") + } + } + + // [Go] Do we actually need to copy this given garbage collection + // and the lack of deallocating destructors? + tag_copy := yaml_tag_directive_t{ + handle: make([]byte, len(value.handle)), + prefix: make([]byte, len(value.prefix)), + } + copy(tag_copy.handle, value.handle) + copy(tag_copy.prefix, value.prefix) + emitter.tag_directives = append(emitter.tag_directives, tag_copy) + return true +} + +// Increase the indentation level. +func yaml_emitter_increase_indent(emitter *yaml_emitter_t, flow, indentless bool) bool { + emitter.indents = append(emitter.indents, emitter.indent) + if emitter.indent < 0 { + if flow { + emitter.indent = emitter.best_indent + } else { + emitter.indent = 0 + } + } else if !indentless { + emitter.indent += emitter.best_indent + } + return true +} + +// State dispatcher. +func yaml_emitter_state_machine(emitter *yaml_emitter_t, event *yaml_event_t) bool { + switch emitter.state { + default: + case yaml_EMIT_STREAM_START_STATE: + return yaml_emitter_emit_stream_start(emitter, event) + + case yaml_EMIT_FIRST_DOCUMENT_START_STATE: + return yaml_emitter_emit_document_start(emitter, event, true) + + case yaml_EMIT_DOCUMENT_START_STATE: + return yaml_emitter_emit_document_start(emitter, event, false) + + case yaml_EMIT_DOCUMENT_CONTENT_STATE: + return yaml_emitter_emit_document_content(emitter, event) + + case yaml_EMIT_DOCUMENT_END_STATE: + return yaml_emitter_emit_document_end(emitter, event) + + case yaml_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE: + return yaml_emitter_emit_flow_sequence_item(emitter, event, true) + + case yaml_EMIT_FLOW_SEQUENCE_ITEM_STATE: + return yaml_emitter_emit_flow_sequence_item(emitter, event, false) + + case yaml_EMIT_FLOW_MAPPING_FIRST_KEY_STATE: + return yaml_emitter_emit_flow_mapping_key(emitter, event, true) + + case yaml_EMIT_FLOW_MAPPING_KEY_STATE: + return yaml_emitter_emit_flow_mapping_key(emitter, event, false) + + case yaml_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE: + return yaml_emitter_emit_flow_mapping_value(emitter, event, true) + + case yaml_EMIT_FLOW_MAPPING_VALUE_STATE: + return yaml_emitter_emit_flow_mapping_value(emitter, event, false) + + case yaml_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE: + return yaml_emitter_emit_block_sequence_item(emitter, event, true) + + case yaml_EMIT_BLOCK_SEQUENCE_ITEM_STATE: + return yaml_emitter_emit_block_sequence_item(emitter, event, false) + + case yaml_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE: + return yaml_emitter_emit_block_mapping_key(emitter, event, true) + + case yaml_EMIT_BLOCK_MAPPING_KEY_STATE: + return yaml_emitter_emit_block_mapping_key(emitter, event, false) + + case yaml_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE: + return yaml_emitter_emit_block_mapping_value(emitter, event, true) + + case yaml_EMIT_BLOCK_MAPPING_VALUE_STATE: + return yaml_emitter_emit_block_mapping_value(emitter, event, false) + + case yaml_EMIT_END_STATE: + return yaml_emitter_set_emitter_error(emitter, "expected nothing after STREAM-END") + } + panic("invalid emitter state") +} + +// Expect STREAM-START. +func yaml_emitter_emit_stream_start(emitter *yaml_emitter_t, event *yaml_event_t) bool { + if event.typ != yaml_STREAM_START_EVENT { + return yaml_emitter_set_emitter_error(emitter, "expected STREAM-START") + } + if emitter.encoding == yaml_ANY_ENCODING { + emitter.encoding = event.encoding + if emitter.encoding == yaml_ANY_ENCODING { + emitter.encoding = yaml_UTF8_ENCODING + } + } + if emitter.best_indent < 2 || emitter.best_indent > 9 { + emitter.best_indent = 2 + } + if emitter.best_width >= 0 && emitter.best_width <= emitter.best_indent*2 { + emitter.best_width = 80 + } + if emitter.best_width < 0 { + emitter.best_width = 1<<31 - 1 + } + if emitter.line_break == yaml_ANY_BREAK { + emitter.line_break = yaml_LN_BREAK + } + + emitter.indent = -1 + emitter.line = 0 + emitter.column = 0 + emitter.whitespace = true + emitter.indention = true + + if emitter.encoding != yaml_UTF8_ENCODING { + if !yaml_emitter_write_bom(emitter) { + return false + } + } + emitter.state = yaml_EMIT_FIRST_DOCUMENT_START_STATE + return true +} + +// Expect DOCUMENT-START or STREAM-END. +func yaml_emitter_emit_document_start(emitter *yaml_emitter_t, event *yaml_event_t, first bool) bool { + + if event.typ == yaml_DOCUMENT_START_EVENT { + + if event.version_directive != nil { + if !yaml_emitter_analyze_version_directive(emitter, event.version_directive) { + return false + } + } + + for i := 0; i < len(event.tag_directives); i++ { + tag_directive := &event.tag_directives[i] + if !yaml_emitter_analyze_tag_directive(emitter, tag_directive) { + return false + } + if !yaml_emitter_append_tag_directive(emitter, tag_directive, false) { + return false + } + } + + for i := 0; i < len(default_tag_directives); i++ { + tag_directive := &default_tag_directives[i] + if !yaml_emitter_append_tag_directive(emitter, tag_directive, true) { + return false + } + } + + implicit := event.implicit + if !first || emitter.canonical { + implicit = false + } + + if emitter.open_ended && (event.version_directive != nil || len(event.tag_directives) > 0) { + if !yaml_emitter_write_indicator(emitter, []byte("..."), true, false, false) { + return false + } + if !yaml_emitter_write_indent(emitter) { + return false + } + } + + if event.version_directive != nil { + implicit = false + if !yaml_emitter_write_indicator(emitter, []byte("%YAML"), true, false, false) { + return false + } + if !yaml_emitter_write_indicator(emitter, []byte("1.1"), true, false, false) { + return false + } + if !yaml_emitter_write_indent(emitter) { + return false + } + } + + if len(event.tag_directives) > 0 { + implicit = false + for i := 0; i < len(event.tag_directives); i++ { + tag_directive := &event.tag_directives[i] + if !yaml_emitter_write_indicator(emitter, []byte("%TAG"), true, false, false) { + return false + } + if !yaml_emitter_write_tag_handle(emitter, tag_directive.handle) { + return false + } + if !yaml_emitter_write_tag_content(emitter, tag_directive.prefix, true) { + return false + } + if !yaml_emitter_write_indent(emitter) { + return false + } + } + } + + if yaml_emitter_check_empty_document(emitter) { + implicit = false + } + if !implicit { + if !yaml_emitter_write_indent(emitter) { + return false + } + if !yaml_emitter_write_indicator(emitter, []byte("---"), true, false, false) { + return false + } + if emitter.canonical { + if !yaml_emitter_write_indent(emitter) { + return false + } + } + } + + emitter.state = yaml_EMIT_DOCUMENT_CONTENT_STATE + return true + } + + if event.typ == yaml_STREAM_END_EVENT { + if emitter.open_ended { + if !yaml_emitter_write_indicator(emitter, []byte("..."), true, false, false) { + return false + } + if !yaml_emitter_write_indent(emitter) { + return false + } + } + if !yaml_emitter_flush(emitter) { + return false + } + emitter.state = yaml_EMIT_END_STATE + return true + } + + return yaml_emitter_set_emitter_error(emitter, "expected DOCUMENT-START or STREAM-END") +} + +// Expect the root node. +func yaml_emitter_emit_document_content(emitter *yaml_emitter_t, event *yaml_event_t) bool { + emitter.states = append(emitter.states, yaml_EMIT_DOCUMENT_END_STATE) + return yaml_emitter_emit_node(emitter, event, true, false, false, false) +} + +// Expect DOCUMENT-END. +func yaml_emitter_emit_document_end(emitter *yaml_emitter_t, event *yaml_event_t) bool { + if event.typ != yaml_DOCUMENT_END_EVENT { + return yaml_emitter_set_emitter_error(emitter, "expected DOCUMENT-END") + } + if !yaml_emitter_write_indent(emitter) { + return false + } + if !event.implicit { + // [Go] Allocate the slice elsewhere. + if !yaml_emitter_write_indicator(emitter, []byte("..."), true, false, false) { + return false + } + if !yaml_emitter_write_indent(emitter) { + return false + } + } + if !yaml_emitter_flush(emitter) { + return false + } + emitter.state = yaml_EMIT_DOCUMENT_START_STATE + emitter.tag_directives = emitter.tag_directives[:0] + return true +} + +// Expect a flow item node. +func yaml_emitter_emit_flow_sequence_item(emitter *yaml_emitter_t, event *yaml_event_t, first bool) bool { + if first { + if !yaml_emitter_write_indicator(emitter, []byte{'['}, true, true, false) { + return false + } + if !yaml_emitter_increase_indent(emitter, true, false) { + return false + } + emitter.flow_level++ + } + + if event.typ == yaml_SEQUENCE_END_EVENT { + emitter.flow_level-- + emitter.indent = emitter.indents[len(emitter.indents)-1] + emitter.indents = emitter.indents[:len(emitter.indents)-1] + if emitter.canonical && !first { + if !yaml_emitter_write_indicator(emitter, []byte{','}, false, false, false) { + return false + } + if !yaml_emitter_write_indent(emitter) { + return false + } + } + if !yaml_emitter_write_indicator(emitter, []byte{']'}, false, false, false) { + return false + } + emitter.state = emitter.states[len(emitter.states)-1] + emitter.states = emitter.states[:len(emitter.states)-1] + + return true + } + + if !first { + if !yaml_emitter_write_indicator(emitter, []byte{','}, false, false, false) { + return false + } + } + + if emitter.canonical || emitter.column > emitter.best_width { + if !yaml_emitter_write_indent(emitter) { + return false + } + } + emitter.states = append(emitter.states, yaml_EMIT_FLOW_SEQUENCE_ITEM_STATE) + return yaml_emitter_emit_node(emitter, event, false, true, false, false) +} + +// Expect a flow key node. +func yaml_emitter_emit_flow_mapping_key(emitter *yaml_emitter_t, event *yaml_event_t, first bool) bool { + if first { + if !yaml_emitter_write_indicator(emitter, []byte{'{'}, true, true, false) { + return false + } + if !yaml_emitter_increase_indent(emitter, true, false) { + return false + } + emitter.flow_level++ + } + + if event.typ == yaml_MAPPING_END_EVENT { + emitter.flow_level-- + emitter.indent = emitter.indents[len(emitter.indents)-1] + emitter.indents = emitter.indents[:len(emitter.indents)-1] + if emitter.canonical && !first { + if !yaml_emitter_write_indicator(emitter, []byte{','}, false, false, false) { + return false + } + if !yaml_emitter_write_indent(emitter) { + return false + } + } + if !yaml_emitter_write_indicator(emitter, []byte{'}'}, false, false, false) { + return false + } + emitter.state = emitter.states[len(emitter.states)-1] + emitter.states = emitter.states[:len(emitter.states)-1] + return true + } + + if !first { + if !yaml_emitter_write_indicator(emitter, []byte{','}, false, false, false) { + return false + } + } + if emitter.canonical || emitter.column > emitter.best_width { + if !yaml_emitter_write_indent(emitter) { + return false + } + } + + if !emitter.canonical && yaml_emitter_check_simple_key(emitter) { + emitter.states = append(emitter.states, yaml_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE) + return yaml_emitter_emit_node(emitter, event, false, false, true, true) + } + if !yaml_emitter_write_indicator(emitter, []byte{'?'}, true, false, false) { + return false + } + emitter.states = append(emitter.states, yaml_EMIT_FLOW_MAPPING_VALUE_STATE) + return yaml_emitter_emit_node(emitter, event, false, false, true, false) +} + +// Expect a flow value node. +func yaml_emitter_emit_flow_mapping_value(emitter *yaml_emitter_t, event *yaml_event_t, simple bool) bool { + if simple { + if !yaml_emitter_write_indicator(emitter, []byte{':'}, false, false, false) { + return false + } + } else { + if emitter.canonical || emitter.column > emitter.best_width { + if !yaml_emitter_write_indent(emitter) { + return false + } + } + if !yaml_emitter_write_indicator(emitter, []byte{':'}, true, false, false) { + return false + } + } + emitter.states = append(emitter.states, yaml_EMIT_FLOW_MAPPING_KEY_STATE) + return yaml_emitter_emit_node(emitter, event, false, false, true, false) +} + +// Expect a block item node. +func yaml_emitter_emit_block_sequence_item(emitter *yaml_emitter_t, event *yaml_event_t, first bool) bool { + if first { + if !yaml_emitter_increase_indent(emitter, false, emitter.mapping_context && !emitter.indention) { + return false + } + } + if event.typ == yaml_SEQUENCE_END_EVENT { + emitter.indent = emitter.indents[len(emitter.indents)-1] + emitter.indents = emitter.indents[:len(emitter.indents)-1] + emitter.state = emitter.states[len(emitter.states)-1] + emitter.states = emitter.states[:len(emitter.states)-1] + return true + } + if !yaml_emitter_write_indent(emitter) { + return false + } + if !yaml_emitter_write_indicator(emitter, []byte{'-'}, true, false, true) { + return false + } + emitter.states = append(emitter.states, yaml_EMIT_BLOCK_SEQUENCE_ITEM_STATE) + return yaml_emitter_emit_node(emitter, event, false, true, false, false) +} + +// Expect a block key node. +func yaml_emitter_emit_block_mapping_key(emitter *yaml_emitter_t, event *yaml_event_t, first bool) bool { + if first { + if !yaml_emitter_increase_indent(emitter, false, false) { + return false + } + } + if event.typ == yaml_MAPPING_END_EVENT { + emitter.indent = emitter.indents[len(emitter.indents)-1] + emitter.indents = emitter.indents[:len(emitter.indents)-1] + emitter.state = emitter.states[len(emitter.states)-1] + emitter.states = emitter.states[:len(emitter.states)-1] + return true + } + if !yaml_emitter_write_indent(emitter) { + return false + } + if yaml_emitter_check_simple_key(emitter) { + emitter.states = append(emitter.states, yaml_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE) + return yaml_emitter_emit_node(emitter, event, false, false, true, true) + } + if !yaml_emitter_write_indicator(emitter, []byte{'?'}, true, false, true) { + return false + } + emitter.states = append(emitter.states, yaml_EMIT_BLOCK_MAPPING_VALUE_STATE) + return yaml_emitter_emit_node(emitter, event, false, false, true, false) +} + +// Expect a block value node. +func yaml_emitter_emit_block_mapping_value(emitter *yaml_emitter_t, event *yaml_event_t, simple bool) bool { + if simple { + if !yaml_emitter_write_indicator(emitter, []byte{':'}, false, false, false) { + return false + } + } else { + if !yaml_emitter_write_indent(emitter) { + return false + } + if !yaml_emitter_write_indicator(emitter, []byte{':'}, true, false, true) { + return false + } + } + emitter.states = append(emitter.states, yaml_EMIT_BLOCK_MAPPING_KEY_STATE) + return yaml_emitter_emit_node(emitter, event, false, false, true, false) +} + +// Expect a node. +func yaml_emitter_emit_node(emitter *yaml_emitter_t, event *yaml_event_t, + root bool, sequence bool, mapping bool, simple_key bool) bool { + + emitter.root_context = root + emitter.sequence_context = sequence + emitter.mapping_context = mapping + emitter.simple_key_context = simple_key + + switch event.typ { + case yaml_ALIAS_EVENT: + return yaml_emitter_emit_alias(emitter, event) + case yaml_SCALAR_EVENT: + return yaml_emitter_emit_scalar(emitter, event) + case yaml_SEQUENCE_START_EVENT: + return yaml_emitter_emit_sequence_start(emitter, event) + case yaml_MAPPING_START_EVENT: + return yaml_emitter_emit_mapping_start(emitter, event) + default: + return yaml_emitter_set_emitter_error(emitter, + "expected SCALAR, SEQUENCE-START, MAPPING-START, or ALIAS") + } + return false +} + +// Expect ALIAS. +func yaml_emitter_emit_alias(emitter *yaml_emitter_t, event *yaml_event_t) bool { + if !yaml_emitter_process_anchor(emitter) { + return false + } + emitter.state = emitter.states[len(emitter.states)-1] + emitter.states = emitter.states[:len(emitter.states)-1] + return true +} + +// Expect SCALAR. +func yaml_emitter_emit_scalar(emitter *yaml_emitter_t, event *yaml_event_t) bool { + if !yaml_emitter_select_scalar_style(emitter, event) { + return false + } + if !yaml_emitter_process_anchor(emitter) { + return false + } + if !yaml_emitter_process_tag(emitter) { + return false + } + if !yaml_emitter_increase_indent(emitter, true, false) { + return false + } + if !yaml_emitter_process_scalar(emitter) { + return false + } + emitter.indent = emitter.indents[len(emitter.indents)-1] + emitter.indents = emitter.indents[:len(emitter.indents)-1] + emitter.state = emitter.states[len(emitter.states)-1] + emitter.states = emitter.states[:len(emitter.states)-1] + return true +} + +// Expect SEQUENCE-START. +func yaml_emitter_emit_sequence_start(emitter *yaml_emitter_t, event *yaml_event_t) bool { + if !yaml_emitter_process_anchor(emitter) { + return false + } + if !yaml_emitter_process_tag(emitter) { + return false + } + if emitter.flow_level > 0 || emitter.canonical || event.sequence_style() == yaml_FLOW_SEQUENCE_STYLE || + yaml_emitter_check_empty_sequence(emitter) { + emitter.state = yaml_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE + } else { + emitter.state = yaml_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE + } + return true +} + +// Expect MAPPING-START. +func yaml_emitter_emit_mapping_start(emitter *yaml_emitter_t, event *yaml_event_t) bool { + if !yaml_emitter_process_anchor(emitter) { + return false + } + if !yaml_emitter_process_tag(emitter) { + return false + } + if emitter.flow_level > 0 || emitter.canonical || event.mapping_style() == yaml_FLOW_MAPPING_STYLE || + yaml_emitter_check_empty_mapping(emitter) { + emitter.state = yaml_EMIT_FLOW_MAPPING_FIRST_KEY_STATE + } else { + emitter.state = yaml_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE + } + return true +} + +// Check if the document content is an empty scalar. +func yaml_emitter_check_empty_document(emitter *yaml_emitter_t) bool { + return false // [Go] Huh? +} + +// Check if the next events represent an empty sequence. +func yaml_emitter_check_empty_sequence(emitter *yaml_emitter_t) bool { + if len(emitter.events)-emitter.events_head < 2 { + return false + } + return emitter.events[emitter.events_head].typ == yaml_SEQUENCE_START_EVENT && + emitter.events[emitter.events_head+1].typ == yaml_SEQUENCE_END_EVENT +} + +// Check if the next events represent an empty mapping. +func yaml_emitter_check_empty_mapping(emitter *yaml_emitter_t) bool { + if len(emitter.events)-emitter.events_head < 2 { + return false + } + return emitter.events[emitter.events_head].typ == yaml_MAPPING_START_EVENT && + emitter.events[emitter.events_head+1].typ == yaml_MAPPING_END_EVENT +} + +// Check if the next node can be expressed as a simple key. +func yaml_emitter_check_simple_key(emitter *yaml_emitter_t) bool { + length := 0 + switch emitter.events[emitter.events_head].typ { + case yaml_ALIAS_EVENT: + length += len(emitter.anchor_data.anchor) + case yaml_SCALAR_EVENT: + if emitter.scalar_data.multiline { + return false + } + length += len(emitter.anchor_data.anchor) + + len(emitter.tag_data.handle) + + len(emitter.tag_data.suffix) + + len(emitter.scalar_data.value) + case yaml_SEQUENCE_START_EVENT: + if !yaml_emitter_check_empty_sequence(emitter) { + return false + } + length += len(emitter.anchor_data.anchor) + + len(emitter.tag_data.handle) + + len(emitter.tag_data.suffix) + case yaml_MAPPING_START_EVENT: + if !yaml_emitter_check_empty_mapping(emitter) { + return false + } + length += len(emitter.anchor_data.anchor) + + len(emitter.tag_data.handle) + + len(emitter.tag_data.suffix) + default: + return false + } + return length <= 128 +} + +// Determine an acceptable scalar style. +func yaml_emitter_select_scalar_style(emitter *yaml_emitter_t, event *yaml_event_t) bool { + + no_tag := len(emitter.tag_data.handle) == 0 && len(emitter.tag_data.suffix) == 0 + if no_tag && !event.implicit && !event.quoted_implicit { + return yaml_emitter_set_emitter_error(emitter, "neither tag nor implicit flags are specified") + } + + style := event.scalar_style() + if style == yaml_ANY_SCALAR_STYLE { + style = yaml_PLAIN_SCALAR_STYLE + } + if emitter.canonical { + style = yaml_DOUBLE_QUOTED_SCALAR_STYLE + } + if emitter.simple_key_context && emitter.scalar_data.multiline { + style = yaml_DOUBLE_QUOTED_SCALAR_STYLE + } + + if style == yaml_PLAIN_SCALAR_STYLE { + if emitter.flow_level > 0 && !emitter.scalar_data.flow_plain_allowed || + emitter.flow_level == 0 && !emitter.scalar_data.block_plain_allowed { + style = yaml_SINGLE_QUOTED_SCALAR_STYLE + } + if len(emitter.scalar_data.value) == 0 && (emitter.flow_level > 0 || emitter.simple_key_context) { + style = yaml_SINGLE_QUOTED_SCALAR_STYLE + } + if no_tag && !event.implicit { + style = yaml_SINGLE_QUOTED_SCALAR_STYLE + } + } + if style == yaml_SINGLE_QUOTED_SCALAR_STYLE { + if !emitter.scalar_data.single_quoted_allowed { + style = yaml_DOUBLE_QUOTED_SCALAR_STYLE + } + } + if style == yaml_LITERAL_SCALAR_STYLE || style == yaml_FOLDED_SCALAR_STYLE { + if !emitter.scalar_data.block_allowed || emitter.flow_level > 0 || emitter.simple_key_context { + style = yaml_DOUBLE_QUOTED_SCALAR_STYLE + } + } + + if no_tag && !event.quoted_implicit && style != yaml_PLAIN_SCALAR_STYLE { + emitter.tag_data.handle = []byte{'!'} + } + emitter.scalar_data.style = style + return true +} + +// Write an achor. +func yaml_emitter_process_anchor(emitter *yaml_emitter_t) bool { + if emitter.anchor_data.anchor == nil { + return true + } + c := []byte{'&'} + if emitter.anchor_data.alias { + c[0] = '*' + } + if !yaml_emitter_write_indicator(emitter, c, true, false, false) { + return false + } + return yaml_emitter_write_anchor(emitter, emitter.anchor_data.anchor) +} + +// Write a tag. +func yaml_emitter_process_tag(emitter *yaml_emitter_t) bool { + if len(emitter.tag_data.handle) == 0 && len(emitter.tag_data.suffix) == 0 { + return true + } + if len(emitter.tag_data.handle) > 0 { + if !yaml_emitter_write_tag_handle(emitter, emitter.tag_data.handle) { + return false + } + if len(emitter.tag_data.suffix) > 0 { + if !yaml_emitter_write_tag_content(emitter, emitter.tag_data.suffix, false) { + return false + } + } + } else { + // [Go] Allocate these slices elsewhere. + if !yaml_emitter_write_indicator(emitter, []byte("!<"), true, false, false) { + return false + } + if !yaml_emitter_write_tag_content(emitter, emitter.tag_data.suffix, false) { + return false + } + if !yaml_emitter_write_indicator(emitter, []byte{'>'}, false, false, false) { + return false + } + } + return true +} + +// Write a scalar. +func yaml_emitter_process_scalar(emitter *yaml_emitter_t) bool { + switch emitter.scalar_data.style { + case yaml_PLAIN_SCALAR_STYLE: + return yaml_emitter_write_plain_scalar(emitter, emitter.scalar_data.value, !emitter.simple_key_context) + + case yaml_SINGLE_QUOTED_SCALAR_STYLE: + return yaml_emitter_write_single_quoted_scalar(emitter, emitter.scalar_data.value, !emitter.simple_key_context) + + case yaml_DOUBLE_QUOTED_SCALAR_STYLE: + return yaml_emitter_write_double_quoted_scalar(emitter, emitter.scalar_data.value, !emitter.simple_key_context) + + case yaml_LITERAL_SCALAR_STYLE: + return yaml_emitter_write_literal_scalar(emitter, emitter.scalar_data.value) + + case yaml_FOLDED_SCALAR_STYLE: + return yaml_emitter_write_folded_scalar(emitter, emitter.scalar_data.value) + } + panic("unknown scalar style") +} + +// Check if a %YAML directive is valid. +func yaml_emitter_analyze_version_directive(emitter *yaml_emitter_t, version_directive *yaml_version_directive_t) bool { + if version_directive.major != 1 || version_directive.minor != 1 { + return yaml_emitter_set_emitter_error(emitter, "incompatible %YAML directive") + } + return true +} + +// Check if a %TAG directive is valid. +func yaml_emitter_analyze_tag_directive(emitter *yaml_emitter_t, tag_directive *yaml_tag_directive_t) bool { + handle := tag_directive.handle + prefix := tag_directive.prefix + if len(handle) == 0 { + return yaml_emitter_set_emitter_error(emitter, "tag handle must not be empty") + } + if handle[0] != '!' { + return yaml_emitter_set_emitter_error(emitter, "tag handle must start with '!'") + } + if handle[len(handle)-1] != '!' { + return yaml_emitter_set_emitter_error(emitter, "tag handle must end with '!'") + } + for i := 1; i < len(handle)-1; i += width(handle[i]) { + if !is_alpha(handle, i) { + return yaml_emitter_set_emitter_error(emitter, "tag handle must contain alphanumerical characters only") + } + } + if len(prefix) == 0 { + return yaml_emitter_set_emitter_error(emitter, "tag prefix must not be empty") + } + return true +} + +// Check if an anchor is valid. +func yaml_emitter_analyze_anchor(emitter *yaml_emitter_t, anchor []byte, alias bool) bool { + if len(anchor) == 0 { + problem := "anchor value must not be empty" + if alias { + problem = "alias value must not be empty" + } + return yaml_emitter_set_emitter_error(emitter, problem) + } + for i := 0; i < len(anchor); i += width(anchor[i]) { + if !is_alpha(anchor, i) { + problem := "anchor value must contain alphanumerical characters only" + if alias { + problem = "alias value must contain alphanumerical characters only" + } + return yaml_emitter_set_emitter_error(emitter, problem) + } + } + emitter.anchor_data.anchor = anchor + emitter.anchor_data.alias = alias + return true +} + +// Check if a tag is valid. +func yaml_emitter_analyze_tag(emitter *yaml_emitter_t, tag []byte) bool { + if len(tag) == 0 { + return yaml_emitter_set_emitter_error(emitter, "tag value must not be empty") + } + for i := 0; i < len(emitter.tag_directives); i++ { + tag_directive := &emitter.tag_directives[i] + if bytes.HasPrefix(tag, tag_directive.prefix) { + emitter.tag_data.handle = tag_directive.handle + emitter.tag_data.suffix = tag[len(tag_directive.prefix):] + return true + } + } + emitter.tag_data.suffix = tag + return true +} + +// Check if a scalar is valid. +func yaml_emitter_analyze_scalar(emitter *yaml_emitter_t, value []byte) bool { + var ( + block_indicators = false + flow_indicators = false + line_breaks = false + special_characters = false + + leading_space = false + leading_break = false + trailing_space = false + trailing_break = false + break_space = false + space_break = false + + preceeded_by_whitespace = false + followed_by_whitespace = false + previous_space = false + previous_break = false + ) + + emitter.scalar_data.value = value + + if len(value) == 0 { + emitter.scalar_data.multiline = false + emitter.scalar_data.flow_plain_allowed = false + emitter.scalar_data.block_plain_allowed = true + emitter.scalar_data.single_quoted_allowed = true + emitter.scalar_data.block_allowed = false + return true + } + + if len(value) >= 3 && ((value[0] == '-' && value[1] == '-' && value[2] == '-') || (value[0] == '.' && value[1] == '.' && value[2] == '.')) { + block_indicators = true + flow_indicators = true + } + + preceeded_by_whitespace = true + for i, w := 0, 0; i < len(value); i += w { + w = width(value[i]) + followed_by_whitespace = i+w >= len(value) || is_blank(value, i+w) + + if i == 0 { + switch value[i] { + case '#', ',', '[', ']', '{', '}', '&', '*', '!', '|', '>', '\'', '"', '%', '@', '`': + flow_indicators = true + block_indicators = true + case '?', ':': + flow_indicators = true + if followed_by_whitespace { + block_indicators = true + } + case '-': + if followed_by_whitespace { + flow_indicators = true + block_indicators = true + } + } + } else { + switch value[i] { + case ',', '?', '[', ']', '{', '}': + flow_indicators = true + case ':': + flow_indicators = true + if followed_by_whitespace { + block_indicators = true + } + case '#': + if preceeded_by_whitespace { + flow_indicators = true + block_indicators = true + } + } + } + + if !is_printable(value, i) || !is_ascii(value, i) && !emitter.unicode { + special_characters = true + } + if is_space(value, i) { + if i == 0 { + leading_space = true + } + if i+width(value[i]) == len(value) { + trailing_space = true + } + if previous_break { + break_space = true + } + previous_space = true + previous_break = false + } else if is_break(value, i) { + line_breaks = true + if i == 0 { + leading_break = true + } + if i+width(value[i]) == len(value) { + trailing_break = true + } + if previous_space { + space_break = true + } + previous_space = false + previous_break = true + } else { + previous_space = false + previous_break = false + } + + // [Go]: Why 'z'? Couldn't be the end of the string as that's the loop condition. + preceeded_by_whitespace = is_blankz(value, i) + } + + emitter.scalar_data.multiline = line_breaks + emitter.scalar_data.flow_plain_allowed = true + emitter.scalar_data.block_plain_allowed = true + emitter.scalar_data.single_quoted_allowed = true + emitter.scalar_data.block_allowed = true + + if leading_space || leading_break || trailing_space || trailing_break { + emitter.scalar_data.flow_plain_allowed = false + emitter.scalar_data.block_plain_allowed = false + } + if trailing_space { + emitter.scalar_data.block_allowed = false + } + if break_space { + emitter.scalar_data.flow_plain_allowed = false + emitter.scalar_data.block_plain_allowed = false + emitter.scalar_data.single_quoted_allowed = false + } + if space_break || special_characters { + emitter.scalar_data.flow_plain_allowed = false + emitter.scalar_data.block_plain_allowed = false + emitter.scalar_data.single_quoted_allowed = false + emitter.scalar_data.block_allowed = false + } + if line_breaks { + emitter.scalar_data.flow_plain_allowed = false + emitter.scalar_data.block_plain_allowed = false + } + if flow_indicators { + emitter.scalar_data.flow_plain_allowed = false + } + if block_indicators { + emitter.scalar_data.block_plain_allowed = false + } + return true +} + +// Check if the event data is valid. +func yaml_emitter_analyze_event(emitter *yaml_emitter_t, event *yaml_event_t) bool { + + emitter.anchor_data.anchor = nil + emitter.tag_data.handle = nil + emitter.tag_data.suffix = nil + emitter.scalar_data.value = nil + + switch event.typ { + case yaml_ALIAS_EVENT: + if !yaml_emitter_analyze_anchor(emitter, event.anchor, true) { + return false + } + + case yaml_SCALAR_EVENT: + if len(event.anchor) > 0 { + if !yaml_emitter_analyze_anchor(emitter, event.anchor, false) { + return false + } + } + if len(event.tag) > 0 && (emitter.canonical || (!event.implicit && !event.quoted_implicit)) { + if !yaml_emitter_analyze_tag(emitter, event.tag) { + return false + } + } + if !yaml_emitter_analyze_scalar(emitter, event.value) { + return false + } + + case yaml_SEQUENCE_START_EVENT: + if len(event.anchor) > 0 { + if !yaml_emitter_analyze_anchor(emitter, event.anchor, false) { + return false + } + } + if len(event.tag) > 0 && (emitter.canonical || !event.implicit) { + if !yaml_emitter_analyze_tag(emitter, event.tag) { + return false + } + } + + case yaml_MAPPING_START_EVENT: + if len(event.anchor) > 0 { + if !yaml_emitter_analyze_anchor(emitter, event.anchor, false) { + return false + } + } + if len(event.tag) > 0 && (emitter.canonical || !event.implicit) { + if !yaml_emitter_analyze_tag(emitter, event.tag) { + return false + } + } + } + return true +} + +// Write the BOM character. +func yaml_emitter_write_bom(emitter *yaml_emitter_t) bool { + if !flush(emitter) { + return false + } + pos := emitter.buffer_pos + emitter.buffer[pos+0] = '\xEF' + emitter.buffer[pos+1] = '\xBB' + emitter.buffer[pos+2] = '\xBF' + emitter.buffer_pos += 3 + return true +} + +func yaml_emitter_write_indent(emitter *yaml_emitter_t) bool { + indent := emitter.indent + if indent < 0 { + indent = 0 + } + if !emitter.indention || emitter.column > indent || (emitter.column == indent && !emitter.whitespace) { + if !put_break(emitter) { + return false + } + } + for emitter.column < indent { + if !put(emitter, ' ') { + return false + } + } + emitter.whitespace = true + emitter.indention = true + return true +} + +func yaml_emitter_write_indicator(emitter *yaml_emitter_t, indicator []byte, need_whitespace, is_whitespace, is_indention bool) bool { + if need_whitespace && !emitter.whitespace { + if !put(emitter, ' ') { + return false + } + } + if !write_all(emitter, indicator) { + return false + } + emitter.whitespace = is_whitespace + emitter.indention = (emitter.indention && is_indention) + emitter.open_ended = false + return true +} + +func yaml_emitter_write_anchor(emitter *yaml_emitter_t, value []byte) bool { + if !write_all(emitter, value) { + return false + } + emitter.whitespace = false + emitter.indention = false + return true +} + +func yaml_emitter_write_tag_handle(emitter *yaml_emitter_t, value []byte) bool { + if !emitter.whitespace { + if !put(emitter, ' ') { + return false + } + } + if !write_all(emitter, value) { + return false + } + emitter.whitespace = false + emitter.indention = false + return true +} + +func yaml_emitter_write_tag_content(emitter *yaml_emitter_t, value []byte, need_whitespace bool) bool { + if need_whitespace && !emitter.whitespace { + if !put(emitter, ' ') { + return false + } + } + for i := 0; i < len(value); { + var must_write bool + switch value[i] { + case ';', '/', '?', ':', '@', '&', '=', '+', '$', ',', '_', '.', '~', '*', '\'', '(', ')', '[', ']': + must_write = true + default: + must_write = is_alpha(value, i) + } + if must_write { + if !write(emitter, value, &i) { + return false + } + } else { + w := width(value[i]) + for k := 0; k < w; k++ { + octet := value[i] + i++ + if !put(emitter, '%') { + return false + } + + c := octet >> 4 + if c < 10 { + c += '0' + } else { + c += 'A' - 10 + } + if !put(emitter, c) { + return false + } + + c = octet & 0x0f + if c < 10 { + c += '0' + } else { + c += 'A' - 10 + } + if !put(emitter, c) { + return false + } + } + } + } + emitter.whitespace = false + emitter.indention = false + return true +} + +func yaml_emitter_write_plain_scalar(emitter *yaml_emitter_t, value []byte, allow_breaks bool) bool { + if !emitter.whitespace { + if !put(emitter, ' ') { + return false + } + } + + spaces := false + breaks := false + for i := 0; i < len(value); { + if is_space(value, i) { + if allow_breaks && !spaces && emitter.column > emitter.best_width && !is_space(value, i+1) { + if !yaml_emitter_write_indent(emitter) { + return false + } + i += width(value[i]) + } else { + if !write(emitter, value, &i) { + return false + } + } + spaces = true + } else if is_break(value, i) { + if !breaks && value[i] == '\n' { + if !put_break(emitter) { + return false + } + } + if !write_break(emitter, value, &i) { + return false + } + emitter.indention = true + breaks = true + } else { + if breaks { + if !yaml_emitter_write_indent(emitter) { + return false + } + } + if !write(emitter, value, &i) { + return false + } + emitter.indention = false + spaces = false + breaks = false + } + } + + emitter.whitespace = false + emitter.indention = false + if emitter.root_context { + emitter.open_ended = true + } + + return true +} + +func yaml_emitter_write_single_quoted_scalar(emitter *yaml_emitter_t, value []byte, allow_breaks bool) bool { + + if !yaml_emitter_write_indicator(emitter, []byte{'\''}, true, false, false) { + return false + } + + spaces := false + breaks := false + for i := 0; i < len(value); { + if is_space(value, i) { + if allow_breaks && !spaces && emitter.column > emitter.best_width && i > 0 && i < len(value)-1 && !is_space(value, i+1) { + if !yaml_emitter_write_indent(emitter) { + return false + } + i += width(value[i]) + } else { + if !write(emitter, value, &i) { + return false + } + } + spaces = true + } else if is_break(value, i) { + if !breaks && value[i] == '\n' { + if !put_break(emitter) { + return false + } + } + if !write_break(emitter, value, &i) { + return false + } + emitter.indention = true + breaks = true + } else { + if breaks { + if !yaml_emitter_write_indent(emitter) { + return false + } + } + if value[i] == '\'' { + if !put(emitter, '\'') { + return false + } + } + if !write(emitter, value, &i) { + return false + } + emitter.indention = false + spaces = false + breaks = false + } + } + if !yaml_emitter_write_indicator(emitter, []byte{'\''}, false, false, false) { + return false + } + emitter.whitespace = false + emitter.indention = false + return true +} + +func yaml_emitter_write_double_quoted_scalar(emitter *yaml_emitter_t, value []byte, allow_breaks bool) bool { + spaces := false + if !yaml_emitter_write_indicator(emitter, []byte{'"'}, true, false, false) { + return false + } + + for i := 0; i < len(value); { + if !is_printable(value, i) || (!emitter.unicode && !is_ascii(value, i)) || + is_bom(value, i) || is_break(value, i) || + value[i] == '"' || value[i] == '\\' { + + octet := value[i] + + var w int + var v rune + switch { + case octet&0x80 == 0x00: + w, v = 1, rune(octet&0x7F) + case octet&0xE0 == 0xC0: + w, v = 2, rune(octet&0x1F) + case octet&0xF0 == 0xE0: + w, v = 3, rune(octet&0x0F) + case octet&0xF8 == 0xF0: + w, v = 4, rune(octet&0x07) + } + for k := 1; k < w; k++ { + octet = value[i+k] + v = (v << 6) + (rune(octet) & 0x3F) + } + i += w + + if !put(emitter, '\\') { + return false + } + + var ok bool + switch v { + case 0x00: + ok = put(emitter, '0') + case 0x07: + ok = put(emitter, 'a') + case 0x08: + ok = put(emitter, 'b') + case 0x09: + ok = put(emitter, 't') + case 0x0A: + ok = put(emitter, 'n') + case 0x0b: + ok = put(emitter, 'v') + case 0x0c: + ok = put(emitter, 'f') + case 0x0d: + ok = put(emitter, 'r') + case 0x1b: + ok = put(emitter, 'e') + case 0x22: + ok = put(emitter, '"') + case 0x5c: + ok = put(emitter, '\\') + case 0x85: + ok = put(emitter, 'N') + case 0xA0: + ok = put(emitter, '_') + case 0x2028: + ok = put(emitter, 'L') + case 0x2029: + ok = put(emitter, 'P') + default: + if v <= 0xFF { + ok = put(emitter, 'x') + w = 2 + } else if v <= 0xFFFF { + ok = put(emitter, 'u') + w = 4 + } else { + ok = put(emitter, 'U') + w = 8 + } + for k := (w - 1) * 4; ok && k >= 0; k -= 4 { + digit := byte((v >> uint(k)) & 0x0F) + if digit < 10 { + ok = put(emitter, digit+'0') + } else { + ok = put(emitter, digit+'A'-10) + } + } + } + if !ok { + return false + } + spaces = false + } else if is_space(value, i) { + if allow_breaks && !spaces && emitter.column > emitter.best_width && i > 0 && i < len(value)-1 { + if !yaml_emitter_write_indent(emitter) { + return false + } + if is_space(value, i+1) { + if !put(emitter, '\\') { + return false + } + } + i += width(value[i]) + } else if !write(emitter, value, &i) { + return false + } + spaces = true + } else { + if !write(emitter, value, &i) { + return false + } + spaces = false + } + } + if !yaml_emitter_write_indicator(emitter, []byte{'"'}, false, false, false) { + return false + } + emitter.whitespace = false + emitter.indention = false + return true +} + +func yaml_emitter_write_block_scalar_hints(emitter *yaml_emitter_t, value []byte) bool { + if is_space(value, 0) || is_break(value, 0) { + indent_hint := []byte{'0' + byte(emitter.best_indent)} + if !yaml_emitter_write_indicator(emitter, indent_hint, false, false, false) { + return false + } + } + + emitter.open_ended = false + + var chomp_hint [1]byte + if len(value) == 0 { + chomp_hint[0] = '-' + } else { + i := len(value) - 1 + for value[i]&0xC0 == 0x80 { + i-- + } + if !is_break(value, i) { + chomp_hint[0] = '-' + } else if i == 0 { + chomp_hint[0] = '+' + emitter.open_ended = true + } else { + i-- + for value[i]&0xC0 == 0x80 { + i-- + } + if is_break(value, i) { + chomp_hint[0] = '+' + emitter.open_ended = true + } + } + } + if chomp_hint[0] != 0 { + if !yaml_emitter_write_indicator(emitter, chomp_hint[:], false, false, false) { + return false + } + } + return true +} + +func yaml_emitter_write_literal_scalar(emitter *yaml_emitter_t, value []byte) bool { + if !yaml_emitter_write_indicator(emitter, []byte{'|'}, true, false, false) { + return false + } + if !yaml_emitter_write_block_scalar_hints(emitter, value) { + return false + } + if !put_break(emitter) { + return false + } + emitter.indention = true + emitter.whitespace = true + breaks := true + for i := 0; i < len(value); { + if is_break(value, i) { + if !write_break(emitter, value, &i) { + return false + } + emitter.indention = true + breaks = true + } else { + if breaks { + if !yaml_emitter_write_indent(emitter) { + return false + } + } + if !write(emitter, value, &i) { + return false + } + emitter.indention = false + breaks = false + } + } + + return true +} + +func yaml_emitter_write_folded_scalar(emitter *yaml_emitter_t, value []byte) bool { + if !yaml_emitter_write_indicator(emitter, []byte{'>'}, true, false, false) { + return false + } + if !yaml_emitter_write_block_scalar_hints(emitter, value) { + return false + } + + if !put_break(emitter) { + return false + } + emitter.indention = true + emitter.whitespace = true + + breaks := true + leading_spaces := true + for i := 0; i < len(value); { + if is_break(value, i) { + if !breaks && !leading_spaces && value[i] == '\n' { + k := 0 + for is_break(value, k) { + k += width(value[k]) + } + if !is_blankz(value, k) { + if !put_break(emitter) { + return false + } + } + } + if !write_break(emitter, value, &i) { + return false + } + emitter.indention = true + breaks = true + } else { + if breaks { + if !yaml_emitter_write_indent(emitter) { + return false + } + leading_spaces = is_blank(value, i) + } + if !breaks && is_space(value, i) && !is_space(value, i+1) && emitter.column > emitter.best_width { + if !yaml_emitter_write_indent(emitter) { + return false + } + i += width(value[i]) + } else { + if !write(emitter, value, &i) { + return false + } + } + emitter.indention = false + breaks = false + } + } + return true +} diff --git a/vendor/gopkg.in/yaml.v2/encode.go b/vendor/gopkg.in/yaml.v2/encode.go new file mode 100644 index 0000000..84f8499 --- /dev/null +++ b/vendor/gopkg.in/yaml.v2/encode.go @@ -0,0 +1,306 @@ +package yaml + +import ( + "encoding" + "fmt" + "reflect" + "regexp" + "sort" + "strconv" + "strings" + "time" +) + +type encoder struct { + emitter yaml_emitter_t + event yaml_event_t + out []byte + flow bool +} + +func newEncoder() (e *encoder) { + e = &encoder{} + e.must(yaml_emitter_initialize(&e.emitter)) + yaml_emitter_set_output_string(&e.emitter, &e.out) + yaml_emitter_set_unicode(&e.emitter, true) + e.must(yaml_stream_start_event_initialize(&e.event, yaml_UTF8_ENCODING)) + e.emit() + e.must(yaml_document_start_event_initialize(&e.event, nil, nil, true)) + e.emit() + return e +} + +func (e *encoder) finish() { + e.must(yaml_document_end_event_initialize(&e.event, true)) + e.emit() + e.emitter.open_ended = false + e.must(yaml_stream_end_event_initialize(&e.event)) + e.emit() +} + +func (e *encoder) destroy() { + yaml_emitter_delete(&e.emitter) +} + +func (e *encoder) emit() { + // This will internally delete the e.event value. + if !yaml_emitter_emit(&e.emitter, &e.event) && e.event.typ != yaml_DOCUMENT_END_EVENT && e.event.typ != yaml_STREAM_END_EVENT { + e.must(false) + } +} + +func (e *encoder) must(ok bool) { + if !ok { + msg := e.emitter.problem + if msg == "" { + msg = "unknown problem generating YAML content" + } + failf("%s", msg) + } +} + +func (e *encoder) marshal(tag string, in reflect.Value) { + if !in.IsValid() { + e.nilv() + return + } + iface := in.Interface() + if m, ok := iface.(Marshaler); ok { + v, err := m.MarshalYAML() + if err != nil { + fail(err) + } + if v == nil { + e.nilv() + return + } + in = reflect.ValueOf(v) + } else if m, ok := iface.(encoding.TextMarshaler); ok { + text, err := m.MarshalText() + if err != nil { + fail(err) + } + in = reflect.ValueOf(string(text)) + } + switch in.Kind() { + case reflect.Interface: + if in.IsNil() { + e.nilv() + } else { + e.marshal(tag, in.Elem()) + } + case reflect.Map: + e.mapv(tag, in) + case reflect.Ptr: + if in.IsNil() { + e.nilv() + } else { + e.marshal(tag, in.Elem()) + } + case reflect.Struct: + e.structv(tag, in) + case reflect.Slice: + if in.Type().Elem() == mapItemType { + e.itemsv(tag, in) + } else { + e.slicev(tag, in) + } + case reflect.String: + e.stringv(tag, in) + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + if in.Type() == durationType { + e.stringv(tag, reflect.ValueOf(iface.(time.Duration).String())) + } else { + e.intv(tag, in) + } + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + e.uintv(tag, in) + case reflect.Float32, reflect.Float64: + e.floatv(tag, in) + case reflect.Bool: + e.boolv(tag, in) + default: + panic("cannot marshal type: " + in.Type().String()) + } +} + +func (e *encoder) mapv(tag string, in reflect.Value) { + e.mappingv(tag, func() { + keys := keyList(in.MapKeys()) + sort.Sort(keys) + for _, k := range keys { + e.marshal("", k) + e.marshal("", in.MapIndex(k)) + } + }) +} + +func (e *encoder) itemsv(tag string, in reflect.Value) { + e.mappingv(tag, func() { + slice := in.Convert(reflect.TypeOf([]MapItem{})).Interface().([]MapItem) + for _, item := range slice { + e.marshal("", reflect.ValueOf(item.Key)) + e.marshal("", reflect.ValueOf(item.Value)) + } + }) +} + +func (e *encoder) structv(tag string, in reflect.Value) { + sinfo, err := getStructInfo(in.Type()) + if err != nil { + panic(err) + } + e.mappingv(tag, func() { + for _, info := range sinfo.FieldsList { + var value reflect.Value + if info.Inline == nil { + value = in.Field(info.Num) + } else { + value = in.FieldByIndex(info.Inline) + } + if info.OmitEmpty && isZero(value) { + continue + } + e.marshal("", reflect.ValueOf(info.Key)) + e.flow = info.Flow + e.marshal("", value) + } + if sinfo.InlineMap >= 0 { + m := in.Field(sinfo.InlineMap) + if m.Len() > 0 { + e.flow = false + keys := keyList(m.MapKeys()) + sort.Sort(keys) + for _, k := range keys { + if _, found := sinfo.FieldsMap[k.String()]; found { + panic(fmt.Sprintf("Can't have key %q in inlined map; conflicts with struct field", k.String())) + } + e.marshal("", k) + e.flow = false + e.marshal("", m.MapIndex(k)) + } + } + } + }) +} + +func (e *encoder) mappingv(tag string, f func()) { + implicit := tag == "" + style := yaml_BLOCK_MAPPING_STYLE + if e.flow { + e.flow = false + style = yaml_FLOW_MAPPING_STYLE + } + e.must(yaml_mapping_start_event_initialize(&e.event, nil, []byte(tag), implicit, style)) + e.emit() + f() + e.must(yaml_mapping_end_event_initialize(&e.event)) + e.emit() +} + +func (e *encoder) slicev(tag string, in reflect.Value) { + implicit := tag == "" + style := yaml_BLOCK_SEQUENCE_STYLE + if e.flow { + e.flow = false + style = yaml_FLOW_SEQUENCE_STYLE + } + e.must(yaml_sequence_start_event_initialize(&e.event, nil, []byte(tag), implicit, style)) + e.emit() + n := in.Len() + for i := 0; i < n; i++ { + e.marshal("", in.Index(i)) + } + e.must(yaml_sequence_end_event_initialize(&e.event)) + e.emit() +} + +// isBase60 returns whether s is in base 60 notation as defined in YAML 1.1. +// +// The base 60 float notation in YAML 1.1 is a terrible idea and is unsupported +// in YAML 1.2 and by this package, but these should be marshalled quoted for +// the time being for compatibility with other parsers. +func isBase60Float(s string) (result bool) { + // Fast path. + if s == "" { + return false + } + c := s[0] + if !(c == '+' || c == '-' || c >= '0' && c <= '9') || strings.IndexByte(s, ':') < 0 { + return false + } + // Do the full match. + return base60float.MatchString(s) +} + +// From http://yaml.org/type/float.html, except the regular expression there +// is bogus. In practice parsers do not enforce the "\.[0-9_]*" suffix. +var base60float = regexp.MustCompile(`^[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+(?:\.[0-9_]*)?$`) + +func (e *encoder) stringv(tag string, in reflect.Value) { + var style yaml_scalar_style_t + s := in.String() + rtag, rs := resolve("", s) + if rtag == yaml_BINARY_TAG { + if tag == "" || tag == yaml_STR_TAG { + tag = rtag + s = rs.(string) + } else if tag == yaml_BINARY_TAG { + failf("explicitly tagged !!binary data must be base64-encoded") + } else { + failf("cannot marshal invalid UTF-8 data as %s", shortTag(tag)) + } + } + if tag == "" && (rtag != yaml_STR_TAG || isBase60Float(s)) { + style = yaml_DOUBLE_QUOTED_SCALAR_STYLE + } else if strings.Contains(s, "\n") { + style = yaml_LITERAL_SCALAR_STYLE + } else { + style = yaml_PLAIN_SCALAR_STYLE + } + e.emitScalar(s, "", tag, style) +} + +func (e *encoder) boolv(tag string, in reflect.Value) { + var s string + if in.Bool() { + s = "true" + } else { + s = "false" + } + e.emitScalar(s, "", tag, yaml_PLAIN_SCALAR_STYLE) +} + +func (e *encoder) intv(tag string, in reflect.Value) { + s := strconv.FormatInt(in.Int(), 10) + e.emitScalar(s, "", tag, yaml_PLAIN_SCALAR_STYLE) +} + +func (e *encoder) uintv(tag string, in reflect.Value) { + s := strconv.FormatUint(in.Uint(), 10) + e.emitScalar(s, "", tag, yaml_PLAIN_SCALAR_STYLE) +} + +func (e *encoder) floatv(tag string, in reflect.Value) { + // FIXME: Handle 64 bits here. + s := strconv.FormatFloat(float64(in.Float()), 'g', -1, 32) + switch s { + case "+Inf": + s = ".inf" + case "-Inf": + s = "-.inf" + case "NaN": + s = ".nan" + } + e.emitScalar(s, "", tag, yaml_PLAIN_SCALAR_STYLE) +} + +func (e *encoder) nilv() { + e.emitScalar("null", "", "", yaml_PLAIN_SCALAR_STYLE) +} + +func (e *encoder) emitScalar(value, anchor, tag string, style yaml_scalar_style_t) { + implicit := tag == "" + e.must(yaml_scalar_event_initialize(&e.event, []byte(anchor), []byte(tag), []byte(value), implicit, implicit, style)) + e.emit() +} diff --git a/vendor/gopkg.in/yaml.v2/parserc.go b/vendor/gopkg.in/yaml.v2/parserc.go new file mode 100644 index 0000000..0a7037a --- /dev/null +++ b/vendor/gopkg.in/yaml.v2/parserc.go @@ -0,0 +1,1096 @@ +package yaml + +import ( + "bytes" +) + +// The parser implements the following grammar: +// +// stream ::= STREAM-START implicit_document? explicit_document* STREAM-END +// implicit_document ::= block_node DOCUMENT-END* +// explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END* +// block_node_or_indentless_sequence ::= +// ALIAS +// | properties (block_content | indentless_block_sequence)? +// | block_content +// | indentless_block_sequence +// block_node ::= ALIAS +// | properties block_content? +// | block_content +// flow_node ::= ALIAS +// | properties flow_content? +// | flow_content +// properties ::= TAG ANCHOR? | ANCHOR TAG? +// block_content ::= block_collection | flow_collection | SCALAR +// flow_content ::= flow_collection | SCALAR +// block_collection ::= block_sequence | block_mapping +// flow_collection ::= flow_sequence | flow_mapping +// block_sequence ::= BLOCK-SEQUENCE-START (BLOCK-ENTRY block_node?)* BLOCK-END +// indentless_sequence ::= (BLOCK-ENTRY block_node?)+ +// block_mapping ::= BLOCK-MAPPING_START +// ((KEY block_node_or_indentless_sequence?)? +// (VALUE block_node_or_indentless_sequence?)?)* +// BLOCK-END +// flow_sequence ::= FLOW-SEQUENCE-START +// (flow_sequence_entry FLOW-ENTRY)* +// flow_sequence_entry? +// FLOW-SEQUENCE-END +// flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? +// flow_mapping ::= FLOW-MAPPING-START +// (flow_mapping_entry FLOW-ENTRY)* +// flow_mapping_entry? +// FLOW-MAPPING-END +// flow_mapping_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? + +// Peek the next token in the token queue. +func peek_token(parser *yaml_parser_t) *yaml_token_t { + if parser.token_available || yaml_parser_fetch_more_tokens(parser) { + return &parser.tokens[parser.tokens_head] + } + return nil +} + +// Remove the next token from the queue (must be called after peek_token). +func skip_token(parser *yaml_parser_t) { + parser.token_available = false + parser.tokens_parsed++ + parser.stream_end_produced = parser.tokens[parser.tokens_head].typ == yaml_STREAM_END_TOKEN + parser.tokens_head++ +} + +// Get the next event. +func yaml_parser_parse(parser *yaml_parser_t, event *yaml_event_t) bool { + // Erase the event object. + *event = yaml_event_t{} + + // No events after the end of the stream or error. + if parser.stream_end_produced || parser.error != yaml_NO_ERROR || parser.state == yaml_PARSE_END_STATE { + return true + } + + // Generate the next event. + return yaml_parser_state_machine(parser, event) +} + +// Set parser error. +func yaml_parser_set_parser_error(parser *yaml_parser_t, problem string, problem_mark yaml_mark_t) bool { + parser.error = yaml_PARSER_ERROR + parser.problem = problem + parser.problem_mark = problem_mark + return false +} + +func yaml_parser_set_parser_error_context(parser *yaml_parser_t, context string, context_mark yaml_mark_t, problem string, problem_mark yaml_mark_t) bool { + parser.error = yaml_PARSER_ERROR + parser.context = context + parser.context_mark = context_mark + parser.problem = problem + parser.problem_mark = problem_mark + return false +} + +// State dispatcher. +func yaml_parser_state_machine(parser *yaml_parser_t, event *yaml_event_t) bool { + //trace("yaml_parser_state_machine", "state:", parser.state.String()) + + switch parser.state { + case yaml_PARSE_STREAM_START_STATE: + return yaml_parser_parse_stream_start(parser, event) + + case yaml_PARSE_IMPLICIT_DOCUMENT_START_STATE: + return yaml_parser_parse_document_start(parser, event, true) + + case yaml_PARSE_DOCUMENT_START_STATE: + return yaml_parser_parse_document_start(parser, event, false) + + case yaml_PARSE_DOCUMENT_CONTENT_STATE: + return yaml_parser_parse_document_content(parser, event) + + case yaml_PARSE_DOCUMENT_END_STATE: + return yaml_parser_parse_document_end(parser, event) + + case yaml_PARSE_BLOCK_NODE_STATE: + return yaml_parser_parse_node(parser, event, true, false) + + case yaml_PARSE_BLOCK_NODE_OR_INDENTLESS_SEQUENCE_STATE: + return yaml_parser_parse_node(parser, event, true, true) + + case yaml_PARSE_FLOW_NODE_STATE: + return yaml_parser_parse_node(parser, event, false, false) + + case yaml_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE: + return yaml_parser_parse_block_sequence_entry(parser, event, true) + + case yaml_PARSE_BLOCK_SEQUENCE_ENTRY_STATE: + return yaml_parser_parse_block_sequence_entry(parser, event, false) + + case yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE: + return yaml_parser_parse_indentless_sequence_entry(parser, event) + + case yaml_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE: + return yaml_parser_parse_block_mapping_key(parser, event, true) + + case yaml_PARSE_BLOCK_MAPPING_KEY_STATE: + return yaml_parser_parse_block_mapping_key(parser, event, false) + + case yaml_PARSE_BLOCK_MAPPING_VALUE_STATE: + return yaml_parser_parse_block_mapping_value(parser, event) + + case yaml_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE: + return yaml_parser_parse_flow_sequence_entry(parser, event, true) + + case yaml_PARSE_FLOW_SEQUENCE_ENTRY_STATE: + return yaml_parser_parse_flow_sequence_entry(parser, event, false) + + case yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE: + return yaml_parser_parse_flow_sequence_entry_mapping_key(parser, event) + + case yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE: + return yaml_parser_parse_flow_sequence_entry_mapping_value(parser, event) + + case yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE: + return yaml_parser_parse_flow_sequence_entry_mapping_end(parser, event) + + case yaml_PARSE_FLOW_MAPPING_FIRST_KEY_STATE: + return yaml_parser_parse_flow_mapping_key(parser, event, true) + + case yaml_PARSE_FLOW_MAPPING_KEY_STATE: + return yaml_parser_parse_flow_mapping_key(parser, event, false) + + case yaml_PARSE_FLOW_MAPPING_VALUE_STATE: + return yaml_parser_parse_flow_mapping_value(parser, event, false) + + case yaml_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE: + return yaml_parser_parse_flow_mapping_value(parser, event, true) + + default: + panic("invalid parser state") + } + return false +} + +// Parse the production: +// stream ::= STREAM-START implicit_document? explicit_document* STREAM-END +// ************ +func yaml_parser_parse_stream_start(parser *yaml_parser_t, event *yaml_event_t) bool { + token := peek_token(parser) + if token == nil { + return false + } + if token.typ != yaml_STREAM_START_TOKEN { + return yaml_parser_set_parser_error(parser, "did not find expected ", token.start_mark) + } + parser.state = yaml_PARSE_IMPLICIT_DOCUMENT_START_STATE + *event = yaml_event_t{ + typ: yaml_STREAM_START_EVENT, + start_mark: token.start_mark, + end_mark: token.end_mark, + encoding: token.encoding, + } + skip_token(parser) + return true +} + +// Parse the productions: +// implicit_document ::= block_node DOCUMENT-END* +// * +// explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END* +// ************************* +func yaml_parser_parse_document_start(parser *yaml_parser_t, event *yaml_event_t, implicit bool) bool { + + token := peek_token(parser) + if token == nil { + return false + } + + // Parse extra document end indicators. + if !implicit { + for token.typ == yaml_DOCUMENT_END_TOKEN { + skip_token(parser) + token = peek_token(parser) + if token == nil { + return false + } + } + } + + if implicit && token.typ != yaml_VERSION_DIRECTIVE_TOKEN && + token.typ != yaml_TAG_DIRECTIVE_TOKEN && + token.typ != yaml_DOCUMENT_START_TOKEN && + token.typ != yaml_STREAM_END_TOKEN { + // Parse an implicit document. + if !yaml_parser_process_directives(parser, nil, nil) { + return false + } + parser.states = append(parser.states, yaml_PARSE_DOCUMENT_END_STATE) + parser.state = yaml_PARSE_BLOCK_NODE_STATE + + *event = yaml_event_t{ + typ: yaml_DOCUMENT_START_EVENT, + start_mark: token.start_mark, + end_mark: token.end_mark, + } + + } else if token.typ != yaml_STREAM_END_TOKEN { + // Parse an explicit document. + var version_directive *yaml_version_directive_t + var tag_directives []yaml_tag_directive_t + start_mark := token.start_mark + if !yaml_parser_process_directives(parser, &version_directive, &tag_directives) { + return false + } + token = peek_token(parser) + if token == nil { + return false + } + if token.typ != yaml_DOCUMENT_START_TOKEN { + yaml_parser_set_parser_error(parser, + "did not find expected ", token.start_mark) + return false + } + parser.states = append(parser.states, yaml_PARSE_DOCUMENT_END_STATE) + parser.state = yaml_PARSE_DOCUMENT_CONTENT_STATE + end_mark := token.end_mark + + *event = yaml_event_t{ + typ: yaml_DOCUMENT_START_EVENT, + start_mark: start_mark, + end_mark: end_mark, + version_directive: version_directive, + tag_directives: tag_directives, + implicit: false, + } + skip_token(parser) + + } else { + // Parse the stream end. + parser.state = yaml_PARSE_END_STATE + *event = yaml_event_t{ + typ: yaml_STREAM_END_EVENT, + start_mark: token.start_mark, + end_mark: token.end_mark, + } + skip_token(parser) + } + + return true +} + +// Parse the productions: +// explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END* +// *********** +// +func yaml_parser_parse_document_content(parser *yaml_parser_t, event *yaml_event_t) bool { + token := peek_token(parser) + if token == nil { + return false + } + if token.typ == yaml_VERSION_DIRECTIVE_TOKEN || + token.typ == yaml_TAG_DIRECTIVE_TOKEN || + token.typ == yaml_DOCUMENT_START_TOKEN || + token.typ == yaml_DOCUMENT_END_TOKEN || + token.typ == yaml_STREAM_END_TOKEN { + parser.state = parser.states[len(parser.states)-1] + parser.states = parser.states[:len(parser.states)-1] + return yaml_parser_process_empty_scalar(parser, event, + token.start_mark) + } + return yaml_parser_parse_node(parser, event, true, false) +} + +// Parse the productions: +// implicit_document ::= block_node DOCUMENT-END* +// ************* +// explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END* +// +func yaml_parser_parse_document_end(parser *yaml_parser_t, event *yaml_event_t) bool { + token := peek_token(parser) + if token == nil { + return false + } + + start_mark := token.start_mark + end_mark := token.start_mark + + implicit := true + if token.typ == yaml_DOCUMENT_END_TOKEN { + end_mark = token.end_mark + skip_token(parser) + implicit = false + } + + parser.tag_directives = parser.tag_directives[:0] + + parser.state = yaml_PARSE_DOCUMENT_START_STATE + *event = yaml_event_t{ + typ: yaml_DOCUMENT_END_EVENT, + start_mark: start_mark, + end_mark: end_mark, + implicit: implicit, + } + return true +} + +// Parse the productions: +// block_node_or_indentless_sequence ::= +// ALIAS +// ***** +// | properties (block_content | indentless_block_sequence)? +// ********** * +// | block_content | indentless_block_sequence +// * +// block_node ::= ALIAS +// ***** +// | properties block_content? +// ********** * +// | block_content +// * +// flow_node ::= ALIAS +// ***** +// | properties flow_content? +// ********** * +// | flow_content +// * +// properties ::= TAG ANCHOR? | ANCHOR TAG? +// ************************* +// block_content ::= block_collection | flow_collection | SCALAR +// ****** +// flow_content ::= flow_collection | SCALAR +// ****** +func yaml_parser_parse_node(parser *yaml_parser_t, event *yaml_event_t, block, indentless_sequence bool) bool { + //defer trace("yaml_parser_parse_node", "block:", block, "indentless_sequence:", indentless_sequence)() + + token := peek_token(parser) + if token == nil { + return false + } + + if token.typ == yaml_ALIAS_TOKEN { + parser.state = parser.states[len(parser.states)-1] + parser.states = parser.states[:len(parser.states)-1] + *event = yaml_event_t{ + typ: yaml_ALIAS_EVENT, + start_mark: token.start_mark, + end_mark: token.end_mark, + anchor: token.value, + } + skip_token(parser) + return true + } + + start_mark := token.start_mark + end_mark := token.start_mark + + var tag_token bool + var tag_handle, tag_suffix, anchor []byte + var tag_mark yaml_mark_t + if token.typ == yaml_ANCHOR_TOKEN { + anchor = token.value + start_mark = token.start_mark + end_mark = token.end_mark + skip_token(parser) + token = peek_token(parser) + if token == nil { + return false + } + if token.typ == yaml_TAG_TOKEN { + tag_token = true + tag_handle = token.value + tag_suffix = token.suffix + tag_mark = token.start_mark + end_mark = token.end_mark + skip_token(parser) + token = peek_token(parser) + if token == nil { + return false + } + } + } else if token.typ == yaml_TAG_TOKEN { + tag_token = true + tag_handle = token.value + tag_suffix = token.suffix + start_mark = token.start_mark + tag_mark = token.start_mark + end_mark = token.end_mark + skip_token(parser) + token = peek_token(parser) + if token == nil { + return false + } + if token.typ == yaml_ANCHOR_TOKEN { + anchor = token.value + end_mark = token.end_mark + skip_token(parser) + token = peek_token(parser) + if token == nil { + return false + } + } + } + + var tag []byte + if tag_token { + if len(tag_handle) == 0 { + tag = tag_suffix + tag_suffix = nil + } else { + for i := range parser.tag_directives { + if bytes.Equal(parser.tag_directives[i].handle, tag_handle) { + tag = append([]byte(nil), parser.tag_directives[i].prefix...) + tag = append(tag, tag_suffix...) + break + } + } + if len(tag) == 0 { + yaml_parser_set_parser_error_context(parser, + "while parsing a node", start_mark, + "found undefined tag handle", tag_mark) + return false + } + } + } + + implicit := len(tag) == 0 + if indentless_sequence && token.typ == yaml_BLOCK_ENTRY_TOKEN { + end_mark = token.end_mark + parser.state = yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE + *event = yaml_event_t{ + typ: yaml_SEQUENCE_START_EVENT, + start_mark: start_mark, + end_mark: end_mark, + anchor: anchor, + tag: tag, + implicit: implicit, + style: yaml_style_t(yaml_BLOCK_SEQUENCE_STYLE), + } + return true + } + if token.typ == yaml_SCALAR_TOKEN { + var plain_implicit, quoted_implicit bool + end_mark = token.end_mark + if (len(tag) == 0 && token.style == yaml_PLAIN_SCALAR_STYLE) || (len(tag) == 1 && tag[0] == '!') { + plain_implicit = true + } else if len(tag) == 0 { + quoted_implicit = true + } + parser.state = parser.states[len(parser.states)-1] + parser.states = parser.states[:len(parser.states)-1] + + *event = yaml_event_t{ + typ: yaml_SCALAR_EVENT, + start_mark: start_mark, + end_mark: end_mark, + anchor: anchor, + tag: tag, + value: token.value, + implicit: plain_implicit, + quoted_implicit: quoted_implicit, + style: yaml_style_t(token.style), + } + skip_token(parser) + return true + } + if token.typ == yaml_FLOW_SEQUENCE_START_TOKEN { + // [Go] Some of the events below can be merged as they differ only on style. + end_mark = token.end_mark + parser.state = yaml_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE + *event = yaml_event_t{ + typ: yaml_SEQUENCE_START_EVENT, + start_mark: start_mark, + end_mark: end_mark, + anchor: anchor, + tag: tag, + implicit: implicit, + style: yaml_style_t(yaml_FLOW_SEQUENCE_STYLE), + } + return true + } + if token.typ == yaml_FLOW_MAPPING_START_TOKEN { + end_mark = token.end_mark + parser.state = yaml_PARSE_FLOW_MAPPING_FIRST_KEY_STATE + *event = yaml_event_t{ + typ: yaml_MAPPING_START_EVENT, + start_mark: start_mark, + end_mark: end_mark, + anchor: anchor, + tag: tag, + implicit: implicit, + style: yaml_style_t(yaml_FLOW_MAPPING_STYLE), + } + return true + } + if block && token.typ == yaml_BLOCK_SEQUENCE_START_TOKEN { + end_mark = token.end_mark + parser.state = yaml_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE + *event = yaml_event_t{ + typ: yaml_SEQUENCE_START_EVENT, + start_mark: start_mark, + end_mark: end_mark, + anchor: anchor, + tag: tag, + implicit: implicit, + style: yaml_style_t(yaml_BLOCK_SEQUENCE_STYLE), + } + return true + } + if block && token.typ == yaml_BLOCK_MAPPING_START_TOKEN { + end_mark = token.end_mark + parser.state = yaml_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE + *event = yaml_event_t{ + typ: yaml_MAPPING_START_EVENT, + start_mark: start_mark, + end_mark: end_mark, + anchor: anchor, + tag: tag, + implicit: implicit, + style: yaml_style_t(yaml_BLOCK_MAPPING_STYLE), + } + return true + } + if len(anchor) > 0 || len(tag) > 0 { + parser.state = parser.states[len(parser.states)-1] + parser.states = parser.states[:len(parser.states)-1] + + *event = yaml_event_t{ + typ: yaml_SCALAR_EVENT, + start_mark: start_mark, + end_mark: end_mark, + anchor: anchor, + tag: tag, + implicit: implicit, + quoted_implicit: false, + style: yaml_style_t(yaml_PLAIN_SCALAR_STYLE), + } + return true + } + + context := "while parsing a flow node" + if block { + context = "while parsing a block node" + } + yaml_parser_set_parser_error_context(parser, context, start_mark, + "did not find expected node content", token.start_mark) + return false +} + +// Parse the productions: +// block_sequence ::= BLOCK-SEQUENCE-START (BLOCK-ENTRY block_node?)* BLOCK-END +// ******************** *********** * ********* +// +func yaml_parser_parse_block_sequence_entry(parser *yaml_parser_t, event *yaml_event_t, first bool) bool { + if first { + token := peek_token(parser) + parser.marks = append(parser.marks, token.start_mark) + skip_token(parser) + } + + token := peek_token(parser) + if token == nil { + return false + } + + if token.typ == yaml_BLOCK_ENTRY_TOKEN { + mark := token.end_mark + skip_token(parser) + token = peek_token(parser) + if token == nil { + return false + } + if token.typ != yaml_BLOCK_ENTRY_TOKEN && token.typ != yaml_BLOCK_END_TOKEN { + parser.states = append(parser.states, yaml_PARSE_BLOCK_SEQUENCE_ENTRY_STATE) + return yaml_parser_parse_node(parser, event, true, false) + } else { + parser.state = yaml_PARSE_BLOCK_SEQUENCE_ENTRY_STATE + return yaml_parser_process_empty_scalar(parser, event, mark) + } + } + if token.typ == yaml_BLOCK_END_TOKEN { + parser.state = parser.states[len(parser.states)-1] + parser.states = parser.states[:len(parser.states)-1] + parser.marks = parser.marks[:len(parser.marks)-1] + + *event = yaml_event_t{ + typ: yaml_SEQUENCE_END_EVENT, + start_mark: token.start_mark, + end_mark: token.end_mark, + } + + skip_token(parser) + return true + } + + context_mark := parser.marks[len(parser.marks)-1] + parser.marks = parser.marks[:len(parser.marks)-1] + return yaml_parser_set_parser_error_context(parser, + "while parsing a block collection", context_mark, + "did not find expected '-' indicator", token.start_mark) +} + +// Parse the productions: +// indentless_sequence ::= (BLOCK-ENTRY block_node?)+ +// *********** * +func yaml_parser_parse_indentless_sequence_entry(parser *yaml_parser_t, event *yaml_event_t) bool { + token := peek_token(parser) + if token == nil { + return false + } + + if token.typ == yaml_BLOCK_ENTRY_TOKEN { + mark := token.end_mark + skip_token(parser) + token = peek_token(parser) + if token == nil { + return false + } + if token.typ != yaml_BLOCK_ENTRY_TOKEN && + token.typ != yaml_KEY_TOKEN && + token.typ != yaml_VALUE_TOKEN && + token.typ != yaml_BLOCK_END_TOKEN { + parser.states = append(parser.states, yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE) + return yaml_parser_parse_node(parser, event, true, false) + } + parser.state = yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE + return yaml_parser_process_empty_scalar(parser, event, mark) + } + parser.state = parser.states[len(parser.states)-1] + parser.states = parser.states[:len(parser.states)-1] + + *event = yaml_event_t{ + typ: yaml_SEQUENCE_END_EVENT, + start_mark: token.start_mark, + end_mark: token.start_mark, // [Go] Shouldn't this be token.end_mark? + } + return true +} + +// Parse the productions: +// block_mapping ::= BLOCK-MAPPING_START +// ******************* +// ((KEY block_node_or_indentless_sequence?)? +// *** * +// (VALUE block_node_or_indentless_sequence?)?)* +// +// BLOCK-END +// ********* +// +func yaml_parser_parse_block_mapping_key(parser *yaml_parser_t, event *yaml_event_t, first bool) bool { + if first { + token := peek_token(parser) + parser.marks = append(parser.marks, token.start_mark) + skip_token(parser) + } + + token := peek_token(parser) + if token == nil { + return false + } + + if token.typ == yaml_KEY_TOKEN { + mark := token.end_mark + skip_token(parser) + token = peek_token(parser) + if token == nil { + return false + } + if token.typ != yaml_KEY_TOKEN && + token.typ != yaml_VALUE_TOKEN && + token.typ != yaml_BLOCK_END_TOKEN { + parser.states = append(parser.states, yaml_PARSE_BLOCK_MAPPING_VALUE_STATE) + return yaml_parser_parse_node(parser, event, true, true) + } else { + parser.state = yaml_PARSE_BLOCK_MAPPING_VALUE_STATE + return yaml_parser_process_empty_scalar(parser, event, mark) + } + } else if token.typ == yaml_BLOCK_END_TOKEN { + parser.state = parser.states[len(parser.states)-1] + parser.states = parser.states[:len(parser.states)-1] + parser.marks = parser.marks[:len(parser.marks)-1] + *event = yaml_event_t{ + typ: yaml_MAPPING_END_EVENT, + start_mark: token.start_mark, + end_mark: token.end_mark, + } + skip_token(parser) + return true + } + + context_mark := parser.marks[len(parser.marks)-1] + parser.marks = parser.marks[:len(parser.marks)-1] + return yaml_parser_set_parser_error_context(parser, + "while parsing a block mapping", context_mark, + "did not find expected key", token.start_mark) +} + +// Parse the productions: +// block_mapping ::= BLOCK-MAPPING_START +// +// ((KEY block_node_or_indentless_sequence?)? +// +// (VALUE block_node_or_indentless_sequence?)?)* +// ***** * +// BLOCK-END +// +// +func yaml_parser_parse_block_mapping_value(parser *yaml_parser_t, event *yaml_event_t) bool { + token := peek_token(parser) + if token == nil { + return false + } + if token.typ == yaml_VALUE_TOKEN { + mark := token.end_mark + skip_token(parser) + token = peek_token(parser) + if token == nil { + return false + } + if token.typ != yaml_KEY_TOKEN && + token.typ != yaml_VALUE_TOKEN && + token.typ != yaml_BLOCK_END_TOKEN { + parser.states = append(parser.states, yaml_PARSE_BLOCK_MAPPING_KEY_STATE) + return yaml_parser_parse_node(parser, event, true, true) + } + parser.state = yaml_PARSE_BLOCK_MAPPING_KEY_STATE + return yaml_parser_process_empty_scalar(parser, event, mark) + } + parser.state = yaml_PARSE_BLOCK_MAPPING_KEY_STATE + return yaml_parser_process_empty_scalar(parser, event, token.start_mark) +} + +// Parse the productions: +// flow_sequence ::= FLOW-SEQUENCE-START +// ******************* +// (flow_sequence_entry FLOW-ENTRY)* +// * ********** +// flow_sequence_entry? +// * +// FLOW-SEQUENCE-END +// ***************** +// flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? +// * +// +func yaml_parser_parse_flow_sequence_entry(parser *yaml_parser_t, event *yaml_event_t, first bool) bool { + if first { + token := peek_token(parser) + parser.marks = append(parser.marks, token.start_mark) + skip_token(parser) + } + token := peek_token(parser) + if token == nil { + return false + } + if token.typ != yaml_FLOW_SEQUENCE_END_TOKEN { + if !first { + if token.typ == yaml_FLOW_ENTRY_TOKEN { + skip_token(parser) + token = peek_token(parser) + if token == nil { + return false + } + } else { + context_mark := parser.marks[len(parser.marks)-1] + parser.marks = parser.marks[:len(parser.marks)-1] + return yaml_parser_set_parser_error_context(parser, + "while parsing a flow sequence", context_mark, + "did not find expected ',' or ']'", token.start_mark) + } + } + + if token.typ == yaml_KEY_TOKEN { + parser.state = yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE + *event = yaml_event_t{ + typ: yaml_MAPPING_START_EVENT, + start_mark: token.start_mark, + end_mark: token.end_mark, + implicit: true, + style: yaml_style_t(yaml_FLOW_MAPPING_STYLE), + } + skip_token(parser) + return true + } else if token.typ != yaml_FLOW_SEQUENCE_END_TOKEN { + parser.states = append(parser.states, yaml_PARSE_FLOW_SEQUENCE_ENTRY_STATE) + return yaml_parser_parse_node(parser, event, false, false) + } + } + + parser.state = parser.states[len(parser.states)-1] + parser.states = parser.states[:len(parser.states)-1] + parser.marks = parser.marks[:len(parser.marks)-1] + + *event = yaml_event_t{ + typ: yaml_SEQUENCE_END_EVENT, + start_mark: token.start_mark, + end_mark: token.end_mark, + } + + skip_token(parser) + return true +} + +// +// Parse the productions: +// flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? +// *** * +// +func yaml_parser_parse_flow_sequence_entry_mapping_key(parser *yaml_parser_t, event *yaml_event_t) bool { + token := peek_token(parser) + if token == nil { + return false + } + if token.typ != yaml_VALUE_TOKEN && + token.typ != yaml_FLOW_ENTRY_TOKEN && + token.typ != yaml_FLOW_SEQUENCE_END_TOKEN { + parser.states = append(parser.states, yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE) + return yaml_parser_parse_node(parser, event, false, false) + } + mark := token.end_mark + skip_token(parser) + parser.state = yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE + return yaml_parser_process_empty_scalar(parser, event, mark) +} + +// Parse the productions: +// flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? +// ***** * +// +func yaml_parser_parse_flow_sequence_entry_mapping_value(parser *yaml_parser_t, event *yaml_event_t) bool { + token := peek_token(parser) + if token == nil { + return false + } + if token.typ == yaml_VALUE_TOKEN { + skip_token(parser) + token := peek_token(parser) + if token == nil { + return false + } + if token.typ != yaml_FLOW_ENTRY_TOKEN && token.typ != yaml_FLOW_SEQUENCE_END_TOKEN { + parser.states = append(parser.states, yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE) + return yaml_parser_parse_node(parser, event, false, false) + } + } + parser.state = yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE + return yaml_parser_process_empty_scalar(parser, event, token.start_mark) +} + +// Parse the productions: +// flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? +// * +// +func yaml_parser_parse_flow_sequence_entry_mapping_end(parser *yaml_parser_t, event *yaml_event_t) bool { + token := peek_token(parser) + if token == nil { + return false + } + parser.state = yaml_PARSE_FLOW_SEQUENCE_ENTRY_STATE + *event = yaml_event_t{ + typ: yaml_MAPPING_END_EVENT, + start_mark: token.start_mark, + end_mark: token.start_mark, // [Go] Shouldn't this be end_mark? + } + return true +} + +// Parse the productions: +// flow_mapping ::= FLOW-MAPPING-START +// ****************** +// (flow_mapping_entry FLOW-ENTRY)* +// * ********** +// flow_mapping_entry? +// ****************** +// FLOW-MAPPING-END +// **************** +// flow_mapping_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? +// * *** * +// +func yaml_parser_parse_flow_mapping_key(parser *yaml_parser_t, event *yaml_event_t, first bool) bool { + if first { + token := peek_token(parser) + parser.marks = append(parser.marks, token.start_mark) + skip_token(parser) + } + + token := peek_token(parser) + if token == nil { + return false + } + + if token.typ != yaml_FLOW_MAPPING_END_TOKEN { + if !first { + if token.typ == yaml_FLOW_ENTRY_TOKEN { + skip_token(parser) + token = peek_token(parser) + if token == nil { + return false + } + } else { + context_mark := parser.marks[len(parser.marks)-1] + parser.marks = parser.marks[:len(parser.marks)-1] + return yaml_parser_set_parser_error_context(parser, + "while parsing a flow mapping", context_mark, + "did not find expected ',' or '}'", token.start_mark) + } + } + + if token.typ == yaml_KEY_TOKEN { + skip_token(parser) + token = peek_token(parser) + if token == nil { + return false + } + if token.typ != yaml_VALUE_TOKEN && + token.typ != yaml_FLOW_ENTRY_TOKEN && + token.typ != yaml_FLOW_MAPPING_END_TOKEN { + parser.states = append(parser.states, yaml_PARSE_FLOW_MAPPING_VALUE_STATE) + return yaml_parser_parse_node(parser, event, false, false) + } else { + parser.state = yaml_PARSE_FLOW_MAPPING_VALUE_STATE + return yaml_parser_process_empty_scalar(parser, event, token.start_mark) + } + } else if token.typ != yaml_FLOW_MAPPING_END_TOKEN { + parser.states = append(parser.states, yaml_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE) + return yaml_parser_parse_node(parser, event, false, false) + } + } + + parser.state = parser.states[len(parser.states)-1] + parser.states = parser.states[:len(parser.states)-1] + parser.marks = parser.marks[:len(parser.marks)-1] + *event = yaml_event_t{ + typ: yaml_MAPPING_END_EVENT, + start_mark: token.start_mark, + end_mark: token.end_mark, + } + skip_token(parser) + return true +} + +// Parse the productions: +// flow_mapping_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? +// * ***** * +// +func yaml_parser_parse_flow_mapping_value(parser *yaml_parser_t, event *yaml_event_t, empty bool) bool { + token := peek_token(parser) + if token == nil { + return false + } + if empty { + parser.state = yaml_PARSE_FLOW_MAPPING_KEY_STATE + return yaml_parser_process_empty_scalar(parser, event, token.start_mark) + } + if token.typ == yaml_VALUE_TOKEN { + skip_token(parser) + token = peek_token(parser) + if token == nil { + return false + } + if token.typ != yaml_FLOW_ENTRY_TOKEN && token.typ != yaml_FLOW_MAPPING_END_TOKEN { + parser.states = append(parser.states, yaml_PARSE_FLOW_MAPPING_KEY_STATE) + return yaml_parser_parse_node(parser, event, false, false) + } + } + parser.state = yaml_PARSE_FLOW_MAPPING_KEY_STATE + return yaml_parser_process_empty_scalar(parser, event, token.start_mark) +} + +// Generate an empty scalar event. +func yaml_parser_process_empty_scalar(parser *yaml_parser_t, event *yaml_event_t, mark yaml_mark_t) bool { + *event = yaml_event_t{ + typ: yaml_SCALAR_EVENT, + start_mark: mark, + end_mark: mark, + value: nil, // Empty + implicit: true, + style: yaml_style_t(yaml_PLAIN_SCALAR_STYLE), + } + return true +} + +var default_tag_directives = []yaml_tag_directive_t{ + {[]byte("!"), []byte("!")}, + {[]byte("!!"), []byte("tag:yaml.org,2002:")}, +} + +// Parse directives. +func yaml_parser_process_directives(parser *yaml_parser_t, + version_directive_ref **yaml_version_directive_t, + tag_directives_ref *[]yaml_tag_directive_t) bool { + + var version_directive *yaml_version_directive_t + var tag_directives []yaml_tag_directive_t + + token := peek_token(parser) + if token == nil { + return false + } + + for token.typ == yaml_VERSION_DIRECTIVE_TOKEN || token.typ == yaml_TAG_DIRECTIVE_TOKEN { + if token.typ == yaml_VERSION_DIRECTIVE_TOKEN { + if version_directive != nil { + yaml_parser_set_parser_error(parser, + "found duplicate %YAML directive", token.start_mark) + return false + } + if token.major != 1 || token.minor != 1 { + yaml_parser_set_parser_error(parser, + "found incompatible YAML document", token.start_mark) + return false + } + version_directive = &yaml_version_directive_t{ + major: token.major, + minor: token.minor, + } + } else if token.typ == yaml_TAG_DIRECTIVE_TOKEN { + value := yaml_tag_directive_t{ + handle: token.value, + prefix: token.prefix, + } + if !yaml_parser_append_tag_directive(parser, value, false, token.start_mark) { + return false + } + tag_directives = append(tag_directives, value) + } + + skip_token(parser) + token = peek_token(parser) + if token == nil { + return false + } + } + + for i := range default_tag_directives { + if !yaml_parser_append_tag_directive(parser, default_tag_directives[i], true, token.start_mark) { + return false + } + } + + if version_directive_ref != nil { + *version_directive_ref = version_directive + } + if tag_directives_ref != nil { + *tag_directives_ref = tag_directives + } + return true +} + +// Append a tag directive to the directives stack. +func yaml_parser_append_tag_directive(parser *yaml_parser_t, value yaml_tag_directive_t, allow_duplicates bool, mark yaml_mark_t) bool { + for i := range parser.tag_directives { + if bytes.Equal(value.handle, parser.tag_directives[i].handle) { + if allow_duplicates { + return true + } + return yaml_parser_set_parser_error(parser, "found duplicate %TAG directive", mark) + } + } + + // [Go] I suspect the copy is unnecessary. This was likely done + // because there was no way to track ownership of the data. + value_copy := yaml_tag_directive_t{ + handle: make([]byte, len(value.handle)), + prefix: make([]byte, len(value.prefix)), + } + copy(value_copy.handle, value.handle) + copy(value_copy.prefix, value.prefix) + parser.tag_directives = append(parser.tag_directives, value_copy) + return true +} diff --git a/vendor/gopkg.in/yaml.v2/readerc.go b/vendor/gopkg.in/yaml.v2/readerc.go new file mode 100644 index 0000000..d5fb097 --- /dev/null +++ b/vendor/gopkg.in/yaml.v2/readerc.go @@ -0,0 +1,391 @@ +package yaml + +import ( + "io" +) + +// Set the reader error and return 0. +func yaml_parser_set_reader_error(parser *yaml_parser_t, problem string, offset int, value int) bool { + parser.error = yaml_READER_ERROR + parser.problem = problem + parser.problem_offset = offset + parser.problem_value = value + return false +} + +// Byte order marks. +const ( + bom_UTF8 = "\xef\xbb\xbf" + bom_UTF16LE = "\xff\xfe" + bom_UTF16BE = "\xfe\xff" +) + +// Determine the input stream encoding by checking the BOM symbol. If no BOM is +// found, the UTF-8 encoding is assumed. Return 1 on success, 0 on failure. +func yaml_parser_determine_encoding(parser *yaml_parser_t) bool { + // Ensure that we had enough bytes in the raw buffer. + for !parser.eof && len(parser.raw_buffer)-parser.raw_buffer_pos < 3 { + if !yaml_parser_update_raw_buffer(parser) { + return false + } + } + + // Determine the encoding. + buf := parser.raw_buffer + pos := parser.raw_buffer_pos + avail := len(buf) - pos + if avail >= 2 && buf[pos] == bom_UTF16LE[0] && buf[pos+1] == bom_UTF16LE[1] { + parser.encoding = yaml_UTF16LE_ENCODING + parser.raw_buffer_pos += 2 + parser.offset += 2 + } else if avail >= 2 && buf[pos] == bom_UTF16BE[0] && buf[pos+1] == bom_UTF16BE[1] { + parser.encoding = yaml_UTF16BE_ENCODING + parser.raw_buffer_pos += 2 + parser.offset += 2 + } else if avail >= 3 && buf[pos] == bom_UTF8[0] && buf[pos+1] == bom_UTF8[1] && buf[pos+2] == bom_UTF8[2] { + parser.encoding = yaml_UTF8_ENCODING + parser.raw_buffer_pos += 3 + parser.offset += 3 + } else { + parser.encoding = yaml_UTF8_ENCODING + } + return true +} + +// Update the raw buffer. +func yaml_parser_update_raw_buffer(parser *yaml_parser_t) bool { + size_read := 0 + + // Return if the raw buffer is full. + if parser.raw_buffer_pos == 0 && len(parser.raw_buffer) == cap(parser.raw_buffer) { + return true + } + + // Return on EOF. + if parser.eof { + return true + } + + // Move the remaining bytes in the raw buffer to the beginning. + if parser.raw_buffer_pos > 0 && parser.raw_buffer_pos < len(parser.raw_buffer) { + copy(parser.raw_buffer, parser.raw_buffer[parser.raw_buffer_pos:]) + } + parser.raw_buffer = parser.raw_buffer[:len(parser.raw_buffer)-parser.raw_buffer_pos] + parser.raw_buffer_pos = 0 + + // Call the read handler to fill the buffer. + size_read, err := parser.read_handler(parser, parser.raw_buffer[len(parser.raw_buffer):cap(parser.raw_buffer)]) + parser.raw_buffer = parser.raw_buffer[:len(parser.raw_buffer)+size_read] + if err == io.EOF { + parser.eof = true + } else if err != nil { + return yaml_parser_set_reader_error(parser, "input error: "+err.Error(), parser.offset, -1) + } + return true +} + +// Ensure that the buffer contains at least `length` characters. +// Return true on success, false on failure. +// +// The length is supposed to be significantly less that the buffer size. +func yaml_parser_update_buffer(parser *yaml_parser_t, length int) bool { + if parser.read_handler == nil { + panic("read handler must be set") + } + + // If the EOF flag is set and the raw buffer is empty, do nothing. + if parser.eof && parser.raw_buffer_pos == len(parser.raw_buffer) { + return true + } + + // Return if the buffer contains enough characters. + if parser.unread >= length { + return true + } + + // Determine the input encoding if it is not known yet. + if parser.encoding == yaml_ANY_ENCODING { + if !yaml_parser_determine_encoding(parser) { + return false + } + } + + // Move the unread characters to the beginning of the buffer. + buffer_len := len(parser.buffer) + if parser.buffer_pos > 0 && parser.buffer_pos < buffer_len { + copy(parser.buffer, parser.buffer[parser.buffer_pos:]) + buffer_len -= parser.buffer_pos + parser.buffer_pos = 0 + } else if parser.buffer_pos == buffer_len { + buffer_len = 0 + parser.buffer_pos = 0 + } + + // Open the whole buffer for writing, and cut it before returning. + parser.buffer = parser.buffer[:cap(parser.buffer)] + + // Fill the buffer until it has enough characters. + first := true + for parser.unread < length { + + // Fill the raw buffer if necessary. + if !first || parser.raw_buffer_pos == len(parser.raw_buffer) { + if !yaml_parser_update_raw_buffer(parser) { + parser.buffer = parser.buffer[:buffer_len] + return false + } + } + first = false + + // Decode the raw buffer. + inner: + for parser.raw_buffer_pos != len(parser.raw_buffer) { + var value rune + var width int + + raw_unread := len(parser.raw_buffer) - parser.raw_buffer_pos + + // Decode the next character. + switch parser.encoding { + case yaml_UTF8_ENCODING: + // Decode a UTF-8 character. Check RFC 3629 + // (http://www.ietf.org/rfc/rfc3629.txt) for more details. + // + // The following table (taken from the RFC) is used for + // decoding. + // + // Char. number range | UTF-8 octet sequence + // (hexadecimal) | (binary) + // --------------------+------------------------------------ + // 0000 0000-0000 007F | 0xxxxxxx + // 0000 0080-0000 07FF | 110xxxxx 10xxxxxx + // 0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx + // 0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx + // + // Additionally, the characters in the range 0xD800-0xDFFF + // are prohibited as they are reserved for use with UTF-16 + // surrogate pairs. + + // Determine the length of the UTF-8 sequence. + octet := parser.raw_buffer[parser.raw_buffer_pos] + switch { + case octet&0x80 == 0x00: + width = 1 + case octet&0xE0 == 0xC0: + width = 2 + case octet&0xF0 == 0xE0: + width = 3 + case octet&0xF8 == 0xF0: + width = 4 + default: + // The leading octet is invalid. + return yaml_parser_set_reader_error(parser, + "invalid leading UTF-8 octet", + parser.offset, int(octet)) + } + + // Check if the raw buffer contains an incomplete character. + if width > raw_unread { + if parser.eof { + return yaml_parser_set_reader_error(parser, + "incomplete UTF-8 octet sequence", + parser.offset, -1) + } + break inner + } + + // Decode the leading octet. + switch { + case octet&0x80 == 0x00: + value = rune(octet & 0x7F) + case octet&0xE0 == 0xC0: + value = rune(octet & 0x1F) + case octet&0xF0 == 0xE0: + value = rune(octet & 0x0F) + case octet&0xF8 == 0xF0: + value = rune(octet & 0x07) + default: + value = 0 + } + + // Check and decode the trailing octets. + for k := 1; k < width; k++ { + octet = parser.raw_buffer[parser.raw_buffer_pos+k] + + // Check if the octet is valid. + if (octet & 0xC0) != 0x80 { + return yaml_parser_set_reader_error(parser, + "invalid trailing UTF-8 octet", + parser.offset+k, int(octet)) + } + + // Decode the octet. + value = (value << 6) + rune(octet&0x3F) + } + + // Check the length of the sequence against the value. + switch { + case width == 1: + case width == 2 && value >= 0x80: + case width == 3 && value >= 0x800: + case width == 4 && value >= 0x10000: + default: + return yaml_parser_set_reader_error(parser, + "invalid length of a UTF-8 sequence", + parser.offset, -1) + } + + // Check the range of the value. + if value >= 0xD800 && value <= 0xDFFF || value > 0x10FFFF { + return yaml_parser_set_reader_error(parser, + "invalid Unicode character", + parser.offset, int(value)) + } + + case yaml_UTF16LE_ENCODING, yaml_UTF16BE_ENCODING: + var low, high int + if parser.encoding == yaml_UTF16LE_ENCODING { + low, high = 0, 1 + } else { + high, low = 1, 0 + } + + // The UTF-16 encoding is not as simple as one might + // naively think. Check RFC 2781 + // (http://www.ietf.org/rfc/rfc2781.txt). + // + // Normally, two subsequent bytes describe a Unicode + // character. However a special technique (called a + // surrogate pair) is used for specifying character + // values larger than 0xFFFF. + // + // A surrogate pair consists of two pseudo-characters: + // high surrogate area (0xD800-0xDBFF) + // low surrogate area (0xDC00-0xDFFF) + // + // The following formulas are used for decoding + // and encoding characters using surrogate pairs: + // + // U = U' + 0x10000 (0x01 00 00 <= U <= 0x10 FF FF) + // U' = yyyyyyyyyyxxxxxxxxxx (0 <= U' <= 0x0F FF FF) + // W1 = 110110yyyyyyyyyy + // W2 = 110111xxxxxxxxxx + // + // where U is the character value, W1 is the high surrogate + // area, W2 is the low surrogate area. + + // Check for incomplete UTF-16 character. + if raw_unread < 2 { + if parser.eof { + return yaml_parser_set_reader_error(parser, + "incomplete UTF-16 character", + parser.offset, -1) + } + break inner + } + + // Get the character. + value = rune(parser.raw_buffer[parser.raw_buffer_pos+low]) + + (rune(parser.raw_buffer[parser.raw_buffer_pos+high]) << 8) + + // Check for unexpected low surrogate area. + if value&0xFC00 == 0xDC00 { + return yaml_parser_set_reader_error(parser, + "unexpected low surrogate area", + parser.offset, int(value)) + } + + // Check for a high surrogate area. + if value&0xFC00 == 0xD800 { + width = 4 + + // Check for incomplete surrogate pair. + if raw_unread < 4 { + if parser.eof { + return yaml_parser_set_reader_error(parser, + "incomplete UTF-16 surrogate pair", + parser.offset, -1) + } + break inner + } + + // Get the next character. + value2 := rune(parser.raw_buffer[parser.raw_buffer_pos+low+2]) + + (rune(parser.raw_buffer[parser.raw_buffer_pos+high+2]) << 8) + + // Check for a low surrogate area. + if value2&0xFC00 != 0xDC00 { + return yaml_parser_set_reader_error(parser, + "expected low surrogate area", + parser.offset+2, int(value2)) + } + + // Generate the value of the surrogate pair. + value = 0x10000 + ((value & 0x3FF) << 10) + (value2 & 0x3FF) + } else { + width = 2 + } + + default: + panic("impossible") + } + + // Check if the character is in the allowed range: + // #x9 | #xA | #xD | [#x20-#x7E] (8 bit) + // | #x85 | [#xA0-#xD7FF] | [#xE000-#xFFFD] (16 bit) + // | [#x10000-#x10FFFF] (32 bit) + switch { + case value == 0x09: + case value == 0x0A: + case value == 0x0D: + case value >= 0x20 && value <= 0x7E: + case value == 0x85: + case value >= 0xA0 && value <= 0xD7FF: + case value >= 0xE000 && value <= 0xFFFD: + case value >= 0x10000 && value <= 0x10FFFF: + default: + return yaml_parser_set_reader_error(parser, + "control characters are not allowed", + parser.offset, int(value)) + } + + // Move the raw pointers. + parser.raw_buffer_pos += width + parser.offset += width + + // Finally put the character into the buffer. + if value <= 0x7F { + // 0000 0000-0000 007F . 0xxxxxxx + parser.buffer[buffer_len+0] = byte(value) + } else if value <= 0x7FF { + // 0000 0080-0000 07FF . 110xxxxx 10xxxxxx + parser.buffer[buffer_len+0] = byte(0xC0 + (value >> 6)) + parser.buffer[buffer_len+1] = byte(0x80 + (value & 0x3F)) + } else if value <= 0xFFFF { + // 0000 0800-0000 FFFF . 1110xxxx 10xxxxxx 10xxxxxx + parser.buffer[buffer_len+0] = byte(0xE0 + (value >> 12)) + parser.buffer[buffer_len+1] = byte(0x80 + ((value >> 6) & 0x3F)) + parser.buffer[buffer_len+2] = byte(0x80 + (value & 0x3F)) + } else { + // 0001 0000-0010 FFFF . 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx + parser.buffer[buffer_len+0] = byte(0xF0 + (value >> 18)) + parser.buffer[buffer_len+1] = byte(0x80 + ((value >> 12) & 0x3F)) + parser.buffer[buffer_len+2] = byte(0x80 + ((value >> 6) & 0x3F)) + parser.buffer[buffer_len+3] = byte(0x80 + (value & 0x3F)) + } + buffer_len += width + + parser.unread++ + } + + // On EOF, put NUL into the buffer and return. + if parser.eof { + parser.buffer[buffer_len] = 0 + buffer_len++ + parser.unread++ + break + } + } + parser.buffer = parser.buffer[:buffer_len] + return true +} diff --git a/vendor/gopkg.in/yaml.v2/resolve.go b/vendor/gopkg.in/yaml.v2/resolve.go new file mode 100644 index 0000000..93a8632 --- /dev/null +++ b/vendor/gopkg.in/yaml.v2/resolve.go @@ -0,0 +1,203 @@ +package yaml + +import ( + "encoding/base64" + "math" + "strconv" + "strings" + "unicode/utf8" +) + +type resolveMapItem struct { + value interface{} + tag string +} + +var resolveTable = make([]byte, 256) +var resolveMap = make(map[string]resolveMapItem) + +func init() { + t := resolveTable + t[int('+')] = 'S' // Sign + t[int('-')] = 'S' + for _, c := range "0123456789" { + t[int(c)] = 'D' // Digit + } + for _, c := range "yYnNtTfFoO~" { + t[int(c)] = 'M' // In map + } + t[int('.')] = '.' // Float (potentially in map) + + var resolveMapList = []struct { + v interface{} + tag string + l []string + }{ + {true, yaml_BOOL_TAG, []string{"y", "Y", "yes", "Yes", "YES"}}, + {true, yaml_BOOL_TAG, []string{"true", "True", "TRUE"}}, + {true, yaml_BOOL_TAG, []string{"on", "On", "ON"}}, + {false, yaml_BOOL_TAG, []string{"n", "N", "no", "No", "NO"}}, + {false, yaml_BOOL_TAG, []string{"false", "False", "FALSE"}}, + {false, yaml_BOOL_TAG, []string{"off", "Off", "OFF"}}, + {nil, yaml_NULL_TAG, []string{"", "~", "null", "Null", "NULL"}}, + {math.NaN(), yaml_FLOAT_TAG, []string{".nan", ".NaN", ".NAN"}}, + {math.Inf(+1), yaml_FLOAT_TAG, []string{".inf", ".Inf", ".INF"}}, + {math.Inf(+1), yaml_FLOAT_TAG, []string{"+.inf", "+.Inf", "+.INF"}}, + {math.Inf(-1), yaml_FLOAT_TAG, []string{"-.inf", "-.Inf", "-.INF"}}, + {"<<", yaml_MERGE_TAG, []string{"<<"}}, + } + + m := resolveMap + for _, item := range resolveMapList { + for _, s := range item.l { + m[s] = resolveMapItem{item.v, item.tag} + } + } +} + +const longTagPrefix = "tag:yaml.org,2002:" + +func shortTag(tag string) string { + // TODO This can easily be made faster and produce less garbage. + if strings.HasPrefix(tag, longTagPrefix) { + return "!!" + tag[len(longTagPrefix):] + } + return tag +} + +func longTag(tag string) string { + if strings.HasPrefix(tag, "!!") { + return longTagPrefix + tag[2:] + } + return tag +} + +func resolvableTag(tag string) bool { + switch tag { + case "", yaml_STR_TAG, yaml_BOOL_TAG, yaml_INT_TAG, yaml_FLOAT_TAG, yaml_NULL_TAG: + return true + } + return false +} + +func resolve(tag string, in string) (rtag string, out interface{}) { + if !resolvableTag(tag) { + return tag, in + } + + defer func() { + switch tag { + case "", rtag, yaml_STR_TAG, yaml_BINARY_TAG: + return + } + failf("cannot decode %s `%s` as a %s", shortTag(rtag), in, shortTag(tag)) + }() + + // Any data is accepted as a !!str or !!binary. + // Otherwise, the prefix is enough of a hint about what it might be. + hint := byte('N') + if in != "" { + hint = resolveTable[in[0]] + } + if hint != 0 && tag != yaml_STR_TAG && tag != yaml_BINARY_TAG { + // Handle things we can lookup in a map. + if item, ok := resolveMap[in]; ok { + return item.tag, item.value + } + + // Base 60 floats are a bad idea, were dropped in YAML 1.2, and + // are purposefully unsupported here. They're still quoted on + // the way out for compatibility with other parser, though. + + switch hint { + case 'M': + // We've already checked the map above. + + case '.': + // Not in the map, so maybe a normal float. + floatv, err := strconv.ParseFloat(in, 64) + if err == nil { + return yaml_FLOAT_TAG, floatv + } + + case 'D', 'S': + // Int, float, or timestamp. + plain := strings.Replace(in, "_", "", -1) + intv, err := strconv.ParseInt(plain, 0, 64) + if err == nil { + if intv == int64(int(intv)) { + return yaml_INT_TAG, int(intv) + } else { + return yaml_INT_TAG, intv + } + } + uintv, err := strconv.ParseUint(plain, 0, 64) + if err == nil { + return yaml_INT_TAG, uintv + } + floatv, err := strconv.ParseFloat(plain, 64) + if err == nil { + return yaml_FLOAT_TAG, floatv + } + if strings.HasPrefix(plain, "0b") { + intv, err := strconv.ParseInt(plain[2:], 2, 64) + if err == nil { + if intv == int64(int(intv)) { + return yaml_INT_TAG, int(intv) + } else { + return yaml_INT_TAG, intv + } + } + uintv, err := strconv.ParseUint(plain[2:], 2, 64) + if err == nil { + return yaml_INT_TAG, uintv + } + } else if strings.HasPrefix(plain, "-0b") { + intv, err := strconv.ParseInt(plain[3:], 2, 64) + if err == nil { + if intv == int64(int(intv)) { + return yaml_INT_TAG, -int(intv) + } else { + return yaml_INT_TAG, -intv + } + } + } + // XXX Handle timestamps here. + + default: + panic("resolveTable item not yet handled: " + string(rune(hint)) + " (with " + in + ")") + } + } + if tag == yaml_BINARY_TAG { + return yaml_BINARY_TAG, in + } + if utf8.ValidString(in) { + return yaml_STR_TAG, in + } + return yaml_BINARY_TAG, encodeBase64(in) +} + +// encodeBase64 encodes s as base64 that is broken up into multiple lines +// as appropriate for the resulting length. +func encodeBase64(s string) string { + const lineLen = 70 + encLen := base64.StdEncoding.EncodedLen(len(s)) + lines := encLen/lineLen + 1 + buf := make([]byte, encLen*2+lines) + in := buf[0:encLen] + out := buf[encLen:] + base64.StdEncoding.Encode(in, []byte(s)) + k := 0 + for i := 0; i < len(in); i += lineLen { + j := i + lineLen + if j > len(in) { + j = len(in) + } + k += copy(out[k:], in[i:j]) + if lines > 1 { + out[k] = '\n' + k++ + } + } + return string(out[:k]) +} diff --git a/vendor/gopkg.in/yaml.v2/scannerc.go b/vendor/gopkg.in/yaml.v2/scannerc.go new file mode 100644 index 0000000..fe93b19 --- /dev/null +++ b/vendor/gopkg.in/yaml.v2/scannerc.go @@ -0,0 +1,2710 @@ +package yaml + +import ( + "bytes" + "fmt" +) + +// Introduction +// ************ +// +// The following notes assume that you are familiar with the YAML specification +// (http://yaml.org/spec/cvs/current.html). We mostly follow it, although in +// some cases we are less restrictive that it requires. +// +// The process of transforming a YAML stream into a sequence of events is +// divided on two steps: Scanning and Parsing. +// +// The Scanner transforms the input stream into a sequence of tokens, while the +// parser transform the sequence of tokens produced by the Scanner into a +// sequence of parsing events. +// +// The Scanner is rather clever and complicated. The Parser, on the contrary, +// is a straightforward implementation of a recursive-descendant parser (or, +// LL(1) parser, as it is usually called). +// +// Actually there are two issues of Scanning that might be called "clever", the +// rest is quite straightforward. The issues are "block collection start" and +// "simple keys". Both issues are explained below in details. +// +// Here the Scanning step is explained and implemented. We start with the list +// of all the tokens produced by the Scanner together with short descriptions. +// +// Now, tokens: +// +// STREAM-START(encoding) # The stream start. +// STREAM-END # The stream end. +// VERSION-DIRECTIVE(major,minor) # The '%YAML' directive. +// TAG-DIRECTIVE(handle,prefix) # The '%TAG' directive. +// DOCUMENT-START # '---' +// DOCUMENT-END # '...' +// BLOCK-SEQUENCE-START # Indentation increase denoting a block +// BLOCK-MAPPING-START # sequence or a block mapping. +// BLOCK-END # Indentation decrease. +// FLOW-SEQUENCE-START # '[' +// FLOW-SEQUENCE-END # ']' +// BLOCK-SEQUENCE-START # '{' +// BLOCK-SEQUENCE-END # '}' +// BLOCK-ENTRY # '-' +// FLOW-ENTRY # ',' +// KEY # '?' or nothing (simple keys). +// VALUE # ':' +// ALIAS(anchor) # '*anchor' +// ANCHOR(anchor) # '&anchor' +// TAG(handle,suffix) # '!handle!suffix' +// SCALAR(value,style) # A scalar. +// +// The following two tokens are "virtual" tokens denoting the beginning and the +// end of the stream: +// +// STREAM-START(encoding) +// STREAM-END +// +// We pass the information about the input stream encoding with the +// STREAM-START token. +// +// The next two tokens are responsible for tags: +// +// VERSION-DIRECTIVE(major,minor) +// TAG-DIRECTIVE(handle,prefix) +// +// Example: +// +// %YAML 1.1 +// %TAG ! !foo +// %TAG !yaml! tag:yaml.org,2002: +// --- +// +// The correspoding sequence of tokens: +// +// STREAM-START(utf-8) +// VERSION-DIRECTIVE(1,1) +// TAG-DIRECTIVE("!","!foo") +// TAG-DIRECTIVE("!yaml","tag:yaml.org,2002:") +// DOCUMENT-START +// STREAM-END +// +// Note that the VERSION-DIRECTIVE and TAG-DIRECTIVE tokens occupy a whole +// line. +// +// The document start and end indicators are represented by: +// +// DOCUMENT-START +// DOCUMENT-END +// +// Note that if a YAML stream contains an implicit document (without '---' +// and '...' indicators), no DOCUMENT-START and DOCUMENT-END tokens will be +// produced. +// +// In the following examples, we present whole documents together with the +// produced tokens. +// +// 1. An implicit document: +// +// 'a scalar' +// +// Tokens: +// +// STREAM-START(utf-8) +// SCALAR("a scalar",single-quoted) +// STREAM-END +// +// 2. An explicit document: +// +// --- +// 'a scalar' +// ... +// +// Tokens: +// +// STREAM-START(utf-8) +// DOCUMENT-START +// SCALAR("a scalar",single-quoted) +// DOCUMENT-END +// STREAM-END +// +// 3. Several documents in a stream: +// +// 'a scalar' +// --- +// 'another scalar' +// --- +// 'yet another scalar' +// +// Tokens: +// +// STREAM-START(utf-8) +// SCALAR("a scalar",single-quoted) +// DOCUMENT-START +// SCALAR("another scalar",single-quoted) +// DOCUMENT-START +// SCALAR("yet another scalar",single-quoted) +// STREAM-END +// +// We have already introduced the SCALAR token above. The following tokens are +// used to describe aliases, anchors, tag, and scalars: +// +// ALIAS(anchor) +// ANCHOR(anchor) +// TAG(handle,suffix) +// SCALAR(value,style) +// +// The following series of examples illustrate the usage of these tokens: +// +// 1. A recursive sequence: +// +// &A [ *A ] +// +// Tokens: +// +// STREAM-START(utf-8) +// ANCHOR("A") +// FLOW-SEQUENCE-START +// ALIAS("A") +// FLOW-SEQUENCE-END +// STREAM-END +// +// 2. A tagged scalar: +// +// !!float "3.14" # A good approximation. +// +// Tokens: +// +// STREAM-START(utf-8) +// TAG("!!","float") +// SCALAR("3.14",double-quoted) +// STREAM-END +// +// 3. Various scalar styles: +// +// --- # Implicit empty plain scalars do not produce tokens. +// --- a plain scalar +// --- 'a single-quoted scalar' +// --- "a double-quoted scalar" +// --- |- +// a literal scalar +// --- >- +// a folded +// scalar +// +// Tokens: +// +// STREAM-START(utf-8) +// DOCUMENT-START +// DOCUMENT-START +// SCALAR("a plain scalar",plain) +// DOCUMENT-START +// SCALAR("a single-quoted scalar",single-quoted) +// DOCUMENT-START +// SCALAR("a double-quoted scalar",double-quoted) +// DOCUMENT-START +// SCALAR("a literal scalar",literal) +// DOCUMENT-START +// SCALAR("a folded scalar",folded) +// STREAM-END +// +// Now it's time to review collection-related tokens. We will start with +// flow collections: +// +// FLOW-SEQUENCE-START +// FLOW-SEQUENCE-END +// FLOW-MAPPING-START +// FLOW-MAPPING-END +// FLOW-ENTRY +// KEY +// VALUE +// +// The tokens FLOW-SEQUENCE-START, FLOW-SEQUENCE-END, FLOW-MAPPING-START, and +// FLOW-MAPPING-END represent the indicators '[', ']', '{', and '}' +// correspondingly. FLOW-ENTRY represent the ',' indicator. Finally the +// indicators '?' and ':', which are used for denoting mapping keys and values, +// are represented by the KEY and VALUE tokens. +// +// The following examples show flow collections: +// +// 1. A flow sequence: +// +// [item 1, item 2, item 3] +// +// Tokens: +// +// STREAM-START(utf-8) +// FLOW-SEQUENCE-START +// SCALAR("item 1",plain) +// FLOW-ENTRY +// SCALAR("item 2",plain) +// FLOW-ENTRY +// SCALAR("item 3",plain) +// FLOW-SEQUENCE-END +// STREAM-END +// +// 2. A flow mapping: +// +// { +// a simple key: a value, # Note that the KEY token is produced. +// ? a complex key: another value, +// } +// +// Tokens: +// +// STREAM-START(utf-8) +// FLOW-MAPPING-START +// KEY +// SCALAR("a simple key",plain) +// VALUE +// SCALAR("a value",plain) +// FLOW-ENTRY +// KEY +// SCALAR("a complex key",plain) +// VALUE +// SCALAR("another value",plain) +// FLOW-ENTRY +// FLOW-MAPPING-END +// STREAM-END +// +// A simple key is a key which is not denoted by the '?' indicator. Note that +// the Scanner still produce the KEY token whenever it encounters a simple key. +// +// For scanning block collections, the following tokens are used (note that we +// repeat KEY and VALUE here): +// +// BLOCK-SEQUENCE-START +// BLOCK-MAPPING-START +// BLOCK-END +// BLOCK-ENTRY +// KEY +// VALUE +// +// The tokens BLOCK-SEQUENCE-START and BLOCK-MAPPING-START denote indentation +// increase that precedes a block collection (cf. the INDENT token in Python). +// The token BLOCK-END denote indentation decrease that ends a block collection +// (cf. the DEDENT token in Python). However YAML has some syntax pecularities +// that makes detections of these tokens more complex. +// +// The tokens BLOCK-ENTRY, KEY, and VALUE are used to represent the indicators +// '-', '?', and ':' correspondingly. +// +// The following examples show how the tokens BLOCK-SEQUENCE-START, +// BLOCK-MAPPING-START, and BLOCK-END are emitted by the Scanner: +// +// 1. Block sequences: +// +// - item 1 +// - item 2 +// - +// - item 3.1 +// - item 3.2 +// - +// key 1: value 1 +// key 2: value 2 +// +// Tokens: +// +// STREAM-START(utf-8) +// BLOCK-SEQUENCE-START +// BLOCK-ENTRY +// SCALAR("item 1",plain) +// BLOCK-ENTRY +// SCALAR("item 2",plain) +// BLOCK-ENTRY +// BLOCK-SEQUENCE-START +// BLOCK-ENTRY +// SCALAR("item 3.1",plain) +// BLOCK-ENTRY +// SCALAR("item 3.2",plain) +// BLOCK-END +// BLOCK-ENTRY +// BLOCK-MAPPING-START +// KEY +// SCALAR("key 1",plain) +// VALUE +// SCALAR("value 1",plain) +// KEY +// SCALAR("key 2",plain) +// VALUE +// SCALAR("value 2",plain) +// BLOCK-END +// BLOCK-END +// STREAM-END +// +// 2. Block mappings: +// +// a simple key: a value # The KEY token is produced here. +// ? a complex key +// : another value +// a mapping: +// key 1: value 1 +// key 2: value 2 +// a sequence: +// - item 1 +// - item 2 +// +// Tokens: +// +// STREAM-START(utf-8) +// BLOCK-MAPPING-START +// KEY +// SCALAR("a simple key",plain) +// VALUE +// SCALAR("a value",plain) +// KEY +// SCALAR("a complex key",plain) +// VALUE +// SCALAR("another value",plain) +// KEY +// SCALAR("a mapping",plain) +// BLOCK-MAPPING-START +// KEY +// SCALAR("key 1",plain) +// VALUE +// SCALAR("value 1",plain) +// KEY +// SCALAR("key 2",plain) +// VALUE +// SCALAR("value 2",plain) +// BLOCK-END +// KEY +// SCALAR("a sequence",plain) +// VALUE +// BLOCK-SEQUENCE-START +// BLOCK-ENTRY +// SCALAR("item 1",plain) +// BLOCK-ENTRY +// SCALAR("item 2",plain) +// BLOCK-END +// BLOCK-END +// STREAM-END +// +// YAML does not always require to start a new block collection from a new +// line. If the current line contains only '-', '?', and ':' indicators, a new +// block collection may start at the current line. The following examples +// illustrate this case: +// +// 1. Collections in a sequence: +// +// - - item 1 +// - item 2 +// - key 1: value 1 +// key 2: value 2 +// - ? complex key +// : complex value +// +// Tokens: +// +// STREAM-START(utf-8) +// BLOCK-SEQUENCE-START +// BLOCK-ENTRY +// BLOCK-SEQUENCE-START +// BLOCK-ENTRY +// SCALAR("item 1",plain) +// BLOCK-ENTRY +// SCALAR("item 2",plain) +// BLOCK-END +// BLOCK-ENTRY +// BLOCK-MAPPING-START +// KEY +// SCALAR("key 1",plain) +// VALUE +// SCALAR("value 1",plain) +// KEY +// SCALAR("key 2",plain) +// VALUE +// SCALAR("value 2",plain) +// BLOCK-END +// BLOCK-ENTRY +// BLOCK-MAPPING-START +// KEY +// SCALAR("complex key") +// VALUE +// SCALAR("complex value") +// BLOCK-END +// BLOCK-END +// STREAM-END +// +// 2. Collections in a mapping: +// +// ? a sequence +// : - item 1 +// - item 2 +// ? a mapping +// : key 1: value 1 +// key 2: value 2 +// +// Tokens: +// +// STREAM-START(utf-8) +// BLOCK-MAPPING-START +// KEY +// SCALAR("a sequence",plain) +// VALUE +// BLOCK-SEQUENCE-START +// BLOCK-ENTRY +// SCALAR("item 1",plain) +// BLOCK-ENTRY +// SCALAR("item 2",plain) +// BLOCK-END +// KEY +// SCALAR("a mapping",plain) +// VALUE +// BLOCK-MAPPING-START +// KEY +// SCALAR("key 1",plain) +// VALUE +// SCALAR("value 1",plain) +// KEY +// SCALAR("key 2",plain) +// VALUE +// SCALAR("value 2",plain) +// BLOCK-END +// BLOCK-END +// STREAM-END +// +// YAML also permits non-indented sequences if they are included into a block +// mapping. In this case, the token BLOCK-SEQUENCE-START is not produced: +// +// key: +// - item 1 # BLOCK-SEQUENCE-START is NOT produced here. +// - item 2 +// +// Tokens: +// +// STREAM-START(utf-8) +// BLOCK-MAPPING-START +// KEY +// SCALAR("key",plain) +// VALUE +// BLOCK-ENTRY +// SCALAR("item 1",plain) +// BLOCK-ENTRY +// SCALAR("item 2",plain) +// BLOCK-END +// + +// Ensure that the buffer contains the required number of characters. +// Return true on success, false on failure (reader error or memory error). +func cache(parser *yaml_parser_t, length int) bool { + // [Go] This was inlined: !cache(A, B) -> unread < B && !update(A, B) + return parser.unread >= length || yaml_parser_update_buffer(parser, length) +} + +// Advance the buffer pointer. +func skip(parser *yaml_parser_t) { + parser.mark.index++ + parser.mark.column++ + parser.unread-- + parser.buffer_pos += width(parser.buffer[parser.buffer_pos]) +} + +func skip_line(parser *yaml_parser_t) { + if is_crlf(parser.buffer, parser.buffer_pos) { + parser.mark.index += 2 + parser.mark.column = 0 + parser.mark.line++ + parser.unread -= 2 + parser.buffer_pos += 2 + } else if is_break(parser.buffer, parser.buffer_pos) { + parser.mark.index++ + parser.mark.column = 0 + parser.mark.line++ + parser.unread-- + parser.buffer_pos += width(parser.buffer[parser.buffer_pos]) + } +} + +// Copy a character to a string buffer and advance pointers. +func read(parser *yaml_parser_t, s []byte) []byte { + w := width(parser.buffer[parser.buffer_pos]) + if w == 0 { + panic("invalid character sequence") + } + if len(s) == 0 { + s = make([]byte, 0, 32) + } + if w == 1 && len(s)+w <= cap(s) { + s = s[:len(s)+1] + s[len(s)-1] = parser.buffer[parser.buffer_pos] + parser.buffer_pos++ + } else { + s = append(s, parser.buffer[parser.buffer_pos:parser.buffer_pos+w]...) + parser.buffer_pos += w + } + parser.mark.index++ + parser.mark.column++ + parser.unread-- + return s +} + +// Copy a line break character to a string buffer and advance pointers. +func read_line(parser *yaml_parser_t, s []byte) []byte { + buf := parser.buffer + pos := parser.buffer_pos + switch { + case buf[pos] == '\r' && buf[pos+1] == '\n': + // CR LF . LF + s = append(s, '\n') + parser.buffer_pos += 2 + parser.mark.index++ + parser.unread-- + case buf[pos] == '\r' || buf[pos] == '\n': + // CR|LF . LF + s = append(s, '\n') + parser.buffer_pos += 1 + case buf[pos] == '\xC2' && buf[pos+1] == '\x85': + // NEL . LF + s = append(s, '\n') + parser.buffer_pos += 2 + case buf[pos] == '\xE2' && buf[pos+1] == '\x80' && (buf[pos+2] == '\xA8' || buf[pos+2] == '\xA9'): + // LS|PS . LS|PS + s = append(s, buf[parser.buffer_pos:pos+3]...) + parser.buffer_pos += 3 + default: + return s + } + parser.mark.index++ + parser.mark.column = 0 + parser.mark.line++ + parser.unread-- + return s +} + +// Get the next token. +func yaml_parser_scan(parser *yaml_parser_t, token *yaml_token_t) bool { + // Erase the token object. + *token = yaml_token_t{} // [Go] Is this necessary? + + // No tokens after STREAM-END or error. + if parser.stream_end_produced || parser.error != yaml_NO_ERROR { + return true + } + + // Ensure that the tokens queue contains enough tokens. + if !parser.token_available { + if !yaml_parser_fetch_more_tokens(parser) { + return false + } + } + + // Fetch the next token from the queue. + *token = parser.tokens[parser.tokens_head] + parser.tokens_head++ + parser.tokens_parsed++ + parser.token_available = false + + if token.typ == yaml_STREAM_END_TOKEN { + parser.stream_end_produced = true + } + return true +} + +// Set the scanner error and return false. +func yaml_parser_set_scanner_error(parser *yaml_parser_t, context string, context_mark yaml_mark_t, problem string) bool { + parser.error = yaml_SCANNER_ERROR + parser.context = context + parser.context_mark = context_mark + parser.problem = problem + parser.problem_mark = parser.mark + return false +} + +func yaml_parser_set_scanner_tag_error(parser *yaml_parser_t, directive bool, context_mark yaml_mark_t, problem string) bool { + context := "while parsing a tag" + if directive { + context = "while parsing a %TAG directive" + } + return yaml_parser_set_scanner_error(parser, context, context_mark, "did not find URI escaped octet") +} + +func trace(args ...interface{}) func() { + pargs := append([]interface{}{"+++"}, args...) + fmt.Println(pargs...) + pargs = append([]interface{}{"---"}, args...) + return func() { fmt.Println(pargs...) } +} + +// Ensure that the tokens queue contains at least one token which can be +// returned to the Parser. +func yaml_parser_fetch_more_tokens(parser *yaml_parser_t) bool { + // While we need more tokens to fetch, do it. + for { + // Check if we really need to fetch more tokens. + need_more_tokens := false + + if parser.tokens_head == len(parser.tokens) { + // Queue is empty. + need_more_tokens = true + } else { + // Check if any potential simple key may occupy the head position. + if !yaml_parser_stale_simple_keys(parser) { + return false + } + + for i := range parser.simple_keys { + simple_key := &parser.simple_keys[i] + if simple_key.possible && simple_key.token_number == parser.tokens_parsed { + need_more_tokens = true + break + } + } + } + + // We are finished. + if !need_more_tokens { + break + } + // Fetch the next token. + if !yaml_parser_fetch_next_token(parser) { + return false + } + } + + parser.token_available = true + return true +} + +// The dispatcher for token fetchers. +func yaml_parser_fetch_next_token(parser *yaml_parser_t) bool { + // Ensure that the buffer is initialized. + if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { + return false + } + + // Check if we just started scanning. Fetch STREAM-START then. + if !parser.stream_start_produced { + return yaml_parser_fetch_stream_start(parser) + } + + // Eat whitespaces and comments until we reach the next token. + if !yaml_parser_scan_to_next_token(parser) { + return false + } + + // Remove obsolete potential simple keys. + if !yaml_parser_stale_simple_keys(parser) { + return false + } + + // Check the indentation level against the current column. + if !yaml_parser_unroll_indent(parser, parser.mark.column) { + return false + } + + // Ensure that the buffer contains at least 4 characters. 4 is the length + // of the longest indicators ('--- ' and '... '). + if parser.unread < 4 && !yaml_parser_update_buffer(parser, 4) { + return false + } + + // Is it the end of the stream? + if is_z(parser.buffer, parser.buffer_pos) { + return yaml_parser_fetch_stream_end(parser) + } + + // Is it a directive? + if parser.mark.column == 0 && parser.buffer[parser.buffer_pos] == '%' { + return yaml_parser_fetch_directive(parser) + } + + buf := parser.buffer + pos := parser.buffer_pos + + // Is it the document start indicator? + if parser.mark.column == 0 && buf[pos] == '-' && buf[pos+1] == '-' && buf[pos+2] == '-' && is_blankz(buf, pos+3) { + return yaml_parser_fetch_document_indicator(parser, yaml_DOCUMENT_START_TOKEN) + } + + // Is it the document end indicator? + if parser.mark.column == 0 && buf[pos] == '.' && buf[pos+1] == '.' && buf[pos+2] == '.' && is_blankz(buf, pos+3) { + return yaml_parser_fetch_document_indicator(parser, yaml_DOCUMENT_END_TOKEN) + } + + // Is it the flow sequence start indicator? + if buf[pos] == '[' { + return yaml_parser_fetch_flow_collection_start(parser, yaml_FLOW_SEQUENCE_START_TOKEN) + } + + // Is it the flow mapping start indicator? + if parser.buffer[parser.buffer_pos] == '{' { + return yaml_parser_fetch_flow_collection_start(parser, yaml_FLOW_MAPPING_START_TOKEN) + } + + // Is it the flow sequence end indicator? + if parser.buffer[parser.buffer_pos] == ']' { + return yaml_parser_fetch_flow_collection_end(parser, + yaml_FLOW_SEQUENCE_END_TOKEN) + } + + // Is it the flow mapping end indicator? + if parser.buffer[parser.buffer_pos] == '}' { + return yaml_parser_fetch_flow_collection_end(parser, + yaml_FLOW_MAPPING_END_TOKEN) + } + + // Is it the flow entry indicator? + if parser.buffer[parser.buffer_pos] == ',' { + return yaml_parser_fetch_flow_entry(parser) + } + + // Is it the block entry indicator? + if parser.buffer[parser.buffer_pos] == '-' && is_blankz(parser.buffer, parser.buffer_pos+1) { + return yaml_parser_fetch_block_entry(parser) + } + + // Is it the key indicator? + if parser.buffer[parser.buffer_pos] == '?' && (parser.flow_level > 0 || is_blankz(parser.buffer, parser.buffer_pos+1)) { + return yaml_parser_fetch_key(parser) + } + + // Is it the value indicator? + if parser.buffer[parser.buffer_pos] == ':' && (parser.flow_level > 0 || is_blankz(parser.buffer, parser.buffer_pos+1)) { + return yaml_parser_fetch_value(parser) + } + + // Is it an alias? + if parser.buffer[parser.buffer_pos] == '*' { + return yaml_parser_fetch_anchor(parser, yaml_ALIAS_TOKEN) + } + + // Is it an anchor? + if parser.buffer[parser.buffer_pos] == '&' { + return yaml_parser_fetch_anchor(parser, yaml_ANCHOR_TOKEN) + } + + // Is it a tag? + if parser.buffer[parser.buffer_pos] == '!' { + return yaml_parser_fetch_tag(parser) + } + + // Is it a literal scalar? + if parser.buffer[parser.buffer_pos] == '|' && parser.flow_level == 0 { + return yaml_parser_fetch_block_scalar(parser, true) + } + + // Is it a folded scalar? + if parser.buffer[parser.buffer_pos] == '>' && parser.flow_level == 0 { + return yaml_parser_fetch_block_scalar(parser, false) + } + + // Is it a single-quoted scalar? + if parser.buffer[parser.buffer_pos] == '\'' { + return yaml_parser_fetch_flow_scalar(parser, true) + } + + // Is it a double-quoted scalar? + if parser.buffer[parser.buffer_pos] == '"' { + return yaml_parser_fetch_flow_scalar(parser, false) + } + + // Is it a plain scalar? + // + // A plain scalar may start with any non-blank characters except + // + // '-', '?', ':', ',', '[', ']', '{', '}', + // '#', '&', '*', '!', '|', '>', '\'', '\"', + // '%', '@', '`'. + // + // In the block context (and, for the '-' indicator, in the flow context + // too), it may also start with the characters + // + // '-', '?', ':' + // + // if it is followed by a non-space character. + // + // The last rule is more restrictive than the specification requires. + // [Go] Make this logic more reasonable. + //switch parser.buffer[parser.buffer_pos] { + //case '-', '?', ':', ',', '?', '-', ',', ':', ']', '[', '}', '{', '&', '#', '!', '*', '>', '|', '"', '\'', '@', '%', '-', '`': + //} + if !(is_blankz(parser.buffer, parser.buffer_pos) || parser.buffer[parser.buffer_pos] == '-' || + parser.buffer[parser.buffer_pos] == '?' || parser.buffer[parser.buffer_pos] == ':' || + parser.buffer[parser.buffer_pos] == ',' || parser.buffer[parser.buffer_pos] == '[' || + parser.buffer[parser.buffer_pos] == ']' || parser.buffer[parser.buffer_pos] == '{' || + parser.buffer[parser.buffer_pos] == '}' || parser.buffer[parser.buffer_pos] == '#' || + parser.buffer[parser.buffer_pos] == '&' || parser.buffer[parser.buffer_pos] == '*' || + parser.buffer[parser.buffer_pos] == '!' || parser.buffer[parser.buffer_pos] == '|' || + parser.buffer[parser.buffer_pos] == '>' || parser.buffer[parser.buffer_pos] == '\'' || + parser.buffer[parser.buffer_pos] == '"' || parser.buffer[parser.buffer_pos] == '%' || + parser.buffer[parser.buffer_pos] == '@' || parser.buffer[parser.buffer_pos] == '`') || + (parser.buffer[parser.buffer_pos] == '-' && !is_blank(parser.buffer, parser.buffer_pos+1)) || + (parser.flow_level == 0 && + (parser.buffer[parser.buffer_pos] == '?' || parser.buffer[parser.buffer_pos] == ':') && + !is_blankz(parser.buffer, parser.buffer_pos+1)) { + return yaml_parser_fetch_plain_scalar(parser) + } + + // If we don't determine the token type so far, it is an error. + return yaml_parser_set_scanner_error(parser, + "while scanning for the next token", parser.mark, + "found character that cannot start any token") +} + +// Check the list of potential simple keys and remove the positions that +// cannot contain simple keys anymore. +func yaml_parser_stale_simple_keys(parser *yaml_parser_t) bool { + // Check for a potential simple key for each flow level. + for i := range parser.simple_keys { + simple_key := &parser.simple_keys[i] + + // The specification requires that a simple key + // + // - is limited to a single line, + // - is shorter than 1024 characters. + if simple_key.possible && (simple_key.mark.line < parser.mark.line || simple_key.mark.index+1024 < parser.mark.index) { + + // Check if the potential simple key to be removed is required. + if simple_key.required { + return yaml_parser_set_scanner_error(parser, + "while scanning a simple key", simple_key.mark, + "could not find expected ':'") + } + simple_key.possible = false + } + } + return true +} + +// Check if a simple key may start at the current position and add it if +// needed. +func yaml_parser_save_simple_key(parser *yaml_parser_t) bool { + // A simple key is required at the current position if the scanner is in + // the block context and the current column coincides with the indentation + // level. + + required := parser.flow_level == 0 && parser.indent == parser.mark.column + + // A simple key is required only when it is the first token in the current + // line. Therefore it is always allowed. But we add a check anyway. + if required && !parser.simple_key_allowed { + panic("should not happen") + } + + // + // If the current position may start a simple key, save it. + // + if parser.simple_key_allowed { + simple_key := yaml_simple_key_t{ + possible: true, + required: required, + token_number: parser.tokens_parsed + (len(parser.tokens) - parser.tokens_head), + } + simple_key.mark = parser.mark + + if !yaml_parser_remove_simple_key(parser) { + return false + } + parser.simple_keys[len(parser.simple_keys)-1] = simple_key + } + return true +} + +// Remove a potential simple key at the current flow level. +func yaml_parser_remove_simple_key(parser *yaml_parser_t) bool { + i := len(parser.simple_keys) - 1 + if parser.simple_keys[i].possible { + // If the key is required, it is an error. + if parser.simple_keys[i].required { + return yaml_parser_set_scanner_error(parser, + "while scanning a simple key", parser.simple_keys[i].mark, + "could not find expected ':'") + } + } + // Remove the key from the stack. + parser.simple_keys[i].possible = false + return true +} + +// Increase the flow level and resize the simple key list if needed. +func yaml_parser_increase_flow_level(parser *yaml_parser_t) bool { + // Reset the simple key on the next level. + parser.simple_keys = append(parser.simple_keys, yaml_simple_key_t{}) + + // Increase the flow level. + parser.flow_level++ + return true +} + +// Decrease the flow level. +func yaml_parser_decrease_flow_level(parser *yaml_parser_t) bool { + if parser.flow_level > 0 { + parser.flow_level-- + parser.simple_keys = parser.simple_keys[:len(parser.simple_keys)-1] + } + return true +} + +// Push the current indentation level to the stack and set the new level +// the current column is greater than the indentation level. In this case, +// append or insert the specified token into the token queue. +func yaml_parser_roll_indent(parser *yaml_parser_t, column, number int, typ yaml_token_type_t, mark yaml_mark_t) bool { + // In the flow context, do nothing. + if parser.flow_level > 0 { + return true + } + + if parser.indent < column { + // Push the current indentation level to the stack and set the new + // indentation level. + parser.indents = append(parser.indents, parser.indent) + parser.indent = column + + // Create a token and insert it into the queue. + token := yaml_token_t{ + typ: typ, + start_mark: mark, + end_mark: mark, + } + if number > -1 { + number -= parser.tokens_parsed + } + yaml_insert_token(parser, number, &token) + } + return true +} + +// Pop indentation levels from the indents stack until the current level +// becomes less or equal to the column. For each intendation level, append +// the BLOCK-END token. +func yaml_parser_unroll_indent(parser *yaml_parser_t, column int) bool { + // In the flow context, do nothing. + if parser.flow_level > 0 { + return true + } + + // Loop through the intendation levels in the stack. + for parser.indent > column { + // Create a token and append it to the queue. + token := yaml_token_t{ + typ: yaml_BLOCK_END_TOKEN, + start_mark: parser.mark, + end_mark: parser.mark, + } + yaml_insert_token(parser, -1, &token) + + // Pop the indentation level. + parser.indent = parser.indents[len(parser.indents)-1] + parser.indents = parser.indents[:len(parser.indents)-1] + } + return true +} + +// Initialize the scanner and produce the STREAM-START token. +func yaml_parser_fetch_stream_start(parser *yaml_parser_t) bool { + + // Set the initial indentation. + parser.indent = -1 + + // Initialize the simple key stack. + parser.simple_keys = append(parser.simple_keys, yaml_simple_key_t{}) + + // A simple key is allowed at the beginning of the stream. + parser.simple_key_allowed = true + + // We have started. + parser.stream_start_produced = true + + // Create the STREAM-START token and append it to the queue. + token := yaml_token_t{ + typ: yaml_STREAM_START_TOKEN, + start_mark: parser.mark, + end_mark: parser.mark, + encoding: parser.encoding, + } + yaml_insert_token(parser, -1, &token) + return true +} + +// Produce the STREAM-END token and shut down the scanner. +func yaml_parser_fetch_stream_end(parser *yaml_parser_t) bool { + + // Force new line. + if parser.mark.column != 0 { + parser.mark.column = 0 + parser.mark.line++ + } + + // Reset the indentation level. + if !yaml_parser_unroll_indent(parser, -1) { + return false + } + + // Reset simple keys. + if !yaml_parser_remove_simple_key(parser) { + return false + } + + parser.simple_key_allowed = false + + // Create the STREAM-END token and append it to the queue. + token := yaml_token_t{ + typ: yaml_STREAM_END_TOKEN, + start_mark: parser.mark, + end_mark: parser.mark, + } + yaml_insert_token(parser, -1, &token) + return true +} + +// Produce a VERSION-DIRECTIVE or TAG-DIRECTIVE token. +func yaml_parser_fetch_directive(parser *yaml_parser_t) bool { + // Reset the indentation level. + if !yaml_parser_unroll_indent(parser, -1) { + return false + } + + // Reset simple keys. + if !yaml_parser_remove_simple_key(parser) { + return false + } + + parser.simple_key_allowed = false + + // Create the YAML-DIRECTIVE or TAG-DIRECTIVE token. + token := yaml_token_t{} + if !yaml_parser_scan_directive(parser, &token) { + return false + } + // Append the token to the queue. + yaml_insert_token(parser, -1, &token) + return true +} + +// Produce the DOCUMENT-START or DOCUMENT-END token. +func yaml_parser_fetch_document_indicator(parser *yaml_parser_t, typ yaml_token_type_t) bool { + // Reset the indentation level. + if !yaml_parser_unroll_indent(parser, -1) { + return false + } + + // Reset simple keys. + if !yaml_parser_remove_simple_key(parser) { + return false + } + + parser.simple_key_allowed = false + + // Consume the token. + start_mark := parser.mark + + skip(parser) + skip(parser) + skip(parser) + + end_mark := parser.mark + + // Create the DOCUMENT-START or DOCUMENT-END token. + token := yaml_token_t{ + typ: typ, + start_mark: start_mark, + end_mark: end_mark, + } + // Append the token to the queue. + yaml_insert_token(parser, -1, &token) + return true +} + +// Produce the FLOW-SEQUENCE-START or FLOW-MAPPING-START token. +func yaml_parser_fetch_flow_collection_start(parser *yaml_parser_t, typ yaml_token_type_t) bool { + // The indicators '[' and '{' may start a simple key. + if !yaml_parser_save_simple_key(parser) { + return false + } + + // Increase the flow level. + if !yaml_parser_increase_flow_level(parser) { + return false + } + + // A simple key may follow the indicators '[' and '{'. + parser.simple_key_allowed = true + + // Consume the token. + start_mark := parser.mark + skip(parser) + end_mark := parser.mark + + // Create the FLOW-SEQUENCE-START of FLOW-MAPPING-START token. + token := yaml_token_t{ + typ: typ, + start_mark: start_mark, + end_mark: end_mark, + } + // Append the token to the queue. + yaml_insert_token(parser, -1, &token) + return true +} + +// Produce the FLOW-SEQUENCE-END or FLOW-MAPPING-END token. +func yaml_parser_fetch_flow_collection_end(parser *yaml_parser_t, typ yaml_token_type_t) bool { + // Reset any potential simple key on the current flow level. + if !yaml_parser_remove_simple_key(parser) { + return false + } + + // Decrease the flow level. + if !yaml_parser_decrease_flow_level(parser) { + return false + } + + // No simple keys after the indicators ']' and '}'. + parser.simple_key_allowed = false + + // Consume the token. + + start_mark := parser.mark + skip(parser) + end_mark := parser.mark + + // Create the FLOW-SEQUENCE-END of FLOW-MAPPING-END token. + token := yaml_token_t{ + typ: typ, + start_mark: start_mark, + end_mark: end_mark, + } + // Append the token to the queue. + yaml_insert_token(parser, -1, &token) + return true +} + +// Produce the FLOW-ENTRY token. +func yaml_parser_fetch_flow_entry(parser *yaml_parser_t) bool { + // Reset any potential simple keys on the current flow level. + if !yaml_parser_remove_simple_key(parser) { + return false + } + + // Simple keys are allowed after ','. + parser.simple_key_allowed = true + + // Consume the token. + start_mark := parser.mark + skip(parser) + end_mark := parser.mark + + // Create the FLOW-ENTRY token and append it to the queue. + token := yaml_token_t{ + typ: yaml_FLOW_ENTRY_TOKEN, + start_mark: start_mark, + end_mark: end_mark, + } + yaml_insert_token(parser, -1, &token) + return true +} + +// Produce the BLOCK-ENTRY token. +func yaml_parser_fetch_block_entry(parser *yaml_parser_t) bool { + // Check if the scanner is in the block context. + if parser.flow_level == 0 { + // Check if we are allowed to start a new entry. + if !parser.simple_key_allowed { + return yaml_parser_set_scanner_error(parser, "", parser.mark, + "block sequence entries are not allowed in this context") + } + // Add the BLOCK-SEQUENCE-START token if needed. + if !yaml_parser_roll_indent(parser, parser.mark.column, -1, yaml_BLOCK_SEQUENCE_START_TOKEN, parser.mark) { + return false + } + } else { + // It is an error for the '-' indicator to occur in the flow context, + // but we let the Parser detect and report about it because the Parser + // is able to point to the context. + } + + // Reset any potential simple keys on the current flow level. + if !yaml_parser_remove_simple_key(parser) { + return false + } + + // Simple keys are allowed after '-'. + parser.simple_key_allowed = true + + // Consume the token. + start_mark := parser.mark + skip(parser) + end_mark := parser.mark + + // Create the BLOCK-ENTRY token and append it to the queue. + token := yaml_token_t{ + typ: yaml_BLOCK_ENTRY_TOKEN, + start_mark: start_mark, + end_mark: end_mark, + } + yaml_insert_token(parser, -1, &token) + return true +} + +// Produce the KEY token. +func yaml_parser_fetch_key(parser *yaml_parser_t) bool { + + // In the block context, additional checks are required. + if parser.flow_level == 0 { + // Check if we are allowed to start a new key (not nessesary simple). + if !parser.simple_key_allowed { + return yaml_parser_set_scanner_error(parser, "", parser.mark, + "mapping keys are not allowed in this context") + } + // Add the BLOCK-MAPPING-START token if needed. + if !yaml_parser_roll_indent(parser, parser.mark.column, -1, yaml_BLOCK_MAPPING_START_TOKEN, parser.mark) { + return false + } + } + + // Reset any potential simple keys on the current flow level. + if !yaml_parser_remove_simple_key(parser) { + return false + } + + // Simple keys are allowed after '?' in the block context. + parser.simple_key_allowed = parser.flow_level == 0 + + // Consume the token. + start_mark := parser.mark + skip(parser) + end_mark := parser.mark + + // Create the KEY token and append it to the queue. + token := yaml_token_t{ + typ: yaml_KEY_TOKEN, + start_mark: start_mark, + end_mark: end_mark, + } + yaml_insert_token(parser, -1, &token) + return true +} + +// Produce the VALUE token. +func yaml_parser_fetch_value(parser *yaml_parser_t) bool { + + simple_key := &parser.simple_keys[len(parser.simple_keys)-1] + + // Have we found a simple key? + if simple_key.possible { + // Create the KEY token and insert it into the queue. + token := yaml_token_t{ + typ: yaml_KEY_TOKEN, + start_mark: simple_key.mark, + end_mark: simple_key.mark, + } + yaml_insert_token(parser, simple_key.token_number-parser.tokens_parsed, &token) + + // In the block context, we may need to add the BLOCK-MAPPING-START token. + if !yaml_parser_roll_indent(parser, simple_key.mark.column, + simple_key.token_number, + yaml_BLOCK_MAPPING_START_TOKEN, simple_key.mark) { + return false + } + + // Remove the simple key. + simple_key.possible = false + + // A simple key cannot follow another simple key. + parser.simple_key_allowed = false + + } else { + // The ':' indicator follows a complex key. + + // In the block context, extra checks are required. + if parser.flow_level == 0 { + + // Check if we are allowed to start a complex value. + if !parser.simple_key_allowed { + return yaml_parser_set_scanner_error(parser, "", parser.mark, + "mapping values are not allowed in this context") + } + + // Add the BLOCK-MAPPING-START token if needed. + if !yaml_parser_roll_indent(parser, parser.mark.column, -1, yaml_BLOCK_MAPPING_START_TOKEN, parser.mark) { + return false + } + } + + // Simple keys after ':' are allowed in the block context. + parser.simple_key_allowed = parser.flow_level == 0 + } + + // Consume the token. + start_mark := parser.mark + skip(parser) + end_mark := parser.mark + + // Create the VALUE token and append it to the queue. + token := yaml_token_t{ + typ: yaml_VALUE_TOKEN, + start_mark: start_mark, + end_mark: end_mark, + } + yaml_insert_token(parser, -1, &token) + return true +} + +// Produce the ALIAS or ANCHOR token. +func yaml_parser_fetch_anchor(parser *yaml_parser_t, typ yaml_token_type_t) bool { + // An anchor or an alias could be a simple key. + if !yaml_parser_save_simple_key(parser) { + return false + } + + // A simple key cannot follow an anchor or an alias. + parser.simple_key_allowed = false + + // Create the ALIAS or ANCHOR token and append it to the queue. + var token yaml_token_t + if !yaml_parser_scan_anchor(parser, &token, typ) { + return false + } + yaml_insert_token(parser, -1, &token) + return true +} + +// Produce the TAG token. +func yaml_parser_fetch_tag(parser *yaml_parser_t) bool { + // A tag could be a simple key. + if !yaml_parser_save_simple_key(parser) { + return false + } + + // A simple key cannot follow a tag. + parser.simple_key_allowed = false + + // Create the TAG token and append it to the queue. + var token yaml_token_t + if !yaml_parser_scan_tag(parser, &token) { + return false + } + yaml_insert_token(parser, -1, &token) + return true +} + +// Produce the SCALAR(...,literal) or SCALAR(...,folded) tokens. +func yaml_parser_fetch_block_scalar(parser *yaml_parser_t, literal bool) bool { + // Remove any potential simple keys. + if !yaml_parser_remove_simple_key(parser) { + return false + } + + // A simple key may follow a block scalar. + parser.simple_key_allowed = true + + // Create the SCALAR token and append it to the queue. + var token yaml_token_t + if !yaml_parser_scan_block_scalar(parser, &token, literal) { + return false + } + yaml_insert_token(parser, -1, &token) + return true +} + +// Produce the SCALAR(...,single-quoted) or SCALAR(...,double-quoted) tokens. +func yaml_parser_fetch_flow_scalar(parser *yaml_parser_t, single bool) bool { + // A plain scalar could be a simple key. + if !yaml_parser_save_simple_key(parser) { + return false + } + + // A simple key cannot follow a flow scalar. + parser.simple_key_allowed = false + + // Create the SCALAR token and append it to the queue. + var token yaml_token_t + if !yaml_parser_scan_flow_scalar(parser, &token, single) { + return false + } + yaml_insert_token(parser, -1, &token) + return true +} + +// Produce the SCALAR(...,plain) token. +func yaml_parser_fetch_plain_scalar(parser *yaml_parser_t) bool { + // A plain scalar could be a simple key. + if !yaml_parser_save_simple_key(parser) { + return false + } + + // A simple key cannot follow a flow scalar. + parser.simple_key_allowed = false + + // Create the SCALAR token and append it to the queue. + var token yaml_token_t + if !yaml_parser_scan_plain_scalar(parser, &token) { + return false + } + yaml_insert_token(parser, -1, &token) + return true +} + +// Eat whitespaces and comments until the next token is found. +func yaml_parser_scan_to_next_token(parser *yaml_parser_t) bool { + + // Until the next token is not found. + for { + // Allow the BOM mark to start a line. + if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { + return false + } + if parser.mark.column == 0 && is_bom(parser.buffer, parser.buffer_pos) { + skip(parser) + } + + // Eat whitespaces. + // Tabs are allowed: + // - in the flow context + // - in the block context, but not at the beginning of the line or + // after '-', '?', or ':' (complex value). + if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { + return false + } + + for parser.buffer[parser.buffer_pos] == ' ' || ((parser.flow_level > 0 || !parser.simple_key_allowed) && parser.buffer[parser.buffer_pos] == '\t') { + skip(parser) + if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { + return false + } + } + + // Eat a comment until a line break. + if parser.buffer[parser.buffer_pos] == '#' { + for !is_breakz(parser.buffer, parser.buffer_pos) { + skip(parser) + if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { + return false + } + } + } + + // If it is a line break, eat it. + if is_break(parser.buffer, parser.buffer_pos) { + if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) { + return false + } + skip_line(parser) + + // In the block context, a new line may start a simple key. + if parser.flow_level == 0 { + parser.simple_key_allowed = true + } + } else { + break // We have found a token. + } + } + + return true +} + +// Scan a YAML-DIRECTIVE or TAG-DIRECTIVE token. +// +// Scope: +// %YAML 1.1 # a comment \n +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +// %TAG !yaml! tag:yaml.org,2002: \n +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +// +func yaml_parser_scan_directive(parser *yaml_parser_t, token *yaml_token_t) bool { + // Eat '%'. + start_mark := parser.mark + skip(parser) + + // Scan the directive name. + var name []byte + if !yaml_parser_scan_directive_name(parser, start_mark, &name) { + return false + } + + // Is it a YAML directive? + if bytes.Equal(name, []byte("YAML")) { + // Scan the VERSION directive value. + var major, minor int8 + if !yaml_parser_scan_version_directive_value(parser, start_mark, &major, &minor) { + return false + } + end_mark := parser.mark + + // Create a VERSION-DIRECTIVE token. + *token = yaml_token_t{ + typ: yaml_VERSION_DIRECTIVE_TOKEN, + start_mark: start_mark, + end_mark: end_mark, + major: major, + minor: minor, + } + + // Is it a TAG directive? + } else if bytes.Equal(name, []byte("TAG")) { + // Scan the TAG directive value. + var handle, prefix []byte + if !yaml_parser_scan_tag_directive_value(parser, start_mark, &handle, &prefix) { + return false + } + end_mark := parser.mark + + // Create a TAG-DIRECTIVE token. + *token = yaml_token_t{ + typ: yaml_TAG_DIRECTIVE_TOKEN, + start_mark: start_mark, + end_mark: end_mark, + value: handle, + prefix: prefix, + } + + // Unknown directive. + } else { + yaml_parser_set_scanner_error(parser, "while scanning a directive", + start_mark, "found uknown directive name") + return false + } + + // Eat the rest of the line including any comments. + if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { + return false + } + + for is_blank(parser.buffer, parser.buffer_pos) { + skip(parser) + if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { + return false + } + } + + if parser.buffer[parser.buffer_pos] == '#' { + for !is_breakz(parser.buffer, parser.buffer_pos) { + skip(parser) + if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { + return false + } + } + } + + // Check if we are at the end of the line. + if !is_breakz(parser.buffer, parser.buffer_pos) { + yaml_parser_set_scanner_error(parser, "while scanning a directive", + start_mark, "did not find expected comment or line break") + return false + } + + // Eat a line break. + if is_break(parser.buffer, parser.buffer_pos) { + if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) { + return false + } + skip_line(parser) + } + + return true +} + +// Scan the directive name. +// +// Scope: +// %YAML 1.1 # a comment \n +// ^^^^ +// %TAG !yaml! tag:yaml.org,2002: \n +// ^^^ +// +func yaml_parser_scan_directive_name(parser *yaml_parser_t, start_mark yaml_mark_t, name *[]byte) bool { + // Consume the directive name. + if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { + return false + } + + var s []byte + for is_alpha(parser.buffer, parser.buffer_pos) { + s = read(parser, s) + if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { + return false + } + } + + // Check if the name is empty. + if len(s) == 0 { + yaml_parser_set_scanner_error(parser, "while scanning a directive", + start_mark, "could not find expected directive name") + return false + } + + // Check for an blank character after the name. + if !is_blankz(parser.buffer, parser.buffer_pos) { + yaml_parser_set_scanner_error(parser, "while scanning a directive", + start_mark, "found unexpected non-alphabetical character") + return false + } + *name = s + return true +} + +// Scan the value of VERSION-DIRECTIVE. +// +// Scope: +// %YAML 1.1 # a comment \n +// ^^^^^^ +func yaml_parser_scan_version_directive_value(parser *yaml_parser_t, start_mark yaml_mark_t, major, minor *int8) bool { + // Eat whitespaces. + if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { + return false + } + for is_blank(parser.buffer, parser.buffer_pos) { + skip(parser) + if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { + return false + } + } + + // Consume the major version number. + if !yaml_parser_scan_version_directive_number(parser, start_mark, major) { + return false + } + + // Eat '.'. + if parser.buffer[parser.buffer_pos] != '.' { + return yaml_parser_set_scanner_error(parser, "while scanning a %YAML directive", + start_mark, "did not find expected digit or '.' character") + } + + skip(parser) + + // Consume the minor version number. + if !yaml_parser_scan_version_directive_number(parser, start_mark, minor) { + return false + } + return true +} + +const max_number_length = 2 + +// Scan the version number of VERSION-DIRECTIVE. +// +// Scope: +// %YAML 1.1 # a comment \n +// ^ +// %YAML 1.1 # a comment \n +// ^ +func yaml_parser_scan_version_directive_number(parser *yaml_parser_t, start_mark yaml_mark_t, number *int8) bool { + + // Repeat while the next character is digit. + if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { + return false + } + var value, length int8 + for is_digit(parser.buffer, parser.buffer_pos) { + // Check if the number is too long. + length++ + if length > max_number_length { + return yaml_parser_set_scanner_error(parser, "while scanning a %YAML directive", + start_mark, "found extremely long version number") + } + value = value*10 + int8(as_digit(parser.buffer, parser.buffer_pos)) + skip(parser) + if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { + return false + } + } + + // Check if the number was present. + if length == 0 { + return yaml_parser_set_scanner_error(parser, "while scanning a %YAML directive", + start_mark, "did not find expected version number") + } + *number = value + return true +} + +// Scan the value of a TAG-DIRECTIVE token. +// +// Scope: +// %TAG !yaml! tag:yaml.org,2002: \n +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +// +func yaml_parser_scan_tag_directive_value(parser *yaml_parser_t, start_mark yaml_mark_t, handle, prefix *[]byte) bool { + var handle_value, prefix_value []byte + + // Eat whitespaces. + if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { + return false + } + + for is_blank(parser.buffer, parser.buffer_pos) { + skip(parser) + if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { + return false + } + } + + // Scan a handle. + if !yaml_parser_scan_tag_handle(parser, true, start_mark, &handle_value) { + return false + } + + // Expect a whitespace. + if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { + return false + } + if !is_blank(parser.buffer, parser.buffer_pos) { + yaml_parser_set_scanner_error(parser, "while scanning a %TAG directive", + start_mark, "did not find expected whitespace") + return false + } + + // Eat whitespaces. + for is_blank(parser.buffer, parser.buffer_pos) { + skip(parser) + if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { + return false + } + } + + // Scan a prefix. + if !yaml_parser_scan_tag_uri(parser, true, nil, start_mark, &prefix_value) { + return false + } + + // Expect a whitespace or line break. + if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { + return false + } + if !is_blankz(parser.buffer, parser.buffer_pos) { + yaml_parser_set_scanner_error(parser, "while scanning a %TAG directive", + start_mark, "did not find expected whitespace or line break") + return false + } + + *handle = handle_value + *prefix = prefix_value + return true +} + +func yaml_parser_scan_anchor(parser *yaml_parser_t, token *yaml_token_t, typ yaml_token_type_t) bool { + var s []byte + + // Eat the indicator character. + start_mark := parser.mark + skip(parser) + + // Consume the value. + if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { + return false + } + + for is_alpha(parser.buffer, parser.buffer_pos) { + s = read(parser, s) + if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { + return false + } + } + + end_mark := parser.mark + + /* + * Check if length of the anchor is greater than 0 and it is followed by + * a whitespace character or one of the indicators: + * + * '?', ':', ',', ']', '}', '%', '@', '`'. + */ + + if len(s) == 0 || + !(is_blankz(parser.buffer, parser.buffer_pos) || parser.buffer[parser.buffer_pos] == '?' || + parser.buffer[parser.buffer_pos] == ':' || parser.buffer[parser.buffer_pos] == ',' || + parser.buffer[parser.buffer_pos] == ']' || parser.buffer[parser.buffer_pos] == '}' || + parser.buffer[parser.buffer_pos] == '%' || parser.buffer[parser.buffer_pos] == '@' || + parser.buffer[parser.buffer_pos] == '`') { + context := "while scanning an alias" + if typ == yaml_ANCHOR_TOKEN { + context = "while scanning an anchor" + } + yaml_parser_set_scanner_error(parser, context, start_mark, + "did not find expected alphabetic or numeric character") + return false + } + + // Create a token. + *token = yaml_token_t{ + typ: typ, + start_mark: start_mark, + end_mark: end_mark, + value: s, + } + + return true +} + +/* + * Scan a TAG token. + */ + +func yaml_parser_scan_tag(parser *yaml_parser_t, token *yaml_token_t) bool { + var handle, suffix []byte + + start_mark := parser.mark + + // Check if the tag is in the canonical form. + if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) { + return false + } + + if parser.buffer[parser.buffer_pos+1] == '<' { + // Keep the handle as '' + + // Eat '!<' + skip(parser) + skip(parser) + + // Consume the tag value. + if !yaml_parser_scan_tag_uri(parser, false, nil, start_mark, &suffix) { + return false + } + + // Check for '>' and eat it. + if parser.buffer[parser.buffer_pos] != '>' { + yaml_parser_set_scanner_error(parser, "while scanning a tag", + start_mark, "did not find the expected '>'") + return false + } + + skip(parser) + } else { + // The tag has either the '!suffix' or the '!handle!suffix' form. + + // First, try to scan a handle. + if !yaml_parser_scan_tag_handle(parser, false, start_mark, &handle) { + return false + } + + // Check if it is, indeed, handle. + if handle[0] == '!' && len(handle) > 1 && handle[len(handle)-1] == '!' { + // Scan the suffix now. + if !yaml_parser_scan_tag_uri(parser, false, nil, start_mark, &suffix) { + return false + } + } else { + // It wasn't a handle after all. Scan the rest of the tag. + if !yaml_parser_scan_tag_uri(parser, false, handle, start_mark, &suffix) { + return false + } + + // Set the handle to '!'. + handle = []byte{'!'} + + // A special case: the '!' tag. Set the handle to '' and the + // suffix to '!'. + if len(suffix) == 0 { + handle, suffix = suffix, handle + } + } + } + + // Check the character which ends the tag. + if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { + return false + } + if !is_blankz(parser.buffer, parser.buffer_pos) { + yaml_parser_set_scanner_error(parser, "while scanning a tag", + start_mark, "did not find expected whitespace or line break") + return false + } + + end_mark := parser.mark + + // Create a token. + *token = yaml_token_t{ + typ: yaml_TAG_TOKEN, + start_mark: start_mark, + end_mark: end_mark, + value: handle, + suffix: suffix, + } + return true +} + +// Scan a tag handle. +func yaml_parser_scan_tag_handle(parser *yaml_parser_t, directive bool, start_mark yaml_mark_t, handle *[]byte) bool { + // Check the initial '!' character. + if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { + return false + } + if parser.buffer[parser.buffer_pos] != '!' { + yaml_parser_set_scanner_tag_error(parser, directive, + start_mark, "did not find expected '!'") + return false + } + + var s []byte + + // Copy the '!' character. + s = read(parser, s) + + // Copy all subsequent alphabetical and numerical characters. + if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { + return false + } + for is_alpha(parser.buffer, parser.buffer_pos) { + s = read(parser, s) + if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { + return false + } + } + + // Check if the trailing character is '!' and copy it. + if parser.buffer[parser.buffer_pos] == '!' { + s = read(parser, s) + } else { + // It's either the '!' tag or not really a tag handle. If it's a %TAG + // directive, it's an error. If it's a tag token, it must be a part of URI. + if directive && !(s[0] == '!' && s[1] == 0) { + yaml_parser_set_scanner_tag_error(parser, directive, + start_mark, "did not find expected '!'") + return false + } + } + + *handle = s + return true +} + +// Scan a tag. +func yaml_parser_scan_tag_uri(parser *yaml_parser_t, directive bool, head []byte, start_mark yaml_mark_t, uri *[]byte) bool { + //size_t length = head ? strlen((char *)head) : 0 + var s []byte + + // Copy the head if needed. + // + // Note that we don't copy the leading '!' character. + if len(head) > 1 { + s = append(s, head[1:]...) + } + + // Scan the tag. + if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { + return false + } + + // The set of characters that may appear in URI is as follows: + // + // '0'-'9', 'A'-'Z', 'a'-'z', '_', '-', ';', '/', '?', ':', '@', '&', + // '=', '+', '$', ',', '.', '!', '~', '*', '\'', '(', ')', '[', ']', + // '%'. + // [Go] Convert this into more reasonable logic. + for is_alpha(parser.buffer, parser.buffer_pos) || parser.buffer[parser.buffer_pos] == ';' || + parser.buffer[parser.buffer_pos] == '/' || parser.buffer[parser.buffer_pos] == '?' || + parser.buffer[parser.buffer_pos] == ':' || parser.buffer[parser.buffer_pos] == '@' || + parser.buffer[parser.buffer_pos] == '&' || parser.buffer[parser.buffer_pos] == '=' || + parser.buffer[parser.buffer_pos] == '+' || parser.buffer[parser.buffer_pos] == '$' || + parser.buffer[parser.buffer_pos] == ',' || parser.buffer[parser.buffer_pos] == '.' || + parser.buffer[parser.buffer_pos] == '!' || parser.buffer[parser.buffer_pos] == '~' || + parser.buffer[parser.buffer_pos] == '*' || parser.buffer[parser.buffer_pos] == '\'' || + parser.buffer[parser.buffer_pos] == '(' || parser.buffer[parser.buffer_pos] == ')' || + parser.buffer[parser.buffer_pos] == '[' || parser.buffer[parser.buffer_pos] == ']' || + parser.buffer[parser.buffer_pos] == '%' { + // Check if it is a URI-escape sequence. + if parser.buffer[parser.buffer_pos] == '%' { + if !yaml_parser_scan_uri_escapes(parser, directive, start_mark, &s) { + return false + } + } else { + s = read(parser, s) + } + if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { + return false + } + } + + // Check if the tag is non-empty. + if len(s) == 0 { + yaml_parser_set_scanner_tag_error(parser, directive, + start_mark, "did not find expected tag URI") + return false + } + *uri = s + return true +} + +// Decode an URI-escape sequence corresponding to a single UTF-8 character. +func yaml_parser_scan_uri_escapes(parser *yaml_parser_t, directive bool, start_mark yaml_mark_t, s *[]byte) bool { + + // Decode the required number of characters. + w := 1024 + for w > 0 { + // Check for a URI-escaped octet. + if parser.unread < 3 && !yaml_parser_update_buffer(parser, 3) { + return false + } + + if !(parser.buffer[parser.buffer_pos] == '%' && + is_hex(parser.buffer, parser.buffer_pos+1) && + is_hex(parser.buffer, parser.buffer_pos+2)) { + return yaml_parser_set_scanner_tag_error(parser, directive, + start_mark, "did not find URI escaped octet") + } + + // Get the octet. + octet := byte((as_hex(parser.buffer, parser.buffer_pos+1) << 4) + as_hex(parser.buffer, parser.buffer_pos+2)) + + // If it is the leading octet, determine the length of the UTF-8 sequence. + if w == 1024 { + w = width(octet) + if w == 0 { + return yaml_parser_set_scanner_tag_error(parser, directive, + start_mark, "found an incorrect leading UTF-8 octet") + } + } else { + // Check if the trailing octet is correct. + if octet&0xC0 != 0x80 { + return yaml_parser_set_scanner_tag_error(parser, directive, + start_mark, "found an incorrect trailing UTF-8 octet") + } + } + + // Copy the octet and move the pointers. + *s = append(*s, octet) + skip(parser) + skip(parser) + skip(parser) + w-- + } + return true +} + +// Scan a block scalar. +func yaml_parser_scan_block_scalar(parser *yaml_parser_t, token *yaml_token_t, literal bool) bool { + // Eat the indicator '|' or '>'. + start_mark := parser.mark + skip(parser) + + // Scan the additional block scalar indicators. + if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { + return false + } + + // Check for a chomping indicator. + var chomping, increment int + if parser.buffer[parser.buffer_pos] == '+' || parser.buffer[parser.buffer_pos] == '-' { + // Set the chomping method and eat the indicator. + if parser.buffer[parser.buffer_pos] == '+' { + chomping = +1 + } else { + chomping = -1 + } + skip(parser) + + // Check for an indentation indicator. + if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { + return false + } + if is_digit(parser.buffer, parser.buffer_pos) { + // Check that the intendation is greater than 0. + if parser.buffer[parser.buffer_pos] == '0' { + yaml_parser_set_scanner_error(parser, "while scanning a block scalar", + start_mark, "found an intendation indicator equal to 0") + return false + } + + // Get the intendation level and eat the indicator. + increment = as_digit(parser.buffer, parser.buffer_pos) + skip(parser) + } + + } else if is_digit(parser.buffer, parser.buffer_pos) { + // Do the same as above, but in the opposite order. + + if parser.buffer[parser.buffer_pos] == '0' { + yaml_parser_set_scanner_error(parser, "while scanning a block scalar", + start_mark, "found an intendation indicator equal to 0") + return false + } + increment = as_digit(parser.buffer, parser.buffer_pos) + skip(parser) + + if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { + return false + } + if parser.buffer[parser.buffer_pos] == '+' || parser.buffer[parser.buffer_pos] == '-' { + if parser.buffer[parser.buffer_pos] == '+' { + chomping = +1 + } else { + chomping = -1 + } + skip(parser) + } + } + + // Eat whitespaces and comments to the end of the line. + if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { + return false + } + for is_blank(parser.buffer, parser.buffer_pos) { + skip(parser) + if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { + return false + } + } + if parser.buffer[parser.buffer_pos] == '#' { + for !is_breakz(parser.buffer, parser.buffer_pos) { + skip(parser) + if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { + return false + } + } + } + + // Check if we are at the end of the line. + if !is_breakz(parser.buffer, parser.buffer_pos) { + yaml_parser_set_scanner_error(parser, "while scanning a block scalar", + start_mark, "did not find expected comment or line break") + return false + } + + // Eat a line break. + if is_break(parser.buffer, parser.buffer_pos) { + if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) { + return false + } + skip_line(parser) + } + + end_mark := parser.mark + + // Set the intendation level if it was specified. + var indent int + if increment > 0 { + if parser.indent >= 0 { + indent = parser.indent + increment + } else { + indent = increment + } + } + + // Scan the leading line breaks and determine the indentation level if needed. + var s, leading_break, trailing_breaks []byte + if !yaml_parser_scan_block_scalar_breaks(parser, &indent, &trailing_breaks, start_mark, &end_mark) { + return false + } + + // Scan the block scalar content. + if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { + return false + } + var leading_blank, trailing_blank bool + for parser.mark.column == indent && !is_z(parser.buffer, parser.buffer_pos) { + // We are at the beginning of a non-empty line. + + // Is it a trailing whitespace? + trailing_blank = is_blank(parser.buffer, parser.buffer_pos) + + // Check if we need to fold the leading line break. + if !literal && !leading_blank && !trailing_blank && len(leading_break) > 0 && leading_break[0] == '\n' { + // Do we need to join the lines by space? + if len(trailing_breaks) == 0 { + s = append(s, ' ') + } + } else { + s = append(s, leading_break...) + } + leading_break = leading_break[:0] + + // Append the remaining line breaks. + s = append(s, trailing_breaks...) + trailing_breaks = trailing_breaks[:0] + + // Is it a leading whitespace? + leading_blank = is_blank(parser.buffer, parser.buffer_pos) + + // Consume the current line. + for !is_breakz(parser.buffer, parser.buffer_pos) { + s = read(parser, s) + if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { + return false + } + } + + // Consume the line break. + if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) { + return false + } + + leading_break = read_line(parser, leading_break) + + // Eat the following intendation spaces and line breaks. + if !yaml_parser_scan_block_scalar_breaks(parser, &indent, &trailing_breaks, start_mark, &end_mark) { + return false + } + } + + // Chomp the tail. + if chomping != -1 { + s = append(s, leading_break...) + } + if chomping == 1 { + s = append(s, trailing_breaks...) + } + + // Create a token. + *token = yaml_token_t{ + typ: yaml_SCALAR_TOKEN, + start_mark: start_mark, + end_mark: end_mark, + value: s, + style: yaml_LITERAL_SCALAR_STYLE, + } + if !literal { + token.style = yaml_FOLDED_SCALAR_STYLE + } + return true +} + +// Scan intendation spaces and line breaks for a block scalar. Determine the +// intendation level if needed. +func yaml_parser_scan_block_scalar_breaks(parser *yaml_parser_t, indent *int, breaks *[]byte, start_mark yaml_mark_t, end_mark *yaml_mark_t) bool { + *end_mark = parser.mark + + // Eat the intendation spaces and line breaks. + max_indent := 0 + for { + // Eat the intendation spaces. + if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { + return false + } + for (*indent == 0 || parser.mark.column < *indent) && is_space(parser.buffer, parser.buffer_pos) { + skip(parser) + if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { + return false + } + } + if parser.mark.column > max_indent { + max_indent = parser.mark.column + } + + // Check for a tab character messing the intendation. + if (*indent == 0 || parser.mark.column < *indent) && is_tab(parser.buffer, parser.buffer_pos) { + return yaml_parser_set_scanner_error(parser, "while scanning a block scalar", + start_mark, "found a tab character where an intendation space is expected") + } + + // Have we found a non-empty line? + if !is_break(parser.buffer, parser.buffer_pos) { + break + } + + // Consume the line break. + if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) { + return false + } + // [Go] Should really be returning breaks instead. + *breaks = read_line(parser, *breaks) + *end_mark = parser.mark + } + + // Determine the indentation level if needed. + if *indent == 0 { + *indent = max_indent + if *indent < parser.indent+1 { + *indent = parser.indent + 1 + } + if *indent < 1 { + *indent = 1 + } + } + return true +} + +// Scan a quoted scalar. +func yaml_parser_scan_flow_scalar(parser *yaml_parser_t, token *yaml_token_t, single bool) bool { + // Eat the left quote. + start_mark := parser.mark + skip(parser) + + // Consume the content of the quoted scalar. + var s, leading_break, trailing_breaks, whitespaces []byte + for { + // Check that there are no document indicators at the beginning of the line. + if parser.unread < 4 && !yaml_parser_update_buffer(parser, 4) { + return false + } + + if parser.mark.column == 0 && + ((parser.buffer[parser.buffer_pos+0] == '-' && + parser.buffer[parser.buffer_pos+1] == '-' && + parser.buffer[parser.buffer_pos+2] == '-') || + (parser.buffer[parser.buffer_pos+0] == '.' && + parser.buffer[parser.buffer_pos+1] == '.' && + parser.buffer[parser.buffer_pos+2] == '.')) && + is_blankz(parser.buffer, parser.buffer_pos+3) { + yaml_parser_set_scanner_error(parser, "while scanning a quoted scalar", + start_mark, "found unexpected document indicator") + return false + } + + // Check for EOF. + if is_z(parser.buffer, parser.buffer_pos) { + yaml_parser_set_scanner_error(parser, "while scanning a quoted scalar", + start_mark, "found unexpected end of stream") + return false + } + + // Consume non-blank characters. + leading_blanks := false + for !is_blankz(parser.buffer, parser.buffer_pos) { + if single && parser.buffer[parser.buffer_pos] == '\'' && parser.buffer[parser.buffer_pos+1] == '\'' { + // Is is an escaped single quote. + s = append(s, '\'') + skip(parser) + skip(parser) + + } else if single && parser.buffer[parser.buffer_pos] == '\'' { + // It is a right single quote. + break + } else if !single && parser.buffer[parser.buffer_pos] == '"' { + // It is a right double quote. + break + + } else if !single && parser.buffer[parser.buffer_pos] == '\\' && is_break(parser.buffer, parser.buffer_pos+1) { + // It is an escaped line break. + if parser.unread < 3 && !yaml_parser_update_buffer(parser, 3) { + return false + } + skip(parser) + skip_line(parser) + leading_blanks = true + break + + } else if !single && parser.buffer[parser.buffer_pos] == '\\' { + // It is an escape sequence. + code_length := 0 + + // Check the escape character. + switch parser.buffer[parser.buffer_pos+1] { + case '0': + s = append(s, 0) + case 'a': + s = append(s, '\x07') + case 'b': + s = append(s, '\x08') + case 't', '\t': + s = append(s, '\x09') + case 'n': + s = append(s, '\x0A') + case 'v': + s = append(s, '\x0B') + case 'f': + s = append(s, '\x0C') + case 'r': + s = append(s, '\x0D') + case 'e': + s = append(s, '\x1B') + case ' ': + s = append(s, '\x20') + case '"': + s = append(s, '"') + case '\'': + s = append(s, '\'') + case '\\': + s = append(s, '\\') + case 'N': // NEL (#x85) + s = append(s, '\xC2') + s = append(s, '\x85') + case '_': // #xA0 + s = append(s, '\xC2') + s = append(s, '\xA0') + case 'L': // LS (#x2028) + s = append(s, '\xE2') + s = append(s, '\x80') + s = append(s, '\xA8') + case 'P': // PS (#x2029) + s = append(s, '\xE2') + s = append(s, '\x80') + s = append(s, '\xA9') + case 'x': + code_length = 2 + case 'u': + code_length = 4 + case 'U': + code_length = 8 + default: + yaml_parser_set_scanner_error(parser, "while parsing a quoted scalar", + start_mark, "found unknown escape character") + return false + } + + skip(parser) + skip(parser) + + // Consume an arbitrary escape code. + if code_length > 0 { + var value int + + // Scan the character value. + if parser.unread < code_length && !yaml_parser_update_buffer(parser, code_length) { + return false + } + for k := 0; k < code_length; k++ { + if !is_hex(parser.buffer, parser.buffer_pos+k) { + yaml_parser_set_scanner_error(parser, "while parsing a quoted scalar", + start_mark, "did not find expected hexdecimal number") + return false + } + value = (value << 4) + as_hex(parser.buffer, parser.buffer_pos+k) + } + + // Check the value and write the character. + if (value >= 0xD800 && value <= 0xDFFF) || value > 0x10FFFF { + yaml_parser_set_scanner_error(parser, "while parsing a quoted scalar", + start_mark, "found invalid Unicode character escape code") + return false + } + if value <= 0x7F { + s = append(s, byte(value)) + } else if value <= 0x7FF { + s = append(s, byte(0xC0+(value>>6))) + s = append(s, byte(0x80+(value&0x3F))) + } else if value <= 0xFFFF { + s = append(s, byte(0xE0+(value>>12))) + s = append(s, byte(0x80+((value>>6)&0x3F))) + s = append(s, byte(0x80+(value&0x3F))) + } else { + s = append(s, byte(0xF0+(value>>18))) + s = append(s, byte(0x80+((value>>12)&0x3F))) + s = append(s, byte(0x80+((value>>6)&0x3F))) + s = append(s, byte(0x80+(value&0x3F))) + } + + // Advance the pointer. + for k := 0; k < code_length; k++ { + skip(parser) + } + } + } else { + // It is a non-escaped non-blank character. + s = read(parser, s) + } + if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) { + return false + } + } + + // Check if we are at the end of the scalar. + if single { + if parser.buffer[parser.buffer_pos] == '\'' { + break + } + } else { + if parser.buffer[parser.buffer_pos] == '"' { + break + } + } + + // Consume blank characters. + if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { + return false + } + + for is_blank(parser.buffer, parser.buffer_pos) || is_break(parser.buffer, parser.buffer_pos) { + if is_blank(parser.buffer, parser.buffer_pos) { + // Consume a space or a tab character. + if !leading_blanks { + whitespaces = read(parser, whitespaces) + } else { + skip(parser) + } + } else { + if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) { + return false + } + + // Check if it is a first line break. + if !leading_blanks { + whitespaces = whitespaces[:0] + leading_break = read_line(parser, leading_break) + leading_blanks = true + } else { + trailing_breaks = read_line(parser, trailing_breaks) + } + } + if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { + return false + } + } + + // Join the whitespaces or fold line breaks. + if leading_blanks { + // Do we need to fold line breaks? + if len(leading_break) > 0 && leading_break[0] == '\n' { + if len(trailing_breaks) == 0 { + s = append(s, ' ') + } else { + s = append(s, trailing_breaks...) + } + } else { + s = append(s, leading_break...) + s = append(s, trailing_breaks...) + } + trailing_breaks = trailing_breaks[:0] + leading_break = leading_break[:0] + } else { + s = append(s, whitespaces...) + whitespaces = whitespaces[:0] + } + } + + // Eat the right quote. + skip(parser) + end_mark := parser.mark + + // Create a token. + *token = yaml_token_t{ + typ: yaml_SCALAR_TOKEN, + start_mark: start_mark, + end_mark: end_mark, + value: s, + style: yaml_SINGLE_QUOTED_SCALAR_STYLE, + } + if !single { + token.style = yaml_DOUBLE_QUOTED_SCALAR_STYLE + } + return true +} + +// Scan a plain scalar. +func yaml_parser_scan_plain_scalar(parser *yaml_parser_t, token *yaml_token_t) bool { + + var s, leading_break, trailing_breaks, whitespaces []byte + var leading_blanks bool + var indent = parser.indent + 1 + + start_mark := parser.mark + end_mark := parser.mark + + // Consume the content of the plain scalar. + for { + // Check for a document indicator. + if parser.unread < 4 && !yaml_parser_update_buffer(parser, 4) { + return false + } + if parser.mark.column == 0 && + ((parser.buffer[parser.buffer_pos+0] == '-' && + parser.buffer[parser.buffer_pos+1] == '-' && + parser.buffer[parser.buffer_pos+2] == '-') || + (parser.buffer[parser.buffer_pos+0] == '.' && + parser.buffer[parser.buffer_pos+1] == '.' && + parser.buffer[parser.buffer_pos+2] == '.')) && + is_blankz(parser.buffer, parser.buffer_pos+3) { + break + } + + // Check for a comment. + if parser.buffer[parser.buffer_pos] == '#' { + break + } + + // Consume non-blank characters. + for !is_blankz(parser.buffer, parser.buffer_pos) { + + // Check for 'x:x' in the flow context. TODO: Fix the test "spec-08-13". + if parser.flow_level > 0 && + parser.buffer[parser.buffer_pos] == ':' && + !is_blankz(parser.buffer, parser.buffer_pos+1) { + yaml_parser_set_scanner_error(parser, "while scanning a plain scalar", + start_mark, "found unexpected ':'") + return false + } + + // Check for indicators that may end a plain scalar. + if (parser.buffer[parser.buffer_pos] == ':' && is_blankz(parser.buffer, parser.buffer_pos+1)) || + (parser.flow_level > 0 && + (parser.buffer[parser.buffer_pos] == ',' || parser.buffer[parser.buffer_pos] == ':' || + parser.buffer[parser.buffer_pos] == '?' || parser.buffer[parser.buffer_pos] == '[' || + parser.buffer[parser.buffer_pos] == ']' || parser.buffer[parser.buffer_pos] == '{' || + parser.buffer[parser.buffer_pos] == '}')) { + break + } + + // Check if we need to join whitespaces and breaks. + if leading_blanks || len(whitespaces) > 0 { + if leading_blanks { + // Do we need to fold line breaks? + if leading_break[0] == '\n' { + if len(trailing_breaks) == 0 { + s = append(s, ' ') + } else { + s = append(s, trailing_breaks...) + } + } else { + s = append(s, leading_break...) + s = append(s, trailing_breaks...) + } + trailing_breaks = trailing_breaks[:0] + leading_break = leading_break[:0] + leading_blanks = false + } else { + s = append(s, whitespaces...) + whitespaces = whitespaces[:0] + } + } + + // Copy the character. + s = read(parser, s) + + end_mark = parser.mark + if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) { + return false + } + } + + // Is it the end? + if !(is_blank(parser.buffer, parser.buffer_pos) || is_break(parser.buffer, parser.buffer_pos)) { + break + } + + // Consume blank characters. + if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { + return false + } + + for is_blank(parser.buffer, parser.buffer_pos) || is_break(parser.buffer, parser.buffer_pos) { + if is_blank(parser.buffer, parser.buffer_pos) { + + // Check for tab character that abuse intendation. + if leading_blanks && parser.mark.column < indent && is_tab(parser.buffer, parser.buffer_pos) { + yaml_parser_set_scanner_error(parser, "while scanning a plain scalar", + start_mark, "found a tab character that violate intendation") + return false + } + + // Consume a space or a tab character. + if !leading_blanks { + whitespaces = read(parser, whitespaces) + } else { + skip(parser) + } + } else { + if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) { + return false + } + + // Check if it is a first line break. + if !leading_blanks { + whitespaces = whitespaces[:0] + leading_break = read_line(parser, leading_break) + leading_blanks = true + } else { + trailing_breaks = read_line(parser, trailing_breaks) + } + } + if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { + return false + } + } + + // Check intendation level. + if parser.flow_level == 0 && parser.mark.column < indent { + break + } + } + + // Create a token. + *token = yaml_token_t{ + typ: yaml_SCALAR_TOKEN, + start_mark: start_mark, + end_mark: end_mark, + value: s, + style: yaml_PLAIN_SCALAR_STYLE, + } + + // Note that we change the 'simple_key_allowed' flag. + if leading_blanks { + parser.simple_key_allowed = true + } + return true +} diff --git a/vendor/gopkg.in/yaml.v2/sorter.go b/vendor/gopkg.in/yaml.v2/sorter.go new file mode 100644 index 0000000..5958822 --- /dev/null +++ b/vendor/gopkg.in/yaml.v2/sorter.go @@ -0,0 +1,104 @@ +package yaml + +import ( + "reflect" + "unicode" +) + +type keyList []reflect.Value + +func (l keyList) Len() int { return len(l) } +func (l keyList) Swap(i, j int) { l[i], l[j] = l[j], l[i] } +func (l keyList) Less(i, j int) bool { + a := l[i] + b := l[j] + ak := a.Kind() + bk := b.Kind() + for (ak == reflect.Interface || ak == reflect.Ptr) && !a.IsNil() { + a = a.Elem() + ak = a.Kind() + } + for (bk == reflect.Interface || bk == reflect.Ptr) && !b.IsNil() { + b = b.Elem() + bk = b.Kind() + } + af, aok := keyFloat(a) + bf, bok := keyFloat(b) + if aok && bok { + if af != bf { + return af < bf + } + if ak != bk { + return ak < bk + } + return numLess(a, b) + } + if ak != reflect.String || bk != reflect.String { + return ak < bk + } + ar, br := []rune(a.String()), []rune(b.String()) + for i := 0; i < len(ar) && i < len(br); i++ { + if ar[i] == br[i] { + continue + } + al := unicode.IsLetter(ar[i]) + bl := unicode.IsLetter(br[i]) + if al && bl { + return ar[i] < br[i] + } + if al || bl { + return bl + } + var ai, bi int + var an, bn int64 + for ai = i; ai < len(ar) && unicode.IsDigit(ar[ai]); ai++ { + an = an*10 + int64(ar[ai]-'0') + } + for bi = i; bi < len(br) && unicode.IsDigit(br[bi]); bi++ { + bn = bn*10 + int64(br[bi]-'0') + } + if an != bn { + return an < bn + } + if ai != bi { + return ai < bi + } + return ar[i] < br[i] + } + return len(ar) < len(br) +} + +// keyFloat returns a float value for v if it is a number/bool +// and whether it is a number/bool or not. +func keyFloat(v reflect.Value) (f float64, ok bool) { + switch v.Kind() { + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return float64(v.Int()), true + case reflect.Float32, reflect.Float64: + return v.Float(), true + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + return float64(v.Uint()), true + case reflect.Bool: + if v.Bool() { + return 1, true + } + return 0, true + } + return 0, false +} + +// numLess returns whether a < b. +// a and b must necessarily have the same kind. +func numLess(a, b reflect.Value) bool { + switch a.Kind() { + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return a.Int() < b.Int() + case reflect.Float32, reflect.Float64: + return a.Float() < b.Float() + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + return a.Uint() < b.Uint() + case reflect.Bool: + return !a.Bool() && b.Bool() + } + panic("not a number") +} diff --git a/vendor/gopkg.in/yaml.v2/writerc.go b/vendor/gopkg.in/yaml.v2/writerc.go new file mode 100644 index 0000000..190362f --- /dev/null +++ b/vendor/gopkg.in/yaml.v2/writerc.go @@ -0,0 +1,89 @@ +package yaml + +// Set the writer error and return false. +func yaml_emitter_set_writer_error(emitter *yaml_emitter_t, problem string) bool { + emitter.error = yaml_WRITER_ERROR + emitter.problem = problem + return false +} + +// Flush the output buffer. +func yaml_emitter_flush(emitter *yaml_emitter_t) bool { + if emitter.write_handler == nil { + panic("write handler not set") + } + + // Check if the buffer is empty. + if emitter.buffer_pos == 0 { + return true + } + + // If the output encoding is UTF-8, we don't need to recode the buffer. + if emitter.encoding == yaml_UTF8_ENCODING { + if err := emitter.write_handler(emitter, emitter.buffer[:emitter.buffer_pos]); err != nil { + return yaml_emitter_set_writer_error(emitter, "write error: "+err.Error()) + } + emitter.buffer_pos = 0 + return true + } + + // Recode the buffer into the raw buffer. + var low, high int + if emitter.encoding == yaml_UTF16LE_ENCODING { + low, high = 0, 1 + } else { + high, low = 1, 0 + } + + pos := 0 + for pos < emitter.buffer_pos { + // See the "reader.c" code for more details on UTF-8 encoding. Note + // that we assume that the buffer contains a valid UTF-8 sequence. + + // Read the next UTF-8 character. + octet := emitter.buffer[pos] + + var w int + var value rune + switch { + case octet&0x80 == 0x00: + w, value = 1, rune(octet&0x7F) + case octet&0xE0 == 0xC0: + w, value = 2, rune(octet&0x1F) + case octet&0xF0 == 0xE0: + w, value = 3, rune(octet&0x0F) + case octet&0xF8 == 0xF0: + w, value = 4, rune(octet&0x07) + } + for k := 1; k < w; k++ { + octet = emitter.buffer[pos+k] + value = (value << 6) + (rune(octet) & 0x3F) + } + pos += w + + // Write the character. + if value < 0x10000 { + var b [2]byte + b[high] = byte(value >> 8) + b[low] = byte(value & 0xFF) + emitter.raw_buffer = append(emitter.raw_buffer, b[0], b[1]) + } else { + // Write the character using a surrogate pair (check "reader.c"). + var b [4]byte + value -= 0x10000 + b[high] = byte(0xD8 + (value >> 18)) + b[low] = byte((value >> 10) & 0xFF) + b[high+2] = byte(0xDC + ((value >> 8) & 0xFF)) + b[low+2] = byte(value & 0xFF) + emitter.raw_buffer = append(emitter.raw_buffer, b[0], b[1], b[2], b[3]) + } + } + + // Write the raw buffer. + if err := emitter.write_handler(emitter, emitter.raw_buffer); err != nil { + return yaml_emitter_set_writer_error(emitter, "write error: "+err.Error()) + } + emitter.buffer_pos = 0 + emitter.raw_buffer = emitter.raw_buffer[:0] + return true +} diff --git a/vendor/gopkg.in/yaml.v2/yaml.go b/vendor/gopkg.in/yaml.v2/yaml.go new file mode 100644 index 0000000..d133edf --- /dev/null +++ b/vendor/gopkg.in/yaml.v2/yaml.go @@ -0,0 +1,346 @@ +// Package yaml implements YAML support for the Go language. +// +// Source code and other details for the project are available at GitHub: +// +// https://github.com/go-yaml/yaml +// +package yaml + +import ( + "errors" + "fmt" + "reflect" + "strings" + "sync" +) + +// MapSlice encodes and decodes as a YAML map. +// The order of keys is preserved when encoding and decoding. +type MapSlice []MapItem + +// MapItem is an item in a MapSlice. +type MapItem struct { + Key, Value interface{} +} + +// The Unmarshaler interface may be implemented by types to customize their +// behavior when being unmarshaled from a YAML document. The UnmarshalYAML +// method receives a function that may be called to unmarshal the original +// YAML value into a field or variable. It is safe to call the unmarshal +// function parameter more than once if necessary. +type Unmarshaler interface { + UnmarshalYAML(unmarshal func(interface{}) error) error +} + +// The Marshaler interface may be implemented by types to customize their +// behavior when being marshaled into a YAML document. The returned value +// is marshaled in place of the original value implementing Marshaler. +// +// If an error is returned by MarshalYAML, the marshaling procedure stops +// and returns with the provided error. +type Marshaler interface { + MarshalYAML() (interface{}, error) +} + +// Unmarshal decodes the first document found within the in byte slice +// and assigns decoded values into the out value. +// +// Maps and pointers (to a struct, string, int, etc) are accepted as out +// values. If an internal pointer within a struct is not initialized, +// the yaml package will initialize it if necessary for unmarshalling +// the provided data. The out parameter must not be nil. +// +// The type of the decoded values should be compatible with the respective +// values in out. If one or more values cannot be decoded due to a type +// mismatches, decoding continues partially until the end of the YAML +// content, and a *yaml.TypeError is returned with details for all +// missed values. +// +// Struct fields are only unmarshalled if they are exported (have an +// upper case first letter), and are unmarshalled using the field name +// lowercased as the default key. Custom keys may be defined via the +// "yaml" name in the field tag: the content preceding the first comma +// is used as the key, and the following comma-separated options are +// used to tweak the marshalling process (see Marshal). +// Conflicting names result in a runtime error. +// +// For example: +// +// type T struct { +// F int `yaml:"a,omitempty"` +// B int +// } +// var t T +// yaml.Unmarshal([]byte("a: 1\nb: 2"), &t) +// +// See the documentation of Marshal for the format of tags and a list of +// supported tag options. +// +func Unmarshal(in []byte, out interface{}) (err error) { + defer handleErr(&err) + d := newDecoder() + p := newParser(in) + defer p.destroy() + node := p.parse() + if node != nil { + v := reflect.ValueOf(out) + if v.Kind() == reflect.Ptr && !v.IsNil() { + v = v.Elem() + } + d.unmarshal(node, v) + } + if len(d.terrors) > 0 { + return &TypeError{d.terrors} + } + return nil +} + +// Marshal serializes the value provided into a YAML document. The structure +// of the generated document will reflect the structure of the value itself. +// Maps and pointers (to struct, string, int, etc) are accepted as the in value. +// +// Struct fields are only unmarshalled if they are exported (have an upper case +// first letter), and are unmarshalled using the field name lowercased as the +// default key. Custom keys may be defined via the "yaml" name in the field +// tag: the content preceding the first comma is used as the key, and the +// following comma-separated options are used to tweak the marshalling process. +// Conflicting names result in a runtime error. +// +// The field tag format accepted is: +// +// `(...) yaml:"[][,[,]]" (...)` +// +// The following flags are currently supported: +// +// omitempty Only include the field if it's not set to the zero +// value for the type or to empty slices or maps. +// Does not apply to zero valued structs. +// +// flow Marshal using a flow style (useful for structs, +// sequences and maps). +// +// inline Inline the field, which must be a struct or a map, +// causing all of its fields or keys to be processed as if +// they were part of the outer struct. For maps, keys must +// not conflict with the yaml keys of other struct fields. +// +// In addition, if the key is "-", the field is ignored. +// +// For example: +// +// type T struct { +// F int "a,omitempty" +// B int +// } +// yaml.Marshal(&T{B: 2}) // Returns "b: 2\n" +// yaml.Marshal(&T{F: 1}} // Returns "a: 1\nb: 0\n" +// +func Marshal(in interface{}) (out []byte, err error) { + defer handleErr(&err) + e := newEncoder() + defer e.destroy() + e.marshal("", reflect.ValueOf(in)) + e.finish() + out = e.out + return +} + +func handleErr(err *error) { + if v := recover(); v != nil { + if e, ok := v.(yamlError); ok { + *err = e.err + } else { + panic(v) + } + } +} + +type yamlError struct { + err error +} + +func fail(err error) { + panic(yamlError{err}) +} + +func failf(format string, args ...interface{}) { + panic(yamlError{fmt.Errorf("yaml: "+format, args...)}) +} + +// A TypeError is returned by Unmarshal when one or more fields in +// the YAML document cannot be properly decoded into the requested +// types. When this error is returned, the value is still +// unmarshaled partially. +type TypeError struct { + Errors []string +} + +func (e *TypeError) Error() string { + return fmt.Sprintf("yaml: unmarshal errors:\n %s", strings.Join(e.Errors, "\n ")) +} + +// -------------------------------------------------------------------------- +// Maintain a mapping of keys to structure field indexes + +// The code in this section was copied from mgo/bson. + +// structInfo holds details for the serialization of fields of +// a given struct. +type structInfo struct { + FieldsMap map[string]fieldInfo + FieldsList []fieldInfo + + // InlineMap is the number of the field in the struct that + // contains an ,inline map, or -1 if there's none. + InlineMap int +} + +type fieldInfo struct { + Key string + Num int + OmitEmpty bool + Flow bool + + // Inline holds the field index if the field is part of an inlined struct. + Inline []int +} + +var structMap = make(map[reflect.Type]*structInfo) +var fieldMapMutex sync.RWMutex + +func getStructInfo(st reflect.Type) (*structInfo, error) { + fieldMapMutex.RLock() + sinfo, found := structMap[st] + fieldMapMutex.RUnlock() + if found { + return sinfo, nil + } + + n := st.NumField() + fieldsMap := make(map[string]fieldInfo) + fieldsList := make([]fieldInfo, 0, n) + inlineMap := -1 + for i := 0; i != n; i++ { + field := st.Field(i) + if field.PkgPath != "" { + continue // Private field + } + + info := fieldInfo{Num: i} + + tag := field.Tag.Get("yaml") + if tag == "" && strings.Index(string(field.Tag), ":") < 0 { + tag = string(field.Tag) + } + if tag == "-" { + continue + } + + inline := false + fields := strings.Split(tag, ",") + if len(fields) > 1 { + for _, flag := range fields[1:] { + switch flag { + case "omitempty": + info.OmitEmpty = true + case "flow": + info.Flow = true + case "inline": + inline = true + default: + return nil, errors.New(fmt.Sprintf("Unsupported flag %q in tag %q of type %s", flag, tag, st)) + } + } + tag = fields[0] + } + + if inline { + switch field.Type.Kind() { + case reflect.Map: + if inlineMap >= 0 { + return nil, errors.New("Multiple ,inline maps in struct " + st.String()) + } + if field.Type.Key() != reflect.TypeOf("") { + return nil, errors.New("Option ,inline needs a map with string keys in struct " + st.String()) + } + inlineMap = info.Num + case reflect.Struct: + sinfo, err := getStructInfo(field.Type) + if err != nil { + return nil, err + } + for _, finfo := range sinfo.FieldsList { + if _, found := fieldsMap[finfo.Key]; found { + msg := "Duplicated key '" + finfo.Key + "' in struct " + st.String() + return nil, errors.New(msg) + } + if finfo.Inline == nil { + finfo.Inline = []int{i, finfo.Num} + } else { + finfo.Inline = append([]int{i}, finfo.Inline...) + } + fieldsMap[finfo.Key] = finfo + fieldsList = append(fieldsList, finfo) + } + default: + //return nil, errors.New("Option ,inline needs a struct value or map field") + return nil, errors.New("Option ,inline needs a struct value field") + } + continue + } + + if tag != "" { + info.Key = tag + } else { + info.Key = strings.ToLower(field.Name) + } + + if _, found = fieldsMap[info.Key]; found { + msg := "Duplicated key '" + info.Key + "' in struct " + st.String() + return nil, errors.New(msg) + } + + fieldsList = append(fieldsList, info) + fieldsMap[info.Key] = info + } + + sinfo = &structInfo{fieldsMap, fieldsList, inlineMap} + + fieldMapMutex.Lock() + structMap[st] = sinfo + fieldMapMutex.Unlock() + return sinfo, nil +} + +func isZero(v reflect.Value) bool { + switch v.Kind() { + case reflect.String: + return len(v.String()) == 0 + case reflect.Interface, reflect.Ptr: + return v.IsNil() + case reflect.Slice: + return v.Len() == 0 + case reflect.Map: + return v.Len() == 0 + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return v.Int() == 0 + case reflect.Float32, reflect.Float64: + return v.Float() == 0 + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + return v.Uint() == 0 + case reflect.Bool: + return !v.Bool() + case reflect.Struct: + vt := v.Type() + for i := v.NumField() - 1; i >= 0; i-- { + if vt.Field(i).PkgPath != "" { + continue // Private field + } + if !isZero(v.Field(i)) { + return false + } + } + return true + } + return false +} diff --git a/vendor/gopkg.in/yaml.v2/yamlh.go b/vendor/gopkg.in/yaml.v2/yamlh.go new file mode 100644 index 0000000..d60a6b6 --- /dev/null +++ b/vendor/gopkg.in/yaml.v2/yamlh.go @@ -0,0 +1,716 @@ +package yaml + +import ( + "io" +) + +// The version directive data. +type yaml_version_directive_t struct { + major int8 // The major version number. + minor int8 // The minor version number. +} + +// The tag directive data. +type yaml_tag_directive_t struct { + handle []byte // The tag handle. + prefix []byte // The tag prefix. +} + +type yaml_encoding_t int + +// The stream encoding. +const ( + // Let the parser choose the encoding. + yaml_ANY_ENCODING yaml_encoding_t = iota + + yaml_UTF8_ENCODING // The default UTF-8 encoding. + yaml_UTF16LE_ENCODING // The UTF-16-LE encoding with BOM. + yaml_UTF16BE_ENCODING // The UTF-16-BE encoding with BOM. +) + +type yaml_break_t int + +// Line break types. +const ( + // Let the parser choose the break type. + yaml_ANY_BREAK yaml_break_t = iota + + yaml_CR_BREAK // Use CR for line breaks (Mac style). + yaml_LN_BREAK // Use LN for line breaks (Unix style). + yaml_CRLN_BREAK // Use CR LN for line breaks (DOS style). +) + +type yaml_error_type_t int + +// Many bad things could happen with the parser and emitter. +const ( + // No error is produced. + yaml_NO_ERROR yaml_error_type_t = iota + + yaml_MEMORY_ERROR // Cannot allocate or reallocate a block of memory. + yaml_READER_ERROR // Cannot read or decode the input stream. + yaml_SCANNER_ERROR // Cannot scan the input stream. + yaml_PARSER_ERROR // Cannot parse the input stream. + yaml_COMPOSER_ERROR // Cannot compose a YAML document. + yaml_WRITER_ERROR // Cannot write to the output stream. + yaml_EMITTER_ERROR // Cannot emit a YAML stream. +) + +// The pointer position. +type yaml_mark_t struct { + index int // The position index. + line int // The position line. + column int // The position column. +} + +// Node Styles + +type yaml_style_t int8 + +type yaml_scalar_style_t yaml_style_t + +// Scalar styles. +const ( + // Let the emitter choose the style. + yaml_ANY_SCALAR_STYLE yaml_scalar_style_t = iota + + yaml_PLAIN_SCALAR_STYLE // The plain scalar style. + yaml_SINGLE_QUOTED_SCALAR_STYLE // The single-quoted scalar style. + yaml_DOUBLE_QUOTED_SCALAR_STYLE // The double-quoted scalar style. + yaml_LITERAL_SCALAR_STYLE // The literal scalar style. + yaml_FOLDED_SCALAR_STYLE // The folded scalar style. +) + +type yaml_sequence_style_t yaml_style_t + +// Sequence styles. +const ( + // Let the emitter choose the style. + yaml_ANY_SEQUENCE_STYLE yaml_sequence_style_t = iota + + yaml_BLOCK_SEQUENCE_STYLE // The block sequence style. + yaml_FLOW_SEQUENCE_STYLE // The flow sequence style. +) + +type yaml_mapping_style_t yaml_style_t + +// Mapping styles. +const ( + // Let the emitter choose the style. + yaml_ANY_MAPPING_STYLE yaml_mapping_style_t = iota + + yaml_BLOCK_MAPPING_STYLE // The block mapping style. + yaml_FLOW_MAPPING_STYLE // The flow mapping style. +) + +// Tokens + +type yaml_token_type_t int + +// Token types. +const ( + // An empty token. + yaml_NO_TOKEN yaml_token_type_t = iota + + yaml_STREAM_START_TOKEN // A STREAM-START token. + yaml_STREAM_END_TOKEN // A STREAM-END token. + + yaml_VERSION_DIRECTIVE_TOKEN // A VERSION-DIRECTIVE token. + yaml_TAG_DIRECTIVE_TOKEN // A TAG-DIRECTIVE token. + yaml_DOCUMENT_START_TOKEN // A DOCUMENT-START token. + yaml_DOCUMENT_END_TOKEN // A DOCUMENT-END token. + + yaml_BLOCK_SEQUENCE_START_TOKEN // A BLOCK-SEQUENCE-START token. + yaml_BLOCK_MAPPING_START_TOKEN // A BLOCK-SEQUENCE-END token. + yaml_BLOCK_END_TOKEN // A BLOCK-END token. + + yaml_FLOW_SEQUENCE_START_TOKEN // A FLOW-SEQUENCE-START token. + yaml_FLOW_SEQUENCE_END_TOKEN // A FLOW-SEQUENCE-END token. + yaml_FLOW_MAPPING_START_TOKEN // A FLOW-MAPPING-START token. + yaml_FLOW_MAPPING_END_TOKEN // A FLOW-MAPPING-END token. + + yaml_BLOCK_ENTRY_TOKEN // A BLOCK-ENTRY token. + yaml_FLOW_ENTRY_TOKEN // A FLOW-ENTRY token. + yaml_KEY_TOKEN // A KEY token. + yaml_VALUE_TOKEN // A VALUE token. + + yaml_ALIAS_TOKEN // An ALIAS token. + yaml_ANCHOR_TOKEN // An ANCHOR token. + yaml_TAG_TOKEN // A TAG token. + yaml_SCALAR_TOKEN // A SCALAR token. +) + +func (tt yaml_token_type_t) String() string { + switch tt { + case yaml_NO_TOKEN: + return "yaml_NO_TOKEN" + case yaml_STREAM_START_TOKEN: + return "yaml_STREAM_START_TOKEN" + case yaml_STREAM_END_TOKEN: + return "yaml_STREAM_END_TOKEN" + case yaml_VERSION_DIRECTIVE_TOKEN: + return "yaml_VERSION_DIRECTIVE_TOKEN" + case yaml_TAG_DIRECTIVE_TOKEN: + return "yaml_TAG_DIRECTIVE_TOKEN" + case yaml_DOCUMENT_START_TOKEN: + return "yaml_DOCUMENT_START_TOKEN" + case yaml_DOCUMENT_END_TOKEN: + return "yaml_DOCUMENT_END_TOKEN" + case yaml_BLOCK_SEQUENCE_START_TOKEN: + return "yaml_BLOCK_SEQUENCE_START_TOKEN" + case yaml_BLOCK_MAPPING_START_TOKEN: + return "yaml_BLOCK_MAPPING_START_TOKEN" + case yaml_BLOCK_END_TOKEN: + return "yaml_BLOCK_END_TOKEN" + case yaml_FLOW_SEQUENCE_START_TOKEN: + return "yaml_FLOW_SEQUENCE_START_TOKEN" + case yaml_FLOW_SEQUENCE_END_TOKEN: + return "yaml_FLOW_SEQUENCE_END_TOKEN" + case yaml_FLOW_MAPPING_START_TOKEN: + return "yaml_FLOW_MAPPING_START_TOKEN" + case yaml_FLOW_MAPPING_END_TOKEN: + return "yaml_FLOW_MAPPING_END_TOKEN" + case yaml_BLOCK_ENTRY_TOKEN: + return "yaml_BLOCK_ENTRY_TOKEN" + case yaml_FLOW_ENTRY_TOKEN: + return "yaml_FLOW_ENTRY_TOKEN" + case yaml_KEY_TOKEN: + return "yaml_KEY_TOKEN" + case yaml_VALUE_TOKEN: + return "yaml_VALUE_TOKEN" + case yaml_ALIAS_TOKEN: + return "yaml_ALIAS_TOKEN" + case yaml_ANCHOR_TOKEN: + return "yaml_ANCHOR_TOKEN" + case yaml_TAG_TOKEN: + return "yaml_TAG_TOKEN" + case yaml_SCALAR_TOKEN: + return "yaml_SCALAR_TOKEN" + } + return "" +} + +// The token structure. +type yaml_token_t struct { + // The token type. + typ yaml_token_type_t + + // The start/end of the token. + start_mark, end_mark yaml_mark_t + + // The stream encoding (for yaml_STREAM_START_TOKEN). + encoding yaml_encoding_t + + // The alias/anchor/scalar value or tag/tag directive handle + // (for yaml_ALIAS_TOKEN, yaml_ANCHOR_TOKEN, yaml_SCALAR_TOKEN, yaml_TAG_TOKEN, yaml_TAG_DIRECTIVE_TOKEN). + value []byte + + // The tag suffix (for yaml_TAG_TOKEN). + suffix []byte + + // The tag directive prefix (for yaml_TAG_DIRECTIVE_TOKEN). + prefix []byte + + // The scalar style (for yaml_SCALAR_TOKEN). + style yaml_scalar_style_t + + // The version directive major/minor (for yaml_VERSION_DIRECTIVE_TOKEN). + major, minor int8 +} + +// Events + +type yaml_event_type_t int8 + +// Event types. +const ( + // An empty event. + yaml_NO_EVENT yaml_event_type_t = iota + + yaml_STREAM_START_EVENT // A STREAM-START event. + yaml_STREAM_END_EVENT // A STREAM-END event. + yaml_DOCUMENT_START_EVENT // A DOCUMENT-START event. + yaml_DOCUMENT_END_EVENT // A DOCUMENT-END event. + yaml_ALIAS_EVENT // An ALIAS event. + yaml_SCALAR_EVENT // A SCALAR event. + yaml_SEQUENCE_START_EVENT // A SEQUENCE-START event. + yaml_SEQUENCE_END_EVENT // A SEQUENCE-END event. + yaml_MAPPING_START_EVENT // A MAPPING-START event. + yaml_MAPPING_END_EVENT // A MAPPING-END event. +) + +// The event structure. +type yaml_event_t struct { + + // The event type. + typ yaml_event_type_t + + // The start and end of the event. + start_mark, end_mark yaml_mark_t + + // The document encoding (for yaml_STREAM_START_EVENT). + encoding yaml_encoding_t + + // The version directive (for yaml_DOCUMENT_START_EVENT). + version_directive *yaml_version_directive_t + + // The list of tag directives (for yaml_DOCUMENT_START_EVENT). + tag_directives []yaml_tag_directive_t + + // The anchor (for yaml_SCALAR_EVENT, yaml_SEQUENCE_START_EVENT, yaml_MAPPING_START_EVENT, yaml_ALIAS_EVENT). + anchor []byte + + // The tag (for yaml_SCALAR_EVENT, yaml_SEQUENCE_START_EVENT, yaml_MAPPING_START_EVENT). + tag []byte + + // The scalar value (for yaml_SCALAR_EVENT). + value []byte + + // Is the document start/end indicator implicit, or the tag optional? + // (for yaml_DOCUMENT_START_EVENT, yaml_DOCUMENT_END_EVENT, yaml_SEQUENCE_START_EVENT, yaml_MAPPING_START_EVENT, yaml_SCALAR_EVENT). + implicit bool + + // Is the tag optional for any non-plain style? (for yaml_SCALAR_EVENT). + quoted_implicit bool + + // The style (for yaml_SCALAR_EVENT, yaml_SEQUENCE_START_EVENT, yaml_MAPPING_START_EVENT). + style yaml_style_t +} + +func (e *yaml_event_t) scalar_style() yaml_scalar_style_t { return yaml_scalar_style_t(e.style) } +func (e *yaml_event_t) sequence_style() yaml_sequence_style_t { return yaml_sequence_style_t(e.style) } +func (e *yaml_event_t) mapping_style() yaml_mapping_style_t { return yaml_mapping_style_t(e.style) } + +// Nodes + +const ( + yaml_NULL_TAG = "tag:yaml.org,2002:null" // The tag !!null with the only possible value: null. + yaml_BOOL_TAG = "tag:yaml.org,2002:bool" // The tag !!bool with the values: true and false. + yaml_STR_TAG = "tag:yaml.org,2002:str" // The tag !!str for string values. + yaml_INT_TAG = "tag:yaml.org,2002:int" // The tag !!int for integer values. + yaml_FLOAT_TAG = "tag:yaml.org,2002:float" // The tag !!float for float values. + yaml_TIMESTAMP_TAG = "tag:yaml.org,2002:timestamp" // The tag !!timestamp for date and time values. + + yaml_SEQ_TAG = "tag:yaml.org,2002:seq" // The tag !!seq is used to denote sequences. + yaml_MAP_TAG = "tag:yaml.org,2002:map" // The tag !!map is used to denote mapping. + + // Not in original libyaml. + yaml_BINARY_TAG = "tag:yaml.org,2002:binary" + yaml_MERGE_TAG = "tag:yaml.org,2002:merge" + + yaml_DEFAULT_SCALAR_TAG = yaml_STR_TAG // The default scalar tag is !!str. + yaml_DEFAULT_SEQUENCE_TAG = yaml_SEQ_TAG // The default sequence tag is !!seq. + yaml_DEFAULT_MAPPING_TAG = yaml_MAP_TAG // The default mapping tag is !!map. +) + +type yaml_node_type_t int + +// Node types. +const ( + // An empty node. + yaml_NO_NODE yaml_node_type_t = iota + + yaml_SCALAR_NODE // A scalar node. + yaml_SEQUENCE_NODE // A sequence node. + yaml_MAPPING_NODE // A mapping node. +) + +// An element of a sequence node. +type yaml_node_item_t int + +// An element of a mapping node. +type yaml_node_pair_t struct { + key int // The key of the element. + value int // The value of the element. +} + +// The node structure. +type yaml_node_t struct { + typ yaml_node_type_t // The node type. + tag []byte // The node tag. + + // The node data. + + // The scalar parameters (for yaml_SCALAR_NODE). + scalar struct { + value []byte // The scalar value. + length int // The length of the scalar value. + style yaml_scalar_style_t // The scalar style. + } + + // The sequence parameters (for YAML_SEQUENCE_NODE). + sequence struct { + items_data []yaml_node_item_t // The stack of sequence items. + style yaml_sequence_style_t // The sequence style. + } + + // The mapping parameters (for yaml_MAPPING_NODE). + mapping struct { + pairs_data []yaml_node_pair_t // The stack of mapping pairs (key, value). + pairs_start *yaml_node_pair_t // The beginning of the stack. + pairs_end *yaml_node_pair_t // The end of the stack. + pairs_top *yaml_node_pair_t // The top of the stack. + style yaml_mapping_style_t // The mapping style. + } + + start_mark yaml_mark_t // The beginning of the node. + end_mark yaml_mark_t // The end of the node. + +} + +// The document structure. +type yaml_document_t struct { + + // The document nodes. + nodes []yaml_node_t + + // The version directive. + version_directive *yaml_version_directive_t + + // The list of tag directives. + tag_directives_data []yaml_tag_directive_t + tag_directives_start int // The beginning of the tag directives list. + tag_directives_end int // The end of the tag directives list. + + start_implicit int // Is the document start indicator implicit? + end_implicit int // Is the document end indicator implicit? + + // The start/end of the document. + start_mark, end_mark yaml_mark_t +} + +// The prototype of a read handler. +// +// The read handler is called when the parser needs to read more bytes from the +// source. The handler should write not more than size bytes to the buffer. +// The number of written bytes should be set to the size_read variable. +// +// [in,out] data A pointer to an application data specified by +// yaml_parser_set_input(). +// [out] buffer The buffer to write the data from the source. +// [in] size The size of the buffer. +// [out] size_read The actual number of bytes read from the source. +// +// On success, the handler should return 1. If the handler failed, +// the returned value should be 0. On EOF, the handler should set the +// size_read to 0 and return 1. +type yaml_read_handler_t func(parser *yaml_parser_t, buffer []byte) (n int, err error) + +// This structure holds information about a potential simple key. +type yaml_simple_key_t struct { + possible bool // Is a simple key possible? + required bool // Is a simple key required? + token_number int // The number of the token. + mark yaml_mark_t // The position mark. +} + +// The states of the parser. +type yaml_parser_state_t int + +const ( + yaml_PARSE_STREAM_START_STATE yaml_parser_state_t = iota + + yaml_PARSE_IMPLICIT_DOCUMENT_START_STATE // Expect the beginning of an implicit document. + yaml_PARSE_DOCUMENT_START_STATE // Expect DOCUMENT-START. + yaml_PARSE_DOCUMENT_CONTENT_STATE // Expect the content of a document. + yaml_PARSE_DOCUMENT_END_STATE // Expect DOCUMENT-END. + yaml_PARSE_BLOCK_NODE_STATE // Expect a block node. + yaml_PARSE_BLOCK_NODE_OR_INDENTLESS_SEQUENCE_STATE // Expect a block node or indentless sequence. + yaml_PARSE_FLOW_NODE_STATE // Expect a flow node. + yaml_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE // Expect the first entry of a block sequence. + yaml_PARSE_BLOCK_SEQUENCE_ENTRY_STATE // Expect an entry of a block sequence. + yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE // Expect an entry of an indentless sequence. + yaml_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE // Expect the first key of a block mapping. + yaml_PARSE_BLOCK_MAPPING_KEY_STATE // Expect a block mapping key. + yaml_PARSE_BLOCK_MAPPING_VALUE_STATE // Expect a block mapping value. + yaml_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE // Expect the first entry of a flow sequence. + yaml_PARSE_FLOW_SEQUENCE_ENTRY_STATE // Expect an entry of a flow sequence. + yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE // Expect a key of an ordered mapping. + yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE // Expect a value of an ordered mapping. + yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE // Expect the and of an ordered mapping entry. + yaml_PARSE_FLOW_MAPPING_FIRST_KEY_STATE // Expect the first key of a flow mapping. + yaml_PARSE_FLOW_MAPPING_KEY_STATE // Expect a key of a flow mapping. + yaml_PARSE_FLOW_MAPPING_VALUE_STATE // Expect a value of a flow mapping. + yaml_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE // Expect an empty value of a flow mapping. + yaml_PARSE_END_STATE // Expect nothing. +) + +func (ps yaml_parser_state_t) String() string { + switch ps { + case yaml_PARSE_STREAM_START_STATE: + return "yaml_PARSE_STREAM_START_STATE" + case yaml_PARSE_IMPLICIT_DOCUMENT_START_STATE: + return "yaml_PARSE_IMPLICIT_DOCUMENT_START_STATE" + case yaml_PARSE_DOCUMENT_START_STATE: + return "yaml_PARSE_DOCUMENT_START_STATE" + case yaml_PARSE_DOCUMENT_CONTENT_STATE: + return "yaml_PARSE_DOCUMENT_CONTENT_STATE" + case yaml_PARSE_DOCUMENT_END_STATE: + return "yaml_PARSE_DOCUMENT_END_STATE" + case yaml_PARSE_BLOCK_NODE_STATE: + return "yaml_PARSE_BLOCK_NODE_STATE" + case yaml_PARSE_BLOCK_NODE_OR_INDENTLESS_SEQUENCE_STATE: + return "yaml_PARSE_BLOCK_NODE_OR_INDENTLESS_SEQUENCE_STATE" + case yaml_PARSE_FLOW_NODE_STATE: + return "yaml_PARSE_FLOW_NODE_STATE" + case yaml_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE: + return "yaml_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE" + case yaml_PARSE_BLOCK_SEQUENCE_ENTRY_STATE: + return "yaml_PARSE_BLOCK_SEQUENCE_ENTRY_STATE" + case yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE: + return "yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE" + case yaml_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE: + return "yaml_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE" + case yaml_PARSE_BLOCK_MAPPING_KEY_STATE: + return "yaml_PARSE_BLOCK_MAPPING_KEY_STATE" + case yaml_PARSE_BLOCK_MAPPING_VALUE_STATE: + return "yaml_PARSE_BLOCK_MAPPING_VALUE_STATE" + case yaml_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE: + return "yaml_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE" + case yaml_PARSE_FLOW_SEQUENCE_ENTRY_STATE: + return "yaml_PARSE_FLOW_SEQUENCE_ENTRY_STATE" + case yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE: + return "yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE" + case yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE: + return "yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE" + case yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE: + return "yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE" + case yaml_PARSE_FLOW_MAPPING_FIRST_KEY_STATE: + return "yaml_PARSE_FLOW_MAPPING_FIRST_KEY_STATE" + case yaml_PARSE_FLOW_MAPPING_KEY_STATE: + return "yaml_PARSE_FLOW_MAPPING_KEY_STATE" + case yaml_PARSE_FLOW_MAPPING_VALUE_STATE: + return "yaml_PARSE_FLOW_MAPPING_VALUE_STATE" + case yaml_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE: + return "yaml_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE" + case yaml_PARSE_END_STATE: + return "yaml_PARSE_END_STATE" + } + return "" +} + +// This structure holds aliases data. +type yaml_alias_data_t struct { + anchor []byte // The anchor. + index int // The node id. + mark yaml_mark_t // The anchor mark. +} + +// The parser structure. +// +// All members are internal. Manage the structure using the +// yaml_parser_ family of functions. +type yaml_parser_t struct { + + // Error handling + + error yaml_error_type_t // Error type. + + problem string // Error description. + + // The byte about which the problem occured. + problem_offset int + problem_value int + problem_mark yaml_mark_t + + // The error context. + context string + context_mark yaml_mark_t + + // Reader stuff + + read_handler yaml_read_handler_t // Read handler. + + input_file io.Reader // File input data. + input []byte // String input data. + input_pos int + + eof bool // EOF flag + + buffer []byte // The working buffer. + buffer_pos int // The current position of the buffer. + + unread int // The number of unread characters in the buffer. + + raw_buffer []byte // The raw buffer. + raw_buffer_pos int // The current position of the buffer. + + encoding yaml_encoding_t // The input encoding. + + offset int // The offset of the current position (in bytes). + mark yaml_mark_t // The mark of the current position. + + // Scanner stuff + + stream_start_produced bool // Have we started to scan the input stream? + stream_end_produced bool // Have we reached the end of the input stream? + + flow_level int // The number of unclosed '[' and '{' indicators. + + tokens []yaml_token_t // The tokens queue. + tokens_head int // The head of the tokens queue. + tokens_parsed int // The number of tokens fetched from the queue. + token_available bool // Does the tokens queue contain a token ready for dequeueing. + + indent int // The current indentation level. + indents []int // The indentation levels stack. + + simple_key_allowed bool // May a simple key occur at the current position? + simple_keys []yaml_simple_key_t // The stack of simple keys. + + // Parser stuff + + state yaml_parser_state_t // The current parser state. + states []yaml_parser_state_t // The parser states stack. + marks []yaml_mark_t // The stack of marks. + tag_directives []yaml_tag_directive_t // The list of TAG directives. + + // Dumper stuff + + aliases []yaml_alias_data_t // The alias data. + + document *yaml_document_t // The currently parsed document. +} + +// Emitter Definitions + +// The prototype of a write handler. +// +// The write handler is called when the emitter needs to flush the accumulated +// characters to the output. The handler should write @a size bytes of the +// @a buffer to the output. +// +// @param[in,out] data A pointer to an application data specified by +// yaml_emitter_set_output(). +// @param[in] buffer The buffer with bytes to be written. +// @param[in] size The size of the buffer. +// +// @returns On success, the handler should return @c 1. If the handler failed, +// the returned value should be @c 0. +// +type yaml_write_handler_t func(emitter *yaml_emitter_t, buffer []byte) error + +type yaml_emitter_state_t int + +// The emitter states. +const ( + // Expect STREAM-START. + yaml_EMIT_STREAM_START_STATE yaml_emitter_state_t = iota + + yaml_EMIT_FIRST_DOCUMENT_START_STATE // Expect the first DOCUMENT-START or STREAM-END. + yaml_EMIT_DOCUMENT_START_STATE // Expect DOCUMENT-START or STREAM-END. + yaml_EMIT_DOCUMENT_CONTENT_STATE // Expect the content of a document. + yaml_EMIT_DOCUMENT_END_STATE // Expect DOCUMENT-END. + yaml_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE // Expect the first item of a flow sequence. + yaml_EMIT_FLOW_SEQUENCE_ITEM_STATE // Expect an item of a flow sequence. + yaml_EMIT_FLOW_MAPPING_FIRST_KEY_STATE // Expect the first key of a flow mapping. + yaml_EMIT_FLOW_MAPPING_KEY_STATE // Expect a key of a flow mapping. + yaml_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE // Expect a value for a simple key of a flow mapping. + yaml_EMIT_FLOW_MAPPING_VALUE_STATE // Expect a value of a flow mapping. + yaml_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE // Expect the first item of a block sequence. + yaml_EMIT_BLOCK_SEQUENCE_ITEM_STATE // Expect an item of a block sequence. + yaml_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE // Expect the first key of a block mapping. + yaml_EMIT_BLOCK_MAPPING_KEY_STATE // Expect the key of a block mapping. + yaml_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE // Expect a value for a simple key of a block mapping. + yaml_EMIT_BLOCK_MAPPING_VALUE_STATE // Expect a value of a block mapping. + yaml_EMIT_END_STATE // Expect nothing. +) + +// The emitter structure. +// +// All members are internal. Manage the structure using the @c yaml_emitter_ +// family of functions. +type yaml_emitter_t struct { + + // Error handling + + error yaml_error_type_t // Error type. + problem string // Error description. + + // Writer stuff + + write_handler yaml_write_handler_t // Write handler. + + output_buffer *[]byte // String output data. + output_file io.Writer // File output data. + + buffer []byte // The working buffer. + buffer_pos int // The current position of the buffer. + + raw_buffer []byte // The raw buffer. + raw_buffer_pos int // The current position of the buffer. + + encoding yaml_encoding_t // The stream encoding. + + // Emitter stuff + + canonical bool // If the output is in the canonical style? + best_indent int // The number of indentation spaces. + best_width int // The preferred width of the output lines. + unicode bool // Allow unescaped non-ASCII characters? + line_break yaml_break_t // The preferred line break. + + state yaml_emitter_state_t // The current emitter state. + states []yaml_emitter_state_t // The stack of states. + + events []yaml_event_t // The event queue. + events_head int // The head of the event queue. + + indents []int // The stack of indentation levels. + + tag_directives []yaml_tag_directive_t // The list of tag directives. + + indent int // The current indentation level. + + flow_level int // The current flow level. + + root_context bool // Is it the document root context? + sequence_context bool // Is it a sequence context? + mapping_context bool // Is it a mapping context? + simple_key_context bool // Is it a simple mapping key context? + + line int // The current line. + column int // The current column. + whitespace bool // If the last character was a whitespace? + indention bool // If the last character was an indentation character (' ', '-', '?', ':')? + open_ended bool // If an explicit document end is required? + + // Anchor analysis. + anchor_data struct { + anchor []byte // The anchor value. + alias bool // Is it an alias? + } + + // Tag analysis. + tag_data struct { + handle []byte // The tag handle. + suffix []byte // The tag suffix. + } + + // Scalar analysis. + scalar_data struct { + value []byte // The scalar value. + multiline bool // Does the scalar contain line breaks? + flow_plain_allowed bool // Can the scalar be expessed in the flow plain style? + block_plain_allowed bool // Can the scalar be expressed in the block plain style? + single_quoted_allowed bool // Can the scalar be expressed in the single quoted style? + block_allowed bool // Can the scalar be expressed in the literal or folded styles? + style yaml_scalar_style_t // The output style. + } + + // Dumper stuff + + opened bool // If the stream was already opened? + closed bool // If the stream was already closed? + + // The information associated with the document nodes. + anchors *struct { + references int // The number of references. + anchor int // The anchor id. + serialized bool // If the node has been emitted? + } + + last_anchor_id int // The last assigned anchor id. + + document *yaml_document_t // The currently emitted document. +} diff --git a/vendor/gopkg.in/yaml.v2/yamlprivateh.go b/vendor/gopkg.in/yaml.v2/yamlprivateh.go new file mode 100644 index 0000000..8110ce3 --- /dev/null +++ b/vendor/gopkg.in/yaml.v2/yamlprivateh.go @@ -0,0 +1,173 @@ +package yaml + +const ( + // The size of the input raw buffer. + input_raw_buffer_size = 512 + + // The size of the input buffer. + // It should be possible to decode the whole raw buffer. + input_buffer_size = input_raw_buffer_size * 3 + + // The size of the output buffer. + output_buffer_size = 128 + + // The size of the output raw buffer. + // It should be possible to encode the whole output buffer. + output_raw_buffer_size = (output_buffer_size*2 + 2) + + // The size of other stacks and queues. + initial_stack_size = 16 + initial_queue_size = 16 + initial_string_size = 16 +) + +// Check if the character at the specified position is an alphabetical +// character, a digit, '_', or '-'. +func is_alpha(b []byte, i int) bool { + return b[i] >= '0' && b[i] <= '9' || b[i] >= 'A' && b[i] <= 'Z' || b[i] >= 'a' && b[i] <= 'z' || b[i] == '_' || b[i] == '-' +} + +// Check if the character at the specified position is a digit. +func is_digit(b []byte, i int) bool { + return b[i] >= '0' && b[i] <= '9' +} + +// Get the value of a digit. +func as_digit(b []byte, i int) int { + return int(b[i]) - '0' +} + +// Check if the character at the specified position is a hex-digit. +func is_hex(b []byte, i int) bool { + return b[i] >= '0' && b[i] <= '9' || b[i] >= 'A' && b[i] <= 'F' || b[i] >= 'a' && b[i] <= 'f' +} + +// Get the value of a hex-digit. +func as_hex(b []byte, i int) int { + bi := b[i] + if bi >= 'A' && bi <= 'F' { + return int(bi) - 'A' + 10 + } + if bi >= 'a' && bi <= 'f' { + return int(bi) - 'a' + 10 + } + return int(bi) - '0' +} + +// Check if the character is ASCII. +func is_ascii(b []byte, i int) bool { + return b[i] <= 0x7F +} + +// Check if the character at the start of the buffer can be printed unescaped. +func is_printable(b []byte, i int) bool { + return ((b[i] == 0x0A) || // . == #x0A + (b[i] >= 0x20 && b[i] <= 0x7E) || // #x20 <= . <= #x7E + (b[i] == 0xC2 && b[i+1] >= 0xA0) || // #0xA0 <= . <= #xD7FF + (b[i] > 0xC2 && b[i] < 0xED) || + (b[i] == 0xED && b[i+1] < 0xA0) || + (b[i] == 0xEE) || + (b[i] == 0xEF && // #xE000 <= . <= #xFFFD + !(b[i+1] == 0xBB && b[i+2] == 0xBF) && // && . != #xFEFF + !(b[i+1] == 0xBF && (b[i+2] == 0xBE || b[i+2] == 0xBF)))) +} + +// Check if the character at the specified position is NUL. +func is_z(b []byte, i int) bool { + return b[i] == 0x00 +} + +// Check if the beginning of the buffer is a BOM. +func is_bom(b []byte, i int) bool { + return b[0] == 0xEF && b[1] == 0xBB && b[2] == 0xBF +} + +// Check if the character at the specified position is space. +func is_space(b []byte, i int) bool { + return b[i] == ' ' +} + +// Check if the character at the specified position is tab. +func is_tab(b []byte, i int) bool { + return b[i] == '\t' +} + +// Check if the character at the specified position is blank (space or tab). +func is_blank(b []byte, i int) bool { + //return is_space(b, i) || is_tab(b, i) + return b[i] == ' ' || b[i] == '\t' +} + +// Check if the character at the specified position is a line break. +func is_break(b []byte, i int) bool { + return (b[i] == '\r' || // CR (#xD) + b[i] == '\n' || // LF (#xA) + b[i] == 0xC2 && b[i+1] == 0x85 || // NEL (#x85) + b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA8 || // LS (#x2028) + b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA9) // PS (#x2029) +} + +func is_crlf(b []byte, i int) bool { + return b[i] == '\r' && b[i+1] == '\n' +} + +// Check if the character is a line break or NUL. +func is_breakz(b []byte, i int) bool { + //return is_break(b, i) || is_z(b, i) + return ( // is_break: + b[i] == '\r' || // CR (#xD) + b[i] == '\n' || // LF (#xA) + b[i] == 0xC2 && b[i+1] == 0x85 || // NEL (#x85) + b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA8 || // LS (#x2028) + b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA9 || // PS (#x2029) + // is_z: + b[i] == 0) +} + +// Check if the character is a line break, space, or NUL. +func is_spacez(b []byte, i int) bool { + //return is_space(b, i) || is_breakz(b, i) + return ( // is_space: + b[i] == ' ' || + // is_breakz: + b[i] == '\r' || // CR (#xD) + b[i] == '\n' || // LF (#xA) + b[i] == 0xC2 && b[i+1] == 0x85 || // NEL (#x85) + b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA8 || // LS (#x2028) + b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA9 || // PS (#x2029) + b[i] == 0) +} + +// Check if the character is a line break, space, tab, or NUL. +func is_blankz(b []byte, i int) bool { + //return is_blank(b, i) || is_breakz(b, i) + return ( // is_blank: + b[i] == ' ' || b[i] == '\t' || + // is_breakz: + b[i] == '\r' || // CR (#xD) + b[i] == '\n' || // LF (#xA) + b[i] == 0xC2 && b[i+1] == 0x85 || // NEL (#x85) + b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA8 || // LS (#x2028) + b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA9 || // PS (#x2029) + b[i] == 0) +} + +// Determine the width of the character. +func width(b byte) int { + // Don't replace these by a switch without first + // confirming that it is being inlined. + if b&0x80 == 0x00 { + return 1 + } + if b&0xE0 == 0xC0 { + return 2 + } + if b&0xF0 == 0xE0 { + return 3 + } + if b&0xF8 == 0xF0 { + return 4 + } + return 0 + +}