Wireshark-dev: [Wireshark-dev] [PATCH] New Type : ISIS LSPID
From: Sebastien Tandel <sebastien@xxxxxxxxx>
Date: Sun, 10 Dec 2006 04:02:51 +0100
Hi all, I am working on a stat module for ISIS and I create a new type, FT_LSPID. Here is a patch made against the revision 20088. Now, you can : - define an hf field with FT_LSPID type - use proto_tree_add_item or proto_tree_add_lspid with FT_LSPID - use lspid_to_str instead of print_system_id (which does not take an additional length parameter) I will send the patch with all the changes in dissectors/packet-isis-* tomorrow. thanx, Sebastien Tandel
Index: doc/README.developer =================================================================== --- doc/README.developer (révision 20088) +++ doc/README.developer (copie de travail) @@ -956,7 +956,7 @@ FT_UINT32, FT_UINT64, FT_INT8, FT_INT16, FT_INT24, FT_INT32, FT_INT64, FT_FLOAT, FT_DOUBLE, FT_ABSOLUTE_TIME, FT_RELATIVE_TIME, FT_STRING, FT_STRINGZ, FT_UINT_STRING, - FT_ETHER, FT_BYTES, FT_IPv4, FT_IPv6, FT_IPXNET, + FT_ETHER, FT_BYTES, FT_IPv4, FT_IPv6, FT_IPXNET, FT_LSPID FT_FRAMENUM, FT_PROTOCOL, FT_GUID, FT_OID FIELDBASE BASE_NONE, BASE_DEC, BASE_HEX, BASE_OCT, BASE_DEC_HEX, BASE_HEX_DEC FIELDCONVERT VALS(x), TFS(x), NULL @@ -1486,6 +1486,7 @@ specified number of characters. FT_ETHER A six octet string displayed in Ethernet-address format. + FT_LSPID A eight octet string displayed in LSPID format FT_BYTES A string of bytes with arbitrary values; used for raw binary data. FT_IPv4 A version 4 IP address (4 bytes) displayed Index: epan/dfilter/semcheck.c =================================================================== --- epan/dfilter/semcheck.c (révision 20088) +++ epan/dfilter/semcheck.c (copie de travail) @@ -70,6 +70,7 @@ case FT_IPXNET: case FT_INT64: /* XXX - should be able to compare with INT */ case FT_UINT64: /* XXX - should be able to compare with INT */ + case FT_LSPID: return a == b; case FT_ETHER: @@ -170,6 +171,7 @@ case FT_PCRE: case FT_GUID: case FT_OID: + case FT_LSPID: return FALSE; case FT_BOOLEAN: @@ -241,6 +243,7 @@ case FT_IPv6: case FT_GUID: case FT_OID: + case FT_LSPID: return TRUE; case FT_NONE: Index: epan/ftypes/ftype-bytes.c =================================================================== --- epan/ftypes/ftype-bytes.c (révision 20088) +++ epan/ftypes/ftype-bytes.c (copie de travail) @@ -39,6 +39,7 @@ #define ETHER_LEN 6 #define IPv6_LEN 16 +#define LSPID_LEN 8 static void bytes_fvalue_new(fvalue_t *fv) @@ -134,6 +135,13 @@ } static void +lspid_fvalue_set(fvalue_t *fv, gpointer value, gboolean already_copied) +{ + g_assert(!already_copied); + common_fvalue_set(fv, value, LSPID_LEN); +} + +static void ipv6_fvalue_set(fvalue_t *fv, gpointer value, gboolean already_copied) { g_assert(!already_copied); @@ -236,6 +244,23 @@ } static gboolean +lspid_from_unparsed(fvalue_t *fv, char *s, gboolean allow_partial_value _U_, LogFunc logfunc) +{ + if (bytes_from_unparsed(fv, s, TRUE, NULL)) { + if (fv->value.bytes->len > LSPID_LEN) { + logfunc("\"%s\" contains too many bytes to be a valid LSPID.", s); + return FALSE; + } + else if (fv->value.bytes->len < LSPID_LEN && ! allow_partial_value) { + logfunc("\"%s\" contains too few bytes to be a valid LSPID.", s); + return FALSE; + } + return TRUE; + } + +} + +static gboolean ipv6_from_unparsed(fvalue_t *fv, char *s, gboolean allow_partial_value _U_, LogFunc logfunc) { guint8 buffer[16]; @@ -264,6 +289,20 @@ ip6_to_str_buf((struct e_in6_addr *)fv->value.bytes->data, buf); } +static int +lspid_repr_len(fvalue_t *fv _U_, ftrepr_t rtype _U_) +{ + /* + * 39 characters for "XXXX.XXXX.XXXX.XX-XX". + */ + return 20; +} + +static void lspid_to_repr(fvalue_t *fv, ftrepr_t rtype _U_, char *buf) +{ + lspid_to_str_buf(fv->value.bytes->data, buf); +} + static gboolean oid_from_unparsed(fvalue_t *fv, char *s, gboolean allow_partial_value _U_, LogFunc logfunc) { @@ -595,6 +634,43 @@ slice, }; + static ftype_t lspid_type = { + FT_LSPID, /* ftype */ + "FT_LSPID", /* name */ + "ISIS LSP id", /* pretty_name */ + LSPID_LEN, /* wire_size */ + bytes_fvalue_new, /* new_value */ + bytes_fvalue_free, /* free_value */ + lspid_from_unparsed, /* val_from_unparsed */ + NULL, /* val_from_string */ + lspid_to_repr, /* val_to_string_repr */ + lspid_repr_len, /* len_string_repr */ + + lspid_fvalue_set, /* set_value */ + NULL, /* set_value_integer */ + NULL, /* set_value_integer64 */ + NULL, /* set_value_floating */ + + value_get, /* get_value */ + NULL, /* get_value_integer */ + NULL, /* get_value_integer64 */ + NULL, /* get_value_floating */ + + cmp_eq, + cmp_ne, + cmp_gt, + cmp_ge, + cmp_lt, + cmp_le, + cmp_bytes_bitwise_and, + cmp_contains, + NULL, /* cmp_matches */ + + len, + slice, + }; + + static ftype_t ipv6_type = { FT_IPv6, /* ftype */ "FT_IPv6", /* name */ @@ -672,4 +748,5 @@ ftype_register(FT_ETHER, ðer_type); ftype_register(FT_IPv6, &ipv6_type); ftype_register(FT_OID, &oid_type); + ftype_register(FT_LSPID, &lspid_type); } Index: epan/ftypes/ftypes.h =================================================================== --- epan/ftypes/ftypes.h (révision 20088) +++ epan/ftypes/ftypes.h (copie de travail) @@ -62,6 +62,7 @@ FT_PCRE, /* a compiled Perl-Compatible Regular Expression object */ FT_GUID, /* GUID, UUID */ FT_OID, /* OBJECT IDENTIFIER */ + FT_LSPID, FT_NUM_TYPES /* last item number plus one */ }; Index: epan/proto.c =================================================================== --- epan/proto.c (révision 20088) +++ epan/proto.c (copie de travail) @@ -142,7 +142,11 @@ proto_tree_set_ether(field_info *fi, const guint8* value); static void proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, gint start); +static void +proto_tree_set_lspid(field_info *fi, const guint8 *value); static void +proto_tree_set_lspid_tvb(field_info *fi, tvbuff_t *tvb, gint start); +static void proto_tree_set_ipxnet(field_info *fi, guint32 value); static void proto_tree_set_ipv4(field_info *fi, guint32 value); @@ -900,6 +904,11 @@ proto_tree_set_ether_tvb(new_fi, tvb, start); break; + case FT_LSPID: + DISSECTOR_ASSERT(length==8); + proto_tree_set_lspid_tvb(new_fi, tvb, start); + break; + case FT_GUID: DISSECTOR_ASSERT(length == 16); proto_tree_set_guid_tvb(new_fi, tvb, start, little_endian); @@ -1982,6 +1991,30 @@ proto_tree_set_string(fi, string, TRUE); } +/* Add a FT_LSPID to a proto_tree */ +proto_item * +proto_tree_add_lspid(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length, + const guint8* value) +{ + proto_item *pi; + field_info *new_fi; + header_field_info *hfinfo; + + if (!tree) + return (NULL); + + TRY_TO_FAKE_THIS_ITEM(tree, hfindex); + + PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo); + DISSECTOR_ASSERT(hfinfo->type == FT_LSPID); + + pi = proto_tree_add_pi(tree, hfindex, tvb, start, &length, &new_fi); + proto_tree_set_lspid(new_fi, value); + + return pi; + +} + /* Add a FT_ETHER to a proto_tree */ proto_item * proto_tree_add_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length, @@ -2057,6 +2090,13 @@ return pi; } +/* Set the FT_LSPID value */ +static void +proto_tree_set_lspid(field_info *fi, const guint8* value) +{ + fvalue_set(&fi->value, (gpointer) value, FALSE); +} + /* Set the FT_ETHER value */ static void proto_tree_set_ether(field_info *fi, const guint8* value) @@ -2065,6 +2105,12 @@ } static void +proto_tree_set_lspid_tvb(field_info *fi, tvbuff_t *tvb, gint start) +{ + proto_tree_set_lspid(fi, tvb_get_ptr(tvb, start, 8)); +} + +static void proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, gint start) { proto_tree_set_ether(fi, tvb_get_ptr(tvb, start, 6)); @@ -3834,6 +3880,15 @@ label_str[ITEM_LABEL_LENGTH - 1] = '\0'; break; + case FT_LSPID: + bytes = fvalue_get(&fi->value); + ret = g_snprintf(label_str, ITEM_LABEL_LENGTH, + "%s: %s", hfinfo->name, + lspid_to_str(bytes)); + if ((ret == -1) || (ret >= ITEM_LABEL_LENGTH)) + label_str[ITEM_LABEL_LENGTH - 1] = '\0'; + break; + case FT_IPv4: ipv4 = fvalue_get(&fi->value); n_addr = ipv4_get_net_order_addr(ipv4); Index: epan/proto.h =================================================================== --- epan/proto.h (révision 20088) +++ epan/proto.h (copie de travail) @@ -773,6 +773,18 @@ proto_tree_add_ipv6_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length, const guint8* value_ptr, const char *format, ...) GNUC_FORMAT_CHECK(printf,7,8); +/** Add a FT_LSPID to a proto_tree. + @param tree the tree to append this item to + @param hfindex field index + @param tvb the tv buffer of the current data + @param start start of data in tvb + @param length length of data in tvb + @param value data to display + @return the newly created item */ +proto_item * +proto_tree_add_lspid(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length, + const guint8* value); + /** Add a FT_ETHER to a proto_tree. @param tree the tree to append this item to @param hfindex field index Index: epan/to_str.c =================================================================== --- epan/to_str.c (révision 20088) +++ epan/to_str.c (copie de travail) @@ -140,6 +140,7 @@ return buf; } + /* This function is very fast and this function is called a lot. XXX update the address_to_str stuff to use this function. @@ -236,6 +237,32 @@ inet_ntop(AF_INET6, (const guchar*)ad, buf, INET6_ADDRSTRLEN); } +gchar * +lspid_to_str(const guint8 *lspid){ + gchar *cur; + guint8 cur_len; + + cur_len = MAX_SYSTEMID_LEN * 3 + 5; + cur = ep_alloc(cur_len); + + g_snprintf(cur, cur_len, "%02x%02x.%02x%02x.%02x%02x.%02x-%02x", + lspid[0], lspid[1], lspid[2], lspid[3], + lspid[4], lspid[5], lspid[6], lspid[7]); + + return cur; +} + +void lspid_to_str_buf(const guint8* lspid, gchar *buf) +{ + if (buf == NULL) + return; + + g_snprintf(buf, MAX_SYSTEMID_LEN * 3 + 5, "%02x%02x.%02x%02x.%02x%02x.%02x-%02x", + lspid[0], lspid[1], lspid[2], lspid[3], + lspid[4], lspid[5], lspid[6], lspid[7]); +} + + gchar* ipx_addr_to_str(guint32 net, const guint8 *ad) { Index: epan/to_str.h =================================================================== --- epan/to_str.h (révision 20088) +++ epan/to_str.h (copie de travail) @@ -56,6 +56,8 @@ extern void address_to_str_buf(const address *addr, gchar *buf, int buf_len); extern gchar* bytestring_to_str(const guint8 *, guint32, char); extern gchar* ether_to_str(const guint8 *); +extern gchar* lspid_to_str(const guint8 *); +extern void lspid_to_str_buf(const guint8* lspid, gchar *buf); extern gchar* ip_to_str(const guint8 *); extern void ip_to_str_buf(const guint8 *, gchar *); extern gchar* fc_to_str(const guint8 *);
- Follow-Ups:
- Re: [Wireshark-dev] [PATCH] New Type : ISIS LSPID
- From: Stephen Fisher
- Re: [Wireshark-dev] [PATCH] New Type : ISIS LSPID
- Prev by Date: [Wireshark-dev] [PATCH] ieee80211 integer overflow
- Next by Date: [Wireshark-dev] [PATCH] ISIS dissector
- Previous by thread: Re: [Wireshark-dev] [PATCH] ieee80211 integer overflow
- Next by thread: Re: [Wireshark-dev] [PATCH] New Type : ISIS LSPID
- Index(es):