Skip to content

Commit

Permalink
Init: hello + op
Browse files Browse the repository at this point in the history
Initial Lua dissector. So far it can parse the hello handshake and the
store operation.
  • Loading branch information
picnoir committed Sep 13, 2023
0 parents commit 972dfdd
Show file tree
Hide file tree
Showing 4 changed files with 173 additions and 0 deletions.
10 changes: 10 additions & 0 deletions default.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{ pkgs ? import <nixpkgs> {} }:

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 ./.;

}
27 changes: 27 additions & 0 deletions flake.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 14 additions & 0 deletions flake.nix
Original file line number Diff line number Diff line change
@@ -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;
};
}
122 changes: 122 additions & 0 deletions nix-packet.lua
Original file line number Diff line number Diff line change
@@ -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)

0 comments on commit 972dfdd

Please sign in to comment.