[DAY#10 PyATS Series] Parsing and Normalizing ARP Tables (Multi-Vendor) using pyATS (Vendor-Agnostic) [Python for Network Engineer]

[DAY#10 PyATS Series] Parsing and Normalizing ARP Tables (Multi-Vendor) using pyATS (Vendor-Agnostic) [Python for Network Engineer]


Introduction: Why ARP Table Normalization Matters

Welcome to Day 10 of the 101 Days of pyATS (Vendor‑Agnostic) series!
Today, we’re focusing on a critical under-the-hood element of L2‑L3 connectivity: parsing and normalizing ARP tables across Cisco, Arista, Palo Alto, and FortiGate devices using pyATS and Genie. For any Python for Network Engineer, being able to extract, standardize, and validate ARP entries is key to:

  • Detecting duplicate IPs or stale entries
  • Automating network inventory and host audits
  • Troubleshooting connectivity issues with precision
  • Ensuring programmatic consistency across vendors

By the end of today’s tutorial, you’ll have a reusable, vendor-agnostic script that:

  • Connects to diverse devices
  • Collects ARP tables via structured output
  • Normalizes the data (IP ↔ MAC ↔ Interface)
  • Runs ping tests to verify host reachability

Ready to level up your network automation? Let’s dive in!


Topology Overview

Here’s our lab layout for Day 10:

Connectivity:

  • Management VM (pyATS) can SSH into all devices
  • Devices share a common L2 segment with a host (Host1 192.168.50.10)
  • We will extract ARP entries from each device to look for that host’s MAC/IP

Why Vendor‑Agnostic Testing Matters

In heterogeneous network environments, inconsistency is a constant risk. Each OS uses slightly different CLI and ARP table formats:

  • Cisco IOS-XE: show ip arp
  • Arista EOS: show ip arp (similar format)
  • Palo Alto PAN-OS: show arp all
  • FortiGate FortiOS: execute arp list

Without a vendor‑agnostic approach, scripts quickly become brittle. pyATS simplifies this by:

  • Parsing structured data via Genie parsers
  • Normalizing entries into unified Python dictionaries
  • Making downstream processing—like ping tests or audits—consistent

The result? A cleaner, deterministic workflow that scales across vendors and use cases.


Topology & Communications

DeviceOSMGMT IPARP Command
Cisco R1IOS‑XE10.100.0.1show ip arp
Arista R2EOS10.100.0.2show ip arp
Palo Alto PA1PAN‑OS10.100.0.3show arp all
FortiGate FG1FortiOS10.100.0.4execute arp list
Host1Linux VM192.168.50.10

Workflow:

  1. Parse ARP entries across devices
  2. Normalize to {"ip":..., "mac":..., "intf":...}
  3. Ping each IP to verify reachability
  4. Log results and generate consolidated report

Workflow Script

Below is a simplified arp_normalize.py script using pyATS and Genie:

from genie.testbed import load
import re
import json

def normalize_arp(parsed_arp, os_type):
    normalized = []
    for entry in parsed_arp:
        ip = entry.get('address') or entry.get('ip')
        mac = entry.get('hardware_address') or entry.get('mac')
        intf = entry.get('interface') or entry.get('ifname')
        normalized.append({'ip': ip, 'mac': mac, 'interface': intf})
    return normalized

def main():
    testbed = load('testbed.yml')
    for name, dev in testbed.devices.items():
        print(f"\n== {name} ({dev.os}) ==")
        dev.connect()
        if dev.os in ['iosxe', 'eos']:
            parsed = dev.parse('show ip arp')['arp_table']
        elif dev.os == 'panos':
            parsed = dev.parse('show arp all')['arp_table']
        elif dev.os == 'fortios':
            entries = dev.parse('execute arp list')['entries']
            parsed = entries.values()
        else:
            print("Unsupported OS!")
            dev.disconnect()
            continue

        arp_list = normalize_arp(parsed, dev.os)
        print("Normalized entries:", json.dumps(arp_list, indent=2))

        # Ping each IP
        for x in arp_list:
            ip = x['ip']
            result = dev.ping(ip, count=2)
            print(f"Ping {ip}: {'' if result else ''}")

        dev.disconnect()

if __name__ == "__main__":
    main()

Explanation by Line

LinesCode SnippetPurpose
1–3ImportsLoad pyATS Genie parser
5–11normalize_arp() functionStandardizes ARP entries
13–33main()Script orchestration
15testbed = load(...)Load YAML testbed
17–32Loop through devicesExtract, normalize, ping
19–28OS-specific parsing logicUnified list output
30–31dev.ping() testValidate reachability

testbed.yml Example

testbed:
  name: arp-parse-lab

devices:
  cisco_r1:
    os: iosxe
    type: router
    connections:
      cli:
        protocol: ssh
        ip: 10.100.0.1

  arista_r2:
    os: eos
    type: switch
    connections:
      cli:
        protocol: ssh
        ip: 10.100.0.2

  paloalto_pa1:
    os: panos
    type: firewall
    connections:
      cli:
        protocol: ssh
        ip: 10.100.0.3

  fortigate_fg1:
    os: fortios
    type: firewall
    connections:
      cli:
        protocol: ssh
        ip: 10.100.0.4

Multi-Vendor CLI Screenshots

Cisco IOS-XE:

R1# show ip arp
Protocol  Address       Age  Hardware Addr   Type   Interface
Internet 192.168.50.10   2   0050.56c0.0008  ARPA   Gig1/0/1

Arista EOS:

R2# show ip arp
Address          Age  MAC              Interface
192.168.50.10    1    0050.56c0.0008   Ethernet1

Palo Alto PAN‑OS:

> show arp all
Address        MAC              Interface
192.168.50.10  00:50:56:c0:00:08 ethernet1/1

FortiGate FortiOS:

# execute arp list
Address          Hardware Addr    Interface
192.168.50.10    00:50:56:c0:00:08 port1

FAQs

1: Why should I parse and normalize ARP tables using pyATS instead of just reading raw CLI output?

Answer:
Raw CLI outputs are vendor-specific and inconsistent. Each platform (Cisco, Arista, Palo Alto, Fortinet) formats ARP outputs differently, which complicates automation and correlation. Parsing with pyATS transforms this output into a consistent Python dictionary format, allowing you to standardize ARP table data, automate device reachability checks, build correlation maps, and integrate into CI pipelines without manually adjusting for each vendor’s output format.


2: What does “normalizing ARP data” mean in a vendor-agnostic context?

Answer:
Normalization refers to converting diverse outputs from different platforms into a uniform schema. For example, a Cisco device might display MACs in aaaa.bbbb.cccc format while Arista might use AA:BB:CC:DD:EE:FF. Using pyATS and Genie parsers, you can normalize:

  • MAC address formats
  • Interface naming conventions
  • VLAN IDs or interface zones
    This ensures your ARP tables across all vendors follow the same structure, making it easier to build vendor-agnostic scripts and dashboards.

3: What pyATS command is used to parse the ARP table of a device?

Answer:
The most commonly used method is:

parsed_arp = device.parse('show ip arp')

This uses the built-in Genie parser to convert the ARP CLI output into a Python dictionary. For non-Cisco platforms, you can use:

parsed_arp = device.parse('show arp')  # Works on Arista, Palo Alto

In some cases, you might need to create a custom parser for Fortinet or legacy platforms if no built-in parser is available.


4: How can I verify if the parser worked correctly or failed?

Answer:
Use structured error handling around your parser call:

try:
    arp_table = device.parse('show ip arp')
except SchemaEmptyParserError:
    print("ARP table is empty or not returned correctly.")
except Exception as e:
    print(f"Parsing failed: {str(e)}")

You can also print the dictionary structure and verify keys like 'interfaces', 'mac_address', 'ip', 'age', etc., to confirm the data is parsed correctly.


5: How can I use the parsed ARP table data in real-world operations?

Answer:
Parsed and normalized ARP data can be used to:

  • Validate L2-L3 neighbor connectivity
  • Build IP-to-MAC-to-interface mappings
  • Detect IP duplication or spoofing
  • Feed into ping test automation (ping each ARP IP)
  • Integrate with inventory or IPAM systems
  • Run diff against historical ARP data to detect anomalies

6: Is the parsing process the same across Cisco, Arista, Fortinet, and Palo Alto?

Answer:
The parsing logic in your Python script remains the same, but the command syntax and parser availability vary by vendor:

  • Cisco: show ip arp (well-supported by Genie)
  • Arista: show arp (supported via EOS Genie plugins)
  • Palo Alto: CLI commands like show arp all or XML API (might need custom parser)
  • Fortinet: ARP table parsing may require REST API or CLI with regular expression pre-processing

So, yes, the methodology is unified, but you may need vendor-specific adjustments to handle edge cases or unsupported features.


7: Can I extend Genie to parse unsupported ARP outputs?

Answer:
Absolutely. pyATS allows you to write your own custom parsers if your device or command is not supported. You can subclass from genie.metaparser.MetaParser, define your schema using Schema classes, and implement your own regex logic in the cli() method. This is particularly useful for Palo Alto and Fortinet platforms where built-in support might be limited.

Once registered, your parser integrates seamlessly with the device.parse() method—maintaining vendor-agnostic compatibility across your scripts.


YouTube Link

Watch the Complete Python for Network Engineer: Parsing and Normalizing ARP Tables (Multi-Vendor) using pyATS (Vendor-Agnostic) [Python for Network Engineer] Lab Demo & Explanation on our channel:

Master Python Network Automation, Ansible, REST API & Cisco DevNet
Master Python Network Automation, Ansible, REST API & Cisco DevNet
Master Python Network Automation, Ansible, REST API & Cisco DevNet
Why Robot Framework for Network Automation?

Join Our Training

Want to master pyATS, Genie, Netmiko, Ansible, APIs, and multi-vendor automation from scratch?

Trainer Sagar Dhawan is conducting a 3-month, instructor-led program designed for Network Engineers who want to transition into automation confidently.

Our curriculum blends:

  • Python for Network Engineer
  • Real-world use cases (Cisco/Arista/Fortinet/Palo Alto)
  • pyATS + Genie Labs
  • CI/CD Integration
  • APIs and Data Models

View Course Outline → https://course.networkjourney.com/python-ansible-api-cisco-devnet-for-network-engineers/

Enroll Now & Future‑Proof Your Career
Emailinfo@networkjourney.com
WhatsApp / Call: +91 97395 21088

Seats are limited. Secure yours today and transform your automation journey.