2

I have a problem with my networkx code. I'm trying to list the attributes of my edges but I keep getting KeyError or when I try to catch the error it skips the entire code.

Background: I have a graph that has the edges representing firewall rules with custom properties for the protocol, source port, destination port and the edge labels contains the action(allow or deny) while the nodes between the edges are the source and destination address... The default value for the protocol, source and destination port is IP, any, any...

What Im trying to do: Im trying to list all the edges (rules) and their respective properties one by one for example:

Rule has PROTOCOL: tcp    ACTION: allow sPORT: 6667 dPORT: 6667  

Problem: I use default values for protocol, source port and destination ports in some instances and hence the values do no show even if I try

for u,v,n in G.edges_iter(data=True): 
    print ('%s %s %s' % (u,v,n)) 

and when I try

print ('Rule has PROTOCOL: %s ACTION: %s sPORT: %s  dPORT: %s' % (n['protocol'],n['label'], n['s_port'], n['d_port']))

I get a KeyError raised because in some edges I do not have either protocol or s_port or d_port declared. And when i try using try and except(continue) on the KeyError it just breaks out of the for loop and goes on to execute the remaining section of my code.

Question: how do I handle the KeyError or enter something like "any" or"None" or "Not declared" when an edge attribute is not available, that i want my code to print something like:

Rule has PROTOCOL: tcp  ACTION: allow sPORT: any dPORT: any 

When Im using default values for source and destination ports instead of skipping the code

This is what my code looks like:

import os
import sys
import string
import networkx as nx

G = nx.read_graphml("fwha.graphml")
count = 0

edges = G.number_of_edges()
nodes = G.number_of_nodes()

print "Number of edges in diagram is: ", edges

for u,v,n in G.edges_iter(data=True):
  try:
    print ('Rule has PROTOCOL:  %s ACTION: %s sPORT: %s dPORT: %s' % (n['protocol'], n['label'], n['s_port'], n['d_port']))
  except KeyError:
    continue

print "Number of nodes in diagram is: ", nodes 
for m,k in G.nodes_iter(data=True):
     print('%s %s' % (k,m))
Lawrence Benson
  • 1,398
  • 1
  • 16
  • 33
ahmed
  • 21
  • 1

2 Answers2

0

It's just a regular python dictionary... you can do a series of things like

n.get('protocol', 'any'),

Which is a lot of typing, so you can do it all at once after the graph is initialized:

for v in G.node:
    G.node[v].setdefault('protocol', 'any')

etc. then walk as normal.

Corley Brigman
  • 11,633
  • 5
  • 33
  • 40
  • Thanks Corley worked on your idea but tweaked it a bit and came up with the answer above which works perfectly. – ahmed Sep 16 '15 at 09:26
0

Well I tried this and even though its not too neat and can use functions to tidy it up, it works for now so :)

for u,v,n in G.edges_iter(data=True):
  try: 
    if not n['s_port']:
      print "No Problem here"
  except KeyError: 
      n['s_port'] = 'any'

for u,v,n in G.edges_iter(data=True):
  try:
    if not n['d_port']:
      print "No Problem here"
  except KeyError:
      n['d_port'] = 'any'
             
for u,v,n in G.edges_iter(data=True):
  try:
     count = count + 1
     print ('Rule %d - Protocol: %s  Action: %s  SourcePort: %s  Destination Port: %s' % (count,n['protocol'], n['label'], n['s_port'], n['d_port']))
  except KeyError, e:
     count = count+1
     print ('Number %s: It didnt execute and the error is %s' % (count, str(e)))
ahmed
  • 21
  • 1