update spykhanat, adding other output CSV file

This commit is contained in:
AleaJactaEst 2020-12-02 00:16:51 +01:00
parent da985311be
commit 2ae6bc9329
4 changed files with 90 additions and 10 deletions

View file

@ -15,9 +15,9 @@ sudo tcpdump -i [networkd card] -w [Pcap output]
ex.: sudo tcpdump -i eth0 -w capture-2020-11-28-17-37-57.pcap ex.: sudo tcpdump -i eth0 -w capture-2020-11-28-17-37-57.pcap
### Extract information ### Extract information
python3 spykhanat.py -m [localization msg.xml] --yaml [Yaml Output file] -w [localisation database.xml] -p [Pcap input] --filter-host-service='[Ip address: Port server khaganat]' python3 spykhanat.py -m [localization msg.xml] --yaml [Yaml Output file] -w [localisation database.xml] -p [Pcap input] --filter-host-service='[Ip address: Port server khaganat]' --csv='[file output CSV {comma separator} - extract only normal message]'
Ex.: python3 spykhanat.py -m ~/khanat/khanat-opennel-code/code/ryzom/common/data_common/msg.xml --yaml capture-2020-11-28-17-37-57.yml -w ~/khanat/khanat-opennel-code/code/ryzom/common/data_common/database.xml -p capture-2020-11-28-17-37-57.pcap --filter-host-service='127.0.0.1:47851' Ex.: python3 spykhanat.py -m ~/khanat/khanat-opennel-code/code/ryzom/common/data_common/msg.xml --yaml capture-2020-11-28-17-37-57.yml -w ~/khanat/khanat-opennel-code/code/ryzom/common/data_common/database.xml -p capture-2020-11-28-17-37-57.pcap --filter-host-service='127.0.0.1:47851' --csv capture-2020-11-28-17-37-57.csv
### Analyze result ### Analyze result

View file

@ -77,7 +77,7 @@ def write_yaml_str_or_array(outyaml, nbspace, value):
outyaml.write(" " * nbspace + str(type(value)) + "\n") outyaml.write(" " * nbspace + str(type(value)) + "\n")
class SpyPcap(): class SpyPcap():
def __init__(self, khanat_host_service, pcap_file, msg_xml, database_xml, filter_host_service, show_raw_packet, show_message_decoded, outyaml=None): def __init__(self, khanat_host_service, pcap_file, msg_xml, database_xml, filter_host_service, show_raw_packet, show_message_decoded, outyaml=None, outcsv=False):
if khanat_host_service: if khanat_host_service:
self.khanat_host_service = re.compile(khanat_host_service) self.khanat_host_service = re.compile(khanat_host_service)
else: else:
@ -113,6 +113,7 @@ class SpyPcap():
self.decodeImpulseSimple.loadDatabase(self.decodeDatabase) self.decodeImpulseSimple.loadDatabase(self.decodeDatabase)
# outyaml # outyaml
self.outyaml = outyaml self.outyaml = outyaml
self.outcsv = outcsv
def readRaw(self): def readRaw(self):
file = open( self.pcap_file , 'rb') file = open( self.pcap_file , 'rb')
@ -435,7 +436,7 @@ class SpyPcap():
self.client_state[clientid]['AckBitMask'] = 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)) 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_server(msgin, _CurrentReceivedNumber, _CurrentReceivedNumber-1)
actions, _ = self.decode_client_send_normal_message(msgin, clientid, dst, sequenceid, "%s_%d" % (target, 0), Parent) actions, impulses = self.decode_client_send_normal_message(msgin, clientid, dst, sequenceid, "%s_%d" % (target, 0), Parent)
else: else:
message = msgin.readUint8('message') message = msgin.readUint8('message')
try: try:
@ -708,7 +709,8 @@ class SpyPcap():
sequencenum = 1 sequencenum = 1
if self.outyaml: if self.outyaml:
self.outyaml.write("# Generated : %s\n\n" % (datetime.now().strftime("%Y-%m-%d %H:%M:%S"))) self.outyaml.write("# Generated : %s\n\n" % (datetime.now().strftime("%Y-%m-%d %H:%M:%S")))
if self.outcsv:
self.outcsv.write("Date,Packet Id,Source,Destination,Key,Value\n")
for pkt in pcapfile.packets: for pkt in pcapfile.packets:
eth_frame = ethernet.Ethernet(pkt.raw()) eth_frame = ethernet.Ethernet(pkt.raw())
if eth_frame.type == 2048: if eth_frame.type == 2048:
@ -783,21 +785,67 @@ class SpyPcap():
havedata = True havedata = True
else: else:
havedata = False havedata = False
if not havedata:
for action in actions_servers:
if action.get_notice():
havedata = True
break
if not havedata:
for action in actions_clients:
if action.get_notice():
havedata = True
break
if not havedata: if not havedata:
for impulse_data in impulses_servers: for impulse_data in impulses_servers:
if impulse_data.get_notice(): if impulse_data.get_notice():
havedata = True havedata = True
break break
if not havedata:
for impulse_data in impulses_clients:
if impulse_data.get_notice():
havedata = True
break
if havedata: if havedata:
print(datetime.fromtimestamp(pkt.timestamp).strftime("%Y/%m/%d %H:%M:%S"), _provenance, "(", list_host[src], "=>", list_host[dst], ") [", Reference, "] ") print(datetime.fromtimestamp(pkt.timestamp).strftime("%Y/%m/%d %H:%M:%S"), "[", Reference, "]", list_host[src], "->", list_host[dst])
if importantinfo: if importantinfo:
for key in importantinfo: for key in importantinfo:
print(" " * 3, key, ":", importantinfo[key]) print(" " * 3, key, ":", importantinfo[key])
if impulses_servers: for action in actions_servers:
data = action.get_notice()
for key in data:
print(" " * 3, key, ":", data[key])
for action in actions_clients:
data = action.get_notice()
for key in data:
print(" " * 3, key, ":", data[key])
for impulse_data in impulses_servers:
data = impulse_data.get_notice()
for key in data:
print(" " * 3, key, ":", data[key])
for impulse_data in impulses_clients:
data = impulse_data.get_notice()
for key in data:
print(" " * 3, key, ":", data[key])
print("")
if self.outcsv:
for key in importantinfo:
self.outcsv.write("%s,%s,%s,%s,%s,%s\n" % (datetime.fromtimestamp(pkt.timestamp).strftime("%Y/%m/%d %H:%M:%S"), Reference, list_host[src], list_host[dst], key, importantinfo[key]))
for action in actions_servers:
data = action.get_notice()
for key in data:
self.outcsv.write("%s,%s,%s,%s,%s,%s\n" % (datetime.fromtimestamp(pkt.timestamp).strftime("%Y/%m/%d %H:%M:%S"), Reference, list_host[src], list_host[dst], key, data[key]))
for action in actions_clients:
data = action.get_notice()
for key in data:
self.outcsv.write("%s,%s,%s,%s,%s,%s\n" % (datetime.fromtimestamp(pkt.timestamp).strftime("%Y/%m/%d %H:%M:%S"), Reference, list_host[src], list_host[dst], key, data[key]))
for impulse_data in impulses_servers: for impulse_data in impulses_servers:
data = impulse_data.get_notice() data = impulse_data.get_notice()
for key in data: for key in data:
print(" " * 3, key, ":", data[key]) self.outcsv.write("%s,%s,%s,%s,%s,%s\n" % (datetime.fromtimestamp(pkt.timestamp).strftime("%Y/%m/%d %H:%M:%S"), Reference, list_host[src], list_host[dst], key, data[key]))
for impulse_data in impulses_clients:
data = impulse_data.get_notice()
for key in data:
self.outcsv.write("%s,%s,%s,%s,%s,%s\n" % (datetime.fromtimestamp(pkt.timestamp).strftime("%Y/%m/%d %H:%M:%S"), Reference, list_host[src], list_host[dst], key, data[key]))
if self.outyaml: if self.outyaml:
self.outyaml.write("\n%s:\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" % ( self.outyaml.write("\n%s:\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" % (
@ -961,8 +1009,10 @@ class SpyPcap():
logging.getLogger(LOGGER).debug("%s [server tick:%d, client tick:%d]" %(client, self.client_state[client]['CurrentSendNumber'], self.client_state[client]['CurrentReceivedNumber'])) logging.getLogger(LOGGER).debug("%s [server tick:%d, client tick:%d]" %(client, self.client_state[client]['CurrentSendNumber'], self.client_state[client]['CurrentReceivedNumber']))
if fullconverted: if fullconverted:
logging.getLogger(LOGGER).info("Full converted") logging.getLogger(LOGGER).info("Full converted")
print("\nEnd : Full converted")
else: else:
logging.getLogger(LOGGER).info("Partially converted") logging.getLogger(LOGGER).info("Partially converted")
print("\nEnd : Partially converted")
logging.getLogger(LOGGER).info("Conversion => End") logging.getLogger(LOGGER).info("Conversion => End")
@ -996,6 +1046,7 @@ def main():
parser.add_argument("-w", "--database-xml", help="file database.xml (from server khanat)", required=True) parser.add_argument("-w", "--database-xml", help="file database.xml (from server khanat)", required=True)
parser.add_argument("-r", "--raw", help="show message raw", action='store_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("--yaml", help="generate YAML file (decode all message)", type=argparse.FileType('w'), default=None)
parser.add_argument("--csv", help="generate CSV file (essential 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-raw-packet", help="show packet (raw data)", action='store_true')
parser.add_argument("--show-message-decoded", help="show packet (raw data)", action='store_true') parser.add_argument("--show-message-decoded", help="show packet (raw data)", action='store_true')
@ -1020,7 +1071,8 @@ def main():
filter_host_service=args.filter_host_service, filter_host_service=args.filter_host_service,
show_raw_packet=args.show_raw_packet, show_raw_packet=args.show_raw_packet,
show_message_decoded=args.show_message_decoded, show_message_decoded=args.show_message_decoded,
outyaml=args.yaml) outyaml=args.yaml,
outcsv=args.csv)
if args.raw: if args.raw:
spy.readRaw() spy.readRaw()
else: else:

View file

@ -67,6 +67,25 @@ class CAction:
self.world = world self.world = world
self.Reference = [] self.Reference = []
self.Name = "" self.Name = ""
self.notice = {}
self.headernotice = None
def set_header_notice(self, header):
self.headernotice = header
def append_notice(self, data):
for key in data:
#print("Add", key)
self.notice.setdefault(key, data [key])
def add_notice(self, id, value):
if not self.headernotice:
return
ref = { self.headernotice + '/' +id: value}
self.append_notice(ref)
def get_notice(self):
return self.notice
def set_name(self, name): def set_name(self, name):
self.Name = name self.Name = name
@ -154,6 +173,7 @@ class CActionPosition(CAction):
self.Position16 = [0, 0, 0] self.Position16 = [0, 0, 0]
self.IsRelative = False self.IsRelative = False
self.Interior = False self.Interior = False
self.set_header_notice("Action/Position")
def __str__(self): def __str__(self):
return "CActionPosition" + super().__str__() + " x:" + str(self.Position16[0]) + " y:" + str(self.Position16[1]) + " z:" + str(self.Position16[2]) + " IsRelative:" + str(self.IsRelative) + " Interior:" + str(self.Interior) return "CActionPosition" + super().__str__() + " x:" + str(self.Position16[0]) + " y:" + str(self.Position16[1]) + " z:" + str(self.Position16[2]) + " IsRelative:" + str(self.IsRelative) + " Interior:" + str(self.Interior)
@ -173,6 +193,11 @@ class CActionPosition(CAction):
self.Position16[2] = message.readUint16('pz') self.Position16[2] = message.readUint16('pz')
self.IsRelative = (self.Position16[2] & 0x1) != 0 self.IsRelative = (self.Position16[2] & 0x1) != 0
self.Interior = (self.Position16[2] & 0x2) != 0 self.Interior = (self.Position16[2] & 0x2) != 0
self.add_notice('px', self.Position16[0] )
self.add_notice('py', self.Position16[1] )
self.add_notice('pz', self.Position16[2] )
self.add_notice('IsRelative', self.Position16[2] & 0x1 )
self.add_notice('Interior', self.Position16[2] & 0x2 )
# message.serialAndLog1( Position16[0] ); # message.serialAndLog1( Position16[0] );
# message.serialAndLog1( Position16[1] ); # message.serialAndLog1( Position16[1] );
@ -576,6 +601,9 @@ class CActionFake():
def get_name(self): def get_name(self):
return self.Name return self.Name
def get_notice(self):
return {}
def get_parameter(self): def get_parameter(self):
ret = {"Type": "CActionFake.%s" % self.Type} ret = {"Type": "CActionFake.%s" % self.Type}
if not self._Message.checkOnlyZeroAtEnd(): if not self._Message.checkOnlyZeroAtEnd():

View file

@ -469,7 +469,7 @@ class ImpulsePosition(ImpulseBase):
# khanat-opennel-code/code/ryzom/server/src/gpm_service/client_messages.cpp void cbClientPosition( CMessage& msgin, const string &serviceName, NLNET::TServiceId serviceId ) # khanat-opennel-code/code/ryzom/server/src/gpm_service/client_messages.cpp void cbClientPosition( CMessage& msgin, const string &serviceName, NLNET::TServiceId serviceId )
logging.getLogger(LOGGER).debug("read") logging.getLogger(LOGGER).debug("read")
self.name = name.replace(':', '_') self.name = name.replace(':', '_')
self.readBool(msgin, '') #self.readBool(msgin, '')
self.readSint32(msgin, 'X') self.readSint32(msgin, 'X')
self.readSint32(msgin, 'Y') self.readSint32(msgin, 'Y')
self.readSint32(msgin, 'Z') self.readSint32(msgin, 'Z')