2020-06-25 20:37:12 -04:00
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <stdint.h>
|
|
|
|
#include <errno.h>
|
|
|
|
|
|
|
|
#include <patty/hash.h>
|
|
|
|
|
|
|
|
#include <patty/ax25.h>
|
|
|
|
|
|
|
|
patty_ax25_route *patty_ax25_route_new(patty_ax25_if *iface,
|
2020-08-24 22:56:38 -05:00
|
|
|
patty_ax25_addr *dest,
|
|
|
|
patty_ax25_addr *repeaters,
|
|
|
|
int hops) {
|
2020-06-25 20:37:12 -04:00
|
|
|
patty_ax25_route *route;
|
|
|
|
|
2020-08-24 22:56:38 -05:00
|
|
|
int i;
|
|
|
|
|
|
|
|
if (hops >= PATTY_AX25_MAX_HOPS) {
|
|
|
|
errno = EOVERFLOW;
|
|
|
|
|
|
|
|
goto error_max_hops;
|
|
|
|
}
|
|
|
|
|
2020-06-25 20:37:12 -04:00
|
|
|
if ((route = malloc(sizeof(*route))) == NULL) {
|
|
|
|
goto error_malloc_route;
|
|
|
|
}
|
|
|
|
|
|
|
|
memset(route, '\0', sizeof(*route));
|
|
|
|
|
2020-08-24 22:56:38 -05:00
|
|
|
route->iface = iface;
|
|
|
|
|
|
|
|
if (dest) {
|
|
|
|
patty_ax25_addr_copy(&route->dest, dest, 0);
|
2020-06-25 20:37:12 -04:00
|
|
|
}
|
|
|
|
|
2020-08-24 22:56:38 -05:00
|
|
|
for (i=0; i<hops; i++) {
|
|
|
|
patty_ax25_addr_copy(&route->repeaters, &repeaters[i], 0);
|
|
|
|
}
|
2020-06-25 20:37:12 -04:00
|
|
|
|
|
|
|
return route;
|
|
|
|
|
|
|
|
error_malloc_route:
|
2020-08-24 22:56:38 -05:00
|
|
|
error_max_hops:
|
2020-06-25 20:37:12 -04:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
patty_ax25_route *patty_ax25_route_new_default(patty_ax25_if *iface) {
|
2020-08-24 22:56:38 -05:00
|
|
|
return patty_ax25_route_new(iface, NULL, NULL, 0);
|
2020-06-25 20:37:12 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
patty_ax25_route_table *patty_ax25_route_table_new() {
|
|
|
|
return patty_dict_new();
|
|
|
|
}
|
|
|
|
|
2020-06-25 22:20:39 -04:00
|
|
|
void patty_ax25_route_table_destroy(patty_ax25_route_table *table) {
|
|
|
|
patty_dict_destroy(table);
|
|
|
|
}
|
|
|
|
|
2020-06-25 20:37:12 -04:00
|
|
|
patty_ax25_route *patty_ax25_route_table_find(patty_ax25_route_table *table,
|
|
|
|
patty_ax25_addr *dest) {
|
2020-06-26 22:44:19 -04:00
|
|
|
patty_ax25_route *route;
|
2020-06-25 20:37:12 -04:00
|
|
|
uint32_t hash;
|
|
|
|
|
|
|
|
patty_hash_init(&hash);
|
|
|
|
patty_ax25_addr_hash(&hash, dest);
|
|
|
|
patty_hash_end(&hash);
|
|
|
|
|
2020-07-08 17:12:40 -04:00
|
|
|
route = patty_dict_get(table, hash);
|
2020-06-26 22:44:19 -04:00
|
|
|
|
|
|
|
if (route) {
|
|
|
|
return route;
|
|
|
|
}
|
|
|
|
|
|
|
|
return patty_ax25_route_table_default(table);
|
|
|
|
}
|
|
|
|
|
|
|
|
patty_ax25_route *patty_ax25_route_table_default(patty_ax25_route_table *table) {
|
|
|
|
patty_ax25_addr empty;
|
|
|
|
|
|
|
|
uint32_t hash;
|
|
|
|
|
|
|
|
memset(&empty, '\0', sizeof(empty));
|
|
|
|
|
|
|
|
patty_hash_init(&hash);
|
|
|
|
patty_ax25_addr_hash(&hash, &empty);
|
|
|
|
patty_hash_end(&hash);
|
|
|
|
|
2020-07-08 17:12:40 -04:00
|
|
|
return patty_dict_get(table, hash);
|
2020-06-25 20:37:12 -04:00
|
|
|
}
|
|
|
|
|
2020-08-24 22:56:38 -05:00
|
|
|
struct dict_ctx_wrapper {
|
|
|
|
int (*callback)(patty_ax25_route *route, void *);
|
|
|
|
void *ctx;
|
|
|
|
};
|
|
|
|
|
|
|
|
static int each_dict_callback(uint32_t key, void *value, void *ctx) {
|
|
|
|
struct dict_ctx_wrapper *wrapper = ctx;
|
|
|
|
|
|
|
|
return wrapper->callback(value, wrapper->ctx);
|
|
|
|
}
|
|
|
|
|
|
|
|
int patty_ax25_route_table_each(patty_ax25_route_table *table,
|
|
|
|
int (*callback)(patty_ax25_route *, void *),
|
|
|
|
void *ctx) {
|
|
|
|
struct dict_ctx_wrapper wrapper = {
|
|
|
|
.callback = callback,
|
|
|
|
.ctx = ctx
|
|
|
|
};
|
|
|
|
|
|
|
|
return patty_dict_each(table, each_dict_callback, &wrapper);
|
|
|
|
}
|
|
|
|
|
2020-06-25 20:37:12 -04:00
|
|
|
int patty_ax25_route_table_add(patty_ax25_route_table *table,
|
|
|
|
patty_ax25_route *route) {
|
|
|
|
uint32_t hash;
|
|
|
|
|
|
|
|
patty_hash_init(&hash);
|
|
|
|
patty_ax25_addr_hash(&hash, &route->dest);
|
|
|
|
patty_hash_end(&hash);
|
|
|
|
|
|
|
|
if (patty_ax25_route_table_find(table, &route->dest) != NULL) {
|
|
|
|
errno = EEXIST;
|
|
|
|
|
|
|
|
goto error_exists;
|
|
|
|
}
|
|
|
|
|
2020-07-08 17:12:40 -04:00
|
|
|
if (patty_dict_set(table, hash, route) == NULL) {
|
|
|
|
goto error_dict_set;
|
2020-06-25 20:37:12 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
2020-07-08 17:12:40 -04:00
|
|
|
error_dict_set:
|
2020-06-25 20:37:12 -04:00
|
|
|
error_exists:
|
|
|
|
return -1;
|
|
|
|
}
|
2020-06-25 23:36:13 -04:00
|
|
|
|
|
|
|
int patty_ax25_route_table_delete(patty_ax25_route_table *route,
|
|
|
|
patty_ax25_addr *dest) {
|
|
|
|
uint32_t hash;
|
|
|
|
|
|
|
|
patty_hash_init(&hash);
|
|
|
|
patty_ax25_addr_hash(&hash, dest);
|
|
|
|
patty_hash_end(&hash);
|
|
|
|
|
2020-07-08 17:12:40 -04:00
|
|
|
return patty_dict_delete(route, hash);
|
2020-06-25 23:36:13 -04:00
|
|
|
}
|