/*
* packet-chdr.c
* Dissector for UHD CHDR packets
*
* Copyright 2010-2013 Ettus Research LLC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*
*/
#include "config.h"
#include
#include
#include
#include
#define LOG_HEADER "[ZPU] "
#ifndef min
#define min(a,b) ((amatch_uint == FW_PORT){
is_network = TRUE;
endianness = ENC_BIG_ENDIAN;
}
else{
is_network = FALSE;
endianness = ENC_LITTLE_ENDIAN;
}
len = tvb_reported_length(tvb);
col_append_str(pinfo->cinfo, COL_PROTOCOL, "/ZPU");
col_append_sep_fstr(pinfo->cinfo, COL_INFO, NULL, "ZPU", tvb_format_text_wsp(tvb, 0, len));
if (tree)
{
item = proto_tree_add_item(tree, proto_zpu, tvb, 0, min(16, len), ENC_NA);
if (len >= 4)
{
zpu_tree = proto_item_add_subtree(item, ett_zpu);
flags_item = proto_tree_add_item(zpu_tree, hf_zpu_flags, tvb, 0, 4, endianness);
flags_tree = proto_item_add_subtree(flags_item, ett_zpu_flags);
proto_tree_add_item(flags_tree, hf_zpu_flags_ack, tvb, 0, 4, ENC_NA);
proto_tree_add_item(flags_tree, hf_zpu_flags_error, tvb, 0, 4, ENC_NA);
proto_tree_add_item(flags_tree, hf_zpu_flags_poke, tvb, 0, 4, ENC_NA);
proto_tree_add_item(flags_tree, hf_zpu_flags_peek, tvb, 0, 4, ENC_NA);
if (len >= 8)
{
proto_tree_add_item(zpu_tree, hf_zpu_seq, tvb, 4, 4, ENC_NA);
if (len >= 12)
{
proto_tree_add_item(zpu_tree, hf_zpu_addr, tvb, 8, 4, ENC_NA);
guint8 *bytes = tvb_get_string(tvb, 8, 4);
unsigned int addr = 0;
memcpy(&addr, bytes, 4);
const unsigned int shmmem_base = 0x6000;
addr = (addr >> 24) | ((addr & 0x00FF0000) >> 8) | ((addr & 0x0000FF00) << 8) | ((addr & 0x000000FF) << 24);
if (addr >= shmmem_base)
{
addr -= 0x6000;
addr /= 4;
proto_tree_add_uint(zpu_tree, hf_zpu_shmem_addr, tvb, 8, 4, addr);
}
if (len >= 16)
{
proto_tree_add_item(zpu_tree, hf_zpu_data, tvb, 12, 4, ENC_NA);
}
}
}
}
}
}
void proto_register_zpu(void)
{
static hf_register_info hf[] = {
{ &hf_zpu_flags,
{ "Flags", "zpu.flags",
FT_UINT32, BASE_HEX,
NULL, 0x0,
NULL, HFILL }
},
{ &hf_zpu_flags_ack,
{ "ACK", "zpu.flags.ack",
FT_BOOLEAN, BASE_NONE,
NULL, 0x1,
NULL, HFILL }
},
{ &hf_zpu_flags_error,
{ "Error", "zpu.flags.error",
FT_BOOLEAN, BASE_NONE,
NULL, 0x2,
NULL, HFILL }
},
{ &hf_zpu_flags_poke,
{ "Poke", "zpu.flags.poke",
FT_BOOLEAN, BASE_NONE,
NULL, 0x4,
NULL, HFILL }
},
{ &hf_zpu_flags_peek,
{ "Peek", "zpu.flags.peek",
FT_BOOLEAN, BASE_NONE,
NULL, 0x8,
NULL, HFILL }
},
{ &hf_zpu_seq,
{ "Sequence ID", "zpu.seq",
FT_UINT32, BASE_HEX,
NULL, 0x0,
NULL, HFILL }
},
{ &hf_zpu_addr,
{ "Address", "zpu.addr",
FT_UINT32, BASE_HEX,
NULL, 0x0,
NULL, HFILL }
},
{ &hf_zpu_shmem_addr,
{ "SHMEM section", "zpu.shmem",
FT_UINT32, BASE_DEC,
NULL, 0x0,
NULL, HFILL }
},
{ &hf_zpu_data,
{ "Data", "zpu.data",
FT_UINT32, BASE_HEX,
NULL, 0x0,
NULL, HFILL }
},
};
static gint *ett[] = {
&ett_zpu,
&ett_zpu_flags,
//&ett_zpu_shmem
};
proto_zpu = proto_register_protocol("ZPU FW", "ZPU", "zpu");
proto_register_field_array(proto_zpu, hf, array_length(hf));
proto_register_subtree_array(ett, array_length(ett));
register_dissector("zpu", dissect_zpu, proto_zpu);
}
/* Handler registration */
void proto_reg_handoff_zpu(void)
{
/* register dissector for UDP packets */
static dissector_handle_t zpu_handle;
zpu_handle = create_dissector_handle(dissect_zpu, proto_zpu);
dissector_add_uint("udp.port", FW_PORT, zpu_handle);
}