From a8db220bbdaf1b131c4b2c67a288651a7251a911 Mon Sep 17 00:00:00 2001 From: XANTRONIX Development Date: Sun, 7 Jun 2020 02:46:12 -0400 Subject: [PATCH] Major refactor WIP --- include/patty/ax25.h | 81 +++++---- include/patty/ax25/address.h | 26 --- include/patty/ax25/frame.h | 10 +- include/patty/ax25/if.h | 31 ++-- include/patty/dict.h | 8 + src/Makefile | 4 +- src/address.c | 30 ---- src/ax25.c | 334 +++++++++++++++++++++++++---------- src/decode.c | 18 +- src/dict.c | 16 +- src/frame.c | 64 +++---- src/hash.c | 2 +- src/if.c | 106 +++++++---- src/iflist.c | 12 +- 14 files changed, 438 insertions(+), 304 deletions(-) delete mode 100644 include/patty/ax25/address.h delete mode 100644 src/address.c diff --git a/include/patty/ax25.h b/include/patty/ax25.h index b3b6af6..b6daa20 100644 --- a/include/patty/ax25.h +++ b/include/patty/ax25.h @@ -8,26 +8,29 @@ #include #include -typedef struct _patty_ax25 patty_ax25; +#pragma pack(push) +#pragma pack(1) + +typedef struct _patty_ax25_addr { + uint8_t callsign[6]; + uint8_t ssid; +} patty_ax25_addr; + +#pragma pack(pop) + +typedef struct _patty_ax25 patty_ax25; +typedef struct _patty_ax25_if patty_ax25_if; #include #include -#include #include #include -#define PATTY_AX25_EVENT_QUEUE_SIZE 32 - -enum patty_ax25_event_type { - PATTY_AX25_EVENT_UNKNOWN, - PATTY_AX25_EVENT_RECV, - PATTY_AX25_EVENT_SEND, - PATTY_AX25_EVENT_READ, - PATTY_AX25_EVENT_WRITE, - PATTY_AX25_EVENT_ERROR -}; +#define PATTY_AX25_ADDRESS_SIZE 7 +#define PATTY_AX25_CALLSIGN_LEN 6 enum patty_ax25_sock_status { + PATTY_AX25_SOCK_CLOSED, PATTY_AX25_SOCK_OPEN, PATTY_AX25_SOCK_LISTENING, PATTY_AX25_SOCK_ESTABLISHED @@ -59,57 +62,67 @@ typedef struct _patty_ax25_sock { unsigned int seq_send, seq_recv; + int fd; + patty_ax25_if *iface; - patty_ax25_address *local, - *remote; + patty_ax25_addr local, + remote, + repeaters[PATTY_AX25_MAX_HOPS]; + + unsigned int hops; } patty_ax25_sock; -typedef struct _patty_ax25_event { - enum patty_ax25_event_type type; - patty_ax25_sock * sock; -} patty_ax25_event; - typedef struct _patty_ax25 { - patty_list *ifaces, - *socks; + patty_list *ifaces; + + patty_dict *socks, + *socks_by_addrpair; int fd, - current, fdmax; fd_set fds, - fds_pending_read, - fds_pending_write, - fds_pending_error; - - patty_dict * fd_lookup; + fds_r, + fds_w; } patty_ax25; int patty_ax25_init(patty_ax25 *ax25); void patty_ax25_stop(patty_ax25 *ax25); +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); + int patty_ax25_open(patty_ax25 *ax25, const char *ifname); int patty_ax25_socket(patty_ax25 *ax25); int patty_ax25_bind(patty_ax25 *ax25, - int socket, const char *callsign, int ssid); + int socket, + const char *callsign, + uint8_t ssid); int patty_ax25_listen(patty_ax25 *ax25, - int socket, const char *callsign, int ssid); + int socket); int patty_ax25_connect(patty_ax25 *ax25, - int socket, const char *callsign, int ssid); + int socket, + const char *callsign, + uint8_t ssid); -int patty_ax25_accept(patty_ax25 *ax25, - int socket); +int patty_ax25_accept(patty_ax25 *ax25, int socket); int patty_ax25_close(patty_ax25 *ax25, int fd); -int patty_ax25_next_event(patty_ax25 *ax25, - patty_ax25_event *ev); +/*int patty_ax25_next_event(patty_ax25 *ax25, + patty_ax25_event *ev);*/ int patty_ax25_recv(patty_ax25 *ax25, int fd, patty_ax25_frame *frame); diff --git a/include/patty/ax25/address.h b/include/patty/ax25/address.h deleted file mode 100644 index 14f0af2..0000000 --- a/include/patty/ax25/address.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef _PATTY_AX25_ADDRESS_H -#define _PATTY_AX25_ADDRESS_H - -#include -#include - -#define PATTY_AX25_ADDRESS_CALLSIGN_LEN 6 -#define PATTY_AX25_ADDRESS_SIZE 7 - -typedef struct _patty_ax25_address { - char callsign[7]; - - uint8_t ssid, - last; - - union { - uint8_t c, - repeated; - }; -} patty_ax25_address; - -patty_ax25_address *patty_ax25_address_create(const char *callsign, int ssid); - -void patty_ax25_address_destroy(patty_ax25_address *address); - -#endif /* _PATTY_AX25_ADDRESS_H */ diff --git a/include/patty/ax25/frame.h b/include/patty/ax25/frame.h index bbfba29..5be08a9 100644 --- a/include/patty/ax25/frame.h +++ b/include/patty/ax25/frame.h @@ -20,11 +20,11 @@ enum patty_ax25_frame_cr { }; typedef struct _patty_ax25_frame { - patty_ax25_address dest; - patty_ax25_address src; - patty_ax25_address repeaters[7]; + patty_ax25_addr dest, + src, + repeaters[7]; - uint8_t hops; + unsigned int hops; enum patty_ax25_version version; enum patty_ax25_frame_type type; @@ -45,7 +45,7 @@ ssize_t patty_ax25_frame_info(patty_ax25_frame *frame, void **info); int patty_ax25_frame_addresed_to(patty_ax25_frame *frame, - char *station, + const char *callsign, uint8_t ssid); #endif /* _PATTY_AX25_FRAME_H */ diff --git a/include/patty/ax25/if.h b/include/patty/ax25/if.h index 84f5a03..fa18a3c 100644 --- a/include/patty/ax25/if.h +++ b/include/patty/ax25/if.h @@ -12,12 +12,9 @@ ((n) & PATTY_AX25_IF_OPT_TYPE_MASK) enum patty_ax25_if_type { - PATTY_AX25_IF_UNKNOWN = 0x00, - PATTY_AX25_IF_KISS_TNC_TTY = 0x01, - PATTY_AX25_IF_KISS_TNC_PORT = 0x02, - PATTY_AX25_IF_KISS_TNC_I2C = 0x04, - PATTY_AX25_IF_KISS_TNC_SPI = 0x08, - PATTY_AX25_IF_SOFT_TNC = 0x10 + PATTY_AX25_IF_UNKNOWN, + PATTY_AX25_IF_KISS_TNC, + PATTY_AX25_IF_HDLC }; typedef struct _patty_ax25_if_stats { @@ -29,31 +26,31 @@ typedef struct _patty_ax25_if_stats { } patty_ax25_if_stats; typedef struct _patty_ax25_if { - enum patty_ax25_if_type type; - patty_ax25_if_stats stats; + enum patty_ax25_if_type type; + patty_ax25_if_stats stats; char name[8]; - patty_kiss_tnc * tnc; - patty_list * addresses; + patty_kiss_tnc *tnc; + patty_list *addrs; } patty_ax25_if; patty_ax25_if *patty_ax25_if_create(int opts, void *info); void patty_ax25_if_destroy(patty_ax25_if *iface); -int patty_ax25_if_each_address(patty_ax25_if *iface, - int (*callback)(patty_ax25_address *, void *), void *ctx); +int patty_ax25_if_each_addr(patty_ax25_if *iface, + int (*callback)(char *, uint8_t, void *), void *ctx); -int patty_ax25_if_add_address(patty_ax25_if *iface, - const char *callsign, int ssid); +int patty_ax25_if_add_addr(patty_ax25_if *iface, + const char *callsign, uint8_t ssid); -int patty_ax25_if_delete_address(patty_ax25_if *iface, - const char *callsign, int ssid); +int patty_ax25_if_delete_addr(patty_ax25_if *iface, + const char *callsign, uint8_t ssid); patty_ax25_if *patty_ax25_get_if(patty_ax25 *ax25, const char *name); -int patty_ax25_each_if(patty_ax25 *ax25, +int patty_ax25_if_each(patty_ax25 *ax25, int (*callback)(patty_ax25_if *, void *), void *ctx); int patty_ax25_add_if(patty_ax25 *ax25, patty_ax25_if *iface); diff --git a/include/patty/dict.h b/include/patty/dict.h index 5588526..6dd3039 100644 --- a/include/patty/dict.h +++ b/include/patty/dict.h @@ -39,8 +39,16 @@ int patty_dict_each(patty_dict *dict, patty_dict_callback callback, void *ctx); void *patty_dict_get(patty_dict *dict, void *key, size_t keysz); +void *patty_dict_set_with_hash(patty_dict *dict, + void *key, + size_t keysz, + void *value, + uint32_t hash); + void *patty_dict_set(patty_dict *dict, void *key, size_t keysz, void *value); +void *patty_dict_delete_with_hash(patty_dict *dict, void *key, size_t keysz); + void *patty_dict_delete(patty_dict *dict, void *key, size_t keysz); void patty_dict_destroy(patty_dict *dict); diff --git a/src/Makefile b/src/Makefile index f1585e1..3d50136 100644 --- a/src/Makefile +++ b/src/Makefile @@ -8,9 +8,9 @@ CFLAGS = $(CGFLAGS) -fPIC -Wall -O2 -I$(INCLUDE_PATH) LDFLAGS = HEADERS = kiss.h ax25.h ax25/if.h ax25/macros.h ax25/proto.h \ - ax25/address.h ax25/frame.h list.h hash.h dict.h + ax25/frame.h list.h hash.h dict.h -OBJS = kiss.o ax25.o if.o address.o frame.o \ +OBJS = kiss.o ax25.o if.o frame.o \ list.o hash.o dict.o EXAMPLES = iflist decode ptmx diff --git a/src/address.c b/src/address.c deleted file mode 100644 index d919b2d..0000000 --- a/src/address.c +++ /dev/null @@ -1,30 +0,0 @@ -#include -#include -#include - -#include - -patty_ax25_address *patty_ax25_address_create(const char *callsign, int ssid) { - patty_ax25_address *addr; - - if ((addr = malloc(sizeof(*addr))) == NULL) { - goto error_malloc_addr; - } - - memset(addr, '\0', sizeof(*addr)); - - memcpy(addr->callsign, callsign, sizeof(addr->callsign)); - - addr->ssid = ssid; - addr->last = 0; - addr->c = 0; - - return addr; - -error_malloc_addr: - return NULL; -} - -void patty_ax25_address_destroy(patty_ax25_address *address) { - free(address); -} diff --git a/src/ax25.c b/src/ax25.c index 6dbdb3f..0606c55 100644 --- a/src/ax25.c +++ b/src/ax25.c @@ -13,20 +13,20 @@ int patty_ax25_init(patty_ax25 *ax25) { goto error_list_new_ifaces; } - if ((ax25->socks = patty_list_new()) == NULL) { - goto error_list_new_socks; + if ((ax25->socks = patty_dict_new()) == NULL) { + goto error_dict_new_socks; } - if ((ax25->fd_lookup = patty_dict_new()) == NULL) { - goto error_dict_new_fd_lookup; + if ((ax25->socks_by_addrpair = patty_dict_new()) == NULL) { + goto error_dict_new_socks_by_addrpair; } return 0; -error_dict_new_fd_lookup: - patty_list_destroy(ax25->socks); +error_dict_new_socks_by_addrpair: + patty_dict_destroy(ax25->socks); -error_list_new_socks: +error_dict_new_socks: patty_list_destroy(ax25->ifaces); error_list_new_ifaces: @@ -40,34 +40,113 @@ static int destroy_if(patty_ax25_if *iface, void *ctx) { } void patty_ax25_stop(patty_ax25 *ax25) { - patty_dict_destroy(ax25->fd_lookup); - patty_list_destroy(ax25->socks); + patty_dict_destroy(ax25->socks_by_addrpair); + patty_dict_destroy(ax25->socks); - patty_ax25_each_if(ax25, destroy_if, NULL); + patty_ax25_if_each(ax25, destroy_if, NULL); patty_list_destroy(ax25->ifaces); } -static void *fd_lookup(patty_ax25 *ax25, int fd) { - void *obj; +static patty_ax25_sock *sock_by_fd(patty_ax25 *ax25, int fd) { + patty_ax25_sock *sock; - if ((obj = patty_dict_get(ax25->fd_lookup, &fd, sizeof(fd))) == NULL) { + if ((sock = patty_dict_get(ax25->socks, &fd, sizeof(fd))) == NULL) { errno = EBADF; goto error_dict_get; } - return obj; + return sock; error_dict_get: return NULL; } -static int fd_store(patty_ax25 *ax25, patty_ax25_sock *sock) { - if (patty_dict_set(ax25->fd_lookup, &ax25->fd, sizeof(ax25->fd), sock) == NULL) { +static inline void hash_init(uint32_t *hash) { + *hash = 0xffffffdf; +} + +static inline void hash_byte(uint32_t *hash, uint8_t c) { + *hash += c; + *hash += (*hash << 10); + *hash ^= (*hash >> 6); +} + +static inline void hash_addr(uint32_t *hash, patty_ax25_addr *addr) { + int i; + + for (i=0; icallsign[i] >> 1); + } + + hash_byte(hash, PATTY_AX25_ADDRESS_SSID_NUMBER(addr->ssid)); +} + +static inline void hash_end(uint32_t *hash) { + *hash += (*hash << 3); + *hash ^= (*hash >> 11); + *hash += (*hash << 15); +} + +static uint32_t hash_addrpair(patty_ax25_addr *local, + patty_ax25_addr *remote) { + uint32_t hash; + + hash_init(&hash); + + hash_addr(&hash, local); + hash_addr(&hash, remote); + + hash_end(&hash); + + return hash; +} + +static patty_ax25_sock *sock_get_fd(patty_ax25 *ax25, + int fd) { + return patty_dict_get(ax25->socks, + fd, + sizeof(fd)); +} + +static patty_ax25_sock *sock_get_addrpair(patty_ax25 *ax25, + patty_ax25_addr *local, + patty_ax25_addr *remote) { + patty_dict_slot *slot; + + uint32_t hash = hash_addrpair(local, remote); + + if ((slot = patty_dict_slot_find(ax25->socks_by_addrpair, hash)) == NULL) { + errno = EBADF; + + goto error_dict_slot_find; + } + + return (patty_ax25_sock *)slot->value; + +error_dict_slot_find: + return NULL; +} + +static int sock_save(patty_ax25 *ax25, patty_ax25_sock *sock) { + uint32_t hash = hash_addrpair(&sock->local, &sock->remote); + + if (patty_dict_set(ax25->socks, + sock->fd, + sizeof(sock->fd), + sock) == NULL) { goto error_dict_set; } - return ax25->fd++; + if (patty_dict_set_with_hash(ax25->socks_by_addrpair, + sock->fd, + sizeof(sock->fd), + sock, + hash) == NULL) { + goto error_dict_set; + } + + return sock->fd; error_dict_set: return -1; @@ -84,7 +163,6 @@ static void sock_init(patty_ax25_sock *sock) { int patty_ax25_socket(patty_ax25 *ax25) { patty_ax25_sock *sock; - int fd; if ((sock = malloc(sizeof(*sock))) == NULL) { goto error_malloc_sock; @@ -92,19 +170,107 @@ int patty_ax25_socket(patty_ax25 *ax25) { sock_init(sock); - if ((fd = fd_store(ax25, sock)) < 0) { - goto error_fd_store; + sock->fd = ax25->fd++; + + if (sock_save(ax25, sock) < 0) { + goto error_sock_save; } - return fd; + return sock->fd; -error_fd_store: +error_sock_save: free(sock); error_malloc_sock: return -1; } +int patty_ax25_pton(const char *callsign, + uint8_t ssid, + patty_ax25_addr *addr) { + int i, + end = 0; + + for (i=0; icallsign[i] = ((end? ' ': callsign[i]) & 0x7f) << 1; + } + + addr->ssid = (ssid & 0x0f) << 1; + + return 0; + +error_invalid_callsign: + return -1; +} + +int patty_ax25_ntop(const patty_ax25_addr *addr, + char *dest, + uint8_t *ssid, + size_t len) { + int i, o, space = 0; + + if (addr == NULL || dest == NULL || ssid == NULL) { + errno = EINVAL; + + goto error_invalid_args; + } + + for (i=0, o=0; icallsign[i])) { + errno = EINVAL; + + goto error_invalid_args; + } + + c = (addr->callsign[i] & 0xfe) >> 1; + + if (!PATTY_AX25_ADDRESS_CHAR_VALID(c)) { + errno = EINVAL; + + goto error_invalid_args; + } else if (c == ' ' && !space) { + space = 1; + } else if (space) { + errno = EINVAL; + + goto error_invalid_args; + } + + dest[o++] = c; + } + + dest[o] = '\0'; + + *ssid = (addr->ssid & 0x1e) >> 1; + + return 0; + +error_invalid_args: + return -1; +} + int patty_ax25_open(patty_ax25 *ax25, const char *ifname) { patty_ax25_sock *sock; @@ -118,7 +284,7 @@ int patty_ax25_open(patty_ax25 *ax25, const char *ifname) { goto error_get_if; } - return fd_store(ax25, sock); + return sock_save(ax25, sock); error_get_if: free(sock); @@ -127,113 +293,87 @@ error_malloc_sock: return -1; } -int patty_ax25_bind(patty_ax25 *ax25, int socket, const char *callsign, int ssid) { +int patty_ax25_bind(patty_ax25 *ax25, + int socket, + const char *callsign, + uint8_t ssid) { patty_ax25_sock *sock; - if ((sock = fd_lookup(ax25, socket)) == NULL) { - goto error_fd_lookup; + if ((sock = sock_get_fd(ax25, socket)) == NULL) { + goto error_sock_get_fd; } /* * If there is already a local address associated with this socket, then * that's a problem. */ - if (sock->local != NULL) { - errno = EEXIST; + if (sock->local.callsign[0] != '\0') { + errno = EADDRINUSE; goto error_exists; } - if ((sock->local = patty_ax25_address_create(callsign, ssid)) == NULL) { - goto error_address_create; + if (patty_ax25_pton(callsign, ssid, &sock->local) < 0) { + goto error_pton; } return 0; -error_address_create: +error_pton: error_exists: -error_fd_lookup: +error_sock_get_fd: return -1; } -int patty_ax25_listen(patty_ax25 *ax25, int socket, const char *callsign, int ssid) { - /* - * Stub - */ - return patty_ax25_bind(ax25, socket, callsign, ssid); -} - -int patty_ax25_connect(patty_ax25 *ax25, int socket, const char *callsign, int ssid) { +int patty_ax25_listen(patty_ax25 *ax25, + int socket) { patty_ax25_sock *sock; - if ((sock = fd_lookup(ax25, socket)) == NULL) { - goto error_fd_lookup; + if ((sock = sock_get_fd(ax25, socket)) == NULL) { + errno = EBADF; + + goto error_sock_get_fd; } - if (sock->remote != NULL) { + if (sock->local.callsign[0] == '\0') { + errno = EINVAL; + + goto error_invalid_fd; + } + + errno = ENOSYS; + +error_invalid_fd: +error_sock_get_fd: + return -1; +} + +int patty_ax25_connect(patty_ax25 *ax25, + int socket, + const char *callsign, + uint8_t ssid) { + patty_ax25_sock *sock; + + if ((sock = sock_get_fd(ax25, socket)) == NULL) { + goto error_sock_get_fd; + } + + if (sock->remote.callsign[0] != '\0') { errno = EEXIST; goto error_exists; } - if ((sock->remote = patty_ax25_address_create(callsign, ssid)) == NULL) { - goto error_address_create; + if (patty_ax25_pton(callsign, ssid, &sock->remote) < 0) { + errno = EINVAL; + + goto error_pton; } return 0; -error_address_create: +error_pton: error_exists: -error_fd_lookup: - return -1; -} - -static int next_fd_event(patty_ax25 *ax25, enum patty_ax25_event_type *type) { - int fd; - - if (ax25->current == 0) { - memcpy(&ax25->fds_pending_read, &ax25->fds, sizeof(ax25->fds)); - memcpy(&ax25->fds_pending_write, &ax25->fds, sizeof(ax25->fds)); - memcpy(&ax25->fds_pending_error, &ax25->fds, sizeof(ax25->fds)); - - if (select(ax25->fdmax, - &ax25->fds_pending_read, - &ax25->fds_pending_write, - &ax25->fds_pending_error, NULL) < 0) { - goto error_select; - } - } - - for (fd=ax25->current; fdfdmax; fd++) { - if (FD_ISSET(fd, &ax25->fds_pending_read)) { - *type = PATTY_AX25_EVENT_RECV; - - FD_CLR(fd, &ax25->fds_pending_read); - - return fd; - } - - if (FD_ISSET(fd, &ax25->fds_pending_write)) { - *type = PATTY_AX25_EVENT_SEND; - - FD_CLR(fd, &ax25->fds_pending_write); - - return fd; - } - - if (FD_ISSET(fd, &ax25->fds_pending_error)) { - *type = PATTY_AX25_EVENT_ERROR; - - FD_CLR(fd, &ax25->fds_pending_error); - - return fd; - } - } - - ax25->current = 0; - - return 0; - -error_select: +error_sock_get_fd: return -1; } diff --git a/src/decode.c b/src/decode.c index 641e884..37c9217 100644 --- a/src/decode.c +++ b/src/decode.c @@ -22,14 +22,24 @@ static void usage(int argc, char **argv, const char *message, ...) { exit(1); } -static int callsign_fprint(FILE *stream, const patty_ax25_address *address) { - fprintf(stream, "%s", address->callsign); +static int callsign_fprint(FILE *stream, const patty_ax25_addr *addr) { + char buf[7]; + uint8_t ssid; - if (address->ssid) { - fprintf(stream, "/%d", address->ssid); + if (patty_ax25_ntop(addr, buf, &ssid, sizeof(buf)) < 0) { + goto error_ntop; + } + + fprintf(stream, "%s", buf); + + if (ssid) { + fprintf(stream, "/%d", ssid); } return 0; + +error_ntop: + return -1; } #define printable(c) \ diff --git a/src/dict.c b/src/dict.c index 188c840..0d0bb3c 100644 --- a/src/dict.c +++ b/src/dict.c @@ -108,11 +108,13 @@ void *patty_dict_get(patty_dict *dict, void *key, size_t keysz) { return slot->value; } -void *patty_dict_set(patty_dict *dict, void *key, size_t keysz, void *value) { +void *patty_dict_set_with_hash(patty_dict *dict, + void *key, + size_t keysz, + void *value, + uint32_t hash) { patty_dict_bucket *bucket = &dict->bucket; - uint32_t hash = patty_hash(key, keysz); - int collisions; for (collisions = 0; collisions < 7; collisions++) { @@ -164,6 +166,14 @@ error_malloc_bucket: return NULL; } +void *patty_dict_set(patty_dict *dict, void *key, size_t keysz, void *value) { + return patty_dict_set_with_hash(dict, + key, + keysz, + value, + patty_hash(key, keysz)); +} + void *patty_dict_delete(patty_dict *dict, void *key, size_t keysz) { patty_dict_slot *slot; void *value; diff --git a/src/frame.c b/src/frame.c index 209445f..1859118 100644 --- a/src/frame.c +++ b/src/frame.c @@ -3,17 +3,11 @@ #include -static ssize_t decode_station(patty_ax25_address *address, - void *data, - off_t offset) { +static ssize_t validate_station(void *data, + off_t offset) { int i, space = 0; - uint8_t ssid = ((uint8_t *)data + offset)[6]; - /* - * First, unpack each callsign octet, ensuring all are within the 7 bit - * ASCII space and do not have the extended bit set to 1. - */ - for (i=0; i> 1; @@ -23,36 +17,15 @@ static ssize_t decode_station(patty_ax25_address *address, goto error; } - if (c == ' ') { - /* - * Take note if we have reached the end of the call sign. - */ + if (c == ' ' && !space) { space = 1; + } else if (space) { + errno = EINVAL; - address->callsign[i] = '\0'; - } else { - /* - * If we have already reached the end of the callsign, and a - * non-space character is encountered, then the address is - * erroneous. - */ - if (space) { - errno = EINVAL; - - goto error; - } - - address->callsign[i] = c; + goto error; } } - /* - * Now, unpack the data from the SSID field. - */ - address->c = PATTY_AX25_ADDRESS_SSID_C(ssid); - address->ssid = PATTY_AX25_ADDRESS_SSID_NUMBER(ssid); - address->last = PATTY_AX25_ADDRESS_OCTET_LAST(ssid); - return PATTY_AX25_ADDRESS_SIZE; error: @@ -67,12 +40,16 @@ static ssize_t decode_hops(patty_ax25_frame *frame, int i; + patty_ax25_addr *addr = NULL; + /* - * Try to decode the AX.25-specified maximum number of hops in the current + * Try to count the AX.25-specified maximum number of hops in the current * frame. */ for (i=0; irepeaters[i], data, offset)) < 0) { + addr = (patty_ax25_addr *)((uint8_t *)data + offset); + + if ((decoded = validate_station(data, offset)) < 0) { goto error; } else { offset += decoded; @@ -80,7 +57,7 @@ static ssize_t decode_hops(patty_ax25_frame *frame, frame->hops++; - if (frame->repeaters[i].last) { + if (PATTY_AX25_ADDRESS_OCTET_LAST(addr->ssid)) { break; } } @@ -89,7 +66,7 @@ static ssize_t decode_hops(patty_ax25_frame *frame, * If the last hop does not have the address extension bit set, then * that's a big problem. */ - if (frame->hops && !frame->repeaters[frame->hops-1].last) { + if (addr && PATTY_AX25_ADDRESS_OCTET_LAST(addr->ssid)) { errno = EINVAL; goto error; @@ -107,13 +84,13 @@ static ssize_t decode_address(patty_ax25_frame *frame, off_t offset = start; ssize_t decoded; - if ((decoded = decode_station(&frame->dest, data, offset)) < 0) { + if ((decoded = validate_station(data, offset)) < 0) { goto error; } else { offset += decoded; } - if ((decoded = decode_station(&frame->src, data, offset)) < 0) { + if ((decoded = validate_station(data, offset)) < 0) { goto error; } else { offset += decoded; @@ -137,7 +114,7 @@ static ssize_t decode_address(patty_ax25_frame *frame, * If the source address is not the final address in the frame, begin * decoding repeater addresses. */ - if (!frame->src.last) { + if (!PATTY_AX25_ADDRESS_OCTET_LAST(frame->src.ssid)) { if ((decoded = decode_hops(frame, data, offset)) < 0) { goto error; } else { @@ -259,10 +236,11 @@ error_invalid_args: } int patty_ax25_frame_addresed_to(patty_ax25_frame *frame, - char *station, + const char *station, uint8_t ssid) { return strncmp(frame->dest.callsign, station, - PATTY_AX25_ADDRESS_CALLSIGN_LEN) == 0 + PATTY_AX25_CALLSIGN_LEN) == 0 && frame->dest.ssid == ssid; } + diff --git a/src/hash.c b/src/hash.c index 5898fc4..75232e6 100644 --- a/src/hash.c +++ b/src/hash.c @@ -12,7 +12,7 @@ uint32_t patty_hash(void *key, size_t size) { hash ^= (hash >> 6); } - hash += (hash << 3); + hash += (hash << 3); hash ^= (hash >> 11); hash += (hash << 15); diff --git a/src/if.c b/src/if.c index f47db73..a68f707 100644 --- a/src/if.c +++ b/src/if.c @@ -21,7 +21,7 @@ static patty_ax25_if *create_tnc(const char *device) { goto error_kiss_tnc_open; } - iface->type = PATTY_AX25_IF_KISS_TNC_TTY; + iface->type = PATTY_AX25_IF_KISS_TNC; snprintf(iface->name, sizeof(iface->name), "%s%d", prefix, number++); @@ -42,7 +42,7 @@ patty_ax25_if *patty_ax25_if_create(int opts, void *info) { patty_ax25_if *iface; switch (PATTY_AX25_IF_OPT_TYPE(opts)) { - case PATTY_AX25_IF_KISS_TNC_TTY: { + case PATTY_AX25_IF_KISS_TNC: { iface = create_tnc((const char *)info); break; @@ -59,7 +59,7 @@ patty_ax25_if *patty_ax25_if_create(int opts, void *info) { goto error; } - if ((iface->addresses = patty_list_new()) == NULL) { + if ((iface->addrs = patty_list_new()) == NULL) { goto error; } @@ -71,7 +71,7 @@ error: void patty_ax25_if_destroy(patty_ax25_if *iface) { switch (iface->type) { - case PATTY_AX25_IF_KISS_TNC_TTY: { + case PATTY_AX25_IF_KISS_TNC: { destroy_tnc(iface); break; } @@ -79,16 +79,24 @@ void patty_ax25_if_destroy(patty_ax25_if *iface) { } } -int patty_ax25_if_each_address(patty_ax25_if *iface, int (*callback)(patty_ax25_address *, void *), void *ctx) { +int patty_ax25_if_each_addr(patty_ax25_if *iface, + int (*callback)(char *, uint8_t, void *), void *ctx) { patty_list_iterator *iter; - patty_ax25_address *address; + patty_ax25_addr *addr; - if ((iter = patty_list_start(iface->addresses)) == NULL) { + if ((iter = patty_list_start(iface->addrs)) == NULL) { goto error_list_start; } - while ((address = patty_list_next(iter)) != NULL) { - if (callback(address, ctx) < 0) { + while ((addr = patty_list_next(iter)) != NULL) { + char buf[7]; + uint8_t ssid; + + if (patty_ax25_ntop(addr, buf, &ssid, sizeof(buf)) < 0) { + goto error_ntop; + } + + if (callback(buf, ssid, ctx) < 0) { goto error_callback; } } @@ -98,81 +106,106 @@ int patty_ax25_if_each_address(patty_ax25_if *iface, int (*callback)(patty_ax25_ return 0; error_callback: +error_ntop: patty_list_finish(iter); error_list_start: return -1; } -static patty_ax25_address *find_address(patty_ax25_if *iface, const char *callsign, int ssid) { +static patty_ax25_addr *find_addr(patty_ax25_if *iface, + const char *callsign, + uint8_t ssid) { patty_list_iterator *iter; - patty_ax25_address *address; + patty_ax25_addr *addr; - if ((iter = patty_list_start(iface->addresses)) == NULL) { + if ((iter = patty_list_start(iface->addrs)) == NULL) { goto error_list_start; } - while ((address = patty_list_next(iter)) != NULL) { - if (strncmp(address->callsign, callsign, sizeof(address->callsign)) != 0) { + while ((addr = patty_list_next(iter)) != NULL) { + char buf[7]; + uint8_t addr_ssid; + + if (patty_ax25_ntop(addr, buf, &addr_ssid, sizeof(buf)) < 0) { + goto error_ntop; + } + + if (strncmp(buf, callsign, sizeof(buf)) != 0) { continue; } - if (address->ssid != ssid) { + + if (addr_ssid != ssid) { continue; } patty_list_finish(iter); - return address; + return addr; } patty_list_finish(iter); +error_ntop: + patty_list_finish(iter); + error_list_start: return NULL; } -int patty_ax25_if_add_address(patty_ax25_if *iface, const char *callsign, int ssid) { - patty_ax25_address *address; +int patty_ax25_if_add_addr(patty_ax25_if *iface, + const char *callsign, + uint8_t ssid) { + patty_ax25_addr *addr; - if (find_address(iface, callsign, ssid) != NULL) { + if (find_addr(iface, callsign, ssid) != NULL) { errno = EEXIST; goto error_exists; } - if ((address = malloc(sizeof(*address))) == NULL) { - goto error_malloc_address; + if ((addr = malloc(sizeof(*addr))) == NULL) { + goto error_malloc_addr; } - memset(address, '\0', sizeof(*address)); - memcpy(address->callsign, callsign, sizeof(address->callsign)); + if (patty_ax25_pton(callsign, ssid, addr) < 0) { + goto error_pton; + } - address->ssid = ssid; - - if ((patty_list_append(iface->addresses, address)) == NULL) { + if ((patty_list_append(iface->addrs, addr)) == NULL) { goto error_list_append; } return 0; error_list_append: - free(address); +error_pton: + free(addr); -error_malloc_address: +error_malloc_addr: error_exists: return -1; } -int patty_ax25_if_delete_address(patty_ax25_if *iface, const char *callsign, int ssid) { - patty_list_item *item = iface->addresses->first; +int patty_ax25_if_delete_addr(patty_ax25_if *iface, + const char *callsign, + uint8_t ssid) { + patty_list_item *item = iface->addrs->first; int i = 0; while (item) { - patty_ax25_address *address = item->value; + char buf[7]; + uint8_t addr_ssid; - if (strncmp(address->callsign, callsign, sizeof(address->callsign)) == 0 && address->ssid == ssid) { - if (patty_list_splice(iface->addresses, i) == NULL) { + patty_ax25_addr *addr = item->value; + + if (patty_ax25_ntop(addr, buf, &addr_ssid, sizeof(buf)) < 0) { + goto error_ntop; + } + + if (strncmp(buf, callsign, sizeof(buf)) == 0 && addr_ssid == ssid) { + if (patty_list_splice(iface->addrs, i) == NULL) { goto error_list_splice; } } @@ -184,6 +217,7 @@ int patty_ax25_if_delete_address(patty_ax25_if *iface, const char *callsign, int return 0; error_list_splice: +error_ntop: return -1; } @@ -209,7 +243,7 @@ error_list_start: return NULL; } -int patty_ax25_each_if(patty_ax25 *ax25, int (*callback)(patty_ax25_if *, void *), void *ctx) { +int patty_ax25_if_each(patty_ax25 *ax25, int (*callback)(patty_ax25_if *, void *), void *ctx) { patty_list_iterator *iter; patty_ax25_if *iface; @@ -245,7 +279,7 @@ int patty_ax25_add_if(patty_ax25 *ax25, patty_ax25_if *iface) { } } - if (patty_dict_set(ax25->fd_lookup, &fd, sizeof(fd), iface) == NULL) { + if (patty_dict_set(ax25->socks, fd, sizeof(fd), iface) == NULL) { goto error_dict_set; } @@ -285,7 +319,7 @@ int patty_ax25_delete_if(patty_ax25 *ax25, patty_ax25_if *iface) { ax25->fdmax--; } - if (patty_dict_delete(ax25->fd_lookup, &fd, sizeof(fd)) == NULL) { + if (patty_dict_delete(ax25->socks, fd, sizeof(fd)) == NULL) { goto error_dict_delete; } } diff --git a/src/iflist.c b/src/iflist.c index 9cabd8f..917774f 100644 --- a/src/iflist.c +++ b/src/iflist.c @@ -22,14 +22,14 @@ static void usage(int argc, char **argv, const char *message, ...) { exit(1); } -int address_callback(patty_ax25_address *address, void *ctx) { - return printf(" %s/%d\n", address->callsign, address->ssid); +int addr_callback(char *callsign, uint8_t ssid, void *ctx) { + return printf(" %s/%d\n", callsign, ssid); } int iface_callback(patty_ax25_if *iface, void *ctx) { printf("%s:\n", iface->name); - return patty_ax25_if_each_address(iface, address_callback, ctx); + return patty_ax25_if_each_addr(iface, addr_callback, ctx); } int main(int argc, char **argv) { @@ -48,13 +48,13 @@ int main(int argc, char **argv) { exit(127); } - if ((iface = patty_ax25_if_create(PATTY_AX25_IF_KISS_TNC_TTY, argv[1])) == NULL) { + if ((iface = patty_ax25_if_create(PATTY_AX25_IF_KISS_TNC, argv[1])) == NULL) { perror("Unable to create interface"); exit(127); } - if (patty_ax25_if_add_address(iface, "WX3RKR", 0) < 0) { + if (patty_ax25_if_add_addr(iface, "WX3RKR", 0) < 0) { perror("Unable to add address"); exit(127); @@ -66,7 +66,7 @@ int main(int argc, char **argv) { exit(127); } - patty_ax25_each_if(&ax25, iface_callback, NULL); + patty_ax25_if_each(&ax25, iface_callback, NULL); patty_ax25_stop(&ax25);