243 lines
10 KiB
Python
243 lines
10 KiB
Python
|
#! /usr/bin/env python
|
||
|
|
||
|
# This file is part of Scapy
|
||
|
# Scapy is free software: you can redistribute it and/or modify
|
||
|
# it under the terms of the GNU General Public License as published by
|
||
|
# the Free Software Foundation, either version 2 of the License, or
|
||
|
# any later version.
|
||
|
#
|
||
|
# Scapy is distributed in the hope that it will be useful,
|
||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
|
# GNU General Public License for more details.
|
||
|
#
|
||
|
# You should have received a copy of the GNU General Public License
|
||
|
# along with Scapy. If not, see <http://www.gnu.org/licenses/>.
|
||
|
|
||
|
# scapy.contrib.description = HomePlugGP Layer
|
||
|
# scapy.contrib.status = loads
|
||
|
|
||
|
from __future__ import absolute_import
|
||
|
|
||
|
from scapy.packet import Packet, bind_layers
|
||
|
from scapy.fields import ByteEnumField, ByteField, FieldLenField, \
|
||
|
MACField, PacketListField, ShortField, \
|
||
|
StrFixedLenField, XIntField, PacketField \
|
||
|
|
||
|
# This layer extends HomePlug AV one
|
||
|
from scapy.contrib.homeplugav import HomePlugAV, QualcommTypeList
|
||
|
|
||
|
# Copyright (C) HomePlugGP Layer for Scapy by FlUxIuS (Sebastien Dudek)
|
||
|
# As HomePlug GreenPHY is a subset of HomePlug AV, that is why we use
|
||
|
# HomePlugAV layer as a base here.
|
||
|
|
||
|
HomePlugGPTypes = {0x6008: "CM_SET_KEY_REQ",
|
||
|
0x6009: "CM_SET_KEY_CNF",
|
||
|
0x6064: "CM_SLAC_PARM_REQ",
|
||
|
0x6065: "CM_SLAC_PARM_CNF",
|
||
|
0x606e: "CM_ATTEN_CHAR_IN",
|
||
|
0x606a: "CM_START_ATTEN_CHAR_IND",
|
||
|
0x606f: "CM_ATTEN_CHAR_RSP",
|
||
|
0x6076: "CM_MNBC_SOUND_IND",
|
||
|
0x607c: "CM_SLAC_MATCH_REQ",
|
||
|
0x607d: "CM_SLAC_MATCH_CNF",
|
||
|
0x6086: "CM_ATTENUATION_CHARACTERISTICS_MME"}
|
||
|
|
||
|
QualcommTypeList.update(HomePlugGPTypes)
|
||
|
|
||
|
HPGP_codes = {0x0: "Success"}
|
||
|
|
||
|
KeyType_list = {0x01: "NMK (AES-128)"}
|
||
|
|
||
|
######################################################################
|
||
|
# SLAC operations
|
||
|
######################################################################
|
||
|
|
||
|
|
||
|
class CM_SLAC_PARM_REQ(Packet):
|
||
|
name = "CM_SLAC_PARM_REQ"
|
||
|
fields_desc = [ByteField("ApplicationType", 0x0),
|
||
|
ByteField("SecurityType", 0x0),
|
||
|
StrFixedLenField("RunID", b"\x00" * 8, 8)]
|
||
|
|
||
|
|
||
|
class CM_SLAC_PARM_CNF(Packet):
|
||
|
name = "CM_SLAC_PARM_CNF"
|
||
|
fields_desc = [MACField("MSoundTargetMAC", "00:00:00:00:00:00"),
|
||
|
ByteField("NumberMSounds", 0x0),
|
||
|
ByteField("TimeOut", 0x0),
|
||
|
ByteField("ResponseType", 0x0),
|
||
|
MACField("ForwardingSTA", "00:00:00:00:00:00"),
|
||
|
ByteField("ApplicationType", 0x0),
|
||
|
ByteField("SecurityType", 0x0),
|
||
|
StrFixedLenField("RunID", b"\x00" * 8, 8)]
|
||
|
|
||
|
|
||
|
class HPGP_GROUP(Packet):
|
||
|
name = "HPGP_GROUP"
|
||
|
fields_desc = [ByteField("group", 0x0)]
|
||
|
|
||
|
def extract_padding(self, p):
|
||
|
return "", p
|
||
|
|
||
|
|
||
|
class VS_ATTENUATION_CHARACTERISTICS_MME(Packet):
|
||
|
name = "VS_ATTENUATION_CHARACTERISTICS_MME"
|
||
|
fields_desc = [MACField("EVMACAddress", "00:00:00:00:00:00"),
|
||
|
FieldLenField("NumberOfGroups", None,
|
||
|
count_of="Groups", fmt="B"),
|
||
|
ByteField("NumberOfCarrierPerGroupe", 0),
|
||
|
StrFixedLenField("Reserved", b"\x00" * 7, 7),
|
||
|
PacketListField("Groups", "", HPGP_GROUP,
|
||
|
length_from=lambda pkt: pkt.NumberOfGroups)]
|
||
|
|
||
|
|
||
|
class CM_ATTENUATION_CHARACTERISTICS_MME(Packet):
|
||
|
name = "CM_ATTENUATION_CHARACTERISTICS_MME"
|
||
|
fields_desc = [MACField("EVMACAddress", "00:00:00:00:00:00"),
|
||
|
FieldLenField("NumberOfGroups", None, count_of="Groups",
|
||
|
fmt="B"),
|
||
|
ByteField("NumberOfCarrierPerGroupe", 0),
|
||
|
PacketListField("Groups", "", HPGP_GROUP,
|
||
|
length_from=lambda pkt: pkt.NumberOfGroups)]
|
||
|
|
||
|
|
||
|
class CM_ATTEN_CHAR_IND(Packet):
|
||
|
name = "CM_ATTEN_CHAR_IND"
|
||
|
fields_desc = [ByteField("ApplicationType", 0x0),
|
||
|
ByteField("SecurityType", 0x0),
|
||
|
MACField("SourceAdress", "00:00:00:00:00:00"),
|
||
|
StrFixedLenField("RunID", b"\x00" * 8, 8),
|
||
|
StrFixedLenField("SourceID", b"\x00" * 17, 17),
|
||
|
StrFixedLenField("ResponseID", b"\x00" * 17, 17),
|
||
|
ByteField("NumberOfSounds", 0x0),
|
||
|
FieldLenField("NumberOfGroups", None, count_of="Groups",
|
||
|
fmt="B"),
|
||
|
PacketListField("Groups", "", HPGP_GROUP,
|
||
|
length_from=lambda pkt: pkt.NumberOfGroups)]
|
||
|
|
||
|
|
||
|
class CM_ATTEN_CHAR_RSP(Packet):
|
||
|
name = "CM_ATTEN_CHAR_RSP"
|
||
|
fields_desc = [ByteField("ApplicationType", 0x0),
|
||
|
ByteField("SecurityType", 0x0),
|
||
|
MACField("SourceAdress", "00:00:00:00:00:00"),
|
||
|
StrFixedLenField("RunID", b"\x00" * 8, 8),
|
||
|
StrFixedLenField("SourceID", b"\x00" * 17, 17),
|
||
|
StrFixedLenField("ResponseID", b"\x00" * 17, 17),
|
||
|
ByteEnumField("Result", 0x0, HPGP_codes)]
|
||
|
|
||
|
|
||
|
class SLAC_varfield(Packet):
|
||
|
name = "SLAC_varfield"
|
||
|
fields_desc = [StrFixedLenField("EVID", b"\x00" * 17, 17),
|
||
|
MACField("EVMAC", "00:00:00:00:00:00"),
|
||
|
StrFixedLenField("EVSEID", b"\x00" * 17, 17),
|
||
|
MACField("EVSEMAC", "00:00:00:00:00:00"),
|
||
|
StrFixedLenField("RunID", b"\x00" * 8, 8),
|
||
|
StrFixedLenField("RSVD", b"\x00" * 8, 8)]
|
||
|
|
||
|
|
||
|
class CM_SLAC_MATCH_REQ(Packet):
|
||
|
name = "CM_SLAC_MATCH_REQ"
|
||
|
fields_desc = [ByteField("ApplicationType", 0x0),
|
||
|
ByteField("SecurityType", 0x0),
|
||
|
FieldLenField("MatchVariableFieldLen", None,
|
||
|
count_of="VariableField", fmt="H"),
|
||
|
PacketField("VariableField",
|
||
|
SLAC_varfield(),
|
||
|
SLAC_varfield)]
|
||
|
|
||
|
|
||
|
class SLAC_varfield_cnf(Packet):
|
||
|
name = "SLAC_varfield"
|
||
|
fields_desc = [StrFixedLenField("EVID", b"\x00" * 17, 17),
|
||
|
MACField("EVMAC", "00:00:00:00:00:00"),
|
||
|
StrFixedLenField("EVSEID", b"\x00" * 17, 17),
|
||
|
MACField("EVSEMAC", "00:00:00:00:00:00"),
|
||
|
StrFixedLenField("RunID", b"\x00" * 8, 8),
|
||
|
StrFixedLenField("RSVD", b"\x00" * 8, 8),
|
||
|
StrFixedLenField("NetworkID", b"\x00" * 7, 7),
|
||
|
ByteField("Reserved", 0x0),
|
||
|
StrFixedLenField("NMK", b"\x00" * 16, 16)]
|
||
|
|
||
|
|
||
|
class CM_SLAC_MATCH_CNF(Packet):
|
||
|
name = "CM_SLAC_MATCH_CNF"
|
||
|
fields_desc = [ByteField("ApplicationType", 0x0),
|
||
|
ByteField("SecurityType", 0x0),
|
||
|
FieldLenField("MatchVariableFieldLen", None,
|
||
|
count_of="VariableField", fmt="H"),
|
||
|
PacketField("VariableField",
|
||
|
SLAC_varfield_cnf(),
|
||
|
SLAC_varfield_cnf)]
|
||
|
|
||
|
|
||
|
class CM_START_ATTEN_CHAR_IND(Packet):
|
||
|
name = "CM_START_ATTEN_CHAR_IND"
|
||
|
fields_desc = [ByteField("ApplicationType", 0x0),
|
||
|
ByteField("SecurityType", 0x0),
|
||
|
ByteField("NumberOfSounds", 0x0),
|
||
|
ByteField("TimeOut", 0x0),
|
||
|
ByteField("ResponseType", 0x0),
|
||
|
MACField("ForwardingSTA", "00:00:00:00:00:00"),
|
||
|
StrFixedLenField("RunID", b"\x00" * 8, 8)]
|
||
|
|
||
|
|
||
|
class CM_MNBC_SOUND_IND(Packet):
|
||
|
name = "CM_MNBC_SOUND_IND"
|
||
|
fields_desc = [ByteField("ApplicationType", 0x0),
|
||
|
ByteField("SecurityType", 0x0),
|
||
|
StrFixedLenField("SenderID", b"\x00" * 17, 17),
|
||
|
ByteField("Countdown", 0x0),
|
||
|
StrFixedLenField("RunID", b"\x00" * 8, 8),
|
||
|
StrFixedLenField("RSVD", b"\x00" * 8, 8),
|
||
|
StrFixedLenField("RandomValue", b"\x00" * 16, 16)]
|
||
|
|
||
|
|
||
|
######################################################################
|
||
|
# Set keys for GP
|
||
|
######################################################################
|
||
|
|
||
|
|
||
|
class CM_SET_KEY_REQ(Packet):
|
||
|
name = "CM_SET_KEY_REQ"
|
||
|
fields_desc = [ByteEnumField("KeyType", 0x0, KeyType_list),
|
||
|
XIntField("MyNonce", 0),
|
||
|
XIntField("YourNonce", 0),
|
||
|
ByteField("PID", 0),
|
||
|
ShortField("ProtoRunNumber", 0),
|
||
|
ByteField("ProtoMessNumber", 0),
|
||
|
ByteField("CCoCapability", 0),
|
||
|
StrFixedLenField("NetworkID", b"\x00" * 7, 7),
|
||
|
ByteField("NewEncKeySelect", 0),
|
||
|
StrFixedLenField("NewKey", b"\x00" * 16, 16)]
|
||
|
|
||
|
|
||
|
class CM_SET_KEY_CNF(Packet):
|
||
|
name = "CM_SET_KEY_CNF"
|
||
|
fields_desc = [ByteEnumField("Result", 0x0, HPGP_codes),
|
||
|
XIntField("MyNonce", 0),
|
||
|
XIntField("YourNonce", 0),
|
||
|
ByteField("PID", 0),
|
||
|
ShortField("ProtoRunNumber", 0),
|
||
|
ByteField("ProtoMessNumber", 0),
|
||
|
ByteField("CCoCapability", 0)]
|
||
|
|
||
|
|
||
|
# END #
|
||
|
|
||
|
|
||
|
bind_layers(HomePlugAV, VS_ATTENUATION_CHARACTERISTICS_MME, HPtype=0xA14E)
|
||
|
bind_layers(HomePlugAV, CM_SLAC_PARM_REQ, HPtype=0x6064)
|
||
|
bind_layers(HomePlugAV, CM_SLAC_PARM_CNF, HPtype=0x6065)
|
||
|
bind_layers(HomePlugAV, CM_START_ATTEN_CHAR_IND, HPtype=0x606a)
|
||
|
bind_layers(HomePlugAV, CM_ATTEN_CHAR_IND, HPtype=0x606e)
|
||
|
bind_layers(HomePlugAV, CM_ATTEN_CHAR_RSP, HPtype=0x606f)
|
||
|
bind_layers(HomePlugAV, CM_MNBC_SOUND_IND, HPtype=0x6076)
|
||
|
bind_layers(HomePlugAV, CM_SLAC_MATCH_REQ, HPtype=0x607c)
|
||
|
bind_layers(HomePlugAV, CM_SLAC_MATCH_CNF, HPtype=0x607d)
|
||
|
bind_layers(HomePlugAV, CM_SET_KEY_REQ, HPtype=0x6008)
|
||
|
bind_layers(HomePlugAV, CM_SET_KEY_CNF, HPtype=0x6009)
|
||
|
bind_layers(HomePlugAV, CM_ATTENUATION_CHARACTERISTICS_MME, HPtype=0x6086)
|