Changeset 5516

Show
Ignore:
Timestamp:
02/08/10 14:59:20 (6 months ago)
Author:
nopper
Message:

Readapting tcp and ip decoders to the new injection engine

Location:
pm/trunk/audits/passive
Files:
2 modified

Legend:

Unmodified
Added
Removed
  • pm/trunk/audits/passive/ip/sources/main.py

    r5495 r5516  
    4646""" 
    4747 
    48 from time import time 
     48import time 
    4949 
    5050from umit.pm.core.i18n import _ 
     
    5252from umit.pm.gui.plugins.engine import Plugin 
    5353from umit.pm.manager.auditmanager import AuditManager, PassiveAudit 
     54from umit.pm.manager.sessionmanager import * 
    5455from umit.pm.core.netconst import PROTO_LAYER, NET_LAYER, LL_TYPE_IP, INJ_FORWARD 
    5556from umit.pm.core.auditutils import checksum 
     
    6768    reas_dict = {} 
    6869 
     70    def ip_reassemble(mpkt): 
     71        # Here we have to check for fragmentation 
     72        # by creating a dict to holds id of ip packets 
     73        # and set mpkt.lock() on it if mpkg is MF 
     74        # until the resegmentation is done. 
     75        # If it's a fragment we have to return None 
     76        # to break the chain. 
     77 
     78        # TODO: check ip.flags standard name in UMPA 
     79        ts = time.time() 
     80        mf = mpkt.get_field('ip.flags', 0) & 1 
     81        frag_off = mpkt.get_field('ip.frag', 0) * 8 
     82 
     83        if not mf and frag_off == 0: 
     84            return False 
     85 
     86        ipid = mpkt.get_field('ip.id') 
     87 
     88        if ipid in reas_dict: 
     89            plist = reas_dict[ipid] 
     90 
     91            if len(plist) >= max_frags: 
     92                del reas_dict[ipid] 
     93                manager.user_msg(_('Dropping out the sequence with ID: ' 
     94                                   '%s due reassemble_max_fragments') % 
     95                                 ipid, 7, 'decoder.ip') 
     96 
     97                return False 
     98 
     99            ret = 0 
     100            idx = 0 
     101            inserted = False 
     102 
     103            while idx < len(plist): 
     104                ts2, frag_off2, mpkt2 = plist[idx] 
     105 
     106                if frag_off2 == frag_off: 
     107                    plist[idx] = (ts, frag_off, mpkt.copy()) 
     108                    break 
     109                elif frag_off2 < frag_off: 
     110                    ret += frag_off2 
     111                    idx += 1 
     112                    continue 
     113 
     114                inserted = True 
     115                plist.insert(idx, (ts, frag_off, mpkt.copy())) 
     116                break 
     117 
     118            if not inserted: 
     119                plist.append((ts, frag_off, mpkt.copy())) 
     120 
     121            # Now let's get the last packet and see if MF = 0 
     122            # EVASION! 
     123            if plist[-1][-1].get_field('ip.flags') & 1 == 0: 
     124 
     125                if idx == len(plist) -1: 
     126                    ret = frag_off - ret 
     127                else: 
     128                    while idx < len(plist) - 1: 
     129                        ts2, frag_off2, mpkt2 = plist[idx] 
     130                        ret += frag_off2 
     131                        idx += 1 
     132 
     133                        ret = plist[-1][1] - ret 
     134 
     135                if ret == 0: 
     136                    log.debug('Reassembling sequence with ID: %s' % \ 
     137                              ipid) 
     138 
     139                    reas_payload = '' 
     140 
     141                    for ts2, frag_off2, mpkt2 in plist: 
     142                        try: 
     143                            ihl = mpkt2.l3_len 
     144                            reas_payload += mpkt2.get_field('ip')[ihl:] 
     145                        except: 
     146                            pass 
     147 
     148                    # Ok check that we have a complete payload 
     149                    ihl = mpkt.l3_len 
     150                    p_len = frag_off + mpkt.get_field('ip.len') - ihl 
     151 
     152                    if len(reas_payload) != p_len: 
     153                        mpkt.set_cfield('reassembled_payload', None) 
     154                        manager.user_msg(_('Reassemble of IP packet ' \ 
     155                                           'from %s to %s failed') %  \ 
     156                                         (mpkt.l3_src, mpkt.l3_dst),  \ 
     157                                         4, 'decoder.ip') 
     158 
     159                    # Nice drop out everythin! 
     160                    del reas_dict[ipid] 
     161 
     162                    mpkt.set_cfield('reassembled_payload', reas_payload) 
     163                    return True 
     164        else: 
     165            if len(reas_dict) >= max_len: 
     166                # Ok just drop the list with the minor ts (the oldest) 
     167                min_k = min([(v, k) for k, v in reas_dict.items()])[1] 
     168                del reas_dict[min_k] 
     169 
     170                # Debug 
     171                manager.user_msg(_('Dropping out the oldest sequence ' 
     172                                   'with ID: %s') % min_k, 
     173                                 7, 'decoder.ip') 
     174 
     175            log.debug('First packet of the sequence with ID: %s' % ipid) 
     176            reas_dict[ipid] = [(ts, frag_off, mpkt)] 
     177 
     178        return False 
     179 
    69180    def ip(mpkt): 
     181        mpkt.l3_src, \ 
     182        mpkt.l3_dst, \ 
     183        mpkt.l4_proto = mpkt.get_fields('ip', ('src', 'dst', 'proto')) 
     184 
     185        # TODO: handle IPv6 
     186 
    70187        ipraw = mpkt.get_field('ip') 
    71188 
    72189        if not ipraw: 
    73190            return 
     191 
     192        mpkt.l3_len = mpkt.get_field('ip.ihl') * 4 
     193        mpkt.payload_len = mpkt.get_field('ip.len') - mpkt.l3_len 
     194 
     195        if mpkt.context: 
     196            mpkt.context.check_forwarded(mpkt) 
     197 
     198            if mpkt.flags & MPKT_FORWARDED: 
     199                return None 
     200 
     201            mpkt.context.set_forwardable(mpkt) 
    74202 
    75203        iplen = min(20, len(ipraw)) 
     
    79207            # so the packets are not fully captured. Avoid 
    80208            # further calculation. 
    81             return PROTO_LAYER, mpkt.get_field('ip.proto') 
     209            return PROTO_LAYER, mpkt.l4_proto 
    82210 
    83211        if checksum_check: 
    84             ihl = max(20, mpkt.get_field('ip.ihl') * 4) 
     212            ihl = max(20, mpkt.l3_len) 
    85213            pkt = ipraw[:10] + '\x00\x00' + ipraw[12:ihl] 
    86214 
     
    93221                manager.user_msg(_("Invalid IP packet from %s to %s : " \ 
    94222                                   "wrong checksum %s instead of %s") %  \ 
    95                                  (mpkt.get_field('ip.src'),          \ 
    96                                   mpkt.get_field('ip.dst'),          \ 
     223                                 (mpkt.l3_src, mpkt.l3_dst,          \ 
    97224                                  hex(mpkt.get_field('ip.chksum')),  \ 
    98225                                  hex(chksum)), 
    99226                                 5, 'decoder.ip') 
     227 
    100228            elif reassemble: 
    101                 # Here we have to check for fragmentation 
    102                 # by creating a dict to holds id of ip packets 
    103                 # and set mpkt.lock() on it if mpkg is MF 
    104                 # until the resegmentation is done. 
    105                 # If it's a fragment we have to return None 
    106                 # to break the chain. 
    107  
    108                 # TODO: check ip.flags standard name in UMPA 
    109                 ts = time() 
    110                 mf = mpkt.get_field('ip.flags', 0) & 1 
    111                 frag_off = mpkt.get_field('ip.frag', 0) * 8 
    112  
    113                 if not mf and frag_off == 0: 
    114                     return PROTO_LAYER, mpkt.get_field('ip.proto') 
    115  
    116                 ipid = mpkt.get_field('ip.id') 
    117  
    118                 if ipid in reas_dict: 
    119                     plist = reas_dict[ipid] 
    120  
    121                     if len(plist) >= max_frags: 
    122                         del reas_dict[ipid] 
    123                         manager.user_msg(_('Dropping out the sequence with ID: ' 
    124                                            '%s due reassemble_max_fragments') % 
    125                                          ipid, 7, 'decoder.ip') 
    126  
    127                         return PROTO_LAYER, mpkt.get_field('ip.proto') 
    128  
    129                     ret = 0 
    130                     idx = 0 
    131                     inserted = False 
    132  
    133                     while idx < len(plist): 
    134                         ts2, frag_off2, mpkt2 = plist[idx] 
    135  
    136                         if frag_off2 == frag_off: 
    137                             plist[idx] = (ts, frag_off, mpkt.copy()) 
    138                             break 
    139                         elif frag_off2 < frag_off: 
    140                             ret += frag_off2 
    141                             idx += 1 
    142                             continue 
    143  
    144                         inserted = True 
    145                         plist.insert(idx, (ts, frag_off, mpkt.copy())) 
    146                         break 
    147  
    148                     if not inserted: 
    149                         plist.append((ts, frag_off, mpkt.copy())) 
    150  
    151                     # Now let's get the last packet and see if MF = 0 
    152                     # EVASION! 
    153                     if plist[-1][-1].get_field('ip.flags') & 1 == 0: 
    154  
    155                         if idx == len(plist) -1: 
    156                             ret = frag_off - ret 
    157                         else: 
    158                             while idx < len(plist) - 1: 
    159                                 ts2, frag_off2, mpkt2 = plist[idx] 
    160                                 ret += frag_off2 
    161                                 idx += 1 
    162  
    163                                 ret = plist[-1][1] - ret 
    164  
    165                         if ret == 0: 
    166                             log.debug('Reassembling sequence with ID: %s' % \ 
    167                                       ipid) 
    168  
    169                             reas_payload = '' 
    170  
    171                             for ts2, frag_off2, mpkt2 in plist: 
    172                                 try: 
    173                                     ihl = mpkt2.get_field('ip.ihl') * 4 
    174                                     reas_payload += mpkt2.get_field('ip')[ihl:] 
    175                                 except: 
    176                                     pass 
    177  
    178                             # Ok check that we have a complete payload 
    179                             ihl = mpkt.get_field('ip.ihl') * 4 
    180                             p_len = frag_off + mpkt.get_field('ip.len') - ihl 
    181  
    182                             if len(reas_payload) != p_len: 
    183                                 mpkt.set_cfield('reassembled_payload', None) 
    184                                 manager.user_msg(_('Reassemble of IP packet ' \ 
    185                                                    'from %s to %s failed') % \ 
    186                                                  (mpkt.get_field('ip.src'), 
    187                                                   mpkt.get_field('ip.dst')), 
    188                                                  4, 'decoder.ip') 
    189  
    190                             # Nice drop out everythin! 
    191                             del reas_dict[ipid] 
    192  
    193                             mpkt.set_cfield('reassembled_payload', reas_payload) 
    194                 else: 
    195                     if len(reas_dict) >= max_len: 
    196                         # Ok just drop the list with the minor ts (the oldest) 
    197                         min_k = min([(v, k) for k, v in reas_dict.items()])[1] 
    198                         del reas_dict[min_k] 
    199  
    200                         # Debug 
    201                         manager.user_msg(_('Dropping out the oldest sequence ' 
    202                                            'with ID: %s') % min_k, 
    203                                          7, 'decoder.ip') 
    204  
    205                     log.debug('First packet of the sequence with ID: %s' % ipid) 
    206                     reas_dict[ipid] = [(ts, frag_off, mpkt)] 
    207  
    208         return PROTO_LAYER, mpkt.get_field('ip.proto') 
     229                ip_reassemble(mpkt) 
     230 
     231        ident = IPIdent.create(mpkt) 
     232        sess = SessionManager().get_session(ident) 
     233 
     234        if not sess: 
     235            sess = Session(ident) 
     236            sess.data = IPStatus() 
     237            SessionManager().put_session(sess) 
     238 
     239        sess.prev = mpkt.session 
     240        mpkt.session = sess 
     241 
     242        status = sess.data 
     243        status.last_id = mpkt.get_field('ip.id', 0) 
     244 
     245        manager.run_decoder(PROTO_LAYER, mpkt.l4_proto, mpkt) 
     246 
     247        if mpkt.flags & MPKT_DROPPED: 
     248            status.id_adj -= 1 
     249        elif mpkt.flags & MPKT_MODIFIED or status.id_adj != 0: 
     250            mpkt.set_field('ip.id', mpkt.get_field('ip.id', 0) + status.id_adj) 
     251            mpkt.set_field('ip.len', mpkt.get_field('ip.len', 0) + mpkt.inj_delta) 
     252            mpkt.set_field('ip.chksum', None) 
    209253 
    210254    return ip 
    211255 
    212 def ip_injector(context, mpkt): 
    213     pkt = MetaPacket.new('ip') 
    214  
    215     if mpkt.cfields.get('inj::payload', None): 
    216         pkt.set_field('ip.src', mpkt.get_field('ip.src')) 
    217         pkt.set_field('ip.dst', mpkt.get_field('ip.dst')) 
    218  
    219         # DEBUG: remove me after finished. Only used to track 
    220         # IP packets 
    221         pkt.set_field('ip.id', 666) 
    222  
    223         mpkt.set_cfield('inj::data', pkt) 
    224     else: 
    225         mpkt.reset_field('ip.chksum') 
    226  
    227     return INJ_FORWARD 
     256def ip_injector(context, mpkt, length): 
     257    if length + 20 > context.get_mtu(): 
     258        return False, length 
     259 
     260    sess = mpkt.session 
     261    status = sess.data 
     262 
     263    mpkt.set_fields('ip', { 
     264        'ihl' : 5, 
     265        'version' : 4, 
     266        'tos' : 0, 
     267        'chksum' : None, 
     268        #'len' : None, 
     269        'flags' : 0, 
     270        'frag' : 0, 
     271        'ttl' : 125, 
     272        'proto' : mpkt.l4_proto, 
     273        'src' : mpkt.l3_src, 
     274        'dst' : mpkt.l3_dst, 
     275        'id' : status.last_id + status.id_adj + 1}) 
     276 
     277    if not SessionManager().get_session(sess.ident): 
     278        return False, length 
     279 
     280    length += 20 
     281    further_len = length 
     282 
     283    # TODO: support encapsulated packets 
     284 
     285    status.id_adj += 1 
     286 
     287    payload_len = context.get_mtu() - length 
     288 
     289    if payload_len > mpkt.inject_len: 
     290        payload_len = mpkt.inject_len 
     291 
     292    tlen = further_len + payload_len - mpkt.l2_len 
     293    mpkt.set_field('ip.len', tlen) 
     294 
     295    mpkt.set_data_len(payload_len) 
     296 
     297    return True, length 
    228298 
    229299class IPDecoder(Plugin, PassiveAudit): 
  • pm/trunk/audits/passive/tcp/sources/main.py

    r5506 r5516  
    11#!/usr/bin/env python 
    22# -*- coding: utf-8 -*- 
    3 # Copyright (C) 2008 Adriano Monteiro Marques 
     3# Copyright (C) 2008, 2010 Adriano Monteiro Marques 
    44# 
    55# Author: Francesco Piccinno <stack.box@gmail.com> 
     
    2020 
    2121""" 
    22 TCP protocol dissector 
     22TCP protocol decoder 
    2323 
    2424>>> from umit.pm.core.auditutils import audit_unittest 
     
    3838from umit.pm.core.atoms import defaultdict 
    3939from umit.pm.gui.plugins.engine import Plugin 
     40from umit.pm.manager.sessionmanager import * 
    4041from umit.pm.manager.auditmanager import AuditManager, PassiveAudit 
    4142from umit.pm.core.netconst import * 
     
    241242        if iplen < 20: 
    242243            return 
    243         ipsrc, ipdst = inet_aton(mpkt.get_field('ip.src')), \ 
    244                        inet_aton(mpkt.get_field('ip.dst')) 
     244        ipsrc, ipdst = inet_aton(mpkt.l3_src), \ 
     245                       inet_aton(mpkt.l3_dst) 
    245246 
    246247        # Proto or port unreach 
     
    286287            return 
    287288 
    288         ipsrc, ipdst = inet_aton(mpkt.get_field('ip.src')),\ 
    289                        inet_aton(mpkt.get_field('ip.dst')) 
     289        ipsrc, ipdst = inet_aton(mpkt.l3_src), \ 
     290                       inet_aton(mpkt.l3_dst) 
    290291 
    291292        if ipsrc == '\x00\x00\x00\x00' and \ 
     
    681682        @param mpkt a MetaPacket object 
    682683        """ 
    683         ctup = (inet_aton(mpkt.get_field('ip.src')), 
    684                 inet_aton(mpkt.get_field('ip.dst')), 
    685                 mpkt.get_field('tcp.sport'), mpkt.get_field('tcp.dport')) 
     684        ctup = (inet_aton(mpkt.l3_src), 
     685                inet_aton(mpkt.l3_dst), 
     686                mpkt.l4_src, mpkt.l4_dst) 
    686687 
    687688        hash_idx = ':'.join(ctup[0:2]) 
     
    743744        # First look for client side streams 
    744745 
    745         ctup = (inet_aton(mpkt.get_field('ip.src')), 
    746                 inet_aton(mpkt.get_field('ip.dst')), 
    747                 mpkt.get_field('tcp.sport'), mpkt.get_field('tcp.dport')) 
     746        ctup = (inet_aton(mpkt.l3_src), 
     747                inet_aton(mpkt.l3_dst), 
     748                mpkt.l4_src, mpkt.l4_dst) 
    748749 
    749750        tcp_stream = self.find_tcp_stream(ctup) 
     
    879880    def start(self, reader): 
    880881        self.checksum_check = True 
    881         self.dissectors = True 
    882882        self.reassembler = None 
    883883        self.manager = None 
     
    899899 
    900900        self.checksum_check = conf['checksum_check'] 
    901         self.dissectors = conf['enable_dissectors'] 
    902901 
    903902        self.manager.add_decoder(PROTO_LAYER, NL_TYPE_TCP, self._process_tcp) 
     903        self.manager.add_injector(1, NL_TYPE_TCP, self._inject_tcp) 
    904904 
    905905        if conf['enable_reassemble']: 
     
    908908            self.manager.add_decoder_hook(PROTO_LAYER, NL_TYPE_ICMP, 
    909909                                          self.reassembler.process_icmp, 1) 
    910             self.manager.add_injector(1, NL_TYPE_TCP, self._inject_tcp) 
    911  
    912     def _inject_tcp(self, context, mpkt): 
     910 
     911    def _inject_tcp(self, context, mpkt, length): 
    913912        """ 
    914913        Function that manages injection of fragments in active TCP connection 
    915914        """ 
    916915 
    917         ret = INJ_FORWARD 
    918         stream, orcv = mpkt.cfields.get('inj::data', (None, None)) 
    919  
    920         if not stream: 
    921             log.debug('Last packet of the chain. Exiting') 
    922             return INJ_FORWARD 
    923  
    924         rcv = (stream.client is orcv) and (stream.server) or (stream.client) 
    925  
    926         if not stream: 
    927             raise Exception('inj::data key not present') 
    928  
    929         if stream.state == CONN_UNDEFINED: 
    930             log.error('The data can\'t be injected in a UNDEFINED stream') 
    931             return INJ_ERROR 
    932  
    933         injector = AuditManager().get_injector(0, LL_TYPE_IP) 
    934  
    935         if injector(context, mpkt) == INJ_ERROR: 
    936             log.error('Error in underlayer injector') 
    937             return INJ_ERROR 
    938  
    939         payload = mpkt.cfields.get('inj::payload', None) 
    940  
    941         if not payload: 
    942             # Here we have only to adjust the sequence 
    943             # or check for dropped packet. If flags is dropped just increase 
    944             # the seq_adj and return True 
    945  
    946             if mpkt.get_field('tcp.seq') == rcv.seq + rcv.seq_adj: 
    947                 log.debug('This is the injected packet skipping it') 
    948  
    949                 ret = INJ_SKIP_PACKET 
    950                 mpkt.unset_cfield('inj::data') 
    951  
    952             else: 
    953                 cseq = mpkt.get_field('tcp.seq') 
    954                 cack = mpkt.get_field('tcp.ack') 
    955  
    956                 log.debug('Adjusting sequence for TCP packet') 
    957                 log.debug('TCP sequence %d + %d = %d', cseq, rcv.seq_adj, 
    958                           rcv.seq_adj + cseq) 
    959                 log.debug('TCP ack %d - %d = %d', cack, orcv.seq_adj, 
    960                           cack - orcv.seq_adj) 
    961                 log.debug('Resetting TCP checksum') 
    962  
    963                 mpkt.set_field('tcp.seq', cseq + rcv.seq_adj) 
    964                 mpkt.set_field('tcp.ack', cack - orcv.seq_adj) 
    965                 mpkt.reset_field('tcp.chksum') 
    966                 mpkt.unset_cfield('inj::data') 
    967  
     916        ident = TCPIdent.create(mpkt) 
     917        sess = SessionManager().get_session(ident) 
     918 
     919        if not sess: 
     920            log.debug("No TCP session found.") 
     921            return False, length 
     922 
     923        if ident.l3_src == sess.ident.l3_src: 
     924            status = sess.data[1] 
     925            ostatus = sess.data[0] 
    968926        else: 
    969  
    970             if rcv.seq_adj == 0 and orcv.seq_adj == 0: 
    971  
    972                 ret = INJ_SKIP_PACKET 
    973                 log.error('The packet seems to be OK as is. ' 
    974                           'This is the first packet') 
    975  
    976             elif mpkt.get_field('tcp.seq') == rcv.seq + rcv.seq_adj: 
    977  
    978                 ret = INJ_SKIP_PACKET 
    979                 log.debug('No adjustments needed. SEQ & ACK are ok') 
    980  
    981             else: 
    982                 cseq = mpkt.get_field('tcp.seq') 
    983                 cack = mpkt.get_field('tcp.ack') 
    984  
    985                 log.debug('Adjusting current TCP packet') 
    986                 log.debug('TCP sequence %d + %d = %d', cseq, rcv.seq_adj, 
    987                           rcv.seq_adj + cseq) 
    988                 log.debug('TCP ack %d - %d = %d', cack, orcv.seq_adj, 
    989                           cack - orcv.seq_adj) 
    990                 log.debug('Resetting TCP checksum') 
    991  
    992                 mpkt.set_field('tcp.seq', cseq + rcv.seq_adj) 
    993                 mpkt.set_field('tcp.ack', cack - orcv.seq_adj) 
    994                 mpkt.reset_field('tcp.chksum') 
    995  
    996             plen = len(payload) 
    997             pkt = mpkt.cfields.get('inj::data', None) 
    998  
    999             if not pkt: 
    1000                 log.error('The underlayer injector returns None as mpkt') 
    1001                 return INJ_ERROR 
    1002  
    1003             mtu = context.get_mtu() - pkt.get_size() 
    1004  
    1005             if plen > mtu: 
    1006                 plen = mtu 
    1007  
    1008             prev_len = len(mpkt.get_field('tcp')) - \ 
    1009                      mpkt.get_field('tcp.dataofs') * 4 
    1010  
    1011             nseq = mpkt.get_field('tcp.seq') + prev_len 
    1012             nack = mpkt.get_field('tcp.ack') 
    1013  
    1014             pkt = pkt / MetaPacket.new('tcp') / MetaPacket.new('raw') 
    1015             pkt.set_field('tcp.sport', mpkt.get_field('tcp.sport')) 
    1016             pkt.set_field('tcp.dport', mpkt.get_field('tcp.dport')) 
    1017             pkt.set_field('tcp.flags', TH_PSH) 
    1018             pkt.set_field('tcp.seq', nseq) 
    1019             pkt.set_field('tcp.ack', nack) 
    1020  
    1021             log.debug('Forging new TCP + Raw packet (appended to %s)' % pkt) 
    1022             log.debug('TCP seq: %d' % nseq) 
    1023             log.debug('TCP ack: %d' % nack) 
    1024  
    1025             if rcv.ack_seq != 0: 
    1026                 pkt.set_field('tcp.flags', TH_PSH | TH_ACK) 
    1027  
    1028             pkt.set_field('raw.load', payload[:plen]) 
    1029  
    1030             remaining = payload[plen:] 
    1031  
    1032             # Adjusting seq_adj 
    1033             cur_len = len(mpkt.get_field('tcp')) - \ 
    1034                      mpkt.get_field('tcp.dataofs') * 4 
    1035  
    1036             rcv.seq_adj += cur_len 
    1037  
    1038             log.debug('Current packet has a payload with length = %d. ' 
    1039                       'seq_adj become: %d' % (cur_len, rcv.seq_adj)) 
    1040  
    1041  
    1042             if remaining: 
    1043                 pkt.set_cfield('inj::data', (stream, orcv)) 
    1044                 pkt.set_cfield('inj::payload', remaining) 
    1045  
    1046             mpkt.set_cfield('inj::data', pkt) 
    1047             mpkt.unset_cfield('inj::payload') 
    1048  
    1049         mpkt.unset_cfield('inj::flags') 
    1050         mpkt.unset_cfield('inj::l4proto') 
    1051  
    1052         return ret 
     927            status = sess.data[0] 
     928            ostatus = sess.data[1] 
     929 
     930        mpkt.set_fields('tcp', { 
     931            'sport' : mpkt.l4_src, 
     932            'dport' : mpkt.l4_dst, 
     933            'dataofs' : 5, 
     934            'chksum' : None, 
     935            'urgptr' : 0, 
     936            'flags' : TH_PSH, 
     937            'options' : {}}) 
     938 
     939        if status.injectable & INJ_FIN or \ 
     940           not status.injectable & INJ_FWD or \ 
     941           not ostatus.injectable & INJ_FWD: 
     942            log.debug("Session is not injectable.") 
     943            return False, length 
     944 
     945        mpkt.set_fields('tcp', { 
     946            'seq' : status.last_seq + status.seq_adj, 
     947            'ack' : status.last_ack - ostatus.seq_adj}) 
     948 
     949        if status.last_ack != 0: 
     950            mpkt.set_field('tcp.flags', mpkt.l4_flags | TH_ACK) 
     951 
     952        mpkt.session = sess.prev 
     953        length += 20 + mpkt.l2_len 
     954 
     955        injector = AuditManager().get_injector(0, mpkt.session.ident.magic) 
     956        is_ok, length = injector(context, mpkt, length) 
     957 
     958        if not is_ok: 
     959            return is_ok, length 
     960 
     961        length = context.get_mtu() - length 
     962 
     963        if length > mpkt.inject_len: 
     964            length = mpkt.inject_len 
     965 
     966        payload = mpkt.inject[:length] 
     967        payload_pkt = MetaPacket.new('raw') 
     968        payload_pkt.set_field('raw.load', payload) 
     969        mpkt.add_to('tcp', payload_pkt) 
     970 
     971        status.seq_adj += length 
     972        mpkt.data_len = length 
     973 
     974        return True, length 
    1053975 
    1054976    def _process_tcp(self, mpkt): 
    1055         if self.checksum_check: 
    1056             # TODO: Handle IPv6 here 
    1057             tcpraw = mpkt.get_field('tcp') 
    1058  
    1059             if tcpraw: 
    1060                 ln = mpkt.get_field('ip.len') - 20 
    1061  
    1062                 if ln == len(tcpraw): 
    1063                     ip_src = mpkt.get_field('ip.src') 
    1064                     ip_dst = mpkt.get_field('ip.dst') 
    1065  
    1066                     psdhdr = pack("!4s4sHH", 
    1067                                   inet_aton(ip_src), 
    1068                                   inet_aton(ip_dst), 
    1069                                   mpkt.get_field('ip.proto'), 
    1070                                   ln) 
    1071  
    1072                     chksum = checksum(psdhdr + tcpraw[:16] + \ 
    1073                                       "\x00\x00" + tcpraw[18:]) 
    1074  
    1075                     if mpkt.get_field('tcp.chksum', 0) != chksum: 
    1076                         mpkt.set_cfield('good_checksum', hex(chksum)) 
    1077                         self.manager.user_msg( 
    1078                                     _("Invalid TCP packet from %s to %s : " \ 
    1079                                       "wrong checksum %s instead of %s") %  \ 
    1080                                     (ip_src, ip_dst,                        \ 
    1081                                      hex(mpkt.get_field('tcp.chksum', 0)),  \ 
    1082                                      hex(chksum)), 
    1083                                     5, 'decoder.tcp') 
    1084                     elif self.reassembler: 
    1085                         self.reassembler.process_tcp(mpkt) 
    1086  
    1087         if not self.dissectors: 
    1088             return None 
    1089  
    1090         ret = self.manager.run_decoder(APP_LAYER_TCP, 
    1091                                  mpkt.get_field('tcp.dport'), mpkt) 
    1092  
    1093         ret = max(ret, self.manager.run_decoder(APP_LAYER_TCP, 
    1094                                  mpkt.get_field('tcp.sport'), mpkt)) 
     977        mpkt.l4_src, \ 
     978        mpkt.l4_dst, \ 
     979        mpkt.l4_ack, \ 
     980        mpkt.l4_seq, \ 
     981        mpkt.l4_flags = mpkt.get_fields('tcp', ('sport', 'dport', 'ack', \ 
     982                                                'seq', 'flags')) 
     983        mpkt.l4_len = mpkt.get_field('tcp.dataofs', 5) * 4 
     984 
     985        tcpraw = mpkt.get_field('tcp') 
     986 
     987        if tcpraw: 
     988            mpkt.data_len = mpkt.payload_len - mpkt.l4_len 
     989            mpkt.data = tcpraw[mpkt.l4_len:] 
     990 
     991        if self.checksum_check and tcpraw: 
     992            ln = mpkt.get_field('ip.len') - 20 
     993 
     994            if ln == len(tcpraw): 
     995                ip_src = mpkt.l3_src 
     996                ip_dst = mpkt.l3_dst 
     997 
     998                psdhdr = pack("!4s4sHH", 
     999                              inet_aton(ip_src), 
     1000                              inet_aton(ip_dst), 
     1001                              mpkt.l4_proto, 
     1002                              ln) 
     1003 
     1004                chksum = checksum(psdhdr + tcpraw[:16] + \ 
     1005                                  "\x00\x00" + tcpraw[18:]) 
     1006 
     1007                if mpkt.get_field('tcp.chksum', 0) != chksum: 
     1008                    mpkt.set_cfield('good_checksum', hex(chksum)) 
     1009                    self.manager.user_msg( 
     1010                                _("Invalid TCP packet from %s to %s : " \ 
     1011                                  "wrong checksum %s instead of %s") %  \ 
     1012                                (ip_src, ip_dst,                        \ 
     1013                                 hex(mpkt.get_field('tcp.chksum', 0)),  \ 
     1014                                 hex(chksum)), 
     1015                                5, 'decoder.tcp') 
     1016                elif self.reassembler: 
     1017                    self.reassembler.process_tcp(mpkt) 
     1018 
     1019        ident = TCPIdent.create(mpkt) 
     1020        sess = SessionManager().get_session(ident) 
     1021 
     1022        if not sess: 
     1023            sess = Session(ident) 
     1024            sess.data = (TCPStatus(), TCPStatus()) 
     1025            SessionManager().put_session(sess) 
     1026 
     1027        sess.prev = mpkt.session 
     1028        mpkt.session = sess 
     1029 
     1030        if ident.l3_src == sess.ident.l3_src: 
     1031            status = sess.data[1] 
     1032            ostatus = sess.data[0] 
     1033        else: 
     1034            status = sess.data[0] 
     1035            ostatus = sess.data[1] 
     1036 
     1037        status.last_seq = mpkt.l4_seq + mpkt.data_len 
     1038 
     1039        if mpkt.l4_flags & TH_ACK: 
     1040            status.last_ack = mpkt.l4_ack 
     1041 
     1042        if mpkt.l4_flags & TH_SYN: 
     1043            status.last_seq += 1 
     1044 
     1045        if mpkt.l4_flags & TH_RST: 
     1046            status.injectable |= INJ_FIN 
     1047            ostatus.injectable |= INJ_FIN 
     1048 
     1049        if mpkt.flags & MPKT_FORWARDABLE: 
     1050            status.injectable |= INJ_FWD 
     1051        elif status.injectable & INJ_FWD: 
     1052            status.injectable ^= INJ_FWD 
     1053 
     1054        self.manager.run_decoder(APP_LAYER, PL_DEFAULT, mpkt) 
     1055 
     1056        if mpkt.l4_flags & TH_FIN: 
     1057            status.injectable |= INJ_FIN 
     1058 
     1059        if mpkt.flags & MPKT_DROPPED and mpkt.flags & MPKT_FORWARDABLE: 
     1060            status.seq_adj += mpkt.inj_delta 
     1061        elif (mpkt.flags & MPKT_MODIFIED or \ 
     1062             status.seq_adj != 0 or ostatus != 0) and \ 
     1063             mpkt.flags & MPKT_FORWARDABLE: 
     1064 
     1065            mpkt.set_field('tcp.seq', mpkt.l4_seq + status.seq_adj) 
     1066            mpkt.set_field('tcp.ack', mpkt.l4_ack - ostatus.seq_adj) 
     1067 
     1068            status.seq_adj += mpkt.inj_delta 
     1069 
     1070            mpkt.set_field('tcp.chksum', None) 
    10951071 
    10961072        return None 
     
    11051081    ('decoder.tcp', { 
    11061082        'checksum_check' : [True, 'Cheksum check for TCP segments'], 
    1107         'enable_dissectors' : [True, 'Enable TCP protocol dissectors'], 
    11081083        'enable_reassemble' : [True, 'Enable userland python implementation of ' 
    11091084                               'TCP/IP stack to tracks TCP streams connection. '