diff options
author | Christian Poessinger <christian@poessinger.com> | 2020-05-23 20:14:41 +0200 |
---|---|---|
committer | Christian Poessinger <christian@poessinger.com> | 2020-06-18 21:45:14 +0200 |
commit | 4384a2973993b8b0f572912026f45e9ee910e3ec (patch) | |
tree | 88943c5ae286a5809b3d1ac8a59e936304f783af | |
parent | 4b5793bced424034daa944400eb8c2f198d0d0d2 (diff) | |
download | vyos-1x-4384a2973993b8b0f572912026f45e9ee910e3ec.tar.gz vyos-1x-4384a2973993b8b0f572912026f45e9ee910e3ec.zip |
console-server: T2490: initial support
-rw-r--r-- | data/templates/ser2net/ser2net.conf.tmpl | 78 | ||||
-rw-r--r-- | debian/control | 1 | ||||
-rw-r--r-- | interface-definitions/ser2net.xml.in | 82 | ||||
-rwxr-xr-x | src/conf_mode/ser2net.py | 116 | ||||
-rw-r--r-- | src/systemd/ser2net.service | 13 |
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 |