File: dat_cache.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 (130 lines) | stat: -rw-r--r-- 3,449 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
// SPDX-License-Identifier: GPL-2.0
/* Copyright (C) B.A.T.M.A.N. contributors:
 *
 * Marek Lindner <marek.lindner@mailbox.org>
 *
 * License-Filename: LICENSES/preferred/GPL-2.0
 */

#include <arpa/inet.h>
#include <netinet/if_ether.h>
#include <netinet/in.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 <sys/socket.h>

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

static const int dat_cache_mandatory[] = {
	BATADV_ATTR_DAT_CACHE_IP4ADDRESS,
	BATADV_ATTR_DAT_CACHE_HWADDRESS,
	BATADV_ATTR_DAT_CACHE_VID,
	BATADV_ATTR_LAST_SEEN_MSECS,
};

static int dat_cache_callback(struct nl_msg *msg, void *arg)
{
	int last_seen_msecs, last_seen_secs, last_seen_mins;
	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;
	struct in_addr in_addr;
	uint8_t *hwaddr;
	int16_t vid;
	char *addr;

	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_DAT_CACHE)
		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, dat_cache_mandatory,
				    ARRAY_SIZE(dat_cache_mandatory))) {
		fputs("Missing attributes from kernel\n", stderr);
		exit(1);
	}

	in_addr.s_addr = nla_get_u32(attrs[BATADV_ATTR_DAT_CACHE_IP4ADDRESS]);
	addr = inet_ntoa(in_addr);
	hwaddr = nla_data(attrs[BATADV_ATTR_DAT_CACHE_HWADDRESS]);
	vid = nla_get_u16(attrs[BATADV_ATTR_DAT_CACHE_VID]);

	last_seen_msecs = nla_get_u32(attrs[BATADV_ATTR_LAST_SEEN_MSECS]);
	last_seen_mins = last_seen_msecs / 60000;
	last_seen_msecs = last_seen_msecs % 60000;
	last_seen_secs = last_seen_msecs / 1000;

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

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

	printf(" * %15s ", addr);

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

	printf("%4i %6i:%02i\n",
	       BATADV_PRINT_VID(vid), last_seen_mins, last_seen_secs);

	return NL_OK;
}

static int netlink_print_dat_cache(struct state *state, char *orig_iface,
				   int read_opts, float orig_timeout,
				   float watch_interval)
{
	char *header;
	int ret;

	ret = asprintf(&header, "Distributed ARP Table (%s):\n%s\n",
		       state->mesh_iface,
		       "          IPv4             MAC        VID   last-seen");

	if (ret < 0)
		return ret;

	ret = netlink_print_common(state, orig_iface, read_opts,
				   orig_timeout, watch_interval, header,
				   BATADV_CMD_GET_DAT_CACHE,
				   dat_cache_callback);

	free(header);
	return ret;
}

static struct debug_table_data batctl_debug_table_dat_cache = {
	.netlink_fn = netlink_print_dat_cache,
};

COMMAND_NAMED(DEBUGTABLE, dat_cache, "dc", handle_debug_table,
	      COMMAND_FLAG_MESH_IFACE | COMMAND_FLAG_NETLINK,
	      &batctl_debug_table_dat_cache, "");