Clean up IPMB/I2C link-layer header types.

209 is LINKTYPE_IPMB_LINUX; add _LINUX/_linux to the WTAP_ENCAP_ name
and function/structure names, to clarify that it's not I2C in general,
it's I2C with a particular pseudo-header.

199 is now LINKTYPE_IPMB_KONTRON, not LINKTYPE_IPMB, as it doesn't have
raw I2C packets, it has I2C packets with a pseudo-header.  Change the
WTAP_ENCAP_ name, and add a dissector for it.

Change-Id: Ie097f4317b03d2b2adfd9b81a4b11caf6268399e
Reviewed-on: https://code.wireshark.org/review/32539
Petri-Dish: Guy Harris <guy@alum.mit.edu>
Tested-by: Petri Dish Buildbot
Reviewed-by: Guy Harris <guy@alum.mit.edu>
This commit is contained in:
Guy Harris 2019-03-23 00:35:23 -07:00
parent 80d96e91d2
commit ed23cfba22
6 changed files with 100 additions and 49 deletions

View File

@ -35,6 +35,8 @@ static gint ett_i2c = -1;
static dissector_table_t subdissector_table;
static dissector_handle_t ipmb_handle;
/* I2C packet flags. */
#define I2C_FLAG_RD 0x00000001
#define I2C_FLAG_TEN 0x00000010
@ -70,7 +72,7 @@ static void i2c_prompt(packet_info *pinfo _U_, gchar* result)
}
static gboolean
capture_i2c(const guchar *pd _U_, int offset _U_, int len _U_, capture_packet_info_t *cpinfo, const union wtap_pseudo_header *pseudo_header)
capture_i2c_linux(const guchar *pd _U_, int offset _U_, int len _U_, capture_packet_info_t *cpinfo, const union wtap_pseudo_header *pseudo_header)
{
if (pseudo_header->i2c.is_event) {
capture_dissector_increment_count(cpinfo, proto_i2c_event);
@ -82,7 +84,7 @@ capture_i2c(const guchar *pd _U_, int offset _U_, int len _U_, capture_packet_in
}
static const char *
i2c_get_event_desc(guint32 event)
i2c_linux_get_event_desc(guint32 event)
{
const char *desc;
@ -151,7 +153,7 @@ i2c_get_event_desc(guint32 event)
}
static int
dissect_i2c(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
dissect_i2c_linux(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
{
proto_item *ti;
proto_tree *i2c_tree;
@ -170,7 +172,7 @@ dissect_i2c(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
col_set_str(pinfo->cinfo, COL_PROTOCOL, "I2C Event");
col_add_fstr(pinfo->cinfo, COL_DEF_DST, "----");
col_add_fstr(pinfo->cinfo, COL_INFO, "%s",
i2c_get_event_desc(flags));
i2c_linux_get_event_desc(flags));
} else {
/* Report 7-bit hardware address */
addr = tvb_get_guint8(tvb, 0) >> 1;
@ -194,7 +196,7 @@ dissect_i2c(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
if (is_event) {
proto_tree_add_uint_format_value(i2c_tree, hf_i2c_event, tvb, 0, 0,
flags, "%s (0x%08x)",
i2c_get_event_desc(flags), flags);
i2c_linux_get_event_desc(flags), flags);
} else {
proto_tree_add_uint_format_value(i2c_tree, hf_i2c_addr, tvb, 0, 1,
addr, "0x%02x%s", addr, addr ? "" : " (General Call)");
@ -208,6 +210,48 @@ dissect_i2c(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
return tvb_captured_length(tvb);
}
/* IPMB-over-I2C, with Kontron pseudo-header */
static int
dissect_i2c_kontron(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
{
proto_item *ti;
proto_tree *i2c_tree;
int offset = 0;
guint8 addr;
tvbuff_t *new_tvb;
col_add_str(pinfo->cinfo, COL_DEF_SRC, "I2C");
col_add_str(pinfo->cinfo, COL_PROTOCOL, "I2C");
ti = proto_tree_add_protocol_format(tree, proto_i2c, tvb, 0, -1,
"Inter-Integrated Circuit (Data)");
/* Data length field */
offset++;
/* Port number on which the message was received */
offset++;
/* Report 7-bit hardware address */
addr = tvb_get_guint8(tvb, offset) >> 1;
col_append_fstr(pinfo->cinfo, COL_PROTOCOL, " %s",
tvb_get_guint8(tvb, 0) & 0x01 ? "Read" : "Write");
col_add_fstr(pinfo->cinfo, COL_DEF_DST, "0x%02x", addr);
col_add_fstr(pinfo->cinfo, COL_INFO, "I2C, %d bytes",
tvb_captured_length(tvb));
pinfo->ptype = PT_I2C;
i2c_tree = proto_item_add_subtree(ti, ett_i2c);
proto_tree_add_uint_format_value(i2c_tree, hf_i2c_addr, tvb, 0, 3,
addr, "0x%02x%s", addr, addr ? "" : " (General Call)");
new_tvb = tvb_new_subset_remaining(tvb, offset);
call_dissector(ipmb_handle, new_tvb, pinfo, tree);
return tvb_captured_length(tvb);
}
void
proto_register_i2c(void)
{
@ -239,13 +283,19 @@ proto_register_i2c(void)
void
proto_reg_handoff_i2c(void)
{
dissector_handle_t i2c_handle;
capture_dissector_handle_t i2c_cap_handle;
dissector_handle_t i2c_linux_handle;
capture_dissector_handle_t i2c_linux_cap_handle;
dissector_handle_t i2c_kontron_handle;
i2c_handle = create_dissector_handle(dissect_i2c, proto_i2c);
dissector_add_uint("wtap_encap", WTAP_ENCAP_I2C, i2c_handle);
i2c_cap_handle = create_capture_dissector_handle(capture_i2c, proto_i2c);
capture_dissector_add_uint("wtap_encap", WTAP_ENCAP_I2C, i2c_cap_handle);
i2c_linux_handle = create_dissector_handle(dissect_i2c_linux, proto_i2c);
dissector_add_uint("wtap_encap", WTAP_ENCAP_I2C_LINUX, i2c_linux_handle);
i2c_linux_cap_handle = create_capture_dissector_handle(capture_i2c_linux, proto_i2c);
capture_dissector_add_uint("wtap_encap", WTAP_ENCAP_I2C_LINUX, i2c_linux_cap_handle);
i2c_kontron_handle = create_dissector_handle(dissect_i2c_kontron, proto_i2c);
dissector_add_uint("wtap_encap", WTAP_ENCAP_IPMB_KONTRON, i2c_kontron_handle);
ipmb_handle = find_dissector("ipmb");
}
/*

View File

@ -342,7 +342,7 @@ dissect_pcap_pktdata(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *
/* TODO */
case WTAP_ENCAP_ERF:
/* TODO no description for pseudoheader at http://www.tcpdump.org/linktypes.html */
case WTAP_ENCAP_I2C:
case WTAP_ENCAP_I2C_LINUX:
/* TODO */
default:
/*

View File

@ -995,7 +995,7 @@
["GPRS_LLC"] = 66,
["GSM_UM"] = 116,
["HHDLC"] = 32,
["I2C"] = 112,
["I2C_LINUX"] = 112,
["IEEE802_15_4"] = 104,
["IEEE802_15_4_NOFCS"] = 127,
["IEEE802_15_4_NONASK_PHY"] = 113,
@ -1007,7 +1007,7 @@
["IEEE_802_11_RADIOTAP"] = 23,
["IEEE_802_11_WITH_RADIO"] = 22,
["INFINIBAND"] = 150,
["IPMB"] = 103,
["IPMB_KONTRON"] = 103,
["IPMI_TRACE"] = 173,
["IPNET"] = 124,
["IP_OVER_FC"] = 18,

View File

@ -347,8 +347,8 @@ static const struct {
{ 196, WTAP_ENCAP_SITA },
/* Endace Record File Encapsulation */
{ 197, WTAP_ENCAP_ERF },
/* IPMB */
{ 199, WTAP_ENCAP_IPMB },
/* IPMB/I2C with Kontron pseudo-header */
{ 199, WTAP_ENCAP_IPMB_KONTRON },
/* Juniper-private data link type, used for capturing data on a secure tunnel interface. */
{ 200, WTAP_ENCAP_JUNIPER_ST },
/* Bluetooth HCI UART transport (part H:4) frames, like hcidump */
@ -359,8 +359,8 @@ static const struct {
{ 203, WTAP_ENCAP_LAPD },
/* PPP with pseudoheader */
{ 204, WTAP_ENCAP_PPP_WITH_PHDR },
/* IPMB/I2C */
{ 209, WTAP_ENCAP_I2C },
/* IPMB/I2C with a Linux-specific header (defined by Pigeon Point Systems) */
{ 209, WTAP_ENCAP_I2C_LINUX },
/* FlexRay frame */
{ 210, WTAP_ENCAP_FLEXRAY },
/* MOST frame */
@ -1629,20 +1629,21 @@ pcap_write_erf_pseudoheader(wtap_dumper *wdh,
}
/*
* I2C link-layer on-disk format
* I2C-with=Linux-pseudoheader link-layer on-disk format, as defined by
* Pigeon Point Systems.
*/
struct i2c_file_hdr {
struct i2c_linux_file_hdr {
guint8 bus;
guint8 flags[4];
};
static int
pcap_read_i2c_pseudoheader(FILE_T fh, union wtap_pseudo_header *pseudo_header,
pcap_read_i2c_linux_pseudoheader(FILE_T fh, union wtap_pseudo_header *pseudo_header,
guint packet_size, int *err, gchar **err_info)
{
struct i2c_file_hdr i2c_hdr;
struct i2c_linux_file_hdr i2c_linux_hdr;
if (packet_size < sizeof (struct i2c_file_hdr)) {
if (packet_size < sizeof (struct i2c_linux_file_hdr)) {
/*
* Uh-oh, the packet isn't big enough to even
* have a pseudo-header.
@ -1652,32 +1653,32 @@ pcap_read_i2c_pseudoheader(FILE_T fh, union wtap_pseudo_header *pseudo_header,
packet_size);
return -1;
}
if (!wtap_read_bytes(fh, &i2c_hdr, sizeof (i2c_hdr), err, err_info))
if (!wtap_read_bytes(fh, &i2c_linux_hdr, sizeof (i2c_linux_hdr), err, err_info))
return -1;
pseudo_header->i2c.is_event = i2c_hdr.bus & 0x80 ? 1 : 0;
pseudo_header->i2c.bus = i2c_hdr.bus & 0x7f;
pseudo_header->i2c.flags = pntoh32(&i2c_hdr.flags);
pseudo_header->i2c.is_event = i2c_linux_hdr.bus & 0x80 ? 1 : 0;
pseudo_header->i2c.bus = i2c_linux_hdr.bus & 0x7f;
pseudo_header->i2c.flags = pntoh32(&i2c_linux_hdr.flags);
return (int)sizeof (struct i2c_file_hdr);
return (int)sizeof (struct i2c_linux_file_hdr);
}
static gboolean
pcap_write_i2c_pseudoheader(wtap_dumper *wdh,
pcap_write_i2c_linux_pseudoheader(wtap_dumper *wdh,
const union wtap_pseudo_header *pseudo_header, int *err)
{
struct i2c_file_hdr i2c_hdr;
struct i2c_linux_file_hdr i2c_linux_hdr;
/*
* Write the I2C header.
* Write the I2C Linux-specific pseudo-header.
*/
memset(&i2c_hdr, 0, sizeof(i2c_hdr));
i2c_hdr.bus = pseudo_header->i2c.bus |
memset(&i2c_linux_hdr, 0, sizeof(i2c_linux_hdr));
i2c_linux_hdr.bus = pseudo_header->i2c.bus |
(pseudo_header->i2c.is_event ? 0x80 : 0x00);
phtonl((guint8 *)&i2c_hdr.flags, pseudo_header->i2c.flags);
if (!wtap_dump_file_write(wdh, &i2c_hdr, sizeof(i2c_hdr), err))
phtonl((guint8 *)&i2c_linux_hdr.flags, pseudo_header->i2c.flags);
if (!wtap_dump_file_write(wdh, &i2c_linux_hdr, sizeof(i2c_linux_hdr), err))
return FALSE;
wdh->bytes_dumped += sizeof(i2c_hdr);
wdh->bytes_dumped += sizeof(i2c_linux_hdr);
return TRUE;
}
@ -2233,8 +2234,8 @@ pcap_process_pseudo_header(FILE_T fh, int file_type, int wtap_encap,
return -1; /* Read error */
break;
case WTAP_ENCAP_I2C:
phdr_len = pcap_read_i2c_pseudoheader(fh,
case WTAP_ENCAP_I2C_LINUX:
phdr_len = pcap_read_i2c_linux_pseudoheader(fh,
&rec->rec_header.packet_header.pseudo_header,
packet_size, err, err_info);
if (phdr_len == -1)
@ -2336,7 +2337,7 @@ wtap_encap_requires_phdr(int wtap_encap)
case WTAP_ENCAP_NFC_LLCP:
case WTAP_ENCAP_PPP_WITH_PHDR:
case WTAP_ENCAP_ERF:
case WTAP_ENCAP_I2C:
case WTAP_ENCAP_I2C_LINUX:
return TRUE;
}
return FALSE;
@ -2436,8 +2437,8 @@ pcap_get_phdr_size(int encap, const union wtap_pseudo_header *pseudo_header)
}
break;
case WTAP_ENCAP_I2C:
hdrsize = (int)sizeof (struct i2c_file_hdr);
case WTAP_ENCAP_I2C_LINUX:
hdrsize = (int)sizeof (struct i2c_linux_file_hdr);
break;
default:
@ -2504,8 +2505,8 @@ pcap_write_phdr(wtap_dumper *wdh, int encap, const union wtap_pseudo_header *pse
return FALSE;
break;
case WTAP_ENCAP_I2C:
if (!pcap_write_i2c_pseudoheader(wdh, pseudo_header, err))
case WTAP_ENCAP_I2C_LINUX:
if (!pcap_write_i2c_linux_pseudoheader(wdh, pseudo_header, err))
return FALSE;
break;
}

View File

@ -660,8 +660,8 @@ static struct encap_type_info encap_table_base[] = {
/* WTAP_ENCAP_BLUETOOTH_HCI */
{ "bluetooth-hci", "Bluetooth without transport layer" },
/* WTAP_ENCAP_IPMB */
{ "ipmb", "Intelligent Platform Management Bus" },
/* WTAP_ENCAP_IPMB_KONTRON */
{ "ipmb-kontron", "Intelligent Platform Management Bus with Kontron pseudo-header" },
/* WTAP_ENCAP_IEEE802_15_4 */
{ "wpan", "IEEE 802.15.4 Wireless PAN" },
@ -687,8 +687,8 @@ static struct encap_type_info encap_table_base[] = {
/* WTAP_ENCAP_X2E_SERIAL */
{ "x2e-serial", "X2E serial line capture" },
/* WTAP_ENCAP_I2C */
{ "i2c", "I2C" },
/* WTAP_ENCAP_I2C_LINUX */
{ "i2c-linux", "I2C with Linux-specific pseudo-header" },
/* WTAP_ENCAP_IEEE802_15_4_NONASK_PHY */
{ "wpan-nonask-phy", "IEEE 802.15.4 Wireless PAN non-ASK PHY" },

View File

@ -183,7 +183,7 @@ extern "C" {
#define WTAP_ENCAP_SITA 100
#define WTAP_ENCAP_SCCP 101
#define WTAP_ENCAP_BLUETOOTH_HCI 102 /*raw packets without a transport layer header e.g. H4*/
#define WTAP_ENCAP_IPMB 103
#define WTAP_ENCAP_IPMB_KONTRON 103
#define WTAP_ENCAP_IEEE802_15_4 104
#define WTAP_ENCAP_X2E_XORAYA 105
#define WTAP_ENCAP_FLEXRAY 106
@ -192,7 +192,7 @@ extern "C" {
#define WTAP_ENCAP_CAN20B 109
#define WTAP_ENCAP_LAYER1_EVENT 110
#define WTAP_ENCAP_X2E_SERIAL 111
#define WTAP_ENCAP_I2C 112
#define WTAP_ENCAP_I2C_LINUX 112
#define WTAP_ENCAP_IEEE802_15_4_NONASK_PHY 113
#define WTAP_ENCAP_TNEF 114
#define WTAP_ENCAP_USB_LINUX_MMAPPED 115