Making significant headway towards a working server

This commit is contained in:
XANTRONIX Development 2020-06-26 22:44:19 -04:00 committed by XANTRONIX Industrial
parent 22366f2d0c
commit bdb73c8805
14 changed files with 294 additions and 64 deletions

View file

@ -40,10 +40,28 @@ typedef struct _patty_ax25_if {
tx_bufsz; tx_bufsz;
patty_kiss_tnc *tnc; patty_kiss_tnc *tnc;
patty_list *addrs; patty_ax25_addr addr;
patty_list *aliases;
} patty_ax25_if; } patty_ax25_if;
patty_ax25_if *patty_ax25_if_new(int opts, void *info); typedef struct _patty_ax25_if_info {
patty_ax25_addr addr;
} patty_ax25_if_info;
enum patty_ax25_if_kiss_tnc_info_type {
PATTY_AX25_IF_KISS_TNC_INFO_NONE,
PATTY_AX25_IF_KISS_TNC_INFO_FD,
PATTY_AX25_IF_KISS_TNC_INFO_PATH
};
typedef struct _patty_ax25_if_kiss_tnc_info {
patty_ax25_addr addr;
enum patty_ax25_if_kiss_tnc_info_type type;
int fd;
char path[256];
} patty_ax25_if_kiss_tnc_info;
patty_ax25_if *patty_ax25_if_new(int opts, patty_ax25_if_info *info);
void patty_ax25_if_destroy(patty_ax25_if *iface); void patty_ax25_if_destroy(patty_ax25_if *iface);

View file

@ -22,7 +22,7 @@ enum patty_ax25_proto {
PATTY_AX25_PROTO_INET_ARP = 0xcd, PATTY_AX25_PROTO_INET_ARP = 0xcd,
PATTY_AX25_PROTO_FLEXNET = 0xce, PATTY_AX25_PROTO_FLEXNET = 0xce,
PATTY_AX25_PROTO_NETROM = 0xcf, PATTY_AX25_PROTO_NETROM = 0xcf,
PATTY_AX25_PROTO_RAW = 0xf0, PATTY_AX25_PROTO_NONE = 0xf0,
PATTY_AX25_PROTO_ESCAPE = 0xff PATTY_AX25_PROTO_ESCAPE = 0xff
}; };

View file

@ -29,6 +29,8 @@ void patty_ax25_route_table_destroy(patty_ax25_route_table *table);
patty_ax25_route *patty_ax25_route_table_find(patty_ax25_route_table *table, patty_ax25_route *patty_ax25_route_table_find(patty_ax25_route_table *table,
patty_ax25_addr *dest); patty_ax25_addr *dest);
patty_ax25_route *patty_ax25_route_table_default(patty_ax25_route_table *table);
int patty_ax25_route_table_add(patty_ax25_route_table *table, int patty_ax25_route_table_add(patty_ax25_route_table *table,
patty_ax25_route *route); patty_ax25_route *route);

View file

@ -6,7 +6,7 @@
typedef struct _patty_ax25_server patty_ax25_server; typedef struct _patty_ax25_server patty_ax25_server;
patty_ax25_server *patty_ax25_server_new(); patty_ax25_server *patty_ax25_server_new(const char *path);
void patty_ax25_server_destroy(patty_ax25_server *server); void patty_ax25_server_destroy(patty_ax25_server *server);

View file

@ -55,4 +55,6 @@ patty_ax25_sock *patty_ax25_sock_new(enum patty_ax25_sock_type type);
void patty_ax25_sock_destroy(patty_ax25_sock *sock); void patty_ax25_sock_destroy(patty_ax25_sock *sock);
int patty_ax25_sock_send_sabm(patty_ax25_sock *sock);
#endif /* _PATTY_AX25_SOCK_H */ #endif /* _PATTY_AX25_SOCK_H */

View file

@ -29,13 +29,13 @@ enum patty_kiss_command {
typedef struct _patty_kiss_tnc patty_kiss_tnc; typedef struct _patty_kiss_tnc patty_kiss_tnc;
patty_kiss_tnc *patty_kiss_tnc_open_fd(int fd); patty_kiss_tnc *patty_kiss_tnc_new_fd(int fd);
patty_kiss_tnc *patty_kiss_tnc_open(const char *device); patty_kiss_tnc *patty_kiss_tnc_new(const char *device);
int patty_kiss_tnc_fd(patty_kiss_tnc *tnc); int patty_kiss_tnc_fd(patty_kiss_tnc *tnc);
void patty_kiss_tnc_close(patty_kiss_tnc *tnc); void patty_kiss_tnc_destroy(patty_kiss_tnc *tnc);
size_t patty_kiss_tnc_dropped(patty_kiss_tnc *tnc); size_t patty_kiss_tnc_dropped(patty_kiss_tnc *tnc);

View file

@ -162,8 +162,8 @@ int main(int argc, char **argv) {
} }
tnc = (argc == 2)? tnc = (argc == 2)?
patty_kiss_tnc_open(argv[1]): patty_kiss_tnc_new(argv[1]):
patty_kiss_tnc_open_fd(0); patty_kiss_tnc_new_fd(0);
if (tnc == NULL) { if (tnc == NULL) {
perror("Unable to open TNC"); perror("Unable to open TNC");
@ -204,7 +204,7 @@ int main(int argc, char **argv) {
free(buf); free(buf);
patty_kiss_tnc_close(tnc); patty_kiss_tnc_destroy(tnc);
return 0; return 0;
@ -214,7 +214,7 @@ error_kiss_tnc_recv:
free(buf); free(buf);
error_malloc_buf: error_malloc_buf:
patty_kiss_tnc_close(tnc); patty_kiss_tnc_destroy(tnc);
error_kiss_tnc_open: error_kiss_tnc_open:
return 127; return 127;

View file

@ -5,12 +5,16 @@
#include <patty/ax25.h> #include <patty/ax25.h>
static int init_tnc(patty_ax25_if *iface, const char *device) { static int init_tnc(patty_ax25_if *iface, patty_ax25_if_kiss_tnc_info *info) {
static char *prefix = "kiss"; static char *prefix = "kiss";
static int number = 0; static int number = 0;
if ((iface->tnc = patty_kiss_tnc_open(device)) == NULL) { iface->tnc = (info->type == PATTY_AX25_IF_KISS_TNC_INFO_FD)?
goto error_kiss_tnc_open; patty_kiss_tnc_new_fd(info->fd):
patty_kiss_tnc_new(info->path);
if (iface->tnc == NULL) {
goto error_kiss_tnc_new;
} }
iface->type = PATTY_AX25_IF_KISS_TNC; iface->type = PATTY_AX25_IF_KISS_TNC;
@ -19,15 +23,15 @@ static int init_tnc(patty_ax25_if *iface, const char *device) {
return 0; return 0;
error_kiss_tnc_open: error_kiss_tnc_new:
return -1; return -1;
} }
static void close_tnc(patty_ax25_if *iface) { static void destroy_tnc(patty_ax25_if *iface) {
patty_kiss_tnc_close(iface->tnc); patty_kiss_tnc_destroy(iface->tnc);
} }
patty_ax25_if *patty_ax25_if_new(int opts, void *info) { patty_ax25_if *patty_ax25_if_new(int opts, patty_ax25_if_info *info) {
patty_ax25_if *iface; patty_ax25_if *iface;
if ((iface = malloc(sizeof(*iface))) == NULL) { if ((iface = malloc(sizeof(*iface))) == NULL) {
@ -36,6 +40,12 @@ patty_ax25_if *patty_ax25_if_new(int opts, void *info) {
memset(iface, '\0', sizeof(*iface)); memset(iface, '\0', sizeof(*iface));
if (info->addr.callsign[0] == '\0') {
errno = EINVAL;
goto error_invalid_address;
}
if ((iface->rx_buf = malloc(PATTY_AX25_IF_BUFSZ)) == NULL) { if ((iface->rx_buf = malloc(PATTY_AX25_IF_BUFSZ)) == NULL) {
goto error_malloc_rx_buf; goto error_malloc_rx_buf;
} else { } else {
@ -48,13 +58,13 @@ patty_ax25_if *patty_ax25_if_new(int opts, void *info) {
iface->tx_bufsz = PATTY_AX25_IF_BUFSZ; iface->tx_bufsz = PATTY_AX25_IF_BUFSZ;
} }
if ((iface->addrs = patty_list_new()) == NULL) { if ((iface->aliases = patty_list_new()) == NULL) {
goto error_list_new; goto error_list_new_aliases;
} }
switch (PATTY_AX25_IF_OPT_TYPE(opts)) { switch (PATTY_AX25_IF_OPT_TYPE(opts)) {
case PATTY_AX25_IF_KISS_TNC: case PATTY_AX25_IF_KISS_TNC:
if (init_tnc(iface, (const char *)info) < 0) { if (init_tnc(iface, (patty_ax25_if_kiss_tnc_info *)info) < 0) {
goto error_init; goto error_init;
} }
@ -66,13 +76,15 @@ patty_ax25_if *patty_ax25_if_new(int opts, void *info) {
goto error_invalid_if_type; goto error_invalid_if_type;
} }
memcpy(&iface->addr, &info->addr, sizeof(iface->addr));
return iface; return iface;
error_invalid_if_type: error_invalid_if_type:
error_init: error_init:
patty_list_destroy(iface->addrs); patty_list_destroy(iface->aliases);
error_list_new: error_list_new_aliases:
free(iface->tx_buf); free(iface->tx_buf);
error_malloc_tx_buf: error_malloc_tx_buf:
@ -82,20 +94,21 @@ error_malloc_rx_buf:
free(iface); free(iface);
error_malloc_iface: error_malloc_iface:
error_invalid_address:
return NULL; return NULL;
} }
void patty_ax25_if_destroy(patty_ax25_if *iface) { void patty_ax25_if_destroy(patty_ax25_if *iface) {
switch (iface->type) { switch (iface->type) {
case PATTY_AX25_IF_KISS_TNC: case PATTY_AX25_IF_KISS_TNC:
close_tnc(iface); destroy_tnc(iface);
break; break;
default: default:
break; break;
} }
patty_list_destroy(iface->addrs); patty_list_destroy(iface->aliases);
free(iface->tx_buf); free(iface->tx_buf);
free(iface->rx_buf); free(iface->rx_buf);
@ -107,14 +120,22 @@ int patty_ax25_if_addr_each(patty_ax25_if *iface,
patty_list_iterator *iter; patty_list_iterator *iter;
patty_ax25_addr *addr; patty_ax25_addr *addr;
if ((iter = patty_list_start(iface->addrs)) == NULL) { char buf[7];
uint8_t ssid;
if (patty_ax25_ntop(&iface->addr, buf, &ssid, sizeof(buf)) < 0) {
goto error_ntop_addr;
}
if (callback(buf, ssid, ctx) < 0) {
goto error_callback_addr;
}
if ((iter = patty_list_start(iface->aliases)) == NULL) {
goto error_list_start; goto error_list_start;
} }
while ((addr = patty_list_next(iter)) != NULL) { while ((addr = patty_list_next(iter)) != NULL) {
char buf[7];
uint8_t ssid;
if (patty_ax25_ntop(addr, buf, &ssid, sizeof(buf)) < 0) { if (patty_ax25_ntop(addr, buf, &ssid, sizeof(buf)) < 0) {
goto error_ntop; goto error_ntop;
} }
@ -133,6 +154,8 @@ error_ntop:
patty_list_finish(iter); patty_list_finish(iter);
error_list_start: error_list_start:
error_callback_addr:
error_ntop_addr:
return -1; return -1;
} }
@ -142,14 +165,22 @@ static patty_ax25_addr *find_addr(patty_ax25_if *iface,
patty_list_iterator *iter; patty_list_iterator *iter;
patty_ax25_addr *addr; patty_ax25_addr *addr;
if ((iter = patty_list_start(iface->addrs)) == NULL) { char buf[7];
uint8_t addr_ssid;
if (patty_ax25_ntop(&iface->addr, buf, &addr_ssid, sizeof(buf)) < 0) {
goto error_ntop_addr;
}
if (strncmp(buf, callsign, sizeof(buf)) == 0 && addr_ssid == ssid) {
return &iface->addr;
}
if ((iter = patty_list_start(iface->aliases)) == NULL) {
goto error_list_start; goto error_list_start;
} }
while ((addr = patty_list_next(iter)) != NULL) { 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) { if (patty_ax25_ntop(addr, buf, &addr_ssid, sizeof(buf)) < 0) {
goto error_ntop; goto error_ntop;
} }
@ -158,7 +189,6 @@ static patty_ax25_addr *find_addr(patty_ax25_if *iface,
continue; continue;
} }
if (addr_ssid != ssid) { if (addr_ssid != ssid) {
continue; continue;
} }
@ -172,6 +202,7 @@ error_ntop:
patty_list_finish(iter); patty_list_finish(iter);
error_list_start: error_list_start:
error_ntop_addr:
return NULL; return NULL;
} }
@ -194,7 +225,7 @@ int patty_ax25_if_addr_add(patty_ax25_if *iface,
goto error_pton; goto error_pton;
} }
if ((patty_list_append(iface->addrs, addr)) == NULL) { if ((patty_list_append(iface->aliases, addr)) == NULL) {
goto error_list_append; goto error_list_append;
} }
@ -212,7 +243,7 @@ error_exists:
int patty_ax25_if_addr_delete(patty_ax25_if *iface, int patty_ax25_if_addr_delete(patty_ax25_if *iface,
const char *callsign, const char *callsign,
uint8_t ssid) { uint8_t ssid) {
patty_list_item *item = iface->addrs->first; patty_list_item *item = iface->aliases->first;
int i = 0; int i = 0;
while (item) { while (item) {
@ -226,7 +257,7 @@ int patty_ax25_if_addr_delete(patty_ax25_if *iface,
} }
if (strncmp(buf, callsign, sizeof(buf)) == 0 && addr_ssid == ssid) { if (strncmp(buf, callsign, sizeof(buf)) == 0 && addr_ssid == ssid) {
if (patty_list_splice(iface->addrs, i) == NULL) { if (patty_list_splice(iface->aliases, i) == NULL) {
goto error_list_splice; goto error_list_splice;
} }
} }

View file

@ -17,8 +17,14 @@ enum kiss_flags {
KISS_ESCAPE = 1 << 2 KISS_ESCAPE = 1 << 2
}; };
enum tnc_opts {
TNC_NONE = 0,
TNC_CLOSE_ON_DESTROY = 1 << 0
};
struct _patty_kiss_tnc { struct _patty_kiss_tnc {
int fd; int fd,
opts;
void *buf, void *buf,
*frame; *frame;
@ -30,7 +36,7 @@ struct _patty_kiss_tnc {
ssize_t readlen; ssize_t readlen;
}; };
patty_kiss_tnc *patty_kiss_tnc_open_fd(int fd) { patty_kiss_tnc *patty_kiss_tnc_new_fd(int fd) {
patty_kiss_tnc *tnc; patty_kiss_tnc *tnc;
if ((tnc = malloc(sizeof(*tnc))) == NULL) { if ((tnc = malloc(sizeof(*tnc))) == NULL) {
@ -42,6 +48,7 @@ patty_kiss_tnc *patty_kiss_tnc_open_fd(int fd) {
} }
tnc->fd = fd; tnc->fd = fd;
tnc->opts = TNC_NONE;
tnc->bufsz = PATTY_KISS_BUFSZ; tnc->bufsz = PATTY_KISS_BUFSZ;
tnc->offset = 0; tnc->offset = 0;
tnc->dropped = 0; tnc->dropped = 0;
@ -56,7 +63,7 @@ error_malloc_tnc:
return NULL; return NULL;
} }
patty_kiss_tnc *patty_kiss_tnc_open(const char *device) { patty_kiss_tnc *patty_kiss_tnc_new(const char *device) {
patty_kiss_tnc *tnc; patty_kiss_tnc *tnc;
int fd; int fd;
@ -64,13 +71,15 @@ patty_kiss_tnc *patty_kiss_tnc_open(const char *device) {
goto error_open; goto error_open;
} }
if ((tnc = patty_kiss_tnc_open_fd(fd)) == NULL) { if ((tnc = patty_kiss_tnc_new_fd(fd)) == NULL) {
goto error_tnc_open_fd; goto error_tnc_new_fd;
} }
tnc->opts |= TNC_CLOSE_ON_DESTROY;
return tnc; return tnc;
error_tnc_open_fd: error_tnc_new_fd:
close(fd); close(fd);
error_open: error_open:
@ -81,10 +90,13 @@ int patty_kiss_tnc_fd(patty_kiss_tnc *tnc) {
return tnc->fd; return tnc->fd;
} }
void patty_kiss_tnc_close(patty_kiss_tnc *tnc) { void patty_kiss_tnc_destroy(patty_kiss_tnc *tnc) {
close(tnc->fd); if (tnc->opts & TNC_CLOSE_ON_DESTROY) {
free(tnc->buf); close(tnc->fd);
free(tnc); }
free(tnc->buf);
free(tnc);
} }
static void tnc_drop(patty_kiss_tnc *tnc) { static void tnc_drop(patty_kiss_tnc *tnc) {
@ -107,6 +119,8 @@ ssize_t patty_kiss_tnc_recv(patty_kiss_tnc *tnc,
enum kiss_flags flags = KISS_NONE; enum kiss_flags flags = KISS_NONE;
if (tnc->offset == tnc->readlen) { if (tnc->offset == tnc->readlen) {
errno = 0;
return 0; return 0;
} }
@ -208,6 +222,8 @@ done:
if (flags & KISS_FRAME) { if (flags & KISS_FRAME) {
tnc_drop(tnc); tnc_drop(tnc);
errno = 0;
return 0; return 0;
} }

View file

@ -64,12 +64,33 @@ void patty_ax25_route_table_destroy(patty_ax25_route_table *table) {
patty_ax25_route *patty_ax25_route_table_find(patty_ax25_route_table *table, patty_ax25_route *patty_ax25_route_table_find(patty_ax25_route_table *table,
patty_ax25_addr *dest) { patty_ax25_addr *dest) {
patty_ax25_route *route;
uint32_t hash; uint32_t hash;
patty_hash_init(&hash); patty_hash_init(&hash);
patty_ax25_addr_hash(&hash, dest); patty_ax25_addr_hash(&hash, dest);
patty_hash_end(&hash); patty_hash_end(&hash);
route = patty_dict_get_with_hash(table, hash);
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);
return patty_dict_get_with_hash(table, hash); return patty_dict_get_with_hash(table, hash);
} }

View file

@ -15,6 +15,8 @@
typedef int (*patty_ax25_server_call)(patty_ax25_server *, int); typedef int (*patty_ax25_server_call)(patty_ax25_server *, int);
struct _patty_ax25_server { struct _patty_ax25_server {
char path[PATTY_AX25_SOCK_PATH_SIZE];
int fd, /* fd of UNIX domain socket */ int fd, /* fd of UNIX domain socket */
fd_max; fd_max;
@ -38,7 +40,7 @@ struct _patty_ax25_server {
*clients_by_sock; *clients_by_sock;
}; };
patty_ax25_server *patty_ax25_server_new() { patty_ax25_server *patty_ax25_server_new(const char *path) {
patty_ax25_server *server; patty_ax25_server *server;
if ((server = malloc(sizeof(*server))) == NULL) { if ((server = malloc(sizeof(*server))) == NULL) {
@ -47,6 +49,8 @@ patty_ax25_server *patty_ax25_server_new() {
memset(server, '\0', sizeof(*server)); memset(server, '\0', sizeof(*server));
strncpy(server->path, path, PATTY_AX25_SOCK_PATH_SIZE);
if ((server->ifaces = patty_list_new()) == NULL) { if ((server->ifaces = patty_list_new()) == NULL) {
goto error_list_new_ifaces; goto error_list_new_ifaces;
} }
@ -717,6 +721,8 @@ static int server_connect(patty_ax25_server *server,
patty_ax25_call_connect_response response; patty_ax25_call_connect_response response;
patty_ax25_sock *sock; patty_ax25_sock *sock;
patty_ax25_route *route;
patty_ax25_if *iface;
if (read(client, &request, sizeof(request)) < 0) { if (read(client, &request, sizeof(request)) < 0) {
goto error_io; goto error_io;
@ -750,6 +756,43 @@ static int server_connect(patty_ax25_server *server,
break; break;
} }
if (sock->local.callsign[0]) {
/*
* If there is an address already bound to this socket, locate the
* appropriate route.
*/
route = patty_ax25_route_table_find(server->routes, &sock->local);
} else {
/*
* Otherwise, locate the default route.
*/
route = patty_ax25_route_table_default(server->routes);
}
/*
* If no route could be found, then assume the network is down or not
* configured.
*/
if (route == NULL) {
response.ret = -1;
response.eno = ENETDOWN;
goto error_network_down;
}
iface = sock->iface = route->iface;
/*
* If there is no local address bound to this sock, then bind the
* address of the default route interface.
*/
if (sock->local.callsign[0] == '\0') {
memcpy(&sock->local, &iface->addr, sizeof(sock->local));
}
/*
* Bind the requested remote address to the socket.
*/
memcpy(&sock->remote, &request.peer, sizeof(request.peer)); memcpy(&sock->remote, &request.peer, sizeof(request.peer));
sock->status = PATTY_AX25_SOCK_PENDING_CONNECT; sock->status = PATTY_AX25_SOCK_PENDING_CONNECT;
@ -767,9 +810,17 @@ static int server_connect(patty_ax25_server *server,
* timeout has been exceeded or the peer has sent a UA frame to * timeout has been exceeded or the peer has sent a UA frame to
* acknowledge and establish the connection. * acknowledge and establish the connection.
*/ */
if (patty_ax25_sock_send_sabm(sock) < 0) {
response.ret = -1;
response.eno = EIO;
goto error_sock_send_sabm;
}
return 0; return 0;
error_sock_send_sabm:
error_network_down:
error_invalid_status: error_invalid_status:
error_sock_by_fd: error_sock_by_fd:
if (write(client, &response, sizeof(response)) < 0) { if (write(client, &response, sizeof(response)) < 0) {
@ -956,11 +1007,18 @@ static int handle_client(void *key,
goto error_io; goto error_io;
} }
if (server_calls[call] == NULL) {
errno = ENOSYS;
goto error_not_implemented;
}
return server_calls[call](server, client); return server_calls[call](server, client);
done: done:
return 0; return 0;
error_not_implemented:
error_dict_delete: error_dict_delete:
error_io: error_io:
return -1; return -1;
@ -1101,7 +1159,7 @@ static int handle_socks(patty_ax25_server *server) {
} }
int patty_ax25_server_run(patty_ax25_server *server) { int patty_ax25_server_run(patty_ax25_server *server) {
if (listen_unix(server, PATTY_AX25_SERVER_PATH) < 0) { if (listen_unix(server, server->path) < 0) {
goto error_listen_unix; goto error_listen_unix;
} }
@ -1109,11 +1167,10 @@ int patty_ax25_server_run(patty_ax25_server *server) {
int nready; int nready;
memcpy(&server->fds_r, &server->fds_watch, sizeof(server->fds_r)); memcpy(&server->fds_r, &server->fds_watch, sizeof(server->fds_r));
memcpy(&server->fds_w, &server->fds_watch, sizeof(server->fds_w));
if ((nready = select( server->fd_max, if ((nready = select( server->fd_max,
&server->fds_r, &server->fds_r,
&server->fds_w, NULL,
NULL, NULL,
NULL)) < 0) { NULL)) < 0) {
goto error_io; goto error_io;

View file

@ -1,5 +1,6 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <unistd.h>
#include <patty/ax25.h> #include <patty/ax25.h>
@ -27,3 +28,38 @@ error_malloc_sock:
void patty_ax25_sock_destroy(patty_ax25_sock *sock) { void patty_ax25_sock_destroy(patty_ax25_sock *sock) {
free(sock); free(sock);
} }
static size_t copy_addr_to_buf(patty_ax25_sock *sock, uint8_t *buf, size_t offset) {
size_t i;
memcpy(&buf[offset], &sock->remote, sizeof(patty_ax25_addr));
offset += sizeof(patty_ax25_addr);
memcpy(&buf[offset], &sock->local, sizeof(patty_ax25_addr));
offset += sizeof(patty_ax25_addr);
for (i=0; i<sock->hops; i++) {
memcpy(&buf[offset], &sock->repeaters[i], sizeof(patty_ax25_addr));
offset += sizeof(patty_ax25_addr);
if (i == sock->hops - 1) {
buf[offset - 1] |= 0x01;
}
}
return offset;
}
int patty_ax25_sock_send_sabm(patty_ax25_sock *sock) {
size_t offset = 0;
uint8_t *buf = (uint8_t *)(sock->iface->tx_buf);
offset = copy_addr_to_buf(sock, buf, offset);
buf[offset++] = PATTY_AX25_PROTO_NONE;
buf[offset++] = 0x3f;
return patty_ax25_if_send(sock->iface,
buf,
offset);
}

View file

@ -32,10 +32,15 @@ int main(int argc, char **argv) {
int fd, int fd,
sock; sock;
patty_ax25_addr peer;
char path[256];
if (argc != 2) { if (argc != 2) {
usage(argc, argv, "No patty socket provided"); usage(argc, argv, "No patty socket provided");
} }
patty_ax25_pton("GB9BLM", 0, &peer);
if ((fd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) { if ((fd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) {
fprintf(stderr, "%s: %s: %s: %s\n", fprintf(stderr, "%s: %s: %s: %s\n",
argv[0], "socket()", argv[1], strerror(errno)); argv[0], "socket()", argv[1], strerror(errno));
@ -58,14 +63,14 @@ int main(int argc, char **argv) {
goto error_call_socket; goto error_call_socket;
} }
if (patty_ax25_call_close(fd, sock) < 0) { if (patty_ax25_call_connect(fd, sock, &peer, path) < 0) {
fprintf(stderr, "%s: %s: %s\n", fprintf(stderr, "%s: %s: %s\n",
argv[0], "patty_ax25_call_close()", strerror(errno)); argv[0], "patty_ax25_call_connect()", strerror(errno));
goto error_call_close; goto error_call_close;
} }
fprintf(stderr, "got sock %d\n", sock); fprintf(stderr, "connected sock %d\n", sock);
close(fd); close(fd);

View file

@ -1,8 +1,13 @@
#define _GNU_SOURCE
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <stdarg.h> #include <stdarg.h>
#include <sys/select.h> #include <termios.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h> #include <errno.h>
#include <patty/ax25.h> #include <patty/ax25.h>
@ -17,7 +22,7 @@ static void usage(int argc, char **argv, const char *message, ...) {
va_end(args); va_end(args);
} }
fprintf(stderr, "usage: %s /dev/ttyXX|kiss.cap\n", argv[0]); fprintf(stderr, "usage: %s /dev/ttyXX|kiss.cap [path.sock]\n", argv[0]);
exit(1); exit(1);
} }
@ -27,22 +32,57 @@ int main(int argc, char **argv) {
patty_ax25_if *iface; patty_ax25_if *iface;
patty_ax25_route *route; patty_ax25_route *route;
if (argc != 2) { patty_ax25_if_kiss_tnc_info info = {
.type = PATTY_AX25_IF_KISS_TNC_INFO_FD
};
if (argc < 2) {
usage(argc, argv, "No TNC device or KISS dump file provided"); usage(argc, argv, "No TNC device or KISS dump file provided");
} else if (argc > 3) {
usage(argc, argv, "Too many arguments provided");
} }
if ((server = patty_ax25_server_new()) == NULL) { if ((info.fd = open(argv[1], O_RDWR)) < 0) {
fprintf(stderr, "%s: %s: %s: %s\n",
argv[0], "open()", argv[1], strerror(errno));
goto error_open;
}
if (isatty(info.fd) && grantpt(info.fd) == 0 && unlockpt(info.fd) == 0) {
char name[256];
struct termios t;
if (ptsname_r(info.fd, name, sizeof(name)) < 0) {
goto error_open;
}
if (tcgetattr(info.fd, &t) < 0) {
goto error_open;
}
cfmakeraw(&t);
if (tcsetattr(info.fd, TCSANOW, &t) < 0) {
goto error_open;
}
fprintf(stderr, "pts %s\n", name);
}
errno = 0;
patty_ax25_pton("KZ3ROX", 0, &info.addr);
if ((server = patty_ax25_server_new(argc == 3? argv[2]: PATTY_AX25_SERVER_PATH)) == NULL) {
goto error_server_new; goto error_server_new;
} }
if ((iface = patty_ax25_if_new(PATTY_AX25_IF_KISS_TNC, argv[1])) == NULL) { if ((iface = patty_ax25_if_new(PATTY_AX25_IF_KISS_TNC,
(patty_ax25_if_info *)&info)) == NULL) {
goto error_if_new; goto error_if_new;
} }
if (patty_ax25_if_addr_add(iface, "KZ3ROX", 0) < 0) {
goto error_if_addr_add;
}
if (patty_ax25_server_add_if(server, iface) < 0) { if (patty_ax25_server_add_if(server, iface) < 0) {
goto error_server_add_if; goto error_server_add_if;
} }
@ -70,10 +110,12 @@ error_server_run:
error_server_add_route: error_server_add_route:
error_route_new_default: error_route_new_default:
error_server_add_if: error_server_add_if:
error_if_addr_add:
error_if_new: error_if_new:
patty_ax25_server_destroy(server); patty_ax25_server_destroy(server);
error_server_new: error_server_new:
close(info.fd);
error_open:
return 1; return 1;
} }