Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright (C) 2021 Intel Corporation. All rights reserved.
3 : : * Copyright (C) 2024 Samsung Electronics Co., Ltd.
4 : : * All rights reserved.
5 : : */
6 : :
7 : : #include "spdk/stdinc.h"
8 : : #include "spdk/net.h"
9 : :
10 : : int
11 : 0 : spdk_net_get_interface_name(const char *ip, char *ifc, size_t len)
12 : : {
13 : 0 : struct ifaddrs *addrs, *iap;
14 : : struct sockaddr_in *sa;
15 : 0 : char buf[32];
16 : 0 : int rc = -ENODEV;
17 : :
18 : 0 : getifaddrs(&addrs);
19 [ # # ]: 0 : for (iap = addrs; iap != NULL; iap = iap->ifa_next) {
20 [ # # # # : 0 : if (!(iap->ifa_addr && (iap->ifa_flags & IFF_UP) && iap->ifa_addr->sa_family == AF_INET)) {
# # ]
21 : 0 : continue;
22 : : }
23 : 0 : sa = (struct sockaddr_in *)(iap->ifa_addr);
24 : 0 : inet_ntop(iap->ifa_addr->sa_family, &sa->sin_addr, buf, sizeof(buf));
25 [ # # # # ]: 0 : if (strcmp(ip, buf) != 0) {
26 : 0 : continue;
27 : : }
28 [ # # # # ]: 0 : if (strnlen(iap->ifa_name, len) == len) {
29 : 0 : return -ENOMEM;
30 : : }
31 : 0 : snprintf(ifc, len, "%s", iap->ifa_name);
32 : 0 : rc = 0;
33 : 0 : break;
34 : : }
35 : 0 : freeifaddrs(addrs);
36 : 0 : return rc;
37 : : }
38 : :
39 : : int
40 : 39640 : spdk_net_get_address_string(struct sockaddr *sa, char *addr, size_t len)
41 : : {
42 : 39640 : const char *result = NULL;
43 : :
44 [ + - - + ]: 39640 : if (sa == NULL || addr == NULL) {
45 : 0 : return -1;
46 : : }
47 : :
48 [ + - - ]: 39640 : switch (sa->sa_family) {
49 : 39640 : case AF_INET:
50 : 39640 : result = inet_ntop(AF_INET, &(((struct sockaddr_in *)sa)->sin_addr),
51 : : addr, len);
52 : 39640 : break;
53 : 0 : case AF_INET6:
54 : 0 : result = inet_ntop(AF_INET6, &(((struct sockaddr_in6 *)sa)->sin6_addr),
55 : : addr, len);
56 : 0 : break;
57 : 0 : default:
58 : 0 : break;
59 : : }
60 : :
61 [ + - ]: 39640 : if (result != NULL) {
62 : 39640 : return 0;
63 : : } else {
64 : 0 : return -errno;
65 : : }
66 : : }
67 : :
68 : : bool
69 : 3347 : spdk_net_is_loopback(int fd)
70 : : {
71 : 110 : struct ifaddrs *addrs, *tmp;
72 : 3347 : struct sockaddr_storage sa = {};
73 : 110 : socklen_t salen;
74 : 3347 : struct ifreq ifr = {};
75 : 110 : char ip_addr[256], ip_addr_tmp[256];
76 : : int rc;
77 : 3347 : bool is_loopback = false;
78 : :
79 : 3347 : salen = sizeof(sa);
80 : 3347 : rc = getsockname(fd, (struct sockaddr *)&sa, &salen);
81 [ - + ]: 3347 : if (rc != 0) {
82 : 0 : return is_loopback;
83 : : }
84 : :
85 : 3347 : memset(ip_addr, 0, sizeof(ip_addr));
86 : 3347 : rc = spdk_net_get_address_string((struct sockaddr *)&sa, ip_addr, sizeof(ip_addr));
87 [ - + ]: 3347 : if (rc != 0) {
88 : 0 : return is_loopback;
89 : : }
90 : :
91 : 3347 : getifaddrs(&addrs);
92 [ + + ]: 38885 : for (tmp = addrs; tmp != NULL; tmp = tmp->ifa_next) {
93 [ + - + + ]: 38879 : if (tmp->ifa_addr && (tmp->ifa_flags & IFF_UP) &&
94 [ + + ]: 31309 : (tmp->ifa_addr->sa_family == sa.ss_family)) {
95 : 13699 : memset(ip_addr_tmp, 0, sizeof(ip_addr_tmp));
96 : 13699 : rc = spdk_net_get_address_string(tmp->ifa_addr, ip_addr_tmp, sizeof(ip_addr_tmp));
97 [ - + ]: 13699 : if (rc != 0) {
98 : 0 : continue;
99 : : }
100 : :
101 [ + + ]: 13699 : if (strncmp(ip_addr, ip_addr_tmp, sizeof(ip_addr)) == 0) {
102 : 3341 : memcpy(ifr.ifr_name, tmp->ifa_name, sizeof(ifr.ifr_name));
103 : 3341 : ioctl(fd, SIOCGIFFLAGS, &ifr);
104 [ + + ]: 3341 : if (ifr.ifr_flags & IFF_LOOPBACK) {
105 : 155 : is_loopback = true;
106 : : }
107 : 3341 : goto end;
108 : : }
109 : : }
110 : : }
111 : :
112 : 116 : end:
113 : 3347 : freeifaddrs(addrs);
114 : 3347 : return is_loopback;
115 : : }
|