summaryrefslogtreecommitdiff
path: root/common/lib/scammer/beacon.py
diff options
context:
space:
mode:
Diffstat (limited to 'common/lib/scammer/beacon.py')
-rw-r--r--common/lib/scammer/beacon.py379
1 files changed, 379 insertions, 0 deletions
diff --git a/common/lib/scammer/beacon.py b/common/lib/scammer/beacon.py
new file mode 100644
index 0000000000..91e97323dc
--- /dev/null
+++ b/common/lib/scammer/beacon.py
@@ -0,0 +1,379 @@
+#!/usr/bin/python
+
+#############################################################################
+# Copyright (C) 2011 Spidcom
+#
+# Beacon description in a VS_SNIFFER.IND MME
+#
+# See scpay/layers/inet.py for IPOptions construction.
+#
+# To add a new beacon entry in the script, you need to create a new class
+# which derives Bentry class.
+# In this new class, the header must be filled as class attribute.
+#############################################################################
+
+from scapy.all import Packet, SourceMACField
+from scapy.fields import *
+from common import ETHER_TYPES, HPAV_CCO_LEVEL
+from commonfields import *
+
+BENTRY_HDR = {
+ "NON_PERSISTENT_SCHEDULE": 0x00,
+ "PERSISTENT_SCHEDULE": 0x01,
+ "REGIONS": 0x02,
+ "MAC_ADDRESS": 0x03,
+ "DISCOVER": 0x04,
+ "DISCOVERED_INFO": 0x05,
+ "BEACON_PERIOD_START_TIME_OFFSET": 0x06,
+ "ENCRYPTION_KEY_CHANGE": 0x07,
+ "CCO_HANDOVER": 0x08,
+ "BEACON_RELOCATION": 0x09,
+ "AC_LINE_SYNC_COUNTDOWN": 0x0A,
+ "CHANGE_NUMSLOTS": 0x0B,
+ "CHANGE_HM": 0x0C,
+ "CHANGE_SNID": 0x0D,
+ }
+
+class BEntryHDR (Packet):
+ """Beacon entry header."""
+ # Use the BENTRY_HDR dict to compose a new dict with the keyword
+ # inverted. i.e. bentry['CHANHE_SNID'] will be _bentry[0xd].
+ _bentry = {}
+ for i in BENTRY_HDR:
+ _bentry[BENTRY_HDR[i]] = i
+ fields_desc = [
+ ByteEnumField ("header", 0, _bentry),
+ ByteField ("length", 0)
+ ]
+
+class BEntry (Packet):
+ """Beacon entries are different depending on the Beacon Entry Header. So
+ we need to parse each header to know to which beacon entry it
+ corresponds."""
+ fields_desc = [
+ BEntryHDR,
+ ]
+
+ registered_bentry = {}
+ @classmethod
+ def register_variant(cls):
+ cls.registered_bentry [cls.header.default] = cls
+ @classmethod
+ def dispatch_hook(cls, pkt=None, *args, **kargs):
+ if pkt:
+ header = struct.unpack ('B', pkt[0])[0]
+ if header in cls.registered_bentry:
+ return cls.registered_bentry [header]
+ return cls
+
+ def extract_padding(self, s):
+ return "",s
+
+class BEntrySchedulesAllocations (Packet):
+ """Session Allocation Information."""
+ # The stpf flag indicates if there is a start time in the allocation or
+ # not.
+ fields_desc = [
+ LEBitField ("stpf", 0, 1),
+ LEBitField ("glid", 0, 7),
+ ConditionalField (LEBitField ("st_atu", 0, 12), lambda p: p.stpf),
+ LEBitField ("et_atu", 0, 12),
+ ConditionalField (LEBitField("pad", 0, 4), lambda p: not p.stpf),
+ ]
+
+ def extract_padding(self, s):
+ return "",s
+
+class BEntryNonPersistentSchedule (BEntry):
+ """Beacon entry Non Persistent Schedule."""
+ header = BENTRY_HDR['NON_PERSISTENT_SCHEDULE']
+ fields_desc = [
+ BEntryHDR,
+ LEBitField ("ns", 0, 6),
+ LEBitField ("benpsf_rsvd1", 0, 2),
+ PacketListField ("sai", None, BEntrySchedulesAllocations,
+ count_from=lambda p:p.ns),
+ ]
+
+class BEntryPersistentSchedule (BEntry):
+ """Beacon entry Non Persistent Schedule."""
+ header = BENTRY_HDR['PERSISTENT_SCHEDULE']
+ fields_desc = [
+ BEntryHDR,
+ LEBitField ("pscd", 0, 3),
+ LEBitField ("cscd", 0, 3),
+ LEBitField ("bepsf_rsvd1", 0, 2),
+ LEBitField ("ns", 0, 6),
+ LEBitField ("bepsf_rsvd2", 0, 2),
+ PacketListField ("sai", None, BEntrySchedulesAllocations,
+ count_from=lambda p:p.ns),
+ ]
+
+class BEntryRegionsDesc (Packet):
+ """Region definition."""
+ fields_desc = [
+ LEBitField ("rt", 0, 4),
+ LEBitField ("ret", 0, 12),
+ ]
+
+ def extract_padding(self, s):
+ return "",s
+
+class BEntryRegions (BEntry):
+ """Region beacon entry."""
+ header = BENTRY_HDR['REGIONS']
+ fields_desc = [
+ BEntryHDR,
+ LEBitField ("nr", 0, 6),
+ LEBitField ("ber_rvsd", 0, 2),
+ PacketListField ("rlist", None, BEntryRegionsDesc,
+ count_from=lambda p:p.nr),
+ ]
+
+class BEntryMacAddress (BEntry):
+ """Beacon entry for the mac address."""
+ header = BENTRY_HDR['MAC_ADDRESS']
+ fields_desc = [
+ BEntryHDR,
+ MACField("mac", ETHER_ANY),
+ ]
+
+class BEntryDiscover (BEntry):
+ """Discover beacon entry."""
+ header = BENTRY_HDR['DISCOVER']
+ fields_desc = [
+ BEntryHDR,
+ ByteField ("tei", 0),
+ ]
+
+class BEntryDiscoveredInfo (BEntry):
+ """Discover info beacon entry."""
+ header = BENTRY_HDR['DISCOVERED_INFO']
+ fields_desc = [
+ BEntryHDR,
+ LEBitField ("updated", 0, 1),
+ LEBitField ("cco_cap", 0, 2),
+ LEBitField ("proxy_networking_cap", 0, 1),
+ LEBitField ("backup_cco_cap", 0, 1),
+ LEBitField ("cco_status", 0, 1),
+ LEBitField ("pco_status", 0, 1),
+ LEBitField ("backup_cco_status", 0, 1),
+ ByteField ("numdissta", 0),
+ ByteField ("numdisnet", 0),
+ LEBitField ("authentication_status", 0, 1),
+ LEBitField ("user_appointed", 0, 1),
+ LEBitField ("bedi_rsvd", 0, 6),
+ ]
+
+class BEntryBeaconPeriodStartTimeOffset (BEntry):
+ """Beacon Period Start Time Offset."""
+ header = BENTRY_HDR['BEACON_PERIOD_START_TIME_OFFSET']
+ fields_desc = [
+ BEntryHDR,
+ LEBitField ("bpsto", 0, 24),
+ ]
+
+class BEntryEncryptionKeyChange (BEntry):
+ """Encryption Key change."""
+ header = BENTRY_HDR['ENCRYPTION_KEY_CHANGE']
+ fields_desc = [
+ BEntryHDR,
+ LEBitField ("kccd", 0, 6),
+ LEBitField ("kbc", 0, 1),
+ LEBitField ("beckc_rsvd", 0, 1),
+ LEBitField ("neweks", 0, 4),
+ LEBitField ("beckc_rsvd2", 0, 4),
+ ]
+
+class BEntryCcoHandover (BEntry):
+ """CCo Handover."""
+ header = BENTRY_HDR['CCO_HANDOVER']
+ fields_desc = [
+ BEntryHDR,
+ LEBitField ("hcd", 0, 6),
+ LEBitField ("bech_rsvd", 0, 2),
+ ByteField ("nctei", 0),
+ ]
+
+class BEntryBeaconRelocation (BEntry):
+ """Beacon Relocation"""
+ header = BENTRY_HDR['BEACON_RELOCATION']
+ fields_desc = [
+ BEntryHDR,
+ LEBitField ("rcd", 0, 6),
+ LEBitField ("rlt", 0, 1),
+ LEBitField ("lgf", 0, 1),
+ LEBitField ("rlo", 0, 17),
+ LEBitField ("rlslotid", 0, 3),
+ LEBitField ("bebr_rsvd", 0, 4),
+ ]
+
+class BEntryAcLineSyncCountdown (BEntry):
+ """AC Line Sync Countdown."""
+ header = BENTRY_HDR['AC_LINE_SYNC_COUNTDOWN']
+ fields_desc = [
+ BEntryHDR,
+ LEBitField ("countdown", 0, 6),
+ LEBitField ("beaclsc_rsvd1", 0, 2),
+ LEBitField ("reasoncode", 0, 2),
+ LEBitField ("beaclsc_rsvd2", 0, 6),
+ ]
+
+class BEntryChangeNumslots (BEntry):
+ """Change NumSlots."""
+ header = BENTRY_HDR['CHANGE_NUMSLOTS']
+ fields_desc = [
+ BEntryHDR,
+ LEBitField ("nsccd", 0, 6),
+ LEBitField ("becns_rsvd1", 0, 2),
+ LEBitField ("newnumslot", 0, 3),
+ LEBitField ("becns_rsvd2", 0, 5),
+ ]
+
+class BEntryChangeHm (BEntry):
+ """Change Hybrid Mode."""
+ header = BENTRY_HDR['CHANGE_HM']
+ fields_desc = [
+ BEntryHDR,
+ LEBitField ("hmccd", 0, 6),
+ LEBitField ("newhm", 0, 2),
+ ]
+
+class BEntryChangeSnid (BEntry):
+ """Change SNID."""
+ header = BENTRY_HDR['CHANGE_SNID']
+ fields_desc = [
+ BEntryHDR,
+ LEBitField ("sccd", 0, 4),
+ LEBitField ("newsnid", 0, 4),
+ ]
+
+class BeaconSniff (Packet):
+ """Beacon description inside a VS_SNIFFER.IND MME"""
+ name = "Beacon description inside a VS_SNIFFER.IND MME"
+ fields_desc = [
+ XLEBitField ("nid", 0, 54),
+ XLEBitField ("hm", 0, 2),
+ XByteField ("stei", 0),
+ XLEBitField ("bt", 0, 3),
+ XLEBitField ("ncnr", 0, 1),
+ XLEBitField ("npsm", 0, 1),
+ XLEBitField ("numslots", 0, 3),
+ XLEBitField ("slotusage", 7, 8),
+ XLEBitField ("slotid", 0, 3),
+ XLEBitField ("aclss", 0, 3),
+ XLEBitField ("hoip", 0, 1),
+ XLEBitField ("rtsbf", 0, 1),
+ XLEBitField ("nm", 0, 2),
+ XLEBitField ("ccocap", 0, 2),
+ XLEBitField ("rsvd", 0, 4),
+ FieldLenField("nbe", None, count_of="bentry",fmt="B"),
+ # From here the beacon entry are like Header, Length (in bytes),
+ # entry.
+ # Entries may have N repeated structure i.e. schedules, regions...
+ # So entries does not have the same length, all we know is that
+ # the beacon entries are ordered and there is nbe beacon entries
+ # in the beacon.
+ PacketListField("bentry", None, BEntry, count_from=lambda p:p.nbe),
+ ]
+
+if __name__ == '__main__':
+ """Create a beacon to check if the dissector is correct."""
+ from scapy.utils import str2mac
+ mac = '00:13:d7:00:00:%02x'
+ # Non Persistent schedules.
+ non_peristent_sais = [
+ BEntrySchedulesAllocations (stpf = False , glid = 1,
+ et_atu=50),
+ BEntrySchedulesAllocations (stpf = True, glid = 2,
+ st_atu=50, et_atu=1500),
+ ]
+ bnps = BEntryNonPersistentSchedule (
+ header=BENTRY_HDR['NON_PERSISTENT_SCHEDULE'],
+ length=11 ,ns=3, sai=non_peristent_sais)
+ # Persistent schedules.
+ persistent_sais = [
+ BEntrySchedulesAllocations (stpf = True, glid = 3,
+ st_atu=1500, et_atu=3907)
+ ]
+ bps = BEntryPersistentSchedule (
+ header=BENTRY_HDR['PERSISTENT_SCHEDULE'],
+ length=5, pscd=7, cscd=7, ns=1, sai=persistent_sais)
+ # Create regions.
+ r = BEntryRegions (
+ header = BENTRY_HDR['REGIONS'],
+ length = 4,
+ nr = 2,
+ rlist = [
+ BEntryRegionsDesc (rt=0, ret=50),
+ BEntryRegionsDesc (rt=1, ret=3907)
+ ])
+ # Store the mac address.
+ m = BEntryMacAddress (
+ header = BENTRY_HDR['MAC_ADDRESS'],
+ length = 6,
+ mac = mac % 5)
+ # Discover entry.
+ d = BEntryDiscover (
+ header = BENTRY_HDR['DISCOVER'],
+ length = 1,
+ tei = 0xA)
+ # Discover info entry.
+ di = BEntryDiscoveredInfo (
+ header = BENTRY_HDR['DISCOVERED_INFO'],
+ length = 4,
+ updated = False,
+ cco_cap = 1,
+ proxy_networking_cap = False,
+ backup_cco_cap = True,
+ cco_status = True,
+ pco_status = False,
+ backup_cco_status = False,
+ numdissta = 4,
+ numdisnet = 3,
+ authentication_status = True,
+ user_appointed = False)
+ # Beacon period start time offset.
+ bpsto = BEntryBeaconPeriodStartTimeOffset (
+ header = BENTRY_HDR['BEACON_PERIOD_START_TIME_OFFSET'],
+ length = 3,
+ bpsto = 1204)
+ # Encryption key change.
+ ekc = BEntryEncryptionKeyChange (
+ header = BENTRY_HDR['ENCRYPTION_KEY_CHANGE'],
+ length = 2,
+ kccd = 4,
+ kbc = 1,
+ neweks = 2)
+ # CCo handover.
+ ccoh = BEntryCcoHandover (
+ header = BENTRY_HDR['CCO_HANDOVER'],
+ length = 2,
+ hcd = 3, nctei = 0xb)
+ # Beacon relocation.
+ br = BEntryBeaconRelocation (
+ header = BENTRY_HDR['BEACON_RELOCATION'],
+ length = 4, rcd = 4, rlt = 1, lgf = 1, rlo = 1240, rlslotid = 2)
+ # Ac Line Sync Countdown
+ alsc = BEntryAcLineSyncCountdown (
+ header = BENTRY_HDR['AC_LINE_SYNC_COUNTDOWN'],
+ length = 2, countdown = 3, reasoncode = 1)
+ # Change num slots.
+ cn = BEntryChangeNumslots (
+ header = BENTRY_HDR['CHANGE_NUMSLOTS'],
+ length = 2, nsccd = 3, newnumslot = 2)
+ # Change Hybrid mode.
+ chm = BEntryChangeHm (
+ header = BENTRY_HDR['CHANGE_HM'],
+ length = 1, hmccd = 2, newhm = 1)
+ # Change snid.
+ csnid = BEntryChangeSnid (
+ header = BENTRY_HDR['CHANGE_SNID'],
+ length = 1, sccd = 3, newsnid = 2)
+ # Create the beacon.
+ m = BeaconSniff (nid=0x12345789abc, hm=0, stei=1, bt=1, ncnr=0,
+ npsm=0, numslots=7, slotusage=1, slotid=1, aclss=0, hoip=0,
+ rtsbf=0, nm=2, ccocap=1, rsvd=0,
+ bentry=[bnps, bps, r, m, d, di, bpsto, ekc, ccoh, br, alsc,
+ cn, chm, csnid])
+ m.show ()