UNPKG

over-the-wire

Version:

Network inspection library for Node

113 lines (95 loc) 2.48 kB
const { LinkLayerType } = require('../enums'); const { compile } = require('struct-compile'); const { macToString, macFromString } = require('./mac'); const { OsiModelLayers } = require('./osi'); const { ETHERTYPE } = require('./enums'); const child = require('./child'); const mixins = require('./mixins'); const { EthernetHeader } = compile(` //@NE struct EthernetHeader { //destination MAC uint8_t dst[6]; //source MAC uint8_t src[6]; //underlying protocol uint16_t type; } __attribute__(packed); `); const childProto = { [ETHERTYPE.IP]: 'IPv4', [ETHERTYPE.IPV6]: 'IPv6', [ETHERTYPE.ARP]: 'ARP', [ETHERTYPE.VLAN]: 'Vlan', [ETHERTYPE.IEEE_802_1AD]: 'Vlan', [ETHERTYPE.PPPOES]: 'PPPoESession', [ETHERTYPE.PPPOED]: 'PPPoEDiscovery', [ETHERTYPE.MPLS]: 'Mpls', [ETHERTYPE.WAKE_ON_LAN]: 'WakeOnLanLayer', }; const lookupChild = child.lookupChild(childProto); const lookupKey = child.lookupKey(childProto); /** * Ethernet protocol layer * @class * @implements {Layer} * @property {string} src - Source MAC address. * @property {string} dst - Destination MAC address. * @property {number} type - Protocol type. */ class Ethernet extends EthernetHeader { static linktype = LinkLayerType.LINKTYPE_ETHERNET; name = 'Ethernet'; /** * @param {Buffer|Object} data - Input buffer or object with protocol fields. * @param {Object} opts - Options for the layer. */ constructor(data = {}, opts = {}) { super(data); mixins.ctor(this, data, opts); } static toAlloc = () => EthernetHeader.prototype.config.length; static osi = OsiModelLayers.DataLink; osi = OsiModelLayers.DataLink; /** * The source mac address in human-readable format. * @type {string} */ get src() { return macToString(super.src); } set src(val) { super.src = macFromString(val); } /** * The destination mac address in human-readable format. * @type {string} */ get dst() { return macToString(super.dst); } set dst(val) { super.dst = macFromString(val); } toObject() { return { ...super.toObject(), src: this.src, dst: this.dst, }; } defaults(obj, layers) { if (!obj.type) { if (this.next) { this.type = lookupKey(layers, this.next); } else { this.type = ETHERTYPE.IP; } } } nextProto(layers) { return lookupChild(layers, this.type, this); } }; module.exports = { Ethernet };