| #!/usr/bin/env python | |
| # | |
| # Copyright (c) 2016, The OpenThread Authors. | |
| # All rights reserved. | |
| # | |
| # Redistribution and use in source and binary forms, with or without | |
| # modification, are permitted provided that the following conditions are met: | |
| # 1. Redistributions of source code must retain the above copyright | |
| # notice, this list of conditions and the following disclaimer. | |
| # 2. Redistributions in binary form must reproduce the above copyright | |
| # notice, this list of conditions and the following disclaimer in the | |
| # documentation and/or other materials provided with the distribution. | |
| # 3. Neither the name of the copyright holder nor the | |
| # names of its contributors may be used to endorse or promote products | |
| # derived from this software without specific prior written permission. | |
| # | |
| # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | |
| # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
| # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
| # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE | |
| # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |
| # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |
| # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
| # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
| # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
| # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
| # POSSIBILITY OF SUCH DAMAGE. | |
| # | |
| import coap | |
| import ipv6 | |
| import lowpan | |
| import message | |
| import mle | |
| import net_crypto | |
| import network_data | |
| import network_layer | |
| import sniffer | |
| DEFAULT_MASTER_KEY = bytearray([0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, | |
| 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff]) | |
| def create_default_network_data_prefix_sub_tlvs_factories(): | |
| return { | |
| network_data.TlvType.HAS_ROUTE: network_data.HasRouteFactory( | |
| routes_factory=network_data.RoutesFactory( | |
| route_factory=network_data.RouteFactory()) | |
| ), | |
| network_data.TlvType.BORDER_ROUTER: network_data.BorderRouterFactory(), | |
| network_data.TlvType.LOWPAN_ID: network_data.LowpanIdFactory() | |
| } | |
| def create_default_network_data_prefix_sub_tlvs_factory(): | |
| return network_data.PrefixSubTlvsFactory( | |
| sub_tlvs_factories=create_default_network_data_prefix_sub_tlvs_factories()) | |
| def create_default_network_data_service_sub_tlvs_factories(): | |
| return { | |
| network_data.TlvType.SERVER: network_data.ServerFactory() | |
| } | |
| def create_default_network_data_service_sub_tlvs_factory(): | |
| return network_data.ServiceSubTlvsFactory( | |
| sub_tlvs_factories=create_default_network_data_service_sub_tlvs_factories()) | |
| def create_default_network_data_commissioning_data_sub_tlvs_factories(): | |
| return { | |
| network_data.MeshcopTlvType.STEERING_DATA: network_data.SteeringDataFactory(), | |
| network_data.MeshcopTlvType.BORDER_AGENT_LOCATOR: network_data.BorderAgentLocatorFactory(), | |
| network_data.MeshcopTlvType.COMMISSIONER_SESSION_ID: network_data.CommissionerSessionIdFactory(), | |
| network_data.MeshcopTlvType.COMMISSIONER_UDP_PORT: network_data.CommissionerUdpPortFactory(), | |
| } | |
| def create_default_network_data_commissioning_data_sub_tlvs_factory(): | |
| return network_data.CommissioningDataSubTlvsFactory( | |
| sub_tlvs_factories=create_default_network_data_commissioning_data_sub_tlvs_factories()) | |
| def create_default_network_data_tlvs_factories(): | |
| return { | |
| network_data.TlvType.PREFIX: network_data.PrefixFactory( | |
| sub_tlvs_factory=create_default_network_data_prefix_sub_tlvs_factory() | |
| ), | |
| network_data.TlvType.SERVICE: network_data.ServiceFactory( | |
| sub_tlvs_factory=create_default_network_data_service_sub_tlvs_factory() | |
| ), | |
| network_data.TlvType.COMMISSIONING: network_data.CommissioningDataFactory( | |
| sub_tlvs_factory=create_default_network_data_commissioning_data_sub_tlvs_factory() | |
| ), | |
| } | |
| def create_default_network_data_tlvs_factory(): | |
| return network_data.NetworkDataTlvsFactory( | |
| sub_tlvs_factories=create_default_network_data_tlvs_factories()) | |
| def create_default_mle_tlv_route64_factory(): | |
| return mle.Route64Factory( | |
| link_quality_and_route_data_factory=mle.LinkQualityAndRouteDataFactory()) | |
| def create_default_mle_tlv_network_data_factory(): | |
| return mle.NetworkDataFactory( | |
| network_data_tlvs_factory=create_default_network_data_tlvs_factory()) | |
| def create_default_mle_tlv_address_registration_factory(): | |
| return mle.AddressRegistrationFactory( | |
| addr_compressed_factory=mle.AddressCompressedFactory(), | |
| addr_full_factory=mle.AddressFullFactory()) | |
| def create_default_mle_tlvs_factories(): | |
| return { | |
| mle.TlvType.SOURCE_ADDRESS: mle.SourceAddressFactory(), | |
| mle.TlvType.MODE: mle.ModeFactory(), | |
| mle.TlvType.TIMEOUT: mle.TimeoutFactory(), | |
| mle.TlvType.CHALLENGE: mle.ChallengeFactory(), | |
| mle.TlvType.RESPONSE: mle.ResponseFactory(), | |
| mle.TlvType.LINK_LAYER_FRAME_COUNTER: mle.LinkLayerFrameCounterFactory(), | |
| mle.TlvType.MLE_FRAME_COUNTER: mle.MleFrameCounterFactory(), | |
| mle.TlvType.ROUTE64: create_default_mle_tlv_route64_factory(), | |
| mle.TlvType.ADDRESS16: mle.Address16Factory(), | |
| mle.TlvType.LEADER_DATA: mle.LeaderDataFactory(), | |
| mle.TlvType.NETWORK_DATA: create_default_mle_tlv_network_data_factory(), | |
| mle.TlvType.TLV_REQUEST: mle.TlvRequestFactory(), | |
| mle.TlvType.SCAN_MASK: mle.ScanMaskFactory(), | |
| mle.TlvType.CONNECTIVITY: mle.ConnectivityFactory(), | |
| mle.TlvType.LINK_MARGIN: mle.LinkMarginFactory(), | |
| mle.TlvType.STATUS: mle.StatusFactory(), | |
| mle.TlvType.VERSION: mle.VersionFactory(), | |
| mle.TlvType.ADDRESS_REGISTRATION: create_default_mle_tlv_address_registration_factory(), | |
| mle.TlvType.CHANNEL: mle.ChannelFactory(), | |
| mle.TlvType.PANID: mle.PanIdFactory(), | |
| mle.TlvType.ACTIVE_TIMESTAMP: mle.ActiveTimestampFactory(), | |
| mle.TlvType.PENDING_TIMESTAMP: mle.PendingTimestampFactory(), | |
| mle.TlvType.ACTIVE_OPERATIONAL_DATASET: mle.ActiveOperationalDatasetFactory(), | |
| mle.TlvType.PENDING_OPERATIONAL_DATASET: mle.PendingOperationalDatasetFactory(), | |
| mle.TlvType.THREAD_DISCOVERY: mle.ThreadDiscoveryFactory() | |
| } | |
| def create_default_mle_crypto_engine(master_key): | |
| return net_crypto.CryptoEngine(crypto_material_creator=net_crypto.MleCryptoMaterialCreator(master_key)) | |
| def create_default_mle_message_factory(master_key): | |
| return mle.MleMessageFactory( | |
| aux_sec_hdr_factory=net_crypto.AuxiliarySecurityHeaderFactory(), | |
| mle_command_factory=mle.MleCommandFactory( | |
| tlvs_factories=create_default_mle_tlvs_factories()), | |
| crypto_engine=create_default_mle_crypto_engine(master_key)) | |
| def create_deafult_network_tlvs_factories(): | |
| return { | |
| network_layer.TlvType.TARGET_EID: network_layer.TargetEidFactory(), | |
| network_layer.TlvType.MAC_EXTENDED_ADDRESS: network_layer.MacExtendedAddressFactory(), | |
| network_layer.TlvType.RLOC16: network_layer.Rloc16Factory(), | |
| network_layer.TlvType.ML_EID: network_layer.MlEidFactory(), | |
| network_layer.TlvType.STATUS: network_layer.StatusFactory(), | |
| network_layer.TlvType.TIME_SINCE_LAST_TRANSACTION: network_layer.TimeSinceLastTransactionFactory(), | |
| network_layer.TlvType.ROUTER_MASK: network_layer.RouterMaskFactory(), | |
| network_layer.TlvType.ND_OPTION: network_layer.NdOptionFactory(), | |
| network_layer.TlvType.ND_DATA: network_layer.NdDataFactory(), | |
| network_layer.TlvType.THREAD_NETWORK_DATA: network_layer.ThreadNetworkDataFactory(create_default_network_data_tlvs_factory), | |
| # Routing information are distributed in a Thread network by MLE Routing TLV | |
| # which is in fact MLE Route64 TLV. Thread specificaton v1.1. - Chapter 5.20 | |
| network_layer.TlvType.MLE_ROUTING: create_default_mle_tlv_route64_factory() | |
| } | |
| def create_default_network_tlvs_factory(): | |
| return network_layer.NetworkLayerTlvsFactory( | |
| tlvs_factories=create_deafult_network_tlvs_factories()) | |
| def create_default_uri_path_based_payload_factories(): | |
| network_layer_tlvs_factory = create_default_network_tlvs_factory() | |
| return { | |
| "/a/as": network_layer_tlvs_factory, | |
| "/a/aq": network_layer_tlvs_factory, | |
| "/a/an": network_layer_tlvs_factory | |
| } | |
| def create_default_coap_message_factory(): | |
| return coap.CoapMessageFactory(options_factory=coap.CoapOptionsFactory(), | |
| uri_path_based_payload_factories=create_default_uri_path_based_payload_factories(), | |
| message_id_to_uri_path_binder=coap.CoapMessageIdToUriPathBinder()) | |
| def create_default_ipv6_hop_by_hop_options_factories(): | |
| return { | |
| 109: ipv6.MPLOptionFactory() | |
| } | |
| def create_default_ipv6_hop_by_hop_options_factory(): | |
| return ipv6.HopByHopOptionsFactory( | |
| options_factories=create_default_ipv6_hop_by_hop_options_factories()) | |
| def create_default_based_on_src_dst_ports_udp_payload_factory(master_key): | |
| mle_message_factory = create_default_mle_message_factory(master_key) | |
| coap_message_factory = create_default_coap_message_factory() | |
| return ipv6.UdpBasedOnSrcDstPortsPayloadFactory( | |
| src_dst_port_based_payload_factories={ | |
| 19788: mle_message_factory, | |
| 61631: coap_message_factory | |
| } | |
| ) | |
| def create_default_ipv6_icmp_body_factories(): | |
| return { | |
| ipv6.ICMP_DESTINATION_UNREACHABLE: ipv6.ICMPv6DestinationUnreachableFactory(), | |
| ipv6.ICMP_ECHO_REQUEST: ipv6.ICMPv6EchoBodyFactory(), | |
| ipv6.ICMP_ECHO_RESPONSE: ipv6.ICMPv6EchoBodyFactory(), | |
| "default": ipv6.BytesPayloadFactory() | |
| } | |
| def create_default_ipv6_upper_layer_factories(master_key): | |
| return { | |
| ipv6.IPV6_NEXT_HEADER_UDP: ipv6.UDPDatagramFactory( | |
| udp_header_factory=ipv6.UDPHeaderFactory(), | |
| udp_payload_factory=create_default_based_on_src_dst_ports_udp_payload_factory(master_key) | |
| ), | |
| ipv6.IPV6_NEXT_HEADER_ICMP: ipv6.ICMPv6Factory( | |
| body_factories=create_default_ipv6_icmp_body_factories() | |
| ) | |
| } | |
| def create_default_lowpan_extension_headers_factories(): | |
| return { | |
| ipv6.IPV6_NEXT_HEADER_HOP_BY_HOP: lowpan.LowpanHopByHopFactory( | |
| hop_by_hop_options_factory=create_default_ipv6_hop_by_hop_options_factory() | |
| ) | |
| } | |
| def create_default_ipv6_extension_headers_factories(): | |
| return { | |
| ipv6.IPV6_NEXT_HEADER_HOP_BY_HOP: ipv6.HopByHopFactory( | |
| hop_by_hop_options_factory=create_default_ipv6_hop_by_hop_options_factory()) | |
| } | |
| def create_default_ipv6_packet_factory(master_key): | |
| return ipv6.IPv6PacketFactory( | |
| ehf=create_default_ipv6_extension_headers_factories(), | |
| ulpf=create_default_ipv6_upper_layer_factories(master_key) | |
| ) | |
| def create_default_lowpan_decompressor(context_manager): | |
| return lowpan.LowpanDecompressor( | |
| lowpan_ip_header_factory=lowpan.LowpanIpv6HeaderFactory( | |
| context_manager=context_manager | |
| ), | |
| lowpan_extension_headers_factory=lowpan.LowpanExtensionHeadersFactory( | |
| ext_headers_factories=create_default_lowpan_extension_headers_factories() | |
| ), | |
| lowpan_udp_header_factory=lowpan.LowpanUdpHeaderFactory() | |
| ) | |
| def create_default_thread_context_manager(): | |
| context_manager = lowpan.ContextManager() | |
| context_manager[0] = lowpan.Context("fd00:0db8::/64") | |
| return context_manager | |
| def create_default_lowpan_parser(context_manager, master_key=DEFAULT_MASTER_KEY): | |
| return lowpan.LowpanParser( | |
| lowpan_mesh_header_factory=lowpan.LowpanMeshHeaderFactory(), | |
| lowpan_decompressor=create_default_lowpan_decompressor(context_manager), | |
| lowpan_fragements_buffers_manager=lowpan.LowpanFragmentsBuffersManager(), | |
| ipv6_packet_factory=create_default_ipv6_packet_factory(master_key) | |
| ) | |
| def create_default_thread_message_factory(master_key=DEFAULT_MASTER_KEY): | |
| context_manager = create_default_thread_context_manager() | |
| lowpan_parser = create_default_lowpan_parser(context_manager, master_key) | |
| return message.MessageFactory(lowpan_parser=lowpan_parser) | |
| def create_default_thread_sniffer(nodeid): | |
| return sniffer.Sniffer(nodeid, create_default_thread_message_factory()) |