Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: TYBLE16_simple_data_logger TYBLE16_MP3_Air
6lowpan_iphc.c
00001 /* 00002 * Copyright (c) 2013-2018, Arm Limited and affiliates. 00003 * SPDX-License-Identifier: Apache-2.0 00004 * 00005 * Licensed under the Apache License, Version 2.0 (the "License"); 00006 * you may not use this file except in compliance with the License. 00007 * You may obtain a copy of the License at 00008 * 00009 * http://www.apache.org/licenses/LICENSE-2.0 00010 * 00011 * Unless required by applicable law or agreed to in writing, software 00012 * distributed under the License is distributed on an "AS IS" BASIS, 00013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00014 * See the License for the specific language governing permissions and 00015 * limitations under the License. 00016 */ 00017 00018 #include "nsconfig.h" 00019 #define HAVE_CIPV6 00020 00021 #ifdef HAVE_CIPV6 00022 #include "ns_types.h" 00023 #include "string.h" 00024 #include "ns_trace.h" 00025 #include "Common_Protocols/ipv6.h" 00026 #include "Common_Protocols/ipv6_resolution.h" 00027 #include "6LoWPAN/IPHC_Decode/cipv6.h" 00028 #include "NWK_INTERFACE/Include/protocol.h" 00029 #include "ipv6_stack/protocol_ipv6.h" 00030 #include "6LoWPAN/IPHC_Decode/iphc_compress.h" 00031 #include "6LoWPAN/IPHC_Decode/iphc_decompress.h" 00032 #include "6LoWPAN/Mesh/mesh.h" 00033 #include "6LoWPAN/Thread/thread_common.h" 00034 #include "6LoWPAN/MAC/mac_helper.h" 00035 #include "MLE/mle.h" 00036 00037 #include "6LoWPAN/Bootstraps/protocol_6lowpan.h" 00038 #include "nwk_stats_api.h" 00039 #include "NWK_INTERFACE/Include/protocol_stats.h" 00040 #include "common_functions.h" 00041 00042 #define TRACE_GROUP "iphc" 00043 00044 /* Input: Final IP packet for transmission on link. 00045 * Buffer destination = final destination 00046 * Buffer source undefined. 00047 * Route next hop address set. 00048 * Output: Buffer destination+source = link-layer addresses 00049 * Sent to mesh, LowPAN fragmentation or MAC layers 00050 */ 00051 buffer_t *lowpan_down(buffer_t *buf) 00052 { 00053 protocol_interface_info_entry_t *cur = buf->interface ; 00054 00055 buf->options .type = 0; 00056 00057 if (!buf->route) { 00058 tr_debug("lowpan_down route"); 00059 return buffer_free(buf); 00060 } 00061 00062 const uint8_t *ip_src = buffer_data_pointer(buf) + 8; 00063 const uint8_t *next_hop = buf->route->route_info.next_hop_addr; 00064 bool link_local = addr_is_ipv6_link_local(next_hop); 00065 bool stable_only = false; 00066 00067 /* We have IP next hop - figure out the MAC address */ 00068 if (addr_is_ipv6_multicast(next_hop)) { 00069 buf->dst_sa .addr_type = ADDR_BROADCAST ; 00070 common_write_16_bit(cur->mac_parameters->pan_id, buf->dst_sa .address ); 00071 buf->dst_sa .address [2] = 0x80 | (next_hop[14] & 0x1f); 00072 buf->dst_sa .address [3] = next_hop[15]; 00073 stable_only = true; 00074 } else { /* unicast */ 00075 ipv6_neighbour_t *n = ipv6_interface_resolve_new(cur, buf); 00076 if (!n) { 00077 return NULL; 00078 } 00079 if (thread_info(cur)) { 00080 stable_only = thread_stable_context_check(cur, buf); 00081 } 00082 } 00083 00084 if (!buf->link_specific.ieee802_15_4.useDefaultPanId) { 00085 /* Override dest PAN ID (from multicast map above, or neighbour cache) */ 00086 common_write_16_bit(buf->link_specific.ieee802_15_4.dstPanId, buf->dst_sa .address ); 00087 } 00088 00089 /* Figure out which source MAC address to use. Usually try to match the 00090 * source, for best compression, and to ensure if the layer above uses LL64 00091 * (like MLE), it forces us to use our MAC64. 00092 */ 00093 if (thread_info(cur) && !(link_local && thread_insist_that_mesh_isnt_a_link(cur)) && buf->dst_sa .addr_type == ADDR_802_15_4_SHORT ) { 00094 /* For Thread, we want to always use short source address for unicast 00095 * to non-link-local 16-bit addresses, which is the case where we want 00096 * to use mesh headers. 00097 */ 00098 buf->src_sa .addr_type = ADDR_802_15_4_SHORT ; 00099 } else if (addr_iid_matches_eui64(ip_src + 8, cur->mac)) { 00100 buf->src_sa .addr_type = ADDR_802_15_4_LONG ; 00101 } else if (cur->mac_parameters->mac_short_address < 0xfffe && addr_iid_matches_lowpan_short(ip_src + 8, cur->mac_parameters->mac_short_address)) { 00102 buf->src_sa .addr_type = ADDR_802_15_4_SHORT ; 00103 } else { 00104 /* This lets mac_mlme_write_our_addr choose based on address mode */ 00105 buf->src_sa .addr_type = ADDR_NONE ; 00106 } 00107 00108 if (!mac_helper_write_our_addr(cur, &buf->src_sa )) { 00109 return buffer_free(buf); 00110 } 00111 00112 /* Clear Link Layer Re Transmission Counter */ 00113 //buf->fhss_channel_retries_left = 1+ cur->mac_parameters->number_of_fhss_channel_retries; 00114 00115 00116 if (buf->dst_sa .addr_type != ADDR_802_15_4_LONG && buf->dst_sa .addr_type != ADDR_802_15_4_SHORT && buf->dst_sa .addr_type != ADDR_BROADCAST ) { 00117 tr_debug("IP:Dest Pro. addr_type: %02x", buf->dst_sa .addr_type ); 00118 return buffer_free(buf); 00119 } 00120 00121 uint_fast8_t mesh_size; 00122 if (link_local && thread_insist_that_mesh_isnt_a_link(cur)) { 00123 mesh_size = 0; 00124 } else { 00125 /* Allow the link-layer destination addresses passed from upper layers 00126 * to be remapped - used to implement Thread anycast. 00127 * 00128 * Mapping function can change address and type - if it returns false, 00129 * packet is dropped. 00130 * 00131 * Note that this mapping has to be done before IPHC compression, which 00132 * is why it moved from mesh.c. 00133 */ 00134 if (!mesh_address_map(cur, &buf->dst_sa .addr_type , buf->dst_sa .address )) { 00135 tr_debug("mesh_address_map fail"); 00136 return buffer_free(buf); 00137 } 00138 00139 /* After mapping, compute final mesh header size (which depends on 00140 * the final address). 00141 */ 00142 mesh_size = mesh_header_size(buf); 00143 } 00144 00145 if (mesh_size == 0) { 00146 if (buf->dst_sa .addr_type == ADDR_BROADCAST ) { 00147 /* Thread says multicasts other than MLE are sent to our parent, if we're an end device */ 00148 if (cur->ip_multicast_as_mac_unicast_to_parent && !buf->options .ll_broadcast_tx ) { 00149 if (protocol_6lowpan_interface_get_mac_coordinator_address(cur, &buf->dst_sa ) < 0) { 00150 tr_warn("IP: No parent for multicast as unicast"); 00151 return buffer_free(buf); 00152 } 00153 } else { 00154 /* 00155 * Not using a mesh header, so have to "purify" RFC 4944 multicast - we 00156 * set a 100xxxxxxxxxxxxx RFC 4944 multicast address above, but 00157 * IEEE 802.15.4 only supports broadcast in the real MAC header. 00158 */ 00159 common_write_16_bit(0xFFFF, buf->dst_sa .address + 2); 00160 } 00161 } 00162 } 00163 00164 /* RFC 6282+4944 require that we limit compression to the first fragment. 00165 * This check is slightly conservative - always allow 4 for first-fragment header 00166 */ 00167 uint_fast16_t overhead = mac_helper_frame_overhead(cur, buf); 00168 uint_fast16_t max_iphc_size = mac_helper_max_payload_size(cur, overhead) - mesh_size - 4; 00169 00170 buf = iphc_compress(&cur->lowpan_contexts, buf, max_iphc_size, stable_only); 00171 if (!buf) { 00172 return NULL; 00173 } 00174 00175 if (mesh_size != 0) { 00176 buf->info = (buffer_info_t)(B_FROM_IPV6_TXRX | B_TO_MESH_ROUTING | B_DIR_DOWN); 00177 return buf; 00178 } 00179 00180 buf->info = (buffer_info_t)(B_FROM_IPV6_TXRX | B_TO_MAC | B_DIR_DOWN); 00181 00182 return buf; 00183 } 00184 00185 buffer_t *lowpan_up(buffer_t *buf) 00186 { 00187 protocol_interface_info_entry_t *cur = buf->interface ; 00188 00189 /* Reject: 00190 * Packets without address 00191 * Source broadcast PAN ID 00192 * Short source addresses 0xfffe (illegal) and 0xffff (broadcast) 00193 */ 00194 if (buf->dst_sa .addr_type == ADDR_NONE || buf->src_sa .addr_type == ADDR_NONE || 00195 common_read_16_bit(buf->src_sa .address ) == 0xffff || 00196 (buf->dst_sa .addr_type == ADDR_802_15_4_SHORT && common_read_16_bit(buf->src_sa .address + 2) > 0xfffd)) { 00197 goto drop; 00198 } 00199 00200 /* If our PAN ID is set to 0xffff (eg during beacon scan), the MAC will be 00201 * receiving all packets to all PANs. "Mute" 6LoWPAN reception in this state. 00202 */ 00203 if (cur->mac_parameters->pan_id == 0xffff) { 00204 goto drop; 00205 } 00206 00207 const uint8_t *ip_hc = buffer_data_pointer(buf); 00208 00209 //tr_debug("IP-UP"; 00210 00211 if (buffer_data_length(buf) < 4 || addr_check_broadcast(buf->src_sa .address , buf->src_sa .addr_type ) == 0) { 00212 tr_debug("cipv6_up() Too short or broadcast src"); 00213 goto drop; 00214 } else if ((ip_hc[0] & LOWPAN_FRAG_MASK) == LOWPAN_FRAG) { 00215 /* 11 x00xxx: FRAG1/FRAGN (RFC 4944) */ 00216 buf->info = (buffer_info_t)(B_DIR_UP | B_FROM_IPV6_TXRX | B_TO_FRAGMENTATION); 00217 return buf; 00218 } else if ((ip_hc[0] & LOWPAN_MESH_MASK) == LOWPAN_MESH) { 00219 /* 10 xxxxxx: MESH (RFC 4944) */ 00220 buf->info = (buffer_info_t)(B_DIR_UP | B_FROM_IPV6_TXRX | B_TO_MESH_ROUTING); 00221 return buf; 00222 } else if (ip_hc[0] == LOWPAN_DISPATCH_IPV6) { 00223 /* Send this to new handler */ 00224 buffer_data_strip_header(buf, 1); 00225 buf->ip_routed_up = true; 00226 buf->info = (buffer_info_t)(B_DIR_UP | B_FROM_IPV6_TXRX | B_TO_IPV6_FWD); 00227 return buf; 00228 } else if ((ip_hc[0] & LOWPAN_DISPATCH_IPHC_MASK) != LOWPAN_DISPATCH_IPHC) { 00229 /* Not handled: LOWPAN_HC1/LOWPAN_BC0/IPv6 (RFC 4944), or extension */ 00230 tr_debug("LOWPAN: %02x %02x", ip_hc[0], ip_hc[1]); 00231 goto drop; 00232 } 00233 00234 /* Divert to new routing system - in final system, MAC/Mesh/Frag should send to IPV6_TXRX layer */ 00235 buf->ip_routed_up = true; 00236 buf = iphc_decompress(&cur->lowpan_contexts, buf); 00237 if (buf) { 00238 buf->info = (buffer_info_t)(B_DIR_UP | B_FROM_IPV6_TXRX | B_TO_IPV6_FWD); 00239 } 00240 return buf; 00241 00242 drop: 00243 protocol_stats_update(STATS_IP_RX_DROP, 1); 00244 return buffer_free(buf); 00245 } 00246 00247 #endif /* HAVE_CIPV6 */ 00248
Generated on Tue Jul 12 2022 13:54:00 by
