summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Poessinger <christian@poessinger.com>2020-05-23 20:14:41 +0200
committerChristian Poessinger <christian@poessinger.com>2020-06-18 21:45:14 +0200
commit4384a2973993b8b0f572912026f45e9ee910e3ec (patch)
tree88943c5ae286a5809b3d1ac8a59e936304f783af
parent4b5793bced424034daa944400eb8c2f198d0d0d2 (diff)
downloadvyos-1x-4384a2973993b8b0f572912026f45e9ee910e3ec.tar.gz
vyos-1x-4384a2973993b8b0f572912026f45e9ee910e3ec.zip
console-server: T2490: initial support
-rw-r--r--data/templates/ser2net/ser2net.conf.tmpl78
-rw-r--r--debian/control1
-rw-r--r--interface-definitions/ser2net.xml.in82
-rwxr-xr-xsrc/conf_mode/ser2net.py116
-rw-r--r--src/systemd/ser2net.service13
5 files changed, 290 insertions, 0 deletions
diff --git a/data/templates/ser2net/ser2net.conf.tmpl b/data/templates/ser2net/ser2net.conf.tmpl
new file mode 100644
index 000000000..202fe8104
--- /dev/null
+++ b/data/templates/ser2net/ser2net.conf.tmpl
@@ -0,0 +1,78 @@
+### Autogenerated by ser2net.py ###
+
+# This is the configuration file for ser2net. It has the following format:
+# <TCP port>:<state>:<timeout>:<device>:<options>
+# TCP port
+# Name or number of the TCP/IP port to accept con-
+# nections from for this device. A port number may
+# be of the form [host,]port, such as 127.0.0.1,2000
+# or localhost,2000. If this is specified, it will
+# only bind to the IP address specified. Otherwise
+# it will bind to all the ports on the machine.
+#
+# state Either raw or rawlp or telnet or off. off disables
+# the port from accepting connections. It can be
+# turned on later from the control port. raw enables
+# the port and transfers all data as-is between the
+# port and the long. rawlp enables the port and
+# transfers all input data to device, device is open
+# without any termios setting. It allow to use
+# /dev/lpX devices and printers connected to them.
+# telnet enables the port and runs the telnet proto-
+# col on the port to set up telnet parameters. This
+# is most useful for using telnet.
+#
+# timeout
+# The time (in seconds) before the port will be dis-
+# connected if there is no activity on it. A zero
+# value disables this funciton.
+#
+# device The name of the device to connect to. This
+# must be in the form of /dev/<device>.
+#
+# options
+# Sets operational parameters for the serial port.
+# Options 300, 1200, 2400, 4800, 9600, 19200, 38400,
+# 57600, 115200 set the various baud rates. EVEN,
+# ODD, NONE set the parity. 1STOPBIT, 2STOPBITS set
+# the number of stop bits. 7DATABITS, 8DATABITS set
+# the number of data bits. [-]XONXOFF turns on (-
+# off) XON/XOFF support. [-]RTSCTS turns on (- off)
+# hardware flow control, [-]LOCAL turns off (- on)
+# monitoring of the modem lines, and
+# [-]HANGUP_WHEN_DONE turns on (- off) lowering the
+# modem control lines when the connextion is done.
+# NOBREAK disables automatic setting of the break
+# setting of the serial port.
+# The "remctl" option allow remote control (ala RFC
+# 2217) of serial-port configuration. A banner name
+# may also be specified, that banner will be printed
+# for the line. If no banner is given, then no
+# banner is printed.
+#
+# or...
+
+# BANNER:<banner name>:banner
+# This will create a banner, if the banner name is given in the
+# options of a line, that banner will be printed. This takes the
+# standard "C" \x characters (\r is carraige return, \n is newline,
+# etc.). It also accepts \d, which prints the device name, \p,
+# which prints the TCP port number, and \s which prints the serial
+# parameters (eg 9600N81). Banners can span lines if the last
+# character on a line is '\'. Note that you *must* use \r\n to
+# start a new line.
+#
+# Note that the same device can be listed multiple times under different
+# ports, this allows the same serial port to have both telnet and raw
+# protocols.
+
+# The original config file shipped with the upstream sources can be
+# found in /usr/share/doc/ser2net/examples
+
+BANNER:banner:\r\nser2net port \p device \d [\s] (VyOS)\r\n\r\n
+
+#3001:telnet:600:/dev/ttyS1:19200 8DATABITS NONE 1STOPBIT banner
+
+{% for d in devices %}
+localhost,{{ d.port }}:telnet:{{ d.timeout }}:{{ d.serial_port }}:{{ d.speed }} {{ d.data_bits}}DATABITS {{ d.parity | upper }} {{ d.stop_bits}}STOPBIT banner
+{% endfor %}
diff --git a/debian/control b/debian/control
index 104a267ea..aa1e87e23 100644
--- a/debian/control
+++ b/debian/control
@@ -59,6 +59,7 @@ Depends: python3,
iputils-arping,
libvyosconfig0,
beep,
+ ser2net,
isc-dhcp-server,
isc-dhcp-relay,
keepalived (>=2.0.5),
diff --git a/interface-definitions/ser2net.xml.in b/interface-definitions/ser2net.xml.in
new file mode 100644
index 000000000..84bb82a20
--- /dev/null
+++ b/interface-definitions/ser2net.xml.in
@@ -0,0 +1,82 @@
+<?xml version="1.0"?>
+<interfaceDefinition>
+ <node name="service">
+ <children>
+ <node name="ser2net" owner="${vyos_conf_scripts_dir}/ser2net.py">
+ <properties>
+ <help>Serial to Network</help>
+ </properties>
+ <children>
+ <tagNode name="device">
+ <properties>
+ <help>System serial interface name (ttyS or ttyUSB)</help>
+ <completionHelp>
+ <script>find /dev -name ttyS* -exec basename {} \; | sort</script>
+ <script>find /dev -name ttyUSB* -exec basename {} \; | sort</script>
+ </completionHelp>
+ <valueHelp>
+ <format>ttySxxx</format>
+ <description>Regular serial interface</description>
+ </valueHelp>
+ <valueHelp>
+ <format>ttyUSBxxx</format>
+ <description>USB based serial interface</description>
+ </valueHelp>
+ <constraint>
+ <regex>^tty(S|USB)[0-9]+$</regex>
+ </constraint>
+ </properties>
+ <children>
+ #include <include/interface-description.xml.i>
+ #include <include/port-number.xml.i>
+ <leafNode name="speed">
+ <properties>
+ <help>Serial port baud rate</help>
+ <completionHelp>
+ <list>300 1200 2400 4800 9600 19200 38400 57600 115200</list>
+ </completionHelp>
+ <constraint>
+ <regex>(300|1200|2400|4800|9600|19200|38400|57600|115200)</regex>
+ </constraint>
+ </properties>
+ </leafNode>
+ <leafNode name="data-bits">
+ <properties>
+ <help>Serial port data bits</help>
+ <completionHelp>
+ <list>7 8</list>
+ </completionHelp>
+ <constraint>
+ <regex>(7|8)</regex>
+ </constraint>
+ </properties>
+ </leafNode>
+ <leafNode name="stop-bits">
+ <properties>
+ <help>Serial port stop bits</help>
+ <completionHelp>
+ <list>1 2</list>
+ </completionHelp>
+ <constraint>
+ <regex>(1|2)</regex>
+ </constraint>
+ </properties>
+ </leafNode>
+ <leafNode name="parity">
+ <properties>
+ <help>Parity setting</help>
+ <completionHelp>
+ <list>even odd none</list>
+ </completionHelp>
+ <constraint>
+ <regex>(even|odd|none)</regex>
+ </constraint>
+ </properties>
+ </leafNode>
+ </children>
+ </tagNode>
+ </children>
+ </node>
+ </children>
+ </node>
+</interfaceDefinition>
diff --git a/src/conf_mode/ser2net.py b/src/conf_mode/ser2net.py
new file mode 100755
index 000000000..5231a6a05
--- /dev/null
+++ b/src/conf_mode/ser2net.py
@@ -0,0 +1,116 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2018-2020 VyOS maintainers and contributors
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or later as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+import os
+
+from copy import deepcopy
+from sys import exit
+
+from vyos.config import Config
+from vyos.template import render
+from vyos.util import call
+from vyos import ConfigError
+
+config_file = r'/run/ser2net/ser2net.conf'
+
+default_config_data = {
+ 'devices': [],
+}
+
+def get_config():
+ ser2net = deepcopy(default_config_data)
+ conf = Config()
+ base = ['service', 'ser2net']
+
+ if not conf.exists(base):
+ return None
+ else:
+ conf.set_level(base)
+
+ for serial_port in conf.list_nodes(['device']):
+ conf.set_level(base + ['device', serial_port])
+ serial = {
+ 'data_bits': '',
+ 'parity': '',
+ 'port': '',
+ 'serial_port': '/dev/' + serial_port,
+ 'speed': '',
+ 'stop_bits': '',
+ 'timeout': '600'
+ }
+
+ if conf.exists(['data-bits']):
+ serial['data_bits'] = conf.return_value(['data-bits'])
+
+ if conf.exists(['stop-bits']):
+ serial['stop_bits'] = conf.return_value(['stop-bits'])
+
+ if conf.exists(['parity']):
+ serial['parity'] = conf.return_value(['parity'])
+
+ if conf.exists(['port']):
+ serial['port'] = conf.return_value(['port'])
+
+ if conf.exists(['speed']):
+ serial['speed'] = conf.return_value(['speed'])
+
+ ser2net['devices'].append(serial)
+
+ return ser2net
+
+def verify(ser2net):
+ if not ser2net:
+ return None
+
+ for device in ser2net['devices']:
+ if not os.path.exists('{serial_port}'.format(**device)):
+ raise ConfigError('Serial interface "{serial_port} does not exist"'
+ .format(**device))
+
+ for key in ['data_bits', 'parity', 'port', 'speed', 'stop_bits']:
+ if not device[key]:
+ value = key.replace('_','-')
+ raise ConfigError(f'{value} option must be defined!')
+
+ return None
+
+def generate(ser2net):
+ if not ser2net:
+ return None
+
+ render(config_file, 'ser2net/ser2net.conf.tmpl', ser2net)
+ return None
+
+def apply(ser2net):
+ if not ser2net:
+ call('systemctl stop ser2net.service')
+ if os.path.isfile(config_file):
+ os.unlink(config_file)
+
+ return None
+
+ call('systemctl restart ser2net.service')
+ return None
+
+if __name__ == '__main__':
+ try:
+ c = get_config()
+ verify(c)
+ generate(c)
+ apply(c)
+ except ConfigError as e:
+ print(e)
+ exit(1)
diff --git a/src/systemd/ser2net.service b/src/systemd/ser2net.service
new file mode 100644
index 000000000..a5b4243af
--- /dev/null
+++ b/src/systemd/ser2net.service
@@ -0,0 +1,13 @@
+[Unit]
+Description=Serial to Network Proxy
+ConditionPathExists=/run/ser2net/ser2net.conf
+After=vyos-router.service
+
+[Service]
+WorkingDirectory=/run/ser2net
+PIDFile=/run/ser2net/ser2net.pid
+ExecStart=/usr/sbin/ser2net -n -c /run/ser2net/ser2net.conf -P /run/ser2net/ser2net.pid -p localhost,2000
+Restart=always
+
+[Install]
+WantedBy=multi-user.target