Add toolchain and mbtk source
Change-Id: Ie12546301367ea59240bf23d5e184ad7e36e40b3
diff --git a/mbtk/mbtk_lib/src/mbtk_ifc.c b/mbtk/mbtk_lib/src/mbtk_ifc.c
new file mode 100755
index 0000000..51267f5
--- /dev/null
+++ b/mbtk/mbtk_lib/src/mbtk_ifc.c
@@ -0,0 +1,577 @@
+/*
+* MBTK Network Interface control.
+*
+* Author : lb
+* Date : 2021/8/20 11:44:05
+*
+*/
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+//#include <net/if.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <linux/if_ether.h>
+#include <linux/sockios.h>
+//#include <cutils/properties.h>
+#include <arpa/inet.h>
+#include <pthread.h>
+#include <linux/route.h>
+#include <sys/ioctl.h>
+#include <unistd.h>
+
+#include "mbtk_type.h"
+#include "mbtk_log.h"
+#include "mbtk_utils.h"
+#include "mbtk_ifc.h"
+
+#define IFNAMSIZ 16
+
+static int ifc_ctl_sock = -1;
+static pthread_mutex_t ifc_sock_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+static void ifc_init_ifr(const char *name, struct ifreq *ifr)
+{
+ memset(ifr, 0, sizeof(struct ifreq));
+ strncpy(ifr->ifr_name, name, IFNAMSIZ);
+ ifr->ifr_name[IFNAMSIZ - 1] = 0;
+}
+
+static int ifc_set_flags(int sock, const char *name, unsigned set, unsigned clr)
+{
+ struct ifreq ifr;
+ ifc_init_ifr(name, &ifr);
+
+ if(ioctl(sock, SIOCGIFFLAGS, &ifr) < 0)
+ return -1;
+ ifr.ifr_flags = (ifr.ifr_flags & (~clr)) | set;
+ return ioctl(sock, SIOCSIFFLAGS, &ifr);
+}
+
+static void init_sockaddr_in(struct sockaddr *sa, in_addr_t addr)
+{
+ struct sockaddr_in *sin = (struct sockaddr_in *) sa;
+ sin->sin_family = AF_INET;
+ sin->sin_port = 0;
+ sin->sin_addr.s_addr = addr;
+}
+
+#if 1
+static const char *ipaddr_to_string(in_addr_t addr)
+{
+ struct in_addr in_addr;
+
+ in_addr.s_addr = addr;
+ return inet_ntoa(in_addr);
+}
+#endif
+
+static in_addr_t prefixLengthToIpv4Netmask(int prefix_length)
+{
+ in_addr_t mask = 0;
+
+ // C99 (6.5.7): shifts of 32 bits have undefined results
+ if (prefix_length <= 0 || prefix_length > 32)
+ {
+ return 0;
+ }
+
+ mask = ~mask << (32 - prefix_length);
+ mask = htonl(mask);
+
+ return mask;
+}
+
+#if 1
+static int ifc_set_prefixLength(const char *name, int prefixLength)
+{
+ struct ifreq ifr;
+ // TODO - support ipv6
+// if (prefixLength > 32 || prefixLength < 0) return -1;
+
+ in_addr_t mask = prefixLengthToIpv4Netmask(prefixLength);
+ ifc_init_ifr(name, &ifr);
+ init_sockaddr_in(&ifr.ifr_addr, mask);
+
+ return ioctl(ifc_ctl_sock, SIOCSIFNETMASK, &ifr);
+}
+#endif
+
+int ifc_act_on_ipv4_route(int action, const char *ifname, struct in_addr dst, int prefix_length,
+ struct in_addr gw)
+{
+ struct rtentry rt;
+ int result;
+ in_addr_t netmask;
+
+ memset(&rt, 0, sizeof(rt));
+
+ rt.rt_dst.sa_family = AF_INET;
+ rt.rt_dev = (void*) ifname;
+
+ netmask = prefixLengthToIpv4Netmask(prefix_length);
+ init_sockaddr_in(&rt.rt_genmask, netmask);
+ init_sockaddr_in(&rt.rt_dst, dst.s_addr);
+ rt.rt_flags = RTF_UP;
+
+ if (prefix_length == 32)
+ {
+ rt.rt_flags |= RTF_HOST;
+ }
+
+ if (gw.s_addr != 0)
+ {
+ rt.rt_flags |= RTF_GATEWAY;
+ init_sockaddr_in(&rt.rt_gateway, gw.s_addr);
+ }
+
+ result = ioctl(ifc_ctl_sock, action, &rt);
+ if (result < 0)
+ {
+ if (errno == EEXIST)
+ {
+ result = 0;
+ }
+ else
+ {
+ result = -errno;
+ }
+ }
+ return result;
+}
+
+static int ifc_create_default_route1(const char *name, in_addr_t gw)
+{
+ struct in_addr in_dst, in_gw;
+
+ in_dst.s_addr = 0;
+ in_gw.s_addr = gw;
+
+ int ret = ifc_act_on_ipv4_route(SIOCADDRT, name, in_dst, 0, in_gw);
+ LOGD("ifc_create_default_route(%s, %d) = %d", name, gw, ret);
+ return ret;
+}
+
+/* deprecated - v4 only */
+static int ifc_create_default_route2(const char *name, const char *gw)
+{
+ struct in_addr in_dst, in_gw;
+
+ in_dst.s_addr = 0;
+ if(gw == NULL)
+ {
+ in_gw.s_addr = 0;
+ }
+ else
+ {
+ if(inet_aton(gw,(struct in_addr *)&(in_gw.s_addr)) < 0)
+ {
+ LOGE("inet_aton error.");
+ return -1;
+ }
+ }
+
+ int ret = ifc_act_on_ipv4_route(SIOCADDRT, name, in_dst, 0, in_gw);
+ LOGD("ifc_create_default_route(%s) = %d", name, ret);
+ return ret;
+}
+
+int mbtk_ifc_open(void)
+{
+ pthread_mutex_lock(&ifc_sock_mutex);
+ if (ifc_ctl_sock == -1)
+ {
+ ifc_ctl_sock = socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
+ if (ifc_ctl_sock < 0)
+ {
+ LOGE("socket() failed: %s\n", strerror(errno));
+ }
+ }
+
+ return ifc_ctl_sock < 0 ? -1 : 0;
+}
+
+int mbtk_ifc_close(void)
+{
+ if (ifc_ctl_sock != -1)
+ {
+ (void)close(ifc_ctl_sock);
+ ifc_ctl_sock = -1;
+ }
+ pthread_mutex_unlock(&ifc_sock_mutex);
+
+ return 0;
+}
+
+int mbtk_ifc_set_addr(const char *name, in_addr_t addr, in_addr_t netmask)
+{
+ struct ifreq ifr, irf_mask;
+ int ret;
+
+ ifc_init_ifr(name, &ifr);
+ init_sockaddr_in(&ifr.ifr_addr, addr);
+
+ ret = ioctl(ifc_ctl_sock, SIOCSIFADDR, &ifr);
+ if(ret)
+ {
+ LOGD("set_addr(%s, %x) = %d fail.", name, addr, ret);
+ }
+
+ if(netmask)
+ {
+ ifc_init_ifr(name, &irf_mask);
+ init_sockaddr_in(&irf_mask.ifr_netmask, netmask);
+ ret = ioctl(ifc_ctl_sock, SIOCSIFNETMASK, &irf_mask);
+ if(ret)
+ {
+ LOGD("set_netmask(%s, %x) = %d fail.", name, netmask, ret);
+ }
+ }
+
+ return ret;
+}
+
+int mbtk_ifc_ip_config(const char *ifname, const char *ipv4, const char *mask, const char *gateway)
+{
+ UNUSED(gateway);
+ struct ifreq ifr;
+
+// struct rtentry rt;
+ // Set IPv4
+ struct sockaddr_in *sin;
+ memset(&ifr,0,sizeof(ifr));
+ strcpy(ifr.ifr_name,ifname);
+ sin = (struct sockaddr_in*)&ifr.ifr_addr;
+ sin->sin_family = AF_INET;
+ if(ipv4) {
+ if(inet_aton(ipv4,&(sin->sin_addr)) < 0)
+ {
+ LOGE("inet_aton error.");
+ return -2;
+ }
+ } else {
+ memset(&(sin->sin_addr), 0, sizeof(struct in_addr));
+ }
+
+ if(ioctl(ifc_ctl_sock,SIOCSIFADDR,&ifr) < 0)
+ {
+ LOGE("ioctl SIOCSIFADDR error.");
+ return -3;
+ }
+
+#if 1
+#if 1
+ //netmask
+ if(mask) {
+ if(inet_aton(mask,&(sin->sin_addr)) < 0)
+ {
+ LOGE("inet_pton error.");
+ return -4;
+ }
+
+ if(ioctl(ifc_ctl_sock, SIOCSIFNETMASK, &ifr) < 0)
+ {
+ LOGE("ioctl error.");
+ return -5;
+ }
+ }
+#else
+
+ //struct ifreq ifr;
+ //strcpy(ifr.ifr_name, interface_name);
+ struct sockaddr_in netmask_addr;
+ bzero(&netmask_addr, sizeof(struct sockaddr_in));
+ netmask_addr.sin_family = PF_INET;
+ inet_aton(mask, &netmask_addr.sin_addr);
+ memcpy(&ifr.ifr_ifru.ifru_netmask, &netmask_addr,
+ sizeof(struct sockaddr_in));
+ if (ioctl(ifc_ctl_sock, SIOCSIFNETMASK, &ifr) < 0)
+ {
+ LOGE("ioctl() fail.");
+ return -1;
+ }
+#endif
+#endif
+
+#if 0
+ //gateway
+ memset(&rt, 0, sizeof(struct rtentry));
+ memset(sin, 0, sizeof(struct sockaddr_in));
+ sin->sin_family = AF_INET;
+ sin->sin_port = 0;
+ if(inet_aton(gateway, &sin->sin_addr)<0)
+ {
+ LOGE( "inet_aton error." );
+ }
+ memcpy ( &rt.rt_gateway, sin, sizeof(struct sockaddr_in));
+ ((struct sockaddr_in *)&rt.rt_dst)->sin_family=AF_INET;
+ ((struct sockaddr_in *)&rt.rt_genmask)->sin_family=AF_INET;
+ rt.rt_flags = RTF_GATEWAY;
+ if (ioctl(ifc_ctl_sock, SIOCADDRT, &rt)<0)
+ {
+ LOGE("ioctl(SIOCADDRT) error in set_default_route\n");
+ return -1;
+ }
+#endif
+ return 0;
+}
+
+int mbtk_ifc_set_netmask(const char *ifname, const char *netmask)
+{
+ int s;
+ if ((s = socket(PF_INET, SOCK_STREAM, 0)) < 0)
+ {
+ LOGE("Socket");
+ return -1;
+ }
+ struct ifreq ifr;
+ strcpy(ifr.ifr_name, ifname);
+ struct sockaddr_in netmask_addr;
+ bzero(&netmask_addr, sizeof(struct sockaddr_in));
+ netmask_addr.sin_family = PF_INET;
+ inet_aton(netmask, &netmask_addr.sin_addr);
+ memcpy(&ifr.ifr_ifru.ifru_netmask, &netmask_addr,
+ sizeof(struct sockaddr_in));
+ if (ioctl(s, SIOCSIFNETMASK, &ifr) < 0)
+ {
+ LOGE("ioctl");
+ close(s);
+ return -1;
+ }
+ close(s);
+ return 0;
+}
+
+
+int mbtk_ifc_get_addr(const char *name, void *addr)
+{
+ int ret;
+ struct ifreq ifr;
+ ifc_init_ifr(name, &ifr);
+
+ ret = ioctl(ifc_ctl_sock, SIOCGIFADDR, &ifr);
+ LOGD("ifc_get_addr(%s, %x) = %d", name, ifr.ifr_addr, ret);
+ if(ret < 0) return -1;
+
+ memcpy(addr, &ifr.ifr_addr, sizeof(struct sockaddr));
+ return 0;
+}
+
+
+int mbtk_ifc_up(const char *name)
+{
+ int ret = ifc_set_flags(ifc_ctl_sock, name, IFF_UP, 0);
+// LOGI("mbtk_ifc_up(%s) = %d", name, ret);
+ return ret;
+}
+
+int mbtk_ifc_down(const char *name)
+{
+ int ret = ifc_set_flags(ifc_ctl_sock, name, 0, IFF_UP);
+// LOGI("mbtk_ifc_down(%s) = %d", name, ret);
+ return ret;
+}
+
+int mbtk_ifc_get_hwaddr(const char *name, void *ptr)
+{
+ int r;
+ struct ifreq ifr;
+ ifc_init_ifr(name, &ifr);
+
+ r = ioctl(ifc_ctl_sock, SIOCGIFHWADDR, &ifr);
+ if(r < 0) return -1;
+
+ memcpy(ptr, &ifr.ifr_hwaddr.sa_data, ETH_ALEN);
+ return 0;
+}
+
+int mbtk_ifc_get_ifindex(const char *name, int *if_indexp)
+{
+ int r;
+ struct ifreq ifr;
+ ifc_init_ifr(name, &ifr);
+
+ r = ioctl(ifc_ctl_sock, SIOCGIFINDEX, &ifr);
+ if(r < 0) return -1;
+
+ *if_indexp = ifr.ifr_ifindex;
+ return 0;
+}
+
+int mbtk_ifc_configure1(const char *ifname,
+ in_addr_t address,
+ uint32_t prefixLength,
+ in_addr_t gateway,
+ in_addr_t netmask)
+{
+ if(mbtk_ifc_open())
+ {
+ LOGE("mbtk_ifc_open() fail.", strerror(errno));
+ return -1;
+ }
+
+ if (mbtk_ifc_up(ifname))
+ {
+ LOGE("failed to turn on interface %s: %s", ifname, strerror(errno));
+ mbtk_ifc_close();
+ return -1;
+ }
+ if (mbtk_ifc_set_addr(ifname, address, netmask))
+ {
+ LOGE("failed to set ipaddr %s: %s", ipaddr_to_string(address), strerror(errno));
+ mbtk_ifc_close();
+ return -1;
+ }
+ if (ifc_set_prefixLength(ifname, prefixLength))
+ {
+ LOGE("failed to set prefixLength %d: %s", prefixLength, strerror(errno));
+ mbtk_ifc_close();
+ return -1;
+ }
+ if (ifc_create_default_route1(ifname, gateway))
+ {
+ LOGE("failed to set default route %s: %s", ipaddr_to_string(gateway), strerror(errno));
+ mbtk_ifc_close();
+ return -1;
+ }
+
+ mbtk_ifc_close();
+ return 0;
+}
+
+int mbtk_ifc_configure2(const char *ifname,
+ const char *ipv4,
+ uint32_t prefixLength,
+ const char *gateway,
+ const char *netmask)
+{
+ if(mbtk_ifc_open())
+ {
+ LOGE("mbtk_ifc_open() fail.", strerror(errno));
+ return -1;
+ }
+
+ if(ipv4 == NULL) {
+ if (mbtk_ifc_down(ifname))
+ {
+ LOGE("failed to turn off interface %s: %s", ifname, strerror(errno));
+ mbtk_ifc_close();
+ return -1;
+ }
+ } else {
+ if (mbtk_ifc_up(ifname))
+ {
+ LOGE("failed to turn on interface %s: %s", ifname, strerror(errno));
+ mbtk_ifc_close();
+ return -1;
+ }
+ }
+
+ if (mbtk_ifc_ip_config(ifname, ipv4, netmask, gateway))
+ {
+ LOGE("failed to set ipaddr: %s", strerror(errno));
+ mbtk_ifc_close();
+ return -1;
+ }
+
+// mbtk_ifc_set_netmask(ifname, netmask);
+
+#if 0
+ if (ifc_set_prefixLength(ifname, prefixLength))
+ {
+ LOGE("failed to set prefixLength %d: %s", prefixLength, strerror(errno));
+ mbtk_ifc_close();
+ return -1;
+ }
+#endif
+
+#if 0
+ if (ifc_create_default_route2(ifname, gateway))
+ {
+ LOGE("failed to set default route: %s", strerror(errno));
+ mbtk_ifc_close();
+ return -1;
+ }
+#endif
+
+ mbtk_ifc_close();
+
+ return 0;
+}
+
+struct in6_ifreq {
+ struct in6_addr addr;
+ uint32_t prefixlen;
+ unsigned int ifindex;
+};
+
+int mbtk_ipv6_config(const char *ifname, const char *ipv6, uint32_t prefixLength)
+{
+ struct ifreq ifr;
+ struct in6_ifreq ifr6;
+ int sockfd;
+ int err = 0;
+
+ // Create IPv6 socket to perform the ioctl operations on
+ sockfd = socket(AF_INET6, SOCK_DGRAM, IPPROTO_IP);
+ if(sockfd < 0) {
+ LOGE("socket() fail.[%d]", errno);
+ return -1;
+ }
+
+ if(ipv6) {
+ if(ifc_set_flags(sockfd, ifname, IFF_UP, 0) < 0) {
+ LOGE("if up fail[%d].", errno);
+ err = -1;
+ goto exit;
+ }
+
+ // Copy the interface name to the ifreq struct
+ strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
+ // Get the ifrindex of the interface
+ if(ioctl(sockfd, SIOGIFINDEX, &ifr) < 0)
+ {
+ LOGE("ioctl SIOGIFINDEX error.");
+ err = -1;
+ goto exit;
+ }
+
+ // Prepare the in6_ifreq struct and set the address to the interface
+ if(inet_pton(AF_INET6, ipv6, &ifr6.addr) < 0) {
+ LOGE("inet_pton() fail[%d].", errno);
+ err = -1;
+ goto exit;
+ }
+ } else {
+ if(ifc_set_flags(sockfd, ifname, 0, IFF_UP) < 0) {
+ LOGE("if down fail[%d].", errno);
+ err = -1;
+ goto exit;
+ }
+
+ // Copy the interface name to the ifreq struct
+ strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
+ // Get the ifrindex of the interface
+ if(ioctl(sockfd, SIOGIFINDEX, &ifr) < 0)
+ {
+ LOGE("ioctl SIOGIFINDEX error.");
+ err = -1;
+ goto exit;
+ }
+
+ // Set IPv6 to 0.
+ memset(&(ifr6.addr), 0, sizeof(struct in6_addr));
+ }
+ ifr6.ifindex = ifr.ifr_ifindex;
+ ifr6.prefixlen = prefixLength;
+ if(ioctl(sockfd, SIOCSIFADDR, &ifr6) < 0) {
+ LOGE("ioctl SIOCSIFADDR error.");
+ err = -1;
+ goto exit;
+ }
+
+ LOGD("Set IPv6 : %s success.", ipv6);
+exit:
+ close(socket);
+ return err;
+}