From c580a00aac271a524e5a75b35f4b91c174ed227b Mon Sep 17 00:00:00 2001 From: michele papalini Date: Thu, 23 Feb 2017 17:01:34 +0100 Subject: Initial commit: sb-forwarder, metis. Change-Id: I65ee3c851a6901929ef4417ad80d34bca0dce445 Signed-off-by: michele papalini --- .../forwarder/metis/platforms/linux/metis_System.c | 190 +++++++++++++++++++++ 1 file changed, 190 insertions(+) create mode 100644 metis/ccnx/forwarder/metis/platforms/linux/metis_System.c (limited to 'metis/ccnx/forwarder/metis/platforms/linux/metis_System.c') diff --git a/metis/ccnx/forwarder/metis/platforms/linux/metis_System.c b/metis/ccnx/forwarder/metis/platforms/linux/metis_System.c new file mode 100644 index 00000000..828566d8 --- /dev/null +++ b/metis/ccnx/forwarder/metis/platforms/linux/metis_System.c @@ -0,0 +1,190 @@ +/* + * Copyright (c) 2017 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 + +/** + * 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; +} + +CPIInterfaceSet * +metisSystem_Interfaces(MetisForwarder *metis) +{ + CPIInterfaceSet *set = cpiInterfaceSet_Create(); + + MetisLogger *logger = metisForwarder_GetLogger(metis); + + // this is the dynamically allocated head of the list + struct ifaddrs *ifaddr; + int failure = getifaddrs(&ifaddr); + assertFalse(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; + } + + CPIInterface *iface = cpiInterfaceSet_GetByName(set, next->ifa_name); + if (iface == NULL) { + unsigned mtu = (unsigned) getMtu(next->ifa_name); + + iface = cpiInterface_Create(next->ifa_name, + metisForwarder_GetNextConnectionId(metis), + next->ifa_flags & IFF_LOOPBACK, + next->ifa_flags & IFF_MULTICAST, + mtu); + + cpiInterfaceSet_Add(set, iface); + } + + int family = next->ifa_addr->sa_family; + switch (family) { + case AF_INET: { + CPIAddress *address = cpiAddress_CreateFromInet((struct sockaddr_in *) next->ifa_addr); + cpiInterface_AddAddress(iface, address); + break; + } + + case AF_INET6: { + CPIAddress *address = cpiAddress_CreateFromInet6((struct sockaddr_in6 *) next->ifa_addr); + cpiInterface_AddAddress(iface, address); + break; + } + + case AF_PACKET: { + struct sockaddr_ll *addr_ll = (struct sockaddr_ll *) next->ifa_addr; + + if (metisLogger_IsLoggable(logger, MetisLoggerFacility_IO, PARCLogLevel_Debug)) { + metisLogger_Log(logger, MetisLoggerFacility_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: { + CPIAddress *address = cpiAddress_CreateFromLink((uint8_t *) addr_ll->sll_addr, addr_ll->sll_halen); + cpiInterface_AddAddress(iface, address); + break; + } + default: + break; + } + + break; + } + } + } + + freeifaddrs(ifaddr); + return set; +} + +CPIAddress * +metisSystem_GetMacAddressByName(MetisForwarder *metis, const char *interfaceName) +{ + CPIAddress *linkAddress = NULL; + + CPIInterfaceSet *interfaceSet = metisSystem_Interfaces(metis); + CPIInterface *interface = cpiInterfaceSet_GetByName(interfaceSet, interfaceName); + + if (interface) { + const CPIAddressList *addressList = cpiInterface_GetAddresses(interface); + + size_t length = cpiAddressList_Length(addressList); + for (size_t i = 0; i < length && !linkAddress; i++) { + const CPIAddress *a = cpiAddressList_GetItem(addressList, i); + if (cpiAddress_GetType(a) == cpiAddressType_LINK) { + linkAddress = cpiAddress_Copy(a); + } + } + } + + cpiInterfaceSet_Destroy(&interfaceSet); + + return linkAddress; +} + +unsigned +metisSystem_InterfaceMtu(MetisForwarder *metis, const char *interfaceName) +{ + unsigned mtu = 0; + + CPIInterfaceSet *interfaceSet = metisSystem_Interfaces(metis); + CPIInterface *interface = cpiInterfaceSet_GetByName(interfaceSet, interfaceName); + + if (interface) { + mtu = cpiInterface_GetMTU(interface); + } + + cpiInterfaceSet_Destroy(&interfaceSet); + + return mtu; +} -- cgit 1.2.3-korg