mirror of
https://github.com/gchq/CyberChef.git
synced 2025-04-20 23:06:16 -04:00
ESM: Tidied up IP operations
This commit is contained in:
commit
7f9a2eeb6b
7 changed files with 1220 additions and 0 deletions
129
src/core/operations/ParseIPv4Header.mjs
Normal file
129
src/core/operations/ParseIPv4Header.mjs
Normal file
|
@ -0,0 +1,129 @@
|
|||
/**
|
||||
* @author n1474335 [n1474335@gmail.com]
|
||||
* @copyright Crown Copyright 2016
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
import Operation from "../Operation";
|
||||
import Utils from "../Utils";
|
||||
import OperationError from "../errors/OperationError";
|
||||
import {fromHex, toHex} from "../lib/Hex";
|
||||
import {ipv4ToStr, protocolLookup} from "../lib/IP";
|
||||
import TCPIPChecksum from "./TCPIPChecksum";
|
||||
|
||||
/**
|
||||
* Parse IPv4 header operation
|
||||
*/
|
||||
class ParseIPv4Header extends Operation {
|
||||
|
||||
/**
|
||||
* ParseIPv4Header constructor
|
||||
*/
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.name = "Parse IPv4 header";
|
||||
this.module = "JSBN";
|
||||
this.description = "Given an IPv4 header, this operations parses and displays each field in an easily readable format.";
|
||||
this.inputType = "string";
|
||||
this.outputType = "html";
|
||||
this.args = [
|
||||
{
|
||||
"name": "Input format",
|
||||
"type": "option",
|
||||
"value": ["Hex", "Raw"]
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} input
|
||||
* @param {Object[]} args
|
||||
* @returns {html}
|
||||
*/
|
||||
run(input, args) {
|
||||
const format = args[0];
|
||||
let output;
|
||||
|
||||
if (format === "Hex") {
|
||||
input = fromHex(input);
|
||||
} else if (format === "Raw") {
|
||||
input = Utils.strToByteArray(input);
|
||||
} else {
|
||||
throw new OperationError("Unrecognised input format.");
|
||||
}
|
||||
|
||||
let ihl = input[0] & 0x0f;
|
||||
const dscp = (input[1] >>> 2) & 0x3f,
|
||||
ecn = input[1] & 0x03,
|
||||
length = input[2] << 8 | input[3],
|
||||
identification = input[4] << 8 | input[5],
|
||||
flags = (input[6] >>> 5) & 0x07,
|
||||
fragOffset = (input[6] & 0x1f) << 8 | input[7],
|
||||
ttl = input[8],
|
||||
protocol = input[9],
|
||||
checksum = input[10] << 8 | input[11],
|
||||
srcIP = input[12] << 24 | input[13] << 16 | input[14] << 8 | input[15],
|
||||
dstIP = input[16] << 24 | input[17] << 16 | input[18] << 8 | input[19],
|
||||
checksumHeader = input.slice(0, 10).concat([0, 0]).concat(input.slice(12, 20));
|
||||
let version = (input[0] >>> 4) & 0x0f,
|
||||
options = [];
|
||||
|
||||
|
||||
// Version
|
||||
if (version !== 4) {
|
||||
version = version + " (Error: for IPv4 headers, this should always be set to 4)";
|
||||
}
|
||||
|
||||
// IHL
|
||||
if (ihl < 5) {
|
||||
ihl = ihl + " (Error: this should always be at least 5)";
|
||||
} else if (ihl > 5) {
|
||||
// sort out options...
|
||||
const optionsLen = ihl * 4 - 20;
|
||||
options = input.slice(20, optionsLen + 20);
|
||||
}
|
||||
|
||||
// Protocol
|
||||
const protocolInfo = protocolLookup[protocol] || {keyword: "", protocol: ""};
|
||||
|
||||
// Checksum
|
||||
const correctChecksum = (new TCPIPChecksum).run(checksumHeader),
|
||||
givenChecksum = Utils.hex(checksum);
|
||||
let checksumResult;
|
||||
if (correctChecksum === givenChecksum) {
|
||||
checksumResult = givenChecksum + " (correct)";
|
||||
} else {
|
||||
checksumResult = givenChecksum + " (incorrect, should be " + correctChecksum + ")";
|
||||
}
|
||||
|
||||
output = `<table class='table table-hover table-condensed table-bordered table-nonfluid'><tr><th>Field</th><th>Value</th></tr>
|
||||
<tr><td>Version</td><td>${version}</td></tr>
|
||||
<tr><td>Internet Header Length (IHL)</td><td>${ihl} (${ihl * 4} bytes)</td></tr>
|
||||
<tr><td>Differentiated Services Code Point (DSCP)</td><td>${dscp}</td></tr>
|
||||
<tr><td>Explicit Congestion Notification (ECN)</td><td>${ecn}</td></tr>
|
||||
<tr><td>Total length</td><td>${length} bytes
|
||||
IP header: ${ihl * 4} bytes
|
||||
Data: ${length - ihl * 4} bytes</td></tr>
|
||||
<tr><td>Identification</td><td>0x${Utils.hex(identification)} (${identification})</td></tr>
|
||||
<tr><td>Flags</td><td>0x${Utils.hex(flags, 2)}
|
||||
Reserved bit:${flags >> 2} (must be 0)
|
||||
Don't fragment:${flags >> 1 & 1}
|
||||
More fragments:${flags & 1}</td></tr>
|
||||
<tr><td>Fragment offset</td><td>${fragOffset}</td></tr>
|
||||
<tr><td>Time-To-Live</td><td>${ttl}</td></tr>
|
||||
<tr><td>Protocol</td><td>${protocol}, ${protocolInfo.protocol} (${protocolInfo.keyword})</td></tr>
|
||||
<tr><td>Header checksum</td><td>${checksumResult}</td></tr>
|
||||
<tr><td>Source IP address</td><td>${ipv4ToStr(srcIP)}</td></tr>
|
||||
<tr><td>Destination IP address</td><td>${ipv4ToStr(dstIP)}</td></tr>`;
|
||||
|
||||
if (ihl > 5) {
|
||||
output += `<tr><td>Options</td><td>${toHex(options)}</td></tr>`;
|
||||
}
|
||||
|
||||
return output + "</table>";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default ParseIPv4Header;
|
Loading…
Add table
Add a link
Reference in a new issue