diff --git a/include/patty/ax25.h b/include/patty/ax25.h index 596f271..be6006b 100644 --- a/include/patty/ax25.h +++ b/include/patty/ax25.h @@ -9,8 +9,8 @@ #include #include -#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, diff --git a/include/patty/ax25/route.h b/include/patty/ax25/route.h index 8d38ed6..5935e5a 100644 --- a/include/patty/ax25/route.h +++ b/include/patty/ax25/route.h @@ -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(); diff --git a/src/ax25.c b/src/ax25.c index e51499e..f123537 100644 --- a/src/ax25.c +++ b/src/ax25.c @@ -5,30 +5,78 @@ #include +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 max) { + len = max; + } - goto error_invalid_callsign; - } + for (i=0; i= '0' && c <= '9') || (c >= 'A' && c <= 'Z')) { + state = ADDR_CALLSIGN; + addr->callsign[o++] = (c & 0x7f) << 1; + } else { + 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; icallsign[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; } diff --git a/src/frame.c b/src/frame.c index e532ffa..9eada96 100644 --- a/src/frame.c +++ b/src/frame.c @@ -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; diff --git a/src/if.c b/src/if.c index 0a3a440..68a10e9 100644 --- a/src/if.c +++ b/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; } diff --git a/src/print.c b/src/print.c index 25314f1..0f7393c 100644 --- a/src/print.c +++ b/src/print.c @@ -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: diff --git a/src/route.c b/src/route.c index ca09d02..d405aff 100644 --- a/src/route.c +++ b/src/route.c @@ -8,8 +8,7 @@ #include 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;