Ticket #30: patch-radiotap-scapy.diff

File patch-radiotap-scapy.diff, 7.1 kB (added by nico@chdir.org, 2 years ago)

Patch (under the GNU GPL)

  • scapy.py

    old new  
    62696269            return self.sprintf("802.1q (%Dot1Q.type%) vlan %Dot1Q.vlan%") 
    62706270 
    62716271 
     6272class RadioTapByteField(ByteField): 
     6273    def __init__(self, name, default, bitset): 
     6274        ByteField.__init__(self, name, default) 
     6275        self.bitset = bitset 
     6276         
     6277    def getfield(self, pkt, s): 
     6278        if pkt[RadioTap].bitmap & (1 << self.bitset): 
     6279            pkt.l += 1 
     6280            return ByteField.getfield(self, pkt, s) 
     6281        else: 
     6282            return s,None 
     6283 
     6284class RadioTapShortField(LEShortField): 
     6285    def __init__(self, name, default, bitset): 
     6286        LEShortField.__init__(self, name, default) 
     6287        self.bitset = bitset 
     6288         
     6289    def getfield(self, pkt, s): 
     6290        if (pkt.l+1) % 2:  
     6291            delta=(pkt.l+2)/2*2 - pkt.l - 1 # alignement 
     6292            pkt.l += delta 
     6293            s = s[delta:] 
     6294        if pkt[RadioTap].bitmap & (1 << self.bitset): 
     6295            pkt.l += 2 
     6296            return LEShortField.getfield(self, pkt, s) 
     6297        else: 
     6298            return s,None 
     6299 
     6300_radiotap_channel_type = { 
     6301    0x4001: "802.11a", 
     6302    0xa000: "802.11b", 
     6303    0xc000: "802.11g (pure)", 
     6304    0x5001: "802.11a (turbo)", 
     6305    0xd000: "802.11g (pure, turbo)", 
     6306    0x9004: "802.11g (turbo)", 
     6307    0x8008: "FHSS" 
     6308} 
     6309 
     6310class RadioTapChannelField(RadioTapShortField): 
     6311    def i2repr(self, pkt, val): 
     6312        if val == 0: 
     6313            return 'N/A' 
     6314        else: 
     6315            return '%d / %0.3f GHz' % ((val-2407)/5.0, val/1000.0) 
     6316 
     6317class RadioTapChannelTypeField(BitEnumField): 
     6318    length=16 
     6319    def __init__(self, name, default, bitset): 
     6320        BitEnumField.__init__(self, name, default, self.length, _radiotap_channel_type) 
     6321        self.bitset = bitset 
     6322         
     6323    def getfield(self, pkt, s): 
     6324        if pkt[RadioTap].bitmap & (1 << self.bitset): 
     6325            pkt.l += self.length/8 
     6326            return BitEnumField.getfield(self, pkt, s) 
     6327        else: 
     6328            return s,None 
     6329 
     6330class RadioTapIntField(XIntField): 
     6331    def __init__(self, name, default, bitset): 
     6332        XIntField.__init__(self, name, default) 
     6333        self.bitset = bitset 
     6334         
     6335    def getfield(self, pkt, s): 
     6336        if (pkt.l+1) % 4:  
     6337            delta=(pkt.l+4)/4*4 - pkt.l - 1 # alignement 
     6338            pkt.l += delta 
     6339            s = s[delta:] 
     6340        if pkt[RadioTap].bitmap & (1 << self.bitset): 
     6341            pkt.l += 4 
     6342            return XIntField.getfield(self, pkt, s) 
     6343        else: 
     6344            return s,None 
     6345 
     6346class RadioTapLongField(XLongField): 
     6347    def __init__(self, name, default, bitset): 
     6348        XLongField.__init__(self, name, default) 
     6349        self.bitset = bitset 
     6350         
     6351    def getfield(self, pkt, s): 
     6352        if pkt[RadioTap].bitmap & (1 << self.bitset): 
     6353            pkt.l += 8 
     6354            return XLongField.getfield(self, pkt, s) 
     6355        else: 
     6356            return s,None 
     6357 
     6358_radiotap_flags = { 
     6359    0x1: "CFP", 
     6360    0x2: "Preamble", 
     6361    0x3: "WEP", 
     6362    0x4: "Frag", 
     6363    0x5: "FCS", 
     6364    0x6: "pad" 
     6365} 
     6366 
     6367class RadioTapFlagsField(BitEnumField): 
     6368    def __init__(self, name, default, bitset): 
     6369        BitEnumField.__init__(self, name, default, 8, _radiotap_flags) 
     6370        self.bitset = bitset 
     6371         
     6372    def getfield(self, pkt, s): 
     6373        if pkt[RadioTap].bitmap & (1 << self.bitset): 
     6374            return BitEnumField.getfield(self, pkt, s) 
     6375        else: 
     6376            return s,None 
     6377 
     6378class RadioTapRateField(RadioTapByteField): 
     6379    def i2repr(self, pkt, x): 
     6380        if x is None: 
     6381            return '0' 
     6382        return '%d Mb/s' % (x*0.512) 
     6383 
     6384_radiotap_msg  = { 
     6385    0x00: "TSFT", 
     6386    0x01: "Flags", 
     6387    0x02: "Rate", 
     6388    0x03: "Channel", 
     6389    0x04: "FrequencyHop", 
     6390    0x05: "SignalPower", 
     6391    0x06: "NoisePower", 
     6392    0x07: "Quality", 
     6393    0x08: "Transmit", 
     6394    0x09: "TransmitDB", 
     6395    0x0a: "TransmitDBM", 
     6396    0x0b: "AntennaId", 
     6397    0x0c: "PowerAntennaDB", 
     6398    0x0d: "NoisePowerDB", 
     6399    0x0e: "FCS", 
     6400    0x1f: "Extension", 
     6401} 
     6402 
     6403class RadioTapBitmapField(LEIntField): 
     6404    def __init__(self, name, d): 
     6405        LEIntField.__init__(self, name, 0) 
     6406        self.d=d 
     6407 
     6408    def i2repr(self, pkt, x): 
     6409        n=0 
     6410        s=[] 
     6411        while n < 32: 
     6412            if x & (1 << n) and _radiotap_msg.has_key(n): 
     6413                s.append(_radiotap_msg[n]) 
     6414            n   += 1 
     6415        return '+'.join(s) 
     6416 
     6417class RadioTapLenPadding(StrLenField): 
     6418    def getfield(self, pkt, x): 
     6419        pkt.l = pkt[RadioTap].len - pkt.l - 8 - 1 # 8 is the header's length 
     6420        return StrLenField.getfield(self, pkt, x) 
     6421 
     6422## /usr/src/linux/include/net/ieee80211_radiotap.h 
     6423## http://madwifi.org/wiki/DevDocs/RadiotapHeader 
     6424class RadioTap(Packet): 
     6425    name = "RadioTap" 
     6426    l=0 # this will represent the length used by fields 
     6427    fields_desc = [ ByteField('version', 0), 
     6428                    ByteField('padding', 0), 
     6429                    LenField('len', None, '@H'), 
     6430                    ## variable headers 
     6431                    RadioTapBitmapField('bitmap', _radiotap_msg), 
     6432                    RadioTapLongField('timestamp', 0, 0), 
     6433                    RadioTapFlagsField('flags', 0, 1), 
     6434                    RadioTapRateField('rate', 0, 2), 
     6435                    RadioTapChannelField('channel', 11, 3), 
     6436                    RadioTapChannelTypeField('chantype', 11, 3), 
     6437                    RadioTapShortField('hop', 0, 4), 
     6438                    RadioTapByteField('signal', 0, 5), 
     6439                    RadioTapByteField('noise', 0, 6), 
     6440                    RadioTapShortField('quality', 0, 7), 
     6441                    RadioTapShortField('tx', 0, 8), 
     6442                    RadioTapShortField('txDB', 0, 9), 
     6443                    RadioTapByteField('txDBM', 0, 10), 
     6444                    RadioTapByteField('antennaID', 0, 11), 
     6445                    RadioTapByteField('powerAntennaDB', 0, 12), 
     6446                    RadioTapByteField('noisepowerDB', 0, 13), 
     6447                    RadioTapIntField('fcs', 0, 14), 
     6448                    RadioTapLenPadding('padding', '', 'l') ] 
     6449 
    62726450class STP(Packet): 
    62736451    name = "Spanning Tree Protocol" 
    62746452    fields_desc = [ ShortField("proto", 0), 
     
    86568834layer_bonds = [ ( Dot3,   LLC,      { } ), 
    86578835                ( GPRS,   IP,       { } ), 
    86588836                ( PrismHeader, Dot11, { }), 
     8837                ( RadioTap,    Dot11, { }), 
    86598838                ( Dot11,  LLC,      { "type" : 2 } ), 
    86608839                ( PPP,    IP,       { "proto" : 0x0021 } ), 
    86618840                ( Ether,  LLC,      { "type" : 0x007a } ), 
     
    88429021            101 : IP, 
    88439022            801 : Dot11, 
    88449023            802 : PrismHeader, 
     9024            803 : RadioTap, 
    88459025            105 : Dot11, 
    88469026            113 : CookedLinux, 
    88479027            119 : PrismHeader, # for atheros 
     9028            127 : RadioTap, 
    88489029            144 : CookedLinux, # called LINUX_IRDA, similar to CookedLinux 
    88499030            783 : IrLAPHead, 
    88509031            0xB1E70073L : HCI_Hdr, # I invented this one 
     
    88559036               IP  : 101, 
    88569037               Dot11  : 801, 
    88579038               PrismHeader : 802, 
     9039               RadioTap    : 803, 
     9040               RadioTap    : 127, 
    88589041               Dot11 : 105, 
    88599042               CookedLinux : 113, 
    88609043               CookedLinux : 144,