mirror of
https://github.com/outbackdingo/udevmand.git
synced 2026-08-25 14:53:42 +00:00
@@ -0,0 +1,134 @@
|
||||
#include "udevmand.h"
|
||||
|
||||
int
|
||||
avl_mac_cmp(const void *k1, const void *k2, void *ptr)
|
||||
{
|
||||
return memcmp(k1, k2, ETH_ALEN);
|
||||
}
|
||||
|
||||
struct avl_tree mac_tree = AVL_TREE_INIT(mac_tree, avl_mac_cmp, false, NULL);
|
||||
|
||||
struct mac*
|
||||
mac_find(uint8_t *addr)
|
||||
{
|
||||
struct mac *mac;
|
||||
uint8_t *addr_buf;
|
||||
|
||||
mac = avl_find_element(&mac_tree, addr, mac, avl);
|
||||
|
||||
if (mac)
|
||||
return mac;
|
||||
|
||||
mac = calloc_a(sizeof(struct mac), &addr_buf, 6);
|
||||
if (!mac)
|
||||
return NULL;
|
||||
mac->addr = memcpy(addr_buf, addr, ETH_ALEN);
|
||||
mac->avl.key = mac->addr;
|
||||
mac->ethers = NULL;
|
||||
*mac->interface = '\0';
|
||||
INIT_LIST_HEAD(&mac->neigh4);
|
||||
INIT_LIST_HEAD(&mac->neigh6);
|
||||
INIT_LIST_HEAD(&mac->wifi);
|
||||
INIT_LIST_HEAD(&mac->dhcpv4);
|
||||
INIT_LIST_HEAD(&mac->bridge_mac);
|
||||
|
||||
avl_insert(&mac_tree, &mac->avl);
|
||||
ULOG_INFO("new mac "MAC_FMT"\n", MAC_VAR(mac->addr));
|
||||
|
||||
return mac;
|
||||
}
|
||||
|
||||
void
|
||||
mac_update(struct mac *mac, char *iface)
|
||||
{
|
||||
char *interface = interface_resolve(iface);
|
||||
|
||||
if (iface && *iface)
|
||||
strncpy(mac->interface, interface, sizeof(mac->interface));
|
||||
|
||||
clock_gettime(CLOCK_MONOTONIC, &mac->ts);
|
||||
}
|
||||
|
||||
void
|
||||
mac_dump(struct mac *mac, int interface)
|
||||
{
|
||||
struct timespec ts;
|
||||
time_t last_seen;
|
||||
char buf[18];
|
||||
void *c, *d;
|
||||
|
||||
clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||
|
||||
last_seen = ts.tv_sec - mac->ts.tv_sec;
|
||||
snprintf(buf, sizeof(buf), MAC_FMT, MAC_VAR(mac->addr));
|
||||
c = blobmsg_open_table(&b, buf);
|
||||
if (interface && *mac->interface)
|
||||
blobmsg_add_string(&b, "interface", mac->interface);
|
||||
if (mac->ethers)
|
||||
blobmsg_add_string(&b, "ethers", mac->ethers);
|
||||
if (last_seen < 5 * 60)
|
||||
blobmsg_add_u32(&b, "last_seen", last_seen);
|
||||
else
|
||||
blobmsg_add_u8(&b, "offline", 1);
|
||||
if (!list_empty(&mac->neigh4)) {
|
||||
struct neigh *neigh;
|
||||
|
||||
d = blobmsg_open_array(&b, "ipv4");
|
||||
list_for_each_entry(neigh, &mac->neigh4, list)
|
||||
blobmsg_add_ipv4(&b, NULL, neigh->ip);
|
||||
blobmsg_close_array(&b, d);
|
||||
}
|
||||
|
||||
if (!list_empty(&mac->neigh6)) {
|
||||
struct neigh *neigh;
|
||||
|
||||
d = blobmsg_open_array(&b, "ipv6");
|
||||
list_for_each_entry(neigh, &mac->neigh6, list)
|
||||
blobmsg_add_ipv6(&b, NULL, neigh->ip);
|
||||
blobmsg_close_array(&b, d);
|
||||
}
|
||||
|
||||
if (!list_empty(&mac->wifi)) {
|
||||
struct wifi_station *sta;
|
||||
|
||||
sta = list_first_entry(&mac->wifi, struct wifi_station, mac);
|
||||
blobmsg_add_field(&b, BLOBMSG_TYPE_TABLE, "wifi",
|
||||
blobmsg_data(sta->info), blobmsg_data_len(sta->info));
|
||||
}
|
||||
|
||||
if (!list_empty(&mac->dhcpv4)) {
|
||||
struct dhcpv4 *dhcpv4;
|
||||
|
||||
d = blobmsg_open_array(&b, "dhcpv4");
|
||||
list_for_each_entry(dhcpv4, &mac->dhcpv4, mac) {
|
||||
blobmsg_add_ipv4(&b, NULL, dhcpv4->ip);
|
||||
if (strlen(dhcpv4->name) > 0)
|
||||
blobmsg_add_string(&b, NULL, dhcpv4->name);
|
||||
break;
|
||||
}
|
||||
blobmsg_close_array(&b, d);
|
||||
}
|
||||
|
||||
if (!list_empty(&mac->bridge_mac)) {
|
||||
struct bridge_mac *bridge_mac;
|
||||
|
||||
d = blobmsg_open_array(&b, "fdb");
|
||||
list_for_each_entry(bridge_mac, &mac->bridge_mac, mac)
|
||||
blobmsg_add_string(&b, NULL, bridge_mac->ifname);
|
||||
blobmsg_close_array(&b, d);
|
||||
}
|
||||
|
||||
blobmsg_close_array(&b, c);
|
||||
}
|
||||
|
||||
int
|
||||
mac_dump_all(void)
|
||||
{
|
||||
struct mac *mac;
|
||||
|
||||
blob_buf_init(&b, 0);
|
||||
|
||||
avl_for_each_element(&mac_tree, mac, avl)
|
||||
mac_dump(mac, 1);
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user