Implement SSID suffix stringes in pton()/ntop()

Implement SSID suffix stringes in pton()/ntop() to make it more
straightforward to specify addresses to bind, connect to, or add routes
for

Changes:

    * Implement SSID suffix string formatting in patty_ax25_ntop(); drop
      the 'ssid' pointer argument

    * Implement SSID suffix string parsing in patty_ax25_pton(); drop
      the 'ssid' argument

    * Change all calls to patty_ax25_ntop() and patty_ax25_pton() to use
      their new calling convention
This commit is contained in:
XANTRONIX Development 2020-08-22 13:31:04 -05:00 committed by XANTRONIX Industrial
parent f41ce994f4
commit 222e51100e
7 changed files with 141 additions and 78 deletions

View file

@ -9,8 +9,8 @@
#include <patty/list.h>
#include <patty/dict.h>
#define PATTY_AX25_ADDR_SIZE 7
#define PATTY_AX25_CALLSIGN_LEN 6
#define PATTY_AX25_ADDRESS_LEN (PATTY_AX25_CALLSIGN_LEN + 3)
#define PATTY_AX25_IF_NAME_SIZE 8
#define PATTY_AX25_MAX_HOPS 8
#define PATTY_AX25_SOCK_PATH_SIZE 256
@ -124,12 +124,10 @@ typedef struct _patty_ax25_if patty_ax25_if;
((c & 0x80) == 0x80)
int patty_ax25_pton(const char *callsign,
uint8_t ssid,
patty_ax25_addr *addr);
int patty_ax25_ntop(const patty_ax25_addr *addr,
char *dest,
uint8_t *ssid,
size_t len);
void patty_ax25_addr_hash(uint32_t *hash,

View file

@ -13,14 +13,12 @@ typedef struct _patty_ax25_route {
typedef struct _patty_dict patty_ax25_route_table;
patty_ax25_route *patty_ax25_route_new(patty_ax25_if *iface,
const char *callsign,
uint8_t ssid);
const char *callsign);
patty_ax25_route *patty_ax25_route_new_default(patty_ax25_if *iface);
int patty_ax25_route_add_hop(patty_ax25_route *route,
const char *callsign,
uint8_t ssid);
const char *callsign);
patty_ax25_route_table *patty_ax25_route_table_new();

View file

@ -5,30 +5,78 @@
#include <patty/ax25.h>
enum addr_state {
ADDR_NONE,
ADDR_CALLSIGN,
ADDR_SSID
};
int patty_ax25_pton(const char *callsign,
uint8_t ssid,
patty_ax25_addr *addr) {
size_t len = strlen(callsign),
max = PATTY_AX25_CALLSIGN_LEN + 3; /* Account for SSID suffixes */
int i,
end = 0;
o = 0,
digits = 0;
for (i=0; i<PATTY_AX25_CALLSIGN_LEN; i++) {
if (callsign[i] == '\0') {
if (i == 0) {
errno = EINVAL;
int ssid = 0;
enum addr_state state = ADDR_NONE;
if (len == 0) {
goto error_invalid_callsign;
} else if (len > max) {
len = max;
}
end = 1;
for (i=0; i<len; i++) {
uint8_t c = callsign[i];
switch (state) {
case ADDR_NONE:
if ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z')) {
state = ADDR_CALLSIGN;
addr->callsign[o++] = (c & 0x7f) << 1;
} else {
if (!PATTY_AX25_ADDR_CHAR_VALID(callsign[i])) {
errno = EINVAL;
goto error_invalid_callsign;
}
break;
case ADDR_CALLSIGN:
if (o > PATTY_AX25_CALLSIGN_LEN) {
goto error_invalid_callsign;
}
if ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z')) {
addr->callsign[o++] = (c & 0x7f) << 1;
} else if (c == '-') {
state = ADDR_SSID;
} else {
goto error_invalid_callsign;
}
break;
case ADDR_SSID:
if (digits >= 2) {
goto error_invalid_callsign;
}
if (c >= '0' && c <= '9') {
ssid *= 10;
ssid += c - '0';
digits++;
} else {
goto error_invalid_callsign;
}
}
}
addr->callsign[i] = ((end? ' ': callsign[i]) & 0x7f) << 1;
while (o < PATTY_AX25_CALLSIGN_LEN) {
addr->callsign[o++] = ' ';
}
addr->ssid = (ssid & 0x0f) << 1;
@ -36,58 +84,85 @@ int patty_ax25_pton(const char *callsign,
return 0;
error_invalid_callsign:
errno = EINVAL;
return -1;
}
static inline int expt(int base, int e) {
int ret;
if (e == 0) {
return 1;
}
ret = base;
while (--e) {
ret *= ret;
}
return ret;
}
int patty_ax25_ntop(const patty_ax25_addr *addr,
char *dest,
uint8_t *ssid,
size_t len) {
int i, o, space = 0;
int i,
o = 0;
if (addr == NULL || dest == NULL || ssid == NULL) {
errno = EINVAL;
int ssid = (addr->ssid & 0x1e) >> 1;
goto error_invalid_args;
}
for (i=0, o=0; i<PATTY_AX25_CALLSIGN_LEN; i++) {
for (i=0; i<PATTY_AX25_CALLSIGN_LEN; i++) {
uint8_t c;
if (o == len) {
break;
}
if (PATTY_AX25_ADDR_OCTET_LAST(addr->callsign[i])) {
errno = EINVAL;
goto error_invalid_args;
goto error_overflow;
}
c = (addr->callsign[i] & 0xfe) >> 1;
if (!PATTY_AX25_ADDR_CHAR_VALID(c)) {
errno = EINVAL;
goto error_invalid_args;
} else if (c == ' ' && !space) {
space = 1;
} else if (c != ' ' && space) {
errno = EINVAL;
goto error_invalid_args;
if (c == ' ') {
break;
}
dest[o++] = space? '\0': c;
dest[o++] = c;
}
if (ssid) {
int place = 2;
if (o == len) {
goto error_overflow;
}
dest[o++] = '-';
while (place--) {
int div = expt(10, place),
num = ssid / div;
if (num) {
if (o == len) {
goto error_overflow;
}
dest[o++] = '0' + num;
}
}
}
if (o == len) {
goto error_overflow;
}
dest[o] = '\0';
*ssid = (addr->ssid & 0x1e) >> 1;
return 0;
error_invalid_args:
error_overflow:
errno = EOVERFLOW;
return -1;
}

View file

@ -38,7 +38,7 @@ static ssize_t decode_station(patty_ax25_addr *addr,
memcpy(addr, ((uint8_t *)data) + offset, sizeof(*addr));
return PATTY_AX25_ADDR_SIZE;
return sizeof(patty_ax25_addr);
error:
return -1;

View file

@ -135,10 +135,9 @@ int patty_ax25_if_addr_each(patty_ax25_if *iface,
int (*callback)(char *, void *), void *ctx) {
patty_list_item *item = iface->aliases->first;
char buf[7];
uint8_t ssid;
char buf[PATTY_AX25_ADDRESS_LEN+1];
if (patty_ax25_ntop(&iface->addr, buf, &ssid, sizeof(buf)) < 0) {
if (patty_ax25_ntop(&iface->addr, buf, sizeof(buf)) < 0) {
goto error_ntop_addr;
}
@ -149,7 +148,7 @@ int patty_ax25_if_addr_each(patty_ax25_if *iface,
while (item) {
patty_ax25_addr *addr = item->value;
if (patty_ax25_ntop(addr, buf, &ssid, sizeof(buf)) < 0) {
if (patty_ax25_ntop(addr, buf, sizeof(buf)) < 0) {
goto error_ntop;
}
@ -173,10 +172,9 @@ static patty_ax25_addr *find_addr(patty_ax25_if *iface,
const char *callsign) {
patty_list_item *item = iface->aliases->first;
char buf[7];
uint8_t ssid;
char buf[PATTY_AX25_ADDRESS_LEN+1];
if (patty_ax25_ntop(&iface->addr, buf, &ssid, sizeof(buf)) < 0) {
if (patty_ax25_ntop(&iface->addr, buf, sizeof(buf)) < 0) {
goto error_ntop_addr;
}
@ -187,7 +185,7 @@ static patty_ax25_addr *find_addr(patty_ax25_if *iface,
while (item) {
patty_ax25_addr *addr = item->value;
if (patty_ax25_ntop(addr, buf, &ssid, sizeof(buf)) < 0) {
if (patty_ax25_ntop(addr, buf, sizeof(buf)) < 0) {
goto error_ntop;
}
@ -219,10 +217,12 @@ int patty_ax25_if_addr_add(patty_ax25_if *iface,
goto error_malloc_addr;
}
if (patty_ax25_pton(callsign, 0, addr) < 0) {
if (patty_ax25_pton(callsign, addr) < 0) {
goto error_pton;
}
addr->ssid = 0;
if ((patty_list_append(iface->aliases, addr)) == NULL) {
goto error_list_append;
}
@ -244,12 +244,11 @@ int patty_ax25_if_addr_delete(patty_ax25_if *iface,
int i = 0;
while (item) {
char buf[7];
uint8_t ssid;
char buf[PATTY_AX25_ADDRESS_LEN+1];
patty_ax25_addr *addr = item->value;
if (patty_ax25_ntop(addr, buf, &ssid, sizeof(buf)) < 0) {
if (patty_ax25_ntop(addr, buf, sizeof(buf)) < 0) {
goto error_ntop;
}

View file

@ -44,19 +44,14 @@ static char *frame_cr(enum patty_ax25_frame_cr cr) {
}
static int print_addr(FILE *fh, const patty_ax25_addr *addr) {
char buf[7];
uint8_t ssid;
char buf[PATTY_AX25_ADDRESS_LEN];
if (patty_ax25_ntop(addr, buf, &ssid, sizeof(buf)) < 0) {
if (patty_ax25_ntop(addr, buf, sizeof(buf)) < 0) {
goto error_ntop;
}
fprintf(fh, "%s", buf);
if (ssid) {
fprintf(fh, "-%d", (int)ssid);
}
return 0;
error_ntop:

View file

@ -8,8 +8,7 @@
#include <patty/ax25.h>
patty_ax25_route *patty_ax25_route_new(patty_ax25_if *iface,
const char *callsign,
uint8_t ssid) {
const char *callsign) {
patty_ax25_route *route;
if ((route = malloc(sizeof(*route))) == NULL) {
@ -19,7 +18,7 @@ patty_ax25_route *patty_ax25_route_new(patty_ax25_if *iface,
memset(route, '\0', sizeof(*route));
if (callsign) {
if (patty_ax25_pton(callsign, ssid, &route->dest) < 0) {
if (patty_ax25_pton(callsign, &route->dest) < 0) {
goto error_pton;
}
}
@ -36,19 +35,18 @@ error_malloc_route:
}
patty_ax25_route *patty_ax25_route_new_default(patty_ax25_if *iface) {
return patty_ax25_route_new(iface, NULL, 0);
return patty_ax25_route_new(iface, NULL);
}
int patty_ax25_route_add_hop(patty_ax25_route *route,
const char *callsign,
uint8_t ssid) {
const char *callsign) {
if (route->nhops == PATTY_AX25_MAX_HOPS) {
errno = ENOMEM;
goto error_max_hops;
}
return patty_ax25_pton(callsign, ssid, &route->hops[route->nhops++]);
return patty_ax25_pton(callsign, &route->hops[route->nhops++]);
error_max_hops:
return -1;