Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: BSDInterfaceTests HelloBSDInterface
BSDInterface.cpp
00001 /* BSD implementation of NetworkInterfaceAPI 00002 * Copyright (c) 2015 ARM Limited 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 00017 #include "BSDInterface.h" 00018 00019 #include <sys/ioctl.h> 00020 #include <netdb.h> 00021 #include <net/if.h> 00022 #include <unistd.h> 00023 #include <netinet/in.h> 00024 #include <sys/socket.h> 00025 #include <arpa/inet.h> 00026 #include <errno.h> 00027 #include <string.h> 00028 #include <stdio.h> 00029 00030 00031 // BSDInterface implementation 00032 static bool ifctl(struct ifreq *ifr, unsigned req) { 00033 struct ifconf ifc; 00034 char buffer[1024]; 00035 00036 int sock = ::socket(AF_INET, SOCK_DGRAM, 0); 00037 if (sock < 0) { 00038 return 0; 00039 } 00040 00041 ifc.ifc_buf = buffer; 00042 ifc.ifc_len = sizeof buffer; 00043 if (ioctl(sock, SIOCGIFCONF, &ifc) < 0) { 00044 ::close(sock); 00045 return false; 00046 } 00047 00048 for (int i = 0; i < ifc.ifc_len; i++) { 00049 strcpy(ifr->ifr_name, ifc.ifc_req[i].ifr_name); 00050 00051 if (ioctl(sock, SIOCGIFFLAGS, ifr) == 0 00052 && !(ifr->ifr_flags & IFF_LOOPBACK) 00053 && ioctl(sock, req, ifr) == 0) { 00054 ::close(sock); 00055 return true; 00056 } 00057 } 00058 00059 ::close(sock); 00060 return false; 00061 } 00062 00063 const char *BSDInterface::getIPAddress() 00064 { 00065 static char ip_address[NS_IP_SIZE] = "\0"; 00066 if (ip_address[0]) { 00067 return ip_address; 00068 } 00069 00070 struct ifreq ifr; 00071 if (!ifctl(&ifr, SIOCGIFADDR)) { 00072 return 0; 00073 } 00074 00075 struct in_addr addr = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr; 00076 strcpy(ip_address, inet_ntoa(addr)); 00077 return ip_address; 00078 } 00079 00080 const char *BSDInterface::getMACAddress() 00081 { 00082 static char mac_address[NS_MAC_SIZE] = "\0"; 00083 if (mac_address[0]) { 00084 return mac_address; 00085 } 00086 00087 struct ifreq ifr; 00088 if (!ifctl(&ifr, SIOCGIFHWADDR)) { 00089 return 0; 00090 } 00091 00092 sprintf(mac_address, "%02x:%02x:%02x:%02x:%02x:%02x", 00093 (unsigned char)ifr.ifr_hwaddr.sa_data[0], 00094 (unsigned char)ifr.ifr_hwaddr.sa_data[1], 00095 (unsigned char)ifr.ifr_hwaddr.sa_data[2], 00096 (unsigned char)ifr.ifr_hwaddr.sa_data[3], 00097 (unsigned char)ifr.ifr_hwaddr.sa_data[4], 00098 (unsigned char)ifr.ifr_hwaddr.sa_data[5]); 00099 return mac_address; 00100 } 00101 00102 int32_t BSDInterface::getHostByName(const char *name, char *ip) 00103 { 00104 struct hostent *host = gethostbyname(name); 00105 if (!host || host->h_addrtype != AF_INET) { 00106 return NS_ERROR_DNS_FAILURE; 00107 } 00108 00109 strcpy(ip, inet_ntoa(*(struct in_addr *)host->h_addr)); 00110 return 0; 00111 } 00112 00113 SocketInterface *BSDInterface::createSocket(ns_protocol_t proto) 00114 { 00115 int type = (proto == NS_UDP) ? SOCK_DGRAM : SOCK_STREAM; 00116 int fd = ::socket(AF_INET, type, 0); 00117 if (fd < 0) { 00118 return 0; 00119 } 00120 00121 return new BSDSocket(fd); 00122 } 00123 00124 void BSDInterface::destroySocket(SocketInterface *socket) 00125 { 00126 ::close(((BSDSocket*)socket)->fd); 00127 delete socket; 00128 } 00129 00130 00131 // BSDSocket implementation 00132 int32_t BSDInterface::BSDSocket::open(const char *ip, uint16_t port) 00133 { 00134 struct sockaddr_in host; 00135 memset(&host, 0, sizeof host); 00136 host.sin_family = AF_INET; 00137 host.sin_port = htons(port); 00138 inet_pton(AF_INET, ip, &host.sin_addr); 00139 00140 if (::connect(fd, (struct sockaddr *)&host, sizeof host) < 0) { 00141 return NS_ERROR_NO_CONNECTION; 00142 } 00143 00144 return 0; 00145 } 00146 00147 int32_t BSDInterface::BSDSocket::close() 00148 { 00149 return 0; 00150 } 00151 00152 int32_t BSDInterface::BSDSocket::send(const void *data, uint32_t size) 00153 { 00154 if (::send(fd, data, size, 0) < 0) { 00155 return NS_ERROR_DEVICE_ERROR; 00156 } 00157 00158 return size; 00159 } 00160 00161 int32_t BSDInterface::BSDSocket::recv(void *data, uint32_t size) 00162 { 00163 int ret = ::recv(fd, data, size, MSG_DONTWAIT); 00164 00165 if (ret > 0) { 00166 return ret; 00167 } else if (errno == EAGAIN) { 00168 return NS_ERROR_WOULD_BLOCK; 00169 } else { 00170 return NS_ERROR_DEVICE_ERROR; 00171 } 00172 } 00173 00174
Generated on Fri Jul 15 2022 09:14:49 by
1.7.2