1
0
mirror of https://github.com/kellyjonbrazil/jc.git synced 2026-04-03 17:44:07 +02:00

Compare commits

...

188 Commits

Author SHA1 Message Date
Kelly Brazil
bed694fcf5 version bump 2020-05-30 20:13:21 -07:00
Kelly Brazil
4b4af69fa1 fix date 2020-05-30 20:12:51 -07:00
Kelly Brazil
9d96190a5b Merge pull request #64 from kellyjonbrazil/dev
Dev v1.11.2
2020-05-30 20:08:32 -07:00
Kelly Brazil
fa44d48c09 freebsd fixes, tests, and fixtures 2020-05-30 19:50:38 -07:00
Kelly Brazil
4ef961c278 add freebsd test and fixtures 2020-05-30 19:18:01 -07:00
Kelly Brazil
292a837d5c add tests and fixtures for freebsd12 2020-05-30 18:54:09 -07:00
Kelly Brazil
aa7b915d84 version bump 2020-05-30 18:53:46 -07:00
Kelly Brazil
c46fe73236 add last fixes for freebsd 2020-05-30 18:53:35 -07:00
Kelly Brazil
039b2c129c freebsd fixes 2020-05-30 18:42:26 -07:00
Kelly Brazil
8f2e5e4808 fix compatible logic 2020-05-30 17:46:09 -07:00
Kelly Brazil
c4da8e4f78 add nixos and freebsd to tested. update new arp fields 2020-05-30 17:05:41 -07:00
Kelly Brazil
bcab9078a4 add w parser fix 2020-05-30 17:02:09 -07:00
Kelly Brazil
b3c6c1ea92 strip whitespace in string fields and add tests 2020-05-30 17:01:59 -07:00
Kelly Brazil
a3af8662bd add permanent field 2020-05-30 16:26:07 -07:00
Kelly Brazil
35940d0bc8 add freebsd permanent and expires fields 2020-05-30 16:25:53 -07:00
Kelly Brazil
26994cdcb7 add freebsd compatibility info 2020-05-30 15:51:54 -07:00
Kelly Brazil
017159a829 add freebsd nestat tests and fixtures 2020-05-30 15:51:06 -07:00
Kelly Brazil
b4e9c85e08 fixup -T freebsd output and add whitespace stripping to parse_post 2020-05-30 15:50:45 -07:00
Kelly Brazil
189146cd84 add more ints. remove whitespace strip code and move to freebsd_osx module 2020-05-30 15:50:07 -07:00
Kelly Brazil
af34153ffa version bump 2020-05-30 15:48:56 -07:00
Kelly Brazil
bf2ff3ffbb fix compatibility search for platform names that append the version number (e.g. freebsd12) 2020-05-30 15:48:29 -07:00
Kelly Brazil
6423c9efd6 integer and float updates 2020-05-29 15:48:51 -07:00
Kelly Brazil
58ab0d4ece strip whitespace from string fields 2020-05-29 15:14:44 -07:00
Kelly Brazil
83a738bf4d update fixtures for osx_flags and osx_inode name change to unix_flags and unix_inode 2020-05-29 14:16:11 -07:00
Kelly Brazil
3640671fc6 rename module 2020-05-29 14:15:28 -07:00
Kelly Brazil
1da623b30e add items 2020-05-29 14:14:48 -07:00
Kelly Brazil
b10ca64646 change osx_inode and osx_flags to unix_inode and unix_flags. Also rename netstat_osx module to netstat_freebsd_osx 2020-05-29 14:14:37 -07:00
Kelly Brazil
2128763ee6 fix osx version from 16.4 to 14.6 2020-05-29 13:25:19 -07:00
Kelly Brazil
a27e7ed39c test updates for added route_flags_pretty and flags_pretty fields 2020-05-29 13:24:52 -07:00
Kelly Brazil
f07b7eaa47 add flags_pretty 2020-05-29 12:55:16 -07:00
Kelly Brazil
6ce18de84c add route_flags_pretty 2020-05-29 12:51:04 -07:00
Kelly Brazil
8631b756e7 add freebsd test files 2020-05-29 12:05:46 -07:00
Kelly Brazil
7414d98412 add freebsd compatibility 2020-05-29 12:05:34 -07:00
Kelly Brazil
d7b19892e8 add freebsd support for netstat -i 2020-05-29 12:04:58 -07:00
Kelly Brazil
96df396eaf formatting 2020-05-29 07:35:25 -07:00
Kelly Brazil
2f6f640317 spelling 2020-05-27 17:11:20 -07:00
Kelly Brazil
c4a0a50f3a add nix-env 2020-05-27 17:08:54 -07:00
Kelly Brazil
658f8a3842 add zypper and ports info 2020-05-27 14:58:16 -07:00
Kelly Brazil
bfb876a1e3 formatting 2020-05-27 09:52:13 -07:00
Kelly Brazil
90c34b1f4e fix dmidecode example 2020-05-26 17:31:56 -07:00
Kelly Brazil
3f9164ea77 bold formatting 2020-05-23 21:11:17 -07:00
Kelly Brazil
7fd6fecbf5 formatting 2020-05-23 21:09:49 -07:00
Kelly Brazil
8029f72363 change osx_flags from integer to string 2020-05-23 21:09:40 -07:00
Kelly Brazil
c7fdce5d3b Merge pull request #62 from kellyjonbrazil/dev
Dev v1.11.0
2020-05-22 16:37:50 -07:00
Kelly Brazil
84f48aa369 version bump 2020-05-22 16:30:22 -07:00
Kelly Brazil
2e9a0a9c12 add features 2020-05-22 16:21:55 -07:00
Kelly Brazil
c1f6f2b950 osx fixes and tests 2020-05-22 16:21:40 -07:00
Kelly Brazil
ede21bca13 add OSX support for stat 2020-05-22 16:05:04 -07:00
Kelly Brazil
8dd9a9f9cb add netstat -i tests 2020-05-22 15:12:10 -07:00
Kelly Brazil
04f92cd133 add linux support for netstat -i 2020-05-22 14:04:11 -07:00
Kelly Brazil
8be8d2393b add netstat -i support for OSX 2020-05-22 13:38:25 -07:00
Kelly Brazil
0a879681be add netstat -r to docs 2020-05-22 12:56:27 -07:00
Kelly Brazil
2ca1587a49 add linux netstat -r tests 2020-05-22 12:44:51 -07:00
Kelly Brazil
ec2cd2d708 add netstat -r support for linux 2020-05-22 12:00:26 -07:00
Kelly Brazil
5d0dbece93 add netstat -r functionality for OSX 2020-05-22 11:09:41 -07:00
Kelly Brazil
df1e4b414b remove unused folder 2020-05-22 08:00:18 -07:00
Kelly Brazil
40760991e7 update copyright date 2020-05-22 07:51:47 -07:00
Kelly Brazil
464f5f86cf update description 2020-05-22 07:50:22 -07:00
Kelly Brazil
7b09e9fccd set empty values to Null and update fixtures 2020-05-21 17:01:17 -07:00
Kelly Brazil
6cba7d4298 remove linux from description 2020-05-21 11:10:00 -07:00
Kelly Brazil
9730f62e49 fixup name field and update test fixtures 2020-05-21 09:44:28 -07:00
Kelly Brazil
e0c1c87f54 formatting 2020-05-21 09:07:01 -07:00
Kelly Brazil
931b3d2b83 formatting 2020-05-20 19:56:28 -07:00
Kelly Brazil
e5d561baee add multipath condition for osx detection 2020-05-20 17:31:51 -07:00
Kelly Brazil
2867593e7a changelog update 2020-05-20 17:28:44 -07:00
Kelly Brazil
dd52fee563 osx netstat tests and fixtures 2020-05-20 17:25:25 -07:00
Kelly Brazil
8e1f885827 fix filtered netstat views 2020-05-20 16:43:53 -07:00
Kelly Brazil
2d39a58f90 doc update 2020-05-20 16:14:03 -07:00
Kelly Brazil
9c4fa2ae26 integer conversions and icmp fix 2020-05-20 15:39:47 -07:00
Kelly Brazil
de52d84e82 fix udp state and udp46 entries 2020-05-20 12:02:32 -07:00
Kelly Brazil
ce9b55059a organize files 2020-05-20 11:24:38 -07:00
Kelly Brazil
bcd370a6a0 code cleanup 2020-05-20 08:19:45 -07:00
Kelly Brazil
c8216850ab code cleanup 2020-05-20 07:19:24 -07:00
Kelly Brazil
f5feedb90b fix comments 2020-05-19 17:38:14 -07:00
Kelly Brazil
a4371cd187 support netstat -A 2020-05-19 17:36:16 -07:00
Kelly Brazil
9d5ba4c834 formatting 2020-05-19 17:14:04 -07:00
Kelly Brazil
1639dee1bb fix parse_post 2020-05-19 17:13:03 -07:00
Kelly Brazil
9363f430f2 use list extend method to simplify code 2020-05-19 16:26:41 -07:00
Kelly Brazil
9192a09073 parse all sections 2020-05-19 16:26:04 -07:00
Kelly Brazil
b915eb9755 initial osx parser 2020-05-19 15:15:08 -07:00
Kelly Brazil
1cfcc2b592 tighten up line test logic when counting tabs 2020-05-14 09:58:16 -07:00
Kelly Brazil
7138dd02b7 cleanup variables after adding to item 2020-05-14 09:51:10 -07:00
Kelly Brazil
b4276643b7 add dmidecode tests and fixtures 2020-05-14 09:43:13 -07:00
Kelly Brazil
2ef00763bf fix first item 2020-05-14 09:33:45 -07:00
Kelly Brazil
54364928fc fix oddities like hybrid single/multiline data and items containing multiple records 2020-05-14 08:57:23 -07:00
Kelly Brazil
09b3b4932b add dmidecode output fixtures 2020-05-13 10:51:38 -07:00
Kelly Brazil
29d6670119 convert integers 2020-05-13 10:18:49 -07:00
Kelly Brazil
2f654b5f1a doc update 2020-05-13 10:13:27 -07:00
Kelly Brazil
e53b9f5992 add caveats to documentation 2020-05-13 10:12:40 -07:00
Kelly Brazil
addb234e61 add dmidecode doc 2020-05-13 09:44:20 -07:00
Kelly Brazil
76eca3b659 add dmidecode 2020-05-13 09:43:35 -07:00
Kelly Brazil
f90dec4c0e add examples to documentation 2020-05-13 09:43:23 -07:00
Kelly Brazil
8900a59d4c simplify logic by removing redundant block 2020-05-13 09:31:12 -07:00
Kelly Brazil
6685138200 fix for missing multi-line values that come immediately after a previous multi-line value 2020-05-13 09:25:02 -07:00
Kelly Brazil
4d3e65b980 fix missing values 2020-05-13 09:00:32 -07:00
Kelly Brazil
e9282bb546 add dmidecode parser 2020-05-13 08:22:52 -07:00
Kelly Brazil
f5627a4594 version bump 2020-05-11 11:03:02 -07:00
Kelly Brazil
81ffdb2510 remove shebang for Fedora packaging 2020-05-11 10:54:26 -07:00
Kelly Brazil
4c00a99850 version bump 2020-05-11 10:37:14 -07:00
Kelly Brazil
2bfcb45b28 make cli.py executable 2020-05-11 10:32:42 -07:00
Kelly Brazil
ab0c10e791 remove execute permissions 2020-05-11 10:27:16 -07:00
Kelly Brazil
2c1935115d Merge pull request #61 from kellyjonbrazil/dev
Dev v1.10.10
2020-05-09 11:47:05 -07:00
Kelly Brazil
d98e43dc78 add netstat item 2020-05-09 11:42:56 -07:00
Kelly Brazil
9348988d64 add netstat test for Fedora32 2020-05-09 11:41:30 -07:00
Kelly Brazil
1285c66467 netstat with bluetooth section 2020-05-09 11:36:23 -07:00
Kelly Brazil
b7191bbc13 handle bluetooth section (ignore for now) 2020-05-09 11:36:03 -07:00
Kelly Brazil
98b97509f7 version bump 2020-05-09 11:25:13 -07:00
Kelly Brazil
2b2b570490 add tests for 'gone - no logout' 2020-05-09 11:22:26 -07:00
Kelly Brazil
cce2d1ff29 add condition for 'gone - no logout' 2020-05-09 11:22:01 -07:00
Kelly Brazil
b79600c572 version bump 2020-05-09 11:01:48 -07:00
Kelly Brazil
140f1a8543 test fixes for issue #60 2020-05-09 11:00:04 -07:00
Kelly Brazil
e34657cfde fix issue #60 that was skipping the first file in some instances using -R without -l 2020-05-08 15:26:11 -07:00
Kelly Brazil
99070fa607 version bump 2020-05-08 10:51:13 -07:00
Kelly Brazil
2b46785b1f add MIT license to vendorized IfconfigParser class 2020-05-08 10:49:30 -07:00
Kelly Brazil
c72562524b fully remove tests from packaging 2020-05-08 09:30:31 -07:00
Kelly Brazil
b7dd6441c7 version bump 2020-05-08 08:20:33 -07:00
Kelly Brazil
31fcc2f755 remove manifest.in - no longer needed due to removing tests 2020-05-08 08:20:21 -07:00
Kelly Brazil
b391aa14bc add license_file to metadata 2020-05-08 08:19:51 -07:00
Kelly Brazil
d3c45debbb remove tests and add license file 2020-05-08 08:19:31 -07:00
Kelly Brazil
5b08469b87 Merge pull request #57 from kellyjonbrazil/dev
Dev v1.10.7
2020-05-01 15:55:50 -07:00
Kelly Brazil
4a77ec63a4 add IfconfigParser class 2020-05-01 14:57:50 -07:00
Kelly Brazil
d13606b6dc modify dependencies for easier packaging into Fedora 2020-05-01 14:37:23 -07:00
Kelly Brazil
05291c93bb vendorize ifconfig-parser module for easier packaging in Fedora 2020-05-01 14:36:54 -07:00
Kelly Brazil
8cf00a208e change text to strings 2020-04-29 15:57:55 -07:00
Kelly Brazil
06d73c8876 formatting 2020-04-23 07:06:44 -07:00
Kelly Brazil
649c646ea2 add brew install option 2020-04-22 16:08:34 -07:00
Kelly Brazil
b7756d9250 version bump 2020-04-20 16:33:26 -07:00
Kelly Brazil
1cd2cd954c remove references to homebrew/shim to allow tests to pass in homebrew packaging ci/cd 2020-04-20 16:31:22 -07:00
Kelly Brazil
72020b8da9 move packages info to jc-packages github page 2020-04-17 10:20:25 -07:00
Kelly Brazil
cf9720b749 update install info 2020-04-16 14:03:31 -07:00
Kelly Brazil
967b9db7f9 spelling 2020-04-15 21:27:22 -07:00
Kelly Brazil
bb3acb1182 formatting 2020-04-15 21:25:06 -07:00
Kelly Brazil
560c7f7e6d formatting 2020-04-15 21:23:55 -07:00
Kelly Brazil
79b2841764 add new binary package install info 2020-04-15 21:22:43 -07:00
Kelly Brazil
a06a89cbd1 version bump 2020-04-14 11:15:24 -07:00
Kelly Brazil
431bd969eb use sys.exit(0) instead of exit() 2020-04-14 11:10:31 -07:00
Kelly Brazil
c87b722aec spelling 2020-04-12 13:23:58 -07:00
Kelly Brazil
3688b8b014 Merge pull request #56 from kellyjonbrazil/dev
Dev v1.10.4
2020-04-12 13:21:38 -07:00
Kelly Brazil
07b8d9e0c0 version bump 2020-04-12 13:18:28 -07:00
Kelly Brazil
7454b53e39 formatting 2020-04-12 13:13:28 -07:00
Kelly Brazil
3d6a76024d update with JC_COLORS info 2020-04-12 13:10:57 -07:00
Kelly Brazil
421b980957 JC_COLORS working 2020-04-12 13:03:09 -07:00
Kelly Brazil
4a22e27d6a add set_env_colors function 2020-04-12 12:43:51 -07:00
Kelly Brazil
99f7842dee fix brek on pipe error 2020-04-09 13:38:33 -07:00
Kelly Brazil
7f869b4b18 change colors to ansi and match jello style 2020-04-09 07:31:21 -07:00
Kelly Brazil
9665f4ee84 add pypi badge 2020-04-07 08:44:15 -07:00
Kelly Brazil
606904d48b Merge pull request #53 from kellyjonbrazil/dev
Dev v1.10.1
2020-04-04 17:28:21 -07:00
Kelly Brazil
3f5279b97c version bump to 1.10.1 2020-04-04 17:25:55 -07:00
Kelly Brazil
f5ec21e6ac use in instead of find() 2020-04-04 17:19:32 -07:00
Kelly Brazil
578a284465 use in instead of find() 2020-04-04 17:18:39 -07:00
Kelly Brazil
422e392d9d use in instead of find() 2020-04-04 17:17:43 -07:00
Kelly Brazil
54dfffd34a use in instead of find() 2020-04-04 17:16:25 -07:00
Kelly Brazil
cffba64d2b use in and startswith() instead of find() 2020-04-04 17:15:03 -07:00
Kelly Brazil
56a0c12a59 use in instead of find() 2020-04-04 17:12:22 -07:00
Kelly Brazil
c174d3de18 use in and startswith() instead of find() 2020-04-04 17:10:46 -07:00
Kelly Brazil
a9c59ef9fc fix logic to not for ' type ' in cleandata[0] 2020-04-04 17:07:38 -07:00
Kelly Brazil
abdb9b2673 use in instead of find() 2020-04-04 17:05:17 -07:00
Kelly Brazil
548aaab626 remove old commented code 2020-04-04 17:04:20 -07:00
Kelly Brazil
20571c87ae us in instead of find() 2020-04-04 17:01:56 -07:00
Kelly Brazil
19e49200de version bump 2020-04-04 16:59:48 -07:00
Kelly Brazil
d32f5c67a9 use startswith() instead of find() 2020-04-04 16:59:03 -07:00
Kelly Brazil
b83b626435 use startswith() instead of find() 2020-04-04 16:57:23 -07:00
Kelly Brazil
ab2c1b25ec use startswith() and in instead of find() 2020-04-04 16:56:11 -07:00
Kelly Brazil
f2d46313a4 use startswith() instead of find() 2020-04-04 16:53:55 -07:00
Kelly Brazil
87e4796a6c use in instead of .find() 2020-04-04 16:52:45 -07:00
Kelly Brazil
0014a5c2f4 us startswith() and in instead of .find() 2020-04-04 16:51:36 -07:00
Kelly Brazil
7af56e0dad use startswith() and in instead of find() 2020-04-04 16:50:05 -07:00
Kelly Brazil
a5ae6e3c01 use startswith() instead of find() 2020-04-04 16:48:16 -07:00
Kelly Brazil
fe1a0d1faf use in instead of .find() 2020-04-04 16:46:09 -07:00
Kelly Brazil
302f05cdda prettify style block 2020-04-03 14:50:20 -07:00
Kelly Brazil
c0044be7b0 rename color grey to gray 2020-04-03 14:48:19 -07:00
Kelly Brazil
0110078807 update badge 2020-04-03 14:47:08 -07:00
Kelly Brazil
42eacb45f8 rename to Tests 2020-04-03 14:45:04 -07:00
Kelly Brazil
a43e2e1991 add -m option info 2020-04-02 17:40:06 -07:00
Kelly Brazil
c8b721d4f6 version bump to 1.10.0 2020-04-02 17:35:35 -07:00
Kelly Brazil
d0bfddc3d9 add color and -m monochrome option 2020-04-02 17:29:25 -07:00
Kelly Brazil
6b925a16c8 add tests badge 2020-04-02 10:55:32 -07:00
Kelly Brazil
89ebd9fc22 add axfr info to schema 2020-03-27 07:31:08 -07:00
Kelly Brazil
6b4ba66231 Merge pull request #52 from kellyjonbrazil/dev
Dev v1.9.3
2020-03-26 17:15:13 -07:00
Kelly Brazil
5b697dc381 add more dig tests 2020-03-26 17:09:29 -07:00
Kelly Brazil
9ba73c95d1 add tests 2020-03-26 16:45:29 -07:00
Kelly Brazil
93aa390447 version bump to v1.9.3 2020-03-26 16:30:17 -07:00
Kelly Brazil
3cfb8945dd use startswith() instead of find 2020-03-26 16:29:59 -07:00
Kelly Brazil
cd8d38f2a1 add axfr support 2020-03-26 16:22:53 -07:00
Kelly Brazil
8ec8cd6294 Merge pull request #50 from kellyjonbrazil/dev
Dev v1.9.2
2020-03-12 17:09:04 -07:00
Kelly Brazil
c028113561 version bump to v1.9.2 2020-03-12 17:06:55 -07:00
Kelly Brazil
5f22e1c803 fix and test for osx arp entries without ifscope 2020-03-12 17:02:26 -07:00
Kelly Brazil
d3351787e5 change osx detection 2020-03-12 16:52:33 -07:00
153 changed files with 41802 additions and 778 deletions

View File

@@ -1,4 +1,4 @@
name: Test code
name: Tests
on:
push:

1
.gitignore vendored
View File

@@ -3,5 +3,4 @@ __pycache__
dist/
build/
*.egg-info/
jc/parsers.old/
.github/

2
LICENSE.md Executable file → Normal file
View File

@@ -1,6 +1,6 @@
MIT License
Copyright (c) 2019 Kelly Brazil
Copyright (c) 2020 Kelly Brazil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@@ -1 +0,0 @@
graft tests/fixtures

201
README.md Executable file → Normal file
View File

@@ -1,9 +1,12 @@
![Tests](https://github.com/kellyjonbrazil/jc/workflows/Tests/badge.svg?branch=master)
![Pypi](https://img.shields.io/pypi/v/jc.svg)
# JC
JSON CLI output utility
`jc` is used to JSONify the output of many standard linux cli tools and file types for easier parsing in scripts. See the [**Parsers**](#parsers) section for supported commands and file types.
`jc` JSONifies the output of many CLI tools and file-types for easier parsing in scripts. See the [**Parsers**](#parsers) section for supported commands and file-types.
This allows further command line processing of output with tools like `jq` simply by piping commands:
This allows further command-line processing of output with tools like `jq` by piping commands:
```
$ ls -l /usr/bin | jc --ls | jq '.[] | select(.size > 50000000)'
{
@@ -63,13 +66,42 @@ Schemas for each parser can be found in the [`docs/parsers`](https://github.com/
Release notes can be found [here](https://blog.kellybrazil.com/category/jc-news/).
## Why Would Anyone Do This?!
For more information on the motivations for this project, please see my [blog post](https://blog.kellybrazil.com/2019/11/26/bringing-the-unix-philosophy-to-the-21st-century/).
## Installation
There are several ways to get `jc`. You can install via `pip`; other OS package repositories like `zypper`, `nix-env`, `brew`, or `portsnap`; via DEB/RPM packages; or by downloading the correct binary for your architecture and running it anywhere on your filesystem.
### Pip (macOS, linux, unix, Windows)
```
$ pip3 install --upgrade jc
```
### OS Package Repositories
#### Zypper (openSUSE linux)
```
# zypper install jc
```
#### nix-env (NixOS linux)
```
$ nix-env -iA nixpkgs.jc
```
#### Brew (macOS)
```
$ brew install jc
```
#### Ports (FreeBSD)
```
# portsnap fetch update && cd /usr/ports/textproc/py-jc && make install clean
```
### Packages and Binaries
Please see https://kellyjonbrazil.github.io/jc-packaging/ for details.
## Usage
`jc` accepts piped input from `STDIN` and outputs a JSON representation of the previous command's output to `STDOUT`.
```
@@ -91,6 +123,7 @@ The JSON output can be compact (default) or pretty formatted with the `-p` optio
- `--csv` enables the `CSV` file parser
- `--df` enables the `df` command parser
- `--dig` enables the `dig` command parser
- `--dmidecode` enables the `dmidecode` command parser
- `--du` enables the `du` command parser
- `--env` enables the `env` command parser
- `--file` enables the `file` command parser
@@ -136,17 +169,30 @@ The JSON output can be compact (default) or pretty formatted with the `-p` optio
### Options
- `-a` about `jc`. Prints information about `jc` and the parsers (in JSON, of course!)
- `-d` debug mode. Prints trace messages if parsing issues encountered
- `-m` monochrome JSON output
- `-p` pretty format the JSON output
- `-q` quiet mode. Suppresses warning messages
- `-r` raw output. Provides a more literal JSON output with all values as text and no additional sematic processing
- `-r` raw output. Provides a more literal JSON output with all values as strings and no additional sematic processing
## Contributions
Feel free to add/improve code or parsers! You can use the [`jc/parsers/foo.py`](https://github.com/kellyjonbrazil/jc/blob/master/jc/parsers/foo.py) parser as a template and submit your parser with a pull request.
### Setting Custom Colors via Environment Variable
You can specify custom colors via the `JC_COLORS` environment variable. The `JC_COLORS` environment variable takes four comma separated string values in the following format:
```
JC_COLORS=<keyname_color>,<keyword_color>,<number_color>,<string_color>
```
Where colors are: `black`, `red`, `green`, `yellow`, `blue`, `magenta`, `cyan`, `gray`, `brightblack`, `brightred`, `brightgreen`, `brightyellow`, `brightblue`, `brightmagenta`, `brightcyan`, `white`, or `default`
For example, to set to the default colors:
```
JC_COLORS=blue,brightblack,magenta,green
```
or
```
JC_COLORS=default,default,default,default
```
## Compatibility
Some parsers like `ls`, `ps`, `dig`, etc. will work on any platform. Other parsers that are platform-specific will generate a warning message if they are used on an unsupported platform. To see all parser information, including compatibility, run `jc -ap`.
You may still use a parser on an unsupported platform - for example, you may want to parse a file with linux `lsof` output on an OSX laptop. In that case you can suppress the warning message with the `-q` cli option or the `quiet=True` function parameter in `parse()`:
```
@@ -156,8 +202,14 @@ $ cat lsof.out | jc --lsof -q
Tested on:
- Centos 7.7
- Ubuntu 18.4
- Fedora32
- OSX 10.11.6
- OSX 10.14.6
- NixOS
- FreeBSD12
## Contributions
Feel free to add/improve code or parsers! You can use the [`jc/parsers/foo.py`](https://github.com/kellyjonbrazil/jc/blob/master/jc/parsers/foo.py) parser as a template and submit your parser with a pull request.
## Acknowledgments
- CI automation and code optimizations from https://github.com/philippeitis
@@ -264,21 +316,25 @@ $ arp -a | jc --arp -p # or: jc -p arp -a
"address": "192.168.71.1",
"hwtype": "ether",
"hwaddress": "00:50:56:c0:00:08",
"iface": "ens33"
"iface": "ens33",
"permanent": true
},
{
"name": null,
"address": "192.168.71.254",
"hwtype": "ether",
"hwaddress": "00:50:56:fe:7a:b4",
"iface": "ens33"
"iface": "ens33",
"permanent": true
},
{
"name": "_gateway",
"address": "192.168.71.2",
"hwtype": "ether",
"hwaddress": "00:50:56:f7:4a:fc",
"iface": "ens33"
"iface": "ens33",
"permanent": false,
"expires": 110
}
]
```
@@ -309,7 +365,7 @@ $ blkid | jc --blkid -p # or: jc -p blkid
]
```
```
$ sudo blkid -o udev -ip /dev/sda2 | jc --blkid -p # or: sudo jc -p blkid -o udev -ip /dev/sda2
# blkid -o udev -ip /dev/sda2 | jc --blkid -p # or: jc -p blkid -o udev -ip /dev/sda2
[
{
"id_fs_uuid": "3klkIj-w1kk-DkJi-0XBJ-y3i7-i2Ac-vHqWBM",
@@ -704,6 +760,52 @@ $ dig -x 1.1.1.1 | jc --dig -p # or: jc -p dig -x 1.1.1.1
}
]
```
### dmidecode
```
# dmidecode | jc --dmidecode -p # or: jc -p dmidecode
[
{
"handle": "0x0000",
"type": 0,
"bytes": 24,
"description": "BIOS Information",
"values": {
"vendor": "Phoenix Technologies LTD",
"version": "6.00",
"release_date": "04/13/2018",
"address": "0xEA490",
"runtime_size": "88944 bytes",
"rom_size": "64 kB",
"characteristics": [
"ISA is supported",
"PCI is supported",
"PC Card (PCMCIA) is supported",
"PNP is supported",
"APM is supported",
"BIOS is upgradeable",
"BIOS shadowing is allowed",
"ESCD support is available",
"Boot from CD is supported",
"Selectable boot is supported",
"EDD is supported",
"Print screen service is supported (int 5h)",
"8042 keyboard services are supported (int 9h)",
"Serial services are supported (int 14h)",
"Printer services are supported (int 17h)",
"CGA/mono video services are supported (int 10h)",
"ACPI is supported",
"Smart battery is supported",
"BIOS boot specification is supported",
"Function key-initiated network boot is supported",
"Targeted content distribution is supported"
],
"bios_revision": "4.6",
"firmware_revision": "0.0"
}
},
...
]
```
### du
```
$ du /usr | jc --du -p # or: jc -p du /usr
@@ -1119,7 +1221,7 @@ $ cat example.ini | jc --ini -p
```
### iptables
```
$ sudo iptables --line-numbers -v -L -t nat | jc --iptables -p # or: sudo jc -p iptables --line-numbers -v -L -t nat
# iptables --line-numbers -v -L -t nat | jc --iptables -p # or: jc -p iptables --line-numbers -v -L -t nat
[
{
"chain": "PREROUTING",
@@ -1349,7 +1451,7 @@ $ lsmod | jc --lsmod -p # or: jc -p lsmod
```
### lsof
```
$ sudo lsof | jc --lsof -p # or: sudo jc -p lsof
# lsof | jc --lsof -p # or: jc -p lsof
[
{
"command": "systemd",
@@ -1436,7 +1538,7 @@ $ mount | jc --mount -p # or: jc -p mount
```
### netstat
```
$ sudo netstat -apee | jc --netstat -p # or: sudo jc -p netstat -apee
# netstat -apee | jc --netstat -p # or: jc -p netstat -apee
[
{
"proto": "tcp",
@@ -1585,6 +1687,75 @@ $ sudo netstat -apee | jc --netstat -p # or: sudo jc -p netstat -apee
},
...
]
$ netstat -r | jc --netstat -p # or: jc -p netstat -r
[
{
"destination": "default",
"gateway": "gateway",
"genmask": "0.0.0.0",
"route_flags": "UG",
"mss": 0,
"window": 0,
"irtt": 0,
"iface": "ens33",
"kind": "route"
},
{
"destination": "172.17.0.0",
"gateway": "0.0.0.0",
"genmask": "255.255.0.0",
"route_flags": "U",
"mss": 0,
"window": 0,
"irtt": 0,
"iface": "docker0",
"kind": "route"
},
{
"destination": "192.168.71.0",
"gateway": "0.0.0.0",
"genmask": "255.255.255.0",
"route_flags": "U",
"mss": 0,
"window": 0,
"irtt": 0,
"iface": "ens33",
"kind": "route"
}
]
$ netstat -i | jc --netstat -p # or: jc -p netstat -i
[
{
"iface": "ens33",
"mtu": 1500,
"rx_ok": 476,
"rx_err": 0,
"rx_drp": 0,
"rx_ovr": 0,
"tx_ok": 312,
"tx_err": 0,
"tx_drp": 0,
"tx_ovr": 0,
"flg": "BMRU",
"kind": "interface"
},
{
"iface": "lo",
"mtu": 65536,
"rx_ok": 0,
"rx_err": 0,
"rx_drp": 0,
"rx_ovr": 0,
"tx_ok": 0,
"tx_err": 0,
"tx_drp": 0,
"tx_ovr": 0,
"flg": "LRU",
"kind": "interface"
}
]
```
### ntpq
```
@@ -1831,7 +2002,7 @@ $ route -ee | jc --route -p # or: jc -p route -ee
```
### /etc/shadow file
```
$ sudo cat /etc/shadow | jc --shadow -p
# cat /etc/shadow | jc --shadow -p
[
{
"username": "root",
@@ -1868,7 +2039,7 @@ $ sudo cat /etc/shadow | jc --shadow -p
```
### ss
```
$ sudo ss -a | jc --ss -p # or: sudo jc -p ss -a
# ss -a | jc --ss -p # or: jc -p ss -a
[
{
"netid": "nl",

View File

@@ -1,6 +1,81 @@
jc changelog
20200311 v1.9.1
20200530 v1.11.2
- Update netstat parser to add freebsd support
- Update netstat parser to add route_flags_pretty field
- Update netstat parser to change osx_inode field name to unix_inode
- Update netstat parser to change osx_flags field name to unix_flags
- Update netstat parser to strip whitespace from state field
- Update route parser to add flags_pretty field
- Update arp parser to add permanent field (freebsd and osx)
- Update arp parser to add expires field (freebsd)
- Update w parser to strip whitespace from what field
- Update last parser to fix FreeBSD issues
- Update stat parser to change osx_flags field name to unix_flags
- Update stat parser to add osx_device field for freebsd and osx
- Fix freebsd compatibility message for df, fstab, mount, ntpq, stat, and uname parsers
- Fix compatibility message for platforms that include the version number at the end (e.g. freebsd12)
20200523 v1.11.1
- Update stat command parser to change osx_flags field to string
20200522 v1.11.0
- Add dmidecode command parser
- Update stat command parser to add OSX support
- Update netstat command parser to add OSX support
- Update netstat command parser to add -r (route) functionality for linux and OSX
- Update netstat command parser to add -i (interface) functionality for linux and OSX
20200511 v1.10.12
- Remove shebang from jc/cli.py for Fedora packaging
20200511 v1.10.11
- Change file permissions for Fedora packaging
20200509 v1.10.10
- Fix ls parser issue where the first file was skipped for ls -R on some platforms
- Update last parser to handle 'gone - no logout' condition
- Update netstat parser to handle bluetooth section (ignore gracefully for now)
20200508 v1.10.9
- Add license info to vendorized ifconfig-parser class
20200508 v1.10.8
- Add license file to dist for Fedora RPM packaging requirements
- Remove tests from package to keep from polluting the global site-packages
20200501 v1.10.7
- Requirements modifications for Fedora RPM packaging requirements
20200420 v1.10.6
- Remove homebrew shim references from du osx tests
20200414 v1.10.5
- Minor change of using sys.exit(0) instead of exit()
20200412 v1.10.4
- Add color customization via JC_COLORS env variable
20200409 v1.10.3
- Fix break on pipe error
20200409 v1.10.2
- Change colors to ansi and match jello colors
20200402 v1.10.1
- Code cleanup
20200402 v1.10.0
- Add color output by default when not piping data to another program
- Add -m option for monochrome output
20200326 v1.9.3
- Add axfr support for dig command parser
20200312 v1.9.2
- Updated arp parser to fix OSX detection for some edge cases
20200312 v1.9.1
- Updated file command parser to make filename splitting more robust
20200311 v1.9.0

View File

@@ -13,6 +13,7 @@ pydocmd simple jc.parsers.crontab_u+ > ../docs/parsers/crontab_u.md
pydocmd simple jc.parsers.csv+ > ../docs/parsers/csv.md
pydocmd simple jc.parsers.df+ > ../docs/parsers/df.md
pydocmd simple jc.parsers.dig+ > ../docs/parsers/dig.md
pydocmd simple jc.parsers.dmidecode+ > ../docs/parsers/dmidecode.md
pydocmd simple jc.parsers.du+ > ../docs/parsers/du.md
pydocmd simple jc.parsers.env+ > ../docs/parsers/env.md
pydocmd simple jc.parsers.file+ > ../docs/parsers/file.md

View File

@@ -59,6 +59,8 @@ Examples:
"hwtype": "ether",
"hwaddress": "00:50:56:f0:98:26",
"iface": "ens33"
"permanent": false,
"expires": 1182
},
{
"name": "gateway",
@@ -66,6 +68,8 @@ Examples:
"hwtype": "ether",
"hwaddress": "00:50:56:f7:4a:fc",
"iface": "ens33"
"permanent": false,
"expires": 110
}
]
@@ -77,6 +81,8 @@ Examples:
"hwtype": "ether",
"hwaddress": "00:50:56:fe:7a:b4",
"iface": "ens33"
"permanent": false,
"expires": "1182"
},
{
"name": "_gateway",
@@ -84,6 +90,8 @@ Examples:
"hwtype": "ether",
"hwaddress": "00:50:56:f7:4a:fc",
"iface": "ens33"
"permanent": false,
"expires": "110"
}
]
@@ -114,7 +122,9 @@ Returns:
"hwtype": string,
"hwaddress": string,
"flags_mask": string,
"iface": string
"iface": string,
"permanent": boolean,
"expires": integer
}
]

View File

@@ -7,7 +7,7 @@ Usage:
Compatibility:
'linux', 'darwin'
'linux', 'darwin', 'freebsd'
Examples:

View File

@@ -353,6 +353,15 @@ Returns:
"answer_num": integer,
"authority_num": integer,
"additional_num": integer,
"axfr": [
{
"name": string,
"class": string,
"type": string,
"ttl": integer,
"data": string
}
],
"question": {
"name": string,
"class": string,
@@ -380,6 +389,7 @@ Returns:
"server": string,
"when": string,
"rcvd": integer
"size": string
}
]

153
docs/parsers/dmidecode.md Normal file
View File

@@ -0,0 +1,153 @@
# jc.parsers.dmidecode
jc - JSON CLI output utility dmidecode Parser
Usage:
specify --dmidecode as the first argument if the piped input is coming from dmidecode
Compatibility:
'linux'
Examples:
# dmidecode | jc --dmidecode -p
[
{
"handle": "0x0000",
"type": 0,
"bytes": 24,
"description": "BIOS Information",
"values": {
"vendor": "Phoenix Technologies LTD",
"version": "6.00",
"release_date": "04/13/2018",
"address": "0xEA490",
"runtime_size": "88944 bytes",
"rom_size": "64 kB",
"characteristics": [
"ISA is supported",
"PCI is supported",
"PC Card (PCMCIA) is supported",
"PNP is supported",
"APM is supported",
"BIOS is upgradeable",
"BIOS shadowing is allowed",
"ESCD support is available",
"Boot from CD is supported",
"Selectable boot is supported",
"EDD is supported",
"Print screen service is supported (int 5h)",
"8042 keyboard services are supported (int 9h)",
"Serial services are supported (int 14h)",
"Printer services are supported (int 17h)",
"CGA/mono video services are supported (int 10h)",
"ACPI is supported",
"Smart battery is supported",
"BIOS boot specification is supported",
"Function key-initiated network boot is supported",
"Targeted content distribution is supported"
],
"bios_revision": "4.6",
"firmware_revision": "0.0"
}
},
...
]
# dmidecode | jc --dmidecode -p -r
[
{
"handle": "0x0000",
"type": "0",
"bytes": "24",
"description": "BIOS Information",
"values": {
"vendor": "Phoenix Technologies LTD",
"version": "6.00",
"release_date": "04/13/2018",
"address": "0xEA490",
"runtime_size": "88944 bytes",
"rom_size": "64 kB",
"characteristics": [
"ISA is supported",
"PCI is supported",
"PC Card (PCMCIA) is supported",
"PNP is supported",
"APM is supported",
"BIOS is upgradeable",
"BIOS shadowing is allowed",
"ESCD support is available",
"Boot from CD is supported",
"Selectable boot is supported",
"EDD is supported",
"Print screen service is supported (int 5h)",
"8042 keyboard services are supported (int 9h)",
"Serial services are supported (int 14h)",
"Printer services are supported (int 17h)",
"CGA/mono video services are supported (int 10h)",
"ACPI is supported",
"Smart battery is supported",
"BIOS boot specification is supported",
"Function key-initiated network boot is supported",
"Targeted content distribution is supported"
],
"bios_revision": "4.6",
"firmware_revision": "0.0"
}
},
...
]
## info
```python
info(self, /, *args, **kwargs)
```
## process
```python
process(proc_data)
```
Final processing to conform to the schema.
Parameters:
proc_data: (dictionary) raw structured data to process
Returns:
List of dictionaries. Structured data with the following schema:
[
{
"handle": string,
"type": integer,
"bytes": integer,
"description": string,
"values": { (null if empty)
"lowercase_no_spaces_keys": string,
"multiline_key_values": [
string,
]
}
}
]
## parse
```python
parse(data, raw=False, quiet=False)
```
Main text parsing function
Parameters:
data: (string) text data to parse
raw: (boolean) output preprocessed JSON if True
quiet: (boolean) suppress warning messages if True
Returns:
List of dictionaries. Raw or processed structured data.

View File

@@ -7,7 +7,7 @@ Usage:
Compatibility:
'linux'
'linux', 'freebsd'
Examples:

View File

@@ -147,6 +147,17 @@ Examples:
info(self, /, *args, **kwargs)
```
## IfconfigParser
```python
IfconfigParser(self, console_output)
```
## InterfaceNotFound
```python
InterfaceNotFound(self, /, *args, **kwargs)
```
## process
```python
process(proc_data)

View File

@@ -7,7 +7,7 @@ Usage:
Compatibility:
'linux', 'darwin'
'linux', 'darwin', 'freebsd'
Example:

View File

@@ -5,13 +5,18 @@ Usage:
Specify --netstat as the first argument if the piped input is coming from netstat
Caveats:
- Use of multiple 'l' options is not supported on OSX (e.g. 'netstat -rlll')
- Use of the 'A' option is not supported on OSX when using the 'r' option (e.g. netstat -rA)
Compatibility:
'linux'
'linux', 'darwin', 'freebsd'
Examples:
$ sudo netstat -apee | jc --netstat -p
# netstat -apee | jc --netstat -p
[
{
"proto": "tcp",
@@ -161,152 +166,73 @@ Examples:
...
]
$ sudo netstat -apee | jc --netstat -p -r
$ netstat -r | jc --netstat -p
[
{
"proto": "tcp",
"recv_q": "0",
"send_q": "0",
"local_address": "localhost",
"foreign_address": "0.0.0.0",
"state": "LISTEN",
"user": "systemd-resolve",
"inode": "26958",
"program_name": "systemd-resolve",
"kind": "network",
"pid": "887",
"local_port": "domain",
"foreign_port": "*",
"transport_protocol": "tcp",
"network_protocol": "ipv4"
"destination": "default",
"gateway": "gateway",
"genmask": "0.0.0.0",
"route_flags": "UG",
"mss": 0,
"window": 0,
"irtt": 0,
"iface": "ens33",
"kind": "route"
},
{
"proto": "tcp",
"recv_q": "0",
"send_q": "0",
"local_address": "0.0.0.0",
"foreign_address": "0.0.0.0",
"state": "LISTEN",
"user": "root",
"inode": "30499",
"program_name": "sshd",
"kind": "network",
"pid": "1186",
"local_port": "ssh",
"foreign_port": "*",
"transport_protocol": "tcp",
"network_protocol": "ipv4"
"destination": "172.17.0.0",
"gateway": "0.0.0.0",
"genmask": "255.255.0.0",
"route_flags": "U",
"mss": 0,
"window": 0,
"irtt": 0,
"iface": "docker0",
"kind": "route"
},
{
"proto": "tcp",
"recv_q": "0",
"send_q": "0",
"local_address": "localhost",
"foreign_address": "localhost",
"state": "ESTABLISHED",
"user": "root",
"inode": "46829",
"program_name": "sshd: root",
"kind": "network",
"pid": "2242",
"local_port": "ssh",
"foreign_port": "52186",
"transport_protocol": "tcp",
"network_protocol": "ipv4"
"destination": "192.168.71.0",
"gateway": "0.0.0.0",
"genmask": "255.255.255.0",
"route_flags": "U",
"mss": 0,
"window": 0,
"irtt": 0,
"iface": "ens33",
"kind": "route"
}
]
$ netstat -i | jc --netstat -p
[
{
"iface": "ens33",
"mtu": 1500,
"rx_ok": 476,
"rx_err": 0,
"rx_drp": 0,
"rx_ovr": 0,
"tx_ok": 312,
"tx_err": 0,
"tx_drp": 0,
"tx_ovr": 0,
"flg": "BMRU",
"kind": "interface"
},
{
"proto": "tcp",
"recv_q": "0",
"send_q": "0",
"local_address": "localhost",
"foreign_address": "localhost",
"state": "ESTABLISHED",
"user": "root",
"inode": "46828",
"program_name": "ssh",
"kind": "network",
"pid": "2241",
"local_port": "52186",
"foreign_port": "ssh",
"transport_protocol": "tcp",
"network_protocol": "ipv4"
},
{
"proto": "tcp6",
"recv_q": "0",
"send_q": "0",
"local_address": "[::]",
"foreign_address": "[::]",
"state": "LISTEN",
"user": "root",
"inode": "30510",
"program_name": "sshd",
"kind": "network",
"pid": "1186",
"local_port": "ssh",
"foreign_port": "*",
"transport_protocol": "tcp",
"network_protocol": "ipv6"
},
{
"proto": "udp",
"recv_q": "0",
"send_q": "0",
"local_address": "localhost",
"foreign_address": "0.0.0.0",
"state": null,
"user": "systemd-resolve",
"inode": "26957",
"program_name": "systemd-resolve",
"kind": "network",
"pid": "887",
"local_port": "domain",
"foreign_port": "*",
"transport_protocol": "udp",
"network_protocol": "ipv4"
},
{
"proto": "raw6",
"recv_q": "0",
"send_q": "0",
"local_address": "[::]",
"foreign_address": "[::]",
"state": "7",
"user": "systemd-network",
"inode": "27001",
"program_name": "systemd-network",
"kind": "network",
"pid": "867",
"local_port": "ipv6-icmp",
"foreign_port": "*",
"transport_protocol": null,
"network_protocol": "ipv6"
},
{
"proto": "unix",
"refcnt": "2",
"flags": null,
"type": "DGRAM",
"state": null,
"inode": "33322",
"program_name": "systemd",
"path": "/run/user/1000/systemd/notify",
"kind": "socket",
"pid": " 1607"
},
{
"proto": "unix",
"refcnt": "2",
"flags": "ACC",
"type": "SEQPACKET",
"state": "LISTENING",
"inode": "20835",
"program_name": "init",
"path": "/run/udev/control",
"kind": "socket",
"pid": " 1"
},
...
"iface": "lo",
"mtu": 65536,
"rx_ok": 0,
"rx_err": 0,
"rx_drp": 0,
"rx_ovr": 0,
"tx_ok": 0,
"tx_err": 0,
"tx_drp": 0,
"tx_ovr": 0,
"flg": "LRU",
"kind": "interface"
}
]
## info
@@ -331,28 +257,100 @@ Returns:
[
{
"proto": string,
"recv_q": integer,
"send_q": integer,
"transport_protocol" string,
"network_protocol": string,
"local_address": string,
"local_port": string,
"local_port_num": integer,
"foreign_address": string,
"foreign_port": string,
"foreign_port_num": integer,
"state": string,
"program_name": string,
"pid": integer,
"user": string,
"security_context": string,
"refcnt": integer,
"flags": string,
"type": string,
"inode": integer,
"path": string,
"kind": string
"proto": string,
"recv_q": integer,
"send_q": integer,
"transport_protocol" string,
"network_protocol": string,
"local_address": string,
"local_port": string,
"local_port_num": integer,
"foreign_address": string,
"foreign_port": string,
"foreign_port_num": integer,
"state": string,
"program_name": string,
"pid": integer,
"user": string,
"security_context": string,
"refcnt": integer,
"flags": string,
"type": string,
"inode": integer,
"path": string,
"kind": string,
"address": string,
"unix_inode": string,
"conn": string,
"refs": string,
"nextref": string,
"name": string,
"unit": integer,
"vendor": integer,
"class": integer,
"subcla": integer,
"unix_flags": integer,
"pcbcount": integer,
"rcvbuf": integer,
"sndbuf": integer,
"rxbytes": integer,
"txbytes": integer,
"destination": string,
"gateway": string,
"route_flags": string,
"route_flags_pretty": [
string,
]
"route_refs": integer,
"use": integer,
"mtu": integer,
"expire": string,
"genmask": string,
"mss": integer,
"window": integer,
"irtt": integer,
"iface": string,
"metric": integer,
"network": string,
"address": string,
"ipkts": integer, - = null
"ierrs": integer, - = null
"idrop": integer, - = null
"opkts": integer, - = null
"oerrs": integer, - = null
"coll": integer, - = null
"rx_ok": integer,
"rx_err": integer,
"rx_drp": integer,
"rx_ovr": integer,
"tx_ok": integer,
"tx_err": integer,
"tx_drp": integer,
"tx_ovr": integer,
"flg": string,
"ibytes": integer,
"obytes": integer,
"r_mbuf": integer,
"s_mbuf": integer,
"r_clus": integer,
"s_clus": integer,
"r_hiwa": integer,
"s_hiwa": integer,
"r_lowa": integer,
"s_lowa": integer,
"r_bcnt": integer,
"s_bcnt": integer,
"r_bmax": integer,
"s_bmax": integer,
"rexmit": integer,
"ooorcv": integer,
"0_win": integer,
"rexmt": float,
"persist": float,
"keep": float,
"2msl": float,
"delack": float,
"rcvtime": float,
}
]

View File

@@ -7,7 +7,7 @@ Usage:
Compatibility:
'linux'
'linux', 'freebsd'
Examples:

View File

@@ -119,17 +119,20 @@ Returns:
[
{
"destination": string,
"gateway": string,
"genmask": string,
"flags": string,
"metric": integer,
"ref": integer,
"use": integer,
"mss": integer,
"window": integer,
"irtt": integer,
"iface": string
"destination": string,
"gateway": string,
"genmask": string,
"flags": string,
"flags_pretty": [
string,
]
"metric": integer,
"ref": integer,
"use": integer,
"mss": integer,
"window": integer,
"irtt": integer,
"iface": string
}
]

View File

@@ -7,7 +7,7 @@ Usage:
Compatibility:
'linux'
'linux', 'darwin', 'freebsd'
Examples:
@@ -141,7 +141,11 @@ Returns:
"access_time": string, # - = null
"modify_time": string, # - = null
"change_time": string, # - = null
"birth_time": string # - = null
"birth_time": string, # - = null
"osx_device": integer,
"rdev": integer,
"block_size": integer,
"osx_flags": string
}
]

View File

@@ -11,7 +11,7 @@ Limitations:
Compatibility:
'linux', 'darwin'
'linux', 'darwin', 'freebsd'
Example:

101
jc/cli.py
View File

@@ -1,4 +1,3 @@
#!/usr/bin/env python3
"""jc - JSON CLI output utility
JC cli module
"""
@@ -9,11 +8,16 @@ import importlib
import textwrap
import signal
import json
from pygments import highlight
from pygments.style import Style
from pygments.token import (Name, Number, String, Keyword)
from pygments.lexers import JsonLexer
from pygments.formatters import Terminal256Formatter
import jc.utils
class info():
version = '1.9.1'
version = '1.11.2'
description = 'jc cli output JSON conversion tool'
author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com'
@@ -31,6 +35,7 @@ parsers = [
'csv',
'df',
'dig',
'dmidecode',
'du',
'env',
'file',
@@ -75,6 +80,63 @@ parsers = [
]
def set_env_colors():
"""
Grab custom colors from JC_COLORS environment variable. JC_COLORS env variable takes 4 comma
separated string values and should be in the format of:
JC_COLORS=<keyname_color>,<keyword_color>,<number_color>,<string_color>
Where colors are: black, red, green, yellow, blue, magenta, cyan, gray, brightblack, brightred,
brightgreen, brightyellow, brightblue, brightmagenta, brightcyan, white, default
Default colors:
JC_COLORS=blue,brightblack,magenta,green
or
JC_COLORS=default,default,default,default
"""
env_colors = os.getenv('JC_COLORS')
input_error = False
if env_colors:
color_list = env_colors.split(',')
else:
input_error = True
if env_colors and len(color_list) != 4:
print('jc: Warning: could not parse JC_COLORS environment variable\n', file=sys.stderr)
input_error = True
if env_colors:
for color in color_list:
if color not in ['black', 'red', 'green', 'yellow', 'blue', 'magenta', 'cyan', 'gray', 'brightblack', 'brightred',
'brightgreen', 'brightyellow', 'brightblue', 'brightmagenta', 'brightcyan', 'white', 'default']:
print('jc: Warning: could not parse JC_COLORS environment variable\n', file=sys.stderr)
input_error = True
# if there is an issue with the env variable, just set all colors to default and move on
if input_error:
color_list = ['default', 'default', 'default', 'default']
# Try the color set in the JC_COLORS env variable first. If it is set to default, then fall back to default colors
return {
Name.Tag: f'bold ansi{color_list[0]}' if not color_list[0] == 'default' else f'bold ansiblue', # key names
Keyword: f'ansi{color_list[1]}' if not color_list[1] == 'default' else f'ansibrightblack', # true, false, null
Number: f'ansi{color_list[2]}' if not color_list[2] == 'default' else f'ansimagenta', # numbers
String: f'ansi{color_list[3]}' if not color_list[3] == 'default' else f'ansigreen' # strings
}
def piped_output():
"""returns False if stdout is a TTY. True if output is being piped to another program"""
if sys.stdout.isatty():
return False
else:
return True
def ctrlc(signum, frame):
"""exit with error on SIGINT"""
sys.exit(1)
@@ -167,6 +229,7 @@ def helptext(message):
Options:
-a about jc
-d debug - show trace messages
-m monochrome output
-p pretty print output
-q quiet - suppress warnings
-r raw JSON output
@@ -181,11 +244,22 @@ def helptext(message):
print(textwrap.dedent(helptext_string), file=sys.stderr)
def json_out(data, pretty=False):
if pretty:
print(json.dumps(data, indent=2))
def json_out(data, pretty=False, mono=False, piped_out=False):
# set colors
class JcStyle(Style):
styles = set_env_colors()
if not mono and not piped_out:
if pretty:
print(highlight(json.dumps(data, indent=2), JsonLexer(), Terminal256Formatter(style=JcStyle))[0:-1])
else:
print(highlight(json.dumps(data), JsonLexer(), Terminal256Formatter(style=JcStyle))[0:-1])
else:
print(json.dumps(data))
if pretty:
print(json.dumps(data, indent=2))
else:
print(json.dumps(data))
def generate_magic_command(args):
@@ -248,7 +322,7 @@ def magic():
valid_command, run_command = generate_magic_command(sys.argv)
if valid_command:
os.system(run_command)
exit()
sys.exit(0)
elif run_command is None:
return
else:
@@ -260,6 +334,12 @@ def main():
# break on ctrl-c keyboard interrupt
signal.signal(signal.SIGINT, ctrlc)
# break on pipe error. need try/except for windows compatibility
try:
signal.signal(signal.SIGPIPE, signal.SIG_DFL)
except AttributeError:
pass
# try magic syntax first: e.g. jc -p ls -al
magic()
@@ -271,13 +351,14 @@ def main():
options.extend(opt[1:])
debug = 'd' in options
mono = 'm' in options
pretty = 'p' in options
quiet = 'q' in options
raw = 'r' in options
if 'a' in options:
json_out(about_jc(), pretty=pretty)
exit()
json_out(about_jc(), pretty=pretty, mono=mono, piped_out=piped_output())
sys.exit(0)
if sys.stdin.isatty():
helptext('missing piped data')
@@ -317,7 +398,7 @@ def main():
helptext('missing or incorrect arguments')
sys.exit(1)
json_out(result, pretty=pretty)
json_out(result, pretty=pretty, mono=mono, piped_out=piped_output())
if __name__ == '__main__':

View File

@@ -58,6 +58,8 @@ Examples:
"hwtype": "ether",
"hwaddress": "00:50:56:f0:98:26",
"iface": "ens33"
"permanent": false,
"expires": 1182
},
{
"name": "gateway",
@@ -65,6 +67,8 @@ Examples:
"hwtype": "ether",
"hwaddress": "00:50:56:f7:4a:fc",
"iface": "ens33"
"permanent": false,
"expires": 110
}
]
@@ -76,6 +80,8 @@ Examples:
"hwtype": "ether",
"hwaddress": "00:50:56:fe:7a:b4",
"iface": "ens33"
"permanent": false,
"expires": "1182"
},
{
"name": "_gateway",
@@ -83,6 +89,8 @@ Examples:
"hwtype": "ether",
"hwaddress": "00:50:56:f7:4a:fc",
"iface": "ens33"
"permanent": false,
"expires": "110"
}
]
"""
@@ -91,7 +99,7 @@ import jc.parsers.universal
class info():
version = '1.1'
version = '1.4'
description = 'arp command parser'
author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com'
@@ -123,7 +131,9 @@ def process(proc_data):
"hwtype": string,
"hwaddress": string,
"flags_mask": string,
"iface": string
"iface": string,
"permanent": boolean,
"expires": integer
}
]
"""
@@ -133,6 +143,14 @@ def process(proc_data):
if 'name' in entry and entry['name'] == '?':
entry['name'] = None
int_list = ['expires']
for key in int_list:
if key in entry:
try:
entry[key] = int(entry[key])
except (ValueError):
entry[key] = None
return proc_data
@@ -156,20 +174,30 @@ def parse(data, raw=False, quiet=False):
cleandata = data.splitlines()
# remove final Entries row if -v was used
if cleandata[-1].find('Entries:') == 0:
if cleandata[-1].startswith('Entries:'):
cleandata.pop(-1)
# detect if osx style was used
if cleandata[0].find(' ifscope ') != -1:
# detect if freebsd/osx style was used
if cleandata[0][-1] == ']':
raw_output = []
for line in cleandata:
line = line.split()
output_line = {}
output_line['name'] = line[0]
output_line['address'] = line[1].lstrip('(').rstrip(')')
output_line['hwtype'] = line[-1].lstrip('[').rstrip(']')
output_line['hwaddress'] = line[3]
output_line['iface'] = line[5]
splitline = line.split()
output_line = {
'name': splitline[0],
'address': splitline[1].lstrip('(').rstrip(')'),
'hwtype': splitline[-1].lstrip('[').rstrip(']'),
'hwaddress': splitline[3],
'iface': splitline[5]
}
if 'permanent' in splitline:
output_line['permanent'] = True
else:
output_line['permanent'] = False
if 'expires' in splitline:
output_line['expires'] = splitline[-3]
raw_output.append(output_line)
if raw:
@@ -178,7 +206,7 @@ def parse(data, raw=False, quiet=False):
return process(raw_output)
# detect if linux style was used
elif cleandata[0].find('Address') == 0:
elif cleandata[0].startswith('Address'):
# fix header row to change Flags Mask to flags_mask
cleandata[0] = cleandata[0].replace('Flags Mask', 'flags_mask')

View File

@@ -132,7 +132,7 @@ import jc.parsers.universal
class info():
version = '1.1'
version = '1.2'
description = 'crontab command and file parser'
author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com'
@@ -227,13 +227,13 @@ def parse(data, raw=False, quiet=False):
# Clear any commented lines
for i, line in reversed(list(enumerate(cleandata))):
if line.strip().find('#') == 0:
if line.strip().startswith('#'):
cleandata.pop(i)
# Pop any variable assignment lines
cron_var = []
for i, line in reversed(list(enumerate(cleandata))):
if line.find('=') != -1:
if '=' in line:
var_line = cleandata.pop(i)
var_name = var_line.split('=', maxsplit=1)[0].strip()
var_value = var_line.split('=', maxsplit=1)[1].strip()

View File

@@ -133,7 +133,7 @@ import jc.parsers.universal
class info():
version = '1.0'
version = '1.1'
description = 'crontab file parser with user support'
author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com'
@@ -228,13 +228,13 @@ def parse(data, raw=False, quiet=False):
# Clear any commented lines
for i, line in reversed(list(enumerate(cleandata))):
if line.strip().find('#') == 0:
if line.strip().startswith('#'):
cleandata.pop(i)
# Pop any variable assignment lines
cron_var = []
for i, line in reversed(list(enumerate(cleandata))):
if line.find('=') != -1:
if '=' in line:
var_line = cleandata.pop(i)
var_name = var_line.split('=', maxsplit=1)[0].strip()
var_value = var_line.split('=', maxsplit=1)[1].strip()

View File

@@ -6,7 +6,7 @@ Usage:
Compatibility:
'linux', 'darwin'
'linux', 'darwin', 'freebsd'
Examples:
@@ -73,13 +73,13 @@ import jc.parsers.universal
class info():
version = '1.1'
version = '1.3'
description = 'df command parser'
author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com'
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
compatible = ['linux', 'darwin']
compatible = ['linux', 'darwin', 'freebsd']
magic_commands = ['df']
@@ -135,7 +135,7 @@ def process(proc_data):
# change any entry for key with '_blocks' in the name to int
for k in entry:
if str(k).find('_blocks') != -1:
if '_blocks' in str(k):
try:
blocks_int = int(entry[k])
entry[k] = blocks_int

View File

@@ -324,7 +324,7 @@ import jc.utils
class info():
version = '1.0'
version = '1.2'
description = 'dig command parser'
author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com'
@@ -361,6 +361,15 @@ def process(proc_data):
"answer_num": integer,
"authority_num": integer,
"additional_num": integer,
"axfr": [
{
"name": string,
"class": string,
"type": string,
"ttl": integer,
"data": string
}
],
"question": {
"name": string,
"class": string,
@@ -388,6 +397,7 @@ def process(proc_data):
"server": string,
"when": string,
"rcvd": integer
"size": string
}
]
"""
@@ -402,6 +412,14 @@ def process(proc_data):
except (ValueError):
entry[key] = None
if 'axfr' in entry:
for ax in entry['axfr']:
try:
ttl_int = int(ax['ttl'])
ax['ttl'] = ttl_int
except (ValueError):
ax['ttl'] = None
if 'answer' in entry:
for ans in entry['answer']:
try:
@@ -508,6 +526,25 @@ def parse_answer(answer):
'data': answer_data}
def parse_axfr(axfr):
# ; <<>> DiG 9.11.14-3-Debian <<>> @81.4.108.41 axfr zonetransfer.me +nocookie
# ; (1 server found)
# ;; global options: +cmd
# zonetransfer.me. 7200 IN A 5.196.105.14
axfr = axfr.split(maxsplit=4)
axfr_name = axfr[0]
axfr_ttl = axfr[1]
axfr_class = axfr[2]
axfr_type = axfr[3]
axfr_data = axfr[4]
return {'name': axfr_name,
'ttl': axfr_ttl,
'class': axfr_class,
'type': axfr_type,
'data': axfr_data}
def parse(data, raw=False, quiet=False):
"""
Main text parsing function
@@ -534,23 +571,38 @@ def parse(data, raw=False, quiet=False):
question = False
authority = False
answer = False
axfr = False
output_entry = {}
for line in cleandata:
if line.find(';; ->>HEADER<<-') == 0:
if line.startswith('; <<>> ') and ' axfr ' in line.lower():
question = False
authority = False
answer = False
axfr = True
axfr_list = []
continue
if ';' not in line and axfr:
axfr_list.append(parse_axfr(line))
output_entry.update({'axfr': axfr_list})
continue
if line.startswith(';; ->>HEADER<<-'):
output_entry = {}
output_entry.update(parse_header(line))
continue
if line.find(';; flags:') == 0:
if line.startswith(';; flags:'):
output_entry.update(parse_flags_line(line))
continue
if line.find(';; QUESTION SECTION:') == 0:
if line.startswith(';; QUESTION SECTION:'):
question = True
authority = False
answer = False
axfr = False
continue
if question:
@@ -558,52 +610,60 @@ def parse(data, raw=False, quiet=False):
question = False
authority = False
answer = False
axfr = False
continue
if line.find(';; AUTHORITY SECTION:') == 0:
if line.startswith(';; AUTHORITY SECTION:'):
question = False
authority = True
answer = False
axfr = False
authority_list = []
continue
if line.find(';') == -1 and authority:
if ';' not in line and authority:
authority_list.append(parse_authority(line))
output_entry.update({'authority': authority_list})
continue
if line.find(';; ANSWER SECTION:') == 0:
if line.startswith(';; ANSWER SECTION:'):
question = False
authority = False
answer = True
axfr = False
answer_list = []
continue
if line.find(';') == -1 and answer:
if ';' not in line and answer:
answer_list.append(parse_answer(line))
output_entry.update({'answer': answer_list})
continue
# footer consists of 4 lines
# footer line 1
if line.find(';; Query time:') == 0:
if line.startswith(';; Query time:'):
output_entry.update({'query_time': line.split(':')[1].lstrip()})
continue
# footer line 2
if line.find(';; SERVER:') == 0:
if line.startswith(';; SERVER:'):
output_entry.update({'server': line.split(':')[1].lstrip()})
continue
# footer line 3
if line.find(';; WHEN:') == 0:
if line.startswith(';; WHEN:'):
output_entry.update({'when': line.split(':', maxsplit=1)[1].lstrip()})
continue
# footer line 4 (last line)
if line.find(';; MSG SIZE rcvd:') == 0:
if line.startswith(';; MSG SIZE rcvd:'):
output_entry.update({'rcvd': line.split(':')[1].lstrip()})
if output_entry:
raw_output.append(output_entry)
elif line.startswith(';; XFR size:'):
output_entry.update({'size': line.split(':')[1].lstrip()})
if output_entry:
raw_output.append(output_entry)

339
jc/parsers/dmidecode.py Normal file
View File

@@ -0,0 +1,339 @@
"""jc - JSON CLI output utility dmidecode Parser
Usage:
specify --dmidecode as the first argument if the piped input is coming from dmidecode
Compatibility:
'linux'
Examples:
# dmidecode | jc --dmidecode -p
[
{
"handle": "0x0000",
"type": 0,
"bytes": 24,
"description": "BIOS Information",
"values": {
"vendor": "Phoenix Technologies LTD",
"version": "6.00",
"release_date": "04/13/2018",
"address": "0xEA490",
"runtime_size": "88944 bytes",
"rom_size": "64 kB",
"characteristics": [
"ISA is supported",
"PCI is supported",
"PC Card (PCMCIA) is supported",
"PNP is supported",
"APM is supported",
"BIOS is upgradeable",
"BIOS shadowing is allowed",
"ESCD support is available",
"Boot from CD is supported",
"Selectable boot is supported",
"EDD is supported",
"Print screen service is supported (int 5h)",
"8042 keyboard services are supported (int 9h)",
"Serial services are supported (int 14h)",
"Printer services are supported (int 17h)",
"CGA/mono video services are supported (int 10h)",
"ACPI is supported",
"Smart battery is supported",
"BIOS boot specification is supported",
"Function key-initiated network boot is supported",
"Targeted content distribution is supported"
],
"bios_revision": "4.6",
"firmware_revision": "0.0"
}
},
...
]
# dmidecode | jc --dmidecode -p -r
[
{
"handle": "0x0000",
"type": "0",
"bytes": "24",
"description": "BIOS Information",
"values": {
"vendor": "Phoenix Technologies LTD",
"version": "6.00",
"release_date": "04/13/2018",
"address": "0xEA490",
"runtime_size": "88944 bytes",
"rom_size": "64 kB",
"characteristics": [
"ISA is supported",
"PCI is supported",
"PC Card (PCMCIA) is supported",
"PNP is supported",
"APM is supported",
"BIOS is upgradeable",
"BIOS shadowing is allowed",
"ESCD support is available",
"Boot from CD is supported",
"Selectable boot is supported",
"EDD is supported",
"Print screen service is supported (int 5h)",
"8042 keyboard services are supported (int 9h)",
"Serial services are supported (int 14h)",
"Printer services are supported (int 17h)",
"CGA/mono video services are supported (int 10h)",
"ACPI is supported",
"Smart battery is supported",
"BIOS boot specification is supported",
"Function key-initiated network boot is supported",
"Targeted content distribution is supported"
],
"bios_revision": "4.6",
"firmware_revision": "0.0"
}
},
...
]
"""
import jc.utils
class info():
version = '1.0'
description = 'dmidecode command parser'
author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com'
# details = 'enter any other details here'
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
compatible = ['linux']
magic_commands = ['dmidecode']
__version__ = info.version
def process(proc_data):
"""
Final processing to conform to the schema.
Parameters:
proc_data: (dictionary) raw structured data to process
Returns:
List of dictionaries. Structured data with the following schema:
[
{
"handle": string,
"type": integer,
"bytes": integer,
"description": string,
"values": { (null if empty)
"lowercase_no_spaces_keys": string,
"multiline_key_values": [
string,
]
}
}
]
"""
for entry in proc_data:
int_list = ['type', 'bytes']
for key in int_list:
if key in entry:
try:
key_int = int(entry[key])
entry[key] = key_int
except (ValueError):
entry[key] = None
if not entry['values']:
entry['values'] = None
return proc_data
def parse(data, raw=False, quiet=False):
"""
Main text parsing function
Parameters:
data: (string) text data to parse
raw: (boolean) output preprocessed JSON if True
quiet: (boolean) suppress warning messages if True
Returns:
List of dictionaries. Raw or processed structured data.
"""
if not quiet:
jc.utils.compatibility(__name__, info.compatible)
item_header = False
item_values = False
value_list = False
item = None
header = None
key = None
val = None
attribute = None
values = None
key_data = None
raw_output = []
data = data.splitlines()
# remove header rows
for row in data.copy():
if row:
data.pop(0)
else:
break
# main parsing loop
for line in data:
# new item
if not line:
item_header = True
item_values = False
value_list = False
if item:
if values:
item['values'][attribute] = values
if key_data:
item['values'][f'{key}_data'] = key_data
raw_output.append(item)
item = {}
header = None
key = None
val = None
attribute = None
values = []
key_data = []
continue
# header
if line.startswith('Handle ') and line.endswith('bytes'):
# Handle 0x0000, DMI type 0, 24 bytes
header = line.replace(',', ' ').split()
item = {
'handle': header[1],
'type': header[4],
'bytes': header[5]
}
continue
# description
if item_header:
item_header = False
item_values = True
value_list = False
item['description'] = line
item['values'] = {}
continue
# new item if multiple descriptions in handle
if not item_header and not line.startswith('\t'):
item_header = False
item_values = True
value_list = False
if item:
if values:
item['values'][attribute] = values
if key_data:
item['values'][f'{key}_data'] = key_data
raw_output.append(item)
item = {
'handle': header[1],
'type': header[4],
'bytes': header[5],
'description': line,
'values': {}
}
key = None
val = None
attribute = None
values = []
key_data = []
continue
# keys and values
if item_values \
and len(line.split(':', maxsplit=1)) == 2 \
and line.startswith('\t') \
and not line.startswith('\t\t') \
and not line.strip().endswith(':'):
item_header = False
item_values = True
value_list = False
if values:
item['values'][attribute] = values
values = []
if key_data:
item['values'][f'{key}_data'] = key_data
key_data = []
key = line.split(':', maxsplit=1)[0].strip().lower().replace(' ', '_')
val = line.split(':', maxsplit=1)[1].strip()
item['values'].update({key: val})
continue
# multi-line key
if item_values \
and line.startswith('\t') \
and not line.startswith('\t\t') \
and line.strip().endswith(':'):
item_header = False
item_values = True
value_list = True
if values:
item['values'][attribute] = values
values = []
if key_data:
item['values'][f'{key}_data'] = key_data
key_data = []
attribute = line[:-1].strip().lower().replace(' ', '_')
values = []
continue
# multi-line values
if value_list \
and line.startswith('\t\t'):
values.append(line.strip())
continue
# data for hybrid multi-line objects
if item_values \
and not value_list \
and line.startswith('\t\t'):
if f'{key}_data' not in item['values']:
item['values'][f'{key}_data'] = []
key_data.append(line.strip())
continue
if item:
raw_output.append(item)
if raw:
return raw_output
else:
return process(raw_output)

View File

@@ -6,7 +6,7 @@ Usage:
Compatibility:
'linux'
'linux', 'freebsd'
Examples:
@@ -70,13 +70,13 @@ import jc.utils
class info():
version = '1.0'
version = '1.2'
description = 'fstab file parser'
author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com'
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
compatible = ['linux']
compatible = ['linux', 'freebsd']
__version__ = info.version
@@ -145,7 +145,7 @@ def parse(data, raw=False, quiet=False):
for line in cleandata:
output_line = {}
# ignore commented lines
if line.strip().find('#') == 0:
if line.strip().startswith('#'):
continue
line_list = line.split(maxsplit=6)

View File

@@ -61,7 +61,7 @@ import jc.utils
class info():
version = '1.0'
version = '1.1'
description = '/etc/hosts file parser'
author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com'
@@ -126,7 +126,7 @@ def parse(data, raw=False, quiet=False):
for line in cleandata:
output_line = {}
# ignore commented lines
if line.strip().find('#') == 0:
if line.strip().startswith('#'):
continue
line_list = line.split(maxsplit=1)
@@ -136,7 +136,7 @@ def parse(data, raw=False, quiet=False):
comment_found = False
for i, item in enumerate(hosts_list):
if item.find('#') != -1:
if '#' in item:
comment_found = True
comment_item = i
break

View File

@@ -141,16 +141,17 @@ Examples:
}
]
"""
import re
from collections import namedtuple
import jc.utils
from ifconfigparser import IfconfigParser
class info():
version = '1.5'
version = '1.7'
description = 'ifconfig command parser'
author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com'
details = 'Using ifconfig-parser package from https://github.com/KnightWhoSayNi/ifconfig-parser'
details = 'Using ifconfig-parser from https://github.com/KnightWhoSayNi/ifconfig-parser'
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
compatible = ['linux', 'aix', 'freebsd', 'darwin']
@@ -160,6 +161,222 @@ class info():
__version__ = info.version
class IfconfigParser(object):
# Author: threeheadedknight@protonmail.com
# Date created: 30.06.2018 17:03
# Python Version: 3.7
# MIT License
# Copyright (c) 2018 threeheadedknight@protonmail.com
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
attributes = ['name', 'type', 'mac_addr', 'ipv4_addr', 'ipv4_bcast', 'ipv4_mask', 'ipv6_addr', 'ipv6_mask',
'ipv6_scope', 'state', 'mtu', 'metric', 'rx_packets', 'rx_errors', 'rx_dropped', 'rx_overruns',
'rx_frame', 'tx_packets', 'tx_errors', 'tx_dropped', 'tx_overruns', 'tx_carrier', 'tx_collisions',
'rx_bytes', 'tx_bytes']
def __init__(self, console_output):
"""
:param console_output:
"""
if isinstance(console_output, list):
source_data = " ".join(console_output)
else:
source_data = console_output.replace("\n", " ")
self.interfaces = self.parser(source_data=source_data)
def list_interfaces(self):
"""
:return:
"""
return sorted(self.interfaces.keys())
def count_interfaces(self):
"""
:return:
"""
return len(self.interfaces.keys())
def filter_interfaces(self, **kwargs):
"""
:param kwargs:
:return:
"""
for attr in kwargs.keys():
if attr not in IfconfigParser.attributes:
raise ValueError("Attribute [{}] not supported.".format(attr))
filtered_interfaces = []
for name, details in self.interfaces.items():
if all(getattr(details, attr) == kwargs[attr] for attr in kwargs.keys()):
filtered_interfaces.append(name)
return sorted(filtered_interfaces)
def get_interface(self, name):
"""
:param name:
:return:
"""
if name in self.list_interfaces():
return self.interfaces[name]
else:
raise InterfaceNotFound("Interface [{}] not found.".format(name))
def get_interfaces(self):
"""
:return:
"""
return self.interfaces
def is_available(self, name):
"""
:param name:
:return:
"""
return name in self.interfaces
def parser(self, source_data):
"""
:param source_data:
:return:
"""
# Linux syntax
re_linux_interface = re.compile(
r"(?P<name>[a-zA-Z0-9:._-]+)\s+Link encap:(?P<type>\S+\s?\S+)(\s+HWaddr\s+\b"
r"(?P<mac_addr>[0-9A-Fa-f:?]+))?",
re.I)
re_linux_ipv4 = re.compile(
r"inet addr:(?P<ipv4_addr>(?:[0-9]{1,3}\.){3}[0-9]{1,3})(\s+Bcast:"
r"(?P<ipv4_bcast>(?:[0-9]{1,3}\.){3}[0-9]{1,3}))?\s+Mask:(?P<ipv4_mask>(?:[0-9]{1,3}\.){3}[0-9]{1,3})",
re.I)
re_linux_ipv6 = re.compile(
r"inet6 addr:\s+(?P<ipv6_addr>\S+)/(?P<ipv6_mask>[0-9]+)\s+Scope:(?P<ipv6_scope>Link|Host)",
re.I)
re_linux_state = re.compile(
r"\W+(?P<state>(?:\w+\s)+)(?:\s+)?MTU:(?P<mtu>[0-9]+)\s+Metric:(?P<metric>[0-9]+)", re.I)
re_linux_rx = re.compile(
r"RX packets:(?P<rx_packets>[0-9]+)\s+errors:(?P<rx_errors>[0-9]+)\s+dropped:"
r"(?P<rx_dropped>[0-9]+)\s+overruns:(?P<rx_overruns>[0-9]+)\s+frame:(?P<rx_frame>[0-9]+)",
re.I)
re_linux_tx = re.compile(
r"TX packets:(?P<tx_packets>[0-9]+)\s+errors:(?P<tx_errors>[0-9]+)\s+dropped:"
r"(?P<tx_dropped>[0-9]+)\s+overruns:(?P<tx_overruns>[0-9]+)\s+carrier:(?P<tx_carrier>[0-9]+)",
re.I)
re_linux_bytes = re.compile(r"\W+RX bytes:(?P<rx_bytes>\d+)\s+\(.*\)\s+TX bytes:(?P<tx_bytes>\d+)\s+\(.*\)", re.I)
re_linux_tx_stats = re.compile(r"collisions:(?P<tx_collisions>[0-9]+)\s+txqueuelen:[0-9]+", re.I)
re_linux = [re_linux_interface, re_linux_ipv4, re_linux_ipv6, re_linux_state, re_linux_rx, re_linux_tx,
re_linux_bytes, re_linux_tx_stats]
# OpenBSD syntax
re_openbsd_interface = re.compile(
r"(?P<name>[a-zA-Z0-9:._-]+):\s+flags=(?P<flags>[0-9]+)<(?P<state>\S+)?>\s+mtu\s+(?P<mtu>[0-9]+)",
re.I)
re_openbsd_ipv4 = re.compile(
r"inet (?P<ipv4_addr>(?:[0-9]{1,3}\.){3}[0-9]{1,3})\s+netmask\s+"
r"(?P<ipv4_mask>(?:[0-9]{1,3}\.){3}[0-9]{1,3})(\s+broadcast\s+"
r"(?P<ipv4_bcast>(?:[0-9]{1,3}\.){3}[0-9]{1,3}))?",
re.I)
re_openbsd_ipv6 = re.compile(
r"inet6\s+(?P<ipv6_addr>\S+)\s+prefixlen\s+(?P<ipv6_mask>[0-9]+)\s+scopeid\s+(?P<ipv6_scope>\w+x\w+)<"
r"(?:link|host)>",
re.I)
re_openbsd_details = re.compile(
r"\S+\s+(?:(?P<mac_addr>[0-9A-Fa-f:?]+)\s+)?txqueuelen\s+[0-9]+\s+\((?P<type>\S+\s?\S+)\)", re.I)
re_openbsd_rx = re.compile(r"RX packets (?P<rx_packets>[0-9]+)\s+bytes\s+(?P<rx_bytes>\d+)\s+.*", re.I)
re_openbsd_rx_stats = re.compile(
r"RX errors (?P<rx_errors>[0-9]+)\s+dropped\s+(?P<rx_dropped>[0-9]+)\s+overruns\s+"
r"(?P<rx_overruns>[0-9]+)\s+frame\s+(?P<rx_frame>[0-9]+)",
re.I)
re_openbsd_tx = re.compile(r"TX packets (?P<tx_packets>[0-9]+)\s+bytes\s+(?P<tx_bytes>\d+)\s+.*", re.I)
re_openbsd_tx_stats = re.compile(
r"TX errors (?P<tx_errors>[0-9]+)\s+dropped\s+(?P<tx_dropped>[0-9]+)\s+overruns\s+"
r"(?P<tx_overruns>[0-9]+)\s+carrier\s+(?P<tx_carrier>[0-9]+)\s+collisions\s+(?P<tx_collisions>[0-9]+)",
re.I)
re_openbsd = [re_openbsd_interface, re_openbsd_ipv4, re_openbsd_ipv6, re_openbsd_details, re_openbsd_rx,
re_openbsd_rx_stats, re_openbsd_tx, re_openbsd_tx_stats]
# FreeBSD syntax
re_freebsd_interface = re.compile(
r"(?P<name>[a-zA-Z0-9:._-]+):\s+flags=(?P<flags>[0-9]+)<(?P<state>\S+)>\s+metric\s+"
r"(?P<metric>[0-9]+)\s+mtu\s+(?P<mtu>[0-9]+)",
re.I)
re_freebsd_ipv4 = re.compile(
r"inet (?P<ipv4_addr>(?:[0-9]{1,3}\.){3}[0-9]{1,3})\s+netmask\s+(?P<ipv4_mask>0x\S+)(\s+broadcast\s+"
r"(?P<ipv4_bcast>(?:[0-9]{1,3}\.){3}[0-9]{1,3}))?",
re.I)
re_freebsd_ipv6 = re.compile(r"\s?inet6\s(?P<ipv6_addr>.*)(?:\%\w+\d+)\sprefixlen\s(?P<ipv6_mask>\d+)(?:\s\w+)?\sscopeid\s(?P<ipv6_scope>\w+x\w+)", re.I)
re_freebsd_details = re.compile(r"ether\s+(?P<mac_addr>[0-9A-Fa-f:?]+)", re.I)
re_freebsd = [re_freebsd_interface, re_freebsd_ipv4, re_freebsd_ipv6, re_freebsd_details]
available_interfaces = dict()
for pattern in [re_linux_interface, re_openbsd_interface, re_freebsd_interface]:
network_interfaces = re.finditer(pattern, source_data)
positions = []
while True:
try:
pos = next(network_interfaces)
positions.append(max(pos.start() - 1, 0))
except StopIteration:
break
if positions:
positions.append(len(source_data))
break
if not positions:
return available_interfaces
for l, r in zip(positions, positions[1:]):
chunk = source_data[l:r]
_interface = dict()
for pattern in re_linux + re_openbsd + re_freebsd:
match = re.search(pattern, chunk.replace('\t', '\n'))
if match:
details = match.groupdict()
for k, v in details.items():
if isinstance(v, str): details[k] = v.strip()
_interface.update(details)
if _interface is not None:
available_interfaces[_interface['name']] = self.update_interface_details(_interface)
return available_interfaces
@staticmethod
def update_interface_details(interface):
for attr in IfconfigParser.attributes:
if attr not in interface:
interface[attr] = None
return namedtuple('Interface', interface.keys())(**interface)
class InterfaceNotFound(Exception):
"""
"""
pass
def process(proc_data):
"""
Final processing to conform to the schema.
@@ -220,7 +437,7 @@ def process(proc_data):
# convert OSX-style subnet mask to dotted quad
if 'ipv4_mask' in entry:
try:
if entry['ipv4_mask'].find('0x') == 0:
if entry['ipv4_mask'].startswith('0x'):
new_mask = entry['ipv4_mask']
new_mask = new_mask.lstrip('0x')
new_mask = '.'.join(str(int(i, 16)) for i in [new_mask[i:i + 2] for i in range(0, len(new_mask), 2)])

View File

@@ -134,7 +134,7 @@ import jc.utils
class info():
version = '1.1'
version = '1.2'
description = 'iptables command parser'
author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com'
@@ -247,7 +247,7 @@ def parse(data, raw=False, quiet=False):
for line in cleandata:
if line.find('Chain') == 0:
if line.startswith('Chain'):
raw_output.append(chain)
chain = {}
headers = []
@@ -259,7 +259,7 @@ def parse(data, raw=False, quiet=False):
continue
elif line.find('target') == 0 or line.find('pkts') == 1 or line.find('num') == 0:
elif line.startswith('target') or line.find('pkts') == 1 or line.startswith('num'):
headers = []
headers = [h for h in ' '.join(line.lower().strip().split()).split() if h]
headers.append("options")

View File

@@ -77,7 +77,7 @@ import jc.utils
class info():
version = '1.0'
version = '1.1'
description = 'jobs command parser'
author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com'
@@ -176,11 +176,11 @@ def parse(data, raw=False, quiet=False):
parsed_line.insert(0, job_number)
# check for + or - in first field
if parsed_line[0].find('+') != -1:
if '+' in parsed_line[0]:
job_history = 'current'
parsed_line[0] = parsed_line[0].rstrip('+')
if parsed_line[0].find('-') != -1:
if '-' in parsed_line[0]:
job_history = 'previous'
parsed_line[0] = parsed_line[0].rstrip('-')

View File

@@ -72,7 +72,7 @@ import jc.utils
class info():
version = '1.0'
version = '1.2'
description = 'last and lastb command parser'
author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com'
@@ -110,6 +110,9 @@ def process(proc_data):
]
"""
for entry in proc_data:
if 'user' in entry and entry['user'] == 'boot_time':
entry['user'] = 'boot time'
if 'tty' in entry and entry['tty'] == '~':
entry['tty'] = None
@@ -122,6 +125,9 @@ def process(proc_data):
if 'logout' in entry and entry['logout'] == 'still_logged_in':
entry['logout'] = 'still logged in'
if 'logout' in entry and entry['logout'] == 'gone_-_no_logout':
entry['logout'] = 'gone - no logout'
return proc_data
@@ -152,16 +158,23 @@ def parse(data, raw=False, quiet=False):
for entry in cleandata:
output_line = {}
if entry.startswith('wtmp begins ') or entry.startswith('btmp begins '):
if entry.startswith('wtmp begins ') or entry.startswith('btmp begins ') or entry.startswith('utx.log begins '):
continue
entry = entry.replace('system boot', 'system_boot')
entry = entry.replace('boot time', 'boot_time')
entry = entry.replace(' still logged in', '- still_logged_in')
entry = entry.replace(' gone - no logout', '- gone_-_no_logout')
linedata = entry.split()
if re.match(r'[MTWFS][ouerha][nedritnu] [JFMASOND][aepuco][nbrynlgptvc]', ' '.join(linedata[2:4])):
linedata.insert(2, '-')
# freebsd fix
if linedata[0] == 'boot_time':
linedata.insert(1, '-')
linedata.insert(1, '~')
output_line['user'] = linedata[0]
output_line['tty'] = linedata[1]
output_line['hostname'] = linedata[2]

View File

@@ -149,7 +149,7 @@ import jc.utils
class info():
version = '1.3'
version = '1.4'
description = 'ls command parser'
author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com'
@@ -235,8 +235,9 @@ def parse(data, raw=False, quiet=False):
if not re.match(r'[-dclpsbDCMnP?]([-r][-w][-xsS]){2}([-r][-w][-xtT])[+]?', linedata[0]) \
and linedata[0].endswith(':'):
parent = linedata.pop(0)[:-1]
# Pop following total line
linedata.pop(0)
# Pop following total line if it exists
if re.match(r'total [0-9]+', linedata[0]):
linedata.pop(0)
if linedata:
# Check if -l was used to parse extra data

View File

@@ -97,7 +97,7 @@ import jc.parsers.universal
class info():
version = '1.0'
version = '1.1'
description = 'lsof command parser'
author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com'
@@ -180,47 +180,6 @@ def parse(data, raw=False, quiet=False):
raw_output = jc.parsers.universal.sparse_table_parse(cleandata)
'''
# find column value of last character of each header
header_text = cleandata.pop(0).lower()
# clean up 'size/off' header
# even though forward slash in a key is valid json, it can make things difficult
header_row = header_text.replace('/', '_')
headers = header_row.split()
header_spec = []
for i, h in enumerate(headers):
# header tuple is (index, header_name, col)
header_spec.append((i, h, header_row.find(h) + len(h)))
# parse lines
for entry in cleandata:
output_line = {}
# normalize data by inserting Null for missing data
temp_line = entry.split(maxsplit=len(headers) - 1)
for spec in header_spec:
index = spec[0]
header_name = spec[1]
col = spec[2] - 1 # subtract one since column starts at 0 instead of 1
if header_name == 'command' or header_name == 'name':
continue
if entry[col] in string.whitespace:
temp_line.insert(index, None)
name = ' '.join(temp_line[9:])
fixed_line = temp_line[0:9]
fixed_line.append(name)
output_line = dict(zip(headers, fixed_line))
raw_output.append(output_line)
'''
if raw:
return raw_output
else:

View File

@@ -6,7 +6,7 @@ Usage:
Compatibility:
'linux', 'darwin'
'linux', 'darwin', 'freebsd'
Example:
@@ -56,13 +56,13 @@ import jc.utils
class info():
version = '1.1'
version = '1.3'
description = 'mount command parser'
author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com'
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
compatible = ['linux', 'darwin']
compatible = ['linux', 'darwin', 'freebsd']
magic_commands = ['mount']
@@ -165,7 +165,7 @@ def parse(data, raw=False, quiet=False):
if cleandata:
# check for OSX output
if cleandata[0].find(' type ') == -1:
if ' type ' not in cleandata[0]:
raw_output = osx_parse(cleandata)
else:

View File

@@ -4,13 +4,18 @@ Usage:
Specify --netstat as the first argument if the piped input is coming from netstat
Caveats:
- Use of multiple 'l' options is not supported on OSX (e.g. 'netstat -rlll')
- Use of the 'A' option is not supported on OSX when using the 'r' option (e.g. netstat -rA)
Compatibility:
'linux'
'linux', 'darwin', 'freebsd'
Examples:
$ sudo netstat -apee | jc --netstat -p
# netstat -apee | jc --netstat -p
[
{
"proto": "tcp",
@@ -160,166 +165,85 @@ Examples:
...
]
$ sudo netstat -apee | jc --netstat -p -r
$ netstat -r | jc --netstat -p
[
{
"proto": "tcp",
"recv_q": "0",
"send_q": "0",
"local_address": "localhost",
"foreign_address": "0.0.0.0",
"state": "LISTEN",
"user": "systemd-resolve",
"inode": "26958",
"program_name": "systemd-resolve",
"kind": "network",
"pid": "887",
"local_port": "domain",
"foreign_port": "*",
"transport_protocol": "tcp",
"network_protocol": "ipv4"
"destination": "default",
"gateway": "gateway",
"genmask": "0.0.0.0",
"route_flags": "UG",
"mss": 0,
"window": 0,
"irtt": 0,
"iface": "ens33",
"kind": "route"
},
{
"proto": "tcp",
"recv_q": "0",
"send_q": "0",
"local_address": "0.0.0.0",
"foreign_address": "0.0.0.0",
"state": "LISTEN",
"user": "root",
"inode": "30499",
"program_name": "sshd",
"kind": "network",
"pid": "1186",
"local_port": "ssh",
"foreign_port": "*",
"transport_protocol": "tcp",
"network_protocol": "ipv4"
"destination": "172.17.0.0",
"gateway": "0.0.0.0",
"genmask": "255.255.0.0",
"route_flags": "U",
"mss": 0,
"window": 0,
"irtt": 0,
"iface": "docker0",
"kind": "route"
},
{
"proto": "tcp",
"recv_q": "0",
"send_q": "0",
"local_address": "localhost",
"foreign_address": "localhost",
"state": "ESTABLISHED",
"user": "root",
"inode": "46829",
"program_name": "sshd: root",
"kind": "network",
"pid": "2242",
"local_port": "ssh",
"foreign_port": "52186",
"transport_protocol": "tcp",
"network_protocol": "ipv4"
"destination": "192.168.71.0",
"gateway": "0.0.0.0",
"genmask": "255.255.255.0",
"route_flags": "U",
"mss": 0,
"window": 0,
"irtt": 0,
"iface": "ens33",
"kind": "route"
}
]
$ netstat -i | jc --netstat -p
[
{
"iface": "ens33",
"mtu": 1500,
"rx_ok": 476,
"rx_err": 0,
"rx_drp": 0,
"rx_ovr": 0,
"tx_ok": 312,
"tx_err": 0,
"tx_drp": 0,
"tx_ovr": 0,
"flg": "BMRU",
"kind": "interface"
},
{
"proto": "tcp",
"recv_q": "0",
"send_q": "0",
"local_address": "localhost",
"foreign_address": "localhost",
"state": "ESTABLISHED",
"user": "root",
"inode": "46828",
"program_name": "ssh",
"kind": "network",
"pid": "2241",
"local_port": "52186",
"foreign_port": "ssh",
"transport_protocol": "tcp",
"network_protocol": "ipv4"
},
{
"proto": "tcp6",
"recv_q": "0",
"send_q": "0",
"local_address": "[::]",
"foreign_address": "[::]",
"state": "LISTEN",
"user": "root",
"inode": "30510",
"program_name": "sshd",
"kind": "network",
"pid": "1186",
"local_port": "ssh",
"foreign_port": "*",
"transport_protocol": "tcp",
"network_protocol": "ipv6"
},
{
"proto": "udp",
"recv_q": "0",
"send_q": "0",
"local_address": "localhost",
"foreign_address": "0.0.0.0",
"state": null,
"user": "systemd-resolve",
"inode": "26957",
"program_name": "systemd-resolve",
"kind": "network",
"pid": "887",
"local_port": "domain",
"foreign_port": "*",
"transport_protocol": "udp",
"network_protocol": "ipv4"
},
{
"proto": "raw6",
"recv_q": "0",
"send_q": "0",
"local_address": "[::]",
"foreign_address": "[::]",
"state": "7",
"user": "systemd-network",
"inode": "27001",
"program_name": "systemd-network",
"kind": "network",
"pid": "867",
"local_port": "ipv6-icmp",
"foreign_port": "*",
"transport_protocol": null,
"network_protocol": "ipv6"
},
{
"proto": "unix",
"refcnt": "2",
"flags": null,
"type": "DGRAM",
"state": null,
"inode": "33322",
"program_name": "systemd",
"path": "/run/user/1000/systemd/notify",
"kind": "socket",
"pid": " 1607"
},
{
"proto": "unix",
"refcnt": "2",
"flags": "ACC",
"type": "SEQPACKET",
"state": "LISTENING",
"inode": "20835",
"program_name": "init",
"path": "/run/udev/control",
"kind": "socket",
"pid": " 1"
},
...
"iface": "lo",
"mtu": 65536,
"rx_ok": 0,
"rx_err": 0,
"rx_drp": 0,
"rx_ovr": 0,
"tx_ok": 0,
"tx_err": 0,
"tx_drp": 0,
"tx_ovr": 0,
"flg": "LRU",
"kind": "interface"
}
]
"""
import string
import jc.utils
class info():
version = '1.2'
version = '1.6'
description = 'netstat command parser'
author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com'
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
compatible = ['linux']
compatible = ['linux', 'darwin', 'freebsd']
magic_commands = ['netstat']
@@ -340,34 +264,112 @@ def process(proc_data):
[
{
"proto": string,
"recv_q": integer,
"send_q": integer,
"transport_protocol" string,
"network_protocol": string,
"local_address": string,
"local_port": string,
"local_port_num": integer,
"foreign_address": string,
"foreign_port": string,
"foreign_port_num": integer,
"state": string,
"program_name": string,
"pid": integer,
"user": string,
"security_context": string,
"refcnt": integer,
"flags": string,
"type": string,
"inode": integer,
"path": string,
"kind": string
"proto": string,
"recv_q": integer,
"send_q": integer,
"transport_protocol" string,
"network_protocol": string,
"local_address": string,
"local_port": string,
"local_port_num": integer,
"foreign_address": string,
"foreign_port": string,
"foreign_port_num": integer,
"state": string,
"program_name": string,
"pid": integer,
"user": string,
"security_context": string,
"refcnt": integer,
"flags": string,
"type": string,
"inode": integer,
"path": string,
"kind": string,
"address": string,
"unix_inode": string,
"conn": string,
"refs": string,
"nextref": string,
"name": string,
"unit": integer,
"vendor": integer,
"class": integer,
"subcla": integer,
"unix_flags": integer,
"pcbcount": integer,
"rcvbuf": integer,
"sndbuf": integer,
"rxbytes": integer,
"txbytes": integer,
"destination": string,
"gateway": string,
"route_flags": string,
"route_flags_pretty": [
string,
]
"route_refs": integer,
"use": integer,
"mtu": integer,
"expire": string,
"genmask": string,
"mss": integer,
"window": integer,
"irtt": integer,
"iface": string,
"metric": integer,
"network": string,
"address": string,
"ipkts": integer, - = null
"ierrs": integer, - = null
"idrop": integer, - = null
"opkts": integer, - = null
"oerrs": integer, - = null
"coll": integer, - = null
"rx_ok": integer,
"rx_err": integer,
"rx_drp": integer,
"rx_ovr": integer,
"tx_ok": integer,
"tx_err": integer,
"tx_drp": integer,
"tx_ovr": integer,
"flg": string,
"ibytes": integer,
"obytes": integer,
"r_mbuf": integer,
"s_mbuf": integer,
"r_clus": integer,
"s_clus": integer,
"r_hiwa": integer,
"s_hiwa": integer,
"r_lowa": integer,
"s_lowa": integer,
"r_bcnt": integer,
"s_bcnt": integer,
"r_bmax": integer,
"s_bmax": integer,
"rexmit": integer,
"ooorcv": integer,
"0_win": integer,
"rexmt": float,
"persist": float,
"keep": float,
"2msl": float,
"delack": float,
"rcvtime": float,
}
]
"""
for entry in proc_data:
# integer changes
int_list = ['recv_q', 'send_q', 'pid', 'refcnt', 'inode']
int_list = ['recv_q', 'send_q', 'pid', 'refcnt', 'inode', 'unit', 'vendor', 'class',
'osx_flags', 'subcla', 'pcbcount', 'rcvbuf', 'sndbuf', 'rxbytes', 'txbytes',
'route_refs', 'use', 'mtu', 'mss', 'window', 'irtt', 'metric', 'ipkts',
'ierrs', 'opkts', 'oerrs', 'coll', 'rx_ok', 'rx_err', 'rx_drp', 'rx_ovr',
'tx_ok', 'tx_err', 'tx_drp', 'tx_ovr', 'idrop', 'ibytes', 'obytes', 'r_mbuf',
's_mbuf', 'r_clus', 's_clus', 'r_hiwa', 's_hiwa', 'r_lowa', 's_lowa', 'r_bcnt',
's_bcnt', 'r_bmax', 's_bmax', 'rexmit', 'ooorcv', '0_win']
for key in int_list:
if key in entry:
try:
@@ -376,6 +378,16 @@ def process(proc_data):
except (ValueError):
entry[key] = None
# float changes
float_list = ['rexmt', 'persist', 'keep', '2msl', 'delack', 'rcvtime']
for key in float_list:
if key in entry:
try:
key_float = float(entry[key])
entry[key] = key_float
except (ValueError):
entry[key] = None
if 'local_port' in entry:
try:
entry['local_port_num'] = int(entry['local_port'])
@@ -391,128 +403,6 @@ def process(proc_data):
return proc_data
def normalize_headers(header):
header = header.lower()
header = header.replace('local address', 'local_address')
header = header.replace('foreign address', 'foreign_address')
header = header.replace('pid/program name', 'program_name')
header = header.replace('security context', 'security_context')
header = header.replace('i-node', 'inode')
header = header.replace('-', '_')
return header
def parse_network(headers, entry):
# Count words in header
# if len of line is one less than len of header, then insert None in field 5
entry = entry.split(maxsplit=len(headers) - 1)
if len(entry) == len(headers) - 1:
entry.insert(5, None)
output_line = dict(zip(headers, entry))
output_line['kind'] = 'network'
return output_line
def parse_socket(header_text, headers, entry):
output_line = {}
# get the column # of first letter of "state"
state_col = header_text.find('state')
# get the program name column area
pn_start = header_text.find('program_name')
pn_end = header_text.find('path') - 1
# remove [ and ] from each line
entry = entry.replace('[ ]', '---')
entry = entry.replace('[', ' ').replace(']', ' ')
# find program_name column area and substitute spaces with \u2063 there
old_pn = entry[pn_start:pn_end]
new_pn = old_pn.replace(' ', '\u2063')
entry = entry.replace(old_pn, new_pn)
entry_list = entry.split(maxsplit=len(headers) - 1)
# check column # to see if state column is populated
if entry[state_col] in string.whitespace:
entry_list.insert(4, None)
output_line = dict(zip(headers, entry_list))
output_line['kind'] = 'socket'
# fix program_name field to turn \u2063 back to spaces
if 'program_name' in output_line:
if output_line['program_name']:
old_d_pn = output_line['program_name']
new_d_pn = old_d_pn.replace('\u2063', ' ')
output_line['program_name'] = new_d_pn
return output_line
def parse_post(raw_data):
# clean up trailing whitespace on each item in each entry
# flags --- = null
# program_name - = null
# split pid and program name and ip addresses and ports
# create network and transport protocol fields
for entry in raw_data:
for item in entry:
try:
entry[item] = entry[item].rstrip()
except (AttributeError):
# skips trying to rstrip Null entries
pass
if 'flags' in entry:
if entry['flags'] == '---':
entry['flags'] = None
if 'program_name' in entry:
entry['program_name'] = entry['program_name'].strip()
if entry['program_name'] == '-':
entry['program_name'] = None
if entry['program_name']:
pid = entry['program_name'].split('/', maxsplit=1)[0]
name = entry['program_name'].split('/', maxsplit=1)[1]
entry['pid'] = pid
entry['program_name'] = name
if 'local_address' in entry:
if entry['local_address']:
ladd = entry['local_address'].rsplit(':', maxsplit=1)[0]
lport = entry['local_address'].rsplit(':', maxsplit=1)[1]
entry['local_address'] = ladd
entry['local_port'] = lport
if 'foreign_address' in entry:
if entry['foreign_address']:
fadd = entry['foreign_address'].rsplit(':', maxsplit=1)[0]
fport = entry['foreign_address'].rsplit(':', maxsplit=1)[1]
entry['foreign_address'] = fadd
entry['foreign_port'] = fport
if 'proto' in entry and 'kind' in entry:
if entry['kind'] == 'network':
if entry['proto'].find('tcp') != -1:
entry['transport_protocol'] = 'tcp'
elif entry['proto'].find('udp') != -1:
entry['transport_protocol'] = 'udp'
else:
entry['transport_protocol'] = None
if entry['proto'].find('6') != -1:
entry['network_protocol'] = 'ipv6'
else:
entry['network_protocol'] = 'ipv4'
return raw_data
def parse(data, raw=False, quiet=False):
"""
Main text parsing function
@@ -527,51 +417,33 @@ def parse(data, raw=False, quiet=False):
List of dictionaries. Raw or processed structured data.
"""
import jc.utils
if not quiet:
jc.utils.compatibility(__name__, info.compatible)
cleandata = data.splitlines()
cleandata = list(filter(None, cleandata))
raw_output = []
network = False
socket = False
headers = ''
network_list = []
socket_list = []
for line in cleandata:
# check for FreeBSD/OSX vs Linux
# is this from FreeBSD/OSX?
if cleandata[0] == 'Active Internet connections' \
or cleandata[0] == 'Active Internet connections (including servers)' \
or cleandata[0] == 'Active Multipath Internet connections' \
or cleandata[0] == 'Active LOCAL (UNIX) domain sockets' \
or cleandata[0] == 'Registered kernel control modules' \
or cleandata[0] == 'Active kernel event sockets' \
or cleandata[0] == 'Active kernel control sockets' \
or cleandata[0] == 'Routing tables' \
or cleandata[0].startswith('Name '):
if line.find('Active Internet') == 0:
network_list = []
network = True
socket = False
continue
import jc.parsers.netstat_freebsd_osx
raw_output = jc.parsers.netstat_freebsd_osx.parse(cleandata)
if line.find('Active UNIX') == 0:
socket_list = []
network = False
socket = True
continue
if line.find('Proto') == 0:
header_text = normalize_headers(line)
headers = header_text.split()
continue
if network:
network_list.append(parse_network(headers, line))
continue
if socket:
socket_list.append(parse_socket(header_text, headers, line))
continue
for item in [network_list, socket_list]:
for entry in item:
raw_output.append(entry)
raw_output = parse_post(raw_output)
# use linux parser
else:
import jc.parsers.netstat_linux
raw_output = jc.parsers.netstat_linux.parse(cleandata)
if raw:
return raw_output

View File

@@ -0,0 +1,320 @@
"""jc - JSON CLI output utility FreeBSD and OSX netstat Parser"""
def normalize_headers(header):
header = header.lower()
header = header.replace('local address', 'local_address')
header = header.replace('foreign address', 'foreign_address')
header = header.replace('(state)', 'state')
header = header.replace('inode', 'unix_inode')
header = header.replace('flags', 'unix_flags')
header = header.replace('-', '_')
return header
def normalize_route_headers(header):
header = header.lower()
header = header.replace('flags', 'route_flags')
header = header.replace('refs', 'route_refs')
header = header.replace('netif', 'iface')
header = header.replace('-', '_')
return header
def normalize_interface_headers(header):
header = header.lower()
header = header.replace('name', 'iface')
header = header.replace('-', '_')
return header
def parse_item(headers, entry, kind):
entry = entry.split(maxsplit=len(headers) - 1)
# fixup udp records with no state field entry
if kind == 'network' and entry[0].startswith('udp'):
entry.insert(5, None)
if kind == 'network' and 'socket' in headers and 'udp' in str(entry):
entry.insert(7, None)
# fixup -T output on FreeBSD
if kind == 'network' and '0_win' in headers and entry[0].startswith('udp'):
entry.insert(1, '')
entry.insert(1, '')
entry.insert(1, '')
# fixup interface records with no address field entry
if kind == 'interface' and len(entry) == 8:
entry.insert(3, None)
output_line = dict(zip(headers, entry))
output_line['kind'] = kind
return output_line
def parse_post(raw_data):
for entry in raw_data:
# fixup name field in Registered kernel control module
if 'name' in entry:
if entry['name']:
entry['name'] = entry['name'].strip()
# create network and transport protocol fields
if 'local_address' in entry:
if entry['local_address']:
ladd = entry['local_address'].rsplit('.', maxsplit=1)[0]
lport = entry['local_address'].rsplit('.', maxsplit=1)[1]
entry['local_address'] = ladd
entry['local_port'] = lport
if 'foreign_address' in entry:
if entry['foreign_address']:
fadd = entry['foreign_address'].rsplit('.', maxsplit=1)[0]
fport = entry['foreign_address'].rsplit('.', maxsplit=1)[1]
entry['foreign_address'] = fadd
entry['foreign_port'] = fport
if 'proto' in entry and 'kind' in entry:
if entry['kind'] == 'network':
if entry['proto'] == 'udp46':
entry['transport_protocol'] = entry['proto'][:-2]
elif entry['proto'].startswith('icm'):
entry['transport_protocol'] = 'icmp'
else:
entry['transport_protocol'] = entry['proto'][:-1]
if '6' in entry['proto']:
entry['network_protocol'] = 'ipv6'
else:
entry['network_protocol'] = 'ipv4'
# add route_flags_pretty field
if 'route_flags' in entry:
flag_map = {
'1': 'PROTO1',
'2': 'PROTO2',
'3': 'PROTO3',
'B': 'BLACKHOLE',
'b': 'BROADCAST',
'C': 'CLONING',
'c': 'PRCLONING',
'D': 'DYNAMIC',
'G': 'GATEWAY',
'H': 'HOST',
'I': 'IFSCOPE',
'i': 'IFREF',
'L': 'LLINFO',
'M': 'MODIFIED',
'm': 'MULTICAST',
'R': 'REJECT',
'r': 'ROUTER',
'S': 'STATIC',
'U': 'UP',
'W': 'WASCLONED',
'X': 'XRESOLVE',
'Y': 'PROXY',
}
pretty_flags = []
for flag in entry['route_flags']:
if flag in flag_map:
pretty_flags.append(flag_map[flag])
entry['route_flags_pretty'] = pretty_flags
# strip whitespace from beginning and end of all string values
for item in entry:
if isinstance(entry[item], str):
entry[item] = entry[item].strip()
return raw_data
def parse(cleandata):
"""
Main text parsing function for OSX netstat
Parameters:
cleandata: (string) text data to parse
Returns:
List of dictionaries. Raw structured data.
"""
raw_output = []
network = False
multipath = False
socket = False
reg_kernel_control = False
active_kernel_event = False
active_kernel_control = False
routing_table = False
interface_table = False
for line in cleandata:
if line.startswith('Active Internet'):
network = True
multipath = False
socket = False
reg_kernel_control = False
active_kernel_event = False
active_kernel_control = False
routing_table = False
interface_table = False
continue
if line.startswith('Active Multipath Internet connections'):
network = False
multipath = True
socket = False
reg_kernel_control = False
active_kernel_event = False
active_kernel_control = False
routing_table = False
interface_table = False
continue
if line.startswith('Active LOCAL (UNIX) domain sockets') or line.startswith('Active UNIX domain sockets'):
network = False
multipath = False
socket = True
reg_kernel_control = False
active_kernel_event = False
active_kernel_control = False
routing_table = False
interface_table = False
continue
if line.startswith('Registered kernel control modules'):
network = False
multipath = False
socket = False
reg_kernel_control = True
active_kernel_event = False
active_kernel_control = False
routing_table = False
interface_table = False
continue
if line.startswith('Active kernel event sockets'):
network = False
multipath = False
socket = False
reg_kernel_control = False
active_kernel_event = True
active_kernel_control = False
routing_table = False
interface_table = False
continue
if line.startswith('Active kernel control sockets'):
network = False
multipath = False
socket = False
reg_kernel_control = False
active_kernel_event = False
active_kernel_control = True
routing_table = False
interface_table = False
continue
if line.startswith('Routing tables'):
network = False
multipath = False
socket = False
reg_kernel_control = False
active_kernel_event = False
active_kernel_control = False
routing_table = True
interface_table = False
continue
if line.startswith('Name '):
network = False
multipath = False
socket = False
reg_kernel_control = False
active_kernel_event = False
active_kernel_control = False
routing_table = False
interface_table = True
# don't continue since there is no real header row for this table
# get headers
if network and (line.startswith('Socket ') or line.startswith('Proto ') or line.startswith('Tcpcb ')):
header_text = normalize_headers(line)
headers = header_text.split()
continue
if socket and line.startswith('Address '):
header_text = normalize_headers(line)
headers = header_text.split()
continue
if reg_kernel_control and (line.startswith('id ') or line.startswith('kctlref ')):
header_text = normalize_headers(line)
headers = header_text.split()
continue
if active_kernel_event and (line.startswith('Proto ') or line.startswith(' pcb ')):
header_text = normalize_headers(line)
headers = header_text.split()
continue
if active_kernel_control and (line.startswith('Proto ') or line.startswith(' pcb ')):
header_text = normalize_headers(line)
headers = header_text.split()
continue
if routing_table and line.startswith('Destination '):
header_text = normalize_route_headers(line)
headers = header_text.split()
continue
if interface_table and line.startswith('Name '):
header_text = normalize_interface_headers(line)
headers = header_text.split()
continue
# get items
if network:
raw_output.append(parse_item(headers, line, 'network'))
continue
if multipath:
# not implemented
continue
if socket:
raw_output.append(parse_item(headers, line, 'socket'))
continue
if reg_kernel_control:
raw_output.append(parse_item(headers, line, 'Registered kernel control module'))
continue
if active_kernel_event:
raw_output.append(parse_item(headers, line, 'Active kernel event socket'))
continue
if active_kernel_control:
raw_output.append(parse_item(headers, line, 'Active kernel control socket'))
continue
if routing_table and not (line.startswith('Internet:') or line.startswith('Internet6:')):
raw_output.append(parse_item(headers, line, 'route'))
continue
if interface_table:
raw_output.append(parse_item(headers, line, 'interface'))
continue
return parse_post(raw_output)

280
jc/parsers/netstat_linux.py Normal file
View File

@@ -0,0 +1,280 @@
"""jc - JSON CLI output utility Linux netstat Parser"""
import string
def normalize_headers(header):
header = header.lower()
header = header.replace('local address', 'local_address')
header = header.replace('foreign address', 'foreign_address')
header = header.replace('pid/program name', 'program_name')
header = header.replace('security context', 'security_context')
header = header.replace('i-node', 'inode')
header = header.replace('-', '_')
return header
def normalize_route_headers(header):
header = header.lower()
header = header.replace('flags', 'route_flags')
header = header.replace('ref', 'route_refs')
header = header.replace('-', '_')
return header
def normalize_interface_headers(header):
header = header.lower()
header = header.replace('-', '_')
return header
def parse_network(headers, entry):
# Count words in header
# if len of line is one less than len of header, then insert None in field 5
entry = entry.split(maxsplit=len(headers) - 1)
if len(entry) == len(headers) - 1:
entry.insert(5, None)
output_line = dict(zip(headers, entry))
output_line['kind'] = 'network'
return output_line
def parse_socket(header_text, headers, entry):
# get the column # of first letter of "state"
state_col = header_text.find('state')
# get the program name column area
pn_start = header_text.find('program_name')
pn_end = header_text.find('path') - 1
# remove [ and ] from each line
entry = entry.replace('[ ]', '---')
entry = entry.replace('[', ' ').replace(']', ' ')
# find program_name column area and substitute spaces with \u2063 there
old_pn = entry[pn_start:pn_end]
new_pn = old_pn.replace(' ', '\u2063')
entry = entry.replace(old_pn, new_pn)
entry_list = entry.split(maxsplit=len(headers) - 1)
# check column # to see if state column is populated
if entry[state_col] in string.whitespace:
entry_list.insert(4, None)
output_line = dict(zip(headers, entry_list))
output_line['kind'] = 'socket'
# fix program_name field to turn \u2063 back to spaces
if 'program_name' in output_line:
if output_line['program_name']:
old_d_pn = output_line['program_name']
new_d_pn = old_d_pn.replace('\u2063', ' ')
output_line['program_name'] = new_d_pn
return output_line
def parse_route(headers, entry):
entry = entry.split(maxsplit=len(headers) - 1)
output_line = dict(zip(headers, entry))
output_line['kind'] = 'route'
return output_line
def parse_interface(headers, entry):
entry = entry.split(maxsplit=len(headers) - 1)
output_line = dict(zip(headers, entry))
output_line['kind'] = 'interface'
return output_line
def parse_post(raw_data):
# clean up trailing whitespace on each item in each entry
# flags --- = null
# program_name - = null
# split pid and program name and ip addresses and ports
# create network and transport protocol fields
for entry in raw_data:
for item in entry:
try:
entry[item] = entry[item].rstrip()
except (AttributeError):
# skips trying to rstrip Null entries
pass
if 'flags' in entry:
if entry['flags'] == '---':
entry['flags'] = None
if 'program_name' in entry:
entry['program_name'] = entry['program_name'].strip()
if entry['program_name'] == '-':
entry['program_name'] = None
if entry['program_name']:
pid = entry['program_name'].split('/', maxsplit=1)[0]
name = entry['program_name'].split('/', maxsplit=1)[1]
entry['pid'] = pid
entry['program_name'] = name
if 'local_address' in entry:
if entry['local_address']:
ladd = entry['local_address'].rsplit(':', maxsplit=1)[0]
lport = entry['local_address'].rsplit(':', maxsplit=1)[1]
entry['local_address'] = ladd
entry['local_port'] = lport
if 'foreign_address' in entry:
if entry['foreign_address']:
fadd = entry['foreign_address'].rsplit(':', maxsplit=1)[0]
fport = entry['foreign_address'].rsplit(':', maxsplit=1)[1]
entry['foreign_address'] = fadd
entry['foreign_port'] = fport
if 'proto' in entry and 'kind' in entry:
if entry['kind'] == 'network':
if 'tcp' in entry['proto']:
entry['transport_protocol'] = 'tcp'
elif 'udp' in entry['proto']:
entry['transport_protocol'] = 'udp'
else:
entry['transport_protocol'] = None
if '6' in entry['proto']:
entry['network_protocol'] = 'ipv6'
else:
entry['network_protocol'] = 'ipv4'
# add route_flags_pretty
# Flag mapping from https://www.man7.org/linux/man-pages/man8/route.8.html
if 'route_flags' in entry:
flag_map = {
'U': 'UP',
'H': 'HOST',
'G': 'GATEWAY',
'R': 'REINSTATE',
'D': 'DYNAMIC',
'M': 'MODIFIED',
'A': 'ADDRCONF',
'C': 'CACHE',
'!': 'REJECT'
}
pretty_flags = []
for flag in entry['route_flags']:
if flag in flag_map:
pretty_flags.append(flag_map[flag])
entry['route_flags_pretty'] = pretty_flags
return raw_data
def parse(cleandata):
"""
Main text parsing function for OSX netstat
Parameters:
cleandata: (string) text data to parse
Returns:
List of dictionaries. Raw structured data.
"""
raw_output = []
network = False
socket = False
bluetooth = False
routing_table = False
interface_table = False
headers = None
for line in cleandata:
if line.startswith('Active Internet'):
network = True
socket = False
bluetooth = False
routing_table = False
interface_table = False
continue
if line.startswith('Active UNIX'):
network = False
socket = True
bluetooth = False
routing_table = False
interface_table = False
continue
if line.startswith('Active Bluetooth'):
network = False
socket = False
bluetooth = True
routing_table = False
interface_table = False
continue
if line.startswith('Kernel IP routing table'):
network = False
socket = False
bluetooth = False
routing_table = True
interface_table = False
continue
if line.startswith('Kernel Interface table'):
network = False
socket = False
bluetooth = False
routing_table = False
interface_table = True
continue
# get headers
if line.startswith('Proto'):
header_text = normalize_headers(line)
headers = header_text.split()
continue
if line.startswith('Destination '):
header_text = normalize_route_headers(line)
headers = header_text.split()
continue
if line.startswith('Iface '):
header_text = normalize_interface_headers(line)
headers = header_text.split()
continue
# parse items
if network:
raw_output.append(parse_network(headers, line))
continue
if socket:
raw_output.append(parse_socket(header_text, headers, line))
continue
if bluetooth:
# not implemented
continue
if routing_table:
raw_output.append(parse_route(headers, line))
continue
if interface_table:
raw_output.append(parse_interface(headers, line))
continue
return parse_post(raw_output)

View File

@@ -6,7 +6,7 @@ Usage:
Compatibility:
'linux'
'linux', 'freebsd'
Examples:
@@ -183,13 +183,13 @@ import jc.parsers.universal
class info():
version = '1.0'
version = '1.1'
description = 'ntpq -p command parser'
author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com'
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
compatible = ['linux']
compatible = ['linux', 'freebsd']
magic_commands = ['ntpq']

View File

@@ -32,7 +32,7 @@ import jc.parsers.universal
class info():
version = '1.0'
version = '1.1'
description = 'pip list command parser'
author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com'
@@ -94,7 +94,7 @@ def parse(data, raw=False, quiet=False):
cleandata = list(filter(None, linedata))
# detect legacy output type
if cleandata[0].find(' (') != -1:
if ' (' in cleandata[0]:
for row in cleandata:
raw_output.append({'package': row.split(' (')[0],
'version': row.split(' (')[1].rstrip(')')})
@@ -103,7 +103,7 @@ def parse(data, raw=False, quiet=False):
else:
# clear separator line
for i, line in reversed(list(enumerate(cleandata))):
if line.find('---') != -1:
if '---' in line:
cleandata.pop(i)
cleandata[0] = cleandata[0].lower()

View File

@@ -101,7 +101,7 @@ import jc.parsers.universal
class info():
version = '1.0'
version = '1.1'
description = 'route command parser'
author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com'
@@ -128,17 +128,20 @@ def process(proc_data):
[
{
"destination": string,
"gateway": string,
"genmask": string,
"flags": string,
"metric": integer,
"ref": integer,
"use": integer,
"mss": integer,
"window": integer,
"irtt": integer,
"iface": string
"destination": string,
"gateway": string,
"genmask": string,
"flags": string,
"flags_pretty": [
string,
]
"metric": integer,
"ref": integer,
"use": integer,
"mss": integer,
"window": integer,
"irtt": integer,
"iface": string
}
]
"""
@@ -152,6 +155,29 @@ def process(proc_data):
except (ValueError):
entry[key] = None
# add flags_pretty
# Flag mapping from https://www.man7.org/linux/man-pages/man8/route.8.html
if 'flags' in entry:
flag_map = {
'U': 'UP',
'H': 'HOST',
'G': 'GATEWAY',
'R': 'REINSTATE',
'D': 'DYNAMIC',
'M': 'MODIFIED',
'A': 'ADDRCONF',
'C': 'CACHE',
'!': 'REJECT'
}
pretty_flags = []
for flag in entry['flags']:
if flag in flag_map:
pretty_flags.append(flag_map[flag])
entry['flags_pretty'] = pretty_flags
return proc_data

View File

@@ -6,7 +6,7 @@ Usage:
Compatibility:
'linux'
'linux', 'darwin', 'freebsd'
Examples:
@@ -100,17 +100,18 @@ Examples:
..
]
"""
import shlex
import jc.utils
class info():
version = '1.0'
version = '1.4'
description = 'stat command parser'
author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com'
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
compatible = ['linux']
compatible = ['linux', 'darwin', 'freebsd']
magic_commands = ['stat']
@@ -149,12 +150,16 @@ def process(proc_data):
"access_time": string, # - = null
"modify_time": string, # - = null
"change_time": string, # - = null
"birth_time": string # - = null
"birth_time": string, # - = null
"unix_device": integer,
"rdev": integer,
"block_size": integer,
"unix_flags": string
}
]
"""
for entry in proc_data:
int_list = ['size', 'blocks', 'io_blocks', 'inode', 'links', 'uid', 'gid']
int_list = ['size', 'blocks', 'io_blocks', 'inode', 'links', 'uid', 'gid', 'unix_device', 'rdev', 'block_size']
for key in int_list:
if key in entry:
try:
@@ -198,81 +203,109 @@ def parse(data, raw=False, quiet=False):
cleandata = list(filter(None, cleandata))
if cleandata:
# stats output contains 8 lines
for line in cleandata:
# line #1
if line.find('File:') == 2:
output_line = {}
line_list = line.split(maxsplit=1)
output_line['file'] = line_list[1]
# linux output
if cleandata[0].startswith(' File: '):
# stats output contains 8 lines
for line in cleandata:
# populate link_to field if -> found
if output_line['file'].find(' -> ') != -1:
filename = output_line['file'].split(' -> ')[0].strip('\u2018').rstrip('\u2019')
link = output_line['file'].split(' -> ')[1].strip('\u2018').rstrip('\u2019')
output_line['file'] = filename
output_line['link_to'] = link
else:
filename = output_line['file'].split(' -> ')[0].strip('\u2018').rstrip('\u2019')
output_line['file'] = filename
# line #1
if line.find('File:') == 2:
output_line = {}
line_list = line.split(maxsplit=1)
output_line['file'] = line_list[1]
continue
# populate link_to field if -> found
if ' -> ' in output_line['file']:
filename = output_line['file'].split(' -> ')[0].strip('\u2018').rstrip('\u2019')
link = output_line['file'].split(' -> ')[1].strip('\u2018').rstrip('\u2019')
output_line['file'] = filename
output_line['link_to'] = link
else:
filename = output_line['file'].split(' -> ')[0].strip('\u2018').rstrip('\u2019')
output_line['file'] = filename
# line #2
if line.find('Size:') == 2:
line_list = line.split(maxsplit=7)
output_line['size'] = line_list[1]
output_line['blocks'] = line_list[3]
output_line['io_blocks'] = line_list[6]
output_line['type'] = line_list[7]
continue
continue
# line #3
if line.find('Device:') == 0:
line_list = line.split()
output_line['device'] = line_list[1]
output_line['inode'] = line_list[3]
output_line['links'] = line_list[5]
continue
# line #2
if line.find('Size:') == 2:
line_list = line.split(maxsplit=7)
output_line['size'] = line_list[1]
output_line['blocks'] = line_list[3]
output_line['io_blocks'] = line_list[6]
output_line['type'] = line_list[7]
continue
# line #4
if line.find('Access: (') == 0:
line = line.replace('(', ' ').replace(')', ' ').replace('/', ' ')
line_list = line.split()
output_line['access'] = line_list[1]
output_line['flags'] = line_list[2]
output_line['uid'] = line_list[4]
output_line['user'] = line_list[5]
output_line['gid'] = line_list[7]
output_line['group'] = line_list[8]
continue
# line #3
if line.startswith('Device:'):
line_list = line.split()
output_line['device'] = line_list[1]
output_line['inode'] = line_list[3]
output_line['links'] = line_list[5]
continue
# line #5
if line.find('Access: 2') == 0:
line_list = line.split(maxsplit=1)
output_line['access_time'] = line_list[1]
continue
# line #4
if line.startswith('Access: ('):
line = line.replace('(', ' ').replace(')', ' ').replace('/', ' ')
line_list = line.split()
output_line['access'] = line_list[1]
output_line['flags'] = line_list[2]
output_line['uid'] = line_list[4]
output_line['user'] = line_list[5]
output_line['gid'] = line_list[7]
output_line['group'] = line_list[8]
continue
# line #6
if line.find('Modify:') == 0:
line_list = line.split(maxsplit=1)
output_line['modify_time'] = line_list[1]
continue
# line #5
if line.startswith('Access: 2'):
line_list = line.split(maxsplit=1)
output_line['access_time'] = line_list[1]
continue
# line #7
if line.find('Change:') == 0:
line_list = line.split(maxsplit=1)
output_line['change_time'] = line_list[1]
continue
# line #6
if line.startswith('Modify:'):
line_list = line.split(maxsplit=1)
output_line['modify_time'] = line_list[1]
continue
# line #8
if line.find('Birth:') == 1:
line_list = line.split(maxsplit=1)
output_line['birth_time'] = line_list[1]
# line #7
if line.startswith('Change:'):
line_list = line.split(maxsplit=1)
output_line['change_time'] = line_list[1]
continue
# line #8
if line.find('Birth:') == 1:
line_list = line.split(maxsplit=1)
output_line['birth_time'] = line_list[1]
raw_output.append(output_line)
continue
# FreeBSD/OSX output
else:
for line in cleandata:
value = shlex.split(line)
output_line = {
'file': value[15],
'unix_device': value[0],
'inode': value[1],
'flags': value[2],
'links': value[3],
'user': value[4],
'group': value[5],
'rdev': value[6],
'size': value[7],
'access_time': value[8],
'modify_time': value[9],
'change_time': value[10],
'birth_time': value[11],
'block_size': value[12],
'blocks': value[13],
'unix_flags': value[14]
}
raw_output.append(output_line)
continue
if raw:
return raw_output

View File

@@ -40,7 +40,7 @@ import jc.utils
class info():
version = '1.0'
version = '1.1'
description = 'systemctl command parser'
author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com'
@@ -110,7 +110,7 @@ def parse(data, raw=False, quiet=False):
raw_output = []
for entry in cleandata[1:]:
if entry.find('LOAD = ') != -1:
if 'LOAD = ' in entry:
break
else:

View File

@@ -59,7 +59,7 @@ import jc.utils
class info():
version = '1.0'
version = '1.1'
description = 'systemctl list-jobs command parser'
author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com'
@@ -137,7 +137,7 @@ def parse(data, raw=False, quiet=False):
raw_output = []
for entry in cleandata[1:]:
if entry.find('No jobs running.') != -1 or entry.find('jobs listed.') != -1:
if 'No jobs running.' in entry or 'jobs listed.' in entry:
break
else:

View File

@@ -34,7 +34,7 @@ import jc.utils
class info():
version = '1.0'
version = '1.1'
description = 'systemctl list-sockets command parser'
author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com'
@@ -102,7 +102,7 @@ def parse(data, raw=False, quiet=False):
raw_output = []
for entry in cleandata[1:]:
if entry.find('sockets listed.') != -1:
if 'sockets listed.' in entry:
break
else:

View File

@@ -31,7 +31,7 @@ import jc.utils
class info():
version = '1.0'
version = '1.1'
description = 'systemctl list-unit-files command parser'
author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com'
@@ -99,7 +99,7 @@ def parse(data, raw=False, quiet=False):
raw_output = []
for entry in cleandata[1:]:
if entry.find('unit files listed.') != -1:
if 'unit files listed.' in entry:
break
else:

View File

@@ -10,7 +10,7 @@ Limitations:
Compatibility:
'linux', 'darwin'
'linux', 'darwin', 'freebsd'
Example:
@@ -30,13 +30,13 @@ import jc.utils
class info():
version = '1.1'
version = '1.2'
description = 'uname -a command parser'
author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com'
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
compatible = ['linux', 'darwin']
compatible = ['linux', 'darwin', 'freebsd']
magic_commands = ['uname']

View File

@@ -83,7 +83,7 @@ import jc.utils
class info():
version = '1.0'
version = '1.1'
description = 'w command parser'
author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com'
@@ -174,6 +174,12 @@ def parse(data, raw=False, quiet=False):
output_line = dict(zip(headers, temp_line))
raw_output.append(output_line)
# strip whitespace from beginning and end of all string values
for row in raw_output:
for item in row:
if isinstance(row[item], str):
row[item] = row[item].strip()
if raw:
return raw_output
else:

View File

@@ -56,7 +56,14 @@ def compatibility(mod_name, compatible):
no return, just prints output to STDERR
"""
if sys.platform not in compatible:
platform_found = False
for platform in compatible:
if sys.platform.startswith(platform):
platform_found = True
break
if not platform_found:
mod = mod_name.split('.')[-1]
compat_list = ', '.join(compatible)
warning_message(f'{mod} parser not compatible with your OS ({sys.platform}).\n Compatible platforms: {compat_list}')

View File

@@ -1,3 +1,3 @@
ifconfig-parser>=0.0.5
ruamel.yaml>=0.15.0
xmltodict>=0.12.0
Pygments>=2.4.2

2
setup.cfg Normal file
View File

@@ -0,0 +1,2 @@
[metadata]
license_file = LICENSE.md

View File

@@ -5,22 +5,21 @@ with open('README.md', 'r') as f:
setuptools.setup(
name='jc',
version='1.9.1',
version='1.11.2',
author='Kelly Brazil',
author_email='kellyjonbrazil@gmail.com',
description='This tool serializes the output of popular command line tools and filetypes to structured JSON output.',
description='Converts the output of popular command-line tools and file-types to JSON.',
install_requires=[
'ifconfig-parser>=0.0.5',
'ruamel.yaml>=0.15.0',
'xmltodict>=0.12.0'
'xmltodict>=0.12.0',
'Pygments>=2.4.2'
],
license='MIT',
long_description=long_description,
long_description_content_type='text/markdown',
python_requires='>=3.6',
url='https://github.com/kellyjonbrazil/jc',
packages=setuptools.find_packages(),
include_package_data=True,
packages=setuptools.find_packages(exclude=['*.tests', '*.tests.*', 'tests.*', 'tests']),
entry_points={
'console_scripts': [
'jc=jc.cli:main'

File diff suppressed because one or more lines are too long

60
tests/fixtures/centos-7.7/dig-axfr.out vendored Normal file
View File

@@ -0,0 +1,60 @@
; <<>> DiG 9.11.4-P2-RedHat-9.11.4-9.P2.el7 <<>> @81.4.108.41 AXFR zonetransfer.me +nocookie
; (1 server found)
;; global options: +cmd
zonetransfer.me. 7200 IN SOA nsztm1.digi.ninja. robin.digi.ninja. 2019100801 172800 900 1209600 3600
zonetransfer.me. 300 IN HINFO "Casio fx-700G" "Windows XP"
zonetransfer.me. 301 IN TXT "google-site-verification=tyP28J7JAUHA9fw2sHXMgcCC0I6XBmmoVi04VlMewxA"
zonetransfer.me. 7200 IN MX 0 ASPMX.L.GOOGLE.COM.
zonetransfer.me. 7200 IN MX 10 ALT1.ASPMX.L.GOOGLE.COM.
zonetransfer.me. 7200 IN MX 10 ALT2.ASPMX.L.GOOGLE.COM.
zonetransfer.me. 7200 IN MX 20 ASPMX2.GOOGLEMAIL.COM.
zonetransfer.me. 7200 IN MX 20 ASPMX3.GOOGLEMAIL.COM.
zonetransfer.me. 7200 IN MX 20 ASPMX4.GOOGLEMAIL.COM.
zonetransfer.me. 7200 IN MX 20 ASPMX5.GOOGLEMAIL.COM.
zonetransfer.me. 7200 IN A 5.196.105.14
zonetransfer.me. 7200 IN NS nsztm1.digi.ninja.
zonetransfer.me. 7200 IN NS nsztm2.digi.ninja.
_acme-challenge.zonetransfer.me. 301 IN TXT "6Oa05hbUJ9xSsvYy7pApQvwCUSSGgxvrbdizjePEsZI"
_sip._tcp.zonetransfer.me. 14000 IN SRV 0 0 5060 www.zonetransfer.me.
14.105.196.5.IN-ADDR.ARPA.zonetransfer.me. 7200 IN PTR www.zonetransfer.me.
asfdbauthdns.zonetransfer.me. 7900 IN AFSDB 1 asfdbbox.zonetransfer.me.
asfdbbox.zonetransfer.me. 7200 IN A 127.0.0.1
asfdbvolume.zonetransfer.me. 7800 IN AFSDB 1 asfdbbox.zonetransfer.me.
canberra-office.zonetransfer.me. 7200 IN A 202.14.81.230
cmdexec.zonetransfer.me. 300 IN TXT "; ls"
contact.zonetransfer.me. 2592000 IN TXT "Remember to call or email Pippa on +44 123 4567890 or pippa@zonetransfer.me when making DNS changes"
dc-office.zonetransfer.me. 7200 IN A 143.228.181.132
deadbeef.zonetransfer.me. 7201 IN AAAA dead:beaf::
dr.zonetransfer.me. 300 IN LOC 53 20 56.558 N 1 38 33.526 W 0.00m 1m 10000m 10m
DZC.zonetransfer.me. 7200 IN TXT "AbCdEfG"
email.zonetransfer.me. 2222 IN NAPTR 1 1 "P" "E2U+email" "" email.zonetransfer.me.zonetransfer.me.
email.zonetransfer.me. 7200 IN A 74.125.206.26
Hello.zonetransfer.me. 7200 IN TXT "Hi to Josh and all his class"
home.zonetransfer.me. 7200 IN A 127.0.0.1
Info.zonetransfer.me. 7200 IN TXT "ZoneTransfer.me service provided by Robin Wood - robin@digi.ninja. See http://digi.ninja/projects/zonetransferme.php for more information."
internal.zonetransfer.me. 300 IN NS intns1.zonetransfer.me.
internal.zonetransfer.me. 300 IN NS intns2.zonetransfer.me.
intns1.zonetransfer.me. 300 IN A 81.4.108.41
intns2.zonetransfer.me. 300 IN A 167.88.42.94
office.zonetransfer.me. 7200 IN A 4.23.39.254
ipv6actnow.org.zonetransfer.me. 7200 IN AAAA 2001:67c:2e8:11::c100:1332
owa.zonetransfer.me. 7200 IN A 207.46.197.32
robinwood.zonetransfer.me. 302 IN TXT "Robin Wood"
rp.zonetransfer.me. 321 IN RP robin.zonetransfer.me. robinwood.zonetransfer.me.
sip.zonetransfer.me. 3333 IN NAPTR 2 3 "P" "E2U+sip" "!^.*$!sip:customer-service@zonetransfer.me!" .
sqli.zonetransfer.me. 300 IN TXT "' or 1=1 --"
sshock.zonetransfer.me. 7200 IN TXT "() { :]}; echo ShellShocked"
staging.zonetransfer.me. 7200 IN CNAME www.sydneyoperahouse.com.
alltcpportsopen.firewall.test.zonetransfer.me. 301 IN A 127.0.0.1
testing.zonetransfer.me. 301 IN CNAME www.zonetransfer.me.
vpn.zonetransfer.me. 4000 IN A 174.36.59.154
www.zonetransfer.me. 7200 IN A 5.196.105.14
xss.zonetransfer.me. 300 IN TXT "'><script>alert('Boo')</script>"
zonetransfer.me. 7200 IN SOA nsztm1.digi.ninja. robin.digi.ninja. 2019100801 172800 900 1209600 3600
;; Query time: 182 msec
;; SERVER: 81.4.108.41#53(81.4.108.41)
;; WHEN: Wed Mar 25 20:01:47 PDT 2020
;; XFR size: 50 records (messages 1, bytes 1994)

File diff suppressed because one or more lines are too long

11810
tests/fixtures/centos-7.7/dmidecode.out vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1 +1 @@
[{"filename": "systemd-private-016de60725a3426792b93fc9f120b8f0-chronyd.service-oZqq4u", "parent": "."}, {"filename": "systemd-private-a30a5a178daa4042b42dfaf5ff9e5f68-chronyd.service-a1tpxv", "parent": "."}, {"filename": "systemd-private-af69d7360f3e40cfa947358c0fb5a6f8-chronyd.service-T3MQ4j", "parent": "."}, {"filename": "tmp.CvALl2jE6u", "parent": "."}, {"filename": "tmp.e7AlxSxY5a", "parent": "."}, {"filename": "tmp.uXm9yegjwj", "parent": "."}, {"filename": "a regular filename", "parent": "./lstest"}, {"filename": "this file has", "parent": "./lstest"}, {"filename": "a combination", "parent": "./lstest"}, {"filename": "of everything", "parent": "./lstest"}, {"filename": "this file has", "parent": "./lstest"}, {"filename": "a newline inside", "parent": "./lstest"}, {"filename": "this file has", "parent": "./lstest"}, {"filename": "four contiguous newlines inside", "parent": "./lstest"}, {"filename": "this file", "parent": "./lstest"}, {"filename": "has", "parent": "./lstest"}, {"filename": "six", "parent": "./lstest"}, {"filename": "newlines", "parent": "./lstest"}, {"filename": "within", "parent": "./lstest"}, {"filename": "this file starts with four newlines", "parent": "./lstest"}, {"filename": "this file starts with one newline", "parent": "./lstest"}]
[{"filename": "lstest", "parent": "."}, {"filename": "systemd-private-016de60725a3426792b93fc9f120b8f0-chronyd.service-oZqq4u", "parent": "."}, {"filename": "systemd-private-a30a5a178daa4042b42dfaf5ff9e5f68-chronyd.service-a1tpxv", "parent": "."}, {"filename": "systemd-private-af69d7360f3e40cfa947358c0fb5a6f8-chronyd.service-T3MQ4j", "parent": "."}, {"filename": "tmp.CvALl2jE6u", "parent": "."}, {"filename": "tmp.e7AlxSxY5a", "parent": "."}, {"filename": "tmp.uXm9yegjwj", "parent": "."}, {"filename": "a regular filename", "parent": "./lstest"}, {"filename": "this file has", "parent": "./lstest"}, {"filename": "a combination", "parent": "./lstest"}, {"filename": "of everything", "parent": "./lstest"}, {"filename": "this file has", "parent": "./lstest"}, {"filename": "a newline inside", "parent": "./lstest"}, {"filename": "this file has", "parent": "./lstest"}, {"filename": "four contiguous newlines inside", "parent": "./lstest"}, {"filename": "this file", "parent": "./lstest"}, {"filename": "has", "parent": "./lstest"}, {"filename": "six", "parent": "./lstest"}, {"filename": "newlines", "parent": "./lstest"}, {"filename": "within", "parent": "./lstest"}, {"filename": "this file starts with four newlines", "parent": "./lstest"}, {"filename": "this file starts with one newline", "parent": "./lstest"}]

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
[{"iface": "docker0", "mtu": 1500, "rx_ok": 0, "rx_err": 0, "rx_drp": 0, "rx_ovr": 0, "tx_ok": 0, "tx_err": 0, "tx_drp": 0, "tx_ovr": 0, "flg": "BMU", "kind": "interface"}, {"iface": "ens33", "mtu": 1500, "rx_ok": 476, "rx_err": 0, "rx_drp": 0, "rx_ovr": 0, "tx_ok": 312, "tx_err": 0, "tx_drp": 0, "tx_ovr": 0, "flg": "BMRU", "kind": "interface"}, {"iface": "lo", "mtu": 65536, "rx_ok": 0, "rx_err": 0, "rx_drp": 0, "rx_ovr": 0, "tx_ok": 0, "tx_err": 0, "tx_drp": 0, "tx_ovr": 0, "flg": "LRU", "kind": "interface"}]

View File

@@ -0,0 +1,5 @@
Kernel Interface table
Iface MTU RX-OK RX-ERR RX-DRP RX-OVR TX-OK TX-ERR TX-DRP TX-OVR Flg
docker0 1500 0 0 0 0 0 0 0 0 BMU
ens33 1500 476 0 0 0 312 0 0 0 BMRU
lo 65536 0 0 0 0 0 0 0 0 LRU

View File

@@ -0,0 +1 @@
[{"destination": "default", "gateway": "gateway", "genmask": "0.0.0.0", "route_flags": "UG", "mss": 0, "window": 0, "irtt": 0, "iface": "ens33", "kind": "route", "route_flags_pretty": ["UP", "GATEWAY"]}, {"destination": "172.17.0.0", "gateway": "0.0.0.0", "genmask": "255.255.0.0", "route_flags": "U", "mss": 0, "window": 0, "irtt": 0, "iface": "docker0", "kind": "route", "route_flags_pretty": ["UP"]}, {"destination": "192.168.71.0", "gateway": "0.0.0.0", "genmask": "255.255.255.0", "route_flags": "U", "mss": 0, "window": 0, "irtt": 0, "iface": "ens33", "kind": "route", "route_flags_pretty": ["UP"]}]

View File

@@ -0,0 +1,5 @@
Kernel IP routing table
Destination Gateway Genmask Flags MSS Window irtt Iface
default gateway 0.0.0.0 UG 0 0 0 ens33
172.17.0.0 0.0.0.0 255.255.0.0 U 0 0 0 docker0
192.168.71.0 0.0.0.0 255.255.255.0 U 0 0 0 ens33

View File

@@ -0,0 +1 @@
[{"destination": "0.0.0.0", "gateway": "192.168.71.2", "genmask": "0.0.0.0", "route_flags": "UG", "metric": 100, "route_refs": 0, "use": 0, "iface": "ens33", "kind": "route", "route_flags_pretty": ["UP", "GATEWAY"]}, {"destination": "172.17.0.0", "gateway": "0.0.0.0", "genmask": "255.255.0.0", "route_flags": "U", "metric": 0, "route_refs": 0, "use": 0, "iface": "docker0", "kind": "route", "route_flags_pretty": ["UP"]}, {"destination": "192.168.71.0", "gateway": "0.0.0.0", "genmask": "255.255.255.0", "route_flags": "U", "metric": 100, "route_refs": 0, "use": 0, "iface": "ens33", "kind": "route", "route_flags_pretty": ["UP"]}]

View File

@@ -0,0 +1,5 @@
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 192.168.71.2 0.0.0.0 UG 100 0 0 ens33
172.17.0.0 0.0.0.0 255.255.0.0 U 0 0 0 docker0
192.168.71.0 0.0.0.0 255.255.255.0 U 100 0 0 ens33

View File

@@ -0,0 +1 @@
[{"destination": "0.0.0.0", "gateway": "192.168.71.2", "genmask": "0.0.0.0", "route_flags": "UG", "metric": 100, "route_refs": 0, "use": 0, "iface": "ens33", "mss": 0, "window": 0, "irtt": 0, "kind": "route", "route_flags_pretty": ["UP", "GATEWAY"]}, {"destination": "172.17.0.0", "gateway": "0.0.0.0", "genmask": "255.255.0.0", "route_flags": "U", "metric": 0, "route_refs": 0, "use": 0, "iface": "docker", "mss": 0, "window": 0, "irtt": 0, "kind": "route", "route_flags_pretty": ["UP"]}, {"destination": "192.168.71.0", "gateway": "0.0.0.0", "genmask": "255.255.255.0", "route_flags": "U", "metric": 100, "route_refs": 0, "use": 0, "iface": "ens33", "mss": 0, "window": 0, "irtt": 0, "kind": "route", "route_flags_pretty": ["UP"]}]

View File

@@ -0,0 +1,5 @@
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface MSS Window irtt
0.0.0.0 192.168.71.2 0.0.0.0 UG 100 0 0 ens33 0 0 0
172.17.0.0 0.0.0.0 255.255.0.0 U 0 0 0 docker 0 0 0
192.168.71.0 0.0.0.0 255.255.255.0 U 100 0 0 ens33 0 0 0

View File

@@ -1 +1 @@
[{"destination": "0.0.0.0", "gateway": "192.168.71.2", "genmask": "0.0.0.0", "flags": "UG", "metric": 100, "ref": 0, "use": 0, "iface": "ens33"}, {"destination": "172.17.0.0", "gateway": "0.0.0.0", "genmask": "255.255.0.0", "flags": "U", "metric": 0, "ref": 0, "use": 0, "iface": "docker0"}, {"destination": "192.168.71.0", "gateway": "0.0.0.0", "genmask": "255.255.255.0", "flags": "U", "metric": 100, "ref": 0, "use": 0, "iface": "ens33"}]
[{"destination": "0.0.0.0", "gateway": "192.168.71.2", "genmask": "0.0.0.0", "flags": "UG", "metric": 100, "ref": 0, "use": 0, "iface": "ens33", "flags_pretty": ["UP", "GATEWAY"]}, {"destination": "172.17.0.0", "gateway": "0.0.0.0", "genmask": "255.255.0.0", "flags": "U", "metric": 0, "ref": 0, "use": 0, "iface": "docker0", "flags_pretty": ["UP"]}, {"destination": "192.168.71.0", "gateway": "0.0.0.0", "genmask": "255.255.255.0", "flags": "U", "metric": 100, "ref": 0, "use": 0, "iface": "ens33", "flags_pretty": ["UP"]}]

View File

@@ -1 +1 @@
[{"destination": "default", "gateway": "gateway", "genmask": "0.0.0.0", "flags": "UG", "metric": 100, "ref": 0, "use": 0, "iface": "ens33"}, {"destination": "172.17.0.0", "gateway": "0.0.0.0", "genmask": "255.255.0.0", "flags": "U", "metric": 0, "ref": 0, "use": 0, "iface": "docker0"}, {"destination": "192.168.71.0", "gateway": "0.0.0.0", "genmask": "255.255.255.0", "flags": "U", "metric": 100, "ref": 0, "use": 0, "iface": "ens33"}]
[{"destination": "default", "gateway": "gateway", "genmask": "0.0.0.0", "flags": "UG", "metric": 100, "ref": 0, "use": 0, "iface": "ens33", "flags_pretty": ["UP", "GATEWAY"]}, {"destination": "172.17.0.0", "gateway": "0.0.0.0", "genmask": "255.255.0.0", "flags": "U", "metric": 0, "ref": 0, "use": 0, "iface": "docker0", "flags_pretty": ["UP"]}, {"destination": "192.168.71.0", "gateway": "0.0.0.0", "genmask": "255.255.255.0", "flags": "U", "metric": 100, "ref": 0, "use": 0, "iface": "ens33", "flags_pretty": ["UP"]}]

File diff suppressed because one or more lines are too long

11810
tests/fixtures/fedora32/dmidecode.out vendored Normal file

File diff suppressed because it is too large Load Diff

1
tests/fixtures/fedora32/last.json vendored Normal file
View File

@@ -0,0 +1 @@
[{"user": "kbrazil", "tty": "pts/0", "hostname": "192.168.71.1", "login": "Fri May 1 15:25", "logout": "gone - no logout"}, {"user": "kbrazil", "tty": "tty1", "hostname": null, "login": "Fri May 1 15:24", "logout": "gone - no logout"}, {"user": "reboot", "tty": "system boot", "hostname": "5.6.6-300.fc32.x", "login": "Fri May 1 15:24", "logout": "running"}, {"user": "kbrazil", "tty": "pts/0", "hostname": "192.168.71.1", "login": "Thu Apr 30 15:27", "logout": "15:22", "duration": "23:55"}, {"user": "kbrazil", "tty": "tty1", "hostname": null, "login": "Thu Apr 30 15:25", "logout": "down", "duration": "23:57"}, {"user": "reboot", "tty": "system boot", "hostname": "5.6.6-300.fc32.x", "login": "Thu Apr 30 15:22", "logout": "15:22", "duration": "1+00:00"}]

8
tests/fixtures/fedora32/last.out vendored Normal file
View File

@@ -0,0 +1,8 @@
kbrazil pts/0 192.168.71.1 Fri May 1 15:25 gone - no logout
kbrazil tty1 Fri May 1 15:24 gone - no logout
reboot system boot 5.6.6-300.fc32.x Fri May 1 15:24 still running
kbrazil pts/0 192.168.71.1 Thu Apr 30 15:27 - 15:22 (23:55)
kbrazil tty1 Thu Apr 30 15:25 - down (23:57)
reboot system boot 5.6.6-300.fc32.x Thu Apr 30 15:22 - 15:22 (1+00:00)
wtmp begins Thu Apr 30 15:22:02 2020

1
tests/fixtures/fedora32/netstat.json vendored Normal file

File diff suppressed because one or more lines are too long

139
tests/fixtures/fedora32/netstat.out vendored Normal file
View File

@@ -0,0 +1,139 @@
Active Internet connections (w/o servers)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 localhost.localdoma:ssh 192.168.71.1:52882 ESTABLISHED
udp 0 0 localhost.locald:bootpc 192.168.71.254:bootps ESTABLISHED
Active UNIX domain sockets (w/o servers)
Proto RefCnt Flags Type State I-Node Path
unix 2 [ ] DGRAM 36371 /run/user/1000/systemd/notify
unix 3 [ ] DGRAM 15453 /run/systemd/notify
unix 9 [ ] DGRAM 15471 /run/systemd/journal/dev-log
unix 2 [ ] DGRAM 165956 @userdb-9bf8f59ca8f2bcce47a377edbaf8985d
unix 12 [ ] DGRAM 15479 /run/systemd/journal/socket
unix 2 [ ] DGRAM 29064 /var/run/chrony/chronyd.sock
unix 2 [ ] DGRAM 165866 @userdb-3f208fa7c8c6d98822a696ee7ca5e3ad
unix 2 [ ] DGRAM 165863 @userdb-da253950013f5ea3bc51a4049480d04e
unix 2 [ ] DGRAM 165865
unix 3 [ ] STREAM CONNECTED 36476
unix 3 [ ] STREAM CONNECTED 31389
unix 3 [ ] STREAM CONNECTED 30999 /var/lib/sss/pipes/private/sbus-dp_implicit_files.692
unix 3 [ ] STREAM CONNECTED 33770 /run/dbus/system_bus_socket
unix 3 [ ] STREAM CONNECTED 30731
unix 2 [ ] DGRAM 24653
unix 3 [ ] STREAM CONNECTED 31370 /var/lib/sss/pipes/private/sbus-dp_implicit_files.692
unix 2 [ ] DGRAM 165862
unix 2 [ ] DGRAM 33725
unix 3 [ ] STREAM CONNECTED 33885
unix 3 [ ] STREAM CONNECTED 31173
unix 3 [ ] STREAM CONNECTED 31019
unix 3 [ ] STREAM CONNECTED 33886
unix 3 [ ] STREAM CONNECTED 30735 /var/lib/sss/pipes/private/sbus-monitor
unix 3 [ ] STREAM CONNECTED 166231
unix 2 [ ] DGRAM 30987
unix 2 [ ] DGRAM 24745
unix 2 [ ] DGRAM 165955
unix 2 [ ] DGRAM 30575
unix 3 [ ] STREAM CONNECTED 31062 /run/dbus/system_bus_socket
unix 2 [ ] STREAM CONNECTED 35419
unix 3 [ ] STREAM CONNECTED 31399 /run/dbus/system_bus_socket
unix 2 [ ] DGRAM 32430
unix 2 [ ] DGRAM 29403
unix 3 [ ] STREAM CONNECTED 166232 /var/lib/sss/pipes/nss
unix 2 [ ] DGRAM 31127
unix 2 [ ] DGRAM 29538
unix 2 [ ] STREAM CONNECTED 33876
unix 3 [ ] STREAM CONNECTED 31020 /var/lib/sss/pipes/private/sbus-monitor
unix 3 [ ] STREAM CONNECTED 30998
unix 3 [ ] STREAM CONNECTED 36475
unix 2 [ ] DGRAM 36002
unix 3 [ ] STREAM CONNECTED 33769
unix 3 [ ] STREAM CONNECTED 31390 /var/lib/sss/pipes/private/sbus-monitor
unix 2 [ ] STREAM CONNECTED 33132
unix 3 [ ] STREAM CONNECTED 31398
unix 3 [ ] STREAM CONNECTED 30022
unix 3 [ ] DGRAM 24748
unix 3 [ ] DGRAM 24747
unix 2 [ ] DGRAM 36348
unix 2 [ ] DGRAM 32085
unix 3 [ ] STREAM CONNECTED 31168 /run/systemd/journal/stdout
unix 3 [ ] DGRAM 15455
unix 3 [ ] STREAM CONNECTED 30830
unix 3 [ ] STREAM CONNECTED 26911
unix 3 [ ] STREAM CONNECTED 35960
unix 2 [ ] DGRAM 24662
unix 2 [ ] STREAM CONNECTED 36345
unix 3 [ ] STREAM CONNECTED 32538
unix 3 [ ] STREAM CONNECTED 28747
unix 3 [ ] STREAM CONNECTED 31026
unix 3 [ ] DGRAM 28615
unix 3 [ ] STREAM CONNECTED 31713 /run/dbus/system_bus_socket
unix 3 [ ] STREAM CONNECTED 31167
unix 3 [ ] STREAM CONNECTED 35989 /run/systemd/journal/stdout
unix 3 [ ] STREAM CONNECTED 36303 /run/systemd/journal/stdout
unix 3 [ ] STREAM CONNECTED 31809 /run/systemd/journal/stdout
unix 3 [ ] STREAM CONNECTED 29396 /run/systemd/journal/stdout
unix 2 [ ] STREAM CONNECTED 34911
unix 3 [ ] DGRAM 36374
unix 2 [ ] STREAM CONNECTED 32241
unix 3 [ ] STREAM CONNECTED 32057 /run/dbus/system_bus_socket
unix 3 [ ] STREAM CONNECTED 32000 /run/systemd/journal/stdout
unix 2 [ ] DGRAM 33083
unix 3 [ ] STREAM CONNECTED 31017
unix 3 [ ] DGRAM 36373
unix 3 [ ] STREAM CONNECTED 34101
unix 3 [ ] STREAM CONNECTED 32539 /run/systemd/journal/stdout
unix 3 [ ] STREAM CONNECTED 26914
unix 3 [ ] STREAM CONNECTED 29395
unix 3 [ ] STREAM CONNECTED 31022
unix 3 [ ] DGRAM 15456
unix 3 [ ] STREAM CONNECTED 29251 /run/systemd/journal/stdout
unix 3 [ ] STREAM CONNECTED 26915
unix 2 [ ] STREAM CONNECTED 33052
unix 3 [ ] STREAM CONNECTED 31999
unix 2 [ ] DGRAM 29496
unix 3 [ ] STREAM CONNECTED 28400
unix 3 [ ] STREAM CONNECTED 36378 /run/dbus/system_bus_socket
unix 3 [ ] STREAM CONNECTED 31808
unix 3 [ ] STREAM CONNECTED 29250
unix 3 [ ] STREAM CONNECTED 24582
unix 3 [ ] STREAM CONNECTED 32056
unix 3 [ ] STREAM CONNECTED 31347
unix 3 [ ] STREAM CONNECTED 28678 /run/systemd/journal/stdout
unix 2 [ ] DGRAM 30980
unix 3 [ ] STREAM CONNECTED 31348 /run/systemd/journal/stdout
unix 3 [ ] STREAM CONNECTED 28677
unix 3 [ ] STREAM CONNECTED 34102 /run/dbus/system_bus_socket
unix 3 [ ] STREAM CONNECTED 24805 /run/systemd/journal/stdout
unix 3 [ ] STREAM CONNECTED 29322 /run/systemd/journal/stdout
unix 2 [ ] DGRAM 36357
unix 3 [ ] STREAM CONNECTED 30832 /run/systemd/journal/stdout
unix 2 [ ] DGRAM 26913
unix 2 [ ] STREAM CONNECTED 32010
unix 3 [ ] STREAM CONNECTED 28748 /run/systemd/journal/stdout
unix 2 [ ] DGRAM 28602
unix 3 [ ] STREAM CONNECTED 28401 /run/systemd/journal/stdout
unix 3 [ ] STREAM CONNECTED 31069 /run/dbus/system_bus_socket
unix 3 [ ] DGRAM 28616
unix 3 [ ] STREAM CONNECTED 32334 /run/systemd/journal/stdout
unix 3 [ ] STREAM CONNECTED 31712
unix 3 [ ] STREAM CONNECTED 36302
unix 3 [ ] STREAM CONNECTED 32333
unix 3 [ ] STREAM CONNECTED 32093
unix 3 [ ] STREAM CONNECTED 26912
unix 2 [ ] STREAM CONNECTED 35774
unix 3 [ ] STREAM CONNECTED 29321
unix 3 [ ] STREAM CONNECTED 31025
unix 3 [ ] STREAM CONNECTED 28470
unix 3 [ ] STREAM CONNECTED 32094 /run/dbus/system_bus_socket
unix 3 [ ] STREAM CONNECTED 31259 /run/systemd/journal/stdout
unix 2 [ ] DGRAM 36471
unix 3 [ ] STREAM CONNECTED 31054
unix 3 [ ] STREAM CONNECTED 31064 /run/dbus/system_bus_socket
unix 3 [ ] STREAM CONNECTED 28471 /run/systemd/journal/stdout
unix 3 [ ] STREAM CONNECTED 36377
unix 2 [ ] STREAM CONNECTED 35788
unix 3 [ ] STREAM CONNECTED 31258
unix 3 [ ] STREAM CONNECTED 31065 /run/dbus/system_bus_socket
Active Bluetooth connections (w/o servers)
Proto Destination Source State PSM DCID SCID IMTU OMTU Security
Proto Destination Source State Channel

1
tests/fixtures/freebsd12/arp-a.json vendored Normal file
View File

@@ -0,0 +1 @@
[{"name": null, "address": "192.168.71.163", "hwtype": "ethernet", "hwaddress": "00:0c:29:1a:4e:3b", "iface": "em0", "permanent": true}, {"name": null, "address": "192.168.71.2", "hwtype": "ethernet", "hwaddress": "00:50:56:f7:4a:fc", "iface": "em0", "permanent": false, "expires": 942}, {"name": null, "address": "192.168.71.1", "hwtype": "ethernet", "hwaddress": "00:50:56:c0:00:08", "iface": "em0", "permanent": false, "expires": 1182}]

3
tests/fixtures/freebsd12/arp-a.out vendored Normal file
View File

@@ -0,0 +1,3 @@
? (192.168.71.163) at 00:0c:29:1a:4e:3b on em0 permanent [ethernet]
? (192.168.71.2) at 00:50:56:f7:4a:fc on em0 expires in 942 seconds [ethernet]
? (192.168.71.1) at 00:50:56:c0:00:08 on em0 expires in 1182 seconds [ethernet]

1
tests/fixtures/freebsd12/last.json vendored Normal file
View File

@@ -0,0 +1 @@
[{"user": "kbrazil", "tty": "pts/0", "hostname": "192.168.71.1", "login": "Thu May 28 21:29", "logout": "still logged in"}, {"user": "kbrazil", "tty": "pts/0", "hostname": "192.168.71.1", "login": "Thu May 28 04:13", "logout": "21:29", "duration": "17:16"}, {"user": "kbrazil", "tty": "pts/0", "hostname": "192.168.71.1", "login": "Wed May 27 16:09", "logout": "04:13", "duration": "12:03"}, {"user": "root", "tty": "ttyv0", "hostname": null, "login": "Wed May 27 12:48", "logout": "still logged in"}, {"user": "kbrazil", "tty": "pts/0", "hostname": "192.168.71.1", "login": "Wed May 27 12:47", "logout": "16:09", "duration": "03:22"}, {"user": "kbrazil", "tty": "ttyv0", "hostname": null, "login": "Wed May 27 12:46", "logout": "12:48", "duration": "00:01"}, {"user": "boot time", "tty": null, "hostname": null, "login": "Wed May 27 12:46"}]

9
tests/fixtures/freebsd12/last.out vendored Normal file
View File

@@ -0,0 +1,9 @@
kbrazil pts/0 192.168.71.1 Thu May 28 21:29 still logged in
kbrazil pts/0 192.168.71.1 Thu May 28 04:13 - 21:29 (17:16)
kbrazil pts/0 192.168.71.1 Wed May 27 16:09 - 04:13 (12:03)
root ttyv0 Wed May 27 12:48 still logged in
kbrazil pts/0 192.168.71.1 Wed May 27 12:47 - 16:09 (03:22)
kbrazil ttyv0 Wed May 27 12:46 - 12:48 (00:01)
boot time Wed May 27 12:46
utx.log begins Wed May 27 12:46:05 PDT 2020

View File

@@ -0,0 +1 @@
[{"tcpcb": "fffff80003df43d0", "proto": "tcp4", "recv_q": 0, "send_q": 0, "local_address": "192.168.71.1", "foreign_address": "192.168.71.1", "state": "ESTABLISHED", "kind": "network", "local_port": "ssh", "foreign_port": "56321", "transport_protocol": "tcp", "network_protocol": "ipv4", "foreign_port_num": 56321}, {"tcpcb": "fffff80003df47a0", "proto": "tcp4", "recv_q": 0, "send_q": 0, "local_address": "localhost", "foreign_address": "*", "state": "LISTEN", "kind": "network", "local_port": "smtp", "foreign_port": "*", "transport_protocol": "tcp", "network_protocol": "ipv4"}, {"tcpcb": "fffff80003df4b70", "proto": "tcp4", "recv_q": 0, "send_q": 0, "local_address": "*", "foreign_address": "*", "state": "LISTEN", "kind": "network", "local_port": "ssh", "foreign_port": "*", "transport_protocol": "tcp", "network_protocol": "ipv4"}, {"tcpcb": "fffff80003df0000", "proto": "tcp6", "recv_q": 0, "send_q": 0, "local_address": "*", "foreign_address": "*", "state": "LISTEN", "kind": "network", "local_port": "ssh", "foreign_port": "*", "transport_protocol": "tcp", "network_protocol": "ipv6"}, {"tcpcb": "fffff80003ae81e8", "proto": "udp4", "recv_q": 0, "send_q": 0, "local_address": "*", "foreign_address": "*", "kind": "network", "local_port": "syslog", "foreign_port": "*", "transport_protocol": "udp", "network_protocol": "ipv4"}, {"tcpcb": "fffff80003ae87a0", "proto": "udp6", "recv_q": 0, "send_q": 0, "local_address": "*", "foreign_address": "*", "kind": "network", "local_port": "syslog", "foreign_port": "*", "transport_protocol": "udp", "network_protocol": "ipv6"}, {"address": "fffff80003ab6100", "type": "stream", "recv_q": 0, "send_q": 0, "unix_inode": "0", "conn": "fffff80003ab6200", "refs": "0", "nextref": "0", "kind": "socket"}, {"address": "fffff80003ab6200", "type": "stream", "recv_q": 0, "send_q": 0, "unix_inode": "0", "conn": "fffff80003ab6100", "refs": "0", "nextref": "0", "kind": "socket"}, {"address": "fffff80003ab6300", "type": "stream", "recv_q": 0, "send_q": 0, "unix_inode": "0", "conn": "0", "refs": "0", "nextref": "0", "kind": "socket"}, {"address": "fffff80003ab6800", "type": "stream", "recv_q": 0, "send_q": 0, "unix_inode": "0", "conn": "fffff80003ab6900", "refs": "0", "nextref": "0", "kind": "socket"}, {"address": "fffff80003ab6900", "type": "stream", "recv_q": 0, "send_q": 0, "unix_inode": "0", "conn": "fffff80003ab6800", "refs": "0", "nextref": "0", "kind": "socket"}, {"address": "fffff80003abf000", "type": "stream", "recv_q": 0, "send_q": 0, "unix_inode": "fffff80003c581e0", "conn": "0", "refs": "0", "nextref": "0", "addr": "/var/run/devd.pipe", "kind": "socket"}, {"address": "fffff80003ac3e00", "type": "dgram", "recv_q": 0, "send_q": 0, "unix_inode": "0", "conn": "fffff80003ab6c00", "refs": "0", "nextref": "fffff80003ab6400", "kind": "socket"}, {"address": "fffff80003ab6400", "type": "dgram", "recv_q": 0, "send_q": 0, "unix_inode": "0", "conn": "fffff80003ab6c00", "refs": "0", "nextref": "fffff80003ab6000", "kind": "socket"}, {"address": "fffff80003ab6000", "type": "dgram", "recv_q": 0, "send_q": 0, "unix_inode": "0", "conn": "fffff80003ab6c00", "refs": "0", "nextref": "fffff80003ab6600", "kind": "socket"}, {"address": "fffff80003ab6500", "type": "dgram", "recv_q": 0, "send_q": 0, "unix_inode": "0", "conn": "fffff80003ab6d00", "refs": "0", "nextref": "0", "kind": "socket"}, {"address": "fffff80003ab6600", "type": "dgram", "recv_q": 0, "send_q": 0, "unix_inode": "0", "conn": "fffff80003ab6c00", "refs": "0", "nextref": "0", "kind": "socket"}, {"address": "fffff80003ab6c00", "type": "dgram", "recv_q": 0, "send_q": 0, "unix_inode": "fffff80003c59d20", "conn": "0", "refs": "fffff80003ac3e00", "nextref": "0", "addr": "/var/run/logpriv", "kind": "socket"}, {"address": "fffff80003ab6d00", "type": "dgram", "recv_q": 0, "send_q": 0, "unix_inode": "fffff80003c67000", "conn": "0", "refs": "fffff80003ab6500", "nextref": "0", "addr": "/var/run/log", "kind": "socket"}, {"address": "fffff80003ab6e00", "type": "seqpac", "recv_q": 0, "send_q": 0, "unix_inode": "fffff80003c58000", "conn": "0", "refs": "0", "nextref": "0", "addr": "/var/run/devd.seqpacket.pipe", "kind": "socket"}]

24
tests/fixtures/freebsd12/netstat-Aa.out vendored Normal file
View File

@@ -0,0 +1,24 @@
Active Internet connections (including servers)
Tcpcb Proto Recv-Q Send-Q Local Address Foreign Address (state)
fffff80003df43d0 tcp4 0 0 192.168.71.1.ssh 192.168.71.1.56321 ESTABLISHED
fffff80003df47a0 tcp4 0 0 localhost.smtp *.* LISTEN
fffff80003df4b70 tcp4 0 0 *.ssh *.* LISTEN
fffff80003df0000 tcp6 0 0 *.ssh *.* LISTEN
fffff80003ae81e8 udp4 0 0 *.syslog *.*
fffff80003ae87a0 udp6 0 0 *.syslog *.*
Active UNIX domain sockets
Address Type Recv-Q Send-Q Inode Conn Refs Nextref Addr
fffff80003ab6100 stream 0 0 0 fffff80003ab6200 0 0
fffff80003ab6200 stream 0 0 0 fffff80003ab6100 0 0
fffff80003ab6300 stream 0 0 0 0 0 0
fffff80003ab6800 stream 0 0 0 fffff80003ab6900 0 0
fffff80003ab6900 stream 0 0 0 fffff80003ab6800 0 0
fffff80003abf000 stream 0 0 fffff80003c581e0 0 0 0 /var/run/devd.pipe
fffff80003ac3e00 dgram 0 0 0 fffff80003ab6c00 0 fffff80003ab6400
fffff80003ab6400 dgram 0 0 0 fffff80003ab6c00 0 fffff80003ab6000
fffff80003ab6000 dgram 0 0 0 fffff80003ab6c00 0 fffff80003ab6600
fffff80003ab6500 dgram 0 0 0 fffff80003ab6d00 0 0
fffff80003ab6600 dgram 0 0 0 fffff80003ab6c00 0 0
fffff80003ab6c00 dgram 0 0 fffff80003c59d20 0 fffff80003ac3e00 0 /var/run/logpriv
fffff80003ab6d00 dgram 0 0 fffff80003c67000 0 fffff80003ab6500 0 /var/run/log
fffff80003ab6e00 seqpac 0 0 fffff80003c58000 0 0 0 /var/run/devd.seqpacket.pipe

View File

@@ -0,0 +1 @@
[{"tcpcb": "fffff80003df43d0", "proto": "tcp4", "rexmit": 3, "ooorcv": 0, "0_win": 0, "local_address": "192.168.71.1", "foreign_address": "192.168.71.1", "kind": "network", "local_port": "ssh", "foreign_port": "64330", "transport_protocol": "tcp", "network_protocol": "ipv4", "foreign_port_num": 64330}, {"tcpcb": "fffff80003df47a0", "proto": "tcp4", "rexmit": 0, "ooorcv": 0, "0_win": 0, "local_address": "localhost", "foreign_address": "*", "kind": "network", "local_port": "smtp", "foreign_port": "*", "transport_protocol": "tcp", "network_protocol": "ipv4"}, {"tcpcb": "fffff80003df4b70", "proto": "tcp4", "rexmit": 0, "ooorcv": 0, "0_win": 0, "local_address": "*", "foreign_address": "*", "kind": "network", "local_port": "ssh", "foreign_port": "*", "transport_protocol": "tcp", "network_protocol": "ipv4"}, {"tcpcb": "fffff80003df0000", "proto": "tcp6", "rexmit": 0, "ooorcv": 0, "0_win": 0, "local_address": "*", "foreign_address": "*", "kind": "network", "local_port": "ssh", "foreign_port": "*", "transport_protocol": "tcp", "network_protocol": "ipv6"}, {"tcpcb": "fffff80003ae81e8", "proto": "udp4", "rexmit": null, "ooorcv": null, "kind": "network", "transport_protocol": "udp", "network_protocol": "ipv4"}, {"tcpcb": "fffff80003ae87a0", "proto": "udp6", "rexmit": null, "ooorcv": null, "kind": "network", "transport_protocol": "udp", "network_protocol": "ipv6"}, {"address": "fffff80003ab6200", "type": "stream", "recv_q": 0, "send_q": 0, "unix_inode": "0", "conn": "fffff80003ab6100", "refs": "0", "nextref": "0", "kind": "socket"}, {"address": "fffff80003ab6100", "type": "stream", "recv_q": 0, "send_q": 0, "unix_inode": "0", "conn": "fffff80003ab6200", "refs": "0", "nextref": "0", "kind": "socket"}, {"address": "fffff80003ab6300", "type": "stream", "recv_q": 0, "send_q": 0, "unix_inode": "0", "conn": "0", "refs": "0", "nextref": "0", "kind": "socket"}, {"address": "fffff80003ab6800", "type": "stream", "recv_q": 0, "send_q": 0, "unix_inode": "0", "conn": "fffff80003ab6900", "refs": "0", "nextref": "0", "kind": "socket"}, {"address": "fffff80003ab6900", "type": "stream", "recv_q": 0, "send_q": 0, "unix_inode": "0", "conn": "fffff80003ab6800", "refs": "0", "nextref": "0", "kind": "socket"}, {"address": "fffff80003abf000", "type": "stream", "recv_q": 0, "send_q": 0, "unix_inode": "fffff80003c581e0", "conn": "0", "refs": "0", "nextref": "0", "addr": "/var/run/devd.pipe", "kind": "socket"}, {"address": "fffff80003ac3e00", "type": "dgram", "recv_q": 0, "send_q": 0, "unix_inode": "0", "conn": "fffff80003ab6c00", "refs": "0", "nextref": "fffff80003ab6400", "kind": "socket"}, {"address": "fffff80003ab6400", "type": "dgram", "recv_q": 0, "send_q": 0, "unix_inode": "0", "conn": "fffff80003ab6c00", "refs": "0", "nextref": "fffff80003ab6000", "kind": "socket"}, {"address": "fffff80003ab6000", "type": "dgram", "recv_q": 0, "send_q": 0, "unix_inode": "0", "conn": "fffff80003ab6c00", "refs": "0", "nextref": "fffff80003ab6600", "kind": "socket"}, {"address": "fffff80003ab6500", "type": "dgram", "recv_q": 0, "send_q": 0, "unix_inode": "0", "conn": "fffff80003ab6d00", "refs": "0", "nextref": "0", "kind": "socket"}, {"address": "fffff80003ab6600", "type": "dgram", "recv_q": 0, "send_q": 0, "unix_inode": "0", "conn": "fffff80003ab6c00", "refs": "0", "nextref": "0", "kind": "socket"}, {"address": "fffff80003ab6c00", "type": "dgram", "recv_q": 0, "send_q": 0, "unix_inode": "fffff80003c59d20", "conn": "0", "refs": "fffff80003ac3e00", "nextref": "0", "addr": "/var/run/logpriv", "kind": "socket"}, {"address": "fffff80003ab6d00", "type": "dgram", "recv_q": 0, "send_q": 0, "unix_inode": "fffff80003c67000", "conn": "0", "refs": "fffff80003ab6500", "nextref": "0", "addr": "/var/run/log", "kind": "socket"}, {"address": "fffff80003ab6e00", "type": "seqpac", "recv_q": 0, "send_q": 0, "unix_inode": "fffff80003c58000", "conn": "0", "refs": "0", "nextref": "0", "addr": "/var/run/devd.seqpacket.pipe", "kind": "socket"}]

View File

@@ -0,0 +1,24 @@
Active Internet connections (including servers)
Tcpcb Proto Rexmit OOORcv 0-win Local Address Foreign Address
fffff80003df43d0 tcp4 3 0 0 192.168.71.1.ssh 192.168.71.1.64330
fffff80003df47a0 tcp4 0 0 0 localhost.smtp *.*
fffff80003df4b70 tcp4 0 0 0 *.ssh *.*
fffff80003df0000 tcp6 0 0 0 *.ssh *.*
fffff80003ae81e8 udp4 *.syslog *.*
fffff80003ae87a0 udp6 *.syslog *.*
Active UNIX domain sockets
Address Type Recv-Q Send-Q Inode Conn Refs Nextref Addr
fffff80003ab6200 stream 0 0 0 fffff80003ab6100 0 0
fffff80003ab6100 stream 0 0 0 fffff80003ab6200 0 0
fffff80003ab6300 stream 0 0 0 0 0 0
fffff80003ab6800 stream 0 0 0 fffff80003ab6900 0 0
fffff80003ab6900 stream 0 0 0 fffff80003ab6800 0 0
fffff80003abf000 stream 0 0 fffff80003c581e0 0 0 0 /var/run/devd.pipe
fffff80003ac3e00 dgram 0 0 0 fffff80003ab6c00 0 fffff80003ab6400
fffff80003ab6400 dgram 0 0 0 fffff80003ab6c00 0 fffff80003ab6000
fffff80003ab6000 dgram 0 0 0 fffff80003ab6c00 0 fffff80003ab6600
fffff80003ab6500 dgram 0 0 0 fffff80003ab6d00 0 0
fffff80003ab6600 dgram 0 0 0 fffff80003ab6c00 0 0
fffff80003ab6c00 dgram 0 0 fffff80003c59d20 0 fffff80003ac3e00 0 /var/run/logpriv
fffff80003ab6d00 dgram 0 0 fffff80003c67000 0 fffff80003ab6500 0 /var/run/log
fffff80003ab6e00 seqpac 0 0 fffff80003c58000 0 0 0 /var/run/devd.seqpacket.pipe

View File

@@ -0,0 +1 @@
[{"tcpcb": "fffff80003df43d0", "proto": "tcp4", "recv_q": 0, "send_q": 0, "local_address": "192.168.71.163", "foreign_address": "192.168.71.1", "state": "ESTABLISHED", "log": "-", "kind": "network", "local_port": "22", "foreign_port": "64330", "transport_protocol": "tcp", "network_protocol": "ipv4", "local_port_num": 22, "foreign_port_num": 64330}, {"tcpcb": "fffff80003df47a0", "proto": "tcp4", "recv_q": 0, "send_q": 0, "local_address": "127.0.0.1", "foreign_address": "*", "state": "LISTEN", "log": "-", "kind": "network", "local_port": "25", "foreign_port": "*", "transport_protocol": "tcp", "network_protocol": "ipv4", "local_port_num": 25}, {"tcpcb": "fffff80003df4b70", "proto": "tcp4", "recv_q": 0, "send_q": 0, "local_address": "*", "foreign_address": "*", "state": "LISTEN", "log": "-", "kind": "network", "local_port": "22", "foreign_port": "*", "transport_protocol": "tcp", "network_protocol": "ipv4", "local_port_num": 22}, {"tcpcb": "fffff80003df0000", "proto": "tcp6", "recv_q": 0, "send_q": 0, "local_address": "*", "foreign_address": "*", "state": "LISTEN", "log": "-", "kind": "network", "local_port": "22", "foreign_port": "*", "transport_protocol": "tcp", "network_protocol": "ipv6", "local_port_num": 22}, {"tcpcb": "fffff80003ae81e8", "proto": "udp4", "recv_q": 0, "send_q": 0, "local_address": "*", "foreign_address": "*", "kind": "network", "local_port": "514", "foreign_port": "*", "transport_protocol": "udp", "network_protocol": "ipv4", "local_port_num": 514}, {"tcpcb": "fffff80003ae87a0", "proto": "udp6", "recv_q": 0, "send_q": 0, "local_address": "*", "foreign_address": "*", "kind": "network", "local_port": "514", "foreign_port": "*", "transport_protocol": "udp", "network_protocol": "ipv6", "local_port_num": 514}, {"address": "fffff80003ab6200", "type": "stream", "recv_q": 0, "send_q": 0, "unix_inode": "0", "conn": "fffff80003ab6100", "refs": "0", "nextref": "0", "kind": "socket"}, {"address": "fffff80003ab6100", "type": "stream", "recv_q": 0, "send_q": 0, "unix_inode": "0", "conn": "fffff80003ab6200", "refs": "0", "nextref": "0", "kind": "socket"}, {"address": "fffff80003ab6300", "type": "stream", "recv_q": 0, "send_q": 0, "unix_inode": "0", "conn": "0", "refs": "0", "nextref": "0", "kind": "socket"}, {"address": "fffff80003ab6800", "type": "stream", "recv_q": 0, "send_q": 0, "unix_inode": "0", "conn": "fffff80003ab6900", "refs": "0", "nextref": "0", "kind": "socket"}, {"address": "fffff80003ab6900", "type": "stream", "recv_q": 0, "send_q": 0, "unix_inode": "0", "conn": "fffff80003ab6800", "refs": "0", "nextref": "0", "kind": "socket"}, {"address": "fffff80003abf000", "type": "stream", "recv_q": 0, "send_q": 0, "unix_inode": "fffff80003c581e0", "conn": "0", "refs": "0", "nextref": "0", "addr": "/var/run/devd.pipe", "kind": "socket"}, {"address": "fffff80003ac3e00", "type": "dgram", "recv_q": 0, "send_q": 0, "unix_inode": "0", "conn": "fffff80003ab6c00", "refs": "0", "nextref": "fffff80003ab6400", "kind": "socket"}, {"address": "fffff80003ab6400", "type": "dgram", "recv_q": 0, "send_q": 0, "unix_inode": "0", "conn": "fffff80003ab6c00", "refs": "0", "nextref": "fffff80003ab6000", "kind": "socket"}, {"address": "fffff80003ab6000", "type": "dgram", "recv_q": 0, "send_q": 0, "unix_inode": "0", "conn": "fffff80003ab6c00", "refs": "0", "nextref": "fffff80003ab6600", "kind": "socket"}, {"address": "fffff80003ab6500", "type": "dgram", "recv_q": 0, "send_q": 0, "unix_inode": "0", "conn": "fffff80003ab6d00", "refs": "0", "nextref": "0", "kind": "socket"}, {"address": "fffff80003ab6600", "type": "dgram", "recv_q": 0, "send_q": 0, "unix_inode": "0", "conn": "fffff80003ab6c00", "refs": "0", "nextref": "0", "kind": "socket"}, {"address": "fffff80003ab6c00", "type": "dgram", "recv_q": 0, "send_q": 0, "unix_inode": "fffff80003c59d20", "conn": "0", "refs": "fffff80003ac3e00", "nextref": "0", "addr": "/var/run/logpriv", "kind": "socket"}, {"address": "fffff80003ab6d00", "type": "dgram", "recv_q": 0, "send_q": 0, "unix_inode": "fffff80003c67000", "conn": "0", "refs": "fffff80003ab6500", "nextref": "0", "addr": "/var/run/log", "kind": "socket"}, {"address": "fffff80003ab6e00", "type": "seqpac", "recv_q": 0, "send_q": 0, "unix_inode": "fffff80003c58000", "conn": "0", "refs": "0", "nextref": "0", "addr": "/var/run/devd.seqpacket.pipe", "kind": "socket"}]

View File

@@ -0,0 +1,24 @@
Active Internet connections (including servers)
Tcpcb Proto Recv-Q Send-Q Local Address Foreign Address (state) Log ID
fffff80003df43d0 tcp4 0 0 192.168.71.163.22 192.168.71.1.64330 ESTABLISHED -
fffff80003df47a0 tcp4 0 0 127.0.0.1.25 *.* LISTEN -
fffff80003df4b70 tcp4 0 0 *.22 *.* LISTEN -
fffff80003df0000 tcp6 0 0 *.22 *.* LISTEN -
fffff80003ae81e8 udp4 0 0 *.514 *.*
fffff80003ae87a0 udp6 0 0 *.514 *.*
Active UNIX domain sockets
Address Type Recv-Q Send-Q Inode Conn Refs Nextref Addr
fffff80003ab6200 stream 0 0 0 fffff80003ab6100 0 0
fffff80003ab6100 stream 0 0 0 fffff80003ab6200 0 0
fffff80003ab6300 stream 0 0 0 0 0 0
fffff80003ab6800 stream 0 0 0 fffff80003ab6900 0 0
fffff80003ab6900 stream 0 0 0 fffff80003ab6800 0 0
fffff80003abf000 stream 0 0 fffff80003c581e0 0 0 0 /var/run/devd.pipe
fffff80003ac3e00 dgram 0 0 0 fffff80003ab6c00 0 fffff80003ab6400
fffff80003ab6400 dgram 0 0 0 fffff80003ab6c00 0 fffff80003ab6000
fffff80003ab6000 dgram 0 0 0 fffff80003ab6c00 0 fffff80003ab6600
fffff80003ab6500 dgram 0 0 0 fffff80003ab6d00 0 0
fffff80003ab6600 dgram 0 0 0 fffff80003ab6c00 0 0
fffff80003ab6c00 dgram 0 0 fffff80003c59d20 0 fffff80003ac3e00 0 /var/run/logpriv
fffff80003ab6d00 dgram 0 0 fffff80003c67000 0 fffff80003ab6500 0 /var/run/log
fffff80003ab6e00 seqpac 0 0 fffff80003c58000 0 0 0 /var/run/devd.seqpacket.pipe

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,24 @@
Active Internet connections (including servers)
Tcpcb Proto Recv-Q Send-Q Local Address Foreign Address R-MBUF S-MBUF R-CLUS S-CLUS R-HIWA S-HIWA R-LOWA S-LOWA R-BCNT S-BCNT R-BMAX S-BMAX rexmt persist keep 2msl delack rcvtime
fffff80003df43d0 tcp4 0 0 192.168.71.1.ssh 192.168.71.1.64330 0 0 0 0 65700 33580 1 2048 0 0 525600 268640 0.00 0.00 5079.93 0.00 0.00 0.00
fffff80003df47a0 tcp4 0 0 localhost.smtp *.* 0 0 0 0 0 0 0 0 0 0 0 0 0.00 0.00 0.00 0.00 0.00 8841.63
fffff80003df4b70 tcp4 0 0 *.ssh *.* 0 0 0 0 0 0 0 0 0 0 0 0 0.00 0.00 0.00 0.00 0.00 8857.24
fffff80003df0000 tcp6 0 0 *.ssh *.* 0 0 0 0 0 0 0 0 0 0 0 0 0.00 0.00 0.00 0.00 0.00 8857.24
fffff80003ae81e8 udp4 0 0 *.syslog *.* 0 0 0 0 0 9216 0 2048 0 0 0 73728
fffff80003ae87a0 udp6 0 0 *.syslog *.* 0 0 0 0 0 9216 0 2048 0 0 0 73728
Active UNIX domain sockets
Address Type Recv-Q Send-Q Inode Conn Refs Nextref Addr
fffff80003ab6200 stream 0 0 0 fffff80003ab6100 0 0
fffff80003ab6100 stream 0 0 0 fffff80003ab6200 0 0
fffff80003ab6300 stream 0 0 0 0 0 0
fffff80003ab6800 stream 0 0 0 fffff80003ab6900 0 0
fffff80003ab6900 stream 0 0 0 fffff80003ab6800 0 0
fffff80003abf000 stream 0 0 fffff80003c581e0 0 0 0 /var/run/devd.pipe
fffff80003ac3e00 dgram 0 0 0 fffff80003ab6c00 0 fffff80003ab6400
fffff80003ab6400 dgram 0 0 0 fffff80003ab6c00 0 fffff80003ab6000
fffff80003ab6000 dgram 0 0 0 fffff80003ab6c00 0 fffff80003ab6600
fffff80003ab6500 dgram 0 0 0 fffff80003ab6d00 0 0
fffff80003ab6600 dgram 0 0 0 fffff80003ab6c00 0 0
fffff80003ab6c00 dgram 0 0 fffff80003c59d20 0 fffff80003ac3e00 0 /var/run/logpriv
fffff80003ab6d00 dgram 0 0 fffff80003c67000 0 fffff80003ab6500 0 /var/run/log
fffff80003ab6e00 seqpac 0 0 fffff80003c58000 0 0 0 /var/run/devd.seqpacket.pipe

View File

@@ -0,0 +1 @@
[{"proto": "tcp4", "rexmit": 3, "ooorcv": 0, "0_win": 0, "local_address": "192.168.71.163", "foreign_address": "192.168.71.1", "kind": "network", "local_port": "ssh", "foreign_port": "64330", "transport_protocol": "tcp", "network_protocol": "ipv4", "foreign_port_num": 64330}, {"proto": "tcp4", "rexmit": 0, "ooorcv": 0, "0_win": 0, "local_address": "localhost", "foreign_address": "*", "kind": "network", "local_port": "smtp", "foreign_port": "*", "transport_protocol": "tcp", "network_protocol": "ipv4"}, {"proto": "tcp4", "rexmit": 0, "ooorcv": 0, "0_win": 0, "local_address": "*", "foreign_address": "*", "kind": "network", "local_port": "ssh", "foreign_port": "*", "transport_protocol": "tcp", "network_protocol": "ipv4"}, {"proto": "tcp6", "rexmit": 0, "ooorcv": 0, "0_win": 0, "local_address": "*", "foreign_address": "*", "kind": "network", "local_port": "ssh", "foreign_port": "*", "transport_protocol": "tcp", "network_protocol": "ipv6"}, {"proto": "udp4", "rexmit": null, "ooorcv": null, "0_win": null, "local_address": "*", "foreign_address": "*", "kind": "network", "local_port": "syslog", "foreign_port": "*", "transport_protocol": "udp", "network_protocol": "ipv4"}, {"proto": "udp6", "rexmit": null, "ooorcv": null, "0_win": null, "local_address": "*", "foreign_address": "*", "kind": "network", "local_port": "syslog", "foreign_port": "*", "transport_protocol": "udp", "network_protocol": "ipv6"}, {"address": "fffff80003ab6200", "type": "stream", "recv_q": 0, "send_q": 0, "unix_inode": "0", "conn": "fffff80003ab6100", "refs": "0", "nextref": "0", "kind": "socket"}, {"address": "fffff80003ab6100", "type": "stream", "recv_q": 0, "send_q": 0, "unix_inode": "0", "conn": "fffff80003ab6200", "refs": "0", "nextref": "0", "kind": "socket"}, {"address": "fffff80003ab6300", "type": "stream", "recv_q": 0, "send_q": 0, "unix_inode": "0", "conn": "0", "refs": "0", "nextref": "0", "kind": "socket"}, {"address": "fffff80003ab6800", "type": "stream", "recv_q": 0, "send_q": 0, "unix_inode": "0", "conn": "fffff80003ab6900", "refs": "0", "nextref": "0", "kind": "socket"}, {"address": "fffff80003ab6900", "type": "stream", "recv_q": 0, "send_q": 0, "unix_inode": "0", "conn": "fffff80003ab6800", "refs": "0", "nextref": "0", "kind": "socket"}, {"address": "fffff80003abf000", "type": "stream", "recv_q": 0, "send_q": 0, "unix_inode": "fffff80003c581e0", "conn": "0", "refs": "0", "nextref": "0", "addr": "/var/run/devd.pipe", "kind": "socket"}, {"address": "fffff80003ac3e00", "type": "dgram", "recv_q": 0, "send_q": 0, "unix_inode": "0", "conn": "fffff80003ab6c00", "refs": "0", "nextref": "fffff80003ab6400", "kind": "socket"}, {"address": "fffff80003ab6400", "type": "dgram", "recv_q": 0, "send_q": 0, "unix_inode": "0", "conn": "fffff80003ab6c00", "refs": "0", "nextref": "fffff80003ab6000", "kind": "socket"}, {"address": "fffff80003ab6000", "type": "dgram", "recv_q": 0, "send_q": 0, "unix_inode": "0", "conn": "fffff80003ab6c00", "refs": "0", "nextref": "fffff80003ab6600", "kind": "socket"}, {"address": "fffff80003ab6500", "type": "dgram", "recv_q": 0, "send_q": 0, "unix_inode": "0", "conn": "fffff80003ab6d00", "refs": "0", "nextref": "0", "kind": "socket"}, {"address": "fffff80003ab6600", "type": "dgram", "recv_q": 0, "send_q": 0, "unix_inode": "0", "conn": "fffff80003ab6c00", "refs": "0", "nextref": "0", "kind": "socket"}, {"address": "fffff80003ab6c00", "type": "dgram", "recv_q": 0, "send_q": 0, "unix_inode": "fffff80003c59d20", "conn": "0", "refs": "fffff80003ac3e00", "nextref": "0", "addr": "/var/run/logpriv", "kind": "socket"}, {"address": "fffff80003ab6d00", "type": "dgram", "recv_q": 0, "send_q": 0, "unix_inode": "fffff80003c67000", "conn": "0", "refs": "fffff80003ab6500", "nextref": "0", "addr": "/var/run/log", "kind": "socket"}, {"address": "fffff80003ab6e00", "type": "seqpac", "recv_q": 0, "send_q": 0, "unix_inode": "fffff80003c58000", "conn": "0", "refs": "0", "nextref": "0", "addr": "/var/run/devd.seqpacket.pipe", "kind": "socket"}]

24
tests/fixtures/freebsd12/netstat-aT.out vendored Normal file
View File

@@ -0,0 +1,24 @@
Active Internet connections (including servers)
Proto Rexmit OOORcv 0-win Local Address Foreign Address
tcp4 3 0 0 192.168.71.163.ssh 192.168.71.1.64330
tcp4 0 0 0 localhost.smtp *.*
tcp4 0 0 0 *.ssh *.*
tcp6 0 0 0 *.ssh *.*
udp4 *.syslog *.*
udp6 *.syslog *.*
Active UNIX domain sockets
Address Type Recv-Q Send-Q Inode Conn Refs Nextref Addr
fffff80003ab6200 stream 0 0 0 fffff80003ab6100 0 0
fffff80003ab6100 stream 0 0 0 fffff80003ab6200 0 0
fffff80003ab6300 stream 0 0 0 0 0 0
fffff80003ab6800 stream 0 0 0 fffff80003ab6900 0 0
fffff80003ab6900 stream 0 0 0 fffff80003ab6800 0 0
fffff80003abf000 stream 0 0 fffff80003c581e0 0 0 0 /var/run/devd.pipe
fffff80003ac3e00 dgram 0 0 0 fffff80003ab6c00 0 fffff80003ab6400
fffff80003ab6400 dgram 0 0 0 fffff80003ab6c00 0 fffff80003ab6000
fffff80003ab6000 dgram 0 0 0 fffff80003ab6c00 0 fffff80003ab6600
fffff80003ab6500 dgram 0 0 0 fffff80003ab6d00 0 0
fffff80003ab6600 dgram 0 0 0 fffff80003ab6c00 0 0
fffff80003ab6c00 dgram 0 0 fffff80003c59d20 0 fffff80003ac3e00 0 /var/run/logpriv
fffff80003ab6d00 dgram 0 0 fffff80003c67000 0 fffff80003ab6500 0 /var/run/log
fffff80003ab6e00 seqpac 0 0 fffff80003c58000 0 0 0 /var/run/devd.seqpacket.pipe

View File

@@ -0,0 +1 @@
[{"proto": "tcp4", "recv_q": 0, "send_q": 0, "local_address": "192.168.71.163", "foreign_address": "192.168.71.1", "state": "ESTABLISHED", "kind": "network", "local_port": "22", "foreign_port": "56321", "transport_protocol": "tcp", "network_protocol": "ipv4", "local_port_num": 22, "foreign_port_num": 56321}, {"proto": "tcp4", "recv_q": 0, "send_q": 0, "local_address": "127.0.0.1", "foreign_address": "*", "state": "LISTEN", "kind": "network", "local_port": "25", "foreign_port": "*", "transport_protocol": "tcp", "network_protocol": "ipv4", "local_port_num": 25}, {"proto": "tcp4", "recv_q": 0, "send_q": 0, "local_address": "*", "foreign_address": "*", "state": "LISTEN", "kind": "network", "local_port": "22", "foreign_port": "*", "transport_protocol": "tcp", "network_protocol": "ipv4", "local_port_num": 22}, {"proto": "tcp6", "recv_q": 0, "send_q": 0, "local_address": "*", "foreign_address": "*", "state": "LISTEN", "kind": "network", "local_port": "22", "foreign_port": "*", "transport_protocol": "tcp", "network_protocol": "ipv6", "local_port_num": 22}, {"proto": "udp4", "recv_q": 0, "send_q": 0, "local_address": "*", "foreign_address": "*", "state": null, "kind": "network", "local_port": "514", "foreign_port": "*", "transport_protocol": "udp", "network_protocol": "ipv4", "local_port_num": 514}, {"proto": "udp6", "recv_q": 0, "send_q": 0, "local_address": "*", "foreign_address": "*", "state": null, "kind": "network", "local_port": "514", "foreign_port": "*", "transport_protocol": "udp", "network_protocol": "ipv6", "local_port_num": 514}, {"address": "fffff80003ab6100", "type": "stream", "recv_q": 0, "send_q": 0, "unix_inode": "0", "conn": "fffff80003ab6200", "refs": "0", "nextref": "0", "kind": "socket"}, {"address": "fffff80003ab6200", "type": "stream", "recv_q": 0, "send_q": 0, "unix_inode": "0", "conn": "fffff80003ab6100", "refs": "0", "nextref": "0", "kind": "socket"}, {"address": "fffff80003ab6300", "type": "stream", "recv_q": 0, "send_q": 0, "unix_inode": "0", "conn": "0", "refs": "0", "nextref": "0", "kind": "socket"}, {"address": "fffff80003ab6800", "type": "stream", "recv_q": 0, "send_q": 0, "unix_inode": "0", "conn": "fffff80003ab6900", "refs": "0", "nextref": "0", "kind": "socket"}, {"address": "fffff80003ab6900", "type": "stream", "recv_q": 0, "send_q": 0, "unix_inode": "0", "conn": "fffff80003ab6800", "refs": "0", "nextref": "0", "kind": "socket"}, {"address": "fffff80003abf000", "type": "stream", "recv_q": 0, "send_q": 0, "unix_inode": "fffff80003c581e0", "conn": "0", "refs": "0", "nextref": "0", "addr": "/var/run/devd.pipe", "kind": "socket"}, {"address": "fffff80003ac3e00", "type": "dgram", "recv_q": 0, "send_q": 0, "unix_inode": "0", "conn": "fffff80003ab6c00", "refs": "0", "nextref": "fffff80003ab6400", "kind": "socket"}, {"address": "fffff80003ab6400", "type": "dgram", "recv_q": 0, "send_q": 0, "unix_inode": "0", "conn": "fffff80003ab6c00", "refs": "0", "nextref": "fffff80003ab6000", "kind": "socket"}, {"address": "fffff80003ab6000", "type": "dgram", "recv_q": 0, "send_q": 0, "unix_inode": "0", "conn": "fffff80003ab6c00", "refs": "0", "nextref": "fffff80003ab6600", "kind": "socket"}, {"address": "fffff80003ab6500", "type": "dgram", "recv_q": 0, "send_q": 0, "unix_inode": "0", "conn": "fffff80003ab6d00", "refs": "0", "nextref": "0", "kind": "socket"}, {"address": "fffff80003ab6600", "type": "dgram", "recv_q": 0, "send_q": 0, "unix_inode": "0", "conn": "fffff80003ab6c00", "refs": "0", "nextref": "0", "kind": "socket"}, {"address": "fffff80003ab6c00", "type": "dgram", "recv_q": 0, "send_q": 0, "unix_inode": "fffff80003c59d20", "conn": "0", "refs": "fffff80003ac3e00", "nextref": "0", "addr": "/var/run/logpriv", "kind": "socket"}, {"address": "fffff80003ab6d00", "type": "dgram", "recv_q": 0, "send_q": 0, "unix_inode": "fffff80003c67000", "conn": "0", "refs": "fffff80003ab6500", "nextref": "0", "addr": "/var/run/log", "kind": "socket"}, {"address": "fffff80003ab6e00", "type": "seqpac", "recv_q": 0, "send_q": 0, "unix_inode": "fffff80003c58000", "conn": "0", "refs": "0", "nextref": "0", "addr": "/var/run/devd.seqpacket.pipe", "kind": "socket"}]

24
tests/fixtures/freebsd12/netstat-an.out vendored Normal file
View File

@@ -0,0 +1,24 @@
Active Internet connections (including servers)
Proto Recv-Q Send-Q Local Address Foreign Address (state)
tcp4 0 0 192.168.71.163.22 192.168.71.1.56321 ESTABLISHED
tcp4 0 0 127.0.0.1.25 *.* LISTEN
tcp4 0 0 *.22 *.* LISTEN
tcp6 0 0 *.22 *.* LISTEN
udp4 0 0 *.514 *.*
udp6 0 0 *.514 *.*
Active UNIX domain sockets
Address Type Recv-Q Send-Q Inode Conn Refs Nextref Addr
fffff80003ab6100 stream 0 0 0 fffff80003ab6200 0 0
fffff80003ab6200 stream 0 0 0 fffff80003ab6100 0 0
fffff80003ab6300 stream 0 0 0 0 0 0
fffff80003ab6800 stream 0 0 0 fffff80003ab6900 0 0
fffff80003ab6900 stream 0 0 0 fffff80003ab6800 0 0
fffff80003abf000 stream 0 0 fffff80003c581e0 0 0 0 /var/run/devd.pipe
fffff80003ac3e00 dgram 0 0 0 fffff80003ab6c00 0 fffff80003ab6400
fffff80003ab6400 dgram 0 0 0 fffff80003ab6c00 0 fffff80003ab6000
fffff80003ab6000 dgram 0 0 0 fffff80003ab6c00 0 fffff80003ab6600
fffff80003ab6500 dgram 0 0 0 fffff80003ab6d00 0 0
fffff80003ab6600 dgram 0 0 0 fffff80003ab6c00 0 0
fffff80003ab6c00 dgram 0 0 fffff80003c59d20 0 fffff80003ac3e00 0 /var/run/logpriv
fffff80003ab6d00 dgram 0 0 fffff80003c67000 0 fffff80003ab6500 0 /var/run/log
fffff80003ab6e00 seqpac 0 0 fffff80003c58000 0 0 0 /var/run/devd.seqpacket.pipe

View File

@@ -0,0 +1 @@
[{"iface": "em0", "mtu": 1500, "network": "<Link#1>", "address": "00:0c:29:1a:4e:3b", "ipkts": 189449, "ierrs": 0, "idrop": 0, "opkts": 211310, "oerrs": 0, "coll": 0, "kind": "interface"}, {"iface": "em0", "mtu": null, "network": "fe80::%em0/64", "address": "fe80::20c:29ff:fe", "ipkts": 0, "ierrs": null, "idrop": null, "opkts": 4, "oerrs": null, "coll": null, "kind": "interface"}, {"iface": "em0", "mtu": null, "network": "192.168.71.0/", "address": "192.168.71.163", "ipkts": 92481, "ierrs": null, "idrop": null, "opkts": 172946, "oerrs": null, "coll": null, "kind": "interface"}, {"iface": "lo0", "mtu": 16384, "network": "<Link#2>", "address": "lo0", "ipkts": 26, "ierrs": 0, "idrop": 0, "opkts": 26, "oerrs": 0, "coll": 0, "kind": "interface"}, {"iface": "lo0", "mtu": null, "network": "localhost", "address": "localhost", "ipkts": 23, "ierrs": null, "idrop": null, "opkts": 23, "oerrs": null, "coll": null, "kind": "interface"}, {"iface": "lo0", "mtu": null, "network": "fe80::%lo0/64", "address": "fe80::1%lo0", "ipkts": 0, "ierrs": null, "idrop": null, "opkts": 0, "oerrs": null, "coll": null, "kind": "interface"}, {"iface": "lo0", "mtu": null, "network": "your-net", "address": "localhost", "ipkts": 3, "ierrs": null, "idrop": null, "opkts": 3, "oerrs": null, "coll": null, "kind": "interface"}]

View File

@@ -0,0 +1,8 @@
Name Mtu Network Address Ipkts Ierrs Idrop Opkts Oerrs Coll
em0 1500 <Link#1> 00:0c:29:1a:4e:3b 189449 0 0 211310 0 0
em0 - fe80::%em0/64 fe80::20c:29ff:fe 0 - - 4 - -
em0 - 192.168.71.0/ 192.168.71.163 92481 - - 172946 - -
lo0 16384 <Link#2> lo0 26 0 0 26 0 0
lo0 - localhost localhost 23 - - 23 - -
lo0 - fe80::%lo0/64 fe80::1%lo0 0 - - 0 - -
lo0 - your-net localhost 3 - - 3 - -

View File

@@ -0,0 +1 @@
[{"iface": "em0", "mtu": 1500, "network": "<Link#1>", "address": "00:0c:29:1a:4e:3b", "ipkts": 372717, "ierrs": 0, "idrop": 0, "ibytes": 372538087, "opkts": 213821, "oerrs": 0, "obytes": 198573339, "coll": 0, "kind": "interface"}, {"iface": "em0", "mtu": null, "network": "fe80::%em0/64", "address": "fe80::20c:29ff:fe", "ipkts": 0, "ierrs": null, "idrop": null, "ibytes": 0, "opkts": 4, "oerrs": null, "obytes": 264, "coll": null, "kind": "interface"}, {"iface": "em0", "mtu": null, "network": "192.168.71.0/", "address": "192.168.71.163", "ipkts": 97396, "ierrs": null, "idrop": null, "ibytes": 68178099, "opkts": 175413, "oerrs": null, "obytes": 193957797, "coll": null, "kind": "interface"}, {"iface": "lo0", "mtu": 16384, "network": "<Link#2>", "address": "lo0", "ipkts": 98, "ierrs": 0, "idrop": 0, "ibytes": 21024, "opkts": 98, "oerrs": 0, "obytes": 21024, "coll": 0, "kind": "interface"}, {"iface": "lo0", "mtu": null, "network": "localhost", "address": "localhost", "ipkts": 25, "ierrs": null, "idrop": null, "ibytes": 4829, "opkts": 25, "oerrs": null, "obytes": 4829, "coll": null, "kind": "interface"}, {"iface": "lo0", "mtu": null, "network": "fe80::%lo0/64", "address": "fe80::1%lo0", "ipkts": 0, "ierrs": null, "idrop": null, "ibytes": 0, "opkts": 0, "oerrs": null, "obytes": 0, "coll": null, "kind": "interface"}, {"iface": "lo0", "mtu": null, "network": "your-net", "address": "localhost", "ipkts": 73, "ierrs": null, "idrop": null, "ibytes": 16195, "opkts": 73, "oerrs": null, "obytes": 16195, "coll": null, "kind": "interface"}]

View File

@@ -0,0 +1,8 @@
Name Mtu Network Address Ipkts Ierrs Idrop Ibytes Opkts Oerrs Obytes Coll
em0 1500 <Link#1> 00:0c:29:1a:4e:3b 372717 0 0 372538087 213821 0 198573339 0
em0 - fe80::%em0/64 fe80::20c:29ff:fe 0 - - 0 4 - 264 -
em0 - 192.168.71.0/ 192.168.71.163 97396 - - 68178099 175413 - 193957797 -
lo0 16384 <Link#2> lo0 98 0 0 21024 98 0 21024 0
lo0 - localhost localhost 25 - - 4829 25 - 4829 -
lo0 - fe80::%lo0/64 fe80::1%lo0 0 - - 0 0 - 0 -
lo0 - your-net localhost 73 - - 16195 73 - 16195 -

View File

@@ -0,0 +1 @@
[{"destination": "default", "gateway": "192.168.71.2", "route_flags": "UGS", "iface": "em0", "kind": "route", "route_flags_pretty": ["UP", "GATEWAY", "STATIC"]}, {"destination": "localhost", "gateway": "link#2", "route_flags": "UH", "iface": "lo0", "kind": "route", "route_flags_pretty": ["UP", "HOST"]}, {"destination": "192.168.71.0/24", "gateway": "link#1", "route_flags": "U", "iface": "em0", "kind": "route", "route_flags_pretty": ["UP"]}, {"destination": "192.168.71.163", "gateway": "link#1", "route_flags": "UHS", "iface": "lo0", "kind": "route", "route_flags_pretty": ["UP", "HOST", "STATIC"]}, {"destination": "::/96", "gateway": "localhost", "route_flags": "UGRS", "iface": "lo0", "kind": "route", "route_flags_pretty": ["UP", "GATEWAY", "REJECT", "STATIC"]}, {"destination": "localhost", "gateway": "link#2", "route_flags": "UH", "iface": "lo0", "kind": "route", "route_flags_pretty": ["UP", "HOST"]}, {"destination": "::ffff:0.0.0.0/96", "gateway": "localhost", "route_flags": "UGRS", "iface": "lo0", "kind": "route", "route_flags_pretty": ["UP", "GATEWAY", "REJECT", "STATIC"]}, {"destination": "fe80::/10", "gateway": "localhost", "route_flags": "UGRS", "iface": "lo0", "kind": "route", "route_flags_pretty": ["UP", "GATEWAY", "REJECT", "STATIC"]}, {"destination": "fe80::%em0/64", "gateway": "link#1", "route_flags": "U", "iface": "em0", "kind": "route", "route_flags_pretty": ["UP"]}, {"destination": "fe80::20c:29ff:fe1", "gateway": "link#1", "route_flags": "UHS", "iface": "lo0", "kind": "route", "route_flags_pretty": ["UP", "HOST", "STATIC"]}, {"destination": "fe80::%lo0/64", "gateway": "link#2", "route_flags": "U", "iface": "lo0", "kind": "route", "route_flags_pretty": ["UP"]}, {"destination": "fe80::1%lo0", "gateway": "link#2", "route_flags": "UHS", "iface": "lo0", "kind": "route", "route_flags_pretty": ["UP", "HOST", "STATIC"]}, {"destination": "ff02::/16", "gateway": "localhost", "route_flags": "UGRS", "iface": "lo0", "kind": "route", "route_flags_pretty": ["UP", "GATEWAY", "REJECT", "STATIC"]}]

20
tests/fixtures/freebsd12/netstat-r.out vendored Normal file
View File

@@ -0,0 +1,20 @@
Routing tables
Internet:
Destination Gateway Flags Netif Expire
default 192.168.71.2 UGS em0
localhost link#2 UH lo0
192.168.71.0/24 link#1 U em0
192.168.71.163 link#1 UHS lo0
Internet6:
Destination Gateway Flags Netif Expire
::/96 localhost UGRS lo0
localhost link#2 UH lo0
::ffff:0.0.0.0/96 localhost UGRS lo0
fe80::/10 localhost UGRS lo0
fe80::%em0/64 link#1 U em0
fe80::20c:29ff:fe1 link#1 UHS lo0
fe80::%lo0/64 link#2 U lo0
fe80::1%lo0 link#2 UHS lo0
ff02::/16 localhost UGRS lo0

1
tests/fixtures/freebsd12/ntpq-p.json vendored Normal file
View File

@@ -0,0 +1 @@
[{"remote": "0.freebsd.pool.", "refid": ".POOL.", "st": 16, "t": "p", "when": null, "poll": 64, "reach": 0, "delay": 0.0, "offset": 0.0, "jitter": 0.0, "state": null}, {"remote": "vf1.bbnx.net", "refid": "252.74.143.178", "st": 2, "t": "u", "when": 1, "poll": 64, "reach": 1, "delay": 387.363, "offset": 1589483.0, "jitter": 39.556, "state": null}, {"remote": "time.airgapped.", "refid": "132.163.96.1", "st": 2, "t": "u", "when": 2, "poll": 64, "reach": 1, "delay": 70.572, "offset": 1589483.0, "jitter": 0.724, "state": null}, {"remote": "clock.trit.net", "refid": "43.77.130.254", "st": 2, "t": "u", "when": 2, "poll": 64, "reach": 1, "delay": 55.717, "offset": 1589483.0, "jitter": 2.021, "state": null}, {"remote": "time.nullrouten", "refid": "132.163.97.1", "st": 2, "t": "u", "when": 1, "poll": 64, "reach": 1, "delay": 59.682, "offset": 1589483.0, "jitter": 7.573, "state": null}]

7
tests/fixtures/freebsd12/ntpq-p.out vendored Normal file
View File

@@ -0,0 +1,7 @@
remote refid st t when poll reach delay offset jitter
==============================================================================
0.freebsd.pool. .POOL. 16 p - 64 0 0.000 0.000 0.000
vf1.bbnx.net 252.74.143.178 2 u 1 64 1 387.363 1589483 39.556
time.airgapped. 132.163.96.1 2 u 2 64 1 70.572 1589483 0.724
clock.trit.net 43.77.130.254 2 u 2 64 1 55.717 1589483 2.021
time.nullrouten 132.163.97.1 2 u 1 64 1 59.682 1589483 7.573

1
tests/fixtures/freebsd12/stat.json vendored Normal file

File diff suppressed because one or more lines are too long

Some files were not shown because too many files have changed in this diff Show More