summaryrefslogtreecommitdiff
path: root/cpack.c
diff options
context:
space:
mode:
authorDenis Ovsienko <infrastation@yandex.ru>2013-04-28 17:20:28 +0400
committerDenis Ovsienko <infrastation@yandex.ru>2013-04-28 18:26:53 +0400
commitb766ec9d3be6d4103a510ffb18d6497df1e50dc8 (patch)
tree503280d4fbcf57c01f1f16807cd429f379e8e73a /cpack.c
parent3e3cc1fce3f6573695f13227f027efc22b4fb8af (diff)
downloadtcpdump-b766ec9d3be6d4103a510ffb18d6497df1e50dc8.tar.gz
fix bug #303 (DLT_IEEE802_11_RADIO ext. bitmaps)
This bug was discovered and pinned down by Wim Torfs. The code in question handles DLT_IEEE802_11_RADIO datalink type, which consists of a variable-sized header, a variable number of fields and the actual 802.11 frame. The integers contained in the fields are aligned, properly extracting them is exactly the purpose of the existing "cpack" module. The issue with the current code is that it sets alignment base for cpack at the end of the variable-sized header, in other words, 64-bit integers would be properly extracted only so long as the header is 64-bit long, which only happens when the total number of bitmaps in it is odd (the minimum number of bitmaps is one). Once this condition isn't met, as is with two bitmaps, decoding becomes incorrect. The reporter's point that the alignment base must be the beginning of the variable-sized header is accurate. This commit adds a new cpack_advance() function to fast-forward the "c_next" pointer of a cpack_state context by an arbitrary number of octets. The ieee802_11_radio_print() function now uses it to skip the header and all its bitmaps, and the alignment base is now the header start.
Diffstat (limited to 'cpack.c')
-rw-r--r--cpack.c11
1 files changed, 11 insertions, 0 deletions
diff --git a/cpack.c b/cpack.c
index c921b390..b863d8e7 100644
--- a/cpack.c
+++ b/cpack.c
@@ -68,6 +68,17 @@ cpack_align_and_reserve(struct cpack_state *cs, size_t wordsize)
return next;
}
+/* Advance by N bytes without returning them. */
+int
+cpack_advance(struct cpack_state *cs, const size_t toskip)
+{
+ /* No space left? */
+ if (cs->c_next - cs->c_buf + toskip > cs->c_len)
+ return -1;
+ cs->c_next += toskip;
+ return 0;
+}
+
int
cpack_init(struct cpack_state *cs, u_int8_t *buf, size_t buflen)
{