ethernet
Version:
Decodes Ethernet headers
63 lines • 2.03 kB
JavaScript
;
// Reference: https://en.wikipedia.org/wiki/IEEE_802.1Q
const TPID_8021Q = 0x8100;
const TPID_8021ad = 0x88a8;
const TPID_QinQ = 0x9100;
const decodeTCI = (tci) => {
return {
pcp: (tci >> 13) & 0x7,
dei: (tci >> 11) & 0x1,
vid: tci & 0xfff,
};
};
const decodeTag = (data) => {
return {
tpid: parseInt(data.substr(0, 4), 16),
tci: decodeTCI(parseInt(data.substr(4, 4), 16)),
};
};
const decode = (data) => {
if (data.length < 14 * 2) {
throw new Error("Frame header must be at least 14 bytes");
}
let result = {
destination: data.substr(0, 12),
source: data.substr(12, 12),
ethertype: parseInt(data.substr(24, 4), 16),
payload: data.substring(28),
};
if (result.ethertype === TPID_8021Q) {
result.tag = decodeTag(data.substr(24, 8));
result.ethertype = parseInt(data.substr(32, 4), 16);
result.payload = data.substring(36);
}
else if (result.ethertype === TPID_8021ad || result.ethertype === TPID_QinQ) {
result.stag = decodeTag(data.substr(24, 8));
result.ctag = decodeTag(data.substr(32, 8));
result.ethertype = parseInt(data.substr(40, 4), 16);
result.payload = data.substring(44);
}
return result;
};
/**
* Decode an Ethernet frame
* @param {string | Buffer} frame The raw frame data as a hex string or Node.js Buffer
* @returns {EthernetHeader}
*/
const ethernet = (frame) => {
if (typeof frame === "string") {
if (!/^([A-Fa-f0-9]{2})+$/.test(frame)) {
throw new TypeError("Frame must be hex string or Buffer");
}
return decode(frame);
}
else if (typeof Buffer !== undefined && Buffer.isBuffer(frame)) {
return decode(frame.toString("hex"));
}
else {
throw new TypeError("Frame must be hex string or Buffer");
}
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = ethernet;
//# sourceMappingURL=ethernet.js.map