/** * Wraps the WiregasmLib lib functionality and manages a single DissectSession */ class Wiregasm { constructor() { this.initialized = false; this.session = null; } /** * Initialize the wrapper and the Wiregasm module * * @param loader Loader function for the Emscripten module * @param overrides Overrides */ async init(loader, overrides = {}, beforeInit = null) { if (this.initialized) { return; } this.lib = await loader(overrides); this.uploadDir = this.lib.getUploadDirectory(); this.pluginsDir = this.lib.getPluginsDirectory(); if (beforeInit !== null) { await beforeInit(this.lib); } this.lib.init(); this.initialized = true; } list_modules() { return this.lib.listModules(); } list_prefs(module) { return this.lib.listPreferences(module); } apply_prefs() { this.lib.applyPreferences(); } set_pref(module, key, value) { const ret = this.lib.setPref(module, key, value); if (ret.code != PrefSetResult.PREFS_SET_OK) { const message = ret.error != '' ? ret.error : preferenceSetCodeToError(ret.code); throw new Error( `Failed to set preference (${module}.${key}): ${message}` ); } } get_pref(module, key) { const response = this.lib.getPref(module, key); if (response.code != 0) { throw new Error(`Failed to get preference (${module}.${key})`); } return response.data; } /** * Check the validity of a filter expression. * * @param filter A display filter expression */ test_filter(filter) { return this.lib.checkFilter(filter); } complete_filter(filter) { const out = this.lib.completeFilter(filter); return { err: out.err, fields: vectorToArray(out.fields), }; } reload_lua_plugins() { this.lib.reloadLuaPlugins(); } add_plugin(name, data, opts = {}) { const path = this.pluginsDir + '/' + name; this.lib.FS.writeFile(path, data, opts); } /** * Load a packet trace file for analysis. * * @returns Response containing the status and summary */ load(name, data, opts = {}) { if (this.session != null) { this.session.delete(); } const path = this.uploadDir + '/' + name; this.lib.FS.writeFile(path, data, opts); this.session = new this.lib.DissectSession(path); return this.session.load(); } /** * Get Packet List information for a range of packets. * * @param filter Output those frames that pass this filter expression * @param skip Skip N frames * @param limit Limit the output to N frames */ frames(filter, skip = 0, limit = 0) { return this.session.getFrames(filter, skip, limit); } /** * Get full information about a frame including the protocol tree. * * @param number Frame number */ frame(num) { return this.session.getFrame(num); } follow(follow, filter) { return this.session.follow(follow, filter); } destroy() { if (this.initialized) { if (this.session !== null) { this.session.delete(); this.session = null; } this.lib.destroy(); this.initialized = false; } } /** * Returns the column headers */ columns() { const vec = this.lib.getColumns(); // convert it from a vector to array return vectorToArray(vec); } } /** * Converts a Vector to a JS array * * @param vec Vector * @returns JS array of the Vector contents */ function vectorToArray(vec) { return new Array(vec.size()).fill(0).map((_, id) => vec.get(id)); } function preferenceSetCodeToError(code) { switch (code) { case PrefSetResult.PREFS_SET_SYNTAX_ERR: return 'Syntax error in string'; case PrefSetResult.PREFS_SET_NO_SUCH_PREF: return 'No such preference'; case PrefSetResult.PREFS_SET_OBSOLETE: return 'Preference used to exist but no longer does'; default: return 'Unknown error'; } } if (typeof exports === 'object' && typeof module === 'object') { module.exports = Wiregasm; module.exports = vectorToArray; } else if (typeof define === 'function' && define['amd']) { define([], function () { return Wiregasm; }); define([], function () { return vectorToArray; }); } else if (typeof exports === 'object') { exports['loadWiregasm'] = Wiregasm; exports['vectorToArray'] = vectorToArray; }