Making significant headway towards a working server
This commit is contained in:
parent
22366f2d0c
commit
bdb73c8805
14 changed files with 294 additions and 64 deletions
|
@ -40,10 +40,28 @@ typedef struct _patty_ax25_if {
|
|||
tx_bufsz;
|
||||
|
||||
patty_kiss_tnc *tnc;
|
||||
patty_list *addrs;
|
||||
patty_ax25_addr addr;
|
||||
patty_list *aliases;
|
||||
} 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);
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ enum patty_ax25_proto {
|
|||
PATTY_AX25_PROTO_INET_ARP = 0xcd,
|
||||
PATTY_AX25_PROTO_FLEXNET = 0xce,
|
||||
PATTY_AX25_PROTO_NETROM = 0xcf,
|
||||
PATTY_AX25_PROTO_RAW = 0xf0,
|
||||
PATTY_AX25_PROTO_NONE = 0xf0,
|
||||
PATTY_AX25_PROTO_ESCAPE = 0xff
|
||||
};
|
||||
|
||||
|
|
|
@ -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_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,
|
||||
patty_ax25_route *route);
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
int patty_ax25_sock_send_sabm(patty_ax25_sock *sock);
|
||||
|
||||
#endif /* _PATTY_AX25_SOCK_H */
|
||||
|
|
|
@ -29,13 +29,13 @@ enum patty_kiss_command {
|
|||
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
|
|
|
@ -162,8 +162,8 @@ int main(int argc, char **argv) {
|
|||
}
|
||||
|
||||
tnc = (argc == 2)?
|
||||
patty_kiss_tnc_open(argv[1]):
|
||||
patty_kiss_tnc_open_fd(0);
|
||||
patty_kiss_tnc_new(argv[1]):
|
||||
patty_kiss_tnc_new_fd(0);
|
||||
|
||||
if (tnc == NULL) {
|
||||
perror("Unable to open TNC");
|
||||
|
@ -204,7 +204,7 @@ int main(int argc, char **argv) {
|
|||
|
||||
free(buf);
|
||||
|
||||
patty_kiss_tnc_close(tnc);
|
||||
patty_kiss_tnc_destroy(tnc);
|
||||
|
||||
return 0;
|
||||
|
||||
|
@ -214,7 +214,7 @@ error_kiss_tnc_recv:
|
|||
free(buf);
|
||||
|
||||
error_malloc_buf:
|
||||
patty_kiss_tnc_close(tnc);
|
||||
patty_kiss_tnc_destroy(tnc);
|
||||
|
||||
error_kiss_tnc_open:
|
||||
return 127;
|
||||
|
|
83
src/if.c
83
src/if.c
|
@ -5,12 +5,16 @@
|
|||
|
||||
#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 int number = 0;
|
||||
|
||||
if ((iface->tnc = patty_kiss_tnc_open(device)) == NULL) {
|
||||
goto error_kiss_tnc_open;
|
||||
iface->tnc = (info->type == PATTY_AX25_IF_KISS_TNC_INFO_FD)?
|
||||
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;
|
||||
|
@ -19,15 +23,15 @@ static int init_tnc(patty_ax25_if *iface, const char *device) {
|
|||
|
||||
return 0;
|
||||
|
||||
error_kiss_tnc_open:
|
||||
error_kiss_tnc_new:
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void close_tnc(patty_ax25_if *iface) {
|
||||
patty_kiss_tnc_close(iface->tnc);
|
||||
static void destroy_tnc(patty_ax25_if *iface) {
|
||||
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;
|
||||
|
||||
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));
|
||||
|
||||
if (info->addr.callsign[0] == '\0') {
|
||||
errno = EINVAL;
|
||||
|
||||
goto error_invalid_address;
|
||||
}
|
||||
|
||||
if ((iface->rx_buf = malloc(PATTY_AX25_IF_BUFSZ)) == NULL) {
|
||||
goto error_malloc_rx_buf;
|
||||
} else {
|
||||
|
@ -48,13 +58,13 @@ patty_ax25_if *patty_ax25_if_new(int opts, void *info) {
|
|||
iface->tx_bufsz = PATTY_AX25_IF_BUFSZ;
|
||||
}
|
||||
|
||||
if ((iface->addrs = patty_list_new()) == NULL) {
|
||||
goto error_list_new;
|
||||
if ((iface->aliases = patty_list_new()) == NULL) {
|
||||
goto error_list_new_aliases;
|
||||
}
|
||||
|
||||
switch (PATTY_AX25_IF_OPT_TYPE(opts)) {
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -66,13 +76,15 @@ patty_ax25_if *patty_ax25_if_new(int opts, void *info) {
|
|||
goto error_invalid_if_type;
|
||||
}
|
||||
|
||||
memcpy(&iface->addr, &info->addr, sizeof(iface->addr));
|
||||
|
||||
return iface;
|
||||
|
||||
error_invalid_if_type:
|
||||
error_init:
|
||||
patty_list_destroy(iface->addrs);
|
||||
patty_list_destroy(iface->aliases);
|
||||
|
||||
error_list_new:
|
||||
error_list_new_aliases:
|
||||
free(iface->tx_buf);
|
||||
|
||||
error_malloc_tx_buf:
|
||||
|
@ -82,20 +94,21 @@ error_malloc_rx_buf:
|
|||
free(iface);
|
||||
|
||||
error_malloc_iface:
|
||||
error_invalid_address:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void patty_ax25_if_destroy(patty_ax25_if *iface) {
|
||||
switch (iface->type) {
|
||||
case PATTY_AX25_IF_KISS_TNC:
|
||||
close_tnc(iface);
|
||||
destroy_tnc(iface);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
patty_list_destroy(iface->addrs);
|
||||
patty_list_destroy(iface->aliases);
|
||||
|
||||
free(iface->tx_buf);
|
||||
free(iface->rx_buf);
|
||||
|
@ -107,14 +120,22 @@ int patty_ax25_if_addr_each(patty_ax25_if *iface,
|
|||
patty_list_iterator *iter;
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
@ -133,6 +154,8 @@ error_ntop:
|
|||
patty_list_finish(iter);
|
||||
|
||||
error_list_start:
|
||||
error_callback_addr:
|
||||
error_ntop_addr:
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -142,14 +165,22 @@ static patty_ax25_addr *find_addr(patty_ax25_if *iface,
|
|||
patty_list_iterator *iter;
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
@ -157,7 +188,6 @@ static patty_ax25_addr *find_addr(patty_ax25_if *iface,
|
|||
if (strncmp(buf, callsign, sizeof(buf)) != 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if (addr_ssid != ssid) {
|
||||
continue;
|
||||
|
@ -172,6 +202,7 @@ error_ntop:
|
|||
patty_list_finish(iter);
|
||||
|
||||
error_list_start:
|
||||
error_ntop_addr:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -194,7 +225,7 @@ int patty_ax25_if_addr_add(patty_ax25_if *iface,
|
|||
goto error_pton;
|
||||
}
|
||||
|
||||
if ((patty_list_append(iface->addrs, addr)) == NULL) {
|
||||
if ((patty_list_append(iface->aliases, addr)) == NULL) {
|
||||
goto error_list_append;
|
||||
}
|
||||
|
||||
|
@ -212,7 +243,7 @@ error_exists:
|
|||
int patty_ax25_if_addr_delete(patty_ax25_if *iface,
|
||||
const char *callsign,
|
||||
uint8_t ssid) {
|
||||
patty_list_item *item = iface->addrs->first;
|
||||
patty_list_item *item = iface->aliases->first;
|
||||
int i = 0;
|
||||
|
||||
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 (patty_list_splice(iface->addrs, i) == NULL) {
|
||||
if (patty_list_splice(iface->aliases, i) == NULL) {
|
||||
goto error_list_splice;
|
||||
}
|
||||
}
|
||||
|
|
36
src/kiss.c
36
src/kiss.c
|
@ -17,8 +17,14 @@ enum kiss_flags {
|
|||
KISS_ESCAPE = 1 << 2
|
||||
};
|
||||
|
||||
enum tnc_opts {
|
||||
TNC_NONE = 0,
|
||||
TNC_CLOSE_ON_DESTROY = 1 << 0
|
||||
};
|
||||
|
||||
struct _patty_kiss_tnc {
|
||||
int fd;
|
||||
int fd,
|
||||
opts;
|
||||
|
||||
void *buf,
|
||||
*frame;
|
||||
|
@ -30,7 +36,7 @@ struct _patty_kiss_tnc {
|
|||
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;
|
||||
|
||||
if ((tnc = malloc(sizeof(*tnc))) == NULL) {
|
||||
|
@ -42,6 +48,7 @@ patty_kiss_tnc *patty_kiss_tnc_open_fd(int fd) {
|
|||
}
|
||||
|
||||
tnc->fd = fd;
|
||||
tnc->opts = TNC_NONE;
|
||||
tnc->bufsz = PATTY_KISS_BUFSZ;
|
||||
tnc->offset = 0;
|
||||
tnc->dropped = 0;
|
||||
|
@ -56,7 +63,7 @@ error_malloc_tnc:
|
|||
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;
|
||||
int fd;
|
||||
|
||||
|
@ -64,13 +71,15 @@ patty_kiss_tnc *patty_kiss_tnc_open(const char *device) {
|
|||
goto error_open;
|
||||
}
|
||||
|
||||
if ((tnc = patty_kiss_tnc_open_fd(fd)) == NULL) {
|
||||
goto error_tnc_open_fd;
|
||||
if ((tnc = patty_kiss_tnc_new_fd(fd)) == NULL) {
|
||||
goto error_tnc_new_fd;
|
||||
}
|
||||
|
||||
tnc->opts |= TNC_CLOSE_ON_DESTROY;
|
||||
|
||||
return tnc;
|
||||
|
||||
error_tnc_open_fd:
|
||||
error_tnc_new_fd:
|
||||
close(fd);
|
||||
|
||||
error_open:
|
||||
|
@ -81,10 +90,13 @@ int patty_kiss_tnc_fd(patty_kiss_tnc *tnc) {
|
|||
return tnc->fd;
|
||||
}
|
||||
|
||||
void patty_kiss_tnc_close(patty_kiss_tnc *tnc) {
|
||||
close(tnc->fd);
|
||||
free(tnc->buf);
|
||||
free(tnc);
|
||||
void patty_kiss_tnc_destroy(patty_kiss_tnc *tnc) {
|
||||
if (tnc->opts & TNC_CLOSE_ON_DESTROY) {
|
||||
close(tnc->fd);
|
||||
}
|
||||
|
||||
free(tnc->buf);
|
||||
free(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;
|
||||
|
||||
if (tnc->offset == tnc->readlen) {
|
||||
errno = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -208,6 +222,8 @@ done:
|
|||
if (flags & KISS_FRAME) {
|
||||
tnc_drop(tnc);
|
||||
|
||||
errno = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
21
src/route.c
21
src/route.c
|
@ -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_addr *dest) {
|
||||
patty_ax25_route *route;
|
||||
uint32_t hash;
|
||||
|
||||
patty_hash_init(&hash);
|
||||
patty_ax25_addr_hash(&hash, dest);
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
65
src/server.c
65
src/server.c
|
@ -15,6 +15,8 @@
|
|||
typedef int (*patty_ax25_server_call)(patty_ax25_server *, int);
|
||||
|
||||
struct _patty_ax25_server {
|
||||
char path[PATTY_AX25_SOCK_PATH_SIZE];
|
||||
|
||||
int fd, /* fd of UNIX domain socket */
|
||||
fd_max;
|
||||
|
||||
|
@ -38,7 +40,7 @@ struct _patty_ax25_server {
|
|||
*clients_by_sock;
|
||||
};
|
||||
|
||||
patty_ax25_server *patty_ax25_server_new() {
|
||||
patty_ax25_server *patty_ax25_server_new(const char *path) {
|
||||
patty_ax25_server *server;
|
||||
|
||||
if ((server = malloc(sizeof(*server))) == NULL) {
|
||||
|
@ -47,6 +49,8 @@ patty_ax25_server *patty_ax25_server_new() {
|
|||
|
||||
memset(server, '\0', sizeof(*server));
|
||||
|
||||
strncpy(server->path, path, PATTY_AX25_SOCK_PATH_SIZE);
|
||||
|
||||
if ((server->ifaces = patty_list_new()) == NULL) {
|
||||
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_sock *sock;
|
||||
patty_ax25_route *route;
|
||||
patty_ax25_if *iface;
|
||||
|
||||
if (read(client, &request, sizeof(request)) < 0) {
|
||||
goto error_io;
|
||||
|
@ -750,6 +756,43 @@ static int server_connect(patty_ax25_server *server,
|
|||
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));
|
||||
|
||||
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
|
||||
* 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;
|
||||
|
||||
error_sock_send_sabm:
|
||||
error_network_down:
|
||||
error_invalid_status:
|
||||
error_sock_by_fd:
|
||||
if (write(client, &response, sizeof(response)) < 0) {
|
||||
|
@ -956,11 +1007,18 @@ static int handle_client(void *key,
|
|||
goto error_io;
|
||||
}
|
||||
|
||||
if (server_calls[call] == NULL) {
|
||||
errno = ENOSYS;
|
||||
|
||||
goto error_not_implemented;
|
||||
}
|
||||
|
||||
return server_calls[call](server, client);
|
||||
|
||||
done:
|
||||
return 0;
|
||||
|
||||
error_not_implemented:
|
||||
error_dict_delete:
|
||||
error_io:
|
||||
return -1;
|
||||
|
@ -1101,7 +1159,7 @@ static int handle_socks(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;
|
||||
}
|
||||
|
||||
|
@ -1109,11 +1167,10 @@ int patty_ax25_server_run(patty_ax25_server *server) {
|
|||
int nready;
|
||||
|
||||
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,
|
||||
&server->fds_r,
|
||||
&server->fds_w,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL)) < 0) {
|
||||
goto error_io;
|
||||
|
|
36
src/sock.c
36
src/sock.c
|
@ -1,5 +1,6 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <patty/ax25.h>
|
||||
|
||||
|
@ -27,3 +28,38 @@ error_malloc_sock:
|
|||
void patty_ax25_sock_destroy(patty_ax25_sock *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);
|
||||
}
|
||||
|
|
|
@ -32,10 +32,15 @@ int main(int argc, char **argv) {
|
|||
int fd,
|
||||
sock;
|
||||
|
||||
patty_ax25_addr peer;
|
||||
char path[256];
|
||||
|
||||
if (argc != 2) {
|
||||
usage(argc, argv, "No patty socket provided");
|
||||
}
|
||||
|
||||
patty_ax25_pton("GB9BLM", 0, &peer);
|
||||
|
||||
if ((fd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) {
|
||||
fprintf(stderr, "%s: %s: %s: %s\n",
|
||||
argv[0], "socket()", argv[1], strerror(errno));
|
||||
|
@ -58,14 +63,14 @@ int main(int argc, char **argv) {
|
|||
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",
|
||||
argv[0], "patty_ax25_call_close()", strerror(errno));
|
||||
argv[0], "patty_ax25_call_connect()", strerror(errno));
|
||||
|
||||
goto error_call_close;
|
||||
}
|
||||
|
||||
fprintf(stderr, "got sock %d\n", sock);
|
||||
fprintf(stderr, "connected sock %d\n", sock);
|
||||
|
||||
close(fd);
|
||||
|
||||
|
|
|
@ -1,8 +1,13 @@
|
|||
#define _GNU_SOURCE
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.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 <patty/ax25.h>
|
||||
|
@ -17,7 +22,7 @@ static void usage(int argc, char **argv, const char *message, ...) {
|
|||
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);
|
||||
}
|
||||
|
@ -27,22 +32,57 @@ int main(int argc, char **argv) {
|
|||
patty_ax25_if *iface;
|
||||
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");
|
||||
} 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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
if (patty_ax25_if_addr_add(iface, "KZ3ROX", 0) < 0) {
|
||||
goto error_if_addr_add;
|
||||
}
|
||||
|
||||
if (patty_ax25_server_add_if(server, iface) < 0) {
|
||||
goto error_server_add_if;
|
||||
}
|
||||
|
@ -70,10 +110,12 @@ error_server_run:
|
|||
error_server_add_route:
|
||||
error_route_new_default:
|
||||
error_server_add_if:
|
||||
error_if_addr_add:
|
||||
error_if_new:
|
||||
patty_ax25_server_destroy(server);
|
||||
|
||||
error_server_new:
|
||||
close(info.fd);
|
||||
|
||||
error_open:
|
||||
return 1;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue