aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/README.developer7
-rw-r--r--epan/tvbuff.c68
-rw-r--r--epan/tvbuff.h3
3 files changed, 78 insertions, 0 deletions
diff --git a/doc/README.developer b/doc/README.developer
index 8f6c99d788..ed1c2ad921 100644
--- a/doc/README.developer
+++ b/doc/README.developer
@@ -1266,6 +1266,7 @@ file is opened.
guint8 *tvb_get_stringz(tvbuff_t *tvb, gint offset, gint *lengthp);
guint8 *tvb_get_ephemeral_stringz(tvbuff_t *tvb, gint offset, gint *lengthp);
+gchar *tvb_get_ephemeral_unicode_stringz(tvbuff_t *tvb, const gint offset, gint *lengthp, const guint encoding);
guint8 *tvb_get_seasonal_stringz(tvbuff_t *tvb, gint offset, gint *lengthp);
Returns a null-terminated buffer, allocated with "g_malloc()",
@@ -1277,11 +1278,17 @@ will be set to the length of the string, including the terminating null.
tvb_get_stringz() returns a buffer allocated by g_malloc() so you must
g_free() it when you are finished with the string. Failure to g_free() this
buffer will lead to memory leaks.
+
tvb_get_ephemeral_stringz() returns a buffer allocated from a special heap
with a lifetime until the next packet is dissected. You do not need to
free() this buffer, it will happen automatically once the next packet is
dissected.
+tvb_get_ephemeral_unicode_stringz() is a unicode (UTF-16) version of
+above. This is intended for reading UTF-16 unicode strings out of a tvbuff
+and returning them as a UTF-8 string for use in Wireshark. The offset and
+returned length pointer are in bytes, not UTF-16 characters.
+
tvb_get_seasonal_stringz() returns a buffer allocated from a special heap
with a lifetime of the current capture session. You do not need to
free() this buffer, it will happen automatically once the a new capture or
diff --git a/epan/tvbuff.c b/epan/tvbuff.c
index 29ab888fa0..c6bec158f4 100644
--- a/epan/tvbuff.c
+++ b/epan/tvbuff.c
@@ -1949,6 +1949,25 @@ tvb_strsize(tvbuff_t *tvb, const gint offset)
return (nul_offset - abs_offset) + 1;
}
+/* Unicode (UTF-16) version of tvb_strsize */
+/* Returns number of *UTF-16 characters* (not bytes) excluding the null terminator */
+guint
+tvb_unicode_strsize(tvbuff_t *tvb, const gint offset)
+{
+ guint i = 0;
+ gunichar2 uchar;
+
+ DISSECTOR_ASSERT(tvb && tvb->initialized);
+
+ do {
+ /* Endianness doesn't matter when looking for null */
+ uchar = tvb_get_ntohs(tvb, offset + i);
+ i += 2;
+ } while(uchar != 0);
+
+ return i;
+}
+
/* Find length of string by looking for end of string ('\0'), up to
* 'maxlength' characters'; if 'maxlength' is -1, searches to end
* of tvbuff.
@@ -2345,6 +2364,55 @@ tvb_get_ephemeral_stringz(tvbuff_t *tvb, const gint offset, gint *lengthp)
}
/*
+ * Unicode (UTF-16) version of tvb_get_ephemeral_stringz()
+ *
+ * Encoding paramter should be ENC_BIG_ENDIAN or ENC_LITTLE_ENDIAN
+ *
+ * Returns an ep_ allocated UTF-8 string
+ */
+gchar *
+tvb_get_ephemeral_unicode_stringz(tvbuff_t *tvb, const gint offset, gint *lengthp, const guint encoding)
+{
+ gchar *tmpbuf = NULL;
+ gunichar2 uchar;
+ gint size; /* Number of UTF-16 characters */
+ gint i; /* Byte counter for tvbuff */
+ gint tmpbuf_len;
+ emem_strbuf_t *strbuf = NULL;
+
+ strbuf = ep_strbuf_new(NULL);
+
+ size = tvb_unicode_strsize(tvb, offset);
+
+ for(i = 0; i < size; i += 2) { /* XXX - make <= ??? */
+
+ if(encoding == ENC_BIG_ENDIAN)
+ uchar = tvb_get_ntohs(tvb, offset + i);
+ else
+ uchar = tvb_get_letohs(tvb, offset + i);
+
+ /* Calculate how much space is needed to store UTF-16 character in UTF-8 */
+ tmpbuf_len = g_unichar_to_utf8(uchar, NULL);
+
+ tmpbuf = g_malloc(tmpbuf_len + 1); /* + 1 to make room for null terminator */
+
+ g_unichar_to_utf8(uchar, tmpbuf);
+
+ /* NULL terminate the tmpbuf so ep_strbuf_append knows where to stop */
+ tmpbuf[tmpbuf_len] = '\0';
+
+ ep_strbuf_append(strbuf, tmpbuf);
+
+ g_free(tmpbuf);
+ }
+
+ if(lengthp)
+ *lengthp = i;
+
+ return strbuf->str;
+}
+
+/*
* Given a tvbuff and an offset, with the offset assumed to refer to
* a null-terminated string, find the length of that string (and throw
* an exception if the tvbuff ends before we find the null), allocate
diff --git a/epan/tvbuff.h b/epan/tvbuff.h
index 8d5b443eb1..d4e76230a9 100644
--- a/epan/tvbuff.h
+++ b/epan/tvbuff.h
@@ -515,12 +515,15 @@ extern guint8 *tvb_get_seasonal_string(tvbuff_t *tvb, const gint offset, const g
* instead it will automatically be freed once the next
* packet is dissected.
*
+ * tvb_get_ephemeral_unicode_stringz() Unicode (UTF-16) version of above
+ *
* tvb_get_seasonal_stringz() returns a string that does not need to be freed,
* instead it will automatically be freed when a new capture
* or file is opened.
*/
extern guint8 *tvb_get_stringz(tvbuff_t *tvb, const gint offset, gint *lengthp);
extern guint8 *tvb_get_ephemeral_stringz(tvbuff_t *tvb, const gint offset, gint *lengthp);
+extern gchar *tvb_get_ephemeral_unicode_stringz(tvbuff_t *tvb, const gint offset, gint *lengthp, const guint encoding);
extern guint8 *tvb_get_seasonal_stringz(tvbuff_t *tvb, const gint offset, gint *lengthp);
/** Looks for a stringz (NUL-terminated string) in tvbuff and copies