#!/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