File: translocal.c

package info (click to toggle)
batctl 2025.5-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 840 kB
  • sloc: ansic: 12,083; makefile: 155; sh: 21
file content (142 lines) | stat: -rw-r--r-- 3,720 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
// SPDX-License-Identifier: GPL-2.0
/* Copyright (C) B.A.T.M.A.N. contributors:
 *
 * Andrew Lunn <andrew@lunn.ch>
 * Sven Eckelmann <sven@narfation.org>
 *
 * License-Filename: LICENSES/preferred/GPL-2.0
 */

#include <netinet/if_ether.h>
#include <netlink/netlink.h>
#include <netlink/genl/genl.h>
#include <netlink/genl/ctrl.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>

#include "batman_adv.h"
#include "bat-hosts.h"
#include "debug.h"
#include "functions.h"
#include "main.h"
#include "netlink.h"

static const int translocal_mandatory[] = {
	BATADV_ATTR_TT_ADDRESS,
	BATADV_ATTR_TT_VID,
	BATADV_ATTR_TT_CRC32,
	BATADV_ATTR_TT_FLAGS,
};

static int translocal_callback(struct nl_msg *msg, void *arg)
{
	struct nlattr *attrs[BATADV_ATTR_MAX + 1];
	struct nlmsghdr *nlh = nlmsg_hdr(msg);
	struct print_opts *opts = arg;
	struct bat_host *bat_host;
	struct genlmsghdr *ghdr;
	int last_seen_msecs = 0;
	int last_seen_secs = 0;
	uint32_t crc32;
	uint32_t flags;
	uint8_t *addr;
	int16_t vid;
	char r;
	char p;
	char n;
	char x;
	char w;
	char i;

	if (!genlmsg_valid_hdr(nlh, 0)) {
		fputs("Received invalid data from kernel.\n", stderr);
		exit(1);
	}

	ghdr = nlmsg_data(nlh);

	if (ghdr->cmd != BATADV_CMD_GET_TRANSTABLE_LOCAL)
		return NL_OK;

	if (nla_parse(attrs, BATADV_ATTR_MAX, genlmsg_attrdata(ghdr, 0),
		      genlmsg_len(ghdr), batadv_netlink_policy)) {
		fputs("Received invalid data from kernel.\n", stderr);
		exit(1);
	}

	if (missing_mandatory_attrs(attrs, translocal_mandatory,
				    ARRAY_SIZE(translocal_mandatory))) {
		fputs("Missing attributes from kernel\n", stderr);
		exit(1);
	}

	addr = nla_data(attrs[BATADV_ATTR_TT_ADDRESS]);
	vid = nla_get_u16(attrs[BATADV_ATTR_TT_VID]);
	crc32 = nla_get_u32(attrs[BATADV_ATTR_TT_CRC32]);
	flags = nla_get_u32(attrs[BATADV_ATTR_TT_FLAGS]);
	last_seen_msecs = 0;
	last_seen_secs = 0;

	if (opts->read_opt & MULTICAST_ONLY && !(addr[0] & 0x01))
		return NL_OK;

	if (opts->read_opt & UNICAST_ONLY && (addr[0] & 0x01))
		return NL_OK;

	r = '.', p = '.', n = '.', x = '.', w = '.', i = '.';
	if (flags & BATADV_TT_CLIENT_ROAM)
		r = 'R';
	if (flags & BATADV_TT_CLIENT_NEW)
		n = 'N';
	if (flags & BATADV_TT_CLIENT_PENDING)
		x = 'X';
	if (flags & BATADV_TT_CLIENT_WIFI)
		w = 'W';
	if (flags & BATADV_TT_CLIENT_ISOLA)
		i = 'I';
	if (flags & BATADV_TT_CLIENT_NOPURGE)
		p = 'P';

	if (attrs[BATADV_ATTR_LAST_SEEN_MSECS]) {
		last_seen_msecs = nla_get_u32(attrs[BATADV_ATTR_LAST_SEEN_MSECS]);
		last_seen_secs = last_seen_msecs / 1000;
		last_seen_msecs = last_seen_msecs % 1000;
	}

	bat_host = bat_hosts_find_by_mac((char *)addr);
	if (!(opts->read_opt & USE_BAT_HOSTS) || !bat_host)
		printf("%02x:%02x:%02x:%02x:%02x:%02x ",
		       addr[0], addr[1], addr[2],
		       addr[3], addr[4], addr[5]);
	else
		printf("%17s ", bat_host->name);

	printf("%4i [%c%c%c%c%c%c] %3u.%03u   (0x%.8x)\n",
	       BATADV_PRINT_VID(vid), r, p, n, x, w, i,
	       last_seen_secs, last_seen_msecs,
	       crc32);

	return NL_OK;
}

static int netlink_print_translocal(struct state *state, char *orig_iface,
				    int read_opts, float orig_timeout,
				    float watch_interval)
{
	return netlink_print_common(state, orig_iface, read_opts,
				    orig_timeout, watch_interval,
				    "Client             VID Flags    Last seen (CRC       )\n",
				    BATADV_CMD_GET_TRANSTABLE_LOCAL,
				    translocal_callback);
}

static struct debug_table_data batctl_debug_table_translocal = {
	.netlink_fn = netlink_print_translocal,
	.option_unicast_only = 1,
	.option_multicast_only = 1,
};

COMMAND_NAMED(DEBUGTABLE, translocal, "tl", handle_debug_table,
	      COMMAND_FLAG_MESH_IFACE | COMMAND_FLAG_NETLINK,
	      &batctl_debug_table_translocal, "");