How to Programmatically Map an Internal IP Address to a Specific Switch Port Using Network APIs


2 views

When debugging network issues or implementing security controls, administrators often need to physically locate devices based on their IP addresses. Traditional methods like DNS lookups (nslookup) might not suffice when dealing with:

  • DHCP-assigned dynamic IPs
  • Devices with multiple network interfaces
  • Virtual machines with floating IPs
  • BYOD devices without proper DNS registration

Modern managed switches maintain several data structures that can help:

# Cisco IOS example of CAM table (MAC address table)
show mac address-table | include 00:1a:2b:3c:4d

The critical data flows are:

  1. ARP cache → MAC address
  2. Switch CAM table → switch port
  3. LLDP/CDP → physical location

Here's a sample script using Netmiko for Cisco devices:

from netmiko import ConnectHandler

def find_port_by_ip(switch_ip, target_ip):
    device = {
        'device_type': 'cisco_ios',
        'host': switch_ip,
        'username': 'admin',
        'password': 'secret'
    }
    
    try:
        connection = ConnectHandler(**device)
        
        # Get ARP entry to find MAC
        arp_output = connection.send_command(f"show ip arp {target_ip}")
        mac_address = arp_output.split()[3]
        
        # Find port for MAC
        mac_table = connection.send_command(f"show mac address-table address {mac_address}")
        port = mac_table.splitlines()[-1].split()[-1]
        
        return port
        
    except Exception as e:
        print(f"Error: {str(e)}")
    finally:
        if connection:
            connection.disconnect()

For environments with network controllers:

  • REST API approach (Cisco DNA Center example):
import requests

def dna_center_lookup(ip):
    url = "https://dnac.example.com/api/v1/host"
    headers = {
        "X-Auth-Token": "your_token_here",
        "Content-Type": "application/json"
    }
    params = {"hostIp": ip}
    
    response = requests.get(url, headers=headers, params=params)
    return response.json()['response']['portId']
Issue Solution
MAC address not in first-hop switch Trace through multiple switches using LLDP neighbors
Virtualized environments Check hypervisor vSwitch port mappings
Wireless clients Use controller API or RADIUS accounting logs

For large deployments consider:

  • Network Access Control (NAC) systems
  • IPAM integrations with switch APIs
  • SDN controller-based solutions

In enterprise networks, identifying the physical location of a device from its IP address requires interfacing with network infrastructure through various protocols. The process typically involves querying switch forwarding tables and correlating MAC addresses with IP assignments.

Modern network equipment exposes several interfaces for this purpose:

1. SNMP (Simple Network Management Protocol)
2. LLDP (Link Layer Discovery Protocol) 
3. REST APIs on modern switches
4. NetFlow/sFlow data analysis

Here's a Python example using PySNMP to query a Cisco switch:

from pysnmp.hlapi import *

def get_port_from_ip(target_ip):
    iterator = getCmd(
        SnmpEngine(),
        CommunityData('public'),
        UdpTransportTarget(('switch.example.com', 161)),
        ContextData(),
        ObjectType(ObjectIdentity('IP-MIB', 'ipNetToMediaNetAddress', target_ip))
    )

    errorIndication, errorStatus, errorIndex, varBinds = next(iterator)
    
    if errorIndication:
        print(errorIndication)
    elif errorStatus:
        print('%s at %s' % (errorStatus.prettyPrint(),
                            errorIndex and varBinds[int(errorIndex)-1][0] or '?'))
    else:
        for varBind in varBinds:
            print(' = '.join([x.prettyPrint() for x in varBind]))

For more modern networks using LLDP:

import requests

headers = {
    'Content-Type': 'application/json',
    'X-Auth-Token': 'your_api_key'
}

response = requests.get(
    'https://switch-api.example.com/api/v1/lldp/neighbors',
    headers=headers, 
    verify=False
)

neighbors = response.json()
for neighbor in neighbors:
    if neighbor['ipAddress'] == target_ip:
        print(f"Found IP {target_ip} on port {neighbor['localPort']}")

In distributed environments, you'll need to:

  • Cache ARP tables from multiple switches
  • Handle VLAN segmentation properly
  • Account for wireless clients and VPN connections
  • Manage different vendor syntax (Cisco vs Juniper vs Aruba)

For production environments, consider integrating with:

- Cisco DNA Center
- Aruba ClearPass
- SolarWinds Network Topology Mapper
- Custom solutions using NetBox API