(plist)
return nofrag,defrag2,missfrag
defrag(plist) -> ([not fragmented], [defragmented],
                  [ [bad fragments], [bad fragments], ... ])
defrag(plist) -> ([not fragmented], [defragmented],
                  [ [bad fragments], [bad fragments], ... ])
defrag ( plist ) - > ( [ not fragmented ] [ defragmented ] [ [ bad fragments ] [ bad fragments ] ... ] )
def defrag(plist):
    """defrag(plist) -> ([not fragmented], [defragmented],
                  [ [bad fragments], [bad fragments], ... ])"""
    frags = defaultdict(PacketList)
    nofrag = PacketList()
    for p in plist:
        ip = p[IP]
        if IP not in p:
            nofrag.append(p)
            continue
        if ip.frag == 0 and ip.flags & 1 == 0:
            nofrag.append(p)
            continue
        uniq = (ip.id,ip.src,ip.dst,ip.proto)
        frags[uniq].append(p)
    defrag = []
    missfrag = []
    for lst in frags.itervalues():
        lst.sort(key=lambda x: x.frag)
        p = lst[0]
        lastp = lst[-1]
        if p.frag > 0 or lastp.flags & 1 != 0: # first or last fragment missing
            missfrag.append(lst)
            continue
        p = p.copy()
        if Padding in p:
            del(p[Padding].underlayer.payload)
        ip = p[IP]
        if ip.len is None or ip.ihl is None:
            clen = len(ip.payload)
        else:
            clen = ip.len - (ip.ihl<<2)
        txt = Raw()
        for q in lst[1:]:
            if clen != q.frag<<3: # Wrong fragmentation offset
                if clen > q.frag<<3:
                    warning("Fragment overlap (%i > %i) %r || %r ||  %r" % (clen, q.frag<<3, p,txt,q))
                missfrag.append(lst)
                break
            if q[IP].len is None or q[IP].ihl is None:
                clen += len(q[IP].payload)
            else:
                clen += q[IP].len - (q[IP].ihl<<2)
            if Padding in q:
                del(q[Padding].underlayer.payload)
            txt.add_payload(q[IP].payload.copy())
        else:
            ip.flags &= ~1 # !MF
            del(ip.chksum)
            del(ip.len)
            p = p/txt
            defrag.append(p)
    defrag2=PacketList()
    for p in defrag:
        defrag2.append(p.__class__(str(p)))
    return nofrag,defrag2,missfrag
def defrag ( plist ) : frags = defaultdict ( PacketList ) nofrag = PacketList ( ) for p in plist : ip = p [ IP ] if IP not in p : nofrag . append ( p ) continue if ip . frag == 0 and ip . flags & 1 == 0 : nofrag . append ( p ) continue uniq = ( ip . id , ip . src , ip . dst , ip . proto ) frags [ uniq ] . append ( p ) defrag = [ ] missfrag = [ ] for lst in frags . itervalues ( ) : lst . sort ( key = lambda x : x . frag ) p = lst [ 0 ] lastp = lst [ - 1 ] if p . frag > 0 or lastp . flags & 1 != 0 : # first or last fragment missing missfrag . append ( lst ) continue p = p . copy ( ) if Padding in p : del ( p [ Padding ] . underlayer . payload ) ip = p [ IP ] if ip . len is None or ip . ihl is None : clen = len ( ip . payload ) else : clen = ip . len - ( ip . ihl << 2 ) txt = Raw ( ) for q in lst [ 1 : ] : if clen != q . frag << 3 : # Wrong fragmentation offset if clen > q . frag << 3 : warning ( "Fragment overlap (%i > %i) %r || %r ||  %r" % ( clen , q . frag << 3 , p , txt , q ) ) missfrag . append ( lst ) break if q [ IP ] . len is None or q [ IP ] . ihl is None : clen += len ( q [ IP ] . payload ) else : clen += q [ IP ] . len - ( q [ IP ] . ihl << 2 ) if Padding in q : del ( q [ Padding ] . underlayer . payload ) txt . add_payload ( q [ IP ] . payload . copy ( ) ) else : ip . flags &= ~ 1 # !MF del ( ip . chksum ) del ( ip . len ) p = p / txt defrag . append ( p ) defrag2 = PacketList ( ) for p in defrag : defrag2 . append ( p . __class__ ( str ( p ) ) ) return nofrag , defrag2 , missfrag