Skip to content

Commit

Permalink
Fix a few bugs related to PDU export feature:
Browse files Browse the repository at this point in the history
- tag length is wrong if proto name was a multiple of 4 bytes
- tag length is wrong in case no IP address is available in packet_info structwhile tag is requested
- endianness issue when dumping the port number
- overlapping tag IPv4 Dst address and IPv6 Src address
- do not call dissector when it is not found
- typo errors
Enhancements:
- add a subtree for tag content
- display IPv6 Src/Dst address

svn path=/trunk/; revision=49232
  • Loading branch information
pquantin committed May 10, 2013
1 parent 2781606 commit 914099a
Show file tree
Hide file tree
Showing 4 changed files with 95 additions and 60 deletions.
88 changes: 60 additions & 28 deletions epan/dissectors/packet-exported_pdu.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,26 +41,29 @@ static int hf_exported_pdu_tag_len = -1;
static int hf_exported_pdu_prot_name = -1;
static int hf_exported_pdu_ipv4_src = -1;
static int hf_exported_pdu_ipv4_dst = -1;
static int hf_exported_pdu_ipv6_src = -1;
static int hf_exported_pdu_ipv6_dst = -1;
static int hf_exported_pdu_src_port = -1;
static int hf_exported_pdu_dst_port = -1;


/* Initialize the subtree pointers */
static gint ett_exported_pdu = -1;
static gint ett_exported_pdu_tag = -1;

#define EXPORTED_PDU_NEXT_PROTO_STR 0
static const value_string exported_pdu_tag_vals[] = {
{ EXP_PDU_TAG_END_OF_OPT, "End-of-options" },
/* 1 - 9 reserved */
{ EXP_PDU_TAG_OPTIONS_LENGTH, "Total length of the options exluding this TLV" },
{ EXP_PDU_TAG_OPTIONS_LENGTH, "Total length of the options excluding this TLV" },
{ EXP_PDU_TAG_LINKTYPE, "Linktype value" },
{ EXP_PDU_TAG_PROTO_NAME, "PDU content protocol name" },
/* Add protocol type related tags here */
/* 13 - 19 reserved */
{ EXP_PDU_TAG_IPV4_SRC, "IPv4 Source Address" },
{ EXP_PDU_TAG_IPV4_DST, "IPv4 Destination Address" },
{ EXP_PDU_TAG_IPV6_SRC, "IPv6 Source Address" },
{ EXP_PDU_TAG_IPV6_DST, "IPv4 Destination Address" },
{ EXP_PDU_TAG_IPV6_DST, "IPv6 Destination Address" },

{ EXP_PDU_TAG_SRC_PORT, "Source Port" },
{ EXP_PDU_TAG_DST_PORT, "Destination Port" },
Expand All @@ -78,14 +81,15 @@ static void
dissect_exported_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
proto_item *ti;
proto_tree *exported_pdu_tree;
proto_tree *exported_pdu_tree, *tag_tree;
tvbuff_t * payload_tvb = NULL;
int offset = 0;
guint16 tag;
int tag_len;
int next_proto_type = -1;
char *proto_name = NULL;
const guchar *src_addr, *dst_addr;
const guchar *src_addr, *dst_addr;
dissector_handle_t proto_handle;

col_set_str(pinfo->cinfo, COL_PROTOCOL, "Exported PDU");

Expand All @@ -95,46 +99,60 @@ dissect_exported_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
exported_pdu_tree = proto_item_add_subtree(ti, ett_exported_pdu);

tag = tvb_get_ntohs(tvb, offset);
proto_tree_add_item(exported_pdu_tree, hf_exported_pdu_tag, tvb, offset, 2, ENC_BIG_ENDIAN);
ti = proto_tree_add_item(exported_pdu_tree, hf_exported_pdu_tag, tvb, offset, 2, ENC_BIG_ENDIAN);
offset+=2;
proto_tree_add_item(exported_pdu_tree, hf_exported_pdu_tag_len, tvb, offset, 2, ENC_BIG_ENDIAN);
tag_tree = proto_item_add_subtree(ti, ett_exported_pdu_tag);
proto_tree_add_item(tag_tree, hf_exported_pdu_tag_len, tvb, offset, 2, ENC_BIG_ENDIAN);
tag_len = tvb_get_ntohs(tvb, offset);
offset+=2;
while(tag != 0){
switch(tag){
case EXP_PDU_TAG_PROTO_NAME:
next_proto_type = EXPORTED_PDU_NEXT_PROTO_STR;
proto_name = tvb_get_ephemeral_string(tvb, offset, tag_len);
proto_tree_add_item(exported_pdu_tree, hf_exported_pdu_prot_name, tvb, offset, tag_len, ENC_BIG_ENDIAN);
proto_tree_add_item(tag_tree, hf_exported_pdu_prot_name, tvb, offset, tag_len, ENC_ASCII|ENC_NA);
break;
case EXP_PDU_TAG_IPV4_SRC:
proto_tree_add_item(exported_pdu_tree, hf_exported_pdu_ipv4_src, tvb, offset, 4, ENC_BIG_ENDIAN);
src_addr = tvb_get_ptr(tvb, offset, 4);
SET_ADDRESS(&pinfo->net_src, AT_IPv4, 4, src_addr);
SET_ADDRESS(&pinfo->src, AT_IPv4, 4, src_addr);
proto_tree_add_item(tag_tree, hf_exported_pdu_ipv4_src, tvb, offset, 4, ENC_BIG_ENDIAN);
src_addr = tvb_get_ptr(tvb, offset, 4);
SET_ADDRESS(&pinfo->net_src, AT_IPv4, 4, src_addr);
SET_ADDRESS(&pinfo->src, AT_IPv4, 4, src_addr);
break;
case EXP_PDU_TAG_IPV4_DST:
proto_tree_add_item(exported_pdu_tree, hf_exported_pdu_ipv4_dst, tvb, offset, 4, ENC_BIG_ENDIAN);
dst_addr = tvb_get_ptr(tvb, offset, 4);
SET_ADDRESS(&pinfo->net_dst, AT_IPv4, 4, dst_addr);
SET_ADDRESS(&pinfo->dst, AT_IPv4, 4, dst_addr);
proto_tree_add_item(tag_tree, hf_exported_pdu_ipv4_dst, tvb, offset, 4, ENC_BIG_ENDIAN);
dst_addr = tvb_get_ptr(tvb, offset, 4);
SET_ADDRESS(&pinfo->net_dst, AT_IPv4, 4, dst_addr);
SET_ADDRESS(&pinfo->dst, AT_IPv4, 4, dst_addr);
break;
case EXP_PDU_TAG_IPV6_SRC:
proto_tree_add_item(tag_tree, hf_exported_pdu_ipv6_src, tvb, offset, 16, ENC_NA);
src_addr = tvb_get_ptr(tvb, offset, 4);
SET_ADDRESS(&pinfo->net_src, AT_IPv6, 16, src_addr);
SET_ADDRESS(&pinfo->src, AT_IPv6, 16, src_addr);
break;
case EXP_PDU_TAG_IPV6_DST:
proto_tree_add_item(tag_tree, hf_exported_pdu_ipv6_dst, tvb, offset, 16, ENC_NA);
dst_addr = tvb_get_ptr(tvb, offset, 4);
SET_ADDRESS(&pinfo->net_dst, AT_IPv6, 16, dst_addr);
SET_ADDRESS(&pinfo->dst, AT_IPv6, 16, dst_addr);
break;
case EXP_PDU_TAG_SRC_PORT:
proto_tree_add_item(exported_pdu_tree, hf_exported_pdu_src_port, tvb, offset, 4, ENC_BIG_ENDIAN);
pinfo->srcport = tvb_get_ntohl(tvb,offset);
break;
proto_tree_add_item(tag_tree, hf_exported_pdu_src_port, tvb, offset, 4, ENC_BIG_ENDIAN);
pinfo->srcport = tvb_get_ntohl(tvb,offset);
break;
case EXP_PDU_TAG_DST_PORT:
proto_tree_add_item(exported_pdu_tree, hf_exported_pdu_dst_port, tvb, offset, 4, ENC_BIG_ENDIAN);
pinfo->destport = tvb_get_ntohl(tvb,offset);
break;
proto_tree_add_item(tag_tree, hf_exported_pdu_dst_port, tvb, offset, 4, ENC_BIG_ENDIAN);
pinfo->destport = tvb_get_ntohl(tvb,offset);
break;
default:
break;
break;
};
offset = offset + tag_len;
proto_tree_add_item(exported_pdu_tree, hf_exported_pdu_tag, tvb, offset, 2, ENC_BIG_ENDIAN);
ti = proto_tree_add_item(exported_pdu_tree, hf_exported_pdu_tag, tvb, offset, 2, ENC_BIG_ENDIAN);
tag = tvb_get_ntohs(tvb, offset);
offset+=2;
proto_tree_add_item(exported_pdu_tree, hf_exported_pdu_tag_len, tvb, offset, 2, ENC_BIG_ENDIAN);
tag_tree = proto_item_add_subtree(ti, ett_exported_pdu_tag);
proto_tree_add_item(tag_tree, hf_exported_pdu_tag_len, tvb, offset, 2, ENC_BIG_ENDIAN);
tag_len = tvb_get_ntohs(tvb, offset);
offset+=2;
}
Expand All @@ -143,7 +161,10 @@ dissect_exported_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)

switch(next_proto_type){
case EXPORTED_PDU_NEXT_PROTO_STR:
call_dissector(find_dissector(proto_name), payload_tvb, pinfo, tree);
proto_handle = find_dissector(proto_name);
if (proto_handle) {
call_dissector(find_dissector(proto_name), payload_tvb, pinfo, tree);
}
break;
default:
break;
Expand Down Expand Up @@ -177,15 +198,25 @@ proto_register_exported_pdu(void)
NULL, HFILL }
},
{ &hf_exported_pdu_ipv4_src,
{ "IPv4 SRC", "exported_pdu.ipv4_src",
{ "IPv4 Src", "exported_pdu.ipv4_src",
FT_IPv4, BASE_NONE, NULL, 0,
NULL, HFILL }
},
{ &hf_exported_pdu_ipv4_dst,
{ "IPv4 DST", "exported_pdu.ipv4_dst",
{ "IPv4 Dst", "exported_pdu.ipv4_dst",
FT_IPv4, BASE_NONE, NULL, 0,
NULL, HFILL }
},
{ &hf_exported_pdu_ipv6_src,
{ "IPv6 Src", "exported_pdu.ipv6_src",
FT_IPv6, BASE_NONE, NULL, 0,
NULL, HFILL }
},
{ &hf_exported_pdu_ipv6_dst,
{ "IPv6 Dst", "exported_pdu.ipv6_dst",
FT_IPv6, BASE_NONE, NULL, 0,
NULL, HFILL }
},
{ &hf_exported_pdu_src_port,
{ "Src Port", "exported_pdu.src_port",
FT_UINT16, BASE_DEC, NULL, 0,
Expand All @@ -200,7 +231,8 @@ proto_register_exported_pdu(void)

/* Setup protocol subtree array */
static gint *ett[] = {
&ett_exported_pdu
&ett_exported_pdu,
&ett_exported_pdu_tag
};

/* Register the protocol name and description */
Expand Down
29 changes: 16 additions & 13 deletions epan/exported_pdu.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@
#include <epan/exported_pdu.h>

/**
* Allcotates and fills the exp_pdu_data_t struct according to the wanted_exp_tags
* bit_fileld, if proto_name is != NULL, wtap_encap must be -1 or viceversa
* Allocates and fills the exp_pdu_data_t struct according to the wanted_exp_tags
* bit_fileld, if proto_name is != NULL, wtap_encap must be -1 or vice-versa
*/
exp_pdu_data_t *
load_export_pdu_tags(packet_info *pinfo, const char* proto_name, int wtap_encap _U_, guint32 tags_bit_field)
Expand All @@ -45,19 +45,16 @@ load_export_pdu_tags(packet_info *pinfo, const char* proto_name, int wtap_encap

exp_pdu_data = (exp_pdu_data_t *)g_malloc(sizeof(exp_pdu_data_t));

/* If we have a protocol name, calculate the buffersize needed including padding and tag + length */
/* If we have a protocol name, calculate the buffer size needed including padding and tag + length */
if(proto_name){
str_len = (int)strlen(proto_name);

/* Add padding if needed */
if(str_len % 4){
tag_str_len = str_len + (4 - str_len % 4);
}
/* Ensure that tag length is a multiple of 4 bytes */
tag_str_len = (str_len + 3) & 0xfffffffc;
/* Add Tag + length */
tag_buf_size = tag_str_len + 4;
}


if((tags_bit_field & EXP_PDU_TAG_IP_SRC_BIT) == EXP_PDU_TAG_IP_SRC_BIT){
/* tag+length */
tag_buf_size+=4;
Expand All @@ -71,7 +68,7 @@ load_export_pdu_tags(packet_info *pinfo, const char* proto_name, int wtap_encap
if((tags_bit_field & EXP_PDU_TAG_IP_DST_BIT) == EXP_PDU_TAG_IP_DST_BIT){
/* tag+length */
tag_buf_size+=4;
if(pinfo->net_src.type == AT_IPv4){
if(pinfo->net_dst.type == AT_IPv4){
tag_buf_size = tag_buf_size + EXP_PDU_TAG_IPV4_DST_LEN;
}else{
tag_buf_size = tag_buf_size + EXP_PDU_TAG_IPV6_DST_LEN;
Expand Down Expand Up @@ -128,7 +125,7 @@ load_export_pdu_tags(packet_info *pinfo, const char* proto_name, int wtap_encap
}

memcpy(exp_pdu_data->tlv_buffer+i, pinfo->net_src.data, pinfo->net_src.len);
i = i + pinfo->net_src.len;
i += (pinfo->net_src.type == AT_IPv4) ? EXP_PDU_TAG_IPV4_SRC_LEN : EXP_PDU_TAG_IPV6_SRC_LEN;
}

if((tags_bit_field & EXP_PDU_TAG_IP_DST_BIT) == EXP_PDU_TAG_IP_DST_BIT){
Expand All @@ -153,7 +150,7 @@ load_export_pdu_tags(packet_info *pinfo, const char* proto_name, int wtap_encap
}

memcpy(exp_pdu_data->tlv_buffer+i, pinfo->net_dst.data, pinfo->net_dst.len);
i = i + pinfo->net_src.len;
i += (pinfo->net_dst.type == AT_IPv4) ? EXP_PDU_TAG_IPV4_DST_LEN : EXP_PDU_TAG_IPV6_DST_LEN;
}

if((tags_bit_field & EXP_PDU_TAG_SRC_PORT_BIT) == EXP_PDU_TAG_SRC_PORT_BIT){
Expand All @@ -165,7 +162,10 @@ load_export_pdu_tags(packet_info *pinfo, const char* proto_name, int wtap_encap
i++;
exp_pdu_data->tlv_buffer[i] = EXP_PDU_TAG_SRC_PORT_LEN; /* tag length */
i++;
memcpy(exp_pdu_data->tlv_buffer+i, &pinfo->srcport, EXP_PDU_TAG_SRC_PORT_LEN);
exp_pdu_data->tlv_buffer[i] = (pinfo->srcport & 0xff000000) >> 24;
exp_pdu_data->tlv_buffer[i+1] = (pinfo->srcport & 0x00ff0000) >> 16;
exp_pdu_data->tlv_buffer[i+2] = (pinfo->srcport & 0x0000ff00) >> 8;
exp_pdu_data->tlv_buffer[i+3] = (pinfo->srcport & 0x000000ff);
i = i +EXP_PDU_TAG_SRC_PORT_LEN;
}

Expand All @@ -178,7 +178,10 @@ load_export_pdu_tags(packet_info *pinfo, const char* proto_name, int wtap_encap
i++;
exp_pdu_data->tlv_buffer[i] = EXP_PDU_TAG_DST_PORT_LEN; /* tag length */
i++;
memcpy(exp_pdu_data->tlv_buffer+i, &pinfo->destport, EXP_PDU_TAG_DST_PORT_LEN);
exp_pdu_data->tlv_buffer[i] = (pinfo->destport & 0xff000000) >> 24;
exp_pdu_data->tlv_buffer[i+1] = (pinfo->destport & 0x00ff0000) >> 16;
exp_pdu_data->tlv_buffer[i+2] = (pinfo->destport & 0x0000ff00) >> 8;
exp_pdu_data->tlv_buffer[i+3] = (pinfo->destport & 0x000000ff);
i = i +EXP_PDU_TAG_DST_PORT_LEN;
}

Expand Down
24 changes: 12 additions & 12 deletions epan/exported_pdu.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
/**
* This struct is used as the data part of tap_queue_packet() and contains a
* buffer with metadata of the protocol PDU included in the tvb in the struct.
* the meta data is in TLV form, at least one tag MUST indicat what protocol is
* the meta data is in TLV form, at least one tag MUST indicate what protocol is
* in the PDU.
* Buffer layout:
* 0 1 2 3
Expand All @@ -53,7 +53,7 @@
/* Tag values */
#define EXP_PDU_TAG_END_OF_OPT 0 /**< End-of-options Tag. */
/* 1 - 9 reserved */
#define EXP_PDU_TAG_OPTIONS_LENGTH 10 /**< Total length of the options exluding this TLV */
#define EXP_PDU_TAG_OPTIONS_LENGTH 10 /**< Total length of the options excluding this TLV */
#define EXP_PDU_TAG_LINKTYPE 11 /**< The value part is the linktype value defined by tcpdump
* http://www.tcpdump.org/linktypes.html
*/
Expand All @@ -65,16 +65,16 @@
/* 13 - 19 reserved */
#define EXP_PDU_TAG_IPV4_SRC 20
#define EXP_PDU_TAG_IPV4_DST 21
#define EXP_PDU_TAG_IPV6_SRC 21
#define EXP_PDU_TAG_IPV6_DST 22
#define EXP_PDU_TAG_IPV6_SRC 22
#define EXP_PDU_TAG_IPV6_DST 23

#define EXP_PDU_TAG_SRC_PORT 23
#define EXP_PDU_TAG_DST_PORT 24
#define EXP_PDU_TAG_SRC_PORT 24
#define EXP_PDU_TAG_DST_PORT 25

#define EXP_PDU_TAG_SCTP_PPID 25
#define EXP_PDU_TAG_SCTP_PPID 26

#define EXP_PDU_TAG_SS7_OPC 26
#define EXP_PDU_TAG_SS7_DPC 27
#define EXP_PDU_TAG_SS7_OPC 27
#define EXP_PDU_TAG_SS7_DPC 28


typedef struct _exp_pdu_data_t {
Expand Down Expand Up @@ -109,8 +109,8 @@ typedef struct _exp_pdu_data_t {
#define EXP_PDU_TAG_SS7_DPC_LEN 2

/**
* Allcotates and fills the exp_pdu_data_t struct according to the wanted_exp_tags
* bit_fileld, if proto_name is != NULL, wtap_encap must be -1 or viceversa
* Allocates and fills the exp_pdu_data_t struct according to the wanted_exp_tags
* bit_fileld, if proto_name is != NULL, wtap_encap must be -1 or vice-versa
*/
WS_DLL_PUBLIC exp_pdu_data_t *load_export_pdu_tags(packet_info *pinfo,
const char* proto_name, int wtap_encap, guint32 wanted_exp_tags);
const char* proto_name, int wtap_encap, guint32 wanted_exp_tags);
14 changes: 7 additions & 7 deletions ui/gtk/export_pdu_dlg.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,19 +78,19 @@ export_pdu_packet(void *tapdata, packet_info *pinfo, epan_dissect_t *edt _U_, co
pkthdr.pkt_encap = exp_pdu_tap_data->pkt_encap;
pkthdr.interface_id = 0;
pkthdr.presence_flags = 0;
if(pinfo->fd->opt_comment == NULL){
pkthdr.opt_comment = NULL;
}else{
pkthdr.opt_comment = g_strdup(pinfo->fd->opt_comment);
}
if(pinfo->fd->opt_comment == NULL){
pkthdr.opt_comment = NULL;
}else{
pkthdr.opt_comment = g_strdup(pinfo->fd->opt_comment);
}
pkthdr.drop_count = 0;
pkthdr.pack_flags = 0;
pkthdr.presence_flags = WTAP_HAS_CAP_LEN|WTAP_HAS_INTERFACE_ID|WTAP_HAS_TS|WTAP_HAS_PACK_FLAGS;

wtap_dump(exp_pdu_tap_data->wdh, &pkthdr, packet_buf, &err);

g_free(packet_buf);
g_free(pkthdr.opt_comment);
g_free(pkthdr.opt_comment);

return FALSE; /* Do not redraw */
}
Expand Down Expand Up @@ -270,7 +270,7 @@ export_pdu_show_cb(GtkWidget *w _U_, gpointer d _U_)
gtk_box_pack_start(GTK_BOX(main_vb), grid, TRUE, TRUE, 0);
row = 0;

label = gtk_label_new("Add a droptown list to select USER_DLT, currently hardcoded to USER10");
label = gtk_label_new("Add a drop-down list to select USER_DLT, currently hardcoded to USER10");
ws_gtk_grid_attach_defaults(GTK_GRID(grid), label, 0, row, 1, 1);

/* Setup the button row */
Expand Down

0 comments on commit 914099a

Please sign in to comment.