#!/usr/bin/python3 # -*- coding: utf-8 -*- # # script to read pcap file (communcation with khanat) # # Copyright (C) 2019 AleaJactaEst # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # Ex.: # sudo tcpdump -i docker0 -w capture2.pcap # ./spykhanat.py --pcap-file=../capture2.pcap --msg-xml=../khanat-opennel-code/code/ryzom/common/data_common/msg.xml import argparse import logging from pcapfile import savefile from pcapfile.protocols.linklayer import ethernet from pcapfile.protocols.network import ip from pcapfile.protocols.transport import udp from pcapfile.protocols.transport import tcp import binascii import re from tools import BitStream from tools import Enum from tools import CActionFactory from tools import CBitSet from tools import DecodeImpulse from tools import World from tools import CGenericMultiPartTemp from tools import CImpulseDecoder from tools import CStringManager from tools import CAction import xml.etree.ElementTree as ET from datetime import datetime LOGGER = 'SpyKhanat' #file = open('capture2.pcap' , 'rb') #pcapfile = savefile.load_savefile(file,verbose=True) #pkt = pcapfile.packets[0] #print(pkt.raw()) #print(pkt.timestamp) #eth_frame = ethernet.Ethernet(pkt.raw()) #print(eth_frame) #ip_packet = ip.IP(binascii.unhexlify(eth_frame.payload)) #print(ip_packet) class SpyPcap(): def __init__(self, khanat_host_service, pcap_file, msg_xml, filter_host_service, show_raw_packet, show_message_decoded, outyaml=None): if khanat_host_service: self.khanat_host_service = re.compile(khanat_host_service) else: self.khanat_host_service = None self.pcap_file = pcap_file self.msg_xml = msg_xml if filter_host_service: self.filter_host_service = re.compile(filter_host_service) else: self.filter_host_service = None self.show_raw_packet = show_raw_packet self.show_message_decoded = show_message_decoded self.actionFactory = CActionFactory.CActionFactory(None) self.client_state = {} self.decodeImpulse = DecodeImpulse.DecodeImpulse() fp = open(msg_xml , 'rt') msgRawXml = fp.read() self.msgXml = ET.fromstring(msgRawXml) self.decodeImpulse.loadMsg(self.msgXml) self.outyaml = outyaml def readRaw(self): file = open( self.pcap_file , 'rb') pcapfile = savefile.load_savefile(file,verbose=False) for pkt in pcapfile.packets: print("pkt:", dir(pkt)) print("pkt.header:", dir(pkt.header)) print("pkt.packet:", dir(pkt.packet)) logging.getLogger(LOGGER).debug("raw: %s" % pkt.raw()) logging.getLogger(LOGGER).debug("timestamp: %s (%s)" % (pkt.timestamp,datetime.fromtimestamp(pkt.timestamp).strftime("%Y/%m/%d %H:%M:%S"))) eth_frame = ethernet.Ethernet(pkt.raw()) logging.getLogger(LOGGER).debug("eth_frame: %s" % eth_frame) if eth_frame.type == 2048: ip_packet = ip.IP(binascii.unhexlify(eth_frame.payload)) logging.getLogger(LOGGER).debug("ip packet: %s" % ip_packet) print("ip_packet:", dir(ip_packet)) logging.getLogger(LOGGER).debug("ip packet: %s ->%s" % (ip_packet.src.decode(), ip_packet.dst.decode()) ) if ip_packet.p == 17: # UDP logging.getLogger(LOGGER).debug("ip packet: protocol UDP (%s)" % ip_packet.p) udp_packet = udp.UDP(binascii.unhexlify(ip_packet.payload)) print("udp_packet:", dir(udp_packet)) logging.getLogger(LOGGER).debug("UDP packet: %s" % udp_packet) data = udp_packet.payload print("data:", dir(data)) logging.getLogger(LOGGER).debug("data packet: %s" % data) data = udp_packet.payload logging.getLogger(LOGGER).info("data packet: timestamp:%s src:%s:%d dst:%s:%d data:%s" % (pkt.timestamp, ip_packet.src.decode(), udp_packet.src_port, ip_packet.dst.decode(), udp_packet.dst_port, data.decode())) elif ip_packet.p == 6: # TCP logging.getLogger(LOGGER).debug("ip packet: protocol TCP (%s)" % ip_packet.p) tcp_packet = tcp.TCP(binascii.unhexlify(ip_packet.payload)) data = tcp_packet.payload logging.getLogger(LOGGER).info("data packet: timestamp:%s src:%s:%d dst:%s:%d data:%s" % (pkt.timestamp, ip_packet.src.decode(), tcp_packet.src_port, ip_packet.dst.decode(), tcp_packet.dst_port, data.decode())) else: logging.getLogger(LOGGER).debug("ip packet: protocol (%s)" % ip_packet.p) def detect_khanat_server(self, packets): hostdetected = {} for pkt in packets: eth_frame = ethernet.Ethernet(pkt.raw()) if eth_frame.type == 2048: ip_packet = ip.IP(binascii.unhexlify(eth_frame.payload)) if ip_packet.p == 17: # UDP udp_packet = udp.UDP(binascii.unhexlify(ip_packet.payload)) data = udp_packet.payload host = "%s:%d" % (ip_packet.src.decode(), udp_packet.src_port) hostdetected.setdefault(host, 0) if len(data) == 20: hostdetected[host] += 1 id = None max = 0 for host in hostdetected: if id: if max < hostdetected[host]: max = hostdetected[host] id = host else: max = hostdetected[host] id = host logging.getLogger(LOGGER).info(" host :%s" % id) return id def initialize_client(self, clientid): self.client_state.setdefault(clientid, {'CurrentReceivedNumber': 0, 'CurrentSendNumber': 0, 'LastReceivedAck': 0, 'AckBitMask': 0, 'RegisteredAction': {}, 'world': World.World(), 'GenericMultiPartTemp': CGenericMultiPartTemp.GenericMultiPartTemp(), 'CImpulseDecoder': None, 'CActionFactory': None, 'LastAck0': [-1], 'LastAck1': [-1, -1], 'LastAck2': [-1, -1, -1, -1]}) self.client_state[clientid]['CImpulseDecoder'] = CImpulseDecoder.CImpulseDecoder(self.client_state[clientid]['world']) self.client_state[clientid]['CActionFactory'] = CActionFactory.CActionFactory(self.client_state[clientid]['world']) def add_registered_action(self, clientid, action): self.client_state[clientid]['RegisteredAction'].setdefault(action.Code, []) self.client_state[clientid]['RegisteredAction'][action.Code].append(action) def decode_server(self, clientid, msgin, receivedPacket, receivedAck, nextSentPacket=0): actions = [] for level in range(0, 3): if level == 0: lAck = self.client_state[clientid]['LastAck0'] channel = 0 elif level == 1: lAck = self.client_state[clientid]['LastAck1'] channel = receivedPacket & 1 elif level == 2: lAck = self.client_state[clientid]['LastAck2'] channel = receivedPacket & 3 keep = True checkOnce = False num = 0 #logging.getLogger(LOGGER).debug("level:%d channel:%d lAck:%s" %(level, channel, ':'.join([str(x) for x in lAck]))) # lastAck = lAck[channel] while True: next = msgin.readBool('next:' + str(level) + ':' + str(channel)) if not next: break if not checkOnce: checkOnce = True keep = receivedAck >= lAck[channel] logging.getLogger(LOGGER).debug("keep:%s [%d => %d]" % (str(keep), receivedAck, lAck[channel])) if keep: lAck[channel] = nextSentPacket logging.getLogger(LOGGER).debug("lAck:%s" % ':'.join([str(x) for x in lAck])) pass num += 1 #actionFactory = CAction.CActionFactory(None) action = self.actionFactory.unpack(msgin) logging.getLogger(LOGGER).debug("action:%s" % action) #action = self._CActionFactory.unpack(msgin) if keep: logging.getLogger(LOGGER).debug("keep Code:%s" % str(action.Code)) actions.append(action) elif action: logging.getLogger(LOGGER).debug("append Code:%s" % str(action.Code)) self.add_registered_action(clientid, action) return actions # def decode_client_receive_normal_message(self, msgin, clientid, dst): # actions = self.client_state[clientid]['CImpulseDecoder'].decode(msgin, self.client_state[clientid]['CurrentReceivedNumber'], self.client_state[clientid]['LastReceivedAck'], self.client_state[clientid]['CurrentSendNumber'] ) # logging.getLogger(LOGGER).info("[Client -> Server] actions:%s" % str(actions)) # # decodeVisualProperties( msgin ); def decode_client_send_normal_message(self, msgin, clientid, dst, sequenceid, name): ''' khanat-opennel-code/code/ryzom/client/src/network_connection.cpp:2029 void CNetworkConnection::sendNormalMessage() khanat-opennel-code/code/ryzom/common/src/game_share/action_block.cpp:36 void CActionBlock::serial(CBitMemStream &msg) ''' #actions = self.client_state[clientid]['CImpulseDecoder'].decode(msgin, self.client_state[clientid]['CurrentReceivedNumber'], self.client_state[clientid]['LastReceivedAck'], self.client_state[clientid]['CurrentSendNumber'] ) actions = [] noerror = True msgin.disable_LogErrorOnStreamOverflow() while noerror: try: cycle = msgin.readUint32("Cycle") num = msgin.readUint8("num") logging.getLogger(LOGGER).debug("[Client -> Server] Cycle:%u num:%u" % (cycle, num)) for i in range(0, num): actions.append(self.client_state[clientid]['CActionFactory'].unpack(msgin)) pass except BitStream.OverflowError: noerror = False except Exception as e: logging.getLogger(LOGGER).debug("[Client -> Server] end %s (not read:%u)" % (e.__class__, msgin.needRead())) raise e msgin.enable_LogErrorOnStreamOverflow() logging.getLogger(LOGGER).debug("[Client -> Server] detail actions [%d] => %s" % ( len(actions), ', '.join([str(x) for x in actions]))) # decodeVisualProperties( msgin ); if self.outyaml and actions: self.outyaml.write("\nblock_%s_udp_%d:\n" %(name, sequenceid)) id = 0 for action in actions: self.outyaml.write(" action_%s_udp_%d_%d:\n" %(name, sequenceid, id)) params = action.get_parameter() for key in params: self.outyaml.write(" %s: %s\n" % (key, params[key])) id += 1 def decode_client_message(self, msgin, clientid, dst, sequenceid, name): CurrentReceivedNumber = msgin.readSint32('CurrentReceivedNumber') SystemMode = msgin.readBool('SystemMode') logging.getLogger(LOGGER).debug("[Client -> Server] {CurrentReceivedNumber:%d, SystemMode:%d, src:%s, dst:%s}" % (CurrentReceivedNumber, SystemMode, clientid, dst)) self.initialize_client(clientid) self.client_state[clientid]['CurrentReceivedNumber'] = CurrentReceivedNumber if not SystemMode: ''' khanat-opennel-code/code/ryzom/client/src/network_connection.cpp:2029 void CNetworkConnection::sendNormalMessage() ''' LastReceivedAck = msgin.readSint32('LastReceivedAck') self.client_state[clientid]['LastReceivedAck'] = LastReceivedAck AckBitMask = msgin.readUint32('AckBitMask') self.client_state[clientid]['AckBitMask'] = AckBitMask logging.getLogger(LOGGER).info("[Client -> Server] Normal Mode {CurrentReceivedNumber:%d, src:%s, dst:%s, LastReceivedAck:%d}" % (CurrentReceivedNumber, clientid, dst, LastReceivedAck)) #self.decode_server(msgin, _CurrentReceivedNumber, _CurrentReceivedNumber-1) self.decode_client_send_normal_message(msgin, clientid, dst, sequenceid, name) else: message = msgin.readUint8('message') try: typeMessage = Enum.CLFECOMMON(message).name except ValueError: typeMessage = "Unknown" if message == Enum.CLFECOMMON.SYSTEM_LOGIN_CODE: UserAddr = msgin.readUint32('UserAddr') UserKey = msgin.readUint32('UserKey') UserId = msgin.readUint32('UserId') LanguageCode = msgin.readString('LanguageCode') logging.getLogger(LOGGER).info("[Client -> Server] System Mode:%s {CurrentReceivedNumber:%d, src:%s, dst:%s, UserAddr:%d, UserId:%d, UserAddr:%d LanguageCode:%s}" % (typeMessage, CurrentReceivedNumber, clientid, dst, UserAddr, UserKey, UserId, LanguageCode)) elif message == Enum.CLFECOMMON.SYSTEM_PROBE_CODE: LatestProbe = msgin.readSint32('LatestProbe') logging.getLogger(LOGGER).info("[Client -> Server] System Mode:%s probe:%d {CurrentReceivedNumber:%d, src:%s, dst:%s}" % (typeMessage, LatestProbe, CurrentReceivedNumber, clientid, dst)) elif message == Enum.CLFECOMMON.SYSTEM_SYNC_CODE: Synchronize = msgin.readUint32('Synchronize') stime = msgin.readSint64('stime') LatestSync = msgin.readUint32('LatestSync') MsgData = msgin.readArrayUint8(16, 'MsgData') md5Msg = bytes(MsgData) DatabaseData = msgin.readArrayUint8(16, 'DatabaseData') md5Database = bytes(DatabaseData) logging.getLogger(LOGGER).info("[Client -> Server] System Mode:%s {CurrentReceivedNumber:%d, src:%s, dst:%s, Synchronize:%d, stime:%d, LatestSync:%d, MsgData:%s, DatabaseData:%s}" % ( typeMessage, CurrentReceivedNumber, clientid, dst, Synchronize, stime, LatestSync, binascii.hexlify(md5Msg).decode(), binascii.hexlify(md5Database).decode())) elif message == Enum.CLFECOMMON.SYSTEM_ACK_SYNC_CODE: LastReceivedNumber = msgin.readSint32('LastReceivedNumber') LastAckInLongAck = msgin.readSint32('LastAckInLongAck') LongAckBitField = CBitSet.CBitSet() LongAckBitField.readSerial(msgin, 'LongAckBitField') LatestSync = msgin.readSint32('LatestSync') logging.getLogger(LOGGER).info("[Client -> Server] System Mode:%s {CurrentReceivedNumber:%d, src:%s, dst:%s, LastReceivedNumber:%d, LastAckInLongAck:%d, LatestSync:%d, LongAckBitField:%s}" % ( typeMessage, CurrentReceivedNumber, clientid, dst, LastReceivedNumber, LastAckInLongAck, LatestSync, LongAckBitField)) elif message == Enum.CLFECOMMON.SYSTEM_ACK_PROBE_CODE: SizeLatestProbes = msgin.readSint32('SizeLatestProbes') LatestProbes = [] for data in range(0, SizeLatestProbes): LatestProbes.append(msgin.readSint32('LatestProbes')) logging.getLogger(LOGGER).info("[Client -> Server] System Mode:%s (%d) {CurrentReceivedNumber:%d, src:%s, dst:%s, SizeLatestProbes:%d, LatestProbes:%s}" % (typeMessage, message, CurrentReceivedNumber, clientid, dst, SizeLatestProbes, str(LatestProbes))) else: logging.getLogger(LOGGER).info("[Client -> Server] System Mode:%s (%d) {CurrentReceivedNumber:%d, src:%s, dst:%s}" % (typeMessage, message, CurrentReceivedNumber, clientid, dst)) logging.getLogger(LOGGER).debug("[Client -> Server] msg:%s" % msgin.showAllData()) def decode_khanat_message(self, msgin, src, dst, sequenceid, clientname): CurrentSendNumber = msgin.readSint32('CurrentSendNumber') logging.getLogger(LOGGER).debug("[Server -> Client] {CurrentSendNumber:%d, src:%s, dst:%s}" % (CurrentSendNumber, src, dst)) SystemMode = msgin.readBool('SystemMode') self.initialize_client(dst) self.client_state[dst]['CurrentSendNumber'] = CurrentSendNumber if not SystemMode: _LastReceivedAck = msgin.readSint32('LastReceivedAck'); logging.getLogger(LOGGER).debug("[Server -> Client] Normal Mode {CurrentSendNumber:%d, src:%s, dst:%s, _LastReceivedAck:%d}" % (CurrentSendNumber, src, dst, _LastReceivedAck)) actions = self.decode_server(dst, msgin, CurrentSendNumber, CurrentSendNumber-1) if actions: logging.getLogger(LOGGER).debug('list actions: [' + str(len(actions)) + '] ' +','.join( [ str(x) for x in actions] ) ) else: logging.getLogger(LOGGER).debug('list actions: None') # Decode the actions received in the impulsions logging.getLogger(LOGGER).debug('=' * 80) for action in actions: logging.getLogger(LOGGER).debug('-' * 80) logging.getLogger(LOGGER).debug('Analyse actions:%s', action) if action.Code == Enum.TActionCode.ACTION_DISCONNECTION_CODE: logging.getLogger(LOGGER).info("Action : ACTION_DISCONNECTION_CODE") elif action.Code == Enum.TActionCode.ACTION_GENERIC_CODE: action.genericAction(self.decodeImpulse, self.client_state[dst]['world'], self.client_state[dst]['GenericMultiPartTemp']) logging.getLogger(LOGGER).info("[Server -> Client] ACTION_GENERIC_CODE : {CurrentSendNumber:%d, src:%s, dst:%s, _LastReceivedAck:%d, action:%s}" % (CurrentSendNumber, src, dst, _LastReceivedAck, action)) elif action.Code == Enum.TActionCode.ACTION_GENERIC_MULTI_PART_CODE: action.genericAction(self.decodeImpulse, self.client_state[dst]['world'], self.client_state[dst]['GenericMultiPartTemp']) logging.getLogger(LOGGER).debug("[Server -> Client] ACTION_GENERIC_MULTI_PART_CODE : %s" % action) for id in self.client_state[dst]['GenericMultiPartTemp'].data: if self.client_state[dst]['GenericMultiPartTemp'].data[id].isAvailable(): logging.getLogger(LOGGER).info("[Server -> Client] ACTION_GENERIC_MULTI_PART_CODE {CurrentSendNumber:%d, src:%s, dst:%s, _LastReceivedAck:%d, id:%d, msg:%s}" % (CurrentSendNumber, src, dst, _LastReceivedAck, id, self.client_state[dst]['GenericMultiPartTemp'].data[id].read().showAllData())) elif action.Code == Enum.TActionCode.ACTION_DUMMY_CODE: logging.getLogger(LOGGER).info("Action : ACTION_DUMMY_CODE") self.add_registered_action(dst, action) # # remove all old actions that are acked # while self._Actions and self._Actions[0].FirstPacket != 0 and self._Actions[0].FirstPacket < self._LastReceivedAck: # logging.getLogger(LOGGER).debug("remove old action [%d/%d] : %s" % (self._Actions[0].FirstPacket, self._LastReceivedAck, self._Actions[0])) # self._Actions.pop(0) else: message = msgin.readUint8('message') logging.getLogger(LOGGER).debug("[Server -> Client] System Mode {CurrentSendNumber:%d, src:%s, dst:%s, message:%d" % (CurrentSendNumber, src, dst, message)) if message == Enum.CLFECOMMON.SYSTEM_SYNC_CODE: logging.getLogger(LOGGER).debug("[Server -> Client] Synchronize") Synchronize = msgin.readUint32('Synchronize') stime = msgin.readSint64('stime') LatestSync = msgin.readUint32('LatestSync') MsgData = msgin.readArrayUint8(16, 'MsgData') DatabaseData = msgin.readArrayUint8(16, 'DatabaseData') logging.getLogger(LOGGER).info("[Server -> Client] System Mode / Synchronize {CurrentSendNumber:%d, src:%s, dst:%s, message:%d, Synchronize:%d, stime:%d, LatestSync:%d, MsgData:%s, DatabaseData:%s}" % (CurrentSendNumber, src, dst, message, Synchronize, stime, LatestSync, str(MsgData), str(DatabaseData))) elif message == Enum.CLFECOMMON.SYSTEM_STALLED_CODE: logging.getLogger(LOGGER).debug("[Server -> Client] Stalled") logging.getLogger(LOGGER).info("[Server -> Client] System Mode / Stalled {CurrentSendNumber:%d, src:%s, dst:%s, message:%d}" % (CurrentSendNumber, src, dst, message)) elif message == Enum.CLFECOMMON.SYSTEM_PROBE_CODE: logging.getLogger(LOGGER).debug("[Server -> Client] Probe") LatestProbe = msgin.readSint32('LatestProbe') logging.getLogger(LOGGER).info("[Server -> Client] System Mode / Probe {CurrentSendNumber:%d, src:%s, dst:%s, message:%d, LatestProbe:%d}" % (CurrentSendNumber, src, dst, message, LatestProbe)) elif message == Enum.CLFECOMMON.SYSTEM_SERVER_DOWN_CODE: logging.getLogger(LOGGER).info("[Server -> Client] System Mode / BACK-END DOWN {CurrentSendNumber:%d, src:%s, dst:%s, message:%d}" % (CurrentSendNumber, src, dst, message)) else: logging.getLogger(LOGGER).warning("CNET: received system %d in state Login" % message) #cActionFactory = CAction.CActionFactory(None) #cActionFactory.unpack(msgin) logging.getLogger(LOGGER).debug("[Server -> Client] msg:%s" % msgin.showAllData()) def read(self): file = open( self.pcap_file , 'rb') pcapfile = savefile.load_savefile(file,verbose=False) khanat_host = self.detect_khanat_server(pcapfile.packets) clientid = 1 serverid = 1 list_host = {} sequenceid = 1 for pkt in pcapfile.packets: eth_frame = ethernet.Ethernet(pkt.raw()) if eth_frame.type == 2048: ip_packet = ip.IP(binascii.unhexlify(eth_frame.payload)) if ip_packet.p == 17: # UDP udp_packet = udp.UDP(binascii.unhexlify(ip_packet.payload)) data = udp_packet.payload if udp_packet.src_port == 53 or udp_packet.dst_port == 53: continue if not self.filter_host_service or self.filter_host_service.match("%s:%d" % (ip_packet.src.decode(), udp_packet.src_port)) or self.filter_host_service.match("%s:%d" % (ip_packet.dst.decode(), udp_packet.dst_port)): logging.getLogger(LOGGER).debug("-" * 80) if self.show_raw_packet: logging.getLogger(LOGGER).debug("[raw packet] timestamp:%s [%s] src:%s:%d dst:%s:%d data:%s" % (pkt.timestamp, datetime.fromtimestamp(pkt.timestamp).strftime("%Y/%m/%d %H:%M:%S"), ip_packet.src.decode(), udp_packet.src_port, ip_packet.dst.decode(), udp_packet.dst_port, data.decode())) msgin = BitStream.BitStream() msgin.fromBytes(binascii.unhexlify(data)) src = "%s:%d" % (ip_packet.src.decode(), udp_packet.src_port) dst = "%s:%d" % (ip_packet.dst.decode(), udp_packet.dst_port) if (self.khanat_host_service and self.khanat_host_service.match(src)) or ( not self.khanat_host_service and khanat_host == src): if src not in list_host: name = "Server%d" % serverid list_host.setdefault(src, name) serverid += 1 else: if src not in list_host: name = "Client%d" % clientid list_host.setdefault(src, name) clientid += 1 if (self.khanat_host_service and self.khanat_host_service.match(dst)) or ( not self.khanat_host_service and khanat_host == dst): if dst not in list_host: name = "Server%d" % serverid list_host.setdefault(dst, name) serverid += 1 else: if dst not in list_host: name = "Client%d" % clientid list_host.setdefault(dst, name) clientid += 1 if (self.khanat_host_service and self.khanat_host_service.match(src)) or ( not self.khanat_host_service and khanat_host == src): _provenance = 'Server -> Client' logging.getLogger(LOGGER).debug("[%s] (message received) [%s] %s" % (_provenance, datetime.fromtimestamp(pkt.timestamp).strftime("%Y/%m/%d %H:%M:%S"), msgin.showAllData())) self.decode_khanat_message(msgin, src, dst, sequenceid, list_host[dst]) else: _provenance = 'Client -> Server' logging.getLogger(LOGGER).debug("[%s] (message received) [%s] %s" % (_provenance, datetime.fromtimestamp(pkt.timestamp).strftime("%Y/%m/%d %H:%M:%S"), msgin.showAllData())) self.decode_client_message(msgin, src, dst, sequenceid, list_host[dst]) moredata='message decoded' if not msgin.checkOnlyZeroAtEnd(): # msgin.needRead() > 7: moredata = "message partially decoded" if self.show_message_decoded: logging.getLogger(LOGGER).debug("[%s] (%s) %s" % (_provenance, moredata, msgin.showAllData())) if self.outyaml: self.outyaml.write("\nudp_%d:\n sequence: %d\n time: %s\n source: %s\n destination: %s\n function: %s\n adress_source: %s\n adress_destination: %s\n state: %s\n message:\n" % ( sequenceid, sequenceid, datetime.fromtimestamp(pkt.timestamp).strftime("%Y/%m/%d %H:%M:%S"), list_host[src], list_host[dst], _provenance, src, dst, moredata )) for key in msgin.extractAllData(): self.outyaml.write(" - %s\n" % key) sequenceid += 1 for client in self.client_state: logging.getLogger(LOGGER).debug("%s [server tick:%d, client tick:%d]" %(client, self.client_state[client]['CurrentSendNumber'], self.client_state[client]['CurrentReceivedNumber'])) def main(): FORMAT = '%(asctime)-15s %(levelname)s %(filename)s:%(lineno)d %(message)s' logging.basicConfig(format=FORMAT) logger = [] logger.append(logging.getLogger(LOGGER)) logger.append(logging.getLogger(CImpulseDecoder.LOGGER)) #logger.append(logging.getLogger(DecodeImpuls.LOGGER)) #logger.append(logging.getLogger(BitStream.LOGGER)) logger.append(logging.getLogger(CStringManager.LOGGER)) logger.append(logging.getLogger(CAction.LOGGER)) logger.append(logging.getLogger(CActionFactory.LOGGER)) logger.append(logging.getLogger(BitStream.LOGGER)) CImpulseDecoder # logger.append(logging.getLogger('CGenericMultiPartTemp')) parser = argparse.ArgumentParser() parser.add_argument("--khanat-host-service", help="filter to detect khanat host:service (FES)") parser.add_argument("--filter-host-service", help="filter host:service") parser.add_argument("-d", "--debug", help="show debug message", action='store_true') parser.add_argument("-v", "--verbose", help="show verbose message", action='store_true') parser.add_argument("-p", "--pcap-file", help="file pcap to read", required=True) parser.add_argument("-m", "--msg-xml", help="file msg.xml (from server khanat)", required=True) parser.add_argument("-r", "--raw", help="show message raw", action='store_true') parser.add_argument("--yaml", help="generate YAML file (decode all message)", type=argparse.FileType('w'), default=None) parser.add_argument("--show-raw-packet", help="show packet (raw data)", action='store_true') parser.add_argument("--show-message-decoded", help="show packet (raw data)", action='store_true') args = parser.parse_args() if args.debug: level = logging.getLevelName('DEBUG') elif args.verbose: level = logging.getLevelName('INFO') else: level = logging.getLevelName('WARNING') for logid in logger: logid.setLevel(level) logging.getLogger(LOGGER).info("Begin") spy = SpyPcap(khanat_host_service=args.khanat_host_service, pcap_file=args.pcap_file, msg_xml=args.msg_xml, filter_host_service=args.filter_host_service, show_raw_packet=args.show_raw_packet, show_message_decoded=args.show_message_decoded, outyaml=args.yaml) if args.raw: spy.readRaw() else: spy.read() logging.getLogger(LOGGER).info("End") if __name__ == "__main__": main()