def proc(self,cmd,size,body): """ try to use decoder subroutines """ print "Incoming cmd: %s, size %s" % (cmd,size) # Let's check all try: decoder = FoscDecoder.decoder_call.get(cmd) if decoder is None: FoscDecoder.printhex(body) else: decoder(struct.pack("<I4sI",cmd,"FOSC",size) + body) except BaseException, e: msg = "cmd %s: %s" % (cmd, e.message) self.decodeerror.append(msg) print "** DECODE ERROR: " + msg
def proc(self, cmd, size, body): """ try to use decoder subroutines """ print("Incoming cmd: %s, size %s" % (cmd, size)) # Let's check all try: decoder = FoscDecoder.decoder_call.get(cmd) if decoder is None: FoscDecoder.printhex(body) else: decoder(struct.pack("<I4sI", cmd, "FOSC", size) + body) except BaseException as e: msg = "cmd %s: %s" % (cmd, e.message) self.decodeerror.append(msg) print("** DECODE ERROR: {}".format(msg))
def run(self): # Mode: # 0: awaiting header # 1: reading data # 2: try to resync mode = 0 remaining = 0 body = "" while not self.endflag: try: if mode == 0: data = self.socket.recv(12) if len(data) == 0: print("Connection closed by peer") self.endflag = True break cmd, magic, size = struct.unpack("<I4sI", data) if magic != "FOSC": print("**************** resync *************") FoscDecoder.printhex(data) mode = 2 self.resync_count += 1 else: self.read_sequence.append(cmd) body = "" remaining = size mode = 1 elif mode == 1: incoming = self.socket.recv(remaining) body += incoming remaining -= len(incoming) print("remaining {}".format( remaining)) if remaining == 0: mode = 0 self.proc(cmd, size, body) else: data = self.socket.recv(2000) # clear incoming buffer if len(data) == 0: mode = 0 else: FoscDecoder.printhex(data) except socket.timeout: mode = 0 print(self.name) except struct.error: print("unpack error") FoscDecoder.printhex(data)
def run(self): # Mode: # 0: awaiting header # 1: reading data # 2: try to resync mode = 0 remaining = 0 body = "" while not self.endflag: try: if mode == 0: data = self.socket.recv(12) if len(data)==0: print "Connection closed by peer" self.endflag = True break cmd, magic, size = struct.unpack("<I4sI",data) if magic != "FOSC": print "**************** resync *************" FoscDecoder.printhex(data) mode = 2 self.resync_count += 1 else: self.read_sequence.append(cmd) body = "" remaining = size mode = 1 elif mode == 1: incoming = self.socket.recv(remaining) body += incoming remaining -= len(incoming) print "remaining",remaining if remaining == 0: mode = 0 self.proc(cmd,size,body) else: data = self.socket.recv(2000) # clear incoming buffer if len(data) == 0: mode = 0 else: FoscDecoder.printhex(data) except socket.timeout: mode = 0 print self.name , except struct.error: print "unpack error" FoscDecoder.printhex(data)
def send_command(self, command, data, verbose=True): dt = struct.pack("<I4sI", command, "FOSC", len(data)) + data print("%s: Sending data" % self.name) if verbose: FoscDecoder.printhex(dt) self.con.send(dt)
delay(5), do_audio_stop(), delay(2), do_video_start(), do_audio_start(), delay(5), do_audio_stop(), do_speaker_on(), delay(2), do_speaker_off(), delay(2), """ """ ( spush.send_cmd6, (playme, 960)), # send audio data to cam """ for cmd in testprogram: func = cmd[0] par = cmd[1] func(*par) # time.sleep(0.5) finally: # Always shut the thread down spush.close() # Display the UID used print("\n** uid: 0x%08x (%s)" % (uid, uid)) FoscDecoder.closeAudioDumpFile() FoscDecoder.datacomp.stats()
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 send_command(self,command,data, verbose = True): dt = struct.pack("<I4sI", command, "FOSC", len(data)) + data print "%s: Sending data" % self.name if verbose: FoscDecoder.printhex(dt) self.con.send(dt)
delay(5), do_audio_stop(), delay(2), do_video_start(), do_audio_start(), delay(5), do_audio_stop(), do_speaker_on(), delay(2), do_speaker_off(), delay(2), """ """ ( spush.send_cmd6, (playme, 960)), # send audio data to cam """ for cmd in testprogram: func = cmd[0] par = cmd[1] func( *par ) # time.sleep(0.5) finally: # Always shut the thread down spush.close() # Display the UID used print "\n** uid: 0x%08x (%s)" % (uid, uid) FoscDecoder.closeAudioDumpFile() FoscDecoder.datacomp.stats()
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:])))
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:])))