BA
/
BaBoRo1
Embed:
(wiki syntax)
Show/hide line numbers
6lowpan_iphc.c
00001 /* 00002 * Copyright (c) 2013-2017, 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 mle_neigh_table_entry_t *mle_entry; 00081 mle_entry = mle_class_get_by_link_address(cur->id, buf->dst_sa .address + 2, buf->dst_sa .addr_type ); 00082 if (mle_entry && thread_addr_is_child(mac_helper_mac16_address_get(cur), mle_entry->short_adr)) { 00083 /* Check if the child can handle only stable network data (e.g. sleepy device) */ 00084 stable_only = !(mle_entry->mode & MLE_THREAD_REQ_FULL_DATA_SET); 00085 } 00086 } 00087 } 00088 00089 if (!buf->link_specific.ieee802_15_4.useDefaultPanId) { 00090 /* Override dest PAN ID (from multicast map above, or neighbour cache) */ 00091 common_write_16_bit(buf->link_specific.ieee802_15_4.dstPanId, buf->dst_sa .address ); 00092 } 00093 00094 /* Figure out which source MAC address to use. Usually try to match the 00095 * source, for best compression, and to ensure if the layer above uses LL64 00096 * (like MLE), it forces us to use our MAC64. 00097 */ 00098 if (thread_info(cur) && !(link_local && thread_insist_that_mesh_isnt_a_link(cur)) && buf->dst_sa .addr_type == ADDR_802_15_4_SHORT ) { 00099 /* For Thread, we want to always use short source address for unicast 00100 * to non-link-local 16-bit addresses, which is the case where we want 00101 * to use mesh headers. 00102 */ 00103 buf->src_sa .addr_type = ADDR_802_15_4_SHORT ; 00104 } else if (addr_iid_matches_eui64(ip_src + 8, cur->mac)) { 00105 buf->src_sa .addr_type = ADDR_802_15_4_LONG ; 00106 } else if (cur->mac_parameters->mac_short_address < 0xfffe && addr_iid_matches_lowpan_short(ip_src + 8, cur->mac_parameters->mac_short_address)) { 00107 buf->src_sa .addr_type = ADDR_802_15_4_SHORT ; 00108 } else { 00109 /* This lets mac_mlme_write_our_addr choose based on address mode */ 00110 buf->src_sa .addr_type = ADDR_NONE ; 00111 } 00112 00113 if (!mac_helper_write_our_addr(cur, &buf->src_sa )) { 00114 return buffer_free(buf); 00115 } 00116 00117 /* Clear Link Layer Re Transmission Counter */ 00118 //buf->fhss_channel_retries_left = 1+ cur->mac_parameters->number_of_fhss_channel_retries; 00119 00120 00121 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 ) { 00122 tr_debug("IP:Dest Pro. addr_type: %02x", buf->dst_sa .addr_type ); 00123 return buffer_free(buf); 00124 } 00125 00126 uint_fast8_t mesh_size; 00127 if (link_local && thread_insist_that_mesh_isnt_a_link(cur)) { 00128 mesh_size = 0; 00129 } else { 00130 /* Allow the link-layer destination addresses passed from upper layers 00131 * to be remapped - used to implement Thread anycast. 00132 * 00133 * Mapping function can change address and type - if it returns false, 00134 * packet is dropped. 00135 * 00136 * Note that this mapping has to be done before IPHC compression, which 00137 * is why it moved from mesh.c. 00138 */ 00139 if (!mesh_address_map(cur, &buf->dst_sa .addr_type , buf->dst_sa .address )) { 00140 tr_debug("mesh_address_map fail"); 00141 return buffer_free(buf); 00142 } 00143 00144 /* After mapping, compute final mesh header size (which depends on 00145 * the final address). 00146 */ 00147 mesh_size = mesh_header_size(buf); 00148 } 00149 00150 if (mesh_size == 0) { 00151 if (buf->dst_sa .addr_type == ADDR_BROADCAST ) { 00152 /* Thread says multicasts other than MLE are sent to our parent, if we're an end device */ 00153 if (cur->ip_multicast_as_mac_unicast_to_parent && !buf->options .ll_broadcast_tx ) { 00154 if (protocol_6lowpan_interface_get_mac_coordinator_address(cur, &buf->dst_sa ) < 0) { 00155 tr_warn("IP: No parent for multicast as unicast"); 00156 return buffer_free(buf); 00157 } 00158 } else { 00159 /* 00160 * Not using a mesh header, so have to "purify" RFC 4944 multicast - we 00161 * set a 100xxxxxxxxxxxxx RFC 4944 multicast address above, but 00162 * IEEE 802.15.4 only supports broadcast in the real MAC header. 00163 */ 00164 common_write_16_bit(0xFFFF, buf->dst_sa .address + 2); 00165 } 00166 } 00167 } 00168 00169 /* RFC 6282+4944 require that we limit compression to the first fragment. 00170 * This check is slightly conservative - always allow 4 for first-fragment header 00171 */ 00172 uint_fast8_t overhead = mac_helper_frame_overhead(cur, buf); 00173 uint_fast16_t max_iphc_size = mac_helper_max_payload_size(cur, overhead) - mesh_size - 4; 00174 00175 buf = iphc_compress(&cur->lowpan_contexts, buf, max_iphc_size, stable_only); 00176 if (!buf) { 00177 return NULL; 00178 } 00179 00180 if (mesh_size != 0) { 00181 buf->info = (buffer_info_t)(B_FROM_IPV6_TXRX | B_TO_MESH_ROUTING | B_DIR_DOWN); 00182 return buf; 00183 } 00184 00185 buf->info = (buffer_info_t)(B_FROM_IPV6_TXRX | B_TO_MAC | B_DIR_DOWN); 00186 00187 return buf; 00188 } 00189 00190 buffer_t *lowpan_up(buffer_t *buf) 00191 { 00192 protocol_interface_info_entry_t *cur = buf->interface ; 00193 00194 /* Reject: 00195 * Packets without address 00196 * Source broadcast PAN ID 00197 * Short source addresses 0xfffe (illegal) and 0xffff (broadcast) 00198 */ 00199 if (buf->dst_sa .addr_type == ADDR_NONE || buf->src_sa .addr_type == ADDR_NONE || 00200 common_read_16_bit(buf->src_sa .address ) == 0xffff || 00201 (buf->dst_sa .addr_type == ADDR_802_15_4_SHORT && common_read_16_bit(buf->src_sa .address + 2) > 0xfffd)) { 00202 goto drop; 00203 } 00204 00205 /* If our PAN ID is set to 0xffff (eg during beacon scan), the MAC will be 00206 * receiving all packets to all PANs. "Mute" 6LoWPAN reception in this state. 00207 */ 00208 if (cur->mac_parameters->pan_id == 0xffff) { 00209 goto drop; 00210 } 00211 00212 const uint8_t *ip_hc = buffer_data_pointer(buf); 00213 00214 //tr_debug("IP-UP"; 00215 00216 if (buffer_data_length(buf) < 4 || addr_check_broadcast(buf->src_sa .address , buf->src_sa .addr_type ) == 0) { 00217 tr_debug("cipv6_up() Too short or broadcast src"); 00218 goto drop; 00219 } else if ((ip_hc[0] & LOWPAN_FRAG_MASK) == LOWPAN_FRAG) { 00220 /* 11 x00xxx: FRAG1/FRAGN (RFC 4944) */ 00221 buf->info = (buffer_info_t)(B_DIR_UP | B_FROM_IPV6_TXRX | B_TO_FRAGMENTATION); 00222 return buf; 00223 } else if ((ip_hc[0] & LOWPAN_MESH_MASK) == LOWPAN_MESH) { 00224 /* 10 xxxxxx: MESH (RFC 4944) */ 00225 buf->info = (buffer_info_t)(B_DIR_UP | B_FROM_IPV6_TXRX | B_TO_MESH_ROUTING); 00226 return buf; 00227 } else if (ip_hc[0] == LOWPAN_DISPATCH_IPV6) { 00228 /* Send this to new handler */ 00229 buffer_data_strip_header(buf, 1); 00230 buf->ip_routed_up = true; 00231 buf->info = (buffer_info_t)(B_DIR_UP | B_FROM_IPV6_TXRX | B_TO_IPV6_FWD); 00232 return buf; 00233 } else if ((ip_hc[0] & LOWPAN_DISPATCH_IPHC_MASK) != LOWPAN_DISPATCH_IPHC) { 00234 /* Not handled: LOWPAN_HC1/LOWPAN_BC0/IPv6 (RFC 4944), or extension */ 00235 tr_debug("LOWPAN: %02x %02x", ip_hc[0], ip_hc[1]); 00236 goto drop; 00237 } 00238 00239 /* Divert to new routing system - in final system, MAC/Mesh/Frag should send to IPV6_TXRX layer */ 00240 buf->ip_routed_up = true; 00241 buf = iphc_decompress(&cur->lowpan_contexts, buf); 00242 if (buf) { 00243 buf->info = (buffer_info_t)(B_DIR_UP | B_FROM_IPV6_TXRX | B_TO_IPV6_FWD); 00244 } 00245 return buf; 00246 00247 drop: 00248 protocol_stats_update(STATS_IP_RX_DROP, 1); 00249 return buffer_free(buf); 00250 } 00251 00252 #endif /* HAVE_CIPV6 */ 00253
Generated on Tue Jul 12 2022 12:21:33 by
