pythonscapy

python/scapy RandMAC() issue


I have a really annoying problem that I tried to solve for a few days. I can't find any information on the net.

I tried to solve it myself, consulted with the documentations. But nothing works.

My problem is

When I assign a variable X with RandMAC() function, X should be the same every time I use it.

Like, X = RandMAC(), and let say X is now AA:BB:CC:DD:EE:FF and when I print X for 3 times, it should be something like this.

X = AA:BB:CC:DD:EE:FF  
X = AA:BB:CC:DD:EE:FF  
X = AA:BB:CC:DD:EE:FF  

But what the code actually does is

X = AA:BB:CC:DD:EE:FF  
X = 00:0A:0B:0C:0D:0E:0F  
X = 11:22:33:44:55:66  

So it changed every time I call print X.

How can I solve this issue ?

My code is as follow.

from scapy.all import *

X = RandMAC()

print X
print X
print X

Thank you all in advance.


Solution

  • RandMAC is a class, and when you call RandMAC() what you get is an instance of that class. scapy has a whole lot of these RandXXXXX classes, and they all behave in the same way: an instance of the class is really a sort of random-thing-generator, not a fixed (but randomly chosen) thing. In this instance, a RandMac is built out of six RandBytes, and a RandByte turns into a random value from 0 to 255 every time its value is asked for.

    The idea, I think, is to make it easy to build (e.g.) an IP packet randomizer that gives you IP packets that are all the same except that a couple of fields are chosen at random for every packet.

    So, anyway, many operations on random-thing objects are effectively delegated to the results of "fixing" them (i.e., picking a particular random value); see volatile.py in the source code, class VolatileValue; the magic happens in the __getattr__ method. In particular, this applies to stringifying via __str__, which is what str() does as observed by Lycha and what print does as observed by Karun S.

    If you want to get a single random value, the nearest thing to the Right Way is probably to call the _fix method: X = RandMAC()._fix(). That happens to be the same as str for RandMAC, but e.g. if you have a random integer then _fix will give you an actual integer while str will give you its string representation.

    None of this appears to be documented. Don't make any large bets on it still working in future versions. (But, for what it's worth, volatile.py hasn't changed for about two years.)