├── .gitmodules ├── .travis.yml ├── LICENSE ├── README.md ├── binding.gyp ├── etc ├── idls │ ├── Common.avdl │ ├── Ethernet2.avdl │ ├── Pdu.avdl │ ├── Radiotap.avdl │ └── dot11 │ │ ├── Common.avdl │ │ ├── Ctrl.avdl │ │ ├── Data.avdl │ │ └── Mgmt.avdl └── scripts │ ├── assemble-idls │ ├── build-deps │ └── compile-idls ├── lib ├── index.js ├── sniffers.js └── utils.js ├── package.json ├── src ├── codecs.cpp ├── codecs.hpp ├── index.cpp ├── pdus.hpp ├── utils.cpp ├── utils.hpp ├── wrapper.cpp └── wrapper.hpp └── test ├── dat └── sample.pcap ├── mocha.opts ├── test_sniffers.js └── test_utils.js /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "etc/deps/avro"] 2 | path = etc/deps/avro 3 | url = https://github.com/apache/avro.git 4 | [submodule "etc/deps/libtins"] 5 | path = etc/deps/libtins 6 | url = https://github.com/mfontanini/libtins.git 7 | [submodule "doc"] 8 | path = doc 9 | url = https://github.com/mtth/layer2.wiki.git 10 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - node 4 | addons: 5 | apt: 6 | sources: 7 | - ubuntu-toolchain-r-test 8 | packages: 9 | - cmake 10 | - g++-4.8 11 | - libboost-all-dev 12 | - libpcap-dev 13 | - libssl-dev 14 | env: 15 | global: 16 | - CXX=g++-4.8 17 | - LD_LIBRARY_PATH="$(pwd)/etc/deps/libtins/build/lib:$(pwd)/etc/deps/avro/lang/c++/build" 18 | install: 19 | - npm run install-all 20 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014, Matthieu Monsch. 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | this software and associated documentation files (the "Software"), to deal in 5 | the Software without restriction, including without limitation the rights to 6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 7 | of the Software, and to permit persons to whom the Software is furnished to do 8 | so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Layer2 [![Build Status](https://travis-ci.org/mtth/layer2.svg?branch=master)](https://travis-ci.org/mtth/layer2) 2 | 3 | ```javascript 4 | var layer2 = require('layer2'); 5 | 6 | layer2.createInterfaceSniffer('eth0') 7 | .on('pdu', function (pdu) { 8 | var frame = pdu.frame.Ethernet2; 9 | var src = frame.srcAddr; 10 | var dst = frame.dstAddr; 11 | console.log(src + ' -> ' + dst + ' [' + pdu.size + ']'); 12 | }); 13 | ``` 14 | 15 | 16 | ## Installation 17 | 18 | You will need a compiler with C++11 support, then if you already have 19 | `avro>=1.7` and `tins>=3.2` installed: 20 | 21 | ```bash 22 | $ npm install layer2 23 | ``` 24 | 25 | Otherwise, you can build both dependencies along with this package by running: 26 | 27 | ```bash 28 | $ git clone --recursive git@github.com:mtth/layer2.git 29 | $ cd layer2 30 | $ npm run install-all 31 | $ export LD_LIBRARY_PATH="$(pwd)/etc/deps/libtins/build/lib:$(pwd)/etc/deps/avro/lang/c++/build:$LD_LIBRARY_PATH" 32 | ``` 33 | 34 | Note the last step required to find the libraries at runtime (alternatively you 35 | could install both dependencies globally). 36 | 37 | 38 | ## Documentation 39 | 40 | + [API](https://github.com/mtth/layer2/wiki/API) 41 | -------------------------------------------------------------------------------- /binding.gyp: -------------------------------------------------------------------------------- 1 | { 2 | 'targets': [ 3 | { 4 | 'target_name': 'index', 5 | 'sources': [ 6 | 'src/index.cpp', 7 | 'src/codecs.cpp', 8 | 'src/utils.cpp', 9 | 'src/wrapper.cpp' 10 | ], 11 | 'link_settings': { 12 | 'libraries': [ 13 | '-lavrocpp', 14 | '-ltins' 15 | ] 16 | }, 17 | 'cflags!': ['-fno-exceptions'], 18 | 'cflags_cc!': ['-fno-exceptions', '-fno-rtti'], 19 | 'conditions': [ 20 | [ 21 | 'OS=="mac"', { 22 | 'xcode_settings': { 23 | 'GCC_ENABLE_CPP_EXCEPTIONS': 'YES', 24 | 'GCC_ENABLE_CPP_RTTI': 'YES', 25 | 'MACOSX_DEPLOYMENT_TARGET': '10.7', 26 | 'OTHER_CPLUSPLUSFLAGS': [ 27 | '-stdlib=libc++' 28 | ] 29 | } 30 | } 31 | ] 32 | ], 33 | 'include_dirs' : [ 34 | '} flags = null; 41 | union {null, int} rate = null; 42 | union {null, radiotap.Channel} channel = null; 43 | union { 44 | null, 45 | Unsupported, 46 | dot11.Unsupported, 47 | dot11.ctrl.Ack, 48 | dot11.ctrl.BlockAck, 49 | dot11.ctrl.BlockAckRequest, 50 | dot11.ctrl.CfEnd, 51 | dot11.ctrl.EndCfAck, 52 | dot11.ctrl.PsPoll, 53 | dot11.ctrl.Rts, 54 | dot11.data.Data, 55 | dot11.data.QosData, 56 | dot11.mgmt.AssocRequest, 57 | dot11.mgmt.AssocResponse, 58 | dot11.mgmt.Authentication, 59 | dot11.mgmt.Beacon, 60 | dot11.mgmt.Deauthentication, 61 | dot11.mgmt.Disassoc, 62 | dot11.mgmt.ProbeRequest, 63 | dot11.mgmt.ProbeResponse, 64 | dot11.mgmt.ReassocRequest, 65 | dot11.mgmt.ReassocResponse 66 | } frame = null; 67 | } 68 | 69 | } 70 | -------------------------------------------------------------------------------- /etc/idls/dot11/Common.avdl: -------------------------------------------------------------------------------- 1 | import idl "../Common.avdl"; 2 | 3 | @namespace("dot11") 4 | protocol Common { 5 | 6 | /** 7 | * Common header for all 802.11 frames. 8 | * 9 | */ 10 | record Header { 11 | boolean toDs; 12 | boolean fromDs; 13 | boolean moreFrag; 14 | boolean retry; 15 | boolean powerMgmt; 16 | boolean wep; 17 | boolean order; 18 | int durationId; 19 | .MacAddr addr1; 20 | } 21 | 22 | /** 23 | * Custom record for unsupported 802.11 frames. 24 | * 25 | * This lets us communicate a bit more information. 26 | * 27 | */ 28 | record Unsupported { 29 | Header @inline(true) header; 30 | int type; 31 | int subtype; 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /etc/idls/dot11/Ctrl.avdl: -------------------------------------------------------------------------------- 1 | import idl "../Common.avdl"; 2 | import idl "./Common.avdl"; 3 | 4 | // TODO: Find a better way to support all the very similar control frames. 5 | 6 | @namespace("dot11.ctrl") 7 | protocol Ctrl { 8 | 9 | record Ack { 10 | dot11.Header @inline(true) header; 11 | } 12 | 13 | record BlockAck { 14 | dot11.Header @inline(true) header; 15 | int barControl; 16 | int startSeq; 17 | int fragNum; 18 | } 19 | 20 | record BlockAckRequest { 21 | dot11.Header @inline(true) header; 22 | int barControl; 23 | int startSeq; 24 | int fragNum; 25 | } 26 | 27 | record CfEnd { 28 | dot11.Header @inline(true) header; 29 | } 30 | 31 | record EndCfAck { 32 | dot11.Header @inline(true) header; 33 | } 34 | 35 | record PsPoll { 36 | dot11.Header @inline(true) header; 37 | } 38 | 39 | record Rts { 40 | dot11.Header @inline(true) header; 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /etc/idls/dot11/Data.avdl: -------------------------------------------------------------------------------- 1 | import idl "../Common.avdl"; 2 | import idl "./Common.avdl"; 3 | 4 | @namespace("dot11.data") 5 | protocol Data { 6 | 7 | record Header { 8 | .MacAddr addr2; 9 | .MacAddr addr3; 10 | .MacAddr addr4; 11 | int fragNum; 12 | int seqNum; 13 | } 14 | 15 | record Data { 16 | dot11.Header @inline(true) header; 17 | Header @inline(true) dataHeader; 18 | } 19 | 20 | record QosData { 21 | dot11.Header @inline(true) header; 22 | Header @inline(true) dataHeader; 23 | int qosControl; 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /etc/idls/dot11/Mgmt.avdl: -------------------------------------------------------------------------------- 1 | import idl "../Common.avdl"; 2 | import idl "./Common.avdl"; 3 | 4 | @namespace("dot11.mgmt") 5 | protocol Mgmt { 6 | 7 | enum Capability { 8 | ESS, 9 | IBSS, 10 | CF_POLL, 11 | CF_POLL_REQ, 12 | PRIVACY, 13 | SHORT_PREAMBLE, 14 | PBCC, 15 | CHANNEL_AGILITY, 16 | SPECTRUM_MGMT, 17 | QOS, 18 | SST, 19 | APSD, 20 | RADIO_MEASUREMENT, 21 | DSSS_OFDM, 22 | DELAYED_BLOCK_ACK, 23 | IMMEDIATE_BLOCK_ACK 24 | } 25 | 26 | /** 27 | * Common header for all 802.11 management frames. 28 | * 29 | * Includes everything but the address fields (to keep them at the same level 30 | * as the others). 31 | * 32 | */ 33 | record Header { 34 | .MacAddr addr2; 35 | .MacAddr addr3; 36 | .MacAddr addr4; 37 | int fragNum; 38 | int seqNum; 39 | // TODO: Add more (e.g. SSID), though tin's API currently makes this difficult. 40 | } 41 | 42 | record AssocRequest { 43 | dot11.Header @inline(true) header; 44 | Header @inline(true) mgmtHeader; 45 | array capabilities; 46 | int listenInterval; 47 | } 48 | 49 | record AssocResponse { 50 | dot11.Header @inline(true) header; 51 | dot11.mgmt.Header @inline(true) mgmtHeader; 52 | array capabilities; 53 | int statusCode; // 0: success, 1: failure (make this an enum?). 54 | int aid; 55 | } 56 | 57 | record Authentication { 58 | dot11.Header @inline(true) header; 59 | Header @inline(true) mgmtHeader; 60 | int authAlgorithm; 61 | int authSeqNumber; 62 | int statusCode; 63 | } 64 | 65 | record Beacon { 66 | dot11.Header @inline(true) header; 67 | Header @inline(true) mgmtHeader; 68 | long timestamp; 69 | int interval; 70 | array capabilities; 71 | } 72 | 73 | record Deauthentication { 74 | dot11.Header @inline(true) header; 75 | Header @inline(true) mgmtHeader; 76 | int reasonCode; 77 | } 78 | 79 | record Disassoc { 80 | dot11.Header @inline(true) header; 81 | Header @inline(true) mgmtHeader; 82 | int reasonCode; 83 | } 84 | 85 | record ProbeRequest { 86 | dot11.Header @inline(true) header; 87 | Header @inline(true) mgmtHeader; 88 | } 89 | 90 | record ProbeResponse { 91 | dot11.Header @inline(true) header; 92 | Header @inline(true) mgmtHeader; 93 | long timestamp; 94 | int interval; 95 | array capabilities; 96 | } 97 | 98 | record ReassocRequest { 99 | dot11.Header @inline(true) header; 100 | Header @inline(true) mgmtHeader; 101 | array capabilities; 102 | int listenInterval; 103 | .MacAddr currentAp; 104 | } 105 | 106 | record ReassocResponse { 107 | dot11.Header @inline(true) header; 108 | Header @inline(true) mgmtHeader; 109 | array capabilities; 110 | int statusCode; // 0: success, 1: failure (make this an enum?). 111 | int aid; 112 | } 113 | 114 | } 115 | -------------------------------------------------------------------------------- /etc/scripts/assemble-idls: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | /* jshint node: true */ 4 | 5 | 'use strict'; 6 | 7 | /** 8 | * Assemble all IDL files and output all defined types to stdout. 9 | * 10 | * This script is called internally by `compile-idls` to code-generate the CPP 11 | * header with all Avro specific types. 12 | * 13 | */ 14 | 15 | var avro = require('avsc'), 16 | path = require('path'); 17 | 18 | 19 | var dpath = path.join(__dirname, '..'); // Path to `etc/` directory. 20 | 21 | avro.assemble(path.join(dpath, 'idls', 'Pdu.avdl'), function (err, attrs) { 22 | if (err) { 23 | throw err; 24 | } 25 | 26 | // CPP code-generation doesn't properly handle namespaces. We work around 27 | // this by forcing all names in the global namespace (manually namespacing 28 | // names with underscores). 29 | var registry = {}; 30 | var protocol = avro.parse(attrs, {registry: registry}); 31 | Object.keys(registry).forEach(function (name) { 32 | var type = registry[name]; 33 | if (type._name) { 34 | type._name = type._name.replace(/\./g, '_'); 35 | } 36 | }); 37 | 38 | // Return all types declared in the IDL files. 39 | console.log(JSON.stringify(JSON.parse(protocol.toString()).types)); 40 | }); 41 | -------------------------------------------------------------------------------- /etc/scripts/build-deps: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Build dependencies. 4 | # 5 | # This will also build the `avrogencpp` binary used to compile IDLs into the 6 | # CPP header. 7 | 8 | set -o nounset 9 | set -o errexit 10 | set -o pipefail 11 | shopt -s nullglob 12 | 13 | # Dependencies directory. 14 | dpath="$(cd "$(dirname "${BASH_SOURCE[0]}")/../deps" && pwd)" 15 | 16 | # Build libtins. 17 | cd "$dpath/libtins" 18 | rm -rf build 19 | mkdir build 20 | cd build 21 | cmake ../ -DLIBTINS_ENABLE_CXX11=1 -Wno-dev 22 | make 23 | 24 | # Build avro. 25 | cd "$dpath/avro/lang/c++" 26 | rm -rf build 27 | # We can't simply run `./build.sh install` because of a deprecated function 28 | # used in tests. We run the commands manually to only make the shared library 29 | # we are interested in. 30 | mkdir build 31 | cd build 32 | cmake ../ -Wno-dev 33 | make avrocpp avrogencpp 34 | # The Avro C++ repository also doesn't respect the usual include directory 35 | # naming convention, we fix this here. 36 | mkdir include 37 | ln -s ../../api include/avro 38 | -------------------------------------------------------------------------------- /etc/scripts/compile-idls: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Generate the CPP header file with all Avro specific record. 4 | # 5 | # This requires the Avro dependency to have been built first (for example using 6 | # the `build-deps` script). 7 | 8 | set -o nounset 9 | set -o errexit 10 | set -o pipefail 11 | shopt -s nullglob 12 | 13 | # `etc/` directory. 14 | dpath="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" 15 | 16 | "${dpath}/deps/avro/lang/c++/build/avrogencpp" \ 17 | -i <("${dpath}/scripts/assemble-idls") \ 18 | -o "${dpath}/../src/pdus.hpp" \ 19 | -n Layer2 20 | -------------------------------------------------------------------------------- /lib/index.js: -------------------------------------------------------------------------------- 1 | /* jshint node: true */ 2 | 3 | 'use strict'; 4 | 5 | var sniffers = require('./sniffers'); 6 | 7 | 8 | module.exports = { 9 | createInterfaceSniffer: sniffers.createInterfaceSniffer, 10 | createFileSniffer: sniffers.createFileSniffer 11 | }; 12 | -------------------------------------------------------------------------------- /lib/sniffers.js: -------------------------------------------------------------------------------- 1 | /* jshint node: true */ 2 | 3 | 'use strict'; 4 | 5 | var utils = require('./utils'), 6 | events = require('events'), 7 | stream = require('stream'), 8 | util = require('util'); 9 | 10 | 11 | // Cache for PDU type to avoid parsing the IDL each time. 12 | var PDU_TYPE; 13 | 14 | 15 | /** 16 | * Sniffer, event emitter used to capture PDUs (i.e. ~frames/packets). 17 | * 18 | * Not meant to be instantiated directly though, only through the two factory 19 | * functions below (so as not to expose the CPP-defined `Wrapper`). 20 | * 21 | */ 22 | function Sniffer(wrapper, batchSize) { 23 | events.EventEmitter.call(this); 24 | 25 | batchSize = batchSize || 65536; // Same default as PCAP's buffer size. 26 | this._bufs = [new Buffer(batchSize), new Buffer(batchSize)]; 27 | this._bufIndex = 0; 28 | this._wrapper = wrapper; 29 | this._type = undefined; 30 | this._sniffing = false; 31 | this._destroyed = false; 32 | 33 | this.once('_end', function () { 34 | this._wrapper.destroy(); 35 | this.emit('end'); 36 | }); 37 | 38 | var self = this; 39 | loadPduType(function (err, type) { 40 | if (err) { 41 | self.emit('error', err); 42 | return; 43 | } 44 | self._type = type; 45 | 46 | self.on('newListener', function start(evt) { 47 | if (evt === 'pdu' && !self.listenerCount('pdu')) { 48 | sniff(); 49 | } 50 | }); 51 | if (self.listenerCount('pdu')) { 52 | // Only start listening right away if a handler is already attached, 53 | // otherwise we are either dropping PDUs, wasting CPU, or both. 54 | sniff(); 55 | } 56 | 57 | function sniff() { 58 | var buf = self._bufs[self._bufIndex]; 59 | self._bufIndex = 1 - self._bufIndex; 60 | self._sniffing = true; 61 | self._wrapper.getPdus(buf, function (err, n) { 62 | if (err) { 63 | self.emit('error', err); 64 | return; 65 | } 66 | 67 | self.emit('batch', n); 68 | 69 | var sniffing = !self._destroyed && !!self.listenerCount('pdu'); 70 | if (sniffing) { 71 | // Trigger the next batch before processing this one, to enable the 72 | // C++ code to run as often as possible. This is possible because we 73 | // use two separate buffers and alternate between each. 74 | sniff(); 75 | } 76 | 77 | try { 78 | var pos = 0; 79 | while (n--) { 80 | var obj = self._type.decode(buf, pos); 81 | self.emit('pdu', obj.value); 82 | pos = obj.offset; 83 | } 84 | } catch (err) { 85 | self.emit('error', err); 86 | return; 87 | } 88 | 89 | self._sniffing = sniffing; 90 | if (!sniffing && self._destroyed) { 91 | self.emit('_end'); 92 | } 93 | }); 94 | } 95 | }); 96 | } 97 | util.inherits(Sniffer, events.EventEmitter); 98 | 99 | /** 100 | * Stop listening. 101 | * 102 | */ 103 | Sniffer.prototype.destroy = function () { 104 | this._destroyed = true; 105 | if (!this._sniffing) { 106 | this.emit('_end'); 107 | } 108 | }; 109 | 110 | /** 111 | * Convenience method to expose a stream interface. 112 | * 113 | * This isn't the default because the main reason behind streams (backpressure) 114 | * doesn't apply for live captures (pdus will be dropped), so the extra 115 | * complexity and performance hit aren't worth it. 116 | * 117 | * Warning: any non-consumed PDUs will be buffered in memory! So beware when 118 | * using this method on high-throughput sniffers. 119 | * 120 | */ 121 | Sniffer.prototype.stream = function () { 122 | var readable = new stream.Readable({ 123 | objectMode: true, 124 | read: function () {} // We push irrespective of this. 125 | }); 126 | this 127 | .on('pdu', function (pdu) { readable.push(pdu); }) 128 | .on('end', function () { readable.push(null); }); 129 | return readable; 130 | }; 131 | 132 | /** 133 | * Factory method for live captures. 134 | * 135 | * For more information see: 136 | * 137 | * + http://www.tcpdump.org/manpages/pcap.3pcap.html 138 | * + http://libtins.github.io/docs/latest/da/d53/classTins_1_1SnifferConfiguration.html 139 | * 140 | */ 141 | function createInterfaceSniffer(dev, opts) { 142 | opts = opts || {}; 143 | var wrapper = new utils.Wrapper().fromInterface( 144 | dev, 145 | opts.snaplen, 146 | opts.promisc, 147 | opts.rfmon, 148 | opts.timeout || 1000, // Default maximum 1 second delay between batches. 149 | opts.bufferSize, 150 | opts.filter 151 | ); 152 | // We use the same size for both PCAP's buffer and ours by default. It is an 153 | // approximation though (we still need to handle overflows) because the 154 | // encodings are different in each, so data size will vary. 155 | return new Sniffer(wrapper, opts.batchSize || opts.bufferSize); 156 | } 157 | 158 | /** 159 | * Factory method for replaying captures from PCAP files. 160 | * 161 | */ 162 | function createFileSniffer(path, opts) { 163 | opts = opts || {}; 164 | var wrapper = new utils.Wrapper().fromFile(path, opts.filter); 165 | var exhausted = false; 166 | return new Sniffer(wrapper, opts.batchSize) 167 | .on('batch', function (n) { 168 | // We must do this in two passes because libtin's `FileSniffer` will 169 | // sometimes return an empty batch even though the file isn't exhausted 170 | // (for example at the very beginning). 171 | if (exhausted) { 172 | this.destroy(); 173 | } 174 | exhausted = !n; 175 | }); 176 | } 177 | 178 | // Helpers. 179 | 180 | /** 181 | * Get PDU type from IDL, caching it for future calls. 182 | * 183 | */ 184 | function loadPduType(cb) { 185 | if (PDU_TYPE) { 186 | process.nextTick(function () { cb(null, PDU_TYPE); }); 187 | return; 188 | } 189 | utils.loadPduType(function (err, type) { 190 | cb(err, PDU_TYPE = type); 191 | }); 192 | } 193 | 194 | 195 | module.exports = { 196 | Sniffer: Sniffer, // For tests. 197 | createInterfaceSniffer: createInterfaceSniffer, 198 | createFileSniffer: createFileSniffer 199 | }; 200 | -------------------------------------------------------------------------------- /lib/utils.js: -------------------------------------------------------------------------------- 1 | /* jshint node: true */ 2 | 3 | 'use strict'; 4 | 5 | /** 6 | * Various utilities. 7 | * 8 | */ 9 | 10 | var assert = require('assert'), 11 | avro = require('avsc'), 12 | path = require('path'), 13 | util = require('util'); 14 | 15 | 16 | // CPP binding. 17 | // 18 | // Either the debug or release version will be returned depending on the 19 | // `LAYER2_DEBUG` environment variable (defaulting to the existing one if none 20 | // is specified). An error is raised if the variable is specified and the 21 | // corresponding addon isn't found. 22 | var ADDON = (/* istanbul ignore next */ function () { 23 | var override = process.env.LAYER2_DEBUG; 24 | var debug = override && parseInt(override); 25 | var dpath = path.join(__dirname, '..', 'build', debug ? 'Debug' : 'Release'); 26 | return require(dpath); 27 | })(); 28 | 29 | 30 | /** 31 | * Load PDU Avro type from IDL files. 32 | * 33 | */ 34 | function loadPduType(cb) { 35 | var opts = { 36 | logicalTypes: { 37 | address: AddressType, 38 | 'timestamp-millis': DateType 39 | }, 40 | registry: {}, 41 | typeHook: createTypeHook() 42 | }; 43 | 44 | var fpath = path.join(__dirname, '..', 'etc', 'idls', 'Pdu.avdl'); 45 | avro.assemble(fpath, function (err, attrs) { 46 | assert.strictEqual(err, null); 47 | 48 | var protocol = avro.parse(attrs, opts); 49 | Object.keys(opts.registry).forEach(function (name) { 50 | var type = opts.registry[name]; 51 | if (type.getName(true) === 'record') { 52 | if (/^dot11\./.test(type.getName())) { 53 | util.inherits(type.getRecordConstructor(), Dot11Frame); 54 | } 55 | } 56 | }); 57 | 58 | cb(null, protocol.getType('Pdu')); 59 | }); 60 | } 61 | 62 | /** 63 | * Generate typehook which does the following: 64 | * 65 | * + Unwraps "optional" unions (of the form `["null", ???]`). 66 | * + Inlines fields with an `inline` annotation. 67 | * 68 | */ 69 | function createTypeHook() { 70 | var visited = []; 71 | 72 | return function typeHook(attrs, opts) { 73 | if (~visited.indexOf(attrs)) { 74 | return; 75 | } 76 | visited.push(attrs); 77 | 78 | if (attrs instanceof Array && attrs[0] === 'null' && attrs.length === 2) { 79 | return new OptionalType(attrs, opts); 80 | } 81 | 82 | if (attrs.type !== 'record') { 83 | // Following inlining only applies to records. 84 | return; 85 | } 86 | 87 | var fields = []; 88 | var namespace = opts.namespace; 89 | opts.namespace = attrs.namespace || opts.namespace; 90 | 91 | attrs.fields.forEach(function (fieldAttrs) { 92 | if (!fieldAttrs.inline) { 93 | // Default behavior. 94 | fields.push(fieldAttrs); 95 | return; 96 | } 97 | 98 | var type; 99 | if (typeof fieldAttrs.type === 'string') { 100 | // This is a reference, we must obtain the underlying type. 101 | var name = fieldAttrs.type; 102 | if (!~name.indexOf('.') && opts.namespace) { 103 | name = opts.namespace + '.' + name; 104 | } 105 | type = opts.registry[name]; 106 | if (!type) { 107 | // Just add the undefined reference so that `parse` can throw an 108 | // appropriate "undefined type" error. 109 | fields.push(fieldAttrs); 110 | return; 111 | } 112 | } else { 113 | type = avro.parse(fieldAttrs.type, opts); 114 | } 115 | 116 | if (type.getName(true) !== 'record') { 117 | throw new Error('only record fields can be inlined'); 118 | } 119 | 120 | type.getFields().forEach(function (inlinedField) { 121 | // Note that we don't need to check for duplicates here since that will 122 | // be done by `parse` when it creates the type after the hook returns. 123 | fields.push({ 124 | aliases: inlinedField.getAliases(), 125 | 'default': inlinedField.getDefault(), 126 | name: inlinedField.getName(), 127 | order: computeOrder(inlinedField.getOrder()), 128 | type: inlinedField.getType() 129 | }); 130 | }); 131 | 132 | function computeOrder(order) { 133 | // If the inlined field has a descending order, we must "invert" all 134 | // its fields' orders. Similarly for ignored. 135 | if (order === 'ignore' || fieldAttrs.order === 'ignore') { 136 | return 'ignore'; 137 | } 138 | switch (fieldAttrs.order || 'ascending') { 139 | case 'descending': 140 | return order === 'ascending' ? 'descending' : 'ascending'; 141 | case 'ascending': 142 | return order; 143 | default: 144 | throw new Error('invalid order: ' + fieldAttrs.order); 145 | } 146 | } 147 | }); 148 | 149 | opts.namespace = namespace; 150 | attrs.fields = fields; 151 | }; 152 | } 153 | 154 | /** 155 | * Custom type to unwrap certain unions. 156 | * 157 | * Unlike the other logical types below, it cannot be applied via `parse`'s 158 | * `logicalTypes` option since unions cannot be annotated. 159 | * 160 | */ 161 | function OptionalType(attrs, opts) { 162 | avro.types.LogicalType.call(this, attrs, opts, [avro.types.UnionType]); 163 | var type = this.getUnderlyingType().getTypes()[1]; 164 | this._name = type.getName() || type.getName(true); 165 | } 166 | util.inherits(OptionalType, avro.types.LogicalType); 167 | 168 | OptionalType.prototype._fromValue = function (val) { 169 | return val === null ? null : val[this._name]; 170 | }; 171 | 172 | OptionalType.prototype._toValue = function (any) { 173 | if (any === null) { 174 | return null; 175 | } 176 | var obj = {}; 177 | obj[this._name] = any; 178 | return obj; 179 | }; 180 | 181 | /** 182 | * Custom type to parse timestamps as dates. 183 | * 184 | */ 185 | function DateType(attrs, opts) { 186 | avro.types.LogicalType.call(this, attrs, opts, [avro.types.LongType]); 187 | } 188 | util.inherits(DateType, avro.types.LogicalType); 189 | 190 | DateType.prototype._fromValue = function (val) { return new Date(val); }; 191 | 192 | DateType.prototype._toValue = function (date) { return +date; }; 193 | 194 | /** 195 | * Custom type to better display addresses (e.g. MAC). 196 | * 197 | */ 198 | function AddressType(attrs, opts) { 199 | avro.types.LogicalType.call(this, attrs, opts, [avro.types.FixedType]); 200 | this._size = this.getUnderlyingType().getSize(); 201 | } 202 | util.inherits(AddressType, avro.types.LogicalType); 203 | 204 | AddressType.prototype._fromValue = function (val) { 205 | if (val.length !== this._size) { 206 | throw new Error('invalid address'); 207 | } 208 | return new Address(val); 209 | }; 210 | 211 | AddressType.prototype._toValue = function (addr) { return addr.toBuffer(); }; 212 | 213 | /** 214 | * Hardware address. 215 | * 216 | */ 217 | function Address(buf) { 218 | this._buf = buf; 219 | this._str = undefined; // Lazily instantiated. 220 | } 221 | 222 | Address.prototype.isMulticast = function () { return !!(this._buf[0] & 1); }; 223 | 224 | Address.prototype.toBuffer = function () { return this._buf; }; 225 | 226 | Address.prototype.toString = function () { 227 | if (!this._str) { 228 | this._str = ADDON.stringifyAddress(this._buf); 229 | } 230 | return this._str; 231 | }; 232 | 233 | Address.prototype.toJSON = Address.prototype.toString; 234 | 235 | Address.prototype.inspect = Address.prototype.toString; 236 | 237 | /** 238 | * Base class to augment all 802.11 frames. 239 | * 240 | */ 241 | function Dot11Frame() {} 242 | 243 | Dot11Frame.prototype.getSrcAddr = function () { 244 | switch (this.toDs + 2 * this.fromDs) { 245 | case 0: 246 | case 1: 247 | return this.addr2; 248 | case 2: 249 | return this.addr3; 250 | case 3: 251 | return this.addr4; 252 | } 253 | }; 254 | 255 | Dot11Frame.prototype.getDstAddr = function () { 256 | switch (this.toDs + 2 * this.fromDs) { 257 | case 0: 258 | case 2: 259 | return this.addr1; 260 | case 1: 261 | return this.addr3; 262 | case 3: 263 | // TODO: Check this. 264 | return this.addr3; 265 | } 266 | }; 267 | 268 | Dot11Frame.prototype.getApAddr = function () { 269 | switch (this.toDs + 2 * this.fromDs) { 270 | case 0: 271 | return this.addr3; 272 | case 1: 273 | return this.addr1; 274 | case 2: 275 | return this.addr2; 276 | case 3: 277 | // Not clear which one to return, so return none. 278 | } 279 | }; 280 | 281 | 282 | module.exports = { 283 | Wrapper: ADDON.Wrapper, 284 | loadPduType: loadPduType, 285 | stringifyAddress: ADDON.stringifyAddress 286 | }; 287 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "layer2", 3 | "version": "0.3.0", 4 | "description": "A streaming API for the data link layer", 5 | "keywords": [ 6 | "802.11", 7 | "capture", 8 | "ethernet", 9 | "frame", 10 | "injection", 11 | "libtins", 12 | "mac", 13 | "monitor", 14 | "packet", 15 | "pcap", 16 | "stream", 17 | "tcpdump", 18 | "wifi", 19 | "wireshark" 20 | ], 21 | "files": [ 22 | "binding.gyp", 23 | "etc/idls", 24 | "lib", 25 | "src" 26 | ], 27 | "main": "./lib", 28 | "scripts": { 29 | "clean": "rm -rf build node_modules", 30 | "cover": "istanbul cover _mocha", 31 | "debug": "lldb -- node _mocha --no-timeouts", 32 | "install-all": "./etc/scripts/build-deps && npm run install-local", 33 | "install-local": "CPLUS_INCLUDE_PATH=\"$(pwd)/etc/deps/libtins/include:$(pwd)/etc/deps/avro/lang/c++/build/include:$CPLUS_INCLUDE_PATH\" LIBRARY_PATH=\"$(pwd)/etc/deps/libtins/build/lib:$(pwd)/etc/deps/avro/lang/c++/build:$LIBRARY_PATH\" npm install", 34 | "test": "mocha" 35 | }, 36 | "dependencies": { 37 | "avsc": "^3.3.9", 38 | "nan": "^2.2.0" 39 | }, 40 | "devDependencies": { 41 | "istanbul": "^0.4.2", 42 | "mocha": "^2.3.4" 43 | }, 44 | "repository": { 45 | "type": "git", 46 | "url": "https://github.com/mtth/layer2.git" 47 | }, 48 | "author": { 49 | "name": "Matthieu Monsch", 50 | "email": "monsch@alum.mit.edu" 51 | }, 52 | "license": "MIT" 53 | } 54 | -------------------------------------------------------------------------------- /src/codecs.cpp: -------------------------------------------------------------------------------- 1 | #include "codecs.hpp" 2 | 3 | namespace Layer2 { 4 | 5 | // Generic. 6 | 7 | std::unique_ptr convert(const Tins::PDU &src) { 8 | Layer2::Unsupported *dst = new Layer2::Unsupported; 9 | dst->name = Tins::Utils::to_string(src.pdu_type()); 10 | return std::unique_ptr(dst); 11 | } 12 | 13 | // Ethernet II. 14 | 15 | std::unique_ptr convert(const Tins::EthernetII &src) { 16 | Layer2::Ethernet2 *dst = new Layer2::Ethernet2; 17 | 18 | src.src_addr().copy(dst->srcAddr.data()); 19 | src.dst_addr().copy(dst->dstAddr.data()); 20 | dst->payloadType = src.payload_type(); 21 | 22 | Tins::PDU *innerPdu = src.inner_pdu(); 23 | if (innerPdu) { 24 | dst->data = const_cast(*innerPdu).serialize(); 25 | } 26 | 27 | return std::unique_ptr(dst); 28 | } 29 | 30 | // 802.11. 31 | 32 | // A few helpers first for the nested headers. 33 | 34 | void populateDot11Header(Layer2::dot11_Header &dst, const Tins::Dot11 &src) { 35 | dst.toDs = src.to_ds(); 36 | dst.fromDs = src.from_ds(); 37 | dst.moreFrag = src.more_frag(); 38 | dst.retry = src.retry(); 39 | dst.powerMgmt = src.power_mgmt(); 40 | dst.wep = src.wep(); 41 | dst.order = src.order(); 42 | dst.durationId = src.duration_id(); 43 | src.addr1().copy(dst.addr1.data()); 44 | } 45 | 46 | void populateDot11DataHeader(Layer2::dot11_data_Header &dst, const Tins::Dot11Data &src) { 47 | dst.fragNum = src.frag_num(); 48 | dst.seqNum = src.seq_num(); 49 | src.addr2().copy(dst.addr2.data()); 50 | src.addr3().copy(dst.addr3.data()); 51 | src.addr4().copy(dst.addr4.data()); 52 | } 53 | 54 | void populateDot11MgmtHeader(Layer2::dot11_mgmt_Header &dst, const Tins::Dot11ManagementFrame &src) { 55 | dst.fragNum = src.frag_num(); 56 | dst.seqNum = src.seq_num(); 57 | src.addr2().copy(dst.addr2.data()); 58 | src.addr3().copy(dst.addr3.data()); 59 | src.addr4().copy(dst.addr4.data()); 60 | } 61 | 62 | void populateDot11Capabilities( 63 | std::vector &dst, 64 | const Tins::Dot11ManagementFrame::capability_information &src 65 | ) { 66 | if (src.ess()) { 67 | dst.push_back(Layer2::dot11_mgmt_Capability::ESS); 68 | } 69 | if (src.ibss()) { 70 | dst.push_back(Layer2::dot11_mgmt_Capability::IBSS); 71 | } 72 | if (src.cf_poll()) { 73 | dst.push_back(Layer2::dot11_mgmt_Capability::CF_POLL); 74 | } 75 | if (src.cf_poll_req()) { 76 | dst.push_back(Layer2::dot11_mgmt_Capability::CF_POLL_REQ); 77 | } 78 | if (src.privacy()) { 79 | dst.push_back(Layer2::dot11_mgmt_Capability::PRIVACY); 80 | } 81 | if (src.short_preamble()) { 82 | dst.push_back(Layer2::dot11_mgmt_Capability::SHORT_PREAMBLE); 83 | } 84 | if (src.pbcc()) { 85 | dst.push_back(Layer2::dot11_mgmt_Capability::PBCC); 86 | } 87 | if (src.channel_agility()) { 88 | dst.push_back(Layer2::dot11_mgmt_Capability::CHANNEL_AGILITY); 89 | } 90 | if (src.spectrum_mgmt()) { 91 | dst.push_back(Layer2::dot11_mgmt_Capability::SPECTRUM_MGMT); 92 | } 93 | if (src.qos()) { 94 | dst.push_back(Layer2::dot11_mgmt_Capability::QOS); 95 | } 96 | if (src.sst()) { 97 | dst.push_back(Layer2::dot11_mgmt_Capability::SST); 98 | } 99 | if (src.apsd()) { 100 | dst.push_back(Layer2::dot11_mgmt_Capability::APSD); 101 | } 102 | if (src.radio_measurement()) { 103 | dst.push_back(Layer2::dot11_mgmt_Capability::RADIO_MEASUREMENT); 104 | } 105 | if (src.dsss_ofdm()) { 106 | dst.push_back(Layer2::dot11_mgmt_Capability::DSSS_OFDM); 107 | } 108 | if (src.delayed_block_ack()) { 109 | dst.push_back(Layer2::dot11_mgmt_Capability::DELAYED_BLOCK_ACK); 110 | } 111 | if (src.immediate_block_ack()) { 112 | dst.push_back(Layer2::dot11_mgmt_Capability::IMMEDIATE_BLOCK_ACK); 113 | } 114 | } 115 | 116 | // Now the actual PDUs. 117 | 118 | std::unique_ptr convert(const Tins::Dot11Ack &src) { 119 | Layer2::dot11_ctrl_Ack *dst = new Layer2::dot11_ctrl_Ack; 120 | populateDot11Header(dst->header, src); 121 | return std::unique_ptr(dst); 122 | } 123 | 124 | std::unique_ptr convert(const Tins::Dot11BlockAck &src) { 125 | Layer2::dot11_ctrl_BlockAck *dst = new Layer2::dot11_ctrl_BlockAck; 126 | populateDot11Header(dst->header, src); 127 | return std::unique_ptr(dst); 128 | } 129 | 130 | std::unique_ptr convert(const Tins::Dot11BlockAckRequest &src) { 131 | Layer2::dot11_ctrl_BlockAckRequest *dst = new Layer2::dot11_ctrl_BlockAckRequest; 132 | populateDot11Header(dst->header, src); 133 | return std::unique_ptr(dst); 134 | } 135 | 136 | std::unique_ptr convert(const Tins::Dot11CFEnd &src) { 137 | Layer2::dot11_ctrl_CfEnd *dst = new Layer2::dot11_ctrl_CfEnd; 138 | populateDot11Header(dst->header, src); 139 | return std::unique_ptr(dst); 140 | } 141 | 142 | std::unique_ptr convert(const Tins::Dot11EndCFAck &src) { 143 | Layer2::dot11_ctrl_EndCfAck *dst = new Layer2::dot11_ctrl_EndCfAck; 144 | populateDot11Header(dst->header, src); 145 | return std::unique_ptr(dst); 146 | } 147 | 148 | std::unique_ptr convert(const Tins::Dot11PSPoll &src) { 149 | Layer2::dot11_ctrl_PsPoll *dst = new Layer2::dot11_ctrl_PsPoll; 150 | populateDot11Header(dst->header, src); 151 | return std::unique_ptr(dst); 152 | } 153 | 154 | std::unique_ptr convert(const Tins::Dot11RTS &src) { 155 | Layer2::dot11_ctrl_Rts *dst = new Layer2::dot11_ctrl_Rts; 156 | populateDot11Header(dst->header, src); 157 | return std::unique_ptr(dst); 158 | } 159 | 160 | std::unique_ptr convert(const Tins::Dot11Data &src) { 161 | Layer2::dot11_data_Data *dst = new Layer2::dot11_data_Data; 162 | populateDot11Header(dst->header, src); 163 | populateDot11DataHeader(dst->dataHeader, src); 164 | return std::unique_ptr(dst); 165 | } 166 | 167 | std::unique_ptr convert(const Tins::Dot11QoSData &src) { 168 | Layer2::dot11_data_QosData *dst = new Layer2::dot11_data_QosData; 169 | populateDot11Header(dst->header, src); 170 | populateDot11DataHeader(dst->dataHeader, src); 171 | dst->qosControl = src.qos_control(); 172 | return std::unique_ptr(dst); 173 | } 174 | 175 | std::unique_ptr convert(const Tins::Dot11AssocRequest &src) { 176 | Layer2::dot11_mgmt_AssocRequest *dst = new Layer2::dot11_mgmt_AssocRequest; 177 | populateDot11Header(dst->header, src); 178 | populateDot11MgmtHeader(dst->mgmtHeader, src); 179 | populateDot11Capabilities(dst->capabilities, src.capabilities()); 180 | dst->listenInterval = src.listen_interval(); 181 | return std::unique_ptr(dst); 182 | } 183 | 184 | std::unique_ptr convert(const Tins::Dot11AssocResponse &src) { 185 | Layer2::dot11_mgmt_AssocResponse *dst = new Layer2::dot11_mgmt_AssocResponse; 186 | populateDot11Header(dst->header, src); 187 | populateDot11MgmtHeader(dst->mgmtHeader, src); 188 | populateDot11Capabilities(dst->capabilities, src.capabilities()); 189 | dst->statusCode = src.status_code(); 190 | dst->aid = src.aid(); 191 | return std::unique_ptr(dst); 192 | } 193 | 194 | std::unique_ptr convert(const Tins::Dot11Authentication &src) { 195 | Layer2::dot11_mgmt_Authentication *dst = new Layer2::dot11_mgmt_Authentication; 196 | populateDot11Header(dst->header, src); 197 | populateDot11MgmtHeader(dst->mgmtHeader, src); 198 | dst->authAlgorithm = src.auth_algorithm(); 199 | dst->authSeqNumber = src.auth_seq_number(); 200 | dst->statusCode = src.status_code(); 201 | return std::unique_ptr(dst); 202 | } 203 | 204 | std::unique_ptr convert(const Tins::Dot11Beacon &src) { 205 | Layer2::dot11_mgmt_Beacon *dst = new Layer2::dot11_mgmt_Beacon; 206 | populateDot11Header(dst->header, src); 207 | populateDot11MgmtHeader(dst->mgmtHeader, src); 208 | dst->timestamp = src.timestamp(); 209 | dst->interval = src.interval(); 210 | populateDot11Capabilities(dst->capabilities, src.capabilities()); 211 | return std::unique_ptr(dst); 212 | } 213 | 214 | std::unique_ptr convert(const Tins::Dot11Deauthentication &src) { 215 | Layer2::dot11_mgmt_Deauthentication *dst = new Layer2::dot11_mgmt_Deauthentication; 216 | populateDot11Header(dst->header, src); 217 | populateDot11MgmtHeader(dst->mgmtHeader, src); 218 | dst->reasonCode = src.reason_code(); 219 | return std::unique_ptr(dst); 220 | } 221 | 222 | std::unique_ptr convert(const Tins::Dot11Disassoc &src) { 223 | Layer2::dot11_mgmt_Disassoc *dst = new Layer2::dot11_mgmt_Disassoc; 224 | populateDot11Header(dst->header, src); 225 | populateDot11MgmtHeader(dst->mgmtHeader, src); 226 | dst->reasonCode = src.reason_code(); 227 | return std::unique_ptr(dst); 228 | } 229 | 230 | std::unique_ptr convert(const Tins::Dot11ProbeRequest &src) { 231 | Layer2::dot11_mgmt_ProbeRequest *dst = new Layer2::dot11_mgmt_ProbeRequest; 232 | populateDot11Header(dst->header, src); 233 | populateDot11MgmtHeader(dst->mgmtHeader, src); 234 | return std::unique_ptr(dst); 235 | } 236 | 237 | std::unique_ptr convert(const Tins::Dot11ProbeResponse &src) { 238 | Layer2::dot11_mgmt_ProbeResponse *dst = new Layer2::dot11_mgmt_ProbeResponse; 239 | populateDot11Header(dst->header, src); 240 | populateDot11MgmtHeader(dst->mgmtHeader, src); 241 | dst->timestamp = src.timestamp(); 242 | dst->interval = src.interval(); 243 | populateDot11Capabilities(dst->capabilities, src.capabilities()); 244 | return std::unique_ptr(dst); 245 | } 246 | 247 | std::unique_ptr convert(const Tins::Dot11ReAssocRequest &src) { 248 | Layer2::dot11_mgmt_ReassocRequest *dst = new Layer2::dot11_mgmt_ReassocRequest; 249 | populateDot11Header(dst->header, src); 250 | populateDot11MgmtHeader(dst->mgmtHeader, src); 251 | populateDot11Capabilities(dst->capabilities, src.capabilities()); 252 | dst->listenInterval = src.listen_interval(); 253 | src.current_ap().copy(dst->currentAp.data()); 254 | return std::unique_ptr(dst); 255 | } 256 | 257 | std::unique_ptr convert(const Tins::Dot11ReAssocResponse &src) { 258 | Layer2::dot11_mgmt_ReassocResponse *dst = new Layer2::dot11_mgmt_ReassocResponse; 259 | populateDot11Header(dst->header, src); 260 | populateDot11MgmtHeader(dst->mgmtHeader, src); 261 | populateDot11Capabilities(dst->capabilities, src.capabilities()); 262 | dst->statusCode = src.status_code(); 263 | dst->aid = src.aid(); 264 | return std::unique_ptr(dst); 265 | } 266 | 267 | std::unique_ptr convert(const Tins::Dot11 &src) { 268 | Layer2::dot11_Unsupported *dst = new Layer2::dot11_Unsupported; 269 | populateDot11Header(dst->header, src); 270 | dst->type = src.type(); 271 | dst->subtype = src.subtype(); 272 | return std::unique_ptr(dst); 273 | } 274 | 275 | // Radiotap. 276 | 277 | std::unique_ptr convert(const Tins::RadioTap &src) { 278 | Layer2::Radiotap *dst = new Layer2::Radiotap(); 279 | 280 | Tins::RadioTap::PresentFlags present = src.present(); 281 | if (present & Tins::RadioTap::PresentFlags::TSTF) { 282 | dst->tsft.set_long(src.tsft()); 283 | } 284 | 285 | if (present & Tins::RadioTap::PresentFlags::FLAGS) { 286 | Tins::RadioTap::FrameFlags frameFlags = src.flags(); 287 | std::vector flags; 288 | if (frameFlags & Tins::RadioTap::FrameFlags::CFP) { 289 | flags.push_back(Layer2::radiotap_Flag::CFP); 290 | } 291 | if (frameFlags & Tins::RadioTap::FrameFlags::PREAMBLE) { 292 | flags.push_back(Layer2::radiotap_Flag::PREAMBLE); 293 | } 294 | if (frameFlags & Tins::RadioTap::FrameFlags::WEP) { 295 | flags.push_back(Layer2::radiotap_Flag::WEP); 296 | } 297 | if (frameFlags & Tins::RadioTap::FrameFlags::FRAGMENTATION) { 298 | flags.push_back(Layer2::radiotap_Flag::FRAGMENTATION); 299 | } 300 | if (frameFlags & Tins::RadioTap::FrameFlags::FCS) { 301 | flags.push_back(Layer2::radiotap_Flag::FCS); 302 | } 303 | if (frameFlags & Tins::RadioTap::FrameFlags::PADDING) { 304 | flags.push_back(Layer2::radiotap_Flag::PADDING); 305 | } 306 | if (frameFlags & Tins::RadioTap::FrameFlags::FAILED_FCS) { 307 | flags.push_back(Layer2::radiotap_Flag::FAILED_FCS); 308 | } 309 | if (frameFlags & Tins::RadioTap::FrameFlags::SHORT_GI) { 310 | flags.push_back(Layer2::radiotap_Flag::SHORT_GI); 311 | } 312 | dst->flags.set_array(flags); 313 | } 314 | 315 | if (present & Tins::RadioTap::PresentFlags::RATE) { 316 | dst->rate.set_int(src.rate()); 317 | } 318 | 319 | if (present & Tins::RadioTap::PresentFlags::CHANNEL) { 320 | Layer2::radiotap_Channel channel; 321 | channel.freq = src.channel_freq(); 322 | switch (src.channel_type()) { 323 | case Tins::RadioTap::TURBO: 324 | channel.type = Layer2::radiotap_ChannelType::TURBO; 325 | break; 326 | case Tins::RadioTap::CCK: 327 | channel.type = Layer2::radiotap_ChannelType::CCK; 328 | break; 329 | case Tins::RadioTap::OFDM: 330 | channel.type = Layer2::radiotap_ChannelType::OFDM; 331 | break; 332 | case Tins::RadioTap::TWO_GZ: 333 | channel.type = Layer2::radiotap_ChannelType::TWO_GZ; 334 | break; 335 | case Tins::RadioTap::FIVE_GZ: 336 | channel.type = Layer2::radiotap_ChannelType::FIVE_GZ; 337 | break; 338 | case Tins::RadioTap::PASSIVE: 339 | channel.type = Layer2::radiotap_ChannelType::PASSIVE; 340 | break; 341 | case Tins::RadioTap::DYN_CCK_OFDM: 342 | channel.type = Layer2::radiotap_ChannelType::DYN_CCK_OFDM; 343 | break; 344 | case Tins::RadioTap::GFSK: 345 | channel.type = Layer2::radiotap_ChannelType::GFSK; 346 | break; 347 | } 348 | dst->channel.set_radiotap_Channel(channel); 349 | } 350 | 351 | Tins::PDU *innerPdu = src.inner_pdu(); 352 | if (innerPdu) { 353 | switch (innerPdu->pdu_type()) { 354 | case Tins::PDU::PDUType::DOT11_ACK: 355 | dst->frame.set_dot11_ctrl_Ack(*Layer2::convert(static_cast(*innerPdu))); 356 | break; 357 | case Tins::PDU::PDUType::DOT11_BLOCK_ACK: 358 | dst->frame.set_dot11_ctrl_BlockAck(*Layer2::convert(static_cast(*innerPdu))); 359 | break; 360 | case Tins::PDU::PDUType::DOT11_BLOCK_ACK_REQ: 361 | dst->frame.set_dot11_ctrl_BlockAckRequest(*Layer2::convert(static_cast(*innerPdu))); 362 | break; 363 | case Tins::PDU::PDUType::DOT11_CF_END: 364 | dst->frame.set_dot11_ctrl_CfEnd(*Layer2::convert(static_cast(*innerPdu))); 365 | break; 366 | case Tins::PDU::PDUType::DOT11_END_CF_ACK: 367 | dst->frame.set_dot11_ctrl_EndCfAck(*Layer2::convert(static_cast(*innerPdu))); 368 | break; 369 | case Tins::PDU::PDUType::DOT11_PS_POLL: 370 | dst->frame.set_dot11_ctrl_PsPoll(*Layer2::convert(static_cast(*innerPdu))); 371 | break; 372 | case Tins::PDU::PDUType::DOT11_RTS: 373 | dst->frame.set_dot11_ctrl_Rts(*Layer2::convert(static_cast(*innerPdu))); 374 | break; 375 | case Tins::PDU::PDUType::DOT11_DATA: 376 | dst->frame.set_dot11_data_Data(*Layer2::convert(static_cast(*innerPdu))); 377 | break; 378 | case Tins::PDU::PDUType::DOT11_QOS_DATA: 379 | dst->frame.set_dot11_data_QosData(*Layer2::convert(static_cast(*innerPdu))); 380 | break; 381 | case Tins::PDU::PDUType::DOT11_ASSOC_REQ: 382 | dst->frame.set_dot11_mgmt_AssocRequest(*Layer2::convert(static_cast(*innerPdu))); 383 | break; 384 | case Tins::PDU::PDUType::DOT11_ASSOC_RESP: 385 | dst->frame.set_dot11_mgmt_AssocResponse(*Layer2::convert(static_cast(*innerPdu))); 386 | break; 387 | case Tins::PDU::PDUType::DOT11_AUTH: 388 | dst->frame.set_dot11_mgmt_Authentication(*Layer2::convert(static_cast(*innerPdu))); 389 | break; 390 | case Tins::PDU::PDUType::DOT11_BEACON: 391 | dst->frame.set_dot11_mgmt_Beacon(*Layer2::convert(static_cast(*innerPdu))); 392 | break; 393 | case Tins::PDU::PDUType::DOT11_DEAUTH: 394 | dst->frame.set_dot11_mgmt_Deauthentication(*Layer2::convert(static_cast(*innerPdu))); 395 | break; 396 | case Tins::PDU::PDUType::DOT11_DIASSOC: 397 | dst->frame.set_dot11_mgmt_Disassoc(*Layer2::convert(static_cast(*innerPdu))); 398 | break; 399 | case Tins::PDU::PDUType::DOT11_PROBE_REQ: 400 | dst->frame.set_dot11_mgmt_ProbeRequest(*Layer2::convert(static_cast(*innerPdu))); 401 | break; 402 | case Tins::PDU::PDUType::DOT11_PROBE_RESP: 403 | dst->frame.set_dot11_mgmt_ProbeResponse(*Layer2::convert(static_cast(*innerPdu))); 404 | break; 405 | case Tins::PDU::PDUType::DOT11_REASSOC_REQ: 406 | dst->frame.set_dot11_mgmt_ReassocRequest(*Layer2::convert(static_cast(*innerPdu))); 407 | break; 408 | case Tins::PDU::PDUType::DOT11_REASSOC_RESP: 409 | dst->frame.set_dot11_mgmt_ReassocResponse(*Layer2::convert(static_cast(*innerPdu))); 410 | break; 411 | case Tins::PDU::PDUType::DOT11: 412 | dst->frame.set_dot11_Unsupported(*Layer2::convert(static_cast(*innerPdu))); 413 | break; 414 | default: 415 | dst->frame.set_Unsupported(*Layer2::convert(*innerPdu)); 416 | ; // This should never happen. Throw an exception here? 417 | } 418 | } 419 | 420 | return std::unique_ptr(dst); 421 | } 422 | 423 | } 424 | -------------------------------------------------------------------------------- /src/codecs.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "./pdus.hpp" 4 | #include 5 | #include 6 | 7 | /** 8 | * Converters between tins PDU data structures and Avro records. 9 | * 10 | */ 11 | 12 | namespace Layer2 { 13 | 14 | std::unique_ptr convert(const Tins::EthernetII &src); 15 | std::unique_ptr convert(const Tins::RadioTap &src); 16 | std::unique_ptr convert(const Tins::PDU &src); 17 | 18 | } 19 | 20 | namespace avro { 21 | 22 | template <> 23 | struct codec_traits { 24 | 25 | static void encode(Encoder &encoder, const Tins::Packet &src) { 26 | Layer2::Pdu dst; 27 | dst.timestamp = src.timestamp().seconds() * 1000 + src.timestamp().microseconds() / 1000; 28 | const Tins::PDU *pdu = src.pdu(); 29 | if (pdu) { 30 | dst.size = pdu->size(); 31 | switch (pdu->pdu_type()) { 32 | case Tins::PDU::PDUType::ETHERNET_II: 33 | dst.frame.set_Ethernet2(*Layer2::convert(static_cast(*pdu))); 34 | break; 35 | case Tins::PDU::PDUType::RADIOTAP: 36 | dst.frame.set_Radiotap(*Layer2::convert(static_cast(*pdu))); 37 | break; 38 | default: 39 | dst.frame.set_Unsupported(*Layer2::convert(*pdu)); 40 | } 41 | } else { 42 | dst.size = 0; 43 | } 44 | avro::encode(encoder, dst); 45 | } 46 | 47 | }; 48 | 49 | } 50 | -------------------------------------------------------------------------------- /src/index.cpp: -------------------------------------------------------------------------------- 1 | #include "utils.hpp" 2 | #include "wrapper.hpp" 3 | 4 | namespace Layer2 { 5 | 6 | void Init(v8::Handle exports) { 7 | 8 | Nan::Set( 9 | exports, 10 | Nan::New("Wrapper").ToLocalChecked(), 11 | Nan::GetFunction(Wrapper::Init()).ToLocalChecked() 12 | ); 13 | 14 | Nan::Set( 15 | exports, 16 | Nan::New("stringifyAddress").ToLocalChecked(), 17 | Nan::GetFunction(Nan::New(stringifyAddress)).ToLocalChecked() 18 | ); 19 | 20 | } 21 | 22 | } // Layer2 23 | 24 | NODE_MODULE(index, Layer2::Init) 25 | -------------------------------------------------------------------------------- /src/pdus.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | 20 | #ifndef SRC_PDUS_HPP_4119412750__H_ 21 | #define SRC_PDUS_HPP_4119412750__H_ 22 | 23 | 24 | #include 25 | #include "boost/any.hpp" 26 | #include "avro/Specific.hh" 27 | #include "avro/Encoder.hh" 28 | #include "avro/Decoder.hh" 29 | 30 | namespace Layer2 { 31 | struct Unsupported { 32 | std::string name; 33 | Unsupported() : 34 | name(std::string()) 35 | { } 36 | }; 37 | 38 | struct Ethernet2 { 39 | boost::array srcAddr; 40 | boost::array dstAddr; 41 | int32_t payloadType; 42 | std::vector data; 43 | Ethernet2() : 44 | srcAddr(boost::array()), 45 | dstAddr(boost::array()), 46 | payloadType(int32_t()), 47 | data(std::vector()) 48 | { } 49 | }; 50 | 51 | struct dot11_Header { 52 | bool toDs; 53 | bool fromDs; 54 | bool moreFrag; 55 | bool retry; 56 | bool powerMgmt; 57 | bool wep; 58 | bool order; 59 | int32_t durationId; 60 | boost::array addr1; 61 | dot11_Header() : 62 | toDs(bool()), 63 | fromDs(bool()), 64 | moreFrag(bool()), 65 | retry(bool()), 66 | powerMgmt(bool()), 67 | wep(bool()), 68 | order(bool()), 69 | durationId(int32_t()), 70 | addr1(boost::array()) 71 | { } 72 | }; 73 | 74 | struct dot11_Unsupported { 75 | dot11_Header header; 76 | int32_t type; 77 | int32_t subtype; 78 | dot11_Unsupported() : 79 | header(dot11_Header()), 80 | type(int32_t()), 81 | subtype(int32_t()) 82 | { } 83 | }; 84 | 85 | struct dot11_ctrl_Ack { 86 | dot11_Header header; 87 | dot11_ctrl_Ack() : 88 | header(dot11_Header()) 89 | { } 90 | }; 91 | 92 | struct dot11_ctrl_BlockAck { 93 | dot11_Header header; 94 | int32_t barControl; 95 | int32_t startSeq; 96 | int32_t fragNum; 97 | dot11_ctrl_BlockAck() : 98 | header(dot11_Header()), 99 | barControl(int32_t()), 100 | startSeq(int32_t()), 101 | fragNum(int32_t()) 102 | { } 103 | }; 104 | 105 | struct dot11_ctrl_BlockAckRequest { 106 | dot11_Header header; 107 | int32_t barControl; 108 | int32_t startSeq; 109 | int32_t fragNum; 110 | dot11_ctrl_BlockAckRequest() : 111 | header(dot11_Header()), 112 | barControl(int32_t()), 113 | startSeq(int32_t()), 114 | fragNum(int32_t()) 115 | { } 116 | }; 117 | 118 | struct dot11_ctrl_CfEnd { 119 | dot11_Header header; 120 | dot11_ctrl_CfEnd() : 121 | header(dot11_Header()) 122 | { } 123 | }; 124 | 125 | struct dot11_ctrl_EndCfAck { 126 | dot11_Header header; 127 | dot11_ctrl_EndCfAck() : 128 | header(dot11_Header()) 129 | { } 130 | }; 131 | 132 | struct dot11_ctrl_PsPoll { 133 | dot11_Header header; 134 | dot11_ctrl_PsPoll() : 135 | header(dot11_Header()) 136 | { } 137 | }; 138 | 139 | struct dot11_ctrl_Rts { 140 | dot11_Header header; 141 | dot11_ctrl_Rts() : 142 | header(dot11_Header()) 143 | { } 144 | }; 145 | 146 | struct dot11_data_Header { 147 | boost::array addr2; 148 | boost::array addr3; 149 | boost::array addr4; 150 | int32_t fragNum; 151 | int32_t seqNum; 152 | dot11_data_Header() : 153 | addr2(boost::array()), 154 | addr3(boost::array()), 155 | addr4(boost::array()), 156 | fragNum(int32_t()), 157 | seqNum(int32_t()) 158 | { } 159 | }; 160 | 161 | struct dot11_data_Data { 162 | dot11_Header header; 163 | dot11_data_Header dataHeader; 164 | dot11_data_Data() : 165 | header(dot11_Header()), 166 | dataHeader(dot11_data_Header()) 167 | { } 168 | }; 169 | 170 | struct dot11_data_QosData { 171 | dot11_Header header; 172 | dot11_data_Header dataHeader; 173 | int32_t qosControl; 174 | dot11_data_QosData() : 175 | header(dot11_Header()), 176 | dataHeader(dot11_data_Header()), 177 | qosControl(int32_t()) 178 | { } 179 | }; 180 | 181 | enum dot11_mgmt_Capability { 182 | ESS, 183 | IBSS, 184 | CF_POLL, 185 | CF_POLL_REQ, 186 | PRIVACY, 187 | SHORT_PREAMBLE, 188 | PBCC, 189 | CHANNEL_AGILITY, 190 | SPECTRUM_MGMT, 191 | QOS, 192 | SST, 193 | APSD, 194 | RADIO_MEASUREMENT, 195 | DSSS_OFDM, 196 | DELAYED_BLOCK_ACK, 197 | IMMEDIATE_BLOCK_ACK, 198 | }; 199 | 200 | struct dot11_mgmt_Header { 201 | boost::array addr2; 202 | boost::array addr3; 203 | boost::array addr4; 204 | int32_t fragNum; 205 | int32_t seqNum; 206 | dot11_mgmt_Header() : 207 | addr2(boost::array()), 208 | addr3(boost::array()), 209 | addr4(boost::array()), 210 | fragNum(int32_t()), 211 | seqNum(int32_t()) 212 | { } 213 | }; 214 | 215 | struct dot11_mgmt_AssocRequest { 216 | dot11_Header header; 217 | dot11_mgmt_Header mgmtHeader; 218 | std::vector capabilities; 219 | int32_t listenInterval; 220 | dot11_mgmt_AssocRequest() : 221 | header(dot11_Header()), 222 | mgmtHeader(dot11_mgmt_Header()), 223 | capabilities(std::vector()), 224 | listenInterval(int32_t()) 225 | { } 226 | }; 227 | 228 | struct dot11_mgmt_AssocResponse { 229 | dot11_Header header; 230 | dot11_mgmt_Header mgmtHeader; 231 | std::vector capabilities; 232 | int32_t statusCode; 233 | int32_t aid; 234 | dot11_mgmt_AssocResponse() : 235 | header(dot11_Header()), 236 | mgmtHeader(dot11_mgmt_Header()), 237 | capabilities(std::vector()), 238 | statusCode(int32_t()), 239 | aid(int32_t()) 240 | { } 241 | }; 242 | 243 | struct dot11_mgmt_Authentication { 244 | dot11_Header header; 245 | dot11_mgmt_Header mgmtHeader; 246 | int32_t authAlgorithm; 247 | int32_t authSeqNumber; 248 | int32_t statusCode; 249 | dot11_mgmt_Authentication() : 250 | header(dot11_Header()), 251 | mgmtHeader(dot11_mgmt_Header()), 252 | authAlgorithm(int32_t()), 253 | authSeqNumber(int32_t()), 254 | statusCode(int32_t()) 255 | { } 256 | }; 257 | 258 | struct dot11_mgmt_Beacon { 259 | dot11_Header header; 260 | dot11_mgmt_Header mgmtHeader; 261 | int64_t timestamp; 262 | int32_t interval; 263 | std::vector capabilities; 264 | dot11_mgmt_Beacon() : 265 | header(dot11_Header()), 266 | mgmtHeader(dot11_mgmt_Header()), 267 | timestamp(int64_t()), 268 | interval(int32_t()), 269 | capabilities(std::vector()) 270 | { } 271 | }; 272 | 273 | struct dot11_mgmt_Deauthentication { 274 | dot11_Header header; 275 | dot11_mgmt_Header mgmtHeader; 276 | int32_t reasonCode; 277 | dot11_mgmt_Deauthentication() : 278 | header(dot11_Header()), 279 | mgmtHeader(dot11_mgmt_Header()), 280 | reasonCode(int32_t()) 281 | { } 282 | }; 283 | 284 | struct dot11_mgmt_Disassoc { 285 | dot11_Header header; 286 | dot11_mgmt_Header mgmtHeader; 287 | int32_t reasonCode; 288 | dot11_mgmt_Disassoc() : 289 | header(dot11_Header()), 290 | mgmtHeader(dot11_mgmt_Header()), 291 | reasonCode(int32_t()) 292 | { } 293 | }; 294 | 295 | struct dot11_mgmt_ProbeRequest { 296 | dot11_Header header; 297 | dot11_mgmt_Header mgmtHeader; 298 | dot11_mgmt_ProbeRequest() : 299 | header(dot11_Header()), 300 | mgmtHeader(dot11_mgmt_Header()) 301 | { } 302 | }; 303 | 304 | struct dot11_mgmt_ProbeResponse { 305 | dot11_Header header; 306 | dot11_mgmt_Header mgmtHeader; 307 | int64_t timestamp; 308 | int32_t interval; 309 | std::vector capabilities; 310 | dot11_mgmt_ProbeResponse() : 311 | header(dot11_Header()), 312 | mgmtHeader(dot11_mgmt_Header()), 313 | timestamp(int64_t()), 314 | interval(int32_t()), 315 | capabilities(std::vector()) 316 | { } 317 | }; 318 | 319 | struct dot11_mgmt_ReassocRequest { 320 | dot11_Header header; 321 | dot11_mgmt_Header mgmtHeader; 322 | std::vector capabilities; 323 | int32_t listenInterval; 324 | boost::array currentAp; 325 | dot11_mgmt_ReassocRequest() : 326 | header(dot11_Header()), 327 | mgmtHeader(dot11_mgmt_Header()), 328 | capabilities(std::vector()), 329 | listenInterval(int32_t()), 330 | currentAp(boost::array()) 331 | { } 332 | }; 333 | 334 | struct dot11_mgmt_ReassocResponse { 335 | dot11_Header header; 336 | dot11_mgmt_Header mgmtHeader; 337 | std::vector capabilities; 338 | int32_t statusCode; 339 | int32_t aid; 340 | dot11_mgmt_ReassocResponse() : 341 | header(dot11_Header()), 342 | mgmtHeader(dot11_mgmt_Header()), 343 | capabilities(std::vector()), 344 | statusCode(int32_t()), 345 | aid(int32_t()) 346 | { } 347 | }; 348 | 349 | enum radiotap_Flag { 350 | CFP, 351 | PREAMBLE, 352 | WEP, 353 | FRAGMENTATION, 354 | FCS, 355 | PADDING, 356 | FAILED_FCS, 357 | SHORT_GI, 358 | }; 359 | 360 | enum radiotap_ChannelType { 361 | TURBO, 362 | CCK, 363 | OFDM, 364 | TWO_GZ, 365 | FIVE_GZ, 366 | PASSIVE, 367 | DYN_CCK_OFDM, 368 | GFSK, 369 | }; 370 | 371 | struct radiotap_Channel { 372 | int32_t freq; 373 | radiotap_ChannelType type; 374 | radiotap_Channel() : 375 | freq(int32_t()), 376 | type(radiotap_ChannelType()) 377 | { } 378 | }; 379 | 380 | struct _63_Union__0__ { 381 | private: 382 | size_t idx_; 383 | boost::any value_; 384 | public: 385 | size_t idx() const { return idx_; } 386 | bool is_null() const { 387 | return (idx_ == 0); 388 | } 389 | void set_null() { 390 | idx_ = 0; 391 | value_ = boost::any(); 392 | } 393 | int64_t get_long() const; 394 | void set_long(const int64_t& v); 395 | _63_Union__0__(); 396 | }; 397 | 398 | struct _63_Union__1__ { 399 | private: 400 | size_t idx_; 401 | boost::any value_; 402 | public: 403 | size_t idx() const { return idx_; } 404 | bool is_null() const { 405 | return (idx_ == 0); 406 | } 407 | void set_null() { 408 | idx_ = 0; 409 | value_ = boost::any(); 410 | } 411 | std::vector get_array() const; 412 | void set_array(const std::vector& v); 413 | _63_Union__1__(); 414 | }; 415 | 416 | struct _63_Union__2__ { 417 | private: 418 | size_t idx_; 419 | boost::any value_; 420 | public: 421 | size_t idx() const { return idx_; } 422 | bool is_null() const { 423 | return (idx_ == 0); 424 | } 425 | void set_null() { 426 | idx_ = 0; 427 | value_ = boost::any(); 428 | } 429 | int32_t get_int() const; 430 | void set_int(const int32_t& v); 431 | _63_Union__2__(); 432 | }; 433 | 434 | struct _63_Union__3__ { 435 | private: 436 | size_t idx_; 437 | boost::any value_; 438 | public: 439 | size_t idx() const { return idx_; } 440 | bool is_null() const { 441 | return (idx_ == 0); 442 | } 443 | void set_null() { 444 | idx_ = 0; 445 | value_ = boost::any(); 446 | } 447 | radiotap_Channel get_radiotap_Channel() const; 448 | void set_radiotap_Channel(const radiotap_Channel& v); 449 | _63_Union__3__(); 450 | }; 451 | 452 | struct _63_Union__4__ { 453 | private: 454 | size_t idx_; 455 | boost::any value_; 456 | public: 457 | size_t idx() const { return idx_; } 458 | bool is_null() const { 459 | return (idx_ == 0); 460 | } 461 | void set_null() { 462 | idx_ = 0; 463 | value_ = boost::any(); 464 | } 465 | Unsupported get_Unsupported() const; 466 | void set_Unsupported(const Unsupported& v); 467 | dot11_Unsupported get_dot11_Unsupported() const; 468 | void set_dot11_Unsupported(const dot11_Unsupported& v); 469 | dot11_ctrl_Ack get_dot11_ctrl_Ack() const; 470 | void set_dot11_ctrl_Ack(const dot11_ctrl_Ack& v); 471 | dot11_ctrl_BlockAck get_dot11_ctrl_BlockAck() const; 472 | void set_dot11_ctrl_BlockAck(const dot11_ctrl_BlockAck& v); 473 | dot11_ctrl_BlockAckRequest get_dot11_ctrl_BlockAckRequest() const; 474 | void set_dot11_ctrl_BlockAckRequest(const dot11_ctrl_BlockAckRequest& v); 475 | dot11_ctrl_CfEnd get_dot11_ctrl_CfEnd() const; 476 | void set_dot11_ctrl_CfEnd(const dot11_ctrl_CfEnd& v); 477 | dot11_ctrl_EndCfAck get_dot11_ctrl_EndCfAck() const; 478 | void set_dot11_ctrl_EndCfAck(const dot11_ctrl_EndCfAck& v); 479 | dot11_ctrl_PsPoll get_dot11_ctrl_PsPoll() const; 480 | void set_dot11_ctrl_PsPoll(const dot11_ctrl_PsPoll& v); 481 | dot11_ctrl_Rts get_dot11_ctrl_Rts() const; 482 | void set_dot11_ctrl_Rts(const dot11_ctrl_Rts& v); 483 | dot11_data_Data get_dot11_data_Data() const; 484 | void set_dot11_data_Data(const dot11_data_Data& v); 485 | dot11_data_QosData get_dot11_data_QosData() const; 486 | void set_dot11_data_QosData(const dot11_data_QosData& v); 487 | dot11_mgmt_AssocRequest get_dot11_mgmt_AssocRequest() const; 488 | void set_dot11_mgmt_AssocRequest(const dot11_mgmt_AssocRequest& v); 489 | dot11_mgmt_AssocResponse get_dot11_mgmt_AssocResponse() const; 490 | void set_dot11_mgmt_AssocResponse(const dot11_mgmt_AssocResponse& v); 491 | dot11_mgmt_Authentication get_dot11_mgmt_Authentication() const; 492 | void set_dot11_mgmt_Authentication(const dot11_mgmt_Authentication& v); 493 | dot11_mgmt_Beacon get_dot11_mgmt_Beacon() const; 494 | void set_dot11_mgmt_Beacon(const dot11_mgmt_Beacon& v); 495 | dot11_mgmt_Deauthentication get_dot11_mgmt_Deauthentication() const; 496 | void set_dot11_mgmt_Deauthentication(const dot11_mgmt_Deauthentication& v); 497 | dot11_mgmt_Disassoc get_dot11_mgmt_Disassoc() const; 498 | void set_dot11_mgmt_Disassoc(const dot11_mgmt_Disassoc& v); 499 | dot11_mgmt_ProbeRequest get_dot11_mgmt_ProbeRequest() const; 500 | void set_dot11_mgmt_ProbeRequest(const dot11_mgmt_ProbeRequest& v); 501 | dot11_mgmt_ProbeResponse get_dot11_mgmt_ProbeResponse() const; 502 | void set_dot11_mgmt_ProbeResponse(const dot11_mgmt_ProbeResponse& v); 503 | dot11_mgmt_ReassocRequest get_dot11_mgmt_ReassocRequest() const; 504 | void set_dot11_mgmt_ReassocRequest(const dot11_mgmt_ReassocRequest& v); 505 | dot11_mgmt_ReassocResponse get_dot11_mgmt_ReassocResponse() const; 506 | void set_dot11_mgmt_ReassocResponse(const dot11_mgmt_ReassocResponse& v); 507 | _63_Union__4__(); 508 | }; 509 | 510 | struct Radiotap { 511 | typedef _63_Union__0__ tsft_t; 512 | typedef _63_Union__1__ flags_t; 513 | typedef _63_Union__2__ rate_t; 514 | typedef _63_Union__3__ channel_t; 515 | typedef _63_Union__4__ frame_t; 516 | tsft_t tsft; 517 | flags_t flags; 518 | rate_t rate; 519 | channel_t channel; 520 | frame_t frame; 521 | Radiotap() : 522 | tsft(tsft_t()), 523 | flags(flags_t()), 524 | rate(rate_t()), 525 | channel(channel_t()), 526 | frame(frame_t()) 527 | { } 528 | }; 529 | 530 | struct _63_Union__5__ { 531 | private: 532 | size_t idx_; 533 | boost::any value_; 534 | public: 535 | size_t idx() const { return idx_; } 536 | Unsupported get_Unsupported() const; 537 | void set_Unsupported(const Unsupported& v); 538 | Ethernet2 get_Ethernet2() const; 539 | void set_Ethernet2(const Ethernet2& v); 540 | Radiotap get_Radiotap() const; 541 | void set_Radiotap(const Radiotap& v); 542 | _63_Union__5__(); 543 | }; 544 | 545 | struct Pdu { 546 | typedef _63_Union__5__ frame_t; 547 | int32_t size; 548 | int64_t timestamp; 549 | frame_t frame; 550 | Pdu() : 551 | size(int32_t()), 552 | timestamp(int64_t()), 553 | frame(frame_t()) 554 | { } 555 | }; 556 | 557 | struct _63_Union__6__ { 558 | private: 559 | size_t idx_; 560 | boost::any value_; 561 | public: 562 | size_t idx() const { return idx_; } 563 | Unsupported get_Unsupported() const; 564 | void set_Unsupported(const Unsupported& v); 565 | boost::array get_MacAddr() const; 566 | void set_MacAddr(const boost::array& v); 567 | Ethernet2 get_Ethernet2() const; 568 | void set_Ethernet2(const Ethernet2& v); 569 | dot11_Header get_dot11_Header() const; 570 | void set_dot11_Header(const dot11_Header& v); 571 | dot11_Unsupported get_dot11_Unsupported() const; 572 | void set_dot11_Unsupported(const dot11_Unsupported& v); 573 | dot11_ctrl_Ack get_dot11_ctrl_Ack() const; 574 | void set_dot11_ctrl_Ack(const dot11_ctrl_Ack& v); 575 | dot11_ctrl_BlockAck get_dot11_ctrl_BlockAck() const; 576 | void set_dot11_ctrl_BlockAck(const dot11_ctrl_BlockAck& v); 577 | dot11_ctrl_BlockAckRequest get_dot11_ctrl_BlockAckRequest() const; 578 | void set_dot11_ctrl_BlockAckRequest(const dot11_ctrl_BlockAckRequest& v); 579 | dot11_ctrl_CfEnd get_dot11_ctrl_CfEnd() const; 580 | void set_dot11_ctrl_CfEnd(const dot11_ctrl_CfEnd& v); 581 | dot11_ctrl_EndCfAck get_dot11_ctrl_EndCfAck() const; 582 | void set_dot11_ctrl_EndCfAck(const dot11_ctrl_EndCfAck& v); 583 | dot11_ctrl_PsPoll get_dot11_ctrl_PsPoll() const; 584 | void set_dot11_ctrl_PsPoll(const dot11_ctrl_PsPoll& v); 585 | dot11_ctrl_Rts get_dot11_ctrl_Rts() const; 586 | void set_dot11_ctrl_Rts(const dot11_ctrl_Rts& v); 587 | dot11_data_Header get_dot11_data_Header() const; 588 | void set_dot11_data_Header(const dot11_data_Header& v); 589 | dot11_data_Data get_dot11_data_Data() const; 590 | void set_dot11_data_Data(const dot11_data_Data& v); 591 | dot11_data_QosData get_dot11_data_QosData() const; 592 | void set_dot11_data_QosData(const dot11_data_QosData& v); 593 | dot11_mgmt_Capability get_dot11_mgmt_Capability() const; 594 | void set_dot11_mgmt_Capability(const dot11_mgmt_Capability& v); 595 | dot11_mgmt_Header get_dot11_mgmt_Header() const; 596 | void set_dot11_mgmt_Header(const dot11_mgmt_Header& v); 597 | dot11_mgmt_AssocRequest get_dot11_mgmt_AssocRequest() const; 598 | void set_dot11_mgmt_AssocRequest(const dot11_mgmt_AssocRequest& v); 599 | dot11_mgmt_AssocResponse get_dot11_mgmt_AssocResponse() const; 600 | void set_dot11_mgmt_AssocResponse(const dot11_mgmt_AssocResponse& v); 601 | dot11_mgmt_Authentication get_dot11_mgmt_Authentication() const; 602 | void set_dot11_mgmt_Authentication(const dot11_mgmt_Authentication& v); 603 | dot11_mgmt_Beacon get_dot11_mgmt_Beacon() const; 604 | void set_dot11_mgmt_Beacon(const dot11_mgmt_Beacon& v); 605 | dot11_mgmt_Deauthentication get_dot11_mgmt_Deauthentication() const; 606 | void set_dot11_mgmt_Deauthentication(const dot11_mgmt_Deauthentication& v); 607 | dot11_mgmt_Disassoc get_dot11_mgmt_Disassoc() const; 608 | void set_dot11_mgmt_Disassoc(const dot11_mgmt_Disassoc& v); 609 | dot11_mgmt_ProbeRequest get_dot11_mgmt_ProbeRequest() const; 610 | void set_dot11_mgmt_ProbeRequest(const dot11_mgmt_ProbeRequest& v); 611 | dot11_mgmt_ProbeResponse get_dot11_mgmt_ProbeResponse() const; 612 | void set_dot11_mgmt_ProbeResponse(const dot11_mgmt_ProbeResponse& v); 613 | dot11_mgmt_ReassocRequest get_dot11_mgmt_ReassocRequest() const; 614 | void set_dot11_mgmt_ReassocRequest(const dot11_mgmt_ReassocRequest& v); 615 | dot11_mgmt_ReassocResponse get_dot11_mgmt_ReassocResponse() const; 616 | void set_dot11_mgmt_ReassocResponse(const dot11_mgmt_ReassocResponse& v); 617 | radiotap_Flag get_radiotap_Flag() const; 618 | void set_radiotap_Flag(const radiotap_Flag& v); 619 | radiotap_ChannelType get_radiotap_ChannelType() const; 620 | void set_radiotap_ChannelType(const radiotap_ChannelType& v); 621 | radiotap_Channel get_radiotap_Channel() const; 622 | void set_radiotap_Channel(const radiotap_Channel& v); 623 | Radiotap get_Radiotap() const; 624 | void set_Radiotap(const Radiotap& v); 625 | Pdu get_Pdu() const; 626 | void set_Pdu(const Pdu& v); 627 | _63_Union__6__(); 628 | }; 629 | 630 | inline 631 | int64_t _63_Union__0__::get_long() const { 632 | if (idx_ != 1) { 633 | throw avro::Exception("Invalid type for union"); 634 | } 635 | return boost::any_cast(value_); 636 | } 637 | 638 | inline 639 | void _63_Union__0__::set_long(const int64_t& v) { 640 | idx_ = 1; 641 | value_ = v; 642 | } 643 | 644 | inline 645 | std::vector _63_Union__1__::get_array() const { 646 | if (idx_ != 1) { 647 | throw avro::Exception("Invalid type for union"); 648 | } 649 | return boost::any_cast >(value_); 650 | } 651 | 652 | inline 653 | void _63_Union__1__::set_array(const std::vector& v) { 654 | idx_ = 1; 655 | value_ = v; 656 | } 657 | 658 | inline 659 | int32_t _63_Union__2__::get_int() const { 660 | if (idx_ != 1) { 661 | throw avro::Exception("Invalid type for union"); 662 | } 663 | return boost::any_cast(value_); 664 | } 665 | 666 | inline 667 | void _63_Union__2__::set_int(const int32_t& v) { 668 | idx_ = 1; 669 | value_ = v; 670 | } 671 | 672 | inline 673 | radiotap_Channel _63_Union__3__::get_radiotap_Channel() const { 674 | if (idx_ != 1) { 675 | throw avro::Exception("Invalid type for union"); 676 | } 677 | return boost::any_cast(value_); 678 | } 679 | 680 | inline 681 | void _63_Union__3__::set_radiotap_Channel(const radiotap_Channel& v) { 682 | idx_ = 1; 683 | value_ = v; 684 | } 685 | 686 | inline 687 | Unsupported _63_Union__4__::get_Unsupported() const { 688 | if (idx_ != 1) { 689 | throw avro::Exception("Invalid type for union"); 690 | } 691 | return boost::any_cast(value_); 692 | } 693 | 694 | inline 695 | void _63_Union__4__::set_Unsupported(const Unsupported& v) { 696 | idx_ = 1; 697 | value_ = v; 698 | } 699 | 700 | inline 701 | dot11_Unsupported _63_Union__4__::get_dot11_Unsupported() const { 702 | if (idx_ != 2) { 703 | throw avro::Exception("Invalid type for union"); 704 | } 705 | return boost::any_cast(value_); 706 | } 707 | 708 | inline 709 | void _63_Union__4__::set_dot11_Unsupported(const dot11_Unsupported& v) { 710 | idx_ = 2; 711 | value_ = v; 712 | } 713 | 714 | inline 715 | dot11_ctrl_Ack _63_Union__4__::get_dot11_ctrl_Ack() const { 716 | if (idx_ != 3) { 717 | throw avro::Exception("Invalid type for union"); 718 | } 719 | return boost::any_cast(value_); 720 | } 721 | 722 | inline 723 | void _63_Union__4__::set_dot11_ctrl_Ack(const dot11_ctrl_Ack& v) { 724 | idx_ = 3; 725 | value_ = v; 726 | } 727 | 728 | inline 729 | dot11_ctrl_BlockAck _63_Union__4__::get_dot11_ctrl_BlockAck() const { 730 | if (idx_ != 4) { 731 | throw avro::Exception("Invalid type for union"); 732 | } 733 | return boost::any_cast(value_); 734 | } 735 | 736 | inline 737 | void _63_Union__4__::set_dot11_ctrl_BlockAck(const dot11_ctrl_BlockAck& v) { 738 | idx_ = 4; 739 | value_ = v; 740 | } 741 | 742 | inline 743 | dot11_ctrl_BlockAckRequest _63_Union__4__::get_dot11_ctrl_BlockAckRequest() const { 744 | if (idx_ != 5) { 745 | throw avro::Exception("Invalid type for union"); 746 | } 747 | return boost::any_cast(value_); 748 | } 749 | 750 | inline 751 | void _63_Union__4__::set_dot11_ctrl_BlockAckRequest(const dot11_ctrl_BlockAckRequest& v) { 752 | idx_ = 5; 753 | value_ = v; 754 | } 755 | 756 | inline 757 | dot11_ctrl_CfEnd _63_Union__4__::get_dot11_ctrl_CfEnd() const { 758 | if (idx_ != 6) { 759 | throw avro::Exception("Invalid type for union"); 760 | } 761 | return boost::any_cast(value_); 762 | } 763 | 764 | inline 765 | void _63_Union__4__::set_dot11_ctrl_CfEnd(const dot11_ctrl_CfEnd& v) { 766 | idx_ = 6; 767 | value_ = v; 768 | } 769 | 770 | inline 771 | dot11_ctrl_EndCfAck _63_Union__4__::get_dot11_ctrl_EndCfAck() const { 772 | if (idx_ != 7) { 773 | throw avro::Exception("Invalid type for union"); 774 | } 775 | return boost::any_cast(value_); 776 | } 777 | 778 | inline 779 | void _63_Union__4__::set_dot11_ctrl_EndCfAck(const dot11_ctrl_EndCfAck& v) { 780 | idx_ = 7; 781 | value_ = v; 782 | } 783 | 784 | inline 785 | dot11_ctrl_PsPoll _63_Union__4__::get_dot11_ctrl_PsPoll() const { 786 | if (idx_ != 8) { 787 | throw avro::Exception("Invalid type for union"); 788 | } 789 | return boost::any_cast(value_); 790 | } 791 | 792 | inline 793 | void _63_Union__4__::set_dot11_ctrl_PsPoll(const dot11_ctrl_PsPoll& v) { 794 | idx_ = 8; 795 | value_ = v; 796 | } 797 | 798 | inline 799 | dot11_ctrl_Rts _63_Union__4__::get_dot11_ctrl_Rts() const { 800 | if (idx_ != 9) { 801 | throw avro::Exception("Invalid type for union"); 802 | } 803 | return boost::any_cast(value_); 804 | } 805 | 806 | inline 807 | void _63_Union__4__::set_dot11_ctrl_Rts(const dot11_ctrl_Rts& v) { 808 | idx_ = 9; 809 | value_ = v; 810 | } 811 | 812 | inline 813 | dot11_data_Data _63_Union__4__::get_dot11_data_Data() const { 814 | if (idx_ != 10) { 815 | throw avro::Exception("Invalid type for union"); 816 | } 817 | return boost::any_cast(value_); 818 | } 819 | 820 | inline 821 | void _63_Union__4__::set_dot11_data_Data(const dot11_data_Data& v) { 822 | idx_ = 10; 823 | value_ = v; 824 | } 825 | 826 | inline 827 | dot11_data_QosData _63_Union__4__::get_dot11_data_QosData() const { 828 | if (idx_ != 11) { 829 | throw avro::Exception("Invalid type for union"); 830 | } 831 | return boost::any_cast(value_); 832 | } 833 | 834 | inline 835 | void _63_Union__4__::set_dot11_data_QosData(const dot11_data_QosData& v) { 836 | idx_ = 11; 837 | value_ = v; 838 | } 839 | 840 | inline 841 | dot11_mgmt_AssocRequest _63_Union__4__::get_dot11_mgmt_AssocRequest() const { 842 | if (idx_ != 12) { 843 | throw avro::Exception("Invalid type for union"); 844 | } 845 | return boost::any_cast(value_); 846 | } 847 | 848 | inline 849 | void _63_Union__4__::set_dot11_mgmt_AssocRequest(const dot11_mgmt_AssocRequest& v) { 850 | idx_ = 12; 851 | value_ = v; 852 | } 853 | 854 | inline 855 | dot11_mgmt_AssocResponse _63_Union__4__::get_dot11_mgmt_AssocResponse() const { 856 | if (idx_ != 13) { 857 | throw avro::Exception("Invalid type for union"); 858 | } 859 | return boost::any_cast(value_); 860 | } 861 | 862 | inline 863 | void _63_Union__4__::set_dot11_mgmt_AssocResponse(const dot11_mgmt_AssocResponse& v) { 864 | idx_ = 13; 865 | value_ = v; 866 | } 867 | 868 | inline 869 | dot11_mgmt_Authentication _63_Union__4__::get_dot11_mgmt_Authentication() const { 870 | if (idx_ != 14) { 871 | throw avro::Exception("Invalid type for union"); 872 | } 873 | return boost::any_cast(value_); 874 | } 875 | 876 | inline 877 | void _63_Union__4__::set_dot11_mgmt_Authentication(const dot11_mgmt_Authentication& v) { 878 | idx_ = 14; 879 | value_ = v; 880 | } 881 | 882 | inline 883 | dot11_mgmt_Beacon _63_Union__4__::get_dot11_mgmt_Beacon() const { 884 | if (idx_ != 15) { 885 | throw avro::Exception("Invalid type for union"); 886 | } 887 | return boost::any_cast(value_); 888 | } 889 | 890 | inline 891 | void _63_Union__4__::set_dot11_mgmt_Beacon(const dot11_mgmt_Beacon& v) { 892 | idx_ = 15; 893 | value_ = v; 894 | } 895 | 896 | inline 897 | dot11_mgmt_Deauthentication _63_Union__4__::get_dot11_mgmt_Deauthentication() const { 898 | if (idx_ != 16) { 899 | throw avro::Exception("Invalid type for union"); 900 | } 901 | return boost::any_cast(value_); 902 | } 903 | 904 | inline 905 | void _63_Union__4__::set_dot11_mgmt_Deauthentication(const dot11_mgmt_Deauthentication& v) { 906 | idx_ = 16; 907 | value_ = v; 908 | } 909 | 910 | inline 911 | dot11_mgmt_Disassoc _63_Union__4__::get_dot11_mgmt_Disassoc() const { 912 | if (idx_ != 17) { 913 | throw avro::Exception("Invalid type for union"); 914 | } 915 | return boost::any_cast(value_); 916 | } 917 | 918 | inline 919 | void _63_Union__4__::set_dot11_mgmt_Disassoc(const dot11_mgmt_Disassoc& v) { 920 | idx_ = 17; 921 | value_ = v; 922 | } 923 | 924 | inline 925 | dot11_mgmt_ProbeRequest _63_Union__4__::get_dot11_mgmt_ProbeRequest() const { 926 | if (idx_ != 18) { 927 | throw avro::Exception("Invalid type for union"); 928 | } 929 | return boost::any_cast(value_); 930 | } 931 | 932 | inline 933 | void _63_Union__4__::set_dot11_mgmt_ProbeRequest(const dot11_mgmt_ProbeRequest& v) { 934 | idx_ = 18; 935 | value_ = v; 936 | } 937 | 938 | inline 939 | dot11_mgmt_ProbeResponse _63_Union__4__::get_dot11_mgmt_ProbeResponse() const { 940 | if (idx_ != 19) { 941 | throw avro::Exception("Invalid type for union"); 942 | } 943 | return boost::any_cast(value_); 944 | } 945 | 946 | inline 947 | void _63_Union__4__::set_dot11_mgmt_ProbeResponse(const dot11_mgmt_ProbeResponse& v) { 948 | idx_ = 19; 949 | value_ = v; 950 | } 951 | 952 | inline 953 | dot11_mgmt_ReassocRequest _63_Union__4__::get_dot11_mgmt_ReassocRequest() const { 954 | if (idx_ != 20) { 955 | throw avro::Exception("Invalid type for union"); 956 | } 957 | return boost::any_cast(value_); 958 | } 959 | 960 | inline 961 | void _63_Union__4__::set_dot11_mgmt_ReassocRequest(const dot11_mgmt_ReassocRequest& v) { 962 | idx_ = 20; 963 | value_ = v; 964 | } 965 | 966 | inline 967 | dot11_mgmt_ReassocResponse _63_Union__4__::get_dot11_mgmt_ReassocResponse() const { 968 | if (idx_ != 21) { 969 | throw avro::Exception("Invalid type for union"); 970 | } 971 | return boost::any_cast(value_); 972 | } 973 | 974 | inline 975 | void _63_Union__4__::set_dot11_mgmt_ReassocResponse(const dot11_mgmt_ReassocResponse& v) { 976 | idx_ = 21; 977 | value_ = v; 978 | } 979 | 980 | inline 981 | Unsupported _63_Union__5__::get_Unsupported() const { 982 | if (idx_ != 0) { 983 | throw avro::Exception("Invalid type for union"); 984 | } 985 | return boost::any_cast(value_); 986 | } 987 | 988 | inline 989 | void _63_Union__5__::set_Unsupported(const Unsupported& v) { 990 | idx_ = 0; 991 | value_ = v; 992 | } 993 | 994 | inline 995 | Ethernet2 _63_Union__5__::get_Ethernet2() const { 996 | if (idx_ != 1) { 997 | throw avro::Exception("Invalid type for union"); 998 | } 999 | return boost::any_cast(value_); 1000 | } 1001 | 1002 | inline 1003 | void _63_Union__5__::set_Ethernet2(const Ethernet2& v) { 1004 | idx_ = 1; 1005 | value_ = v; 1006 | } 1007 | 1008 | inline 1009 | Radiotap _63_Union__5__::get_Radiotap() const { 1010 | if (idx_ != 2) { 1011 | throw avro::Exception("Invalid type for union"); 1012 | } 1013 | return boost::any_cast(value_); 1014 | } 1015 | 1016 | inline 1017 | void _63_Union__5__::set_Radiotap(const Radiotap& v) { 1018 | idx_ = 2; 1019 | value_ = v; 1020 | } 1021 | 1022 | inline 1023 | Unsupported _63_Union__6__::get_Unsupported() const { 1024 | if (idx_ != 0) { 1025 | throw avro::Exception("Invalid type for union"); 1026 | } 1027 | return boost::any_cast(value_); 1028 | } 1029 | 1030 | inline 1031 | void _63_Union__6__::set_Unsupported(const Unsupported& v) { 1032 | idx_ = 0; 1033 | value_ = v; 1034 | } 1035 | 1036 | inline 1037 | boost::array _63_Union__6__::get_MacAddr() const { 1038 | if (idx_ != 1) { 1039 | throw avro::Exception("Invalid type for union"); 1040 | } 1041 | return boost::any_cast >(value_); 1042 | } 1043 | 1044 | inline 1045 | void _63_Union__6__::set_MacAddr(const boost::array& v) { 1046 | idx_ = 1; 1047 | value_ = v; 1048 | } 1049 | 1050 | inline 1051 | Ethernet2 _63_Union__6__::get_Ethernet2() const { 1052 | if (idx_ != 2) { 1053 | throw avro::Exception("Invalid type for union"); 1054 | } 1055 | return boost::any_cast(value_); 1056 | } 1057 | 1058 | inline 1059 | void _63_Union__6__::set_Ethernet2(const Ethernet2& v) { 1060 | idx_ = 2; 1061 | value_ = v; 1062 | } 1063 | 1064 | inline 1065 | dot11_Header _63_Union__6__::get_dot11_Header() const { 1066 | if (idx_ != 3) { 1067 | throw avro::Exception("Invalid type for union"); 1068 | } 1069 | return boost::any_cast(value_); 1070 | } 1071 | 1072 | inline 1073 | void _63_Union__6__::set_dot11_Header(const dot11_Header& v) { 1074 | idx_ = 3; 1075 | value_ = v; 1076 | } 1077 | 1078 | inline 1079 | dot11_Unsupported _63_Union__6__::get_dot11_Unsupported() const { 1080 | if (idx_ != 4) { 1081 | throw avro::Exception("Invalid type for union"); 1082 | } 1083 | return boost::any_cast(value_); 1084 | } 1085 | 1086 | inline 1087 | void _63_Union__6__::set_dot11_Unsupported(const dot11_Unsupported& v) { 1088 | idx_ = 4; 1089 | value_ = v; 1090 | } 1091 | 1092 | inline 1093 | dot11_ctrl_Ack _63_Union__6__::get_dot11_ctrl_Ack() const { 1094 | if (idx_ != 5) { 1095 | throw avro::Exception("Invalid type for union"); 1096 | } 1097 | return boost::any_cast(value_); 1098 | } 1099 | 1100 | inline 1101 | void _63_Union__6__::set_dot11_ctrl_Ack(const dot11_ctrl_Ack& v) { 1102 | idx_ = 5; 1103 | value_ = v; 1104 | } 1105 | 1106 | inline 1107 | dot11_ctrl_BlockAck _63_Union__6__::get_dot11_ctrl_BlockAck() const { 1108 | if (idx_ != 6) { 1109 | throw avro::Exception("Invalid type for union"); 1110 | } 1111 | return boost::any_cast(value_); 1112 | } 1113 | 1114 | inline 1115 | void _63_Union__6__::set_dot11_ctrl_BlockAck(const dot11_ctrl_BlockAck& v) { 1116 | idx_ = 6; 1117 | value_ = v; 1118 | } 1119 | 1120 | inline 1121 | dot11_ctrl_BlockAckRequest _63_Union__6__::get_dot11_ctrl_BlockAckRequest() const { 1122 | if (idx_ != 7) { 1123 | throw avro::Exception("Invalid type for union"); 1124 | } 1125 | return boost::any_cast(value_); 1126 | } 1127 | 1128 | inline 1129 | void _63_Union__6__::set_dot11_ctrl_BlockAckRequest(const dot11_ctrl_BlockAckRequest& v) { 1130 | idx_ = 7; 1131 | value_ = v; 1132 | } 1133 | 1134 | inline 1135 | dot11_ctrl_CfEnd _63_Union__6__::get_dot11_ctrl_CfEnd() const { 1136 | if (idx_ != 8) { 1137 | throw avro::Exception("Invalid type for union"); 1138 | } 1139 | return boost::any_cast(value_); 1140 | } 1141 | 1142 | inline 1143 | void _63_Union__6__::set_dot11_ctrl_CfEnd(const dot11_ctrl_CfEnd& v) { 1144 | idx_ = 8; 1145 | value_ = v; 1146 | } 1147 | 1148 | inline 1149 | dot11_ctrl_EndCfAck _63_Union__6__::get_dot11_ctrl_EndCfAck() const { 1150 | if (idx_ != 9) { 1151 | throw avro::Exception("Invalid type for union"); 1152 | } 1153 | return boost::any_cast(value_); 1154 | } 1155 | 1156 | inline 1157 | void _63_Union__6__::set_dot11_ctrl_EndCfAck(const dot11_ctrl_EndCfAck& v) { 1158 | idx_ = 9; 1159 | value_ = v; 1160 | } 1161 | 1162 | inline 1163 | dot11_ctrl_PsPoll _63_Union__6__::get_dot11_ctrl_PsPoll() const { 1164 | if (idx_ != 10) { 1165 | throw avro::Exception("Invalid type for union"); 1166 | } 1167 | return boost::any_cast(value_); 1168 | } 1169 | 1170 | inline 1171 | void _63_Union__6__::set_dot11_ctrl_PsPoll(const dot11_ctrl_PsPoll& v) { 1172 | idx_ = 10; 1173 | value_ = v; 1174 | } 1175 | 1176 | inline 1177 | dot11_ctrl_Rts _63_Union__6__::get_dot11_ctrl_Rts() const { 1178 | if (idx_ != 11) { 1179 | throw avro::Exception("Invalid type for union"); 1180 | } 1181 | return boost::any_cast(value_); 1182 | } 1183 | 1184 | inline 1185 | void _63_Union__6__::set_dot11_ctrl_Rts(const dot11_ctrl_Rts& v) { 1186 | idx_ = 11; 1187 | value_ = v; 1188 | } 1189 | 1190 | inline 1191 | dot11_data_Header _63_Union__6__::get_dot11_data_Header() const { 1192 | if (idx_ != 12) { 1193 | throw avro::Exception("Invalid type for union"); 1194 | } 1195 | return boost::any_cast(value_); 1196 | } 1197 | 1198 | inline 1199 | void _63_Union__6__::set_dot11_data_Header(const dot11_data_Header& v) { 1200 | idx_ = 12; 1201 | value_ = v; 1202 | } 1203 | 1204 | inline 1205 | dot11_data_Data _63_Union__6__::get_dot11_data_Data() const { 1206 | if (idx_ != 13) { 1207 | throw avro::Exception("Invalid type for union"); 1208 | } 1209 | return boost::any_cast(value_); 1210 | } 1211 | 1212 | inline 1213 | void _63_Union__6__::set_dot11_data_Data(const dot11_data_Data& v) { 1214 | idx_ = 13; 1215 | value_ = v; 1216 | } 1217 | 1218 | inline 1219 | dot11_data_QosData _63_Union__6__::get_dot11_data_QosData() const { 1220 | if (idx_ != 14) { 1221 | throw avro::Exception("Invalid type for union"); 1222 | } 1223 | return boost::any_cast(value_); 1224 | } 1225 | 1226 | inline 1227 | void _63_Union__6__::set_dot11_data_QosData(const dot11_data_QosData& v) { 1228 | idx_ = 14; 1229 | value_ = v; 1230 | } 1231 | 1232 | inline 1233 | dot11_mgmt_Capability _63_Union__6__::get_dot11_mgmt_Capability() const { 1234 | if (idx_ != 15) { 1235 | throw avro::Exception("Invalid type for union"); 1236 | } 1237 | return boost::any_cast(value_); 1238 | } 1239 | 1240 | inline 1241 | void _63_Union__6__::set_dot11_mgmt_Capability(const dot11_mgmt_Capability& v) { 1242 | idx_ = 15; 1243 | value_ = v; 1244 | } 1245 | 1246 | inline 1247 | dot11_mgmt_Header _63_Union__6__::get_dot11_mgmt_Header() const { 1248 | if (idx_ != 16) { 1249 | throw avro::Exception("Invalid type for union"); 1250 | } 1251 | return boost::any_cast(value_); 1252 | } 1253 | 1254 | inline 1255 | void _63_Union__6__::set_dot11_mgmt_Header(const dot11_mgmt_Header& v) { 1256 | idx_ = 16; 1257 | value_ = v; 1258 | } 1259 | 1260 | inline 1261 | dot11_mgmt_AssocRequest _63_Union__6__::get_dot11_mgmt_AssocRequest() const { 1262 | if (idx_ != 17) { 1263 | throw avro::Exception("Invalid type for union"); 1264 | } 1265 | return boost::any_cast(value_); 1266 | } 1267 | 1268 | inline 1269 | void _63_Union__6__::set_dot11_mgmt_AssocRequest(const dot11_mgmt_AssocRequest& v) { 1270 | idx_ = 17; 1271 | value_ = v; 1272 | } 1273 | 1274 | inline 1275 | dot11_mgmt_AssocResponse _63_Union__6__::get_dot11_mgmt_AssocResponse() const { 1276 | if (idx_ != 18) { 1277 | throw avro::Exception("Invalid type for union"); 1278 | } 1279 | return boost::any_cast(value_); 1280 | } 1281 | 1282 | inline 1283 | void _63_Union__6__::set_dot11_mgmt_AssocResponse(const dot11_mgmt_AssocResponse& v) { 1284 | idx_ = 18; 1285 | value_ = v; 1286 | } 1287 | 1288 | inline 1289 | dot11_mgmt_Authentication _63_Union__6__::get_dot11_mgmt_Authentication() const { 1290 | if (idx_ != 19) { 1291 | throw avro::Exception("Invalid type for union"); 1292 | } 1293 | return boost::any_cast(value_); 1294 | } 1295 | 1296 | inline 1297 | void _63_Union__6__::set_dot11_mgmt_Authentication(const dot11_mgmt_Authentication& v) { 1298 | idx_ = 19; 1299 | value_ = v; 1300 | } 1301 | 1302 | inline 1303 | dot11_mgmt_Beacon _63_Union__6__::get_dot11_mgmt_Beacon() const { 1304 | if (idx_ != 20) { 1305 | throw avro::Exception("Invalid type for union"); 1306 | } 1307 | return boost::any_cast(value_); 1308 | } 1309 | 1310 | inline 1311 | void _63_Union__6__::set_dot11_mgmt_Beacon(const dot11_mgmt_Beacon& v) { 1312 | idx_ = 20; 1313 | value_ = v; 1314 | } 1315 | 1316 | inline 1317 | dot11_mgmt_Deauthentication _63_Union__6__::get_dot11_mgmt_Deauthentication() const { 1318 | if (idx_ != 21) { 1319 | throw avro::Exception("Invalid type for union"); 1320 | } 1321 | return boost::any_cast(value_); 1322 | } 1323 | 1324 | inline 1325 | void _63_Union__6__::set_dot11_mgmt_Deauthentication(const dot11_mgmt_Deauthentication& v) { 1326 | idx_ = 21; 1327 | value_ = v; 1328 | } 1329 | 1330 | inline 1331 | dot11_mgmt_Disassoc _63_Union__6__::get_dot11_mgmt_Disassoc() const { 1332 | if (idx_ != 22) { 1333 | throw avro::Exception("Invalid type for union"); 1334 | } 1335 | return boost::any_cast(value_); 1336 | } 1337 | 1338 | inline 1339 | void _63_Union__6__::set_dot11_mgmt_Disassoc(const dot11_mgmt_Disassoc& v) { 1340 | idx_ = 22; 1341 | value_ = v; 1342 | } 1343 | 1344 | inline 1345 | dot11_mgmt_ProbeRequest _63_Union__6__::get_dot11_mgmt_ProbeRequest() const { 1346 | if (idx_ != 23) { 1347 | throw avro::Exception("Invalid type for union"); 1348 | } 1349 | return boost::any_cast(value_); 1350 | } 1351 | 1352 | inline 1353 | void _63_Union__6__::set_dot11_mgmt_ProbeRequest(const dot11_mgmt_ProbeRequest& v) { 1354 | idx_ = 23; 1355 | value_ = v; 1356 | } 1357 | 1358 | inline 1359 | dot11_mgmt_ProbeResponse _63_Union__6__::get_dot11_mgmt_ProbeResponse() const { 1360 | if (idx_ != 24) { 1361 | throw avro::Exception("Invalid type for union"); 1362 | } 1363 | return boost::any_cast(value_); 1364 | } 1365 | 1366 | inline 1367 | void _63_Union__6__::set_dot11_mgmt_ProbeResponse(const dot11_mgmt_ProbeResponse& v) { 1368 | idx_ = 24; 1369 | value_ = v; 1370 | } 1371 | 1372 | inline 1373 | dot11_mgmt_ReassocRequest _63_Union__6__::get_dot11_mgmt_ReassocRequest() const { 1374 | if (idx_ != 25) { 1375 | throw avro::Exception("Invalid type for union"); 1376 | } 1377 | return boost::any_cast(value_); 1378 | } 1379 | 1380 | inline 1381 | void _63_Union__6__::set_dot11_mgmt_ReassocRequest(const dot11_mgmt_ReassocRequest& v) { 1382 | idx_ = 25; 1383 | value_ = v; 1384 | } 1385 | 1386 | inline 1387 | dot11_mgmt_ReassocResponse _63_Union__6__::get_dot11_mgmt_ReassocResponse() const { 1388 | if (idx_ != 26) { 1389 | throw avro::Exception("Invalid type for union"); 1390 | } 1391 | return boost::any_cast(value_); 1392 | } 1393 | 1394 | inline 1395 | void _63_Union__6__::set_dot11_mgmt_ReassocResponse(const dot11_mgmt_ReassocResponse& v) { 1396 | idx_ = 26; 1397 | value_ = v; 1398 | } 1399 | 1400 | inline 1401 | radiotap_Flag _63_Union__6__::get_radiotap_Flag() const { 1402 | if (idx_ != 27) { 1403 | throw avro::Exception("Invalid type for union"); 1404 | } 1405 | return boost::any_cast(value_); 1406 | } 1407 | 1408 | inline 1409 | void _63_Union__6__::set_radiotap_Flag(const radiotap_Flag& v) { 1410 | idx_ = 27; 1411 | value_ = v; 1412 | } 1413 | 1414 | inline 1415 | radiotap_ChannelType _63_Union__6__::get_radiotap_ChannelType() const { 1416 | if (idx_ != 28) { 1417 | throw avro::Exception("Invalid type for union"); 1418 | } 1419 | return boost::any_cast(value_); 1420 | } 1421 | 1422 | inline 1423 | void _63_Union__6__::set_radiotap_ChannelType(const radiotap_ChannelType& v) { 1424 | idx_ = 28; 1425 | value_ = v; 1426 | } 1427 | 1428 | inline 1429 | radiotap_Channel _63_Union__6__::get_radiotap_Channel() const { 1430 | if (idx_ != 29) { 1431 | throw avro::Exception("Invalid type for union"); 1432 | } 1433 | return boost::any_cast(value_); 1434 | } 1435 | 1436 | inline 1437 | void _63_Union__6__::set_radiotap_Channel(const radiotap_Channel& v) { 1438 | idx_ = 29; 1439 | value_ = v; 1440 | } 1441 | 1442 | inline 1443 | Radiotap _63_Union__6__::get_Radiotap() const { 1444 | if (idx_ != 30) { 1445 | throw avro::Exception("Invalid type for union"); 1446 | } 1447 | return boost::any_cast(value_); 1448 | } 1449 | 1450 | inline 1451 | void _63_Union__6__::set_Radiotap(const Radiotap& v) { 1452 | idx_ = 30; 1453 | value_ = v; 1454 | } 1455 | 1456 | inline 1457 | Pdu _63_Union__6__::get_Pdu() const { 1458 | if (idx_ != 31) { 1459 | throw avro::Exception("Invalid type for union"); 1460 | } 1461 | return boost::any_cast(value_); 1462 | } 1463 | 1464 | inline 1465 | void _63_Union__6__::set_Pdu(const Pdu& v) { 1466 | idx_ = 31; 1467 | value_ = v; 1468 | } 1469 | 1470 | inline _63_Union__0__::_63_Union__0__() : idx_(0) { } 1471 | inline _63_Union__1__::_63_Union__1__() : idx_(0) { } 1472 | inline _63_Union__2__::_63_Union__2__() : idx_(0) { } 1473 | inline _63_Union__3__::_63_Union__3__() : idx_(0) { } 1474 | inline _63_Union__4__::_63_Union__4__() : idx_(0) { } 1475 | inline _63_Union__5__::_63_Union__5__() : idx_(0), value_(Unsupported()) { } 1476 | inline _63_Union__6__::_63_Union__6__() : idx_(0), value_(Unsupported()) { } 1477 | } 1478 | namespace avro { 1479 | template<> struct codec_traits { 1480 | static void encode(Encoder& e, const Layer2::Unsupported& v) { 1481 | avro::encode(e, v.name); 1482 | } 1483 | static void decode(Decoder& d, Layer2::Unsupported& v) { 1484 | if (avro::ResolvingDecoder *rd = 1485 | dynamic_cast(&d)) { 1486 | const std::vector fo = rd->fieldOrder(); 1487 | for (std::vector::const_iterator it = fo.begin(); 1488 | it != fo.end(); ++it) { 1489 | switch (*it) { 1490 | case 0: 1491 | avro::decode(d, v.name); 1492 | break; 1493 | default: 1494 | break; 1495 | } 1496 | } 1497 | } else { 1498 | avro::decode(d, v.name); 1499 | } 1500 | } 1501 | }; 1502 | 1503 | template<> struct codec_traits { 1504 | static void encode(Encoder& e, const Layer2::Ethernet2& v) { 1505 | avro::encode(e, v.srcAddr); 1506 | avro::encode(e, v.dstAddr); 1507 | avro::encode(e, v.payloadType); 1508 | avro::encode(e, v.data); 1509 | } 1510 | static void decode(Decoder& d, Layer2::Ethernet2& v) { 1511 | if (avro::ResolvingDecoder *rd = 1512 | dynamic_cast(&d)) { 1513 | const std::vector fo = rd->fieldOrder(); 1514 | for (std::vector::const_iterator it = fo.begin(); 1515 | it != fo.end(); ++it) { 1516 | switch (*it) { 1517 | case 0: 1518 | avro::decode(d, v.srcAddr); 1519 | break; 1520 | case 1: 1521 | avro::decode(d, v.dstAddr); 1522 | break; 1523 | case 2: 1524 | avro::decode(d, v.payloadType); 1525 | break; 1526 | case 3: 1527 | avro::decode(d, v.data); 1528 | break; 1529 | default: 1530 | break; 1531 | } 1532 | } 1533 | } else { 1534 | avro::decode(d, v.srcAddr); 1535 | avro::decode(d, v.dstAddr); 1536 | avro::decode(d, v.payloadType); 1537 | avro::decode(d, v.data); 1538 | } 1539 | } 1540 | }; 1541 | 1542 | template<> struct codec_traits { 1543 | static void encode(Encoder& e, const Layer2::dot11_Header& v) { 1544 | avro::encode(e, v.toDs); 1545 | avro::encode(e, v.fromDs); 1546 | avro::encode(e, v.moreFrag); 1547 | avro::encode(e, v.retry); 1548 | avro::encode(e, v.powerMgmt); 1549 | avro::encode(e, v.wep); 1550 | avro::encode(e, v.order); 1551 | avro::encode(e, v.durationId); 1552 | avro::encode(e, v.addr1); 1553 | } 1554 | static void decode(Decoder& d, Layer2::dot11_Header& v) { 1555 | if (avro::ResolvingDecoder *rd = 1556 | dynamic_cast(&d)) { 1557 | const std::vector fo = rd->fieldOrder(); 1558 | for (std::vector::const_iterator it = fo.begin(); 1559 | it != fo.end(); ++it) { 1560 | switch (*it) { 1561 | case 0: 1562 | avro::decode(d, v.toDs); 1563 | break; 1564 | case 1: 1565 | avro::decode(d, v.fromDs); 1566 | break; 1567 | case 2: 1568 | avro::decode(d, v.moreFrag); 1569 | break; 1570 | case 3: 1571 | avro::decode(d, v.retry); 1572 | break; 1573 | case 4: 1574 | avro::decode(d, v.powerMgmt); 1575 | break; 1576 | case 5: 1577 | avro::decode(d, v.wep); 1578 | break; 1579 | case 6: 1580 | avro::decode(d, v.order); 1581 | break; 1582 | case 7: 1583 | avro::decode(d, v.durationId); 1584 | break; 1585 | case 8: 1586 | avro::decode(d, v.addr1); 1587 | break; 1588 | default: 1589 | break; 1590 | } 1591 | } 1592 | } else { 1593 | avro::decode(d, v.toDs); 1594 | avro::decode(d, v.fromDs); 1595 | avro::decode(d, v.moreFrag); 1596 | avro::decode(d, v.retry); 1597 | avro::decode(d, v.powerMgmt); 1598 | avro::decode(d, v.wep); 1599 | avro::decode(d, v.order); 1600 | avro::decode(d, v.durationId); 1601 | avro::decode(d, v.addr1); 1602 | } 1603 | } 1604 | }; 1605 | 1606 | template<> struct codec_traits { 1607 | static void encode(Encoder& e, const Layer2::dot11_Unsupported& v) { 1608 | avro::encode(e, v.header); 1609 | avro::encode(e, v.type); 1610 | avro::encode(e, v.subtype); 1611 | } 1612 | static void decode(Decoder& d, Layer2::dot11_Unsupported& v) { 1613 | if (avro::ResolvingDecoder *rd = 1614 | dynamic_cast(&d)) { 1615 | const std::vector fo = rd->fieldOrder(); 1616 | for (std::vector::const_iterator it = fo.begin(); 1617 | it != fo.end(); ++it) { 1618 | switch (*it) { 1619 | case 0: 1620 | avro::decode(d, v.header); 1621 | break; 1622 | case 1: 1623 | avro::decode(d, v.type); 1624 | break; 1625 | case 2: 1626 | avro::decode(d, v.subtype); 1627 | break; 1628 | default: 1629 | break; 1630 | } 1631 | } 1632 | } else { 1633 | avro::decode(d, v.header); 1634 | avro::decode(d, v.type); 1635 | avro::decode(d, v.subtype); 1636 | } 1637 | } 1638 | }; 1639 | 1640 | template<> struct codec_traits { 1641 | static void encode(Encoder& e, const Layer2::dot11_ctrl_Ack& v) { 1642 | avro::encode(e, v.header); 1643 | } 1644 | static void decode(Decoder& d, Layer2::dot11_ctrl_Ack& v) { 1645 | if (avro::ResolvingDecoder *rd = 1646 | dynamic_cast(&d)) { 1647 | const std::vector fo = rd->fieldOrder(); 1648 | for (std::vector::const_iterator it = fo.begin(); 1649 | it != fo.end(); ++it) { 1650 | switch (*it) { 1651 | case 0: 1652 | avro::decode(d, v.header); 1653 | break; 1654 | default: 1655 | break; 1656 | } 1657 | } 1658 | } else { 1659 | avro::decode(d, v.header); 1660 | } 1661 | } 1662 | }; 1663 | 1664 | template<> struct codec_traits { 1665 | static void encode(Encoder& e, const Layer2::dot11_ctrl_BlockAck& v) { 1666 | avro::encode(e, v.header); 1667 | avro::encode(e, v.barControl); 1668 | avro::encode(e, v.startSeq); 1669 | avro::encode(e, v.fragNum); 1670 | } 1671 | static void decode(Decoder& d, Layer2::dot11_ctrl_BlockAck& v) { 1672 | if (avro::ResolvingDecoder *rd = 1673 | dynamic_cast(&d)) { 1674 | const std::vector fo = rd->fieldOrder(); 1675 | for (std::vector::const_iterator it = fo.begin(); 1676 | it != fo.end(); ++it) { 1677 | switch (*it) { 1678 | case 0: 1679 | avro::decode(d, v.header); 1680 | break; 1681 | case 1: 1682 | avro::decode(d, v.barControl); 1683 | break; 1684 | case 2: 1685 | avro::decode(d, v.startSeq); 1686 | break; 1687 | case 3: 1688 | avro::decode(d, v.fragNum); 1689 | break; 1690 | default: 1691 | break; 1692 | } 1693 | } 1694 | } else { 1695 | avro::decode(d, v.header); 1696 | avro::decode(d, v.barControl); 1697 | avro::decode(d, v.startSeq); 1698 | avro::decode(d, v.fragNum); 1699 | } 1700 | } 1701 | }; 1702 | 1703 | template<> struct codec_traits { 1704 | static void encode(Encoder& e, const Layer2::dot11_ctrl_BlockAckRequest& v) { 1705 | avro::encode(e, v.header); 1706 | avro::encode(e, v.barControl); 1707 | avro::encode(e, v.startSeq); 1708 | avro::encode(e, v.fragNum); 1709 | } 1710 | static void decode(Decoder& d, Layer2::dot11_ctrl_BlockAckRequest& v) { 1711 | if (avro::ResolvingDecoder *rd = 1712 | dynamic_cast(&d)) { 1713 | const std::vector fo = rd->fieldOrder(); 1714 | for (std::vector::const_iterator it = fo.begin(); 1715 | it != fo.end(); ++it) { 1716 | switch (*it) { 1717 | case 0: 1718 | avro::decode(d, v.header); 1719 | break; 1720 | case 1: 1721 | avro::decode(d, v.barControl); 1722 | break; 1723 | case 2: 1724 | avro::decode(d, v.startSeq); 1725 | break; 1726 | case 3: 1727 | avro::decode(d, v.fragNum); 1728 | break; 1729 | default: 1730 | break; 1731 | } 1732 | } 1733 | } else { 1734 | avro::decode(d, v.header); 1735 | avro::decode(d, v.barControl); 1736 | avro::decode(d, v.startSeq); 1737 | avro::decode(d, v.fragNum); 1738 | } 1739 | } 1740 | }; 1741 | 1742 | template<> struct codec_traits { 1743 | static void encode(Encoder& e, const Layer2::dot11_ctrl_CfEnd& v) { 1744 | avro::encode(e, v.header); 1745 | } 1746 | static void decode(Decoder& d, Layer2::dot11_ctrl_CfEnd& v) { 1747 | if (avro::ResolvingDecoder *rd = 1748 | dynamic_cast(&d)) { 1749 | const std::vector fo = rd->fieldOrder(); 1750 | for (std::vector::const_iterator it = fo.begin(); 1751 | it != fo.end(); ++it) { 1752 | switch (*it) { 1753 | case 0: 1754 | avro::decode(d, v.header); 1755 | break; 1756 | default: 1757 | break; 1758 | } 1759 | } 1760 | } else { 1761 | avro::decode(d, v.header); 1762 | } 1763 | } 1764 | }; 1765 | 1766 | template<> struct codec_traits { 1767 | static void encode(Encoder& e, const Layer2::dot11_ctrl_EndCfAck& v) { 1768 | avro::encode(e, v.header); 1769 | } 1770 | static void decode(Decoder& d, Layer2::dot11_ctrl_EndCfAck& v) { 1771 | if (avro::ResolvingDecoder *rd = 1772 | dynamic_cast(&d)) { 1773 | const std::vector fo = rd->fieldOrder(); 1774 | for (std::vector::const_iterator it = fo.begin(); 1775 | it != fo.end(); ++it) { 1776 | switch (*it) { 1777 | case 0: 1778 | avro::decode(d, v.header); 1779 | break; 1780 | default: 1781 | break; 1782 | } 1783 | } 1784 | } else { 1785 | avro::decode(d, v.header); 1786 | } 1787 | } 1788 | }; 1789 | 1790 | template<> struct codec_traits { 1791 | static void encode(Encoder& e, const Layer2::dot11_ctrl_PsPoll& v) { 1792 | avro::encode(e, v.header); 1793 | } 1794 | static void decode(Decoder& d, Layer2::dot11_ctrl_PsPoll& v) { 1795 | if (avro::ResolvingDecoder *rd = 1796 | dynamic_cast(&d)) { 1797 | const std::vector fo = rd->fieldOrder(); 1798 | for (std::vector::const_iterator it = fo.begin(); 1799 | it != fo.end(); ++it) { 1800 | switch (*it) { 1801 | case 0: 1802 | avro::decode(d, v.header); 1803 | break; 1804 | default: 1805 | break; 1806 | } 1807 | } 1808 | } else { 1809 | avro::decode(d, v.header); 1810 | } 1811 | } 1812 | }; 1813 | 1814 | template<> struct codec_traits { 1815 | static void encode(Encoder& e, const Layer2::dot11_ctrl_Rts& v) { 1816 | avro::encode(e, v.header); 1817 | } 1818 | static void decode(Decoder& d, Layer2::dot11_ctrl_Rts& v) { 1819 | if (avro::ResolvingDecoder *rd = 1820 | dynamic_cast(&d)) { 1821 | const std::vector fo = rd->fieldOrder(); 1822 | for (std::vector::const_iterator it = fo.begin(); 1823 | it != fo.end(); ++it) { 1824 | switch (*it) { 1825 | case 0: 1826 | avro::decode(d, v.header); 1827 | break; 1828 | default: 1829 | break; 1830 | } 1831 | } 1832 | } else { 1833 | avro::decode(d, v.header); 1834 | } 1835 | } 1836 | }; 1837 | 1838 | template<> struct codec_traits { 1839 | static void encode(Encoder& e, const Layer2::dot11_data_Header& v) { 1840 | avro::encode(e, v.addr2); 1841 | avro::encode(e, v.addr3); 1842 | avro::encode(e, v.addr4); 1843 | avro::encode(e, v.fragNum); 1844 | avro::encode(e, v.seqNum); 1845 | } 1846 | static void decode(Decoder& d, Layer2::dot11_data_Header& v) { 1847 | if (avro::ResolvingDecoder *rd = 1848 | dynamic_cast(&d)) { 1849 | const std::vector fo = rd->fieldOrder(); 1850 | for (std::vector::const_iterator it = fo.begin(); 1851 | it != fo.end(); ++it) { 1852 | switch (*it) { 1853 | case 0: 1854 | avro::decode(d, v.addr2); 1855 | break; 1856 | case 1: 1857 | avro::decode(d, v.addr3); 1858 | break; 1859 | case 2: 1860 | avro::decode(d, v.addr4); 1861 | break; 1862 | case 3: 1863 | avro::decode(d, v.fragNum); 1864 | break; 1865 | case 4: 1866 | avro::decode(d, v.seqNum); 1867 | break; 1868 | default: 1869 | break; 1870 | } 1871 | } 1872 | } else { 1873 | avro::decode(d, v.addr2); 1874 | avro::decode(d, v.addr3); 1875 | avro::decode(d, v.addr4); 1876 | avro::decode(d, v.fragNum); 1877 | avro::decode(d, v.seqNum); 1878 | } 1879 | } 1880 | }; 1881 | 1882 | template<> struct codec_traits { 1883 | static void encode(Encoder& e, const Layer2::dot11_data_Data& v) { 1884 | avro::encode(e, v.header); 1885 | avro::encode(e, v.dataHeader); 1886 | } 1887 | static void decode(Decoder& d, Layer2::dot11_data_Data& v) { 1888 | if (avro::ResolvingDecoder *rd = 1889 | dynamic_cast(&d)) { 1890 | const std::vector fo = rd->fieldOrder(); 1891 | for (std::vector::const_iterator it = fo.begin(); 1892 | it != fo.end(); ++it) { 1893 | switch (*it) { 1894 | case 0: 1895 | avro::decode(d, v.header); 1896 | break; 1897 | case 1: 1898 | avro::decode(d, v.dataHeader); 1899 | break; 1900 | default: 1901 | break; 1902 | } 1903 | } 1904 | } else { 1905 | avro::decode(d, v.header); 1906 | avro::decode(d, v.dataHeader); 1907 | } 1908 | } 1909 | }; 1910 | 1911 | template<> struct codec_traits { 1912 | static void encode(Encoder& e, const Layer2::dot11_data_QosData& v) { 1913 | avro::encode(e, v.header); 1914 | avro::encode(e, v.dataHeader); 1915 | avro::encode(e, v.qosControl); 1916 | } 1917 | static void decode(Decoder& d, Layer2::dot11_data_QosData& v) { 1918 | if (avro::ResolvingDecoder *rd = 1919 | dynamic_cast(&d)) { 1920 | const std::vector fo = rd->fieldOrder(); 1921 | for (std::vector::const_iterator it = fo.begin(); 1922 | it != fo.end(); ++it) { 1923 | switch (*it) { 1924 | case 0: 1925 | avro::decode(d, v.header); 1926 | break; 1927 | case 1: 1928 | avro::decode(d, v.dataHeader); 1929 | break; 1930 | case 2: 1931 | avro::decode(d, v.qosControl); 1932 | break; 1933 | default: 1934 | break; 1935 | } 1936 | } 1937 | } else { 1938 | avro::decode(d, v.header); 1939 | avro::decode(d, v.dataHeader); 1940 | avro::decode(d, v.qosControl); 1941 | } 1942 | } 1943 | }; 1944 | 1945 | template<> struct codec_traits { 1946 | static void encode(Encoder& e, Layer2::dot11_mgmt_Capability v) { 1947 | if (v < Layer2::ESS || v > Layer2::IMMEDIATE_BLOCK_ACK) 1948 | { 1949 | std::ostringstream error; 1950 | error << "enum value " << v << " is out of bound for Layer2::dot11_mgmt_Capability and cannot be encoded"; 1951 | throw avro::Exception(error.str()); 1952 | } 1953 | e.encodeEnum(v); 1954 | } 1955 | static void decode(Decoder& d, Layer2::dot11_mgmt_Capability& v) { 1956 | size_t index = d.decodeEnum(); 1957 | if (index < Layer2::ESS || index > Layer2::IMMEDIATE_BLOCK_ACK) 1958 | { 1959 | std::ostringstream error; 1960 | error << "enum value " << index << " is out of bound for Layer2::dot11_mgmt_Capability and cannot be decoded"; 1961 | throw avro::Exception(error.str()); 1962 | } 1963 | v = static_cast(index); 1964 | } 1965 | }; 1966 | 1967 | template<> struct codec_traits { 1968 | static void encode(Encoder& e, const Layer2::dot11_mgmt_Header& v) { 1969 | avro::encode(e, v.addr2); 1970 | avro::encode(e, v.addr3); 1971 | avro::encode(e, v.addr4); 1972 | avro::encode(e, v.fragNum); 1973 | avro::encode(e, v.seqNum); 1974 | } 1975 | static void decode(Decoder& d, Layer2::dot11_mgmt_Header& v) { 1976 | if (avro::ResolvingDecoder *rd = 1977 | dynamic_cast(&d)) { 1978 | const std::vector fo = rd->fieldOrder(); 1979 | for (std::vector::const_iterator it = fo.begin(); 1980 | it != fo.end(); ++it) { 1981 | switch (*it) { 1982 | case 0: 1983 | avro::decode(d, v.addr2); 1984 | break; 1985 | case 1: 1986 | avro::decode(d, v.addr3); 1987 | break; 1988 | case 2: 1989 | avro::decode(d, v.addr4); 1990 | break; 1991 | case 3: 1992 | avro::decode(d, v.fragNum); 1993 | break; 1994 | case 4: 1995 | avro::decode(d, v.seqNum); 1996 | break; 1997 | default: 1998 | break; 1999 | } 2000 | } 2001 | } else { 2002 | avro::decode(d, v.addr2); 2003 | avro::decode(d, v.addr3); 2004 | avro::decode(d, v.addr4); 2005 | avro::decode(d, v.fragNum); 2006 | avro::decode(d, v.seqNum); 2007 | } 2008 | } 2009 | }; 2010 | 2011 | template<> struct codec_traits { 2012 | static void encode(Encoder& e, const Layer2::dot11_mgmt_AssocRequest& v) { 2013 | avro::encode(e, v.header); 2014 | avro::encode(e, v.mgmtHeader); 2015 | avro::encode(e, v.capabilities); 2016 | avro::encode(e, v.listenInterval); 2017 | } 2018 | static void decode(Decoder& d, Layer2::dot11_mgmt_AssocRequest& v) { 2019 | if (avro::ResolvingDecoder *rd = 2020 | dynamic_cast(&d)) { 2021 | const std::vector fo = rd->fieldOrder(); 2022 | for (std::vector::const_iterator it = fo.begin(); 2023 | it != fo.end(); ++it) { 2024 | switch (*it) { 2025 | case 0: 2026 | avro::decode(d, v.header); 2027 | break; 2028 | case 1: 2029 | avro::decode(d, v.mgmtHeader); 2030 | break; 2031 | case 2: 2032 | avro::decode(d, v.capabilities); 2033 | break; 2034 | case 3: 2035 | avro::decode(d, v.listenInterval); 2036 | break; 2037 | default: 2038 | break; 2039 | } 2040 | } 2041 | } else { 2042 | avro::decode(d, v.header); 2043 | avro::decode(d, v.mgmtHeader); 2044 | avro::decode(d, v.capabilities); 2045 | avro::decode(d, v.listenInterval); 2046 | } 2047 | } 2048 | }; 2049 | 2050 | template<> struct codec_traits { 2051 | static void encode(Encoder& e, const Layer2::dot11_mgmt_AssocResponse& v) { 2052 | avro::encode(e, v.header); 2053 | avro::encode(e, v.mgmtHeader); 2054 | avro::encode(e, v.capabilities); 2055 | avro::encode(e, v.statusCode); 2056 | avro::encode(e, v.aid); 2057 | } 2058 | static void decode(Decoder& d, Layer2::dot11_mgmt_AssocResponse& v) { 2059 | if (avro::ResolvingDecoder *rd = 2060 | dynamic_cast(&d)) { 2061 | const std::vector fo = rd->fieldOrder(); 2062 | for (std::vector::const_iterator it = fo.begin(); 2063 | it != fo.end(); ++it) { 2064 | switch (*it) { 2065 | case 0: 2066 | avro::decode(d, v.header); 2067 | break; 2068 | case 1: 2069 | avro::decode(d, v.mgmtHeader); 2070 | break; 2071 | case 2: 2072 | avro::decode(d, v.capabilities); 2073 | break; 2074 | case 3: 2075 | avro::decode(d, v.statusCode); 2076 | break; 2077 | case 4: 2078 | avro::decode(d, v.aid); 2079 | break; 2080 | default: 2081 | break; 2082 | } 2083 | } 2084 | } else { 2085 | avro::decode(d, v.header); 2086 | avro::decode(d, v.mgmtHeader); 2087 | avro::decode(d, v.capabilities); 2088 | avro::decode(d, v.statusCode); 2089 | avro::decode(d, v.aid); 2090 | } 2091 | } 2092 | }; 2093 | 2094 | template<> struct codec_traits { 2095 | static void encode(Encoder& e, const Layer2::dot11_mgmt_Authentication& v) { 2096 | avro::encode(e, v.header); 2097 | avro::encode(e, v.mgmtHeader); 2098 | avro::encode(e, v.authAlgorithm); 2099 | avro::encode(e, v.authSeqNumber); 2100 | avro::encode(e, v.statusCode); 2101 | } 2102 | static void decode(Decoder& d, Layer2::dot11_mgmt_Authentication& v) { 2103 | if (avro::ResolvingDecoder *rd = 2104 | dynamic_cast(&d)) { 2105 | const std::vector fo = rd->fieldOrder(); 2106 | for (std::vector::const_iterator it = fo.begin(); 2107 | it != fo.end(); ++it) { 2108 | switch (*it) { 2109 | case 0: 2110 | avro::decode(d, v.header); 2111 | break; 2112 | case 1: 2113 | avro::decode(d, v.mgmtHeader); 2114 | break; 2115 | case 2: 2116 | avro::decode(d, v.authAlgorithm); 2117 | break; 2118 | case 3: 2119 | avro::decode(d, v.authSeqNumber); 2120 | break; 2121 | case 4: 2122 | avro::decode(d, v.statusCode); 2123 | break; 2124 | default: 2125 | break; 2126 | } 2127 | } 2128 | } else { 2129 | avro::decode(d, v.header); 2130 | avro::decode(d, v.mgmtHeader); 2131 | avro::decode(d, v.authAlgorithm); 2132 | avro::decode(d, v.authSeqNumber); 2133 | avro::decode(d, v.statusCode); 2134 | } 2135 | } 2136 | }; 2137 | 2138 | template<> struct codec_traits { 2139 | static void encode(Encoder& e, const Layer2::dot11_mgmt_Beacon& v) { 2140 | avro::encode(e, v.header); 2141 | avro::encode(e, v.mgmtHeader); 2142 | avro::encode(e, v.timestamp); 2143 | avro::encode(e, v.interval); 2144 | avro::encode(e, v.capabilities); 2145 | } 2146 | static void decode(Decoder& d, Layer2::dot11_mgmt_Beacon& v) { 2147 | if (avro::ResolvingDecoder *rd = 2148 | dynamic_cast(&d)) { 2149 | const std::vector fo = rd->fieldOrder(); 2150 | for (std::vector::const_iterator it = fo.begin(); 2151 | it != fo.end(); ++it) { 2152 | switch (*it) { 2153 | case 0: 2154 | avro::decode(d, v.header); 2155 | break; 2156 | case 1: 2157 | avro::decode(d, v.mgmtHeader); 2158 | break; 2159 | case 2: 2160 | avro::decode(d, v.timestamp); 2161 | break; 2162 | case 3: 2163 | avro::decode(d, v.interval); 2164 | break; 2165 | case 4: 2166 | avro::decode(d, v.capabilities); 2167 | break; 2168 | default: 2169 | break; 2170 | } 2171 | } 2172 | } else { 2173 | avro::decode(d, v.header); 2174 | avro::decode(d, v.mgmtHeader); 2175 | avro::decode(d, v.timestamp); 2176 | avro::decode(d, v.interval); 2177 | avro::decode(d, v.capabilities); 2178 | } 2179 | } 2180 | }; 2181 | 2182 | template<> struct codec_traits { 2183 | static void encode(Encoder& e, const Layer2::dot11_mgmt_Deauthentication& v) { 2184 | avro::encode(e, v.header); 2185 | avro::encode(e, v.mgmtHeader); 2186 | avro::encode(e, v.reasonCode); 2187 | } 2188 | static void decode(Decoder& d, Layer2::dot11_mgmt_Deauthentication& v) { 2189 | if (avro::ResolvingDecoder *rd = 2190 | dynamic_cast(&d)) { 2191 | const std::vector fo = rd->fieldOrder(); 2192 | for (std::vector::const_iterator it = fo.begin(); 2193 | it != fo.end(); ++it) { 2194 | switch (*it) { 2195 | case 0: 2196 | avro::decode(d, v.header); 2197 | break; 2198 | case 1: 2199 | avro::decode(d, v.mgmtHeader); 2200 | break; 2201 | case 2: 2202 | avro::decode(d, v.reasonCode); 2203 | break; 2204 | default: 2205 | break; 2206 | } 2207 | } 2208 | } else { 2209 | avro::decode(d, v.header); 2210 | avro::decode(d, v.mgmtHeader); 2211 | avro::decode(d, v.reasonCode); 2212 | } 2213 | } 2214 | }; 2215 | 2216 | template<> struct codec_traits { 2217 | static void encode(Encoder& e, const Layer2::dot11_mgmt_Disassoc& v) { 2218 | avro::encode(e, v.header); 2219 | avro::encode(e, v.mgmtHeader); 2220 | avro::encode(e, v.reasonCode); 2221 | } 2222 | static void decode(Decoder& d, Layer2::dot11_mgmt_Disassoc& v) { 2223 | if (avro::ResolvingDecoder *rd = 2224 | dynamic_cast(&d)) { 2225 | const std::vector fo = rd->fieldOrder(); 2226 | for (std::vector::const_iterator it = fo.begin(); 2227 | it != fo.end(); ++it) { 2228 | switch (*it) { 2229 | case 0: 2230 | avro::decode(d, v.header); 2231 | break; 2232 | case 1: 2233 | avro::decode(d, v.mgmtHeader); 2234 | break; 2235 | case 2: 2236 | avro::decode(d, v.reasonCode); 2237 | break; 2238 | default: 2239 | break; 2240 | } 2241 | } 2242 | } else { 2243 | avro::decode(d, v.header); 2244 | avro::decode(d, v.mgmtHeader); 2245 | avro::decode(d, v.reasonCode); 2246 | } 2247 | } 2248 | }; 2249 | 2250 | template<> struct codec_traits { 2251 | static void encode(Encoder& e, const Layer2::dot11_mgmt_ProbeRequest& v) { 2252 | avro::encode(e, v.header); 2253 | avro::encode(e, v.mgmtHeader); 2254 | } 2255 | static void decode(Decoder& d, Layer2::dot11_mgmt_ProbeRequest& v) { 2256 | if (avro::ResolvingDecoder *rd = 2257 | dynamic_cast(&d)) { 2258 | const std::vector fo = rd->fieldOrder(); 2259 | for (std::vector::const_iterator it = fo.begin(); 2260 | it != fo.end(); ++it) { 2261 | switch (*it) { 2262 | case 0: 2263 | avro::decode(d, v.header); 2264 | break; 2265 | case 1: 2266 | avro::decode(d, v.mgmtHeader); 2267 | break; 2268 | default: 2269 | break; 2270 | } 2271 | } 2272 | } else { 2273 | avro::decode(d, v.header); 2274 | avro::decode(d, v.mgmtHeader); 2275 | } 2276 | } 2277 | }; 2278 | 2279 | template<> struct codec_traits { 2280 | static void encode(Encoder& e, const Layer2::dot11_mgmt_ProbeResponse& v) { 2281 | avro::encode(e, v.header); 2282 | avro::encode(e, v.mgmtHeader); 2283 | avro::encode(e, v.timestamp); 2284 | avro::encode(e, v.interval); 2285 | avro::encode(e, v.capabilities); 2286 | } 2287 | static void decode(Decoder& d, Layer2::dot11_mgmt_ProbeResponse& v) { 2288 | if (avro::ResolvingDecoder *rd = 2289 | dynamic_cast(&d)) { 2290 | const std::vector fo = rd->fieldOrder(); 2291 | for (std::vector::const_iterator it = fo.begin(); 2292 | it != fo.end(); ++it) { 2293 | switch (*it) { 2294 | case 0: 2295 | avro::decode(d, v.header); 2296 | break; 2297 | case 1: 2298 | avro::decode(d, v.mgmtHeader); 2299 | break; 2300 | case 2: 2301 | avro::decode(d, v.timestamp); 2302 | break; 2303 | case 3: 2304 | avro::decode(d, v.interval); 2305 | break; 2306 | case 4: 2307 | avro::decode(d, v.capabilities); 2308 | break; 2309 | default: 2310 | break; 2311 | } 2312 | } 2313 | } else { 2314 | avro::decode(d, v.header); 2315 | avro::decode(d, v.mgmtHeader); 2316 | avro::decode(d, v.timestamp); 2317 | avro::decode(d, v.interval); 2318 | avro::decode(d, v.capabilities); 2319 | } 2320 | } 2321 | }; 2322 | 2323 | template<> struct codec_traits { 2324 | static void encode(Encoder& e, const Layer2::dot11_mgmt_ReassocRequest& v) { 2325 | avro::encode(e, v.header); 2326 | avro::encode(e, v.mgmtHeader); 2327 | avro::encode(e, v.capabilities); 2328 | avro::encode(e, v.listenInterval); 2329 | avro::encode(e, v.currentAp); 2330 | } 2331 | static void decode(Decoder& d, Layer2::dot11_mgmt_ReassocRequest& v) { 2332 | if (avro::ResolvingDecoder *rd = 2333 | dynamic_cast(&d)) { 2334 | const std::vector fo = rd->fieldOrder(); 2335 | for (std::vector::const_iterator it = fo.begin(); 2336 | it != fo.end(); ++it) { 2337 | switch (*it) { 2338 | case 0: 2339 | avro::decode(d, v.header); 2340 | break; 2341 | case 1: 2342 | avro::decode(d, v.mgmtHeader); 2343 | break; 2344 | case 2: 2345 | avro::decode(d, v.capabilities); 2346 | break; 2347 | case 3: 2348 | avro::decode(d, v.listenInterval); 2349 | break; 2350 | case 4: 2351 | avro::decode(d, v.currentAp); 2352 | break; 2353 | default: 2354 | break; 2355 | } 2356 | } 2357 | } else { 2358 | avro::decode(d, v.header); 2359 | avro::decode(d, v.mgmtHeader); 2360 | avro::decode(d, v.capabilities); 2361 | avro::decode(d, v.listenInterval); 2362 | avro::decode(d, v.currentAp); 2363 | } 2364 | } 2365 | }; 2366 | 2367 | template<> struct codec_traits { 2368 | static void encode(Encoder& e, const Layer2::dot11_mgmt_ReassocResponse& v) { 2369 | avro::encode(e, v.header); 2370 | avro::encode(e, v.mgmtHeader); 2371 | avro::encode(e, v.capabilities); 2372 | avro::encode(e, v.statusCode); 2373 | avro::encode(e, v.aid); 2374 | } 2375 | static void decode(Decoder& d, Layer2::dot11_mgmt_ReassocResponse& v) { 2376 | if (avro::ResolvingDecoder *rd = 2377 | dynamic_cast(&d)) { 2378 | const std::vector fo = rd->fieldOrder(); 2379 | for (std::vector::const_iterator it = fo.begin(); 2380 | it != fo.end(); ++it) { 2381 | switch (*it) { 2382 | case 0: 2383 | avro::decode(d, v.header); 2384 | break; 2385 | case 1: 2386 | avro::decode(d, v.mgmtHeader); 2387 | break; 2388 | case 2: 2389 | avro::decode(d, v.capabilities); 2390 | break; 2391 | case 3: 2392 | avro::decode(d, v.statusCode); 2393 | break; 2394 | case 4: 2395 | avro::decode(d, v.aid); 2396 | break; 2397 | default: 2398 | break; 2399 | } 2400 | } 2401 | } else { 2402 | avro::decode(d, v.header); 2403 | avro::decode(d, v.mgmtHeader); 2404 | avro::decode(d, v.capabilities); 2405 | avro::decode(d, v.statusCode); 2406 | avro::decode(d, v.aid); 2407 | } 2408 | } 2409 | }; 2410 | 2411 | template<> struct codec_traits { 2412 | static void encode(Encoder& e, Layer2::radiotap_Flag v) { 2413 | if (v < Layer2::CFP || v > Layer2::SHORT_GI) 2414 | { 2415 | std::ostringstream error; 2416 | error << "enum value " << v << " is out of bound for Layer2::radiotap_Flag and cannot be encoded"; 2417 | throw avro::Exception(error.str()); 2418 | } 2419 | e.encodeEnum(v); 2420 | } 2421 | static void decode(Decoder& d, Layer2::radiotap_Flag& v) { 2422 | size_t index = d.decodeEnum(); 2423 | if (index < Layer2::CFP || index > Layer2::SHORT_GI) 2424 | { 2425 | std::ostringstream error; 2426 | error << "enum value " << index << " is out of bound for Layer2::radiotap_Flag and cannot be decoded"; 2427 | throw avro::Exception(error.str()); 2428 | } 2429 | v = static_cast(index); 2430 | } 2431 | }; 2432 | 2433 | template<> struct codec_traits { 2434 | static void encode(Encoder& e, Layer2::radiotap_ChannelType v) { 2435 | if (v < Layer2::TURBO || v > Layer2::GFSK) 2436 | { 2437 | std::ostringstream error; 2438 | error << "enum value " << v << " is out of bound for Layer2::radiotap_ChannelType and cannot be encoded"; 2439 | throw avro::Exception(error.str()); 2440 | } 2441 | e.encodeEnum(v); 2442 | } 2443 | static void decode(Decoder& d, Layer2::radiotap_ChannelType& v) { 2444 | size_t index = d.decodeEnum(); 2445 | if (index < Layer2::TURBO || index > Layer2::GFSK) 2446 | { 2447 | std::ostringstream error; 2448 | error << "enum value " << index << " is out of bound for Layer2::radiotap_ChannelType and cannot be decoded"; 2449 | throw avro::Exception(error.str()); 2450 | } 2451 | v = static_cast(index); 2452 | } 2453 | }; 2454 | 2455 | template<> struct codec_traits { 2456 | static void encode(Encoder& e, const Layer2::radiotap_Channel& v) { 2457 | avro::encode(e, v.freq); 2458 | avro::encode(e, v.type); 2459 | } 2460 | static void decode(Decoder& d, Layer2::radiotap_Channel& v) { 2461 | if (avro::ResolvingDecoder *rd = 2462 | dynamic_cast(&d)) { 2463 | const std::vector fo = rd->fieldOrder(); 2464 | for (std::vector::const_iterator it = fo.begin(); 2465 | it != fo.end(); ++it) { 2466 | switch (*it) { 2467 | case 0: 2468 | avro::decode(d, v.freq); 2469 | break; 2470 | case 1: 2471 | avro::decode(d, v.type); 2472 | break; 2473 | default: 2474 | break; 2475 | } 2476 | } 2477 | } else { 2478 | avro::decode(d, v.freq); 2479 | avro::decode(d, v.type); 2480 | } 2481 | } 2482 | }; 2483 | 2484 | template<> struct codec_traits { 2485 | static void encode(Encoder& e, Layer2::_63_Union__0__ v) { 2486 | e.encodeUnionIndex(v.idx()); 2487 | switch (v.idx()) { 2488 | case 0: 2489 | e.encodeNull(); 2490 | break; 2491 | case 1: 2492 | avro::encode(e, v.get_long()); 2493 | break; 2494 | } 2495 | } 2496 | static void decode(Decoder& d, Layer2::_63_Union__0__& v) { 2497 | size_t n = d.decodeUnionIndex(); 2498 | if (n >= 2) { throw avro::Exception("Union index too big"); } 2499 | switch (n) { 2500 | case 0: 2501 | d.decodeNull(); 2502 | v.set_null(); 2503 | break; 2504 | case 1: 2505 | { 2506 | int64_t vv; 2507 | avro::decode(d, vv); 2508 | v.set_long(vv); 2509 | } 2510 | break; 2511 | } 2512 | } 2513 | }; 2514 | 2515 | template<> struct codec_traits { 2516 | static void encode(Encoder& e, Layer2::_63_Union__1__ v) { 2517 | e.encodeUnionIndex(v.idx()); 2518 | switch (v.idx()) { 2519 | case 0: 2520 | e.encodeNull(); 2521 | break; 2522 | case 1: 2523 | avro::encode(e, v.get_array()); 2524 | break; 2525 | } 2526 | } 2527 | static void decode(Decoder& d, Layer2::_63_Union__1__& v) { 2528 | size_t n = d.decodeUnionIndex(); 2529 | if (n >= 2) { throw avro::Exception("Union index too big"); } 2530 | switch (n) { 2531 | case 0: 2532 | d.decodeNull(); 2533 | v.set_null(); 2534 | break; 2535 | case 1: 2536 | { 2537 | std::vector vv; 2538 | avro::decode(d, vv); 2539 | v.set_array(vv); 2540 | } 2541 | break; 2542 | } 2543 | } 2544 | }; 2545 | 2546 | template<> struct codec_traits { 2547 | static void encode(Encoder& e, Layer2::_63_Union__2__ v) { 2548 | e.encodeUnionIndex(v.idx()); 2549 | switch (v.idx()) { 2550 | case 0: 2551 | e.encodeNull(); 2552 | break; 2553 | case 1: 2554 | avro::encode(e, v.get_int()); 2555 | break; 2556 | } 2557 | } 2558 | static void decode(Decoder& d, Layer2::_63_Union__2__& v) { 2559 | size_t n = d.decodeUnionIndex(); 2560 | if (n >= 2) { throw avro::Exception("Union index too big"); } 2561 | switch (n) { 2562 | case 0: 2563 | d.decodeNull(); 2564 | v.set_null(); 2565 | break; 2566 | case 1: 2567 | { 2568 | int32_t vv; 2569 | avro::decode(d, vv); 2570 | v.set_int(vv); 2571 | } 2572 | break; 2573 | } 2574 | } 2575 | }; 2576 | 2577 | template<> struct codec_traits { 2578 | static void encode(Encoder& e, Layer2::_63_Union__3__ v) { 2579 | e.encodeUnionIndex(v.idx()); 2580 | switch (v.idx()) { 2581 | case 0: 2582 | e.encodeNull(); 2583 | break; 2584 | case 1: 2585 | avro::encode(e, v.get_radiotap_Channel()); 2586 | break; 2587 | } 2588 | } 2589 | static void decode(Decoder& d, Layer2::_63_Union__3__& v) { 2590 | size_t n = d.decodeUnionIndex(); 2591 | if (n >= 2) { throw avro::Exception("Union index too big"); } 2592 | switch (n) { 2593 | case 0: 2594 | d.decodeNull(); 2595 | v.set_null(); 2596 | break; 2597 | case 1: 2598 | { 2599 | Layer2::radiotap_Channel vv; 2600 | avro::decode(d, vv); 2601 | v.set_radiotap_Channel(vv); 2602 | } 2603 | break; 2604 | } 2605 | } 2606 | }; 2607 | 2608 | template<> struct codec_traits { 2609 | static void encode(Encoder& e, Layer2::_63_Union__4__ v) { 2610 | e.encodeUnionIndex(v.idx()); 2611 | switch (v.idx()) { 2612 | case 0: 2613 | e.encodeNull(); 2614 | break; 2615 | case 1: 2616 | avro::encode(e, v.get_Unsupported()); 2617 | break; 2618 | case 2: 2619 | avro::encode(e, v.get_dot11_Unsupported()); 2620 | break; 2621 | case 3: 2622 | avro::encode(e, v.get_dot11_ctrl_Ack()); 2623 | break; 2624 | case 4: 2625 | avro::encode(e, v.get_dot11_ctrl_BlockAck()); 2626 | break; 2627 | case 5: 2628 | avro::encode(e, v.get_dot11_ctrl_BlockAckRequest()); 2629 | break; 2630 | case 6: 2631 | avro::encode(e, v.get_dot11_ctrl_CfEnd()); 2632 | break; 2633 | case 7: 2634 | avro::encode(e, v.get_dot11_ctrl_EndCfAck()); 2635 | break; 2636 | case 8: 2637 | avro::encode(e, v.get_dot11_ctrl_PsPoll()); 2638 | break; 2639 | case 9: 2640 | avro::encode(e, v.get_dot11_ctrl_Rts()); 2641 | break; 2642 | case 10: 2643 | avro::encode(e, v.get_dot11_data_Data()); 2644 | break; 2645 | case 11: 2646 | avro::encode(e, v.get_dot11_data_QosData()); 2647 | break; 2648 | case 12: 2649 | avro::encode(e, v.get_dot11_mgmt_AssocRequest()); 2650 | break; 2651 | case 13: 2652 | avro::encode(e, v.get_dot11_mgmt_AssocResponse()); 2653 | break; 2654 | case 14: 2655 | avro::encode(e, v.get_dot11_mgmt_Authentication()); 2656 | break; 2657 | case 15: 2658 | avro::encode(e, v.get_dot11_mgmt_Beacon()); 2659 | break; 2660 | case 16: 2661 | avro::encode(e, v.get_dot11_mgmt_Deauthentication()); 2662 | break; 2663 | case 17: 2664 | avro::encode(e, v.get_dot11_mgmt_Disassoc()); 2665 | break; 2666 | case 18: 2667 | avro::encode(e, v.get_dot11_mgmt_ProbeRequest()); 2668 | break; 2669 | case 19: 2670 | avro::encode(e, v.get_dot11_mgmt_ProbeResponse()); 2671 | break; 2672 | case 20: 2673 | avro::encode(e, v.get_dot11_mgmt_ReassocRequest()); 2674 | break; 2675 | case 21: 2676 | avro::encode(e, v.get_dot11_mgmt_ReassocResponse()); 2677 | break; 2678 | } 2679 | } 2680 | static void decode(Decoder& d, Layer2::_63_Union__4__& v) { 2681 | size_t n = d.decodeUnionIndex(); 2682 | if (n >= 22) { throw avro::Exception("Union index too big"); } 2683 | switch (n) { 2684 | case 0: 2685 | d.decodeNull(); 2686 | v.set_null(); 2687 | break; 2688 | case 1: 2689 | { 2690 | Layer2::Unsupported vv; 2691 | avro::decode(d, vv); 2692 | v.set_Unsupported(vv); 2693 | } 2694 | break; 2695 | case 2: 2696 | { 2697 | Layer2::dot11_Unsupported vv; 2698 | avro::decode(d, vv); 2699 | v.set_dot11_Unsupported(vv); 2700 | } 2701 | break; 2702 | case 3: 2703 | { 2704 | Layer2::dot11_ctrl_Ack vv; 2705 | avro::decode(d, vv); 2706 | v.set_dot11_ctrl_Ack(vv); 2707 | } 2708 | break; 2709 | case 4: 2710 | { 2711 | Layer2::dot11_ctrl_BlockAck vv; 2712 | avro::decode(d, vv); 2713 | v.set_dot11_ctrl_BlockAck(vv); 2714 | } 2715 | break; 2716 | case 5: 2717 | { 2718 | Layer2::dot11_ctrl_BlockAckRequest vv; 2719 | avro::decode(d, vv); 2720 | v.set_dot11_ctrl_BlockAckRequest(vv); 2721 | } 2722 | break; 2723 | case 6: 2724 | { 2725 | Layer2::dot11_ctrl_CfEnd vv; 2726 | avro::decode(d, vv); 2727 | v.set_dot11_ctrl_CfEnd(vv); 2728 | } 2729 | break; 2730 | case 7: 2731 | { 2732 | Layer2::dot11_ctrl_EndCfAck vv; 2733 | avro::decode(d, vv); 2734 | v.set_dot11_ctrl_EndCfAck(vv); 2735 | } 2736 | break; 2737 | case 8: 2738 | { 2739 | Layer2::dot11_ctrl_PsPoll vv; 2740 | avro::decode(d, vv); 2741 | v.set_dot11_ctrl_PsPoll(vv); 2742 | } 2743 | break; 2744 | case 9: 2745 | { 2746 | Layer2::dot11_ctrl_Rts vv; 2747 | avro::decode(d, vv); 2748 | v.set_dot11_ctrl_Rts(vv); 2749 | } 2750 | break; 2751 | case 10: 2752 | { 2753 | Layer2::dot11_data_Data vv; 2754 | avro::decode(d, vv); 2755 | v.set_dot11_data_Data(vv); 2756 | } 2757 | break; 2758 | case 11: 2759 | { 2760 | Layer2::dot11_data_QosData vv; 2761 | avro::decode(d, vv); 2762 | v.set_dot11_data_QosData(vv); 2763 | } 2764 | break; 2765 | case 12: 2766 | { 2767 | Layer2::dot11_mgmt_AssocRequest vv; 2768 | avro::decode(d, vv); 2769 | v.set_dot11_mgmt_AssocRequest(vv); 2770 | } 2771 | break; 2772 | case 13: 2773 | { 2774 | Layer2::dot11_mgmt_AssocResponse vv; 2775 | avro::decode(d, vv); 2776 | v.set_dot11_mgmt_AssocResponse(vv); 2777 | } 2778 | break; 2779 | case 14: 2780 | { 2781 | Layer2::dot11_mgmt_Authentication vv; 2782 | avro::decode(d, vv); 2783 | v.set_dot11_mgmt_Authentication(vv); 2784 | } 2785 | break; 2786 | case 15: 2787 | { 2788 | Layer2::dot11_mgmt_Beacon vv; 2789 | avro::decode(d, vv); 2790 | v.set_dot11_mgmt_Beacon(vv); 2791 | } 2792 | break; 2793 | case 16: 2794 | { 2795 | Layer2::dot11_mgmt_Deauthentication vv; 2796 | avro::decode(d, vv); 2797 | v.set_dot11_mgmt_Deauthentication(vv); 2798 | } 2799 | break; 2800 | case 17: 2801 | { 2802 | Layer2::dot11_mgmt_Disassoc vv; 2803 | avro::decode(d, vv); 2804 | v.set_dot11_mgmt_Disassoc(vv); 2805 | } 2806 | break; 2807 | case 18: 2808 | { 2809 | Layer2::dot11_mgmt_ProbeRequest vv; 2810 | avro::decode(d, vv); 2811 | v.set_dot11_mgmt_ProbeRequest(vv); 2812 | } 2813 | break; 2814 | case 19: 2815 | { 2816 | Layer2::dot11_mgmt_ProbeResponse vv; 2817 | avro::decode(d, vv); 2818 | v.set_dot11_mgmt_ProbeResponse(vv); 2819 | } 2820 | break; 2821 | case 20: 2822 | { 2823 | Layer2::dot11_mgmt_ReassocRequest vv; 2824 | avro::decode(d, vv); 2825 | v.set_dot11_mgmt_ReassocRequest(vv); 2826 | } 2827 | break; 2828 | case 21: 2829 | { 2830 | Layer2::dot11_mgmt_ReassocResponse vv; 2831 | avro::decode(d, vv); 2832 | v.set_dot11_mgmt_ReassocResponse(vv); 2833 | } 2834 | break; 2835 | } 2836 | } 2837 | }; 2838 | 2839 | template<> struct codec_traits { 2840 | static void encode(Encoder& e, const Layer2::Radiotap& v) { 2841 | avro::encode(e, v.tsft); 2842 | avro::encode(e, v.flags); 2843 | avro::encode(e, v.rate); 2844 | avro::encode(e, v.channel); 2845 | avro::encode(e, v.frame); 2846 | } 2847 | static void decode(Decoder& d, Layer2::Radiotap& v) { 2848 | if (avro::ResolvingDecoder *rd = 2849 | dynamic_cast(&d)) { 2850 | const std::vector fo = rd->fieldOrder(); 2851 | for (std::vector::const_iterator it = fo.begin(); 2852 | it != fo.end(); ++it) { 2853 | switch (*it) { 2854 | case 0: 2855 | avro::decode(d, v.tsft); 2856 | break; 2857 | case 1: 2858 | avro::decode(d, v.flags); 2859 | break; 2860 | case 2: 2861 | avro::decode(d, v.rate); 2862 | break; 2863 | case 3: 2864 | avro::decode(d, v.channel); 2865 | break; 2866 | case 4: 2867 | avro::decode(d, v.frame); 2868 | break; 2869 | default: 2870 | break; 2871 | } 2872 | } 2873 | } else { 2874 | avro::decode(d, v.tsft); 2875 | avro::decode(d, v.flags); 2876 | avro::decode(d, v.rate); 2877 | avro::decode(d, v.channel); 2878 | avro::decode(d, v.frame); 2879 | } 2880 | } 2881 | }; 2882 | 2883 | template<> struct codec_traits { 2884 | static void encode(Encoder& e, Layer2::_63_Union__5__ v) { 2885 | e.encodeUnionIndex(v.idx()); 2886 | switch (v.idx()) { 2887 | case 0: 2888 | avro::encode(e, v.get_Unsupported()); 2889 | break; 2890 | case 1: 2891 | avro::encode(e, v.get_Ethernet2()); 2892 | break; 2893 | case 2: 2894 | avro::encode(e, v.get_Radiotap()); 2895 | break; 2896 | } 2897 | } 2898 | static void decode(Decoder& d, Layer2::_63_Union__5__& v) { 2899 | size_t n = d.decodeUnionIndex(); 2900 | if (n >= 3) { throw avro::Exception("Union index too big"); } 2901 | switch (n) { 2902 | case 0: 2903 | { 2904 | Layer2::Unsupported vv; 2905 | avro::decode(d, vv); 2906 | v.set_Unsupported(vv); 2907 | } 2908 | break; 2909 | case 1: 2910 | { 2911 | Layer2::Ethernet2 vv; 2912 | avro::decode(d, vv); 2913 | v.set_Ethernet2(vv); 2914 | } 2915 | break; 2916 | case 2: 2917 | { 2918 | Layer2::Radiotap vv; 2919 | avro::decode(d, vv); 2920 | v.set_Radiotap(vv); 2921 | } 2922 | break; 2923 | } 2924 | } 2925 | }; 2926 | 2927 | template<> struct codec_traits { 2928 | static void encode(Encoder& e, const Layer2::Pdu& v) { 2929 | avro::encode(e, v.size); 2930 | avro::encode(e, v.timestamp); 2931 | avro::encode(e, v.frame); 2932 | } 2933 | static void decode(Decoder& d, Layer2::Pdu& v) { 2934 | if (avro::ResolvingDecoder *rd = 2935 | dynamic_cast(&d)) { 2936 | const std::vector fo = rd->fieldOrder(); 2937 | for (std::vector::const_iterator it = fo.begin(); 2938 | it != fo.end(); ++it) { 2939 | switch (*it) { 2940 | case 0: 2941 | avro::decode(d, v.size); 2942 | break; 2943 | case 1: 2944 | avro::decode(d, v.timestamp); 2945 | break; 2946 | case 2: 2947 | avro::decode(d, v.frame); 2948 | break; 2949 | default: 2950 | break; 2951 | } 2952 | } 2953 | } else { 2954 | avro::decode(d, v.size); 2955 | avro::decode(d, v.timestamp); 2956 | avro::decode(d, v.frame); 2957 | } 2958 | } 2959 | }; 2960 | 2961 | template<> struct codec_traits { 2962 | static void encode(Encoder& e, Layer2::_63_Union__6__ v) { 2963 | e.encodeUnionIndex(v.idx()); 2964 | switch (v.idx()) { 2965 | case 0: 2966 | avro::encode(e, v.get_Unsupported()); 2967 | break; 2968 | case 1: 2969 | avro::encode(e, v.get_MacAddr()); 2970 | break; 2971 | case 2: 2972 | avro::encode(e, v.get_Ethernet2()); 2973 | break; 2974 | case 3: 2975 | avro::encode(e, v.get_dot11_Header()); 2976 | break; 2977 | case 4: 2978 | avro::encode(e, v.get_dot11_Unsupported()); 2979 | break; 2980 | case 5: 2981 | avro::encode(e, v.get_dot11_ctrl_Ack()); 2982 | break; 2983 | case 6: 2984 | avro::encode(e, v.get_dot11_ctrl_BlockAck()); 2985 | break; 2986 | case 7: 2987 | avro::encode(e, v.get_dot11_ctrl_BlockAckRequest()); 2988 | break; 2989 | case 8: 2990 | avro::encode(e, v.get_dot11_ctrl_CfEnd()); 2991 | break; 2992 | case 9: 2993 | avro::encode(e, v.get_dot11_ctrl_EndCfAck()); 2994 | break; 2995 | case 10: 2996 | avro::encode(e, v.get_dot11_ctrl_PsPoll()); 2997 | break; 2998 | case 11: 2999 | avro::encode(e, v.get_dot11_ctrl_Rts()); 3000 | break; 3001 | case 12: 3002 | avro::encode(e, v.get_dot11_data_Header()); 3003 | break; 3004 | case 13: 3005 | avro::encode(e, v.get_dot11_data_Data()); 3006 | break; 3007 | case 14: 3008 | avro::encode(e, v.get_dot11_data_QosData()); 3009 | break; 3010 | case 15: 3011 | avro::encode(e, v.get_dot11_mgmt_Capability()); 3012 | break; 3013 | case 16: 3014 | avro::encode(e, v.get_dot11_mgmt_Header()); 3015 | break; 3016 | case 17: 3017 | avro::encode(e, v.get_dot11_mgmt_AssocRequest()); 3018 | break; 3019 | case 18: 3020 | avro::encode(e, v.get_dot11_mgmt_AssocResponse()); 3021 | break; 3022 | case 19: 3023 | avro::encode(e, v.get_dot11_mgmt_Authentication()); 3024 | break; 3025 | case 20: 3026 | avro::encode(e, v.get_dot11_mgmt_Beacon()); 3027 | break; 3028 | case 21: 3029 | avro::encode(e, v.get_dot11_mgmt_Deauthentication()); 3030 | break; 3031 | case 22: 3032 | avro::encode(e, v.get_dot11_mgmt_Disassoc()); 3033 | break; 3034 | case 23: 3035 | avro::encode(e, v.get_dot11_mgmt_ProbeRequest()); 3036 | break; 3037 | case 24: 3038 | avro::encode(e, v.get_dot11_mgmt_ProbeResponse()); 3039 | break; 3040 | case 25: 3041 | avro::encode(e, v.get_dot11_mgmt_ReassocRequest()); 3042 | break; 3043 | case 26: 3044 | avro::encode(e, v.get_dot11_mgmt_ReassocResponse()); 3045 | break; 3046 | case 27: 3047 | avro::encode(e, v.get_radiotap_Flag()); 3048 | break; 3049 | case 28: 3050 | avro::encode(e, v.get_radiotap_ChannelType()); 3051 | break; 3052 | case 29: 3053 | avro::encode(e, v.get_radiotap_Channel()); 3054 | break; 3055 | case 30: 3056 | avro::encode(e, v.get_Radiotap()); 3057 | break; 3058 | case 31: 3059 | avro::encode(e, v.get_Pdu()); 3060 | break; 3061 | } 3062 | } 3063 | static void decode(Decoder& d, Layer2::_63_Union__6__& v) { 3064 | size_t n = d.decodeUnionIndex(); 3065 | if (n >= 32) { throw avro::Exception("Union index too big"); } 3066 | switch (n) { 3067 | case 0: 3068 | { 3069 | Layer2::Unsupported vv; 3070 | avro::decode(d, vv); 3071 | v.set_Unsupported(vv); 3072 | } 3073 | break; 3074 | case 1: 3075 | { 3076 | boost::array vv; 3077 | avro::decode(d, vv); 3078 | v.set_MacAddr(vv); 3079 | } 3080 | break; 3081 | case 2: 3082 | { 3083 | Layer2::Ethernet2 vv; 3084 | avro::decode(d, vv); 3085 | v.set_Ethernet2(vv); 3086 | } 3087 | break; 3088 | case 3: 3089 | { 3090 | Layer2::dot11_Header vv; 3091 | avro::decode(d, vv); 3092 | v.set_dot11_Header(vv); 3093 | } 3094 | break; 3095 | case 4: 3096 | { 3097 | Layer2::dot11_Unsupported vv; 3098 | avro::decode(d, vv); 3099 | v.set_dot11_Unsupported(vv); 3100 | } 3101 | break; 3102 | case 5: 3103 | { 3104 | Layer2::dot11_ctrl_Ack vv; 3105 | avro::decode(d, vv); 3106 | v.set_dot11_ctrl_Ack(vv); 3107 | } 3108 | break; 3109 | case 6: 3110 | { 3111 | Layer2::dot11_ctrl_BlockAck vv; 3112 | avro::decode(d, vv); 3113 | v.set_dot11_ctrl_BlockAck(vv); 3114 | } 3115 | break; 3116 | case 7: 3117 | { 3118 | Layer2::dot11_ctrl_BlockAckRequest vv; 3119 | avro::decode(d, vv); 3120 | v.set_dot11_ctrl_BlockAckRequest(vv); 3121 | } 3122 | break; 3123 | case 8: 3124 | { 3125 | Layer2::dot11_ctrl_CfEnd vv; 3126 | avro::decode(d, vv); 3127 | v.set_dot11_ctrl_CfEnd(vv); 3128 | } 3129 | break; 3130 | case 9: 3131 | { 3132 | Layer2::dot11_ctrl_EndCfAck vv; 3133 | avro::decode(d, vv); 3134 | v.set_dot11_ctrl_EndCfAck(vv); 3135 | } 3136 | break; 3137 | case 10: 3138 | { 3139 | Layer2::dot11_ctrl_PsPoll vv; 3140 | avro::decode(d, vv); 3141 | v.set_dot11_ctrl_PsPoll(vv); 3142 | } 3143 | break; 3144 | case 11: 3145 | { 3146 | Layer2::dot11_ctrl_Rts vv; 3147 | avro::decode(d, vv); 3148 | v.set_dot11_ctrl_Rts(vv); 3149 | } 3150 | break; 3151 | case 12: 3152 | { 3153 | Layer2::dot11_data_Header vv; 3154 | avro::decode(d, vv); 3155 | v.set_dot11_data_Header(vv); 3156 | } 3157 | break; 3158 | case 13: 3159 | { 3160 | Layer2::dot11_data_Data vv; 3161 | avro::decode(d, vv); 3162 | v.set_dot11_data_Data(vv); 3163 | } 3164 | break; 3165 | case 14: 3166 | { 3167 | Layer2::dot11_data_QosData vv; 3168 | avro::decode(d, vv); 3169 | v.set_dot11_data_QosData(vv); 3170 | } 3171 | break; 3172 | case 15: 3173 | { 3174 | Layer2::dot11_mgmt_Capability vv; 3175 | avro::decode(d, vv); 3176 | v.set_dot11_mgmt_Capability(vv); 3177 | } 3178 | break; 3179 | case 16: 3180 | { 3181 | Layer2::dot11_mgmt_Header vv; 3182 | avro::decode(d, vv); 3183 | v.set_dot11_mgmt_Header(vv); 3184 | } 3185 | break; 3186 | case 17: 3187 | { 3188 | Layer2::dot11_mgmt_AssocRequest vv; 3189 | avro::decode(d, vv); 3190 | v.set_dot11_mgmt_AssocRequest(vv); 3191 | } 3192 | break; 3193 | case 18: 3194 | { 3195 | Layer2::dot11_mgmt_AssocResponse vv; 3196 | avro::decode(d, vv); 3197 | v.set_dot11_mgmt_AssocResponse(vv); 3198 | } 3199 | break; 3200 | case 19: 3201 | { 3202 | Layer2::dot11_mgmt_Authentication vv; 3203 | avro::decode(d, vv); 3204 | v.set_dot11_mgmt_Authentication(vv); 3205 | } 3206 | break; 3207 | case 20: 3208 | { 3209 | Layer2::dot11_mgmt_Beacon vv; 3210 | avro::decode(d, vv); 3211 | v.set_dot11_mgmt_Beacon(vv); 3212 | } 3213 | break; 3214 | case 21: 3215 | { 3216 | Layer2::dot11_mgmt_Deauthentication vv; 3217 | avro::decode(d, vv); 3218 | v.set_dot11_mgmt_Deauthentication(vv); 3219 | } 3220 | break; 3221 | case 22: 3222 | { 3223 | Layer2::dot11_mgmt_Disassoc vv; 3224 | avro::decode(d, vv); 3225 | v.set_dot11_mgmt_Disassoc(vv); 3226 | } 3227 | break; 3228 | case 23: 3229 | { 3230 | Layer2::dot11_mgmt_ProbeRequest vv; 3231 | avro::decode(d, vv); 3232 | v.set_dot11_mgmt_ProbeRequest(vv); 3233 | } 3234 | break; 3235 | case 24: 3236 | { 3237 | Layer2::dot11_mgmt_ProbeResponse vv; 3238 | avro::decode(d, vv); 3239 | v.set_dot11_mgmt_ProbeResponse(vv); 3240 | } 3241 | break; 3242 | case 25: 3243 | { 3244 | Layer2::dot11_mgmt_ReassocRequest vv; 3245 | avro::decode(d, vv); 3246 | v.set_dot11_mgmt_ReassocRequest(vv); 3247 | } 3248 | break; 3249 | case 26: 3250 | { 3251 | Layer2::dot11_mgmt_ReassocResponse vv; 3252 | avro::decode(d, vv); 3253 | v.set_dot11_mgmt_ReassocResponse(vv); 3254 | } 3255 | break; 3256 | case 27: 3257 | { 3258 | Layer2::radiotap_Flag vv; 3259 | avro::decode(d, vv); 3260 | v.set_radiotap_Flag(vv); 3261 | } 3262 | break; 3263 | case 28: 3264 | { 3265 | Layer2::radiotap_ChannelType vv; 3266 | avro::decode(d, vv); 3267 | v.set_radiotap_ChannelType(vv); 3268 | } 3269 | break; 3270 | case 29: 3271 | { 3272 | Layer2::radiotap_Channel vv; 3273 | avro::decode(d, vv); 3274 | v.set_radiotap_Channel(vv); 3275 | } 3276 | break; 3277 | case 30: 3278 | { 3279 | Layer2::Radiotap vv; 3280 | avro::decode(d, vv); 3281 | v.set_Radiotap(vv); 3282 | } 3283 | break; 3284 | case 31: 3285 | { 3286 | Layer2::Pdu vv; 3287 | avro::decode(d, vv); 3288 | v.set_Pdu(vv); 3289 | } 3290 | break; 3291 | } 3292 | } 3293 | }; 3294 | 3295 | } 3296 | #endif 3297 | -------------------------------------------------------------------------------- /src/utils.cpp: -------------------------------------------------------------------------------- 1 | #include "utils.hpp" 2 | 3 | namespace Layer2 { 4 | 5 | NAN_METHOD(stringifyAddress) { 6 | 7 | static const char hex[] = "0123456789abcdef"; 8 | 9 | if ( 10 | info.Length() != 1 || 11 | !node::Buffer::HasInstance(info[0]) 12 | ) { 13 | Nan::ThrowError("invalid arguments"); 14 | return; 15 | } 16 | 17 | v8::Local buf = info[0]->ToObject(); 18 | uint32_t i = node::Buffer::Length(buf); 19 | if (i == 0) { 20 | Nan::ThrowError("empty buffer"); 21 | return; 22 | } 23 | 24 | uint8_t *data = (uint8_t *) node::Buffer::Data(buf); 25 | uint8_t addr[3 * i]; 26 | uint8_t *cp = addr; 27 | 28 | *cp++ = hex[*data >> 4]; 29 | *cp++ = hex[*data++ & 0x0f]; 30 | while (--i) { 31 | *cp++ = ':'; 32 | *cp++ = hex[*data >> 4]; 33 | *cp++ = hex[*data++ & 0x0f]; 34 | } 35 | *cp = '\0'; 36 | 37 | info.GetReturnValue().Set(Nan::New((char *) addr).ToLocalChecked()); 38 | } 39 | 40 | } // Layer 2 41 | -------------------------------------------------------------------------------- /src/utils.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace Layer2 { 6 | 7 | NAN_METHOD(stringifyAddress); 8 | 9 | } 10 | -------------------------------------------------------------------------------- /src/wrapper.cpp: -------------------------------------------------------------------------------- 1 | #include "codecs.hpp" 2 | #include "wrapper.hpp" 3 | #include 4 | 5 | namespace Layer2 { 6 | 7 | #define LAYER2_BUFFER_SIZE 1024 8 | 9 | // Black hole array used to write any overflowing data. We must use this since 10 | // Avro's encoder will throw an error when it tries to write and the underlying 11 | // stream is full. Since this might happen at every loop, it is cheaper to fake 12 | // a successful write rather than catch (which might also have side-effects). 13 | static uint8_t BUFFER[LAYER2_BUFFER_SIZE] = {0}; 14 | 15 | /** 16 | * Helper class to handle encoding Avro records to a JavaScript buffer. 17 | * 18 | */ 19 | class BufferOutputStream : public avro::OutputStream { 20 | public: 21 | enum State { ALMOST_EMPTY, ALMOST_FULL, FULL }; 22 | 23 | static BufferOutputStream *fromBuffer( 24 | v8::Local buf, 25 | float loadFactor 26 | ) { 27 | if (!node::Buffer::HasInstance(buf)) { 28 | return NULL; 29 | } 30 | 31 | v8::Local obj = buf->ToObject(); 32 | uint8_t *data = (uint8_t *) node::Buffer::Data(obj); 33 | size_t len = node::Buffer::Length(obj); 34 | return new BufferOutputStream(data, len, loadFactor); 35 | } 36 | 37 | BufferOutputStream(uint8_t *data, size_t len, float loadFactor) : 38 | _data(data), 39 | _len(len), 40 | _hwm(len *loadFactor), 41 | _pos(0) {}; 42 | 43 | ~BufferOutputStream() {}; 44 | 45 | virtual bool next(uint8_t **data, size_t *len) { 46 | if (_pos < _hwm) { 47 | *data = _data + _pos; 48 | *len = _hwm - _pos; 49 | _pos = _hwm; 50 | } else if (_pos < _len) { 51 | *data = _data + _pos; 52 | *len = _len - _pos; 53 | _pos = _len; 54 | } else { 55 | *data = BUFFER; 56 | *len = LAYER2_BUFFER_SIZE; 57 | _pos = _len + 1; 58 | } 59 | return true; 60 | } 61 | 62 | virtual void backup(size_t len) { _pos -= len; } 63 | 64 | virtual void flush() {} 65 | 66 | virtual uint64_t byteCount() const { return _pos; } 67 | 68 | State getState() const { 69 | if (_pos < _len) { 70 | return State::ALMOST_EMPTY; 71 | } 72 | if (_pos == _len) { 73 | return State::ALMOST_FULL; 74 | } 75 | return State::FULL; 76 | } 77 | 78 | private: 79 | uint8_t *_data; 80 | size_t _len; 81 | size_t _hwm; // High watermark. 82 | size_t _pos; 83 | }; 84 | 85 | /** 86 | * Helper class to handle asynchronous PDU capture. 87 | * 88 | */ 89 | class Worker : public Nan::AsyncWorker { 90 | public: 91 | Worker(Wrapper *wrapper, v8::Local buf, Nan::Callback *callback) : 92 | AsyncWorker(callback), 93 | _wrapper(wrapper), 94 | _stream(BufferOutputStream::fromBuffer(buf, 0.9)), 95 | _numPdus(0) { 96 | _wrapper->_encoder->init(*_stream); 97 | } 98 | 99 | ~Worker() {} 100 | 101 | void Execute() { 102 | std::chrono::time_point start, current; 103 | start = std::chrono::high_resolution_clock::now(); 104 | 105 | // First, check whether we have a backlogged PDU. 106 | if (_wrapper->_packet.pdu()) { 107 | avro::encode(*_wrapper->_encoder, _wrapper->_packet); 108 | delete _wrapper->_packet.release_pdu(); 109 | switch (_stream->getState()) { 110 | case BufferOutputStream::State::FULL: 111 | SetErrorMessage("buffer too small"); 112 | case BufferOutputStream::State::ALMOST_FULL: 113 | return; 114 | default: 115 | ; // Else we have room for more. 116 | } 117 | } 118 | 119 | while (true) { 120 | Tins::Packet packet(_wrapper->_sniffer->next_packet()); 121 | if (!packet) { 122 | return; 123 | } 124 | _numPdus++; 125 | avro::encode(*_wrapper->_encoder, packet); 126 | switch (_stream->getState()) { 127 | case BufferOutputStream::State::FULL: 128 | // There wasn't enough room, we have to save the PDU until the next 129 | // call (otherwise it will never be transmitted). 130 | _wrapper->_packet = packet; 131 | --_numPdus; 132 | case BufferOutputStream::State::ALMOST_FULL: 133 | return; 134 | default: 135 | // Otherwise, continue looping if the timeout hasn't been reached. 136 | current = std::chrono::high_resolution_clock::now(); 137 | if ( 138 | _wrapper->_timeout && 139 | std::chrono::duration_cast(current - start).count() > _wrapper->_timeout 140 | ) { 141 | return; 142 | } 143 | } 144 | } 145 | } 146 | 147 | void HandleOKCallback() { 148 | Nan::HandleScope scope; 149 | // We have to call this to prevent the encoder from resetting the stream 150 | // after it has been deleted. 151 | _wrapper->_encoder->init(*_stream); 152 | v8::Local argv[] = { 153 | Nan::Null(), 154 | Nan::New(_numPdus) 155 | }; 156 | callback->Call(2, argv); 157 | } 158 | 159 | void HandleErrorCallback() { 160 | Nan::HandleScope scope; 161 | _wrapper->_encoder->init(*_stream); 162 | v8::Local argv[] = { 163 | v8::Exception::Error(Nan::New(ErrorMessage()).ToLocalChecked()) 164 | }; 165 | callback->Call(1, argv); 166 | } 167 | 168 | private: 169 | Wrapper *_wrapper; 170 | std::unique_ptr _stream; 171 | uint32_t _numPdus; 172 | }; 173 | 174 | // v8 exposed functions. 175 | 176 | /** 177 | * JavaScript constructor. 178 | * 179 | * It should always be followed by exactly one call, either to `FromInterface` 180 | * or to `FromFile`. Behavior otherwise is undefined. 181 | * 182 | */ 183 | NAN_METHOD(Wrapper::Empty) {} 184 | 185 | /** 186 | * Destructor. 187 | * 188 | * This is required to close the capture handle deterministically. 189 | * 190 | */ 191 | NAN_METHOD(Wrapper::Destroy) { 192 | Wrapper *wrapper = ObjectWrap::Unwrap(info.This()); 193 | wrapper->_sniffer.reset(); 194 | } 195 | 196 | NAN_METHOD(Wrapper::FromInterface) { 197 | if ( 198 | info.Length() != 7 || 199 | !info[0]->IsString() || 200 | !(info[1]->IsUndefined() || info[1]->IsUint32()) || // snaplen 201 | !(info[2]->IsUndefined() || info[2]->IsBoolean()) || // promisc 202 | !(info[3]->IsUndefined() || info[3]->IsBoolean()) || // rfmon 203 | !(info[4]->IsUndefined() || info[4]->IsUint32()) || // timeout 204 | !(info[5]->IsUndefined() || info[5]->IsUint32()) || // bufferSize 205 | !(info[6]->IsUndefined() || info[6]->IsString()) // filter 206 | ) { 207 | Nan::ThrowError("invalid arguments"); 208 | return; 209 | } 210 | 211 | // The device to listen on. 212 | Nan::Utf8String dev(info[0]); 213 | 214 | // Prepare the configuration, only overriding system defaults when a value 215 | // has been specified. 216 | Tins::SnifferConfiguration config; 217 | uint32_t timeout = 0; 218 | if (!info[1]->IsUndefined()) { 219 | config.set_snap_len(info[1]->Uint32Value()); 220 | } 221 | if (!info[2]->IsUndefined()) { 222 | config.set_promisc_mode(info[2]->BooleanValue()); 223 | } 224 | if (!info[3]->IsUndefined()) { 225 | config.set_rfmon(info[3]->BooleanValue()); 226 | } 227 | if (!info[4]->IsUndefined()) { 228 | timeout = info[4]->Uint32Value(); 229 | config.set_timeout(timeout); 230 | } 231 | if (!info[5]->IsUndefined()) { 232 | config.set_buffer_size(info[5]->Uint32Value()); 233 | } 234 | if (!info[6]->IsUndefined()) { 235 | Nan::Utf8String filter(info[6]); 236 | config.set_filter(std::string(*filter)); 237 | } 238 | 239 | Tins::Sniffer *sniffer; 240 | try { 241 | sniffer = new Tins::Sniffer(*dev, config); 242 | } catch (std::runtime_error &err) { 243 | Nan::ThrowError(err.what()); 244 | return; 245 | } 246 | 247 | Wrapper *wrapper = new Wrapper(sniffer, timeout); 248 | wrapper->Wrap(info.This()); 249 | info.GetReturnValue().Set(info.This()); 250 | } 251 | 252 | NAN_METHOD(Wrapper::FromFile) { 253 | if ( 254 | info.Length() != 2 || 255 | !info[0]->IsString() || 256 | !(info[1]->IsUndefined() || info[1]->IsString()) // filter 257 | ) { 258 | Nan::ThrowError("invalid arguments"); 259 | return; 260 | } 261 | 262 | // The file to open. 263 | Nan::Utf8String path(info[0]); 264 | 265 | Tins::SnifferConfiguration config; 266 | if (!info[1]->IsUndefined()) { 267 | Nan::Utf8String filter(info[1]); 268 | config.set_filter(std::string(*filter)); 269 | } 270 | 271 | Tins::FileSniffer *sniffer; 272 | try { 273 | sniffer = new Tins::FileSniffer(*path, config); 274 | } catch (std::runtime_error &err) { 275 | Nan::ThrowError(err.what()); 276 | return; 277 | } 278 | 279 | Wrapper *wrapper = new Wrapper(sniffer, 0); 280 | wrapper->Wrap(info.This()); 281 | info.GetReturnValue().Set(info.This()); 282 | } 283 | 284 | NAN_METHOD(Wrapper::GetPdus) { 285 | if ( 286 | info.Length() != 2 || 287 | !node::Buffer::HasInstance(info[0]) || 288 | !info[1]->IsFunction() 289 | ) { 290 | Nan::ThrowError("invalid arguments"); 291 | return; 292 | } 293 | 294 | Wrapper *wrapper = ObjectWrap::Unwrap(info.This()); 295 | Nan::Callback *callback = new Nan::Callback(info[1].As()); 296 | Worker *worker = new Worker(wrapper, info[0], callback); 297 | worker->SaveToPersistent("buffer", info[0]); 298 | worker->SaveToPersistent("wrapper", info.This()); 299 | Nan::AsyncQueueWorker(worker); 300 | } 301 | 302 | /** 303 | * Initializer, returns the `Wrapper` JavaScript function template. 304 | * 305 | */ 306 | v8::Local Wrapper::Init() { 307 | v8::Local tpl = Nan::New(Wrapper::Empty); 308 | tpl->SetClassName(Nan::New("Wrapper").ToLocalChecked()); 309 | tpl->InstanceTemplate()->SetInternalFieldCount(1); 310 | Nan::SetPrototypeMethod(tpl, "destroy", Wrapper::Destroy); 311 | Nan::SetPrototypeMethod(tpl, "getPdus", Wrapper::GetPdus); 312 | Nan::SetPrototypeMethod(tpl, "fromInterface", Wrapper::FromInterface); 313 | Nan::SetPrototypeMethod(tpl, "fromFile", Wrapper::FromFile); 314 | return tpl; 315 | } 316 | 317 | } 318 | -------------------------------------------------------------------------------- /src/wrapper.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | namespace Layer2 { 8 | 9 | /** 10 | * Class wrapping tin's Sniffer. 11 | * 12 | * It won't be exposed directly from the JavaScript API but rather called from 13 | * an `EventEmitter` to keep the API simpler (otherwise users would have to 14 | * deal with decoding the PDUs) and more familiar. 15 | * 16 | */ 17 | class Wrapper : public Nan::ObjectWrap { 18 | public: 19 | 20 | /** 21 | * JavaScript glue function. 22 | * 23 | * This creates the associated JavaScript function and sets up the prototype, 24 | * etc. 25 | * 26 | */ 27 | static v8::Local Init(); 28 | 29 | private: 30 | friend class Worker; 31 | 32 | std::unique_ptr _sniffer; 33 | avro::EncoderPtr _encoder; 34 | Tins::Packet _packet; // Used to store last PDU in case of overflow. 35 | uint32_t _timeout; 36 | 37 | Wrapper(Tins::BaseSniffer *sniffer, uint32_t timeout) : 38 | _sniffer(sniffer), 39 | _packet(), 40 | _timeout(timeout) { 41 | _encoder = avro::binaryEncoder(); 42 | } 43 | 44 | ~Wrapper() {} 45 | 46 | /** 47 | * Required function constructor. 48 | * 49 | */ 50 | static NAN_METHOD(Empty); 51 | 52 | /** 53 | * Destructor, to free the underlying capture handle. 54 | * 55 | */ 56 | static NAN_METHOD(Destroy); 57 | 58 | /** 59 | * Prototype method which will take in a buffer and a callback. 60 | * 61 | * The buffer will be populated with Avro-encoded PDUs. The callback will 62 | * take in two arguments, an eventual error and the total number of PDUs 63 | * successfully written to the input buffer. 64 | * 65 | */ 66 | static NAN_METHOD(GetPdus); 67 | 68 | /** 69 | * Factory method to create a `Tins::Sniffer` (live capture). 70 | * 71 | */ 72 | static NAN_METHOD(FromInterface); 73 | 74 | /** 75 | * Factor method to create a `Tins::FileSniffer`. 76 | * 77 | */ 78 | static NAN_METHOD(FromFile); 79 | }; 80 | 81 | } 82 | -------------------------------------------------------------------------------- /test/dat/sample.pcap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mtth/layer2/06b3d0000e845317fb28ff00ad7c1776d015996f/test/dat/sample.pcap -------------------------------------------------------------------------------- /test/mocha.opts: -------------------------------------------------------------------------------- 1 | --ui tdd 2 | -------------------------------------------------------------------------------- /test/test_sniffers.js: -------------------------------------------------------------------------------- 1 | /* jshint node: true, mocha: true */ 2 | 3 | 'use strict'; 4 | 5 | var sniffers = require('../lib/sniffers'), 6 | utils = require('../lib/utils'), 7 | assert = require('assert'), 8 | path = require('path'); 9 | 10 | 11 | var DPATH = path.join(__dirname, 'dat'); // Test data directory. 12 | 13 | suite('sniffers', function () { 14 | 15 | suite('Sniffer', function () { 16 | 17 | var type; // PDU type, loaded asynchronously. 18 | 19 | before(function (done) { 20 | utils.loadPduType(function (err, type_) { 21 | type = type_; 22 | done(); 23 | }); 24 | }); 25 | 26 | test('eager single PDU', function (done) { 27 | var val = type.random(); 28 | var w = new Wrapper([val]); 29 | new sniffers.Sniffer(w) 30 | .on('pdu', function (pdu) { 31 | assert(!pdu.compare(val)); 32 | this.destroy(); 33 | }) 34 | .on('end', function () { 35 | assert(w.destroyed); 36 | done(); 37 | }); 38 | }); 39 | 40 | test('delayed single PDU', function (done) { 41 | var val = type.random(); 42 | var w = new Wrapper([val]); 43 | var s = new sniffers.Sniffer(w); 44 | setImmediate(function () { 45 | s.on('pdu', function (pdu) { 46 | assert(!pdu.compare(val)); 47 | done(); 48 | }); 49 | }); 50 | }); 51 | 52 | // Mock wrapper to test sniffer logic. 53 | function Wrapper(pdus) { 54 | this._pdus = pdus; 55 | this.destroyed = false; 56 | } 57 | 58 | Wrapper.prototype.getPdus = function (buf, cb) { 59 | var pdus = this._pdus; 60 | var n = 0; 61 | var pos = 0; 62 | while (pdus.length && (pos = type.encode(pdus[0], buf, pos)) > 0) { 63 | n++; 64 | pdus.shift(); 65 | } 66 | setImmediate(function () { cb(null, n); }); 67 | }; 68 | 69 | Wrapper.prototype.destroy = function () { this.destroyed = true; }; 70 | 71 | }); 72 | 73 | suite('file sniffer', function () { 74 | 75 | test('missing file', function () { 76 | assert.throws(function () { 77 | sniffers.createFileSniffer(path.join(DPATH, 'foo.pcap')); 78 | }, /No such file/); 79 | }); 80 | 81 | test('non empty', function (done) { 82 | var n = 0; 83 | sniffers.createFileSniffer(path.join(DPATH, 'sample.pcap')) 84 | .on('pdu', function () { n++; }) 85 | .on('end', function () { 86 | assert.equal(n, 10); 87 | done(); 88 | }); 89 | }); 90 | 91 | }); 92 | 93 | }); 94 | -------------------------------------------------------------------------------- /test/test_utils.js: -------------------------------------------------------------------------------- 1 | /* jshint mocha: true, node: true */ 2 | 3 | 'use strict'; 4 | 5 | var utils = require('../lib/utils'), 6 | assert = require('assert'); 7 | 8 | 9 | suite('utils', function () { 10 | 11 | test('stringify addresses', function () { 12 | var buf; 13 | buf = new Buffer('0123456789ab', 'hex'); 14 | assert.equal(utils.stringifyAddress(buf), '01:23:45:67:89:ab'); 15 | buf = new Buffer('001122334455', 'hex'); 16 | assert.equal(utils.stringifyAddress(buf), '00:11:22:33:44:55'); 17 | buf = new Buffer('', 'hex'); 18 | assert.throws(function () { utils.stringifyAddress(buf); }); 19 | }); 20 | 21 | }); 22 | --------------------------------------------------------------------------------