Python appending to a list when it shouldn't

155 Views Asked by At

For fun I'm making a simple script that sniffs on a network and logs the IP addresses and their mac addresses.

from scapy.all import *
import sys
import os

regestry = [['192.168.0.1','E8:DE:27:55:17:F4']]

def islocal(str):
    lst = str.split('.')
    if lst[0] == '192' and lst[1] == '168': 
        return True
    else:
        return False

def packatalize(packet):
    try:    
        dst = packet["IP"].dst
        if islocal(dst):
            var = False
            for reg in regestry:
                if dst not in reg:
                    print 'not in reg'
                    var = True
                elif dst in reg:
                    print 'in reg'
                    var = False
                    pass
            if var == True:
                print 'appending'
                regestry.append([dst,packet.dst])
                print regestry
                var = False

            else:
                pass    
        else:
            print 'not local'
            pass 
    except Exception as e: 
        print str(e)

sniff(prn=packatalize)

sys.exit()

This does what I want it to do, but for some reason it is appending these IP and MAC registries over and over even though they are already there.

2

There are 2 best solutions below

0
On BEST ANSWER

For fun I'm making a simple script that sniffs on a network and logs the IP addresses and their mac addresses.

Then may I suggest you use an appropriate data structure for your particular application? A dict seems good enough though, because its keys are unique, i.e. re-updating a mac address for an existing IP, would update the mac address in the registry instead of creating a new entry.

>>> registry = {}
>>> registry['192.168.0.1'] = 'E8:DE:27:55:17:F4'

To use the dict:

>>> registry['192.168.0.2'] = 'E8:DE:27:55:17:F1'
>>> for ip, mac in registry.iteritems():
...     print ip, mac
... 
192.168.0.2 E8:DE:27:55:17:F1
192.168.0.1 E8:DE:27:55:17:F4

If you want your dictionary to maintain the insertion order, please meet OrderedDict

If you want to use a set instead of simulating one with a list

Instead of manually checking if a value is already in a list and only adding if it doesn't exist, you may use a set (which may be less error-prone than writing it yourself with your own Python code)

>>> registry = set()

This line creates a set, in your example it would be a list of "unique" values

>>> registry.add(('192.168.0.1','E8:DE:27:55:17:F4'))

This adds the value if it doesn't already exist.

Then to use it, it's not that much different from a list, e.g.

>>> registry.add(('192.168.0.2','E8:DE:27:55:17:F1'))
>>> for reg in registry:
...     print reg
... 
('192.168.0.1', 'E8:DE:27:55:17:F4')
('192.168.0.2', 'E8:DE:27:55:17:F1')

Please note though that the set doesn't maintain the insertion order.

0
On

You don't detect if item is in list

for reg in regestry:
    if dst not in reg:
        print 'not in reg'
            var = True
        elif dst in reg:
            print 'in reg'
            var = False
            pass

After this code is executed, 'var' is true iff the new item matched the last element of the list - it's overwritten at every iteration with the comparison result. The code after treats 'var' as if it indicated if the new item matched any item.

Perhaps you intended to use break instead of pass on that last line? That would fix this issue.