Line data Source code
1 : /* SPDX-License-Identifier: GPL-2.0-only */
2 : /*
3 : * Copyright (c) 2023 Meta Platforms, Inc. and affiliates.
4 : */
5 :
6 : // clang-format off
7 : // Include net/if.h before any kernel header to avoid conflicts.
8 : #include <net/if.h>
9 : // clang-format on
10 :
11 : #include "core/if.h"
12 :
13 : #include <errno.h>
14 : #include <limits.h>
15 : #include <stdlib.h>
16 : #include <string.h>
17 : #include <sys/types.h>
18 :
19 : #include "core/helper.h"
20 : #include "core/logger.h"
21 :
22 : static char _bf_if_name[IFNAMSIZ];
23 :
24 0 : int bf_if_index_from_name(const char *name)
25 : {
26 : unsigned int r;
27 :
28 0 : bf_assert(name);
29 :
30 0 : r = if_nametoindex(name);
31 0 : if (r == 0)
32 : return -ENOENT;
33 :
34 0 : if (r > INT_MAX)
35 0 : return -E2BIG;
36 :
37 : return (int)r;
38 : }
39 :
40 0 : const char *bf_if_name_from_index(int index)
41 : {
42 0 : if (!if_indextoname(index, _bf_if_name))
43 0 : return NULL;
44 :
45 : return _bf_if_name;
46 : }
47 :
48 0 : ssize_t bf_if_get_ifaces(struct bf_if_iface **ifaces)
49 : {
50 : _cleanup_free_ struct bf_if_iface *_ifaces = NULL;
51 : struct if_nameindex *if_ni, *it;
52 : ssize_t n_ifaces = 0;
53 : size_t i = 0;
54 :
55 0 : bf_assert(ifaces);
56 :
57 0 : if_ni = if_nameindex();
58 0 : if (!if_ni)
59 0 : return bf_err_r(errno, "failed to fetch interfaces details");
60 :
61 : // Gather the number of interfaces to allocate the memory.
62 0 : for (it = if_ni; it->if_index != 0 || it->if_name != NULL; ++it)
63 0 : ++n_ifaces;
64 :
65 0 : if (n_ifaces == 0)
66 : return 0;
67 :
68 0 : _ifaces = malloc(n_ifaces * sizeof(*_ifaces));
69 0 : if (!_ifaces) {
70 0 : if_freenameindex(if_ni);
71 0 : return bf_err_r(-ENOMEM,
72 : "failed to allocate memory for interfaces buffer");
73 : }
74 :
75 0 : for (it = if_ni; it->if_index != 0 || it->if_name != NULL; ++it) {
76 0 : _ifaces[i].index = it->if_index;
77 :
78 0 : if (it->if_index)
79 0 : strncpy(_ifaces[i].name, it->if_name, IF_NAMESIZE);
80 : else
81 0 : bf_warn("interface %d has no name", it->if_index);
82 :
83 0 : ++i;
84 : }
85 :
86 0 : *ifaces = TAKE_PTR(_ifaces);
87 :
88 0 : if_freenameindex(if_ni);
89 :
90 0 : return n_ifaces;
91 : }
|