def parse(cls, buf, options=None):
        """
        According to Philip, an abuf is like a TARDIS: it's bigger on the inside
        """

        error = []
        do_header = True
        do_question = True
        do_answer = True
        do_authority = True
        do_additional = True
        do_options = True

        if options and isinstance(options, dict):
            if 'DO_Header' in options and not options['DO_Header']:
                do_header = options['DO_Header']
            if 'DO_Question' in options and not options['DO_Question']:
                do_question = options['DO_Question']
            if 'DO_Answer' in options and not options['DO_Answer']:
                do_answer = options['DO_Answer']
            if 'DO_Authority' in options and not options['DO_Authority']:
                do_authority = options['DO_Authority']
            if 'DO_Additional' in options and not options['DO_Additional']:
                do_additional = options['DO_Additional']
            if 'DO_Options' in options and not options['DO_Options']:
                do_options = options['DO_Options']

        dnsres = {}
        offset = 0
        offset, hdr = cls._parse_header(buf, offset, error)
        if do_header:
            dnsres['HEADER'] = hdr
        for i in range(hdr['QDCOUNT']):
            res = cls._do_query(buf, offset, error)
            if res is None:
                e = ('additional', offset, ('_do_query failed, additional record %d' % i))
                error.append(e)
                dnsres['ERROR'] = error
                return dnsres
            offset, qry = res
            if do_question:
                if i == 0:
                    dnsres['QuestionSection'] = [qry]
                else:
                    dnsres['QuestionSection'].append(qry)
        for i in range(hdr['ANCOUNT']):
            res = cls._do_rr(buf, offset, error, hdr)
            if res is None:
                e = ('additional', offset, ('_do_rr failed, additional record %d' % i))
                error.append(e)
                dnsres['ERROR'] = error
                return dnsres
            offset, rr = res
            if do_answer:
                if i == 0:
                    dnsres['AnswerSection'] = [rr]
                else:
                    dnsres['AnswerSection'].append(rr)
        for i in range(hdr['NSCOUNT']):
            res = cls._do_rr(buf, offset, error, hdr)
            if res is None:
                e = ('additional', offset, ('_do_rr failed, additional record %d' % i))
                error.append(e)
                dnsres['ERROR'] = error
                return dnsres
            offset, rr = res
            if do_authority:
                if i == 0:
                    dnsres['AuthoritySection'] = [rr]
                else:
                    dnsres['AuthoritySection'].append(rr)
        for i in range(hdr['ARCOUNT']):
            res = cls._do_rr(buf, offset, error, hdr)
            if res is None:
                e = ('additional', offset, ('_do_rr failed, additional record %d' % i))
                error.append(e)
                dnsres['ERROR'] = error
                return dnsres
            offset, rr = res
            if do_options:
                if "EDNS0" in rr:
                    dnsres['EDNS0'] = rr['EDNS0']
                    continue
            if do_additional:
                if 'AdditionalSection' in dnsres:
                    dnsres['AdditionalSection'].append(rr)
                else:
                    dnsres['AdditionalSection'] = [rr]
        hdr['ReturnCode'] = cls._rcode_to_text(hdr['ReturnCode'])

        if offset < len(buf):
            e = ('end', offset, 'trailing garbage, buf size = %d' % len(buf))
            error.append(e)
            #result['decodedabufs_with_ERROR'] += 1
            dnsres['ERROR'] = error

        return dnsres
def parse ( cls , buf , options = None ) : error = [ ] do_header = True do_question = True do_answer = True do_authority = True do_additional = True do_options = True if options and isinstance ( options , dict ) : if 'DO_Header' in options and not options [ 'DO_Header' ] : do_header = options [ 'DO_Header' ] if 'DO_Question' in options and not options [ 'DO_Question' ] : do_question = options [ 'DO_Question' ] if 'DO_Answer' in options and not options [ 'DO_Answer' ] : do_answer = options [ 'DO_Answer' ] if 'DO_Authority' in options and not options [ 'DO_Authority' ] : do_authority = options [ 'DO_Authority' ] if 'DO_Additional' in options and not options [ 'DO_Additional' ] : do_additional = options [ 'DO_Additional' ] if 'DO_Options' in options and not options [ 'DO_Options' ] : do_options = options [ 'DO_Options' ] dnsres = { } offset = 0 offset , hdr = cls . _parse_header ( buf , offset , error ) if do_header : dnsres [ 'HEADER' ] = hdr for i in range ( hdr [ 'QDCOUNT' ] ) : res = cls . _do_query ( buf , offset , error ) if res is None : e = ( 'additional' , offset , ( '_do_query failed, additional record %d' % i ) ) error . append ( e ) dnsres [ 'ERROR' ] = error return dnsres offset , qry = res if do_question : if i == 0 : dnsres [ 'QuestionSection' ] = [ qry ] else : dnsres [ 'QuestionSection' ] . append ( qry ) for i in range ( hdr [ 'ANCOUNT' ] ) : res = cls . _do_rr ( buf , offset , error , hdr ) if res is None : e = ( 'additional' , offset , ( '_do_rr failed, additional record %d' % i ) ) error . append ( e ) dnsres [ 'ERROR' ] = error return dnsres offset , rr = res if do_answer : if i == 0 : dnsres [ 'AnswerSection' ] = [ rr ] else : dnsres [ 'AnswerSection' ] . append ( rr ) for i in range ( hdr [ 'NSCOUNT' ] ) : res = cls . _do_rr ( buf , offset , error , hdr ) if res is None : e = ( 'additional' , offset , ( '_do_rr failed, additional record %d' % i ) ) error . append ( e ) dnsres [ 'ERROR' ] = error return dnsres offset , rr = res if do_authority : if i == 0 : dnsres [ 'AuthoritySection' ] = [ rr ] else : dnsres [ 'AuthoritySection' ] . append ( rr ) for i in range ( hdr [ 'ARCOUNT' ] ) : res = cls . _do_rr ( buf , offset , error , hdr ) if res is None : e = ( 'additional' , offset , ( '_do_rr failed, additional record %d' % i ) ) error . append ( e ) dnsres [ 'ERROR' ] = error return dnsres offset , rr = res if do_options : if "EDNS0" in rr : dnsres [ 'EDNS0' ] = rr [ 'EDNS0' ] continue if do_additional : if 'AdditionalSection' in dnsres : dnsres [ 'AdditionalSection' ] . append ( rr ) else : dnsres [ 'AdditionalSection' ] = [ rr ] hdr [ 'ReturnCode' ] = cls . _rcode_to_text ( hdr [ 'ReturnCode' ] ) if offset < len ( buf ) : e = ( 'end' , offset , 'trailing garbage, buf size = %d' % len ( buf ) ) error . append ( e ) dnsres [ 'ERROR' ] = error return dnsres
According to Philip, an abuf is like a TARDIS: it's bigger on the inside