1

I'm working with scapy and have a question related to scapy but also python. I try to use variables as scapy field-names. Here is an extract of code that should illustrate what I try to do (It is not working):

class Test(Packet):
    name = "Test23"
    def __init__(self,foo=None):
        self.foo=foo

    fields_desc = [
                BitField(self.foo, 0x0, 4),
                BitField("bar", 0x3, 4)
                ]

Now I imagine the problem is due to the fact that fields_desc is a class attribute and not a class variable. Now, how could I reach what I want? (setting the name of self.foo at runtime/class inizialisation?)

I would be thankfull for any help. With best regards

Edit: Appending an counter would be enough. I tried:

class Counter:
     count = 0    
     def __init__(self):
         self.__class__.count += 1 
     foo = [ 
            "lala"+str(count)
            ]   
     print foo 


a=Counter()
a.count
print a.foo
b=Counter()
b.count
print b.foo

But doesn't seem to work. Would be cool if you could point me to the correct direction, somehow I'm lost.

Jan
  • 55
  • 4

2 Answers2

1

I'm guessing what you are trying to do is change the name of the first BitField based on the raw data input you're parsing with 'getfield'? It's kinda hard to tell...

Anyway, from the function pre_dissect you can look at the raw data and append Fields to the self.fields_desc as you wish. When using pre_dissect make sure to return the raw packet data at the end of the function un-modified.

This in my experience is very rarely the right way to go on this, usually ConditionalField's and class-overloading works much better in the long run.

Good luck

Lyager
  • 73
  • 4
1

I think class attributes are initialized before the class constructor runs, so self.foo has not been assigned when fields_desc is created. Try declaring fields_desc as an empty array and appending the BitField objects to it inside your __init__ function.

I don't know how the Packet class you're inheriting from works, but you may also want to look at the super() function.

Edit: Maybe you're looking for something like this?

class Counter:
    i = 0
    foo = []
    def count(self):
        self.__class__.i += 1
        self.__class__.foo.append(['lala' + str(self.__class__.i)])

a = Counter()
a.count()
print Counter().foo
b = Counter()
b.count()
print Counter().foo

Output

[['lala1']]
[['lala1'], ['lala2']]

More info on class variables here

Community
  • 1
  • 1
James
  • 2,626
  • 5
  • 37
  • 51
  • Thx for the idea. I looked at super() function already, but that only works with new type classes which would mean i would have to fork scapy :S – Jan Jul 19 '11 at 13:40
  • The fist idea doesn't work unfortunately. Scapy raises an exception if I try what you proposed. Here the code I wrote: http://pastebin.com/DYK4wuMw – Jan Jul 19 '11 at 13:51
  • Yes, it is sth like that, but then I would need to append the `i` to the first element of `fields_desc` which brings me back to the problem that I'm unable to do so :S – Jan Jul 19 '11 at 14:09
  • Hmmm, but I cannot use the first example I wrote with it, or am I missing sth? I cannot append an count to `BitField("bar", 0x3, 4)` if `BitField` is a class attribute. – Jan Jul 19 '11 at 15:24
  • `self.__class__.fields_desc.append(BitField("bar" + str(self.__class__.i), 0x3, 4))`? – James Jul 19 '11 at 15:31
  • Nice solution indeed, I have it working now, thanks to you :-) – Jan Jul 19 '11 at 15:50