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:
parent
f41ce994f4
commit
222e51100e
7 changed files with 141 additions and 78 deletions
|
@ -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,
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
153
src/ax25.c
153
src/ax25.c
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
23
src/if.c
23
src/if.c
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
12
src/route.c
12
src/route.c
|
@ -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;
|
||||
|
|
Loading…
Add table
Reference in a new issue