nvtsrv: Add test server
This commit is contained in:
+221
@@ -0,0 +1,221 @@
|
||||
/*
|
||||
* RFC2217 test server
|
||||
*/
|
||||
#include <poll.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "lib/nvt_log.h"
|
||||
#include "lib/nvt_socket.h"
|
||||
#include "telnet.h"
|
||||
|
||||
#define MATCH(s1, s2) (strcmp(s1, s2) == 0)
|
||||
|
||||
struct {
|
||||
unsigned char mline;
|
||||
tn_ctx_t *tnct;
|
||||
} dd;
|
||||
|
||||
struct pollfd pfds[3];
|
||||
int nfds;
|
||||
|
||||
#define fd_srv pfds[1].fd
|
||||
#define fd_cli pfds[2].fd
|
||||
|
||||
|
||||
static void _nvtsrv_usage(void)
|
||||
{
|
||||
printf("Usage:\n" " nvtsrv host:port\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
static void _tn_cli_close(void)
|
||||
{
|
||||
int i = 2;
|
||||
|
||||
printf("%d: fd=%d: Closed\n", i, pfds[i].fd);
|
||||
close(pfds[i].fd);
|
||||
pfds[i].fd = -1;
|
||||
nfds = 2;
|
||||
}
|
||||
|
||||
static void _tn_tx(void *cctx, const void *buf, int len)
|
||||
{
|
||||
int nw;
|
||||
|
||||
nvt_log_buf(LOG_INFO, "Tx", buf, len);
|
||||
|
||||
if (fd_cli < 0)
|
||||
{
|
||||
printf("Write fd is closed - drop Tx\n");
|
||||
return;
|
||||
}
|
||||
|
||||
nw = write(fd_cli, buf, len);
|
||||
if (nw != len)
|
||||
{
|
||||
printf("Write failed %d != %d\n", nw, len);
|
||||
_tn_cli_close();
|
||||
}
|
||||
}
|
||||
|
||||
static void _tn_ss(void *cctx, int signal, int value)
|
||||
{
|
||||
printf("RFC2217 signal %d: %02x", signal, value);
|
||||
}
|
||||
|
||||
static void _nvtsrv_init(void)
|
||||
{
|
||||
free(dd.tnct);
|
||||
|
||||
memset(&dd, 0, sizeof(dd));
|
||||
|
||||
dd.tnct = telnet_ctx_init(NULL, _tn_tx, _tn_ss);
|
||||
}
|
||||
|
||||
static void _nvtsrv_cmd(tn_ctx_t * tcc, const char *line)
|
||||
{
|
||||
char cmd[8];
|
||||
const char *args;
|
||||
int len, val;
|
||||
|
||||
cmd[0] = '\0';
|
||||
len = 0;
|
||||
sscanf(line, "%7s %n", cmd, &len);
|
||||
args = line + len;
|
||||
|
||||
if (MATCH(cmd, "w"))
|
||||
{
|
||||
_tn_tx(NULL, args, strlen(args));
|
||||
}
|
||||
else if (MATCH(cmd, "m"))
|
||||
{
|
||||
sscanf(args, "%x", &val);
|
||||
telnet_rfc2217_change_modemstate(tcc, val);
|
||||
}
|
||||
}
|
||||
|
||||
static void _nvtsrv_set_signal_handlers(void)
|
||||
{
|
||||
struct sigaction sa = {
|
||||
.sa_handler = SIG_IGN,
|
||||
.sa_flags = SA_RESTART,
|
||||
};
|
||||
|
||||
sigemptyset(&sa.sa_mask);
|
||||
sigaction(SIGPIPE, &sa, NULL);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const char *s;
|
||||
char buf[128];
|
||||
int rc, nr, i, len;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
s = *argv++;
|
||||
argc--;
|
||||
if (*s != '-')
|
||||
break;
|
||||
}
|
||||
|
||||
if (argc <= 0)
|
||||
_nvtsrv_usage();
|
||||
|
||||
nvt_log_level(0, 10);
|
||||
nvt_log_dest(NVT_LOG_STDOUT);
|
||||
|
||||
_nvtsrv_set_signal_handlers();
|
||||
|
||||
memset(pfds, 0, sizeof(pfds));
|
||||
|
||||
pfds[0].fd = STDIN_FILENO;
|
||||
pfds[0].events = POLLIN;
|
||||
|
||||
pfds[1].fd = socket_create_server(argv[0]);
|
||||
pfds[1].events = POLLIN;
|
||||
|
||||
pfds[2].fd = -1;
|
||||
pfds[2].events = POLLIN;
|
||||
|
||||
nfds = 2;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
for (i = 0; i < 3; i++)
|
||||
pfds[i].revents = 0;
|
||||
|
||||
rc = poll(pfds, nfds, -1);
|
||||
if (rc < 0)
|
||||
{
|
||||
printf("poll failed: %m\n");
|
||||
break;
|
||||
}
|
||||
|
||||
i = 0;
|
||||
if (pfds[i].revents)
|
||||
{
|
||||
nr = read(pfds[i].fd, buf, sizeof(buf) - 1);
|
||||
if (nr <= 0)
|
||||
break;
|
||||
buf[nr] = 0;
|
||||
len = strcspn(buf, "\n\r");
|
||||
buf[len] = 0;
|
||||
// printf("%d: fd=%d: r %d: '%.*s'\n", i, pfds[i].fd, nr, nr, buf);
|
||||
_nvtsrv_cmd(dd.tnct, buf);
|
||||
}
|
||||
|
||||
i = 2;
|
||||
if (pfds[i].revents)
|
||||
{
|
||||
nr = 0;
|
||||
if (pfds[i].revents & POLLIN)
|
||||
{
|
||||
nr = read(pfds[i].fd, buf, sizeof(buf));
|
||||
if (nr <= 0)
|
||||
{
|
||||
_tn_cli_close();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (pfds[i].revents & (POLLERR | POLLHUP))
|
||||
{
|
||||
_tn_cli_close();
|
||||
}
|
||||
|
||||
if (nr > 0)
|
||||
{
|
||||
buf[nr] = 0;
|
||||
len = strcspn(buf, "\n\r");
|
||||
buf[len] = 0;
|
||||
nvt_log_buf(LOG_INFO, "Rx", buf, nr);
|
||||
// printf("%d: fd=%d: r %d: '%.*s'\n", i, pfds[i].fd, nr, nr, buf);
|
||||
len = nr;
|
||||
rc = telnet_rx(dd.tnct, buf, &len);
|
||||
printf("%d: fd=%d: r %d: '%.*s'\n", i, pfds[i].fd, rc, len,
|
||||
buf);
|
||||
}
|
||||
}
|
||||
|
||||
i = 1;
|
||||
if (pfds[i].revents)
|
||||
{
|
||||
if (pfds[2].fd >= 0)
|
||||
{
|
||||
printf("Client already connected on fd=%d\n", pfds[2].fd);
|
||||
break;
|
||||
}
|
||||
pfds[2].fd = socket_create_server_client(pfds[i].fd);
|
||||
printf("%d: fd=%d: Connected\n", 2, pfds[2].fd);
|
||||
pfds[2].events = POLLIN;
|
||||
nfds = 3;
|
||||
_nvtsrv_init();
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user