|
| 1 | +/* |
| 2 | + * Copyright (c) 2021, Pelion and affiliates. |
| 3 | + * SPDX-License-Identifier: Apache-2.0 |
| 4 | + * |
| 5 | + * Licensed under the Apache License, Version 2.0 (the "License"); |
| 6 | + * you may not use this file except in compliance with the License. |
| 7 | + * You may obtain a copy of the License at |
| 8 | + * |
| 9 | + * http://www.apache.org/licenses/LICENSE-2.0 |
| 10 | + * |
| 11 | + * Unless required by applicable law or agreed to in writing, software |
| 12 | + * distributed under the License is distributed on an "AS IS" BASIS, |
| 13 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 14 | + * See the License for the specific language governing permissions and |
| 15 | + * limitations under the License. |
| 16 | + */ |
| 17 | + |
| 18 | +#include <string.h> |
| 19 | +#include "nsconfig.h" |
| 20 | +#ifdef HAVE_WS |
| 21 | +#include "ns_types.h" |
| 22 | +#include "ns_trace.h" |
| 23 | +#include "nsdynmemLIB.h" |
| 24 | +#include "net_interface.h" |
| 25 | +#include "eventOS_event.h" |
| 26 | +#include "randLIB.h" |
| 27 | +#include "common_functions.h" |
| 28 | +#include "mac_common_defines.h" |
| 29 | +#include "sw_mac.h" |
| 30 | +#include "ccmLIB.h" |
| 31 | +#include "Core/include/ns_monitor.h" |
| 32 | +#include "NWK_INTERFACE/Include/protocol.h" |
| 33 | +#include "6LoWPAN/Bootstraps/protocol_6lowpan.h" |
| 34 | +#include "6LoWPAN/Bootstraps/protocol_6lowpan_interface.h" |
| 35 | +#include "ipv6_stack/protocol_ipv6.h" |
| 36 | +#include "ipv6_stack/ipv6_routing_table.h" |
| 37 | +#include "6LoWPAN/MAC/mac_helper.h" |
| 38 | +#include "6LoWPAN/MAC/mac_data_poll.h" |
| 39 | +#include "6LoWPAN/MAC/mpx_api.h" |
| 40 | +#include "6LoWPAN/MAC/mac_ie_lib.h" |
| 41 | +#include "MPL/mpl.h" |
| 42 | +#include "RPL/rpl_protocol.h" |
| 43 | +#include "RPL/rpl_control.h" |
| 44 | +#include "RPL/rpl_data.h" |
| 45 | +#include "RPL/rpl_policy.h" |
| 46 | +#include "Common_Protocols/icmpv6.h" |
| 47 | +#include "Common_Protocols/icmpv6_radv.h" |
| 48 | +#include "Common_Protocols/ipv6_constants.h" |
| 49 | +#include "Common_Protocols/ip.h" |
| 50 | +#include "Service_Libs/Trickle/trickle.h" |
| 51 | +#include "Service_Libs/fhss/channel_list.h" |
| 52 | +#include "Service_Libs/utils/ns_time.h" |
| 53 | +#include "6LoWPAN/ws/ws_common_defines.h" |
| 54 | +#include "6LoWPAN/ws/ws_common_defines.h" |
| 55 | +#include "6LoWPAN/ws/ws_config.h" |
| 56 | +#include "6LoWPAN/ws/ws_common.h" |
| 57 | +#include "6LoWPAN/ws/ws_bootstrap.h" |
| 58 | +#include "6LoWPAN/ws/ws_bbr_api_internal.h" |
| 59 | +#include "6LoWPAN/ws/ws_common_defines.h" |
| 60 | +#include "6LoWPAN/ws/ws_llc.h" |
| 61 | +#include "6LoWPAN/ws/ws_neighbor_class.h" |
| 62 | +#include "6LoWPAN/ws/ws_ie_lib.h" |
| 63 | +#include "6LoWPAN/ws/ws_stats.h" |
| 64 | +#include "6LoWPAN/ws/ws_cfg_settings.h" |
| 65 | +#include "6LoWPAN/lowpan_adaptation_interface.h" |
| 66 | +#include "Service_Libs/etx/etx.h" |
| 67 | +#include "Service_Libs/mac_neighbor_table/mac_neighbor_table.h" |
| 68 | +#include "Service_Libs/nd_proxy/nd_proxy.h" |
| 69 | +#include "Service_Libs/blacklist/blacklist.h" |
| 70 | +#include "platform/topo_trace.h" |
| 71 | +#include "dhcp_service_api.h" |
| 72 | +#include "libDHCPv6/libDHCPv6.h" |
| 73 | +#include "libDHCPv6/libDHCPv6_vendordata.h" |
| 74 | +#include "DHCPv6_client/dhcpv6_client_api.h" |
| 75 | +#include "ws_management_api.h" |
| 76 | +#include "net_rpl.h" |
| 77 | +#include "mac_api.h" |
| 78 | +#include "6LoWPAN/ws/ws_pae_controller.h" |
| 79 | +#include "6LoWPAN/ws/ws_eapol_pdu.h" |
| 80 | +#include "6LoWPAN/ws/ws_eapol_auth_relay.h" |
| 81 | +#include "6LoWPAN/ws/ws_eapol_relay.h" |
| 82 | +#include "libNET/src/net_dns_internal.h" |
| 83 | +#include "Service_Libs/random_early_detection/random_early_detection_api.h" |
| 84 | + |
| 85 | +#define TRACE_GROUP "wsbs" |
| 86 | + |
| 87 | +static void ws_bootstrap_6lbr_pan_config_analyse(struct protocol_interface_info_entry *cur, const struct mcps_data_ind_s *data, const struct mcps_data_ie_list *ie_ext, ws_utt_ie_t *ws_utt, ws_us_ie_t *ws_us) |
| 88 | +{ |
| 89 | + ws_bs_ie_t ws_bs_ie; |
| 90 | + ws_bt_ie_t ws_bt_ie; |
| 91 | + llc_neighbour_req_t neighbor_info; |
| 92 | + |
| 93 | + if (data->SrcPANId != cur->ws_info->network_pan_id) { |
| 94 | + return; |
| 95 | + } |
| 96 | + if (!ws_wh_bt_read(ie_ext->headerIeList, ie_ext->headerIeListLength, &ws_bt_ie)) { |
| 97 | + tr_warn("BT-IE"); |
| 98 | + return; |
| 99 | + } |
| 100 | + |
| 101 | + if (!ws_wp_nested_bs_read(ie_ext->payloadIeList, ie_ext->payloadIeListLength, &ws_bs_ie)) { |
| 102 | + // Corrupted |
| 103 | + tr_error("No broadcast schedule"); |
| 104 | + return; |
| 105 | + } |
| 106 | + |
| 107 | + //If we are border router or learned configuration we only update already learned neighbours. |
| 108 | + |
| 109 | + if (ws_bootstrap_neighbor_info_request(cur, data->SrcAddr, &neighbor_info, false)) { |
| 110 | + //Update Neighbor Broadcast and Unicast Parameters |
| 111 | + ws_neighbor_class_neighbor_unicast_time_info_update(neighbor_info.ws_neighbor, ws_utt, data->timestamp, (uint8_t *) data->SrcAddr); |
| 112 | + ws_neighbor_class_neighbor_unicast_schedule_set(neighbor_info.ws_neighbor, ws_us, &cur->ws_info->hopping_schdule); |
| 113 | + ws_neighbor_class_neighbor_broadcast_time_info_update(neighbor_info.ws_neighbor, &ws_bt_ie, data->timestamp); |
| 114 | + ws_neighbor_class_neighbor_broadcast_schedule_set(neighbor_info.ws_neighbor, &ws_bs_ie); |
| 115 | + } |
| 116 | +} |
| 117 | + |
| 118 | +static void ws_bootstrap_6lbr_pan_config_solicit_analyse(struct protocol_interface_info_entry *cur, const struct mcps_data_ind_s *data, ws_utt_ie_t *ws_utt, ws_us_ie_t *ws_us) |
| 119 | +{ |
| 120 | + llc_neighbour_req_t neighbor_info; |
| 121 | + |
| 122 | + if (data->SrcPANId != cur->ws_info->network_pan_id) { |
| 123 | + return; |
| 124 | + } |
| 125 | + |
| 126 | + if (ws_bootstrap_neighbor_info_request(cur, data->SrcAddr, &neighbor_info, false)) { |
| 127 | + ws_neighbor_class_neighbor_unicast_time_info_update(neighbor_info.ws_neighbor, ws_utt, data->timestamp, (uint8_t *) data->SrcAddr); |
| 128 | + ws_neighbor_class_neighbor_unicast_schedule_set(neighbor_info.ws_neighbor, ws_us, &cur->ws_info->hopping_schdule); |
| 129 | + } |
| 130 | +} |
| 131 | + |
| 132 | +void ws_bootstrap_6lbr_asynch_ind(struct protocol_interface_info_entry *cur, const struct mcps_data_ind_s *data, const struct mcps_data_ie_list *ie_ext, uint8_t message_type) |
| 133 | +{ |
| 134 | + // Store weakest heard packet RSSI |
| 135 | + if (cur->ws_info->weakest_received_rssi > data->signal_dbm) { |
| 136 | + cur->ws_info->weakest_received_rssi = data->signal_dbm; |
| 137 | + } |
| 138 | + |
| 139 | + if (data->SrcAddrMode != MAC_ADDR_MODE_64_BIT) { |
| 140 | + // Not from long address |
| 141 | + return; |
| 142 | + } |
| 143 | + ws_stats_update(cur, STATS_WS_ASYNCH_RX, 1); |
| 144 | + //Validate network name |
| 145 | + switch (message_type) { |
| 146 | + case WS_FT_PAN_ADVERT: |
| 147 | + case WS_FT_PAN_ADVERT_SOL: |
| 148 | + case WS_FT_PAN_CONF_SOL: |
| 149 | + //Check Network Name |
| 150 | + if (!ws_bootstrap_network_name_matches(ie_ext, cur->ws_info->cfg->gen.network_name)) { |
| 151 | + // Not in our network |
| 152 | + return; |
| 153 | + } |
| 154 | + break; |
| 155 | + case WS_FT_PAN_CONF: |
| 156 | + break; |
| 157 | + default: |
| 158 | + return; |
| 159 | + } |
| 160 | + //UTT-IE and US-IE are mandatory for all Asynch Messages |
| 161 | + ws_utt_ie_t ws_utt; |
| 162 | + if (!ws_wh_utt_read(ie_ext->headerIeList, ie_ext->headerIeListLength, &ws_utt)) { |
| 163 | + // Corrupted |
| 164 | + return; |
| 165 | + } |
| 166 | + |
| 167 | + ws_us_ie_t ws_us; |
| 168 | + if (!ws_wp_nested_us_read(ie_ext->payloadIeList, ie_ext->payloadIeListLength, &ws_us)) { |
| 169 | + // Corrupted |
| 170 | + return; |
| 171 | + } |
| 172 | + |
| 173 | + if (!ws_bootstrap_validate_channel_plan(&ws_us, cur) || |
| 174 | + !ws_bootstrap_validate_channel_function(&ws_us, NULL)) { |
| 175 | + return; |
| 176 | + } |
| 177 | + |
| 178 | + //Handle Message's |
| 179 | + switch (message_type) { |
| 180 | + case WS_FT_PAN_ADVERT: |
| 181 | + // Analyse Advertisement |
| 182 | + ws_stats_update(cur, STATS_WS_ASYNCH_RX_PA, 1); |
| 183 | + tr_info("received ADVERT Src:%s panid:%x rssi:%d", trace_array(data->SrcAddr, 8), data->SrcPANId, data->signal_dbm); |
| 184 | + // Border routers do not do any analysing on the Advertisements heard from others |
| 185 | + // in future if we need PANID conflict detection we could use this |
| 186 | + break; |
| 187 | + case WS_FT_PAN_ADVERT_SOL: |
| 188 | + ws_stats_update(cur, STATS_WS_ASYNCH_RX_PAS, 1); |
| 189 | + tr_info("received ADVERT SOL Src:%s rssi:%d", trace_array(data->SrcAddr, 8), data->signal_dbm); |
| 190 | + trickle_inconsistent_heard(&cur->ws_info->trickle_pan_advertisement, &cur->ws_info->trickle_params_pan_discovery); |
| 191 | + |
| 192 | + break; |
| 193 | + case WS_FT_PAN_CONF: |
| 194 | + ws_stats_update(cur, STATS_WS_ASYNCH_RX_PC, 1); |
| 195 | + tr_info("received CONFIG Src:%s rssi:%d", trace_array(data->SrcAddr, 8), data->signal_dbm); |
| 196 | + ws_bootstrap_6lbr_pan_config_analyse(cur, data, ie_ext, &ws_utt, &ws_us); |
| 197 | + break; |
| 198 | + case WS_FT_PAN_CONF_SOL: |
| 199 | + ws_stats_update(cur, STATS_WS_ASYNCH_RX_PCS, 1); |
| 200 | + tr_info("received CONFIG SOL Src:%s rssi:%d", trace_array(data->SrcAddr, 8), data->signal_dbm); |
| 201 | + trickle_inconsistent_heard(&cur->ws_info->trickle_pan_config, &cur->ws_info->trickle_params_pan_discovery); |
| 202 | + ws_bootstrap_6lbr_pan_config_solicit_analyse(cur, data, &ws_utt, &ws_us); |
| 203 | + default: |
| 204 | + // Unknown message do not process |
| 205 | + break; |
| 206 | + } |
| 207 | +} |
| 208 | + |
| 209 | +void ws_bootstrap_6lbr_asynch_confirm(struct protocol_interface_info_entry *interface, uint8_t asynch_message) |
| 210 | +{ |
| 211 | + ws_stats_update(interface, STATS_WS_ASYNCH_TX, 1); |
| 212 | + if (interface->bootsrap_mode == ARM_NWK_BOOTSRAP_MODE_6LoWPAN_BORDER_ROUTER) { |
| 213 | + if (asynch_message == WS_FT_PAN_CONF && interface->ws_info->pending_key_index_info.state == PENDING_KEY_INDEX_ACTIVATE) { |
| 214 | + interface->ws_info->pending_key_index_info.state = NO_PENDING_PROCESS; |
| 215 | + tr_info("Activate new default key %u", interface->ws_info->pending_key_index_info.index + 1); |
| 216 | + mac_helper_security_auto_request_key_index_set(interface, interface->ws_info->pending_key_index_info.index, interface->ws_info->pending_key_index_info.index + 1); |
| 217 | + } |
| 218 | + } |
| 219 | +} |
| 220 | + |
| 221 | +#endif |
| 222 | + |
0 commit comments