zoukankan      html  css  js  c++  java
  • Wireshark lua dissector 对TCP消息包合并分析

    应用程序发送的数据报都是流式的,IP不保证同一个一个应用数据包会被抓包后在同一个IP数据包中,因此对于使用自制dissector的时候需要考虑这种情况。

    Lua Dissector相关资料可以见:http://wiki.wireshark.org/Lua/Dissectors

    Lua脚本书写wireshark dissector非常方便,使用Lua合并tcp数据报进行分析的样例如下,其实就是多了一个条件分支,所谓难者不会,会者不难:

     1 local slicer = Proto("slicer","Slicer")
     2 function slicer.dissector(tvb, pinfo, tree)
     3     local offset = pinfo.desegment_offset or 0
     4 
     5     local len = get_len() -- for tests i used a constant, but can be taken from tvb
     6 
     7     while true do
     8         local nxtpdu = offset + len
     9 
    10         if nxtpdu > tvb:len() then
    11             pinfo.desegment_len = nxtpdu - tvb:len()
    12             pinfo.desegment_offset = offset
    13             return
    14         end
    15 
    16         tree:add(slicer, tvb(offset, len))
    17 
    18         offset = nxtpdu
    19 
    20         if nxtpdu == tvb:len() then
    21              return
    22         end
    23     end
    24 end
    25 local tcp_table = DissectorTable.get("tcp.port")
    26 tcp_table:add(2506, slicer)

    对于Lua Dissector脚本使用方法如下:

    tshark

    tshark -X lua_script:slicer.lua -i lo0 -f "tcp port 2506" -O aa -V

    Wireshark

    On OSX

    Copy slicer.lua to ~/.wireshark

    Add dofile(USER_DIR.."slicer.lua") to the end of /Applications/Wireshark.app/Contents/Resources/share/wireshark/init.lua

    在wireshark的C语言版本中,有针对tcp合并报的相关函数,packet-tcp.c 具体见下:

    /*
    2152     * Loop for dissecting PDUs within a TCP stream; assumes that a PDU
    2153     * consists of a fixed-length chunk of data that contains enough information
    2154     * to determine the length of the PDU, followed by rest of the PDU.
    2155     *
    2156     * The first three arguments are the arguments passed to the dissector
    2157     * that calls this routine.
    2158     *
    2159     * "proto_desegment" is the dissector's flag controlling whether it should
    2160     * desegment PDUs that cross TCP segment boundaries.
    2161     *
    2162     * "fixed_len" is the length of the fixed-length part of the PDU.
    2163     *
    2164     * "get_pdu_len()" is a routine called to get the length of the PDU from
    2165     * the fixed-length part of the PDU; it's passed "pinfo", "tvb" and "offset".
    2166     *
    2167     * "dissect_pdu()" is the routine to dissect a PDU.
    2168     */
    2169    void
    2170    tcp_dissect_pdus(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
    2171                     gboolean proto_desegment, guint fixed_len,
    2172                     guint (*get_pdu_len)(packet_info *, tvbuff_t *, int),
    2173                     dissector_t dissect_pdu)
    2174    {
    2175        volatile int offset = 0;
    2176        int offset_before;
    2177        guint length_remaining;
    2178        guint plen;
    2179        guint length;
    2180        tvbuff_t *next_tvb;
    2181        proto_item *item=NULL;
    2182        void *pd_save;
    2183    
    2184        while (tvb_reported_length_remaining(tvb, offset) != 0) {
    2185            /*
    2186             * We use "tvb_ensure_length_remaining()" to make sure there actually
    2187             * *is* data remaining.  The protocol we're handling could conceivably
    2188             * consists of a sequence of fixed-length PDUs, and therefore the
    2189             * "get_pdu_len" routine might not actually fetch anything from
    2190             * the tvbuff, and thus might not cause an exception to be thrown if
    2191             * we've run past the end of the tvbuff.
    2192             *
    2193             * This means we're guaranteed that "length_remaining" is positive.
    2194             */
    2195            length_remaining = tvb_ensure_length_remaining(tvb, offset);
    2196    
    2197            /*
    2198             * Can we do reassembly?
    2199             */
    2200            if (proto_desegment && pinfo->can_desegment) {
    2201                /*
    2202                 * Yes - is the fixed-length part of the PDU split across segment
    2203                 * boundaries?
    2204                 */
    2205                if (length_remaining < fixed_len) {
    2206                    /*
    2207                     * Yes.  Tell the TCP dissector where the data for this message
    2208                     * starts in the data it handed us and that we need "some more
    2209                     * data."  Don't tell it exactly how many bytes we need because
    2210                     * if/when we ask for even more (after the header) that will
    2211                     * break reassembly.
    2212                     */
    2213                    pinfo->desegment_offset = offset;
    2214                    pinfo->desegment_len = DESEGMENT_ONE_MORE_SEGMENT;
    2215                    return;
    2216                }
    2217            }
    2218    
    2219            /*
    2220             * Get the length of the PDU.
    2221             */
    2222            plen = (*get_pdu_len)(pinfo, tvb, offset);
    2223            if (plen < fixed_len) {
    2224                /*
    2225                 * Either:
    2226                 *
    2227                 *  1) the length value extracted from the fixed-length portion
    2228                 *     doesn't include the fixed-length portion's length, and
    2229                 *     was so large that, when the fixed-length portion's
    2230                 *     length was added to it, the total length overflowed;
    2231                 *
    2232                 *  2) the length value extracted from the fixed-length portion
    2233                 *     includes the fixed-length portion's length, and the value
    2234                 *     was less than the fixed-length portion's length, i.e. it
    2235                 *     was bogus.
    2236                 *
    2237                 * Report this as a bounds error.
    2238                 */
    2239                show_reported_bounds_error(tvb, pinfo, tree);
    2240                return;
    2241            }
    2242    
    2243            /*
    2244             * Do not display the the PDU length if it crosses the boundary of the
    2245             * packet and no more packets are available.
    2246             *
    2247             * XXX - we don't necessarily know whether more packets are
    2248             * available; we might be doing a one-pass read through the
    2249             * capture in TShark, or we might be doing a live capture in
    2250             * Wireshark.
    2251             */
    2252    #if 0
    2253            if (length_remaining >= plen || there are more packets)
    2254            {
    2255    #endif
    2256                    /*
    2257                     * Display the PDU length as a field
    2258                     */
    2259                    item=proto_tree_add_uint(pinfo->tcp_tree, hf_tcp_pdu_size,
    2260                                             tvb, offset, plen, plen);
    2261                    PROTO_ITEM_SET_GENERATED(item);
    2262    #if 0
    2263            } else {
    2264                    item = proto_tree_add_text(pinfo->tcp_tree, tvb, offset, -1,
    2265                        "PDU Size: %u cut short at %u",plen,length_remaining);
    2266                    PROTO_ITEM_SET_GENERATED(item);
    2267            }
    2268    #endif
    2269    
    2270    
    2271            /* give a hint to TCP where the next PDU starts
    2272             * so that it can attempt to find it in case it starts
    2273             * somewhere in the middle of a segment.
    2274             */
    2275            if(!pinfo->fd->flags.visited && tcp_analyze_seq) {
    2276                guint remaining_bytes;
    2277                remaining_bytes=tvb_reported_length_remaining(tvb, offset);
    2278                if(plen>remaining_bytes) {
    2279                    pinfo->want_pdu_tracking=2;
    2280                    pinfo->bytes_until_next_pdu=plen-remaining_bytes;
    2281                }
    2282            }
    2283    
    2284            /*
    2285             * Can we do reassembly?
    2286             */
    2287            if (proto_desegment && pinfo->can_desegment) {
    2288                /*
    2289                 * Yes - is the PDU split across segment boundaries?
    2290                 */
    2291                if (length_remaining < plen) {
    2292                    /*
    2293                     * Yes.  Tell the TCP dissector where the data for this message
    2294                     * starts in the data it handed us, and how many more bytes we
    2295                     * need, and return.
    2296                     */
    2297                    pinfo->desegment_offset = offset;
    2298                    pinfo->desegment_len = plen - length_remaining;
    2299                    return;
    2300                }
    2301            }
    2302    
    2303            /*
    2304             * Construct a tvbuff containing the amount of the payload we have
    2305             * available.  Make its reported length the amount of data in the PDU.
    2306             *
    2307             * XXX - if reassembly isn't enabled. the subdissector will throw a
    2308             * BoundsError exception, rather than a ReportedBoundsError exception.
    2309             * We really want a tvbuff where the length is "length", the reported
    2310             * length is "plen", and the "if the snapshot length were infinite"
    2311             * length is the minimum of the reported length of the tvbuff handed
    2312             * to us and "plen", with a new type of exception thrown if the offset
    2313             * is within the reported length but beyond that third length, with
    2314             * that exception getting the "Unreassembled Packet" error.
    2315             */
    2316            length = length_remaining;
    2317            if (length > plen)
    2318                length = plen;
    2319            next_tvb = tvb_new_subset(tvb, offset, length, plen);
    2320    
    2321            /*
    2322             * Dissect the PDU.
    2323             *
    2324             * Catch the ReportedBoundsError exception; if this particular message
    2325             * happens to get a ReportedBoundsError exception, that doesn't mean
    2326             * that we should stop dissecting PDUs within this frame or chunk of
    2327             * reassembled data.
    2328             *
    2329             * If it gets a BoundsError, we can stop, as there's nothing more to
    2330             * see, so we just re-throw it.
    2331             */
    2332            pd_save = pinfo->private_data;
    2333            TRY {
    2334                (*dissect_pdu)(next_tvb, pinfo, tree);
    2335            }
    2336            CATCH(BoundsError) {
    2337                RETHROW;
    2338            }
    2339            CATCH(ReportedBoundsError) {
    2340                /*  Restore the private_data structure in case one of the
    2341                 *  called dissectors modified it (and, due to the exception,
    2342                 *  was unable to restore it).
    2343                 */
    2344                pinfo->private_data = pd_save;
    2345                show_reported_bounds_error(tvb, pinfo, tree);
    2346            }
    2347            ENDTRY;
    2348    
    2349            /*
    2350             * Step to the next PDU.
    2351             * Make sure we don't overflow.
    2352             */
    2353            offset_before = offset;
    2354            offset += plen;
    2355            if (offset <= offset_before)
    2356                break;
    2357        }
    2358    }
    2359    
  • 相关阅读:
    POJ 2533 Longest Ordered Subsequence 最长上升子序列
    HDU 2059 龟兔赛跑 动态规划
    POJ 1328 Radar Installation 贪心
    动手动脑课后作业
    学生信息添加界面(连接数据库实现学生信息的存储)
    回文递归小测总结
    Java开学测试学生成绩管理系统
    动手动脑(第六周)
    Java课后总结原码、补码、反码
    如何在静态方法中访问实例对象
  • 原文地址:https://www.cnblogs.com/davad/p/3617077.html
Copyright © 2011-2022 走看看