summaryrefslogtreecommitdiff
path: root/common/lib/scammer/vs_intellon.py
diff options
context:
space:
mode:
Diffstat (limited to 'common/lib/scammer/vs_intellon.py')
-rw-r--r--common/lib/scammer/vs_intellon.py173
1 files changed, 173 insertions, 0 deletions
diff --git a/common/lib/scammer/vs_intellon.py b/common/lib/scammer/vs_intellon.py
new file mode 100644
index 0000000000..655cbaef8f
--- /dev/null
+++ b/common/lib/scammer/vs_intellon.py
@@ -0,0 +1,173 @@
+#!/usr/bin/python
+
+# Warning: the followings MME must be sent with an MMV = 0, otherwise the plug
+# will not answer to the request.
+
+from scapy.all import Packet
+from scapy.fields import XBitField, XByteField, ByteField, ByteEnumField
+from scapy.fields import StrFixedLenField, MACField, ETHER_ANY, LEShortField
+from scapy.fields import Field
+
+from common import INTELLON_OUI, HPAV_RESULT
+from scammer import MMEPayload
+
+INTELLON_DEVICE_ID = {
+ 1: 'INT6000A1',
+ 2: 'INT6300A0',
+ 3: 'INT6400A0',
+}
+
+class INTTonemapField (Field):
+ """Special Field for Intellon Tonemap field."""
+ def __init__(self, name, default):
+ Field.__init__(self, name, default, "578c")
+
+ # TODO: Implement addfield (self, pkt, s, val) if needed
+
+ def getfield (self, pkt, s):
+ w = s[0:self.sz]
+ result = ""
+ for c in w:
+ valh = (ord(c) >> 4) & 0xf
+ vall = ord(c) & 0xf
+ if valh <= 9:
+ valh += ord ('0')
+ else:
+ valh += ord ('a') - 10
+ if vall <= 9:
+ vall += ord ('0')
+ else:
+ vall += ord ('a') - 10
+ result += chr (vall)
+ result += chr (valh)
+ s = s[self.sz:]
+ return s, result
+
+ def extract_padding(self, s):
+ return "", s
+
+class INT_VS_HEADER(Packet):
+ """The Intellon vendor specific MME."""
+ name = 'HomePlug AV Intellon VS MME'
+ fields_desc = [
+ XBitField('oui', INTELLON_OUI, 24),
+ ]
+
+class INT_VS_SW_VER_REQ(MMEPayload):
+ """Handle a Intellon INT_VS_SW_VER.REQ MME."""
+ name = 'HomePlug AV Intellon VS_SW_VER.REQ'
+ fields_desc = [
+ INT_VS_HEADER,
+ ]
+
+ def extract_padding(self, s):
+ return '', s
+
+class INT_VS_SW_VER_CNF(MMEPayload):
+ """Handle a Intellon VS_SW_VER.CNF MME."""
+ name = 'HomePlug AV Intellon VS_SW_VER.CNF'
+ fields_desc = [
+ INT_VS_HEADER,
+ ByteEnumField('result', 0, HPAV_RESULT),
+ ByteEnumField('deviceid', 0, INTELLON_DEVICE_ID),
+ ByteField('length', 0),
+ StrFixedLenField('version', '', 64),
+ ByteField('upgradable', 0),
+ StrFixedLenField('rsvd', '', 5),
+ ]
+
+ def extract_padding(self, s):
+ return '', s
+
+class INT_VS_TONE_MAP_TX_REQ(MMEPayload):
+ """Handle a Intellon VS_TONE_MAP_TX.REQ MME."""
+ name = 'HomePlug AV Intellon VS_TONE_MAP_TX.REQ'
+ fields_desc = [
+ INT_VS_HEADER,
+ MACField('peer_mac', ETHER_ANY),
+ ByteField('tmslot', 0),
+ ]
+
+class INT_VS_TONE_MAP_TX_CNF(MMEPayload):
+ """Handle a Intellon VS_TONE_MAP_TX.CNF MME."""
+ name = 'HomePlug AV Intellon VS_TONE_MAP_TX.CNF'
+ fields_desc = [
+ INT_VS_HEADER,
+ ByteEnumField('mstatus', 0, {0: 'success', 1: 'unknown mac',
+ 2: 'unknow tm slot'}),
+ ByteField('tmslot', 0),
+ ByteField('numtms', 0),
+ LEShortField('tm_num_act_carriers', 0),
+ INTTonemapField('modulation_list', ''),
+ ]
+
+class INT_VS_TONE_MAP_RX_REQ(MMEPayload):
+ """Handle a Intellon VS_TONE_MAP_RX.REQ MME."""
+ name = 'HomePlug AV Intellon VS_TONE_MAP_RX.REQ'
+ fields_desc = [
+ INT_VS_HEADER,
+ MACField('peer_mac', ETHER_ANY),
+ ByteField('tmslot', 0),
+ ]
+
+class INT_VS_TONE_MAP_RX_CNF(MMEPayload):
+ """Handle a Intellon VS_TONE_MAP_RX.CNF MME."""
+ name = 'HomePlug AV Intellon VS_TONE_MAP_RX.CNF'
+ fields_desc = [
+ INT_VS_HEADER,
+ ByteEnumField('mstatus', 0, {0: 'success', 1: 'unknown mac',
+ 2: 'unknow tm slot'}),
+ ByteField('tmslot', 0),
+ ByteField('numtms', 0),
+ LEShortField('tm_num_act_carriers', 0),
+ INTTonemapField('modulation_list', ''),
+ XByteField('gil', 0),
+ ByteField('avg_agc_gain', 0),
+ ]
+
+if __name__ == '__main__':
+ from scapy.all import Ether, srp1
+ from scammer import MME
+ from optparse import OptionParser
+
+ usage = """%prog [options] smac dmac
+ by default the version MME is sent"""
+
+ parser = OptionParser(usage = usage)
+ parser.add_option('-p', '--peer-mac', dest = 'pmac', type = 'string',
+ help = 'Peer mac address for tonemap MMEs')
+ parser.add_option('-t', '--tx-tonemap', dest = 'txtm', type = 'int',
+ default = None, help = 'TX Tonemap request')
+ parser.add_option('-r', '--rx-tonemap', dest = 'rxtm', type = 'int',
+ default = None, help = 'RX Tonemap request')
+ parser.add_option('-i', '--iface', dest = 'iface', type = 'string',
+ default = 'eth1',
+ help = 'The physical interface to use (default eth1)')
+ options, args = parser.parse_args()
+
+ if len(args) != 2:
+ parser.error('Wrong number of arguments')
+
+ if (options.txtm or options.rxtm) and not options.pmac:
+ parser.error('Missing peer mac address')
+
+ smac, dmac = args
+
+ if options.txtm:
+ print type(options.txtm)
+ m = Ether(src = smac, dst = dmac) / MME (mmv = 0) / \
+ INT_VS_TONE_MAP_TX_REQ(tmslot = options.txtm,
+ peer_mac = options.pmac)
+ elif options.rxtm:
+ m = Ether(src = smac, dst = dmac) / MME (mmv = 0) / \
+ INT_VS_TONE_MAP_RX_REQ(tmslot = options.rxtm,
+ peer_mac = options.pmac)
+ else:
+ m = Ether(src = smac, dst = dmac) / MME (mmv = 0) / \
+ INT_VS_SW_VER_REQ ()
+
+ if m:
+ m.show()
+ cnf = srp1(m, iface = options.iface, verbose = False, timeout = 5)
+ if cnf:
+ cnf.show()