Jukka Rissanen | 0f66426 | 2018-02-21 16:18:35 +0200 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (c) 2018 Intel Corporation |
| 3 | * |
| 4 | * SPDX-License-Identifier: Apache-2.0 |
| 5 | */ |
| 6 | |
| 7 | /** |
| 8 | * @file |
| 9 | * |
| 10 | * Routines setting up the host system. Those are placed in separate file |
| 11 | * because there is naming conflicts between host and zephyr network stacks. |
| 12 | */ |
| 13 | |
Jukka Rissanen | 0f66426 | 2018-02-21 16:18:35 +0200 | [diff] [blame] | 14 | /* Host include files */ |
| 15 | #include <stdio.h> |
Jukka Rissanen | 9135b17 | 2018-07-23 13:58:21 +0300 | [diff] [blame] | 16 | #include <stdlib.h> |
Jukka Rissanen | 0f66426 | 2018-02-21 16:18:35 +0200 | [diff] [blame] | 17 | #include <stdarg.h> |
| 18 | #include <errno.h> |
| 19 | #include <string.h> |
| 20 | #include <stdbool.h> |
Alberto Escolar Piedras | 7c776c8 | 2018-08-02 12:07:35 +0200 | [diff] [blame] | 21 | #include <unistd.h> |
Jukka Rissanen | 0f66426 | 2018-02-21 16:18:35 +0200 | [diff] [blame] | 22 | #include <fcntl.h> |
| 23 | #include <sys/ioctl.h> |
| 24 | #include <sys/socket.h> |
Alberto Escolar Piedras | c065ebd | 2018-09-25 16:52:27 +0200 | [diff] [blame] | 25 | #include <sys/select.h> |
Jukka Rissanen | 0f66426 | 2018-02-21 16:18:35 +0200 | [diff] [blame] | 26 | #include <net/if.h> |
Jukka Rissanen | 16f31f1 | 2018-03-12 21:54:19 +0200 | [diff] [blame] | 27 | #include <time.h> |
Jukka Rissanen | c345f59 | 2023-10-03 14:58:25 +0300 | [diff] [blame] | 28 | #include <inttypes.h> |
| 29 | #include <nsi_tracing.h> |
Jukka Rissanen | 0f66426 | 2018-02-21 16:18:35 +0200 | [diff] [blame] | 30 | |
| 31 | #ifdef __linux |
Jukka Rissanen | c345f59 | 2023-10-03 14:58:25 +0300 | [diff] [blame] | 32 | #include <linux/if.h> |
Jukka Rissanen | 0f66426 | 2018-02-21 16:18:35 +0200 | [diff] [blame] | 33 | #include <linux/if_tun.h> |
| 34 | #endif |
| 35 | |
Jukka Rissanen | 0f66426 | 2018-02-21 16:18:35 +0200 | [diff] [blame] | 36 | #include "eth_native_posix_priv.h" |
| 37 | |
| 38 | /* Note that we cannot create the TUN/TAP device from the setup script |
| 39 | * as we need to get a file descriptor to communicate with the interface. |
| 40 | */ |
Jukka Rissanen | c345f59 | 2023-10-03 14:58:25 +0300 | [diff] [blame] | 41 | int eth_iface_create(const char *dev_name, const char *if_name, bool tun_only) |
Jukka Rissanen | 0f66426 | 2018-02-21 16:18:35 +0200 | [diff] [blame] | 42 | { |
| 43 | struct ifreq ifr; |
| 44 | int fd, ret = -EINVAL; |
| 45 | |
Jukka Rissanen | c345f59 | 2023-10-03 14:58:25 +0300 | [diff] [blame] | 46 | fd = open(dev_name, O_RDWR); |
Jukka Rissanen | 0f66426 | 2018-02-21 16:18:35 +0200 | [diff] [blame] | 47 | if (fd < 0) { |
| 48 | return -errno; |
| 49 | } |
| 50 | |
Flavio Ceolin | da49f2e | 2018-09-11 19:09:03 -0700 | [diff] [blame] | 51 | (void)memset(&ifr, 0, sizeof(ifr)); |
Jukka Rissanen | 0f66426 | 2018-02-21 16:18:35 +0200 | [diff] [blame] | 52 | |
| 53 | #ifdef __linux |
| 54 | ifr.ifr_flags = (tun_only ? IFF_TUN : IFF_TAP) | IFF_NO_PI; |
| 55 | |
Jukka Rissanen | 179d520 | 2019-03-12 23:36:51 +0200 | [diff] [blame] | 56 | strncpy(ifr.ifr_name, if_name, IFNAMSIZ - 1); |
Jukka Rissanen | 0f66426 | 2018-02-21 16:18:35 +0200 | [diff] [blame] | 57 | |
| 58 | ret = ioctl(fd, TUNSETIFF, (void *)&ifr); |
| 59 | if (ret < 0) { |
| 60 | ret = -errno; |
| 61 | close(fd); |
| 62 | return ret; |
| 63 | } |
| 64 | #endif |
| 65 | |
| 66 | return fd; |
| 67 | } |
| 68 | |
| 69 | int eth_iface_remove(int fd) |
| 70 | { |
| 71 | return close(fd); |
| 72 | } |
| 73 | |
| 74 | static int ssystem(const char *fmt, ...) |
| 75 | __attribute__((__format__(__printf__, 1, 2))); |
| 76 | |
| 77 | static int ssystem(const char *fmt, ...) |
| 78 | { |
| 79 | char cmd[255]; |
| 80 | va_list ap; |
Jukka Rissanen | 9135b17 | 2018-07-23 13:58:21 +0300 | [diff] [blame] | 81 | int ret; |
Jukka Rissanen | 0f66426 | 2018-02-21 16:18:35 +0200 | [diff] [blame] | 82 | |
| 83 | va_start(ap, fmt); |
| 84 | vsnprintf(cmd, sizeof(cmd), fmt, ap); |
| 85 | va_end(ap); |
| 86 | |
Jukka Rissanen | c345f59 | 2023-10-03 14:58:25 +0300 | [diff] [blame] | 87 | nsi_print_trace("%s\n", cmd); |
Jukka Rissanen | 0f66426 | 2018-02-21 16:18:35 +0200 | [diff] [blame] | 88 | |
Jukka Rissanen | 9135b17 | 2018-07-23 13:58:21 +0300 | [diff] [blame] | 89 | ret = system(cmd); |
| 90 | |
| 91 | return -WEXITSTATUS(ret); |
Jukka Rissanen | 0f66426 | 2018-02-21 16:18:35 +0200 | [diff] [blame] | 92 | } |
| 93 | |
Jukka Rissanen | 0f66426 | 2018-02-21 16:18:35 +0200 | [diff] [blame] | 94 | int eth_wait_data(int fd) |
| 95 | { |
| 96 | struct timeval timeout; |
| 97 | fd_set rset; |
| 98 | int ret; |
| 99 | |
| 100 | FD_ZERO(&rset); |
| 101 | |
| 102 | FD_SET(fd, &rset); |
| 103 | |
| 104 | timeout.tv_sec = 0; |
Jukka Rissanen | 5afa30c | 2018-03-26 13:04:00 +0300 | [diff] [blame] | 105 | timeout.tv_usec = 0; |
Jukka Rissanen | 0f66426 | 2018-02-21 16:18:35 +0200 | [diff] [blame] | 106 | |
| 107 | ret = select(fd + 1, &rset, NULL, NULL, &timeout); |
| 108 | if (ret < 0 && errno != EINTR) { |
| 109 | return -errno; |
| 110 | } else if (ret > 0) { |
| 111 | if (FD_ISSET(fd, &rset)) { |
| 112 | return 0; |
| 113 | } |
| 114 | } |
| 115 | |
| 116 | return -EAGAIN; |
| 117 | } |
| 118 | |
Jukka Rissanen | c345f59 | 2023-10-03 14:58:25 +0300 | [diff] [blame] | 119 | int eth_clock_gettime(uint64_t *second, uint32_t *nanosecond) |
Jukka Rissanen | 16f31f1 | 2018-03-12 21:54:19 +0200 | [diff] [blame] | 120 | { |
| 121 | struct timespec tp; |
| 122 | int ret; |
| 123 | |
| 124 | ret = clock_gettime(CLOCK_MONOTONIC_RAW, &tp); |
| 125 | if (ret < 0) { |
| 126 | return -errno; |
| 127 | } |
| 128 | |
Jukka Rissanen | c345f59 | 2023-10-03 14:58:25 +0300 | [diff] [blame] | 129 | *second = (uint64_t)tp.tv_sec; |
| 130 | *nanosecond = (uint32_t)tp.tv_nsec; |
Jukka Rissanen | 16f31f1 | 2018-03-12 21:54:19 +0200 | [diff] [blame] | 131 | |
| 132 | return 0; |
| 133 | } |
Jukka Rissanen | af44d7c | 2018-07-23 14:00:19 +0300 | [diff] [blame] | 134 | |
Jukka Rissanen | af44d7c | 2018-07-23 14:00:19 +0300 | [diff] [blame] | 135 | int eth_promisc_mode(const char *if_name, bool enable) |
| 136 | { |
| 137 | return ssystem("ip link set dev %s promisc %s", |
| 138 | if_name, enable ? "on" : "off"); |
| 139 | } |