def __parseUDP(self): """ Parse RTP over UDP session. """ def extract(p): """ Extract information from a UDP packet. :param Packet p: UDP packet. """ ptype = ord(str(p[UDP].payload)[1]) & 0x7F #Delete RTP marker p[UDP].decode_payload_as(RTP) if ptype == self.ptype: #Avoid duplicates while running on loopback interface if p[RTP].sequence not in self.sequences: self.lengths.append(p.len) self.times.append(p.time) self.sequences.append(p[RTP].sequence + self.__add) self.timestamps.append(p[RTP].timestamp) VTLOG.debug("UDP/RTP packet found. Sequence: " + str(p[RTP].sequence)) if p[RTP].sequence == 65535: self.__add += 65536 play = False for p in self.cap: if p.haslayer(IP): if (str(p).find("PAUSE") != -1) and play: VTLOG.debug("PAUSE found!") break if not play: play = self.__prepare(p) elif play and (p[IP].src == self.conf['ip']) and ( p.haslayer(UDP)) and (str(p).find("GStreamer") == -1): if (p.sport == self.sport) and (p.dport == self.dport): extract(p) bubbleSort(self.sequences, self.times, self.timestamps) VTLOG.debug("Sequence list sorted")
def __parseUDP(self): """ Parse RTP over UDP session. """ def extract(p): """ Extract information from a UDP packet. :param Packet p: UDP packet. """ ptype = ord(str(p[UDP].payload)[1]) & 0x7F #Delete RTP marker p[UDP].decode_payload_as(RTP) if ptype == self.ptype: #Avoid duplicates while running on loopback interface if p[RTP].sequence not in self.sequences: self.lengths.append(p.len) self.times.append(p.time) self.sequences.append(p[RTP].sequence + self.__add) self.timestamps.append(p[RTP].timestamp) VTLOG.debug("UDP/RTP packet found. Sequence: " + str(p[RTP].sequence)) if p[RTP].sequence == 65535: self.__add += 65536 play = False for p in self.cap: if p.haslayer(IP): if (str(p).find("PAUSE") != -1) and play: VTLOG.debug("PAUSE found!") break if not play: play = self.__prepare(p) elif play and (p[IP].src == self.conf['ip']) and (p.haslayer(UDP)) and (str(p).find("GStreamer") == -1): if (p.sport == self.sport) and (p.dport == self.dport): extract(p) bubbleSort(self.sequences, self.times, self.timestamps) VTLOG.debug("Sequence list sorted")
def calculate(self): bubbleSort(self.times, self.lengths) x = self.times y = [0 for i in range(0, len(x))] for i in range(1, len(x)): if x[i] == x[i - 1]: y[i] = -1 supr = True while supr: try: x.pop(y.index(-1)) y.pop(y.index(-1)) self.lengths.pop(y.index(-1)) except: supr = False for i in range(1, len(x)): length = 0 j = i while x[j] + 1 > x[i] and j >= 0: length = length + self.lengths[j] * 8 / 1000 j = j - 1 y[i] = length self.graph(x, y) return self.data
def calculate(self): bubbleSort(self.times, self.lengths) x = self.times y = [0 for i in range(0, len(x))] for i in range(1, len(x)): if x[i] == x[i-1]: y[i] = -1 supr = True while supr: try: x.pop(y.index(-1)) y.pop(y.index(-1)) self.lengths.pop(y.index(-1)) except: supr = False for i in range(1, len(x)): length = 0 j = i while x[j] + 1 > x[i] and j >= 0: length = length + self.lengths[j] * 8 / 1000 j = j - 1 y[i] = length self.graph(x, y) return self.data
def __parseTCP(self): """ Parse RTP over TCP session. """ def extract(p): """ Extract many RTSP packets from a TCP stream recursively. :param Packet p: TCP stream. """ fin = False a = p[RTSPi].length b = p[RTSPi].payload c = str(b)[0:a] loss = c.find('PACKETLOSS') if loss == -1: #No loss: look inside then ptype = ord(str( p[RTSPi].payload)[1]) & 0x7F #Delete RTP marker if ptype == self.ptype: aux = str(p).split('ENDOFPACKET') p[RTSPi].decode_payload_as(RTP) #Avoid duplicates while running on loopback interface if p[RTP].sequence not in self.sequences: self.lengths.append(int(aux[2])) self.times.append(float(aux[1]) / 1000000) self.sequences.append(p[RTP].sequence + self.__add) self.timestamps.append(p[RTP].timestamp) VTLOG.debug("TCP/RTP packet found. Sequence: " + str(p[RTP].sequence)) if p[RTP].sequence == 65535: self.__add += 65536 else: #Avoid PACKETLOSS a = loss + len('PACKETLOSS') VTLOG.debug("PACKETLOSS!") p = RTSPi(str(b)[a:len(b)]) ptype = ord(str(p[RTSPi].payload)[1]) & 0x7F #Let's find the next RTSP packet while not fin and not ((p[RTSPi].magic == 0x24) and (p[RTSPi].channel == 0x00) and (ptype == self.ptype)): stream = str(p) if stream.find('PACKETLOSS') == 0: #Avoid PACKETLOSS stream = stream[len('PACKETLOSS'):len(stream)] VTLOG.debug("PACKETLOSS!") else: #Find next packet stream = stream[1:len(stream)] if len(stream) > 5: p = RTSPi(stream) ptype = ord(str(p[RTSPi].payload)[1]) & 0x7F else: #Yep! We're done! fin = True if not fin: extract(p) def fillGaps(seqlist, lenlist): """ Locate packet losses. :param list seqlist: List of RTP sequence numbers. :param list lenlist: List of packet lengths. :returns: List of losses (0 -> no loss, 1 -> loss). :rtype: list """ fill = [0 for i in range(0, len(seqlist))] for i in range(0, len(seqlist) - 1): if seqlist[i] + lenlist[i] < seqlist[i + 1]: fill[i] = 1 return fill play = False packetlist = [] seqlist = [] lenlist = [] for p in self.cap: if p.haslayer(IP): if (str(p).find("PAUSE") != -1) and play: VTLOG.debug("PAUSE found!") break if not play: play = self.__prepare(p) #Packets from server, with TCP layer. Avoid ACK's. Avoid RTSP packets elif play and (p[IP].src == self.conf['ip']) and p.haslayer(TCP) and ( len(p) > 66) and (str(p).find("RTSP/1.0") == -1): if (p.sport == self.sport) and (p.dport == self.dport): packetlist.append(p) seqlist.append(p[TCP].seq) lenlist.append(len(p[TCP].payload)) VTLOG.debug("TCP packet appended. Sequence: " + str(p[TCP].seq)) bubbleSort(seqlist, packetlist, lenlist) VTLOG.debug("Sequence list sorted") #Locate packet losses fill = fillGaps(seqlist, lenlist) stream = '' for i, p in enumerate(packetlist): stream = ''.join([stream, str(p[TCP].payload)]) #Mark ENDOFPACKET and save time and length stream = ''.join([stream, 'ENDOFPACKET']) stream = ''.join([stream, str(int(p.time * 1000000))]) stream = ''.join([stream, 'ENDOFPACKET']) stream = ''.join([stream, str(p.len)]) stream = ''.join([stream, 'ENDOFPACKET']) if fill[i]: #Mark PACKETLOSS VTLOG.debug("PACKETLOSS!") stream = ''.join([stream, 'PACKETLOSS']) VTLOG.debug("TCP payloads assembled") stream = RTSPi(stream) extract(stream)
def __parseTCP(self): """ Parse RTP over TCP session. """ def extract(p): """ Extract many RTSP packets from a TCP stream recursively. :param Packet p: TCP stream. """ fin = False a = p[RTSPi].length b = p[RTSPi].payload c = str(b)[0:a] loss = c.find('PACKETLOSS') if loss == -1: #No loss: look inside then ptype = ord(str(p[RTSPi].payload)[1]) & 0x7F #Delete RTP marker if ptype == self.ptype: aux = str(p).split('ENDOFPACKET') p[RTSPi].decode_payload_as(RTP) #Avoid duplicates while running on loopback interface if p[RTP].sequence not in self.sequences: self.lengths.append(int(aux[2])) self.times.append(float(aux[1]) / 1000000) self.sequences.append(p[RTP].sequence + self.__add) self.timestamps.append(p[RTP].timestamp) VTLOG.debug("TCP/RTP packet found. Sequence: " + str(p[RTP].sequence)) if p[RTP].sequence == 65535: self.__add += 65536 else: #Avoid PACKETLOSS a = loss + len('PACKETLOSS') VTLOG.debug("PACKETLOSS!") p = RTSPi(str(b)[a:len(b)]) ptype = ord(str(p[RTSPi].payload)[1]) & 0x7F #Let's find the next RTSP packet while not fin and not ((p[RTSPi].magic == 0x24) and (p[RTSPi].channel == 0x00) and (ptype == self.ptype)): stream = str(p) if stream.find('PACKETLOSS') == 0: #Avoid PACKETLOSS stream = stream[len('PACKETLOSS'):len(stream)] VTLOG.debug("PACKETLOSS!") else: #Find next packet stream = stream[1:len(stream)] if len(stream) > 5: p = RTSPi(stream) ptype = ord(str(p[RTSPi].payload)[1]) & 0x7F else: #Yep! We're done! fin = True if not fin: extract(p) def fillGaps(seqlist, lenlist): """ Locate packet losses. :param list seqlist: List of RTP sequence numbers. :param list lenlist: List of packet lengths. :returns: List of losses (0 -> no loss, 1 -> loss). :rtype: list """ fill = [0 for i in range(0, len(seqlist))] for i in range(0, len(seqlist)-1): if seqlist[i] + lenlist[i] < seqlist[i+1]: fill[i] = 1 return fill play = False packetlist = [] seqlist = [] lenlist = [] for p in self.cap: if p.haslayer(IP): if (str(p).find("PAUSE") != -1) and play: VTLOG.debug("PAUSE found!") break if not play: play = self.__prepare(p) #Packets from server, with TCP layer. Avoid ACK's. Avoid RTSP packets elif play and (p[IP].src == self.conf['ip']) and p.haslayer(TCP) and (len(p) > 66) and (str(p).find("RTSP/1.0") == -1): if (p.sport == self.sport) and (p.dport == self.dport): packetlist.append(p) seqlist.append(p[TCP].seq) lenlist.append(len(p[TCP].payload)) VTLOG.debug("TCP packet appended. Sequence: " + str(p[TCP].seq)) bubbleSort(seqlist, packetlist, lenlist) VTLOG.debug("Sequence list sorted") #Locate packet losses fill = fillGaps(seqlist, lenlist) stream = '' for i, p in enumerate(packetlist): stream = ''.join([stream, str(p[TCP].payload)]) #Mark ENDOFPACKET and save time and length stream = ''.join([stream, 'ENDOFPACKET']) stream = ''.join([stream, str(int(p.time * 1000000))]) stream = ''.join([stream, 'ENDOFPACKET']) stream = ''.join([stream, str(p.len)]) stream = ''.join([stream, 'ENDOFPACKET']) if fill[i]: #Mark PACKETLOSS VTLOG.debug("PACKETLOSS!") stream = ''.join([stream, 'PACKETLOSS']) VTLOG.debug("TCP payloads assembled") stream = RTSPi(stream) extract(stream)