BA / Mbed OS BaBoRo1
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers thread_network_data_lib.c Source File

thread_network_data_lib.c

00001 /*
00002  * Copyright (c) 2014-2017, Arm Limited and affiliates.
00003  * SPDX-License-Identifier: BSD-3-Clause
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions are met:
00007  *
00008  * 1. Redistributions of source code must retain the above copyright
00009  *    notice, this list of conditions and the following disclaimer.
00010  * 2. Redistributions in binary form must reproduce the above copyright
00011  *    notice, this list of conditions and the following disclaimer in the
00012  *    documentation and/or other materials provided with the distribution.
00013  * 3. Neither the name of the copyright holder nor the
00014  *    names of its contributors may be used to endorse or promote products
00015  *    derived from this software without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00018  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00019  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00020  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
00021  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00022  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00023  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00024  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00025  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00026  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00027  * POSSIBILITY OF SUCH DAMAGE.
00028  */
00029 /*
00030  * \file thread_network_data_lib.c
00031  * \brief Add short description about this file!!!
00032  *
00033  */
00034 #include "nsconfig.h"
00035 #ifdef HAVE_THREAD
00036 #include "thread_tmfcop_lib.h"
00037 #include <string.h>
00038 #include <ns_types.h>
00039 #include <nsdynmemLIB.h>
00040 #include "common_functions.h"
00041 #include "ns_trace.h"
00042 #include "NWK_INTERFACE/Include/protocol.h"
00043 #include "6LoWPAN/Thread/thread_common.h"
00044 #include "6LoWPAN/Thread/thread_joiner_application.h"
00045 #include "6LoWPAN/Thread/thread_network_data_lib.h"
00046 #include "6LoWPAN/Thread/thread_management_internal.h"
00047 #include "6LoWPAN/Thread/thread_management_client.h"
00048 #include "6LoWPAN/Thread/thread_bootstrap.h"
00049 
00050 #define TRACE_GROUP "tndl"
00051 
00052 /**
00053  * Claculate Prefix bits to bytes count
00054  *
00055  * \param prefixLenInBits len in bits
00056  *
00057  * return Byte length
00058  */
00059 uint8_t prefixBits_to_bytes(uint8_t prefixLenInBits)
00060 {
00061     uint8_t prefix_len = 0;
00062     if (prefixLenInBits) {
00063         prefix_len = (prefixLenInBits / 8);
00064         if (prefixLenInBits % 8) {
00065             prefix_len++;
00066         }
00067     }
00068     return prefix_len;
00069 }
00070 
00071 static int thread_network_data_prefix_sub_tlv_malformed_check(uint8_t *data_ptr, uint8_t data_length)
00072 {
00073     uint8_t *dptr;
00074     uint8_t length;
00075     uint8_t type;
00076     uint8_t prefix_len;
00077     dptr = data_ptr;
00078     //SKIP Domain ID
00079     dptr++;
00080     data_length--;
00081     //Read Prefix len
00082 
00083     prefix_len = prefixBits_to_bytes(*dptr);
00084     prefix_len++; //Add
00085     if (prefix_len >= data_length) {
00086         return -1;
00087     }
00088 
00089     data_length -= prefix_len;
00090     dptr += prefix_len;
00091 
00092 
00093     while (data_length) {
00094         if (data_length >= 2) {
00095             type  = *dptr++;
00096             length = *dptr++;
00097             data_length -= 2;
00098             if (data_length >= length) {
00099                 type &= THREAD_NWK_DATA_TYPE_MASK;
00100                 if (type == THREAD_NWK_DATA_TYPE_6LOWPAN_ID) {
00101                     if (length != 2) {
00102                         return -1;
00103                     }
00104                 } else if (type == THREAD_NWK_DATA_TYPE_ROUTE) {
00105                     if (length == 0) {
00106                         return -1;
00107                     } else if ((length % 3) != 0) {
00108                         tr_debug("Has Route LengthF: %x", length % 3);
00109                         return -1;
00110                     }
00111                 } else if (type == THREAD_NWK_DATA_TYPE_BORDER_ROUTER) {
00112                     if (length == 0) {
00113                         return -1;
00114                     } else if ((length % 4) != 0) {
00115                         tr_debug("BorderRouter LengthF: %x", length % 4);
00116                         return -1;
00117                     }
00118                 } else {
00119                     tr_debug("TyF: %x", type);
00120                     return -1;
00121                 }
00122                 data_length -= length;
00123                 dptr += length;
00124             } else {
00125                 // buffer is overrun this is malformed.
00126                 tr_debug("l!! %x < %x", data_length, length);
00127                 return -1;
00128             }
00129         } else {
00130             tr_debug("MainLF: %x", data_length);
00131             return -1;
00132         }
00133     }
00134     return 0;
00135 }
00136 
00137 int thread_network_data_malformed_check(uint8_t *network_data_ptr, uint16_t network_data_length)
00138 {
00139     uint8_t *dptr;
00140     uint8_t length;
00141     uint8_t type;
00142     dptr = network_data_ptr;
00143     while (network_data_length) {
00144         if (network_data_length >= 2) {
00145             type  = *dptr++;
00146             length = *dptr++;
00147 
00148             if (length == 0) {
00149                 // 0 is not valid length for TLV
00150                 return -1;
00151             }
00152             network_data_length -= 2;
00153             if (network_data_length >= length) {
00154                 if (type == THREAD_NWK_DATA_TYPE_PREFIX) {
00155                     //Do subTLV Malformed test
00156                     if (thread_network_data_prefix_sub_tlv_malformed_check(dptr, length) != 0) {
00157                         tr_debug("prefixSubMal");
00158                         return -1;
00159                     }
00160                 }
00161                 network_data_length -= length;
00162                 dptr += length;
00163             } else {
00164                 // buffer is overrun this is malformed.
00165                 tr_error("Lenf fail");
00166                 return -1;
00167             }
00168         } else {
00169             return -1;
00170         }
00171     }
00172     return 0;
00173 }
00174 
00175 int thread_network_data_sub_tlv_malformed_check(uint8_t *network_data_ptr, uint8_t network_data_length)
00176 {
00177     uint8_t *dptr;
00178     uint8_t length;
00179 
00180     if (!network_data_ptr) {
00181         return -1;
00182     }
00183 
00184     dptr = network_data_ptr;
00185     while (network_data_length) {
00186         if (network_data_length >= 2) {
00187             dptr++;
00188             length = *dptr++;
00189             network_data_length -= 2;
00190             if (length) {
00191                 if (network_data_length >= length) {
00192                     network_data_length -= length;
00193                     dptr += length;
00194                 } else {
00195                     // buffer is overrun this is malformed.
00196                     tr_error("Sub Tlv Length fail");
00197                     return -1;
00198                 }
00199             }
00200         } else {
00201             return -1;
00202         }
00203     }
00204     return 0;
00205 }
00206 
00207 
00208 uint8_t *thread_nd_commission_data_write_steering_data(uint8_t *ptr, const uint8_t *steeringData, uint8_t length)
00209 {
00210     if (length) {
00211         *ptr++ = THREAD_TLV_STEERING_DATA;
00212         *ptr++ = length;
00213 
00214         memcpy(ptr, steeringData, length);
00215         ptr += length;
00216     }
00217     return ptr;
00218 }
00219 
00220 uint8_t *thread_nd_network_data_border_router_tlv_write(uint8_t *ptr, uint16_t routerId, uint16_t flags)
00221 {
00222     ptr = common_write_16_bit(routerId, ptr);
00223     ptr = common_write_16_bit(flags, ptr);
00224     return ptr;
00225 }
00226 
00227 uint8_t *thread_nd_network_data_has_route_tlv_write(uint8_t *ptr, uint16_t routerId, uint8_t prf)
00228 {
00229     ptr = common_write_16_bit(routerId, ptr);
00230     *ptr++ = prf;
00231     return ptr;
00232 }
00233 
00234 #endif