From bac3da61644515f05663789b122554dc77549286 Mon Sep 17 00:00:00 2001 From: Luca Muscariello Date: Thu, 17 Jan 2019 13:47:57 +0100 Subject: This is the first commit of the hicn project Change-Id: I6f2544ad9b9f8891c88cc4bcce3cf19bd3cc863f Signed-off-by: Luca Muscariello --- hicn-light/src/platforms/CMakeLists.txt | 31 +++++ hicn-light/src/platforms/README.txt | 17 +++ hicn-light/src/platforms/android/system.c | 183 +++++++++++++++++++++++++++++ hicn-light/src/platforms/darwin/system.c | 146 ++++++++++++++++++++++++ hicn-light/src/platforms/linux/system.c | 184 ++++++++++++++++++++++++++++++ 5 files changed, 561 insertions(+) create mode 100755 hicn-light/src/platforms/CMakeLists.txt create mode 100755 hicn-light/src/platforms/README.txt create mode 100755 hicn-light/src/platforms/android/system.c create mode 100755 hicn-light/src/platforms/darwin/system.c create mode 100755 hicn-light/src/platforms/linux/system.c (limited to 'hicn-light/src/platforms') diff --git a/hicn-light/src/platforms/CMakeLists.txt b/hicn-light/src/platforms/CMakeLists.txt new file mode 100755 index 000000000..fcb4282ba --- /dev/null +++ b/hicn-light/src/platforms/CMakeLists.txt @@ -0,0 +1,31 @@ +# Copyright (c) 2017-2019 Cisco and/or its affiliates. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at: +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +cmake_minimum_required(VERSION 3.5 FATAL_ERROR) + +if(${CMAKE_SYSTEM_NAME} STREQUAL "Android") + list(APPEND SOURCE_FILES + ${CMAKE_CURRENT_SOURCE_DIR}/android/system.c + ) +elseif(APPLE) + list(APPEND SOURCE_FILES + ${CMAKE_CURRENT_SOURCE_DIR}/darwin/system.c + ) +elseif( ${CMAKE_SYSTEM_NAME} STREQUAL "Linux" ) + list(APPEND SOURCE_FILES + ${CMAKE_CURRENT_SOURCE_DIR}/linux/system.c + ) +endif() + +set(SOURCE_FILES ${SOURCE_FILES} PARENT_SCOPE) +set(HEADER_FILES ${HEADER_FILES} PARENT_SCOPE) \ No newline at end of file diff --git a/hicn-light/src/platforms/README.txt b/hicn-light/src/platforms/README.txt new file mode 100755 index 000000000..a1293944c --- /dev/null +++ b/hicn-light/src/platforms/README.txt @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2017-2019 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +Operating system dependent modules. + diff --git a/hicn-light/src/platforms/android/system.c b/hicn-light/src/platforms/android/system.c new file mode 100755 index 000000000..68f99424b --- /dev/null +++ b/hicn-light/src/platforms/android/system.c @@ -0,0 +1,183 @@ +/* + * Copyright (c) 2017-2019 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +//#define __USE_MISC +#include + +// to get the list of arp types +#include + +// for the mac address +#include + +#include +#include + +#include + +#include "ifaddrs.h" + +/** + * Returns the MTU for a named interface + * + * On linux, we get the MTU by opening a socket and reading SIOCGIFMTU + * + * @param [in] ifname Interface name (e.g. "eth0") + * + * @retval number The MTU in bytes + * + * Example: + * @code + * <#example#> + * @endcode + */ +static int getMtu(const char *ifname) { + struct ifreq ifr; + int fd; + + fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP); + + strcpy(ifr.ifr_name, ifname); + ioctl(fd, SIOCGIFMTU, &ifr); + + close(fd); + return ifr.ifr_mtu; +} + +InterfaceSet *system_Interfaces(Forwarder *forwarder) { + InterfaceSet *set = interfaceSetCreate(); + + Logger *logger = forwarder_GetLogger(forwarder); + + // this is the dynamically allocated head of the list + struct ifaddrs *ifaddr; + int failure = getifaddrs(&ifaddr); + parcAssertFalse(failure, "Error getifaddrs: (%d) %s", errno, strerror(errno)); + + struct ifaddrs *next; + for (next = ifaddr; next != NULL; next = next->ifa_next) { + if ((next->ifa_addr == NULL) || ((next->ifa_flags & IFF_UP) == 0)) { + continue; + } + + Interface *iface = interfaceSetGetByName(set, next->ifa_name); + if (iface == NULL) { + unsigned mtu = (unsigned)getMtu(next->ifa_name); + + iface = interfaceCreate( + next->ifa_name, forwarder_GetNextConnectionId(forwarder), + next->ifa_flags & IFF_LOOPBACK, next->ifa_flags & IFF_MULTICAST, mtu); + + interfaceSetAdd(set, iface); + } + + int family = next->ifa_addr->sa_family; + switch (family) { + case AF_INET: { + Address *address = + addressCreateFromInet((struct sockaddr_in *)next->ifa_addr); + interfaceAddAddress(iface, address); + break; + } + + case AF_INET6: { + Address *address = + addressCreateFromInet6((struct sockaddr_in6 *)next->ifa_addr); + interfaceAddAddress(iface, address); + break; + } + + case AF_PACKET: { + struct sockaddr_ll *addr_ll = (struct sockaddr_ll *)next->ifa_addr; + + if (logger_IsLoggable(logger, LoggerFacility_IO, PARCLogLevel_Debug)) { + logger_Log(logger, LoggerFacility_IO, PARCLogLevel_Debug, __func__, + "sockaddr_ll family %d proto %d ifindex %d hatype %d " + "pkttype %d halen %d", + addr_ll->sll_family, addr_ll->sll_protocol, + addr_ll->sll_ifindex, addr_ll->sll_hatype, + addr_ll->sll_pkttype, addr_ll->sll_halen); + } + + switch (addr_ll->sll_hatype) { + // list of the ARP hatypes we can extract a MAC address from + case ARPHRD_ETHER: + // fallthrough + case ARPHRD_IEEE802: { + Address *address = addressCreateFromLink( + (uint8_t *)addr_ll->sll_addr, addr_ll->sll_halen); + interfaceAddAddress(iface, address); + break; + } + default: + break; + } + + break; + } + } + } + + freeifaddrs(ifaddr); + return set; +} + +Address *system_GetMacAddressByName(Forwarder *forwarder, + const char *interfaceName) { + Address *linkAddress = NULL; + + InterfaceSet *interfaceSet = system_Interfaces(forwarder); + Interface *interface = interfaceSetGetByName(interfaceSet, interfaceName); + + if (interface) { + const AddressList *addressList = interfaceGetAddresses(interface); + + size_t length = addressListLength(addressList); + for (size_t i = 0; i < length && !linkAddress; i++) { + const Address *a = addressListGetItem(addressList, i); + if (addressGetType(a) == ADDR_LINK) { + linkAddress = addressCopy(a); + } + } + } + + interfaceSetDestroy(&interfaceSet); + + return linkAddress; +} + +unsigned system_InterfaceMtu(Forwarder *forwarder, const char *interfaceName) { + unsigned mtu = 0; + + InterfaceSet *interfaceSet = system_Interfaces(forwarder); + Interface *interface = interfaceSetGetByName(interfaceSet, interfaceName); + + if (interface) { + mtu = interfaceGetMTU(interface); + } + + interfaceSetDestroy(&interfaceSet); + + return mtu; +} diff --git a/hicn-light/src/platforms/darwin/system.c b/hicn-light/src/platforms/darwin/system.c new file mode 100755 index 000000000..b8ef80c63 --- /dev/null +++ b/hicn-light/src/platforms/darwin/system.c @@ -0,0 +1,146 @@ +/* + * Copyright (c) 2017-2019 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include + +#include +#include + +InterfaceSet *system_Interfaces(Forwarder *forwarder) { + InterfaceSet *set = interfaceSetCreate(); + + // this is the dynamically allocated head of the list + struct ifaddrs *ifaddr; + int failure = getifaddrs(&ifaddr); + parcAssertFalse(failure, "Error getifaddrs: (%d) %s", errno, strerror(errno)); + + struct ifaddrs *next; + for (next = ifaddr; next != NULL; next = next->ifa_next) { + if ((next->ifa_addr == NULL) || ((next->ifa_flags & IFF_UP) == 0)) { + continue; + } + + // This assumes the LINK address comes first so we can get the MTU + // when the interface is created. + + Interface *iface = interfaceSetGetByName(set, next->ifa_name); + if (iface == NULL) { + unsigned mtu = 0; + + if (next->ifa_data != NULL) { + struct if_data *ifdata = (struct if_data *)next->ifa_data; + mtu = ifdata->ifi_mtu; + } + + iface = interfaceCreate( + next->ifa_name, forwarder_GetNextConnectionId(forwarder), + next->ifa_flags & IFF_LOOPBACK, next->ifa_flags & IFF_MULTICAST, mtu); + + interfaceSetAdd(set, iface); + } + + int family = next->ifa_addr->sa_family; + switch (family) { + case AF_INET: { + Address *address = + addressCreateFromInet((struct sockaddr_in *)next->ifa_addr); + interfaceAddAddress(iface, address); + break; + } + + case AF_INET6: { + Address *address = + addressCreateFromInet6((struct sockaddr_in6 *)next->ifa_addr); + interfaceAddAddress(iface, address); + break; + } + + case AF_LINK: { + struct sockaddr_dl *addr_dl = (struct sockaddr_dl *)next->ifa_addr; + + // skip links with 0-length address + if (addr_dl->sdl_alen > 0) { + // addr_dl->sdl_data[12] contains the interface name followed by the + // MAC address, so need to offset in to the array past the interface + // name. + Address *address = addressCreateFromLink( + (uint8_t *)&addr_dl->sdl_data[addr_dl->sdl_nlen], + addr_dl->sdl_alen); + interfaceAddAddress(iface, address); + } + break; + } + } + } + + freeifaddrs(ifaddr); + + return set; +} + +Address *system_GetMacAddressByName(Forwarder *forwarder, + const char *interfaceName) { + Address *linkAddress = NULL; + + InterfaceSet *interfaceSet = system_Interfaces(forwarder); + Interface *interface = interfaceSetGetByName(interfaceSet, interfaceName); + + if (interface) { + const AddressList *addressList = interfaceGetAddresses(interface); + + size_t length = addressListLength(addressList); + for (size_t i = 0; i < length && !linkAddress; i++) { + const Address *a = addressListGetItem(addressList, i); + if (addressGetType(a) == ADDR_LINK) { + linkAddress = addressCopy(a); + } + } + } + + interfaceSetDestroy(&interfaceSet); + + return linkAddress; +} + +unsigned system_InterfaceMtu(Forwarder *forwarder, const char *interfaceName) { + unsigned mtu = 0; + + if (interfaceName) { + InterfaceSet *interfaceSet = system_Interfaces(forwarder); + Interface *interface = interfaceSetGetByName(interfaceSet, interfaceName); + + if (interface) { + mtu = interfaceGetMTU(interface); + } + + interfaceSetDestroy(&interfaceSet); + } + return mtu; +} diff --git a/hicn-light/src/platforms/linux/system.c b/hicn-light/src/platforms/linux/system.c new file mode 100755 index 000000000..fcf13becc --- /dev/null +++ b/hicn-light/src/platforms/linux/system.c @@ -0,0 +1,184 @@ +/* + * Copyright (c) 2017-2019 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//#define __USE_MISC +#include + +// to get the list of arp types +#include + +// for the mac address +#include + +#include +#include + +#include + +#include + +/** + * Returns the MTU for a named interface + * + * On linux, we get the MTU by opening a socket and reading SIOCGIFMTU + * + * @param [in] ifname Interface name (e.g. "eth0") + * + * @retval number The MTU in bytes + * + * Example: + * @code + * <#example#> + * @endcode + */ +static int getMtu(const char *ifname) { + struct ifreq ifr; + int fd; + + fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP); + + strcpy(ifr.ifr_name, ifname); + ioctl(fd, SIOCGIFMTU, &ifr); + + close(fd); + return ifr.ifr_mtu; +} + +InterfaceSet *system_Interfaces(Forwarder *forwarder) { + InterfaceSet *set = interfaceSetCreate(); + + Logger *logger = forwarder_GetLogger(forwarder); + + // this is the dynamically allocated head of the list + struct ifaddrs *ifaddr; + int failure = getifaddrs(&ifaddr); + parcAssertFalse(failure, "Error getifaddrs: (%d) %s", errno, strerror(errno)); + + struct ifaddrs *next; + for (next = ifaddr; next != NULL; next = next->ifa_next) { + if ((next->ifa_addr == NULL) || ((next->ifa_flags & IFF_UP) == 0)) { + continue; + } + + Interface *iface = interfaceSetGetByName(set, next->ifa_name); + if (iface == NULL) { + unsigned mtu = (unsigned)getMtu(next->ifa_name); + + iface = interfaceCreate( + next->ifa_name, forwarder_GetNextConnectionId(forwarder), + next->ifa_flags & IFF_LOOPBACK, next->ifa_flags & IFF_MULTICAST, mtu); + + interfaceSetAdd(set, iface); + } + + int family = next->ifa_addr->sa_family; + switch (family) { + case AF_INET: { + Address *address = + addressCreateFromInet((struct sockaddr_in *)next->ifa_addr); + interfaceAddAddress(iface, address); + break; + } + + case AF_INET6: { + Address *address = + addressCreateFromInet6((struct sockaddr_in6 *)next->ifa_addr); + interfaceAddAddress(iface, address); + break; + } + + case AF_PACKET: { + struct sockaddr_ll *addr_ll = (struct sockaddr_ll *)next->ifa_addr; + + if (logger_IsLoggable(logger, LoggerFacility_IO, PARCLogLevel_Debug)) { + logger_Log(logger, LoggerFacility_IO, PARCLogLevel_Debug, __func__, + "sockaddr_ll family %d proto %d ifindex %d hatype %d " + "pkttype %d halen %d", + addr_ll->sll_family, addr_ll->sll_protocol, + addr_ll->sll_ifindex, addr_ll->sll_hatype, + addr_ll->sll_pkttype, addr_ll->sll_halen); + } + + switch (addr_ll->sll_hatype) { + // list of the ARP hatypes we can extract a MAC address from + case ARPHRD_ETHER: + // fallthrough + case ARPHRD_IEEE802: { + Address *address = addressCreateFromLink( + (uint8_t *)addr_ll->sll_addr, addr_ll->sll_halen); + interfaceAddAddress(iface, address); + break; + } + default: + break; + } + + break; + } + } + } + + freeifaddrs(ifaddr); + return set; +} + +Address *system_GetMacAddressByName(Forwarder *forwarder, + const char *interfaceName) { + Address *linkAddress = NULL; + + InterfaceSet *interfaceSet = system_Interfaces(forwarder); + Interface *interface = interfaceSetGetByName(interfaceSet, interfaceName); + + if (interface) { + const AddressList *addressList = interfaceGetAddresses(interface); + + size_t length = addressListLength(addressList); + for (size_t i = 0; i < length && !linkAddress; i++) { + const Address *a = addressListGetItem(addressList, i); + if (addressGetType(a) == ADDR_LINK) { + linkAddress = addressCopy(a); + } + } + } + + interfaceSetDestroy(&interfaceSet); + + return linkAddress; +} + +unsigned system_InterfaceMtu(Forwarder *forwarder, const char *interfaceName) { + unsigned mtu = 0; + + InterfaceSet *interfaceSet = system_Interfaces(forwarder); + Interface *interface = interfaceSetGetByName(interfaceSet, interfaceName); + + if (interface) { + mtu = interfaceGetMTU(interface); + } + + interfaceSetDestroy(&interfaceSet); + + return mtu; +} -- cgit 1.2.3-korg