Exemple #1
0
# to be able to import our modules from the directory above
os.sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

from parsers.CurrentTime import ParserCurrentTime
from parsers.Fragmentation import ParserFragmentation
from parsers.ProcessCPU import ParserProcessCPU
from _common import ssh, cycle, simple_command_with_timestamp, prepend_timestamp

import re
import sys
import time

sshc, args = ssh([
	{ 'name':'--collect-time',   'type':int, 'default':5,  'help':'How long should each cycle take' },
	{ 'name':'--history',   'type':int, 'default':45,  'help':'Maximum lines to show (45 by default)' },
	{ 'name':'--hz',    'type':int, 'default':100,  'help':'CONFIG_HZ of device, do not change' },
	{ 'name':'--raw',   'default':False, 'action':'store_true',  'help':'Show raw difference (not divided by interval)' },
	{ 'name':'--no-cpu',   'default':False, 'action':'store_true',  'help':'Do not show CPU usage on each line' },
], """
""", supports_script=True)

def do(sshc, cache, history, hz, raw, show_cpu):
	frags = ParserFragmentation(sshc).get()
	usage = ParserProcessCPU(sshc).get([])
	etime = ParserCurrentTime(sshc).get()
	
	if 'last' not in cache:
		cache['last'] = {
			'collected_on': etime.as_timestamp(),
			'frags': frags,
			'cpu' : usage,
		}
sshc, args = ssh([
    {
        'name': '--cycle-time',
        'type': int,
        'default': 5,
        'help': 'How long should each cycle take'
    },
    {
        'name': '--iface',
        'default': None,
        'action': 'append',
        'help': 'Show this interface only (can repeat)'
    },
    {
        'name': '--all-ifaces',
        'default': False,
        'action': 'store_true',
        'help': 'Show all interfaces regardless on link status'
    },
    {
        'name': '--display',
        'default': 'fnkod',
        'help': 'What fields to disply (f, n, k, o, d)'
    },
    {
        'name': '--show-timestamp',
        'default': False,
        'action': 'store_true',
        'help': 'Show timestamp on each line'
    },
    {
        'name': '--no-colors',
        'default': False,
        'action': 'store_true',
        'help': 'Do not colorize the output'
    },
], """
This program collects the traffic counters from network interfaces. By default it only shows the interface in the
up state, but it can be changed with `--all-iface` option or by pressing the 'a' key (and enter).

It collects the "front port" counters ("wire" counters on the incoming ports), npu counters (traffic hitting the NPU)
and the kernel counters (traffic that is not offloaded). By default all counters are shown and they can be enabled/disabled 
by pressing "f", "n" or "k" keys (and enter). All bandwidth counters are shown in the relevant units and the program
uses the SI to calculate them (ie. dividing by 1000 and NOT by 1024).

Be aware that on some models the NPU lanes are shared. This program displays the NPU column for each interface, 
but in case of shared lanes the same counter will be displayed for all the relevant interfaces.

There are also drop counters collected. Visibility of this field can be enabled/disabled with 'd' key. Similar to NPU counters, 
the drop counters are disabled for each interface, but they are collected for the whole NPU, hence the numbers will be the same 
for all the ports on the same NPU. Unlike others, these counters are not averaged per second, but intestat the total number 
of drops is shown. Drop counters can be zeroed with "z" key. 

This program needs a definition of ports used by each platform. It is possible that your platform is not yet supported,
but it should not be a problem to add the right definition - just send an email to Ondrej Holecek <*****@*****.**>.

If you are running this program with the output redirected to file, you most probably want to use `--show-timestamp` and `--no-colors` options.
""")
sshc, args = ssh([
    {
        'name': '--cycle-time',
        'type': int,
        'default': 5,
        'help': 'How long should each cycle take'
    },
    {
        'name': '--direction',
        'type': str,
        'default': None,
        'action': 'append',
        'choices': ['initiator', 'responder'],
        'help': 'Which direction to show (can repeat)'
    },
    {
        'name': '--status',
        'type': str,
        'default': None,
        'action': 'append',
        'choices': ['established', 'connecting'],
        'help': 'Which status to show (can repeat)'
    },
    {
        'name': '--max-age',
        'type': int,
        'default': None,
        'help': 'Show only VPNs not older that this in seconds'
    },
])
Exemple #4
0
sshc, args = ssh([
    {
        'name': '--command',
        'required': True,
        'action': 'append',
        'help': 'What command to keep running, can repeat'
    },
    {
        'name': '--vdom',
        'default': None,
        'help': 'VDOM to use when executing the command'
    },
    {
        'name': '--mgmt-vdom',
        'default': False,
        'action': 'store_true',
        'help': 'Use management VDOM to execute the command'
    },
    {
        'name': '--keepalive-string',
        'default': ' \b',
        'help': 'String to send every --keepalive-time'
    },
    {
        'name': '--keepalive-time',
        'type': int,
        'default': 30,
        'help': 'How often to send keepalive'
    },
    {
        'name': '--outfile',
        'default': None,
        'help': 'Save the output also to this file'
    },
    {
        'name': '--no-stdout',
        'default': False,
        'action': 'store_true',
        'help': 'Do not print data on standard output'
    },
    {
        'name': '--no-remove-string',
        'default': False,
        'action': 'store_true',
        'help': 'Disable automatic removal of the keepalive string form output'
    },
    {
        'name': '--no-auto-commands',
        'default': False,
        'action': 'store_true',
        'help': 'Do not send any commands that user didnt specify'
    },
], """
This utility is used to enable some debug outputs (usually with 'diagnose debug application ...' but other commands will work too) and capture the data appearing on the terminal. 

By default the user does not need to bother with debug enabling (`diagnose debug reset`, `diagnose debug duration 0`, `diagnose debug console timestamp enable`, `diagnose debug enable`) because the utility executes these commands automatically and in the right order. If you want to supress this automatization, use `--no-auto-commands` parameter).

The program automatically takes care of the SSH session timeout - by default it sends a space and backspace characters every 30 seconds. The string can be changed with `--keepalive-string` option and the timeout with `--keepalive-time` option. By default the program automatically removes the string from displayed outputs, but in case you use some general purpose string (such as '\\n') you may want to disable this feature with `--no-remove-string` option.

By default all commands are executed in the global context in the order they appear on the command line. The context can be changed globally with `--vdom` or `--mgmt-vdom` parameters. Also the context can be specified for each command individually with '<...>' prefix (use vdom name for specific VDOM, 'global' for global context or keep it empty to use the current management VDOM).

By default the output is printed on standard output (if `--no-stdout` is not used). Additionally the same output can be appended to a file specified with `--outfile` parameter. If you want to overwrite the output file instead of appending at the end, use `!` as the first character.
""")
Exemple #5
0
sshc, args = ssh([
	{ 'name':'--cycle-time',   'type':int, 'default':5,  'help':'How long should each cycle take' },
	{ 'name':'--repeat-header',  'default':0, 'type':int,  'help':'After how many lines to repeat header' },
	{ 'name':'--empty-line',  'default':False, 'action':'store_true',  'help':'Print empty line after each cycle' },
	{ 'name':'--sessions-in-use',  'default':False, 'action':'store_true',  'help':'Show all sessions in use at each moment' },
	{ 'name':'--recent-pps',  'default':False, 'action':'store_true',  'help':'Show recent packets per second' },
	{ 'name':'--recent-bps',  'default':False, 'action':'store_true',  'help':'Show recent bits per second' },
	{ 'name':'--tcp-sessions-in-use',  'default':False, 'action':'store_true',  'help':'Show TCP sessions in use at each moment' },
	{ 'name':'--udp-sessions-in-use',  'default':False, 'action':'store_true',  'help':'Show UDP sessions in use at each moment' },
	{ 'name':'--icmp-sessions-in-use',  'default':False, 'action':'store_true',  'help':'Show ICMP sessions in use at each moment' },
	{ 'name':'--ip-sessions-in-use',  'default':False, 'action':'store_true',  'help':'Show IP sessions in use at each moment' },
	{ 'name':'--tcp-sessions-active',  'default':False, 'action':'store_true',  'help':'Show TCP sessions active at each moment' },
	{ 'name':'--udp-sessions-active',  'default':False, 'action':'store_true',  'help':'Show UDP sessions active at each moment' },
	{ 'name':'--icmp-sessions-active',  'default':False, 'action':'store_true',  'help':'Show ICMP sessions active at each moment' },
	{ 'name':'--ip-sessions-active',  'default':False, 'action':'store_true',  'help':'Show IP sessions active at each moment' },
	{ 'name':'--tcp-sessions-per-second',  'default':False, 'action':'store_true',  'help':'Show TCP sessions per second' },
	{ 'name':'--udp-sessions-per-second',  'default':False, 'action':'store_true',  'help':'Show UDP sessions per second' },
	{ 'name':'--icmp-sessions-per-second',  'default':False, 'action':'store_true',  'help':'Show ICMP sessions per second' },
	{ 'name':'--ip-sessions-per-second',  'default':False, 'action':'store_true',  'help':'Show IP sessions per second' },
	{ 'name':'--all-sessions-per-second',  'default':False, 'action':'store_true',  'help':'Show all sessions per second' },
	{ 'name':'--all-counters',  'default':False, 'action':'store_true',  'help':'Show all known counters' },
	{ 'name':'--only-total',  'default':False, 'action':'store_true',  'help':'Do not show per IPSE counters' },
], """
This utility continuously parses the output of "diag ips session stat" and displays various IPS session statistics.

It can show (everything per engine + summary):
- TCP/UDP/ICMP/IP sessions currently in use
- TCP/UDP/ICMP/IP sessions currently active
- based on "totals" it can calculate the average number of sessions per second (this was verified with FortiTester)
  (be aware that this is an average, so the totals might not much exactly for small number of sessions)
- recent packets per seconds as reported by the IPS engine - this is counted in both directions together (this was
  also verified with FortiTester)
- recent bits per seconds as reported by the IPS engine (this was verified with FortiTester)

Run it with "-h" parameter to find all possible options - the option names are pretty self-explanatory.

You can enable each counter independently (by default all are disabled!), or you can use "--all-counters" to enable 
all known counters (in that case you may also want to use "--empty-line" parameter to print an empty line after each 
cycle to make the output more human readable).

Note: For some reason (not only but mainly when somebody else is debugging on the save device) the output of the 
command it not always correct/showing all the IPS engines. The program can recognize the problem, because it knows 
how many IPS engines there are running. In that case the error is printed, but if it is only occasional, it is 
not really a problem.
""")
from parsers.CurrentTime import ParserCurrentTime
from parsers.Processes import ParserProcesses
from _common import ssh, cycle, simple_command_with_timestamp

import re
import sys

sshc, args = ssh([
    {
        'name': '--cycle-time',
        'type': int,
        'default': 5,
        'help': 'How long should each cycle take'
    },
    {
        'name': '--process-name',
        'required': True,
        'help': 'Regular expression on the process name to dump stack for'
    },
], """
This program take the process name as a parameter and then every `--cycle-time` it print the current 
stack trace for this program. This stack trace contains the exact part of the code which is executing.

If there are multiple processes of the same name, the stack dump is printent for all of them.
""")


def do(sshc, process_re):
    etime = ParserCurrentTime(sshc).get()

    processes = ParserProcesses(sshc).get()
    for process in processes:
Exemple #7
0
# to be able to import our modules from the directory above
os.sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

from parsers.CurrentTime import ParserCurrentTime
from _common import ssh, prepend_timestamp

import re
import datetime
import sys

sshc, args = ssh([
    {
        'name': '--cycle-time',
        'type': int,
        'default': 1,
        'help': 'How long should each cycle take'
    },
], """
Just run the mpstat continuously with timestamp added at the beginning of each line.
""")

re_split = re.compile('^(.*?)(TIME.*?\r\n\r\n)(.*)$', re.DOTALL)
re_time = re.compile('^(\d+):(\d+):(\d+)\s+(\S+)\s+all\s+', re.M)


def divide(data, info):
    g = re_split.search(data)
    if not g: return None

    return ([g.group(2)], g.group(3))
Exemple #8
0
sshc, args = ssh([
    {
        'name': '--silent',
        'default': False,
        'action': 'store_true',
        'help': 'Do not display any progress'
    },
    {
        'name': '--cpu',
        'default': None,
        'action': 'append',
        'help': 'Show only specific CPU(s)'
    },
    {
        'name': '--desc',
        'default': None,
        'help': 'Only show handler matching RE'
    },
    {
        'name': '--with-time',
        'default': False,
        'action': 'store_true',
        'help': 'Show timestamp on each line'
    },
    {
        'name': '--no-colors',
        'default': False,
        'action': 'store_true',
        'help': 'Do not colorize handlers'
    },
], """
Show how interrupts are bound to CPU cores.

Because on some devices the required data collection can take even more than a minute, 
it shows the progress by default, but it can be disabled with `--silent` parameter.

All IRQs and all CPUs are shown by default, but it can be limited using `--cpu` and
`--desc` parameters. Both can be used more than ones. Parameter `--cpu` expects cpu
id and paramter `--desc` expects a regular expression that must match on handler name.

Some IRQs have no affinity, which means those can be handled by any CPU, however to make
the output more readable, those were move to the 'CPU All' section at the end of output,
which will be display unless `--cpu` parameter is used.

By default some well known handlers are colorized (on non-Windows terminals),
this can be disabled with `--no-colors` parameter.
""")
Exemple #9
0
os.sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

from parsers.CurrentTime import ParserCurrentTime
from parsers.Interrupts import ParserInterrupts
from parsers.ProcessCPU import ParserProcessCPU
from _common import ssh, cycle, simple_command_with_timestamp, prepend_timestamp

import re
import sys

sshc, args = ssh([
	{ 'name':'--collect-time',   'type':float, 'default':5,  'help':'How long should each cycle take' },
	{ 'name':'--max',   'type':int, 'default':45,  'help':'Maximum lines to show (45 by default)' },
	{ 'name':'--show-zeros',  'default':False, 'action':'store_true',  'help':'Include lines with zero runs' },
	{ 'name':'--summarize', 'default':False, 'action':'store_true',  'help':'Summarize ticks from all CPUs' },
	{ 'name':'--cpu', 'type':int, 'default':[], 'action':'append',  'help':'Summarize ticks from selected CPUs' },
	{ 'name':'--no-soft', 'default':False, 'action':'store_true',  'help':'Do not show softirqs' },
	{ 'name':'--no-hard', 'default':False, 'action':'store_true',  'help':'Do not show hardirqs' },
	{ 'name':'--desc',   'type':str, 'help':'Regex to filter interrupts by description' },
	{ 'name':'--hz',           'type':int, 'default':100,  'help':'CONFIG_HZ of device, do not change' },
], """
""", supports_script=True)

def difference_per_second(old, new, time_difference):
	if 'interrupts' not in old or 'interrupts' not in new: raise Exception('Invalid structures for calculating difference')
	if 'collected_on' not in old or 'collected_on' not in new: raise Exception('Invalid structures for calculating difference')
	if 'cpus' not in old or 'cpus' not in new: raise Exception('Invalid structures for calculating difference')
	if new['cpus'] != old['cpus']: raise Exception('Number of CPUs has changed')

	diff = {}
	for k in new['interrupts'].keys():
		if k not in old['interrupts']: continue
Exemple #10
0
import sys

sshc, args = ssh([
    {
        'name': '--filter',
        'default': '',
        'help': 'Tcpdump filter, default ""'
    },
    {
        'name': '--interface',
        'default': 'any',
        'help': 'Interface name, default "any"'
    },
    {
        'name': '--direction',
        'default': 'both',
        'choices': ['in', 'out', 'both'],
        'help': 'Which direction to save, default "both"'
    },
    {
        'name': '--simulate',
        'help': 'File name to simulate the SSH output'
    },
], """
Run the sniffer of FortiGate and dump packets in libpcap (old) format on standard input.

Can be processed by Wireshark with:
$ wireshark -k -i <(./sniffer.py  --host 10.109.250.102 --port 10003 --filter 'proto 89')
""")

#
import os

# to be able to import our modules from the directory above
os.sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

from parsers.CurrentTime import ParserCurrentTime
from parsers.GenericLineSplit import ParserGenericLineSplit
from _common import ssh, cycle, prepend_timestamp

sshc, args = ssh([
    {
        'name': '--cycle-time',
        'type': int,
        'default': 5,
        'help': 'How long should each cycle take'
    },
    {
        'name': '--show-raw',
        'action': 'store_true',
        'default': False,
        'help': 'Show also raw counters values'
    },
])


def do(sshc, info, show_raw):
    etime = ParserCurrentTime(sshc).get()

    s = ParserGenericLineSplit(sshc).get("\s*:\s*",
                                         "diag vpn ike stats",
                                         vdom="",
                                         key_index=0,
sshc, args = ssh([
    {
        'name': '--cycle-time',
        'type': int,
        'default': 5,
        'help': 'How long should each cycle take'
    },
    {
        'name': '--direction',
        'type': str,
        'default': None,
        'action': 'append',
        'choices': ['initiator', 'responder'],
        'help': 'Which direction to show (can repeat)'
    },
    {
        'name': '--status',
        'type': str,
        'default': None,
        'action': 'append',
        'choices': ['established', 'connecting'],
        'help': 'Which status to show (can repeat)'
    },
    {
        'name': '--phase',
        'type': str,
        'default': None,
        'action': 'append',
        'choices': ['1', '2'],
        'help': 'Which IPSec phase to show counters for (can repeat)'
    },
    {
        'name': '--age',
        'type': str,
        'default': None,
        'action': 'append',
        'choices': ['current', 'total'],
        'help': 'Show current or total numbers (can repeat)'
    },
    {
        'name': '--use',
        'type': str,
        'default': None,
        'action': 'append',
        'choices': ['created', 'established'],
        'help': 'Show numbers of created or established SAs (can repeat)'
    },
    {
        'name': '--no-colors',
        'default': False,
        'action': 'store_true',
        'help': 'Do not print color codes'
    },
    {
        'name':
        '--repeat-header',
        'type':
        int,
        'default':
        20,
        'help':
        'How often to repeat header line (20 lines by default), 0 to disable'
    },
])
Exemple #13
0
sshc, args = ssh([
    {
        'name': '--max',
        'type': int,
        'default': 25,
        'help': 'How many lines of output to show (0 for all)'
    },
    {
        'name': '--sort-by',
        'default': 'total',
        'choices': ['total', 'user', 'system', 'pid'],
        'help': 'How to sort the output'
    },
    {
        'name': '--collect-time',
        'type': int,
        'default': 1,
        'help': 'How long to collect data in each cycle'
    },
    {
        'name': '--pid-group',
        'type': int,
        'default': 50,
        'help': 'How many PIDs to query at once'
    },
    {
        'name': '--process-name',
        'default': None,
        'help': 'Regular expression on the process name'
    },
    {
        'name': '--cpu',
        'type': int,
        'default': None,
        'action': 'append',
        'help': 'CPU number to show processes on (can repeat)'
    },
    {
        'name': '--state',
        'type': str,
        'default': None,
        'action': 'append',
        'help': 'Process state to show (can repeat)'
    },
    {
        'name': '--pid',
        'type': int,
        'default': None,
        'action': 'append',
        'help': 'Show only processed with this PID'
    },
    {
        'name': '--ppid',
        'type': int,
        'default': None,
        'action': 'append',
        'help': 'Show only processed with this parent'
    },
    {
        'name': '--negate-pid',
        'default': False,
        'action': 'store_true',
        'help': 'Parameters --pid and --ppid are negated'
    },
    {
        'name': '--system',
        'default': False,
        'action': 'store_true',
        'help': 'Show only kernel threads (alias to PPID 2)'
    },
    {
        'name': '--userland',
        'default': False,
        'action': 'store_true',
        'help': 'Show only userland processes (negate to PPID 0 and 2)'
    },
    {
        'name': '--hz',
        'type': int,
        'default': 100,
        'help': 'CONFIG_HZ of device, do not change'
    },
],
                 """
This is very similar to FortiGate's "diag sys top" program, with following differencies:
- also the kernel threads are shown
- the cpu the process was last seen running on is shown
- cpu utilization is split between "kernel" and "userland" utilization for each process
- it displays the "global" utilization (percentage of all possible CPU ticks)
- and it also displays "of counsumed" utilization (percentage out of the running processes)
- it DOES NOT display any memory statistics

Different sorting algorithms can be applied (see help for `--sort-by` option).

It is possible to only shown the processes in the specific state (see help for `--state` option),
or processes running on a specific CPU (see help for `--cpu` option).
""",
                 supports_script=True)
from parsers.Processes import ParserProcesses
from parsers.ProcessStat import ParserProcessStat
from _common import ssh, cycle

sshc, args = ssh([
    {
        'name': '--cycle-time',
        'type': int,
        'default': 5,
        'help': 'How long should each cycle take'
    },
    {
        'name': '--pid-group',
        'type': int,
        'default': 50,
        'help': 'How many PIDs to query at once'
    },
],
                 """
This program displays the processes running on each CPU (core). 

Be aware that the processes can jump between different cores during their lifetime,
and this collects the actual status only once per `cycle-time`, hence this is not
very accurate. 

However, it can be used to identify the process occupying the specific core all the time.
""",
                 supports_script=True)


def do(sshc, pid_group_count):
    processes = ParserProcesses(sshc).get2()
Exemple #15
0
#!/usr/bin/env python2.7

import os

# to be able to import our modules from the directory above
os.sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

from _common import ssh, prepend_timestamp

import sys

sshc, args = ssh([
	{ 'name':'--cycle-time',   'type':int, 'default':1,  'help':'How long should each cycle take' },
	{ 'name':'--action', 'type':str, 'choices':['dump'], 'default':'dump', 'help': 'What to do - "dump"' },
], """
""")

def divide(data, info):
	sessions = []

	while True:
		# find the next session
		i = data.find("\r\n\r\n")
		if i == -1: break

		ses = data[:i]
		data = data[i+4:]

		# remove empty lines at the beginning
		while ses[0] == '\r' or ses[0] == '\n':
			ses = ses[1:]