Python parsing JSON count Blocks

1

I have a .json file exported from Wireshark wich has the following example:

"_source": {
  "layers": {
    "frame": {
      "frame.encap_type": "1",
      "frame.time": "Jan 23, 2018 10:32:28.074649000 Mitteleurop\u00c3\u00a4ische Zeit",
      "frame.offset_shift": "0.000000000",
      "frame.time_epoch": "1516699948.074649000",
      "frame.time_delta": "0.000036000",
      "frame.time_delta_displayed": "0.000036000",
      "frame.time_relative": "141.761654000",
      "frame.number": "18",
      "frame.len": "76",
      "frame.cap_len": "76",
      "frame.marked": "0",
      "frame.ignored": "0",
      "frame.protocols": "eth:ethertype:pn_rt:pn_dcp"
    },
    "eth": {
      "eth.dst": "60:38:e0:e3:16:05",
      "eth.dst_tree": {
        "eth.dst_resolved": "BelkinIn_e3:16:05",
        "eth.addr": "60:38:e0:e3:16:05",
        "eth.addr_resolved": "BelkinIn_e3:16:05",
        "eth.lg": "0",
        "eth.ig": "0"
      },
      "eth.src": "00:a0:45:84:3c:9c",
      "eth.src_tree": {
        "eth.src_resolved": "PhoenixC_84:3c:9c",
        "eth.addr": "00:a0:45:84:3c:9c",
        "eth.addr_resolved": "PhoenixC_84:3c:9c",
        "eth.lg": "0",
        "eth.ig": "0"
      },
      "eth.type": "0x00008892"
    },
    "pn_rt": {
      "pn_rt.frame_id": "65277"
    },
    "pn_dcp": {
      "pn_dcp.service_id": "3",
      "pn_dcp.service_type": "1",
      "pn_dcp.xid": "0x00000007",
      "pn_dcp.reserved16": "0",
      "pn_dcp.data_length": "50",
      "pn_dcp.block": {
        "pn_dcp.option": "2",
        "pn_dcp.suboption_device": "2",
        "pn_dcp.block_length": "5",
        "pn_dcp.block_info": "0",
        "pn_dcp.suboption_device_nameofstation": "dut"
      },
      "pn.padding": "data",
      "pn_dcp.block": {
        "pn_dcp.option": "2",
        "pn_dcp.suboption_device": "3",
        "pn_dcp.block_length": "6",
        "pn_dcp.block_info": "0",
        "pn_dcp.suboption_vendor_id": "0x00000174",
        "pn_dcp.suboption_device_id": "0x00001234"
      },
      "pn_dcp.block": {
        "pn_dcp.option": "1",
        "pn_dcp.suboption_ip": "1",
        "pn_dcp.block_length": "8",
        "pn.undecoded": "data",
        "pn.undecoded_tree": {
          "_ws.expert": {
            "pn.undecoded_data": "",
            "_ws.expert.message": "Undecoded Data, 8 bytes",
            "_ws.expert.severity": "6291456",
            "_ws.expert.group": "83886080"
          }
        }
      },
      "pn_dcp.block": {
        "pn_dcp.option": "1",
        "pn_dcp.suboption_ip": "2",
        "pn_dcp.block_length": "14",
        "pn_dcp.suboption_ip_block_info": "1",
        "pn_dcp.subobtion_ip_ip": "192.168.0.50",
        "pn_dcp.subobtion_ip_subnetmask": "255.255.255.0",
        "pn_dcp.suboption_ip_standard_gateway": "0.0.0.0"
      }
    }
  }
}

I´m able to find out with Python which dcp_option is set und which suboption was used. But I only get the last pn_dcp.block preferences. So my question is: Is it possible to count the pn_dcp.block from this dictionary? And is it possible to read out all pn_dcp.block information?

here is the example code:

if __name__ == '__main__':
    j = None
    with open(INFILE, 'r') as f:
        j = json.load(f)

    for p in j:
        r = build_line(p)
def build_line(p):
    p = p['_source']['layers']
    # DCP ----------------------
    dcp = p['pn_dcp']
    dcp_id = dcp['pn_dcp.service_id']
    dcp_type = dcp['pn_dcp.service_type']

# There is no direct option in Get -------
    if not 'pn_dcp.block' in dcp:
        dcp_block = dcp
    else:
        dcp_block = dcp['pn_dcp.block']
    dcp_option = dcp_block['pn_dcp.option']

# Differenz options --------------------------------
    if dcp_option == '1':
        dcp_suboption = dcp_block['pn_dcp.suboption_ip']
    elif dcp_option == '2':
        dcp_suboption = dcp_block['pn_dcp.suboption_device']
    elif dcp_option == '3':
        dcp_suboption = dcp_block['pn_dcp.suboption_dhcp']
    elif dcp_option == '5':
        dcp_suboption = dcp_block['pn_dcp.suboption_control']
    elif dcp_option == '6':
        dcp_suboption = dcp_block['pn_dcp.suboption_deviceinitiative']
    elif dcp_option == '255':
        dcp_suboption = dcp_block['pn_dcp.suboption_all']
    elif dcp_option == '0':
        dcp_suboption = dcp_block['pn_dcp.reserved16']
    else:
        return 'other' # for no option find

# Format -------------------------------------------------------------
    act = "%02x%02x" % (int(dcp_id, 10), int(dcp_type, 10))
    option = "%02x%02x" % (int(dcp_option, 10), int(dcp_suboption, 10))

# Options ------------------------------------------------------------------
options = OPTIONS.get(option, 'invalid')
activity = ACTIVITIES.get(act, 'invalid')
Event = activity + options

I hope this helps. I´m climping down the Blocks from source to layers to pn_dcp. Then I am searching the Block pn_dcp.block and I read out the dcp_options and dcp_suboptions.

python
json
parsing
wireshark
asked on Stack Overflow Feb 7, 2018 by Knix • edited Feb 7, 2018 by Knix

2 Answers

0

The problem is that pn_dcp.block is a duplicate key, so when you parse the json into an object or a dictionary the second pn_dcp.block will rewrite the first. The only way is to pre filter the file so this names can be unique. I would do something like this:

import re

i = 0

def replace(match):
    global i
    i += 1
    return 'pn_dcp.block%i' % i

with open('data.json') as f:
    data = f.read()

formatted = json.loads(re.sub("pn_dcp.block([^_])", replace, data))

Then you can continue with your code and use i to loop through all the pn_dcp.block

answered on Stack Overflow Feb 7, 2018 by rxw
0

Is it possible to count the pn_dcp.block from this dictionary?

no, pn_dcp.block is a dulicate key in this dictionary.
Keys need to be unique, therefore its allways overwriten by the last occurrence.

And is it possible to read out all pn_dcp.block information?

Kind of, you can add an object_pairs_hook to json.load:

pn_dcp_blocks=[]
def saveBlocks(*args):
if args[0][0][0]=="pn_dcp.option":
    global pn_dcp_blocks
    pn_dcp_blocks.append(args[0])

with open(INFILE, 'r') as f:
    j = json.load(f, object_pairs_hook =saveBlocks)

which outputs you a structure like this:

pn_dcp_blocks = {list} <class 'list'>: 
 0 = {list} <class 'list'>: 
  0 = {tuple} <class 'tuple'>: ('pn_dcp.option', '2')
  1 = {tuple} <class 'tuple'>: ('pn_dcp.suboption_device', '2')
  2 = {tuple} <class 'tuple'>: ('pn_dcp.block_length', '5')
  3 = {tuple} <class 'tuple'>: ('pn_dcp.block_info', '0')
  4 = {tuple} <class 'tuple'>: ('pn_dcp.suboption_device_nameofstation', 'dut')
  __len__ = {int} 5
 1 = {list} <class 'list'>:
  0 = {tuple} <class 'tuple'>: ('pn_dcp.option', '2')
  1 = {tuple} <class 'tuple'>: ('pn_dcp.suboption_device', '3')
  2 = {tuple} <class 'tuple'>: ('pn_dcp.block_length', '6')
  3 = {tuple} <class 'tuple'>: ('pn_dcp.block_info', '0')
  4 = {tuple} <class 'tuple'>: ('pn_dcp.suboption_vendor_id', '0x00000174')
  5 = {tuple} <class 'tuple'>: ('pn_dcp.suboption_device_id', '0x00001234')
  __len__ = {int} 6
 2 = {list} <class 'list'>: 
  <deleted for readability>
 3 = {list} <class 'list'>: 
  <deleted for readability>
 __len__ = {int} 4

please note: you are missing the indented trees in these tuples

answered on Stack Overflow Feb 7, 2018 by Skandix • edited Feb 15, 2018 by Skandix

User contributions licensed under CC BY-SA 3.0