Interactive vendor distribution pie chart with detailed hover information - see device counts, percentages, and VLAN presence at a glance
- Turn MAC tables into dashboards: Transform raw network device outputs into interactive HTML visualizations and CSV reports
- Detect new/unknown vendors: Identify previously unseen devices and track vendor distribution changes over time
- Export SIEM events: Generate normalized CSV/JSONL exports for Elastic, Splunk, and other SIEMs to enable posture-change detection
Quick start: python3 NetVendor.py input_file.txt β Check output/ for results
Try it in 60 seconds: python3 NetVendor.py tests/data/test-mac-table.txt (then open output/vendor_distribution.html in your browser) β See dashboards without touching your own network data
- SOC analysts: Detect new vendors and track device changes for security monitoring
- Network engineers: Analyze MAC address tables and ARP data to understand network composition
- Asset/CMDB owners: Maintain accurate device inventories with vendor identification
- Security architects: Integrate posture-change detection into SIEM workflows
NetVendor is a Python tool for network administrators and cybersecurity professionals to analyze and visualize the vendor distribution of devices on a network. It processes MAC address tables and ARP data from a wide range of network devices (including Cisco, HP/Aruba, Juniper, Extreme, Brocade, and more), providing detailed insights into your network's composition.
When integrated with SIEMs (Elastic, Splunk, QRadar, etc.), NetVendor transforms from a static inventory tool into a posture-change sensor that enables proactive security monitoring and incident response.
- β¨ Features
- π Common Workflows
- π Getting Started
- π Quick Reference
- π Detailed Usage
- π₯ Supported Input Formats
- π Output Details
- π Success Stories & Known Deployments
- π§ Advanced Topics
- π§ͺ Testing & Quality
- π Project Status
- π€ Community
- Multi-vendor MAC address parsing: Supports Cisco, HP/Aruba, Juniper, Extreme, Brocade, and more.
- Flexible input: Accepts MAC address lists, MAC tables, and ARP tables in various formats.
- Vendor identification: Uses a local IEEE OUI cache for fast, secure lookups.
- Comprehensive reporting: Generates CSVs, summaries, and interactive HTML dashboards.
- VLAN and port analysis: Extracts and visualizes VLAN and port data where available.
- Historical drift tracking: Archive vendor summaries and analyze trends over time with metadata correlation.
- SIEM integration: Export normalized CSV/JSONL events for security monitoring and posture-change detection.
- Extensible and robust: Easily add support for new formats; thoroughly tested with real-world data.
Basic Analysis:
python3 NetVendor.py input_file.txtβ Generates standard outputs: Device CSV, Port CSV (if MAC table), HTML dashboard, Vendor Summary
Offline Analysis (air-gapped networks):
python3 NetVendor.py --offline input_file.txtβ Uses only local OUI cache, no external API calls
SIEM Integration:
python3 NetVendor.py \
--siem-export \
--site DC1 \
--environment prod \
input_file.txtβ Generates standard outputs + SIEM-ready CSV/JSONL files
Historical Tracking with Drift Analysis:
python3 NetVendor.py \
--history-dir history \
--site DC1 \
--change-ticket CHG-12345 \
--analyze-drift \
input_file.txtβ Generates standard outputs + archives summary with metadata + creates drift analysis CSV
Complete Workflow (all features):
python3 NetVendor.py \
--offline \
--history-dir history \
--analyze-drift \
--siem-export \
--site DC1 \
--environment prod \
--change-ticket CHG-12345 \
input_file.txtβ Runs offline, generates all outputs, archives with metadata, creates drift analysis, and exports SIEM events
- Python 3.8 or higher
- Required packages:
requests,plotly,rich,tqdm - Input file containing MAC addresses or ARP data from your network devices
git clone https://github.com/StewAlexander-com/NetVendor.git
cd NetVendor
pip install -e .1. Simple Package Entry Point (basic usage, no flags):
netvendor input_file.txt
# or
python3 -m netvendor input_file.txtLimited to basic analysis only - no advanced features
2. Standalone Script (full feature set with all flags):
python3 NetVendor.py input_file.txtImportant: For all advanced features (offline mode, history tracking, SIEM export, drift analysis), use python3 NetVendor.py. The package entry point (netvendor) is a simple wrapper that only accepts an input file argument and does not support flags.
NetVendor generates several output files in the output/ directory:
- Standard outputs (always generated): Device CSV, Port CSV (for MAC tables), interactive HTML dashboard, and vendor summary text file
- Optional outputs (with flags): SIEM exports (CSV/JSONL), historical archives, and drift analysis CSV
See Output Details below for complete file descriptions.
| Flag | Description | Example |
|---|---|---|
--offline |
Disable external vendor lookups (cache-only) | --offline |
--history-dir DIR |
Directory for archiving vendor summaries (created automatically if it doesn't exist) | --history-dir history |
--analyze-drift |
Run drift analysis on archived summaries | --analyze-drift |
--site SITE |
Site/region identifier for SIEM/drift metadata | --site DC1 |
--environment ENV |
Environment identifier for SIEM exports | --environment prod |
--change-ticket ID |
Change ticket/incident ID for drift correlation | --change-ticket CHG-12345 |
--siem-export |
Generate SIEM-friendly CSV/JSONL exports | --siem-export |
Note: Configuration file values and environment variables can provide defaults for these flags. See Configuration section below.
Use the --offline flag when you want to avoid any external vendor lookups (e.g., on airβgapped networks). Devices that are not already present in the local OUI cache will appear as Unknown.
python3 NetVendor.py --offline input_file.txtTrack how vendor composition changes over time and correlate with change windows/incidents:
python3 NetVendor.py \
--history-dir history \
--site DC1 \
--change-ticket CHG-12345 \
--analyze-drift \
input_file.txtWhat it does:
- Creates the history directory if it doesn't exist
- Archives
vendor_summary.txttohistory/vendor_summary-YYYYMMDD-HHMMSS.txt - Creates companion
.metadata.jsonfile withrun_timestamp,site,change_ticket_id - Generates
history/vendor_drift.csvwith metadata rows and vendor percentage trends
SIEM Correlation: The drift CSV metadata enables correlation with change windows and incidents, supporting 8D/5-why workflows. You can join drift data with SIEM events using run_timestamp and site, and correlate vendor mix shifts with change_ticket_id.
For SIEM integration (Elastic, Splunk, etc.), generate normalized CSV and JSONL events:
python3 NetVendor.py \
--siem-export \
--site DC1 \
--environment prod \
input_file.txtStable Schema (all fields present in every record):
timestamp: UTC ISO-8601 collection time (e.g.,2025-10-31T16:23:45Z)site: Site/region identifier (e.g.,DC1,HQ,us-east-1)environment: Environment identifier (e.g.,prod,dev,staging)mac: Normalized MAC address (xx:xx:xx:xx:xx:xx)vendor: Vendor name from OUI lookup (orUnknownif not found)device_name: Device identifier (derived from MAC)vlan: VLAN ID (orN/Aif not available)interface: Network interface/port identifier (e.g.,Gi1/0/1,ge-0/0/0)input_type: Source data type (mac_list,mac_table,arp_table,unknown)source_file: Original input filename
Correlation-friendly design:
- All fields consistently named and present in every record
- MAC addresses normalized for reliable joins
- UTC ISO-8601 timestamps for time-based correlation
- Site and environment tags enable multi-site/environment dashboards
NetVendor is designed to work on Linux (Debian/Ubuntu), macOS (Intel and Apple Silicon), and Windows. All file operations use UTF-8 encoding and cross-platform path handling.
Windows Usage:
# Set encoding environment variables (recommended)
$env:PYTHONIOENCODING = "utf-8"
$env:PYTHONUTF8 = "1"
python3 NetVendor.py input_file.txtLinux/macOS Usage:
python3 NetVendor.py input_file.txtCross-Platform Considerations:
- File paths: All paths use
pathlib.Pathfor cross-platform compatibility (handles/vs\automatically) - File encoding: All file operations explicitly use UTF-8 encoding to prevent encoding issues on Windows
- Line endings: Python's text mode handles both CRLF (Windows) and LF (Unix) automatically
- File locking: Cache writes use atomic operations (write to temp file, then rename) to prevent corruption if multiple processes run simultaneously
- API timeouts: All network requests have 5-second timeouts to prevent hangs on slow/unreliable networks
- Error handling: Permission errors and file system errors are handled gracefully on all platforms
Control debug output with the NETVENDOR_VERBOSE environment variable (only supported by NetVendor.py):
# Quiet mode (default)
python3 NetVendor.py input_file.txt
# Verbose mode - detailed processing information
NETVENDOR_VERBOSE=1 python3 NetVendor.py input_file.txtWhen verbose mode is enabled, you'll see file type detection details, per-line processing information, sample device entries, CSV writing progress, and output file content preview.
For troubleshooting and performance analysis, NetVendor can log runtime behavior to a structured log file:
# Enable runtime logging
NETVENDOR_LOG=1 python3 NetVendor.py input_file.txtWhen enabled, a log file is created at output/netvendor_runtime.log in JSONL format (one JSON object per line). Each entry includes:
timestamp: UTC ISO-8601 timestampevent_type: Type of event (e.g., "processing_start", "file_type_detection", "error")event_data: Event-specific datacontext: Additional context information
The logger captures key runtime events including file processing, error conditions, output generation, and performance metrics. Logging is disabled by default and has no performance impact when not enabled.
NetVendor supports configuration files and environment variables to reduce CLI flag churn in recurring jobs.
Configuration file locations (checked in order):
- Current directory:
./netvendor.conf(or.yaml,.toml) - User config:
~/.config/netvendor/netvendor.conf - System config:
/etc/netvendor/netvendor.conf
Supported formats: INI/ConfigParser (.conf, .ini), YAML (.yaml, .yml - requires PyYAML), TOML (.toml - requires tomli/tomllib)
Example INI config (netvendor.conf):
[netvendor]
offline = true
history_dir = /var/lib/netvendor/history
site = DC1
environment = prod
siem_export = trueExample YAML config (netvendor.yaml):
netvendor:
offline: true
history_dir: /var/lib/netvendor/history
site: DC1
environment: prod
siem_export: trueEnvironment variables (override config file):
NETVENDOR_OFFLINE=trueNETVENDOR_HISTORY_DIR=/var/lib/netvendor/historyNETVENDOR_SITE=DC1NETVENDOR_ENVIRONMENT=prodNETVENDOR_SIEM_EXPORT=true
Precedence: Command-line arguments > Environment variables > Config file > Defaults
See netvendor.conf.example and netvendor.yaml.example for complete examples.
NetVendor provides a programmatic Python API for integration into automation scripts and other tools:
from netvendor import analyze_file
# Basic usage
result = analyze_file("mac_table.txt", offline=True)
print(f"Processed {result['device_count']} devices")
print(f"Found {result['vendor_count']} unique vendors")
print(f"Output files: {result['output_files']}")
# Access device data
for mac, info in result['devices'].items():
print(f"{mac}: {info['vendor']} (VLAN: {info['vlan']})")
# With SIEM export
result = analyze_file(
input_file="mac_table.txt",
offline=True,
siem_export=True,
site="DC1",
environment="prod"
)
# With history tracking
result = analyze_file(
input_file="mac_table.txt",
history_dir="history",
analyze_drift_flag=True,
site="DC1",
change_ticket="CHG-12345"
)API Reference: See netvendor/api.py for complete function signature and return value documentation.
Just paste your raw show mac address-table output into a file; NetVendor will auto-detect the format. No heavy data cleaning required - the tool handles headers, whitespace, and various vendor formats automatically.
NetVendor automatically detects and parses the following formats:
00:11:22:33:44:55
00-11-22-33-44-55
001122334455
0011.2233.4455
Vlan Mac Address Type Ports
10 0011.2233.4455 DYNAMIC Gi1/0/1
20 00:0E:83:11:22:33 DYNAMIC ge-0/0/0
30 B8:AC:6F:77:88:99 DYNamic 1:1
- Cisco:
0011.2233.4455,Gi1/0/1 - HP/Aruba:
00:24:81:44:55:66,1 - Juniper:
00:0E:83:11:22:33/ff:ff:ff:ff:ff:ff,ge-0/0/0 - Extreme:
B8-AC-6F-77-88-99/ff-ff-ff-ff-ff-ff,1:1 - Brocade:
00:11:22:33:44:55/ffff.ffff.ffff,1/1
Protocol Address Age (min) Hardware Addr Type Interface
Internet 192.168.1.1 - 0011.2233.4455 ARPA Vlan10
Format Detection Features:
- Automatic file type detection based on content
- Flexible MAC parsing: Accepts colon, hyphen, dot, and mask/prefix formats
- VLAN extraction from multiple sources (column, interface, etc.)
- Port extraction for detailed switch analysis
- Header skipping and robust error handling
π Device count analysis per VLAN - quickly identify VLANs with high device concentrations for security monitoring
π Comprehensive multi-panel VLAN analysis dashboard - view device counts, vendor diversity, heatmaps, and top vendor distributions across your network segments
Device Information CSV ({input_file}-Devices.csv):
- One row per device
- Columns: MAC, Vendor, VLAN, Port
- Always generated
Port Report CSV ({input_file}-Ports.csv):
- Port utilization and device mapping
- Only generated for MAC address tables (not ARP or simple lists)
- Columns: Port, Total Devices, VLANs, Vendors, Device Details
Vendor Distribution HTML (vendor_distribution.html):
- Interactive dashboard with charts
- Vendor distribution pie chart
- VLAN analysis with multiple subplots
- Always generated
Vendor Summary Text (vendor_summary.txt):
- Plain text summary with vendor counts and percentages
- Formatted table for quick reference
- Always generated
SIEM Export Files (requires --siem-export, written to output/siem/ directory):
siem/netvendor_siem.csv: Line-delimited CSV with headersiem/netvendor_siem.json: JSONL format (one JSON object per line)- Both contain identical data with stable schema for SIEM correlation
History Archive Files (requires --history-dir):
vendor_summary-YYYYMMDD-HHMMSS.txt: Timestamped vendor summary snapshotvendor_summary-YYYYMMDD-HHMMSS.metadata.json: Companion metadata file with:run_timestamp: UTC ISO-8601 timestampsite: Site/region identifierchange_ticket_id: Change ticket/incident ID
Drift Analysis CSV (requires --analyze-drift):
history/vendor_drift.csv: Vendor percentage trends across all archived runs- Includes metadata rows at top:
run_timestamp,site,change_ticket_id - Vendor percentage rows showing changes over time
NetVendor is used in production environments for network monitoring, security posture tracking, and asset management. While specific deployment details are kept confidential, the tool has been successfully deployed in:
- Enterprise SOC environments: Integrated with Elastic Stack and Splunk for continuous posture-change detection across multiple data centers
- Network operations teams: Daily analysis of MAC address tables from Cisco, Juniper, and Aruba switches to track device inventory and vendor distribution
- Air-gapped networks: Offline mode enables vendor identification in isolated environments without external API dependencies
- Change management workflows: Historical drift analysis with change ticket correlation supports incident response and root cause analysis
Have a success story to share? We'd love to hear how you're using NetVendor! See the Community section for details on how to contribute your success story.
For detailed information on advanced topics, see ADVANCED.md:
- Posture-Change Detection & Security Monitoring: SIEM integration workflows, correlation rules, and continuous monitoring strategies
- Operational Best Practices: Vendor lookup optimization, cache management, output organization, troubleshooting, and cross-platform considerations
- Runtime Considerations: Performance benchmarks, network behavior, disk space planning, and error handling details
Want to understand how NetVendor works under the hood? See TUTORIAL.md for a comprehensive technical deep-dive covering:
- Architecture and design decisions
- Code walkthroughs with examples
- Data flow diagrams
- Implementation details for each component
NetVendor includes a comprehensive test suite that validates all execution paths, input formats, and features to ensure reliability and correctness.
Quick test run:
pytest -qDetailed test output:
pytest -vRun specific test categories:
# Test all execution paths (package entry, standalone script, Python API)
pytest tests/test_execution_paths.py -v
# Test core parsing and format detection
pytest tests/test_netvendor.py -v
# Test vendor lookup and caching
pytest tests/test_oui_manager.py -v
# Test output generation
pytest tests/test_vendor_output_handler.py -v
# Test Python API
pytest tests/test_api.py -vTest with coverage report:
pytest --cov=netvendor --cov-report=htmlNetVendor's test suite includes 20+ execution path tests that validate every way users can run the tool:
- β
Package entry point (
netvendor input_file.txt) - Basic analysis - β
Standalone script (
python3 NetVendor.py) - All flag combinations - β
Python API (
from netvendor import analyze_file) - Programmatic usage - β Configuration-driven - Config files and environment variables
- β Input type detection - MAC lists, MAC tables, ARP tables
- β Error handling - Missing files, empty files, invalid inputs
- β Feature combinations - Offline mode, SIEM export, drift analysis, history tracking
Test data: Sample inputs for validation are in tests/data/:
test-mac-list.txt- 100 MAC addressestest-mac-table.txt- 500+ MAC table entries (Cisco format)test-arp-table.txt- ARP table format
Execution Paths (tests/test_execution_paths.py):
- All ways to run NetVendor (package entry, standalone, Python API)
- All flag combinations (offline, SIEM, drift, history)
- Configuration file loading (INI, YAML, TOML)
- Environment variable overrides
- Input type detection and parsing
- Error handling and edge cases
Core Functionality (tests/test_netvendor.py):
- MAC address validation and normalization
- File type detection (MAC list, MAC table, ARP table)
- Port information parsing
- Format type detection
Vendor Lookup (tests/test_oui_manager.py):
- OUI cache functionality
- Failed lookup tracking
- API integration and rate limiting
Output Generation (tests/test_vendor_output_handler.py):
- CSV file generation
- HTML dashboard creation
- Port report generation
- Vendor summary formatting
Python API (tests/test_api.py):
- API function signatures
- Return value validation
- Error handling
NetVendor's testing approach prioritizes:
- Comprehensive coverage: Every execution path is tested
- Real-world data: Tests use realistic network device outputs
- Isolation: Tests use temporary directories to avoid side effects
- Mock data: All tests use controlled mock data for reproducibility
- Cross-platform: Tests validate Windows/Linux/macOS compatibility
For detailed testing documentation, see:
- EXECUTION_PATHS.md - Complete execution path documentation and behavior graphs
- TEST_COVERAGE.md - Detailed test coverage summary
- TUTORIAL.md - Test strategy and debugging guide
If configured locally:
ruff check .
mypy netvendorLatest Release: v12.8 - Enhanced HTML Dashboard Readability
NetVendor is actively maintained and regularly updated.
Recent improvements:
- β Enhanced MAC address parsing for Juniper, Aruba, Extreme, Brocade, and more
- β Improved OUIManager logic and normalization
- β Real-world OUI test coverage
- β Historical drift analysis with metadata correlation (timestamp, site, change_ticket_id)
- β
SIEM export with stable schema for posture-change detection (CSV/JSONL in
output/siem/) - β Runtime logging for troubleshooting and performance analysis (JSONL format)
- β Enhanced error handling with user-friendly messages and actionable hints
- β
Offline mode support for air-gapped networks (
--offlineflag) - β Comprehensive README with TL;DR, workflows, table of contents, and quick-start examples
- β All tests pass and program output confirmed
Planned:
- More vendor format support
- Additional visualization options
- Network topology mapping
- GitHub Discussions for community questions and discussions
- Community chat channels (Slack/Discord)
NetVendor is an open-source project, and we welcome contributions from the community!
- Report bugs or request features: Open an issue on GitHub
- Ask questions: Open a GitHub issue with the "question" label for general questions and use cases
- Security issues: Please report security vulnerabilities privately through GitHub's security advisory system
We'd love to hear how you're using NetVendor! Share your success stories by:
- Opening a GitHub issue with your use case (anonymized as needed)
- Submitting a pull request to add your deployment to the Success Stories section
- Sharing your experience in an issue thread
Contributions are welcome! To contribute:
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests if applicable
- Submit a pull request with a clear description of your changes
- GitHub Discussions: See Planned section for upcoming community features
- Community chat: See Planned section for upcoming community features
MIT License
Stewart Alexander
π‘ Tip: For best results, always use the latest OUI cache and keep your dependencies up to date. And remember: Networks are more fun when you know who's on them! π