python parse tcpdump -i eth

#!/usr/bin/python


import os
import sys
import time
import re
import math
import socket


#10:27:36.422139 00:00:00:05:81:01 (oui Ethernet) > 00:00:00:00:81:01 (oui Ethernet), ethertype Unknown (0x8200), length 136:
#        0x0000:  0000 0000 8101 0000 0005 8101 8200 a3e8
#        0x0010:  1830 0000 0000 0000 006c 0000 0000 0000
#        0x0020:  0000 0000 0000 0000 0000 0000 0001 0000
#        0x0030:  0000 0000 0000 0000 0000 011b 1900 0000
#        0x0040:  a000 0000 0001 88f7 0002 002c 1800 0000
#        0x0050:  318b 5a8a baef 0000 0000 0000 0000 0000
#        0x0060:  0000 0001 0001 e567 00fc 0000 5f0e 7417
#        0x0070:  1b05 04db 0000 0100 0004 0000 0000 0000
#        0x0080:  1621 ce74 a575 7e68
#10:27:36.466652 00:00:00:05:81:01 (oui Ethernet) > 00:00:00:00:81:01 (oui Ethernet), ethertype Unknown (0x8200), length 144:
#        0x0000:  0000 0000 8101 0000 0005 8101 8200 a3e8
#        0x0010:  1830 0000 0000 0000 0074 0000 0000 0000
#        0x0020:  0000 0000 0000 0000 0000 0000 0001 0000
#        0x0030:  0000 0000 0000 0000 0000 011b 1900 0000
#        0x0040:  a000 0000 0001 88f7 0902 0036 1800 0000
#        0x0050:  0000 0000 2458 0000 0000 0000 0000 0000
#        0x0060:  0000 0001 0001 6cb5 03fc 0000 5f0e 7417
#        0x0070:  1dac 2fc5 089c 86ff 0100 f74a 0001 0100
#        0x0080:  0004 0000 0000 0000 1621 ce74 a81c b088
#10:27:36.484633 00:00:00:05:81:01 (oui Ethernet) > 00:00:00:00:81:01 (oui Ethernet), ethertype Unknown (0x8200), length 140:
#        0x0000:  0000 0000 8101 0000 0005 8101 8200 a3e8
#        0x0010:  1830 1224 0000 0000 0070 0000 0000 0000
#        0x0020:  0000 0000 0000 0000 0000 0000 0001 0000
#        0x0030:  0000 0000 0000 0000 0000 011b 1900 0000
#        0x0040:  a000 0000 0001 88a8 0bbc 88f7 0b02 0040
#        0x0050:  1800 003c 0000 0000 0000 0000 0000 0000
#        0x0060:  0000 0000 0000 0001 0001 f2b4 05fd 0000
#        0x0070:  0000 0000 0000 0000 0025 0080 0621 ffff
#        0x0080:  8000 0000 0000 0000 0100 00a0


pat_del = re.compile("(0x[0-9]{4}:)", re.I)



class TpsPacket:
    def __init__(self):
        self._ethline=""
        self._bytelen=0
        self._linenum=0
        self._conline=""
        self._pkttime=""
        self._cvid =0
        self._svid =0
        self._dmac =""
        self._smac =""
        self._ethtype=""
        ''' mesgtype msglen domain flagfield CF  sourceportidentity seqid ctrlfield  interval '''
        self._commhead={}
        ''' utcoffset stepremoved '''
        self._anno={}
        '''originTimestamp'''
        self._sync={}
        self._delayreq={}
        ''' receiveTimestamp  requestingPortIdentity '''
        self._delayresp={}
        '''fpgalogicid vlan rxtime '''
        self._tlv={}
    def dumpcomm(self):
        if self._ethtype != "PTP":
            return
        print self._commhead['mesgtype'],  "  Time    ", self._pkttime
        print self._commhead['mesgtype'],  "  MAC     ", self._smac, "-->", self._dmac
        print self._commhead['mesgtype'],  "  SVID    ", self._svid
        print self._commhead['mesgtype'],  "  CVID    ", self._cvid
        print self._commhead['mesgtype'],  "  Domain  ", self._commhead['domain']
        print self._commhead['mesgtype'],  "  Flag    ", self._commhead['flagfield']
        print self._commhead['mesgtype'],  "  CF      ", self._commhead['CF']
        print self._commhead['mesgtype'],  "  Seq     ", self._commhead['seqid']
    def dumpspecial(self):
        if self._ethtype != "PTP":
            return
        if self._commhead['mesgtype'] =="ANNO":
            pass
        elif self._commhead['mesgtype'] =="SYNC":
            print self._commhead['mesgtype'],  "  t1      ", self._sync['originTimestamp']
            if self._tlv['rxtime'] != "":
                print self._commhead['mesgtype'],  "  t2      ", self._tlv['rxtime']
        elif self._commhead['mesgtype'] =="REQ":
            pass 
        elif self._commhead['mesgtype'] =="RESP":
            print self._commhead['mesgtype'],  "  t4      ", self._delayresp['receiveTimestamp']
        else:
            pass
        print "\n"
    def to_portidenty(self, sid):
        return "ClockIdentity(" + sid[0:2]  + ":"  + sid[2:4]   + ":" + sid[4:6] + ":" \
                                    + sid[6:8] + ":" + sid[8:10] + ":" + sid[10:12]  + ":" + sid[12:14] + ":"\
                                    + sid[16:18] + ")/PortNumber(" +  sid[19:] + ")"
    def to_mac(self, mac):
        return mac[0:2] + ":" + mac[2:4] + ":" + mac[4:6] + ":" + mac[6:8] + ":" + mac[8:10] + ":" + mac[10:12]

    def parse_comm_head(self, ptphead):
        #print("ptphead:", ptphead)
        pos = 0
        if ptphead[pos:pos+4]== "0b02":
            self._commhead['mesgtype'] ="ANNO"
        elif ptphead[pos:pos+4]  == "0002":
            self._commhead['mesgtype'] ="SYNC"
        elif ptphead[pos:pos+4] == "0102":
            self._commhead['mesgtype'] ="REQ"
        elif  ptphead[pos:pos+4] == "0902":
            self._commhead['mesgtype'] ="RESP"
        else:
            self._commhead['mesgtype'] ="UNKNOWN"
        pos = pos + 4
        self._commhead['msglen'] = int(ptphead[pos:pos+4],16)
        pos = pos + 4
        self._commhead['domain'] = int(ptphead[pos:pos+2],16)

        ''' reseverd'''
        pos = pos + 2
        '''flagfiled'''
        pos = pos + 2
        self._commhead['flagfield']= "0x" + (ptphead[pos:pos+4])
        '''CF'''
        pos = pos + 4
        self._commhead['CF']= int(ptphead[pos:pos+16],16)/65536
        '''reserved'''
        pos = pos + 16
        ''' tphead[pos:pos+8]'''

        '''sourcePortIdentity '''
        pos = pos + 8
        sid = ptphead[pos:pos+20]
        self._commhead['sourceportidentity'] = self.to_portidenty(sid)
        '''seqid'''
        pos = pos + 20
        self._commhead['seqid']= int(ptphead[pos:pos+4],16)

        '''controlfield '''
        pos = pos + 4
        self._commhead['ctrlfield']= int(ptphead[pos:pos+2],16)
        pos = pos + 2
        self._commhead['interval']= int(ptphead[pos:pos+2],16) -0x100
        #print(self._commhead)

    def parse_ptp_anno(self, annobody):
        #print("anno body:", annobody)
        pos = 0
        self._anno['timestamp']= int(annobody[pos:pos+20],16)

        self._anno['utcoffset'] = int(annobody[pos+20:pos+24],16)
        self._anno['grandmasterPriority1'] = int(annobody[pos+26:pos+28],16)

        self._anno['stepremoved'] = int(annobody[pos+54:pos+58],16)
        #print(self._anno)

    def parse_ptp_syn(self, syncbody):
        #print("sync body:", syncbody)
        pos = 0
        self._sync['originTimestamp']=str(int(syncbody[pos+4:pos+12],16)) + "." + str(int(syncbody[pos+12:pos+20],16))
        #print(self._sync)

    def parse_ptp_delayreq(self, reqbody):
        #print("delayreq body:", reqbody)
        pos = 0
        self._delayreq['originTimestamp']= int(reqbody[pos:pos+20],16)
        #print(self._delayreq)
    def parse_ptp_delayresp(self, respbody):
        #print("delayresp body:", respbody)
        pos = 0
        self._delayresp['receiveTimestamp']= str(int(respbody[pos+4:pos+12],16)) + "." + str(int(respbody[pos+12:pos+20],16))
        self._delayresp['requestingPortIdentity']= self.to_portidenty(respbody[pos+20:pos+40])
        #print(self._delayresp)
  
    def parse(self, bytelen, num, linelist):
        templine=""
        for i in range(0, len(linelist)):
            if (i == 0):
                self._ethline = linelist[i]
                self._bytelen = bytelen
                self._linenum = num
            else:
                line = pat_del.sub("", linelist[i])
                line = line.replace("\t", "");
                line = line.lstrip()
        #        print(line)
                templine = templine + line
        self._conline = templine.replace(' ', '')
        #print('lenth=%d,line=%s' %(len(self._conline), self._conline))

        pos = self._ethline.find(" ")
        self._pkttime = self._ethline[:pos]
        
        pos = 58*2
        self._dmac = self.to_mac(self._conline[pos: pos+12]) 
        pos = pos + 12
        smac = self._conline[pos: pos+12]
        self._smac = self.to_mac(self._conline[pos: pos+12]) 

        #print('lenth=%d,line=%s' %(len(self._dmac), self._dmac))
        #print('lenth=%d,line=%s' %(len(self._smac), self._smac))

        pos = pos + 12
        
        if (self._conline[pos:pos+4] == "8100") or (self._conline[pos:pos+4] == "88a8"):
            if (self._conline[pos+8:pos+12] == "8100") or (self._conline[pos+8:pos+12] == "88a8"):
                svid = self._conline[pos+5:pos+8]
                cvid = self._conline[pos+13:pos+16]
                self._svid= int(svid,16)
                self._cvid= int(cvid,16)
                #print("svlan %d" %self._svid)
                #print("cvlan %d" %self._cvid)
                pos = pos + 16
            else:
                cvid = self._conline[pos+5:pos+8]
                pos = pos + 8
                #print("cvlan %d" %self._cvid)
        else:
            pass
                #print("cvlan 0")
        
        if (self._conline[pos:pos+4] == "88f7"):
            self._ethtype = "PTP"
            #print(self._ethtype)
        else:    
            return

        pos = pos + 4
        self.parse_comm_head(self._conline[pos:pos+68])
        #print(self._conline[pos:pos+68])
        pos = pos + 68
        if self._commhead['mesgtype'] =="ANNO":
            self.parse_ptp_anno(self._conline[pos:pos+60])
            pos = pos + 60
        elif self._commhead['mesgtype'] =="SYNC":
            self.parse_ptp_syn(self._conline[pos:pos+20])
            pos = pos + 20
        elif self._commhead['mesgtype'] =="REQ":
            self.parse_ptp_delayreq(self._conline[pos:pos+20])
            pos = pos + 20
        elif self._commhead['mesgtype'] =="RESP":
            self.parse_ptp_delayresp(self._conline[pos:pos+40])
            pos = pos + 40
        else:
            pass
        if (self._bytelen *2 - pos > 0):
            self._tlv['fpgalogicid'] = int(self._conline[pos+8:pos+12],16)      
            self._tlv['vlan'] = int(self._conline[pos+12:pos+16], 16)&0xfff
            
            nsec = (int(self._conline[pos+24:pos+32],16) *4294967296L  + int(self._conline[pos+32:pos+40],16))
            self._tlv['rxtime'] = str(nsec /1000000000) + '.' + str(nsec%1000000000)
            #print(self._tlv)
            #print("leave:", self._bytelen *2 - pos)
            #print("logicportid:", self._tlv['fpgalogicid'])
            #print("vlan:", self._tlv['vlan'])
            #print("temp:", temp)
            #print("rxtime:", self._tlv['rxtime'])
        

        

linelist=[]
expnum = 0
linenum = 0



while True:
    line = sys.stdin.readline()
    if not line:
        break
    myline = line.strip('\n').strip('\r')
    if 'Ethernet' in myline:
        posb = myline.find("length")
        pose = myline.find(":", posb)
        bytelen = int(myline[posb+7:pose])
        expnum = (int)(math.ceil(float(bytelen)/16))
        #print('len:%d exp: %d, line:%s' %(bytelen, expnum, myline))
        linelist.append(myline)    
    else:
        linelist.append(myline)
        linenum = linenum +1
        #print('exp: %d,linenum:%d line:%s' %(expnum,linenum, myline))

        if (expnum == linenum):
            onepacket = TpsPacket()
            onepacket.parse(bytelen, linenum, linelist)
            onepacket.dumpcomm()
            onepacket.dumpspecial()
            linelist=[]
            linenum = 0

 

你可能感兴趣的:(SCRIPT)