def process_packet(self, pktlen, data, timestamp): global verbose global camera_ip def possiblemeaning(no): return self.descriptions.get(no, "???") def possibledecode(no, data): func = self.call.get(cmd, FoscDecoder.printhex) try: error = func(ip.tcp.data) except BaseException as e: error = e.message print("*** Decode error: {}".format(e.message)) # Remember # of command for print_stats if no not in self.errors: self.errors.append(no) # call method for some housekeeping self.process_packet(pktlen, data, timestamp) # let dpkt analyse the packet ether = dpkt.ethernet.Ethernet(data) # is it an IP packet? if ether.type != dpkt.ethernet.ETH_TYPE_IP: return # get the content of the IP packet ip = ether.data # is it a TCP/IP packet? if ip.p != dpkt.ip.IP_PROTO_TCP: return # only traffic, from/to the camera if not (socket.inet_ntoa(ip.src) == camera_ip or socket.inet_ntoa(ip.dst) == camera_ip): return # check for HTTP traffic try: http_rq = dpkt.http.Request(ip.tcp.data) print("\nURL-Req: {}".format(urllib.unquote(http_rq.uri))) self.remember_me(http_rq.uri) except dpkt.dpkt.UnpackError: pass # check for "low/level" traffic # is the tcp data larger than 12 bytes? # 4 bytes length information, 4 bytes "FOSC", 4 bytes data len if len(ip.tcp.data) < 12: return # unpack those 8 bytes cmd, magic, datalen = FoscDecoder.unpack("<I4sI", ip.tcp.data) # is the "magic" identifier present? if magic != 'FOSC': return # ignore LoninTest/Reply if cmd in [15, 29]: return # ignore video in if cmd == 26: return # if cmd != 0: return # diff = FoscDecoder.datacomp.put(ip.tcp.data) # FoscDecoder.printhex(ip.tcp.data, "cmd0", diff) # return if not cmd in [106, 107]: return # if cmd in [12, 15, 29, 26]: return if not verbose: print(cmd) return # stop after a given number of decoded packets # if self.count_shown > 10: return # if datalen <= 996: return # 1956 # do some stats self.count_as_shown() self.test_data(ip.tcp.data) self.remember_me(cmd) print() print_src_dest_ip(ip) if socket.inet_ntoa(ip.src) == camera_ip: print("Camera -> User") if socket.inet_ntoa(ip.dst) == camera_ip: print("User -> Camera") print("#%s @ %s:" % (self.count, self.rel_timestamp)) # position in pcap file print("command %s: %s" % (cmd, possiblemeaning(cmd))) print("tcp data length: {}".format(len(ip.tcp.data))) print("datalen {}".format(datalen)) if (datalen + 12) != len(ip.tcp.data): print("Packet length mismatch! Multiple commands in one packet/one command in multiple packets?") possibledecode(cmd, ip.tcp.data) if (datalen + 12) < len(ip.tcp.data): print("Additional data: {}".format(FoscDecoder.printhex(ip.tcp.data[datalen + 12:])))
class fosc_analyser(analyser): """ class to analyse the live or offline capture """ def __init__(self): analyser.__init__(self) # Some additional general stats: # # remember: remember the order in which the commands are found # stat: count how many of each command were detected self.remember = [] self.stat = {} self.errors = [] self.descriptions = FoscDecoder.decoder_descriptions self.call = FoscDecoder.decoder_call def remember_me(self,cmd): self.remember.append(cmd) if cmd in self.stat: self.stat[cmd] += 1 else: self.stat[cmd] = 1 def print_stat(self): analyser.print_stat(self) print "Remember" print self.remember for x in sorted(self.stat): print "cmd %s: %s" % (x, self.stat[x]) if len(self.errors) > 0: print "Decoding errors in cmds:", self.errors def process_packet(self, pktlen, data, timestamp): global verbose global camera_ip def possiblemeaning(no): return self.descriptions.get(no,"???") def possibledecode(no, data): func = self.call.get(cmd, FoscDecoder.printhex) try: error = func(ip.tcp.data) except BaseException, e: error = e.message print "*** Decode error: "+e.message # Remember # of command for print_stats if not no in self.errors: self.errors.append(no) # call super methode for some housekeeping analyser.process_packet(self,pktlen, data, timestamp) # let dpkt analyse the packet ether = dpkt.ethernet.Ethernet(data) # is it an IP packet? if ether.type != dpkt.ethernet.ETH_TYPE_IP: return # get the content of the IP packet ip = ether.data # is it a TCP/IP packet? if ip.p != dpkt.ip.IP_PROTO_TCP: return # only traffic, from/to the camera if not ( socket.inet_ntoa(ip.src) == camera_ip or socket.inet_ntoa(ip.dst) == camera_ip): return # check for HTTP traffic try: http_rq = dpkt.http.Request(ip.tcp.data) print "\nURL-Req:", urllib.unquote(http_rq.uri) self.remember_me(http_rq.uri) except dpkt.dpkt.UnpackError: pass # check for "low/level" traffic # is the tcp data larger than 12 bytes? # 4 bytes length information, 4 bytes "FOSC", 4 bytes data len if len(ip.tcp.data)<12: return # unpack those 8 bytes cmd, magic, datalen = FoscDecoder.unpack("<I4sI",ip.tcp.data) # is the "magic" identifier present? if magic != 'FOSC': return # ignore LoninTest/Reply if cmd in [15,29]: return # ignore video in if cmd == 26: return # if cmd != 0: return # diff = FoscDecoder.datacomp.put(ip.tcp.data) # FoscDecoder.printhex(ip.tcp.data, "cmd0", diff) # return if not cmd in [106,107]: return # if cmd in [12, 15, 29, 26]: return if not verbose: print cmd return # stop after a given number of decoded packets # if self.count_shown > 10: return # if datalen <= 996: return # 1956 # do some stats self.count_as_shown() analyser.test_data(self,ip.tcp.data) self.remember_me(cmd) print print_src_dest_ip(ip) if socket.inet_ntoa(ip.src) == camera_ip: print "Camera -> User" if socket.inet_ntoa(ip.dst) == camera_ip: print "User -> Camera" print "#%s @ %s:" % (self.count, self.rel_timestamp) # position in pcap file print "command %s: %s" % (cmd, possiblemeaning(cmd)) print "tcp data length:", len(ip.tcp.data) print "datalen", datalen if (datalen+12) != len(ip.tcp.data): print "Packet length mismatch! Multiple commands in one packet/one command in multiple packets?" possibledecode(cmd,ip.tcp.data) if (datalen+12) < len(ip.tcp.data): print "Additional data:" FoscDecoder.printhex(ip.tcp.data[datalen+12:])
def process_packet(self, pktlen, data, timestamp): global verbose global camera_ip def possiblemeaning(no): return self.descriptions.get(no, "???") def possibledecode(no, data): func = self.call.get(cmd, FoscDecoder.printhex) try: error = func(ip.tcp.data) except BaseException as e: error = e.message print("*** Decode error: {}".format(e.message)) # Remember # of command for print_stats if no not in self.errors: self.errors.append(no) # call method for some housekeeping self.process_packet(pktlen, data, timestamp) # let dpkt analyse the packet ether = dpkt.ethernet.Ethernet(data) # is it an IP packet? if ether.type != dpkt.ethernet.ETH_TYPE_IP: return # get the content of the IP packet ip = ether.data # is it a TCP/IP packet? if ip.p != dpkt.ip.IP_PROTO_TCP: return # only traffic, from/to the camera if not (socket.inet_ntoa(ip.src) == camera_ip or socket.inet_ntoa(ip.dst) == camera_ip): return # check for HTTP traffic try: http_rq = dpkt.http.Request(ip.tcp.data) print("\nURL-Req: {}".format(urllib.unquote(http_rq.uri))) self.remember_me(http_rq.uri) except dpkt.dpkt.UnpackError: pass # check for "low/level" traffic # is the tcp data larger than 12 bytes? # 4 bytes length information, 4 bytes "FOSC", 4 bytes data len if len(ip.tcp.data) < 12: return # unpack those 8 bytes cmd, magic, datalen = FoscDecoder.unpack("<I4sI", ip.tcp.data) # is the "magic" identifier present? if magic != 'FOSC': return # ignore LoninTest/Reply if cmd in [15, 29]: return # ignore video in if cmd == 26: return # if cmd != 0: return # diff = FoscDecoder.datacomp.put(ip.tcp.data) # FoscDecoder.printhex(ip.tcp.data, "cmd0", diff) # return if not cmd in [106, 107]: return # if cmd in [12, 15, 29, 26]: return if not verbose: print(cmd) return # stop after a given number of decoded packets # if self.count_shown > 10: return # if datalen <= 996: return # 1956 # do some stats self.count_as_shown() self.test_data(ip.tcp.data) self.remember_me(cmd) print() print_src_dest_ip(ip) if socket.inet_ntoa(ip.src) == camera_ip: print("Camera -> User") if socket.inet_ntoa(ip.dst) == camera_ip: print("User -> Camera") print("#%s @ %s:" % (self.count, self.rel_timestamp)) # position in pcap file print("command %s: %s" % (cmd, possiblemeaning(cmd))) print("tcp data length: {}".format(len(ip.tcp.data))) print("datalen {}".format(datalen)) if (datalen + 12) != len(ip.tcp.data): print( "Packet length mismatch! Multiple commands in one packet/one command in multiple packets?" ) possibledecode(cmd, ip.tcp.data) if (datalen + 12) < len(ip.tcp.data): print("Additional data: {}".format( FoscDecoder.printhex(ip.tcp.data[datalen + 12:])))