==> tests/nic.c <==1/* net.rs's tests: proc_net_dev, ext_wraps_and_resets, total_is_monotonic_and_skips_virtual,
2 * loopback_address_is_on_lo, this_machine_has_interfaces, nic_record_layout. */
3#include "mesh/check.h"
4#include "mesh/nic.h"
5
6#include <stdlib.h>
7#include <string.h>
8
9static const char *DEV = "Inter-| Receive | Transmit\n"
10 " face |bytes packets errs drop fifo frame compressed multicast|bytes packets errs drop fifo colls carrier compressed\n"
11 " lo: 1000 10 0 0 0 0 0 0 1000 10 0 0 0 0 0 0\n"
12 "enP7s7: 18446744073709551000 200 1 2 0 0 0 0 3000 300 3 4 0 0 0 0\n"
13 "docker0: 50 1 0 0 0 0 0 0 60 1 0 0 0 0 0 0\n";
14
15static mesh_nic_raw raw(const char *name, uint64_t b) {
16 mesh_nic_raw r;
17 memset(&r, 0, sizeof r);
18 strcpy(r.name, name);
19 r.v[0] = b;
20 r.v[1] = 2 * b;
21 for (int i = 0; i < 8; i++) r.bits[i] = 64;
22 return r;
23}
24
25static void sample(mesh_nics *s, const mesh_nic_raw *r, size_t n, mesh_nic_now **now, size_t *nn) {
26 if (*now) free(*now);
27 mesh_nics_sample(s, r, n, now, nn);
28}
29
30int main(void) {
31 mesh_nic_raw *r;
32 size_t n;
33 char *err = NULL;
34 CHECK_I(mesh_nic_parse_proc_net_dev(DEV, &r, &n, &err), 0);
35 CHECK_U(n, 3);
36 CHECK_S(r[1].name, "enP7s7");
37 const uint64_t want[8] = {18446744073709551000ull, 3000, 200, 300, 1, 3, 2, 4};
38 CHECK(memcmp(r[1].v, want, sizeof want) == 0);
39 free(r);
40 CHECK_I(mesh_nic_parse_proc_net_dev("a\nb\n", &r, &n, &err), -1);
41 free(err);
42 CHECK_I(mesh_nic_parse_proc_net_dev("a\nb\neth0: 1 2 3\n", &r, &n, &err), -1);
43 CHECK_S(err, "/proc/net/dev line 3: 3 fields, want 16");
44 free(err);
45 CHECK_I(mesh_nic_parse_proc_net_dev("a\nb\neth0 1 2\n", &r, &n, &err), -1);
46 CHECK_S(err, "/proc/net/dev line 3: no ':'");
47 free(err);
48
49 mesh_nic_ext e = mesh_nic_ext_new(0xfffffff0u);
50 CHECK_U(mesh_nic_ext_update(&e, 0x10, 32), 0x20);
51 CHECK_U(e.value, 0x100000010ull);
52 CHECK_U(mesh_nic_ext_update(&e, 0x30, 32), 0x20);
53 e = mesh_nic_ext_new(1000);
54 CHECK_U(mesh_nic_ext_update(&e, 1500, 64), 500);
55 CHECK_U(mesh_nic_ext_update(&e, 200, 64), 200);
56 CHECK_U(e.value, 1700);
57 e = mesh_nic_ext_new(UINT64_MAX - 5);
58 CHECK_U(mesh_nic_ext_update(&e, UINT64_MAX, 64), 5);
59
60 mesh_nics s = {0};
61 mesh_nic_now *now = NULL;
62 size_t nn;
63 mesh_nic_raw a[3] = {raw("lo", 100), raw("en0", 1000), raw("veth1", 50)};
64 sample(&s, a, 3, &now, &nn);
65 CHECK_U(s.total[0], 1000);
66 CHECK_U(s.total[1], 2000);
67 CHECK_U(s.counted, 1);
68 mesh_nic_raw b[3] = {raw("lo", 900), raw("en0", 1100), raw("en1", 5000)};
69 sample(&s, b, 3, &now, &nn);
70 CHECK_U(s.total[0], 1100);
71 CHECK_U(mesh_nic_lookup(now, nn, "en1")[0], 5000);
72 mesh_nic_raw c[2] = {raw("en0", 1200), raw("en1", 5100)};
73 sample(&s, c, 2, &now, &nn);
74 CHECK_U(s.total[0], 1300);
75 mesh_nic_raw d[2] = {raw("en0", 50), raw("en1", 5100)};
76 sample(&s, d, 2, &now, &nn);
77 CHECK_U(s.total[0], 1350);
78 mesh_nic_raw f[1] = {raw("en1", 5200)};
79 sample(&s, f, 1, &now, &nn);
80 CHECK_U(s.total[0], 1450);
81 free(now);
82 mesh_nics_free(&s);
83
84 char name[MESH_NIC_NAME_MAX];
85 CHECK_I(mesh_nic_iface_of("127.0.0.1", name, &err), 0);
86 CHECK(strncmp(name, "lo", 2) == 0);
87 CHECK_I(mesh_nic_iface_of("203.0.113.77", name, &err), -1);
88 CHECK_S(err, "no interface holds 203.0.113.77");
89 free(err);
90
91 CHECK_I(mesh_nic_read(&r, &n, &err), 0);
92 int lo = 0;
93 for (size_t i = 0; i < n; i++) lo |= strncmp(r[i].name, "lo", 2) == 0;
94 CHECK(lo);
95 free(r);
96
97 uint8_t rec[MESH_NIC_BYTES];
98 const uint64_t v[8] = {1, 2, 3, 4, 5, 6, 7, 8};
99 mesh_nic_record(rec, "enP2p1s0f1np1-long", v, 6, 1);
100 CHECK(memcmp(rec, "enP2p1s0f1np1-l\0", 16) == 0);
101 CHECK_U(rec[MESH_NI_TX_DROP], 8);
102 CHECK_U(rec[MESH_NI_LINKS], 6);
103 return mesh_check_done();
104}