Kenji Arai / mbed-os_TYBLE16

Dependents:   TYBLE16_simple_data_logger TYBLE16_MP3_Air

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers ws_eapol_relay.c Source File

ws_eapol_relay.c

00001 /*
00002  * Copyright (c) 2018-2019, 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 #include <string.h>
00020 #include "ns_types.h"
00021 #include "ns_list.h"
00022 #include "ns_trace.h"
00023 #include "nsdynmemLIB.h"
00024 #include "fhss_config.h "
00025 #include "NWK_INTERFACE/Include/protocol.h"
00026 #include "mac_api.h"
00027 #include "mac_mcps.h"
00028 #include "Common_Protocols/ipv6_constants.h"
00029 #include "socket_api.h"
00030 #include "6LoWPAN/MAC/mac_helper.h"
00031 #include "6LoWPAN/MAC/mpx_api.h"
00032 #include "6LoWPAN/ws/ws_config.h"
00033 #include "6LoWPAN/ws/ws_eapol_pdu.h"
00034 #include "6LoWPAN/ws/ws_eapol_relay_lib.h"
00035 #include "6LoWPAN/ws/ws_eapol_relay.h"
00036 
00037 #ifdef HAVE_WS
00038 #ifdef HAVE_EAPOL_RELAY
00039 
00040 #define TRACE_GROUP "wser"
00041 
00042 typedef struct {
00043     protocol_interface_info_entry_t *interface_ptr;         /**< Interface pointer */
00044     ns_address_t remote_addr;                               /**< Remote address (border router address) */
00045     int8_t socket_id;                                       /**< Socket ID for relay */
00046     ns_list_link_t link;                                    /**< Link */
00047 } eapol_relay_t;
00048 
00049 static eapol_relay_t *ws_eapol_relay_get(protocol_interface_info_entry_t *interface_ptr);
00050 static int8_t ws_eapol_relay_eapol_pdu_address_check(protocol_interface_info_entry_t *interface_ptr, const uint8_t *eui_64);
00051 static int8_t ws_eapol_relay_eapol_pdu_receive(protocol_interface_info_entry_t *interface_ptr, const uint8_t *eui_64, void *pdu, uint16_t size);
00052 static void ws_eapol_relay_socket_cb(void *cb);
00053 
00054 static const eapol_pdu_recv_cb_data_t eapol_pdu_recv_cb_data = {
00055     .priority = EAPOL_PDU_RECV_LOW_PRIORITY,
00056     .addr_check = ws_eapol_relay_eapol_pdu_address_check,
00057     .receive = ws_eapol_relay_eapol_pdu_receive
00058 };
00059 
00060 static NS_LIST_DEFINE(eapol_relay_list, eapol_relay_t, link);
00061 
00062 int8_t ws_eapol_relay_start(protocol_interface_info_entry_t *interface_ptr, uint16_t local_port, const uint8_t *remote_addr, uint16_t remote_port)
00063 {
00064     if (!interface_ptr || !remote_addr) {
00065         return -1;
00066     }
00067 
00068     if (ws_eapol_relay_get(interface_ptr)) {
00069         return 0;
00070     }
00071 
00072     eapol_relay_t *eapol_relay = ns_dyn_mem_alloc(sizeof(eapol_relay_t));
00073     if (!eapol_relay) {
00074         return -1;
00075     }
00076 
00077     eapol_relay->interface_ptr = interface_ptr;
00078 
00079     eapol_relay->remote_addr.type = ADDRESS_IPV6;
00080     memcpy(&eapol_relay->remote_addr.address, remote_addr, 16);
00081     eapol_relay->remote_addr.identifier = remote_port;
00082 
00083     eapol_relay->socket_id = socket_open(IPV6_NH_UDP, local_port, &ws_eapol_relay_socket_cb);
00084     if (eapol_relay->socket_id < 0) {
00085         ns_dyn_mem_free(eapol_relay);
00086         return -1;
00087     }
00088 
00089     if (ws_eapol_pdu_cb_register(interface_ptr, &eapol_pdu_recv_cb_data) < 0) {
00090         ns_dyn_mem_free(eapol_relay);
00091         return -1;
00092     }
00093 
00094     ns_list_add_to_end(&eapol_relay_list, eapol_relay);
00095 
00096     return 0;
00097 }
00098 
00099 int8_t ws_eapol_relay_delete(protocol_interface_info_entry_t *interface_ptr)
00100 {
00101     if (!interface_ptr) {
00102         return -1;
00103     }
00104 
00105     eapol_relay_t *eapol_relay = ws_eapol_relay_get(interface_ptr);
00106     if (!eapol_relay) {
00107         return -1;
00108     }
00109 
00110     socket_close(eapol_relay->socket_id);
00111 
00112     ws_eapol_pdu_cb_unregister(interface_ptr, &eapol_pdu_recv_cb_data);
00113 
00114     ns_list_remove(&eapol_relay_list, eapol_relay);
00115     ns_dyn_mem_free(eapol_relay);
00116 
00117     return 0;
00118 }
00119 
00120 static eapol_relay_t *ws_eapol_relay_get(protocol_interface_info_entry_t *interface_ptr)
00121 {
00122     ns_list_foreach(eapol_relay_t, entry, &eapol_relay_list) {
00123         if (entry->interface_ptr == interface_ptr) {
00124             return entry;
00125         }
00126     }
00127 
00128     return NULL;
00129 }
00130 
00131 static int8_t ws_eapol_relay_eapol_pdu_address_check(protocol_interface_info_entry_t *interface_ptr, const uint8_t *eui_64)
00132 {
00133     (void) eui_64;
00134     (void) interface_ptr;
00135 
00136     // Low priority, always route all here if asked
00137     return 0;
00138 }
00139 
00140 static int8_t ws_eapol_relay_eapol_pdu_receive(protocol_interface_info_entry_t *interface_ptr, const uint8_t *eui_64, void *pdu, uint16_t size)
00141 {
00142     eapol_relay_t *eapol_relay = ws_eapol_relay_get(interface_ptr);
00143     if (!eapol_relay) {
00144         return -1;
00145     }
00146 
00147     ws_eapol_relay_lib_send_to_relay(eapol_relay->socket_id, eui_64, &eapol_relay->remote_addr, pdu, size);
00148 
00149     return 0;
00150 }
00151 
00152 static void ws_eapol_relay_socket_cb(void *cb)
00153 {
00154     socket_callback_t *cb_data = cb;
00155 
00156     if (cb_data->event_type != SOCKET_DATA) {
00157         return;
00158     }
00159 
00160     eapol_relay_t *eapol_relay = NULL;
00161 
00162     ns_list_foreach(eapol_relay_t, entry, &eapol_relay_list) {
00163         if (entry->socket_id == cb_data->socket_id) {
00164             eapol_relay = entry;
00165             break;
00166         }
00167     }
00168 
00169     if (!eapol_relay) {
00170         return;
00171     }
00172 
00173     uint8_t *socket_pdu = ns_dyn_mem_temporary_alloc(cb_data->d_len);
00174     if (!socket_pdu) {
00175         return;
00176     }
00177 
00178     ns_address_t src_addr;
00179 
00180     if (socket_recvfrom(cb_data->socket_id, socket_pdu, cb_data->d_len, 0, &src_addr) != cb_data->d_len) {
00181         ns_dyn_mem_free(socket_pdu);
00182         return;
00183     }
00184 
00185     //First 8 byte is EUID64 and rsr payload
00186     if (ws_eapol_pdu_send_to_mpx(eapol_relay->interface_ptr, socket_pdu, socket_pdu + 8, cb_data->d_len - 8, socket_pdu, NULL, 0) < 0) {
00187         ns_dyn_mem_free(socket_pdu);
00188     }
00189 }
00190 
00191 #endif /* HAVE_EAPOL_RELAY */
00192 #endif /* HAVE_WS */
00193