From 972dfdd54ffb7ae2bb3d726a38c5dfaf85b4a610 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix=20Baylac=20Jacqu=C3=A9?= Date: Mon, 4 Sep 2023 15:41:10 +0200 Subject: [PATCH] Init: hello + op Initial Lua dissector. So far it can parse the hello handshake and the store operation. --- default.nix | 10 ++++ flake.lock | 27 +++++++++++ flake.nix | 14 ++++++ nix-packet.lua | 122 +++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 173 insertions(+) create mode 100644 default.nix create mode 100644 flake.lock create mode 100644 flake.nix create mode 100644 nix-packet.lua diff --git a/default.nix b/default.nix new file mode 100644 index 0000000..331bab9 --- /dev/null +++ b/default.nix @@ -0,0 +1,10 @@ +{ pkgs ? import {} }: + +pkgs.stdenv.mkDerivation { + pname = "nix-dissector"; + version = "1.0"; + nativeBuildInputs = [ pkgs.autoreconfHook pkgs.pkg-config ]; + buildInputs = [ pkgs.wireshark.dev pkgs.glib ]; + src = pkgs.lib.cleanSource ./.; + +} diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..a30d432 --- /dev/null +++ b/flake.lock @@ -0,0 +1,27 @@ +{ + "nodes": { + "nixpkgs": { + "locked": { + "lastModified": 1693832517, + "narHash": "sha256-Fz1r73mrpGsnkbHvGotxW6v/gVsnieI7poLJ/JbU2to=", + "owner": "Ninjatrappeur", + "repo": "nixpkgs", + "rev": "2966ff4b76ef80e4e68588967ca73293b4a84f6d", + "type": "github" + }, + "original": { + "owner": "Ninjatrappeur", + "ref": "nin/wireshark-dev-fix", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "nixpkgs": "nixpkgs" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..0ee494a --- /dev/null +++ b/flake.nix @@ -0,0 +1,14 @@ +{ + description = "Nix wireshark dissector"; + + inputs = { + nixpkgs.url = "github:Ninjatrappeur/nixpkgs/nin/wireshark-dev-fix"; + }; + + outputs = { self, nixpkgs }: { + + packages.x86_64-linux.nix-dissector = import ./default.nix { inherit (nixpkgs.legacyPackages.x86_64-linux) pkgs; }; + + devShells.x86_64-linux.default = self.packages.x86_64-linux.nix-dissector; + }; +} diff --git a/nix-packet.lua b/nix-packet.lua new file mode 100644 index 0000000..0d0510d --- /dev/null +++ b/nix-packet.lua @@ -0,0 +1,122 @@ +local nix_proto = Proto("nix", "Nix Daemon Protocol") + +local dst_field = ProtoField.uint64("nix.dst", "Destination FD") +local src_field = ProtoField.uint64("nix.src", "Source FD") + +local client_hello_field = ProtoField.bytes("nix.clienthello", "Client Hello") +local client_hello_magic_field = ProtoField.uint64("nix.clienthello.magic", "Client magic number") +local client_hello_version_field = ProtoField.uint64("nix.clienthello.version", "Client version") + +local daemon_hello_field = ProtoField.bytes("nix.daemonhello", "Daemon Hello") +local daemon_hello_magic_field = ProtoField.uint64("nix.daemonhello.magic", "Daemon magic number") +local daemon_hello_version_field = ProtoField.uint64("nix.daemonhello.protolversion", "Protocol Version") + +local op_name_field = ProtoField.string("nix.opname", "Operation Name") + +nix_proto.fields = { + dst_field, + src_field, + op_field, + first_byte_field, + client_hello_field, + client_hello_magic_field, + client_hello_version_field, + daemon_hello_field, + daemon_hello_magic_field, + daemon_hello_version_field, + op_name_field +} + +local op_table = { + [1] = "IsValidPath", + [3] = "HasSubstitutes", + [4] = "QuaryPathHash", + [5] = "QueryReferences", + [6] = "QueryReferrers", + [7] = "AddToStore", + [8] = "AddTextToStore", + [9] = "BuildPaths", + [10] = "EnsurePath", + [11] = "AddTempRoot", + [12] = "AddIndirectRoot", + [13] = "SyncWithGC", + [14] = "FindRoots", + [16] = "ExportPath", + [18] = "QueryDeriver", + [19] = "SetOptions", + [20] = "CollectGarbage", + [21] = "QuerySubstitutablePathInfo", + [22] = "QueryDerivationOutputs", + [23] = "QueryAllValidPaths", + [24] = "QueryFailedPaths", + [25] = "ClearFailedPaths", + [26] = "QueryPathInfo", + [27] = "ImportPaths", + [28] = "QueryDerivationOutputNames", + [29] = "QueryPathFromHashPart", + [30] = "QuerySubstitutablePathInfos", + [31] = "QueryValidPaths", + [32] = "QuerySubstitutablePaths", + [33] = "QueryValidDerivers", + [34] = "OptimiseStore", + [35] = "VerifyStore", + [36] = "BuildDerivation", + [37] = "AddSignatures", + [38] = "NarFromPath", + [39] = "AddToStoreNar", + [40] = "QueryMissing", + [41] = "QueryDerivationOutputMap", + [42] = "RegisterDrvOutput", + [43] = "QueryRealisation", + [44] = "AddMultipleToStore", + [45] = "AddBuildLog", + [46] = "BuildPathsWithResults", +} + +function parse_client_hello(tvb, pinfo, tree, offset) + local subtree = tree:add(client_hello_field, tvb:range(offset, 8)) + + subtree:add_le(client_hello_magic_field, tvb(offset,8)) + return offset + 8 +end + +function parse_daemon_hello(tvb, pinfo, tree, offset) + local subtree = tree:add(daemon_hello_field, tvb:range(offset, 16)) + + subtree:add_le(daemon_hello_magic_field, tvb(offset,8)) + offset = offset + 8 + + subtree:add_le(daemon_hello_version_field, tvb(offset,8)) + return offset + 8 +end + +function parse_op(tvb, pinfo, tree, offset, op) + tree:add(op_name_field, tvb(offset, 8), op_table[op]) +end + + +function nix_proto.dissector(tvb, pinfo, tree) + local offset = 0 + local subtree = tree:add(nix_proto, tvb(), "Nix Daemon Protocol Data") + local dst = subtree:add(dst_field, tvb(offset, 8)) + offset = offset + 8 + + local src = subtree:add(src_field, tvb(offset, 8)) + offset = offset + 8 + + local first_word = tvb(offset, 4):le_uint() + if first_word == 0x6e697863 then + offset = parse_client_hello(tvb, pinfo, subtree, offset) + elseif first_word == 0x6478696f then + offset = parse_daemon_hello(tvb, pinfo, subtree, offset) + elseif op_table[first_word] ~= nil then + offset = parse_op(tvb, pinfo, subtree, offset, first_word) + end + + pinfo.cols.protocol = "Nix Daemon" + pinfo.cols.dst = tostring(tvb(0, 8):uint64()) + pinfo.cols.src = tostring(tvb(8, 8):uint64()) +end + +local wtap_encap_table = DissectorTable.get("wtap_encap") +wtap_encap_table:add(wtap.USER0, nix_proto)