From 0cbe4cd087aeeb435e2d34820aa34fb7af1add21 Mon Sep 17 00:00:00 2001 From: Viacheslav Hletenko Date: Fri, 8 Jul 2022 21:50:14 +0000 Subject: conntrack: T4145: Add show conntrack table ipv4 After firewall rewriting, we lost the ability to show conntrack table as it used old code Rewrite and add it to XML/Python --- op-mode-definitions/show-conntrack.xml.in | 27 ++++++++++ src/op_mode/show_conntrack.py | 84 +++++++++++++++++++++++++++++++ 2 files changed, 111 insertions(+) create mode 100644 op-mode-definitions/show-conntrack.xml.in create mode 100755 src/op_mode/show_conntrack.py diff --git a/op-mode-definitions/show-conntrack.xml.in b/op-mode-definitions/show-conntrack.xml.in new file mode 100644 index 000000000..792623d7d --- /dev/null +++ b/op-mode-definitions/show-conntrack.xml.in @@ -0,0 +1,27 @@ + + + + + + + Show conntrack tables entries + + + + + Show conntrack entries for table + + + + + Show conntrack entries for IPv4 protocol + + sudo ${vyos_op_scripts_dir}/show_conntrack.py + + + + + + + + diff --git a/src/op_mode/show_conntrack.py b/src/op_mode/show_conntrack.py new file mode 100755 index 000000000..4eb160d97 --- /dev/null +++ b/src/op_mode/show_conntrack.py @@ -0,0 +1,84 @@ +#!/usr/bin/env python3 +# +# Copyright (C) 2022 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 . + +import xmltodict + +from tabulate import tabulate +from vyos.util import cmd + + +def _get_raw_data(): + """ + Get conntrack XML output + """ + return cmd(f'sudo conntrack --dump --output xml') + + +def _xml_to_dict(xml): + """ + Convert XML to dictionary + Return: dictionary + """ + parse = xmltodict.parse(xml) + # If only one conntrack entry we must change dict + if 'meta' in parse['conntrack']['flow']: + return dict(conntrack={'flow': [parse['conntrack']['flow']]}) + return parse + + +def _get_formatted_output(xml): + """ + :param xml: + :return: formatted output + """ + data_entries = [] + dict_data = _xml_to_dict(xml) + for entry in dict_data['conntrack']['flow']: + src, dst, sport, dport, proto = {}, {}, {}, {}, {} + for meta in entry['meta']: + direction = meta['@direction'] + if direction in ['original']: + if 'layer3' in meta: + src = meta['layer3']['src'] + dst = meta['layer3']['dst'] + if 'layer4' in meta: + if meta.get('layer4').get('sport'): + sport = meta['layer4']['sport'] + if meta.get('layer4').get('dport'): + dport = meta['layer4']['dport'] + proto = meta['layer4']['@protoname'] + if direction == 'independent': + conn_id = meta['id'] + timeout = meta['timeout'] + src = f'{src}:{sport}' if sport else src + dst = f'{dst}:{dport}' if dport else dst + state = meta['state'] if 'state' in meta else '' + data_entries.append([conn_id, src, dst, proto, state, timeout]) + headers = ["Connection id", "Source", "Destination", "Protocol", "State", "Timeout"] + output = tabulate(data_entries, headers, numalign="left") + return output + + +def show(raw: bool): + conntrack_data = _get_raw_data() + if raw: + return conntrack_data + else: + return _get_formatted_output(conntrack_data) + + +if __name__ == '__main__': + print(show(raw=False)) -- cgit v1.2.3