Reading WLAN packets
Your variable names are quite hard to make sense of. I had to read your explanatory text to figure out what vali was supposed to do; I still have no idea what obs means. Judging by the line print O+'[+]'+W+' Got first packet! Many more to go...\n', it also looks like you might have a variable called "O" (capital letter oh), which most style guides advise against because it's hard to distinguish it from 0 (the number zero). I would use longer, more descriptive names. Write out validation or valid_pairs instead of using vali. Write packet and packet_counter instead of p and pc. I could have written my first sentence as "ur vrbl nms r q hd 2 mk sns of", and you might have been able to understand it, but ovssly ts mch mr dfclt 2 ndrstnd if i wrt lk ths. Apply the same principle to your code.

Spaces between your string concatenation operators also make code easier to read: print O + '[+]' + W + ' Got first packet! Many more to go...\n' is easier to read than the version with everything all scrunched up. In this case, though, I would prefer format strings to using concatenation: print "{} [+] {} Got first packet!".format(O, W). (Or the percent-sign version, if you're stuck on a version of Python before 2.6.)

Your code is rather deeply nested, which makes it harder to read and understand overall. The Zen of Python says flat is better than nested, and while I don't always agree with the Zen, in this case I think it's right. To relieve this problem, I would make some functions. Pick out some nested blocks and drop them into their own functions, passing in whatever arguments they need, so your code is flatter and easier to read and understand. At the very least, your entire block under if p.haslayer(Dot11Elt) could be its own function.



There are improvements both big and small that could be made to your for loop. It looks like you could do the same thing you currently do in a lot less code, like this:

if (p.addr2, ssid) not in obs:
    obs.append((p.addr2,ssid))
    checkmac(p.addr2)
    checknet(ssid)
    count +=1
    get_oui(p.addr2)
    print str(count)+'&gt;',p.addr2+' ('+G+macf+W+') &lt;--Probing--&gt; '+O+ssid+W
    wr_log(p.addr2,ssid,macf)


This does a linear search of obs for the tuple (p.addr2, ssid); it checks every element in obs to see if it's equal to (p.addr2, ssid) as your current code does.

But there are faster ways to do this. I would probably rethink the way obs is stored. Right now, you're storing the valid pairs of MAC addresses and SSIDs as a list, so in order to find duplicates, you have to do a list search. You could speed this up by sorting the list and using a binary search, but you can speed it up even more by bringing a set into the equation.

It wasn't clear to me from your explanation whether you need obs to be in order or not. If you don't need it in order, you can just switch from a list to a set:

if (p.addr2, ssid) not in obs_set:
    obs_set.add((p.addr2, ssid))
    # other stuff


If you do need it in order, you can still use a set to speed this particular operation up, but unfortunately, there's no ordered set in Python. The Stack Overflow question Does Python have an ordered set? gives several ways you can mimic one. Another option: you could just keep your current list, but also add everything to a set. Maybe even wrap it in a class so you don't have to remember to do both. It's sort of hacky, and it takes more memory, but it's simple, quick to implement, avoids adding more dependencies, and is much easier than implementing your own red-black tree. (I consider an OrderedDict with all the values as True to be kind of hacky and a waste of memory too.)