Add command-line and config options to set an TCP socket address (#53)

Still no IPv6 support though.
This commit is contained in:
Victor Antonovich 2019-07-16 11:14:37 +04:00
parent 2465860496
commit 2aa063db79
9 changed files with 56 additions and 23 deletions

View File

@ -53,8 +53,8 @@ Usage:
------
mbusd [-h] [-d] [-L logfile] [-v level] [-c cfgfile] [-p device] [-s speed] [-m mode]
[-t] [-y file] [-Y file] [-P port] [-C maxconn] [-N retries]
[-R pause] [-W wait] [-T timeout]
[-t] [-y file] [-Y file] [-A address] [-P port] [-C maxconn] [-N retries]
[-R pause] [-W wait] [-T timeout]
-h Usage help.
-d Instruct mbusd not to fork itself (non-daemonize).
@ -80,6 +80,8 @@ Usage:
-Y file
Enable RS-485 direction data direction control by writing '0' to file
for transmitter enable and '1' to file for transmitter disable
-A address
Specifies TCP address to bind (default 0.0.0.0).
-P port
Specifies TCP port number (default 502).
-C maxconn

View File

@ -23,6 +23,9 @@ trx_control = addc
############# TCP port settings #############
# TCP server address to bind
address = 0.0.0.0
# TCP server port number
port = 502

View File

@ -22,6 +22,8 @@ mbusd \- MODBUS/TCP to MODBUS/RTU gateway.
.IR file ]
.RB [ -Y
.IR file ]
.RB [ -A
.IR address ]
.RB [ -P
.IR port ]
.RB [ -C
@ -57,6 +59,8 @@ Specifies serial port device name.
Specifies serial port speed.
.IP "\fB-m \fImode\fR"
Specifies serial port mode (like 8N1).
.IP "\fB-A \fIaddress\fR"
Specifies TCP address to bind.
.IP "\fB-P \fIport\fR"
Specifies TCP port number.
.IP \fB-t\fR

View File

@ -67,6 +67,7 @@ cfg_init(void)
cfg.trxcntl = TRX_ADDC;
*cfg.trxcntl_file = '\0';
#endif
strncpy(cfg.serveraddr, DEFAULT_SERVERADDR, INTBUFSIZE);
cfg.serverport = DEFAULT_SERVERPORT;
cfg.maxconn = DEFAULT_MAXCONN;
cfg.maxtry = DEFAULT_MAXTRY;
@ -122,6 +123,10 @@ cfg_handle_param(char *name, char *value)
}
strncpy(cfg.ttymode, value, INTBUFSIZE);
}
else if (CFG_NAME_MATCH("address"))
{
strncpy(cfg.serveraddr, value, INTBUFSIZE);
}
else if (CFG_NAME_MATCH("port"))
{
cfg.serverport = strtoul(value, NULL, 0);

View File

@ -58,6 +58,8 @@ typedef struct
int trxcntl;
/* trx control sysfs file */
char trxcntl_file[INTBUFSIZE + 1];
/* TCP server address */
char serveraddr[INTBUFSIZE + 1];
/* TCP server port number */
int serverport;
/* maximum number of connections */

View File

@ -113,13 +113,12 @@ conn_init(void)
state_tty_set(&tty, TTY_PAUSE);
/* create server socket */
if ((server_sd =
sock_create_server("", cfg.serverport, TRUE)) < 0)
if ((server_sd = sock_create_server(cfg.serveraddr, cfg.serverport, TRUE)) < 0)
{
#ifdef LOG
logw(0, "conn_init():"
" can't create listen() socket (%s)",
strerror(errno));
" can't create listen socket (%s)",
(errno != 0) ? strerror(errno) : "failed");
#endif
return RC_ERR;
}

View File

@ -46,6 +46,7 @@
/*
* Default values
*/
#define DEFAULT_SERVERADDR "0.0.0.0"
#define DEFAULT_SERVERPORT 502
#define DEFAULT_MAXCONN 32
#define DEFAULT_MAXTRY 3

View File

@ -111,7 +111,8 @@ usage(char *exename)
#ifdef TRXCTL
" [-t] [-y sysfsfile] [-Y sysfsfile]\n"
#endif
" [-P port] [-C maxconn] [-N retries] [-R pause] [-W wait] [-T timeout]\n\n"
" [-A address] [-P port] [-C maxconn] [-N retries]\n"
" [-R pause] [-W wait] [-T timeout]\n\n"
"Options:\n"
" -h : this help\n"
" -d : don't daemonize\n"
@ -128,6 +129,7 @@ usage(char *exename)
" -p device : set serial port device name (default %s)\n"
" -s speed : set serial port speed (default %d)\n"
" -m mode : set serial port mode (default %s)\n"
" -A address : set TCP server address to bind (default %s)\n"
" -P port : set TCP server port number (default %d)\n"
#ifdef TRXCTL
" -t : enable RTS RS-485 data direction control using RTS\n"
@ -148,7 +150,8 @@ usage(char *exename)
#ifdef LOG
LOGPATH, LOGNAME, cfg.dbglvl,
#endif
cfg.ttyport, cfg.ttyspeed, cfg.ttymode, cfg.serverport,
cfg.ttyport, cfg.ttyspeed, cfg.ttymode,
cfg.serveraddr, cfg.serverport,
MAX_MAXCONN, cfg.maxconn, MAX_MAXTRY, cfg.maxtry,
MAX_RQSTPAUSE, cfg.rqstpause, MAX_RESPWAIT, cfg.respwait,
MAX_CONNTIMEOUT, cfg.conntimeout);
@ -180,7 +183,7 @@ main(int argc, char *argv[])
#ifdef LOG
"v:L:"
#endif
"p:s:m:P:C:N:R:W:T:c:")) != RC_ERR)
"p:s:m:A:P:C:N:R:W:T:c:")) != RC_ERR)
{
switch (rc)
{
@ -290,6 +293,9 @@ main(int argc, char *argv[])
exit(-1);
}
break;
case 'A':
strncpy(cfg.serveraddr, optarg, INTBUFSIZE);
break;
case 'P':
cfg.serverport = strtoul(optarg, NULL, 0);
break;

View File

@ -94,13 +94,33 @@ sock_create(int blkmode)
* Return: socket descriptor, otherwise RC_ERR if there some errors
*/
int
sock_create_server(char *server_ip,
unsigned short server_port, int blkmode)
sock_create_server(char *server_ip, unsigned short server_port, int blkmode)
{
struct sockaddr_in server_sockaddr;
int sock_opt = 1;
int server_s;
memset(&server_sockaddr, 0, sizeof(server_sockaddr));
server_sockaddr.sin_family = AF_INET; // FIXME IPv6 support
/* parse address to bind socket */
if (server_ip != NULL)
{
if (inet_aton(server_ip, &server_sockaddr.sin_addr) == 0)
{
#ifdef LOG
logw(0, "sock_create_server():"
" can't parse address: %s",
server_ip);
#endif
return RC_ERR;
}
}
else
server_sockaddr.sin_addr.s_addr = htonl(INADDR_ANY);
server_sockaddr.sin_port = htons(server_port);
/* create socket in desired blocking mode */
server_s = sock_create(blkmode);
if (server_s < 0) return server_s;
@ -144,18 +164,9 @@ sock_create_server(char *server_ip,
return RC_ERR;
}
memset(&server_sockaddr, 0, sizeof(server_sockaddr));
server_sockaddr.sin_family = AF_INET;
if (server_ip != NULL)
inet_aton(server_ip, &server_sockaddr.sin_addr);
else
server_sockaddr.sin_addr.s_addr = htonl(INADDR_ANY);
server_sockaddr.sin_port = htons(server_port);
/* bind socket to given address and port */
if (bind(server_s, (struct sockaddr *) & server_sockaddr,
sizeof(server_sockaddr)) == -1)
sizeof(server_sockaddr)) == -1)
{
#ifdef LOG
logw(0, "sock_create_server():"
@ -207,7 +218,7 @@ sock_accept(int server_sd, struct sockaddr_in *rmt_addr, int blkmode)
if (sock_set_blkmode(sd, blkmode) == RC_ERR)
{
#ifdef LOG
logw(0, "sock_accept(): can't set socket blocking mode (%s)",
logw(0, "sock_accept(): can't set socket blocking mode (%s)",
strerror(errno));
#endif
close(sd);