Overview
Network devices form the physical infrastructure that enables communication between computing systems. Routers, switches, and hubs operate at different network layers and serve distinct purposes in managing data transmission. Understanding these devices is essential for software developers working on distributed systems, network automation, infrastructure management, and applications that interact with network hardware.
A router operates at Layer 3 (Network Layer) and forwards packets between different networks based on IP addresses. Routers make intelligent decisions about the best path for data to reach its destination, handling traffic between separate network segments or connecting local networks to the internet.
A switch operates at Layer 2 (Data Link Layer) and forwards frames within a single network based on MAC addresses. Switches create dedicated paths between devices, enabling efficient communication within a local area network without the collision problems inherent in shared media.
A hub operates at Layer 1 (Physical Layer) and broadcasts all incoming data to every connected port. Hubs lack intelligence about where data should go, creating a shared collision domain where only one device can transmit at a time. Modern networks rarely use hubs due to their inefficiency.
Software developers interact with these devices through various protocols and APIs. Network management requires understanding device capabilities, configuration methods, and monitoring approaches. Applications that need to control or monitor network infrastructure must account for device-specific behaviors and limitations.
# Example: Basic network device information structure
class NetworkDevice
attr_reader :ip_address, :mac_address, :device_type, :hostname
def initialize(ip:, mac:, type:, hostname:)
@ip_address = ip
@mac_address = mac
@device_type = type
@hostname = hostname
end
def layer
case device_type
when :hub then 1
when :switch then 2
when :router then 3
end
end
end
router = NetworkDevice.new(
ip: '192.168.1.1',
mac: '00:1A:2B:3C:4D:5E',
type: :router,
hostname: 'gateway-01'
)
# => #<NetworkDevice @device_type=:router, @layer=3>
Key Principles
Network devices operate according to fundamental networking principles that determine how they process and forward traffic. Each device type has specific characteristics that define its behavior and appropriate use cases.
Layer-Based Operation: Network devices function at specific OSI model layers. Layer 1 devices (hubs) work with electrical signals and bits. Layer 2 devices (switches) work with frames and MAC addresses. Layer 3 devices (routers) work with packets and IP addresses. This layered approach determines what information a device uses to make forwarding decisions.
Collision Domains and Broadcast Domains: A collision domain is a network segment where data packets can collide during transmission. Hubs create a single large collision domain for all connected devices. Switches create separate collision domains for each port, eliminating collisions. Broadcast domains contain all devices that receive broadcast traffic. Switches forward broadcasts to all ports within a VLAN, while routers block broadcasts between networks.
MAC Address Learning: Switches build forwarding tables by observing source MAC addresses in received frames. When a frame arrives, the switch records which port received it and associates that port with the source MAC address. This learning process creates a map of which devices connect to which ports, enabling efficient frame forwarding without broadcasting.
Routing Tables and Path Selection: Routers maintain routing tables that map destination networks to next-hop addresses or outgoing interfaces. Routing protocols like OSPF, BGP, and RIP populate these tables automatically, or administrators configure static routes manually. When a packet arrives, the router examines the destination IP address and consults the routing table to determine the best forwarding path.
Store-and-Forward vs Cut-Through: Switches use different forwarding methods. Store-and-forward switches receive the entire frame, check for errors, then forward it. This method ensures error-free transmission but adds latency. Cut-through switches begin forwarding as soon as they read the destination MAC address, reducing latency but potentially propagating corrupted frames.
Network Address Translation (NAT): Routers perform NAT to allow multiple devices with private IP addresses to share a single public IP address. NAT modifies packet headers as traffic passes through the router, translating between private and public address spaces. This function is essential for IPv4 address conservation and network security.
Spanning Tree Protocol: Networks with multiple switches can create loops where traffic circulates indefinitely. The Spanning Tree Protocol (STP) prevents loops by logically blocking redundant paths while maintaining backup routes. If the active path fails, STP activates a backup path to restore connectivity.
Quality of Service (QoS): Network devices prioritize different types of traffic to ensure critical applications receive necessary bandwidth and low latency. QoS mechanisms include traffic classification, queueing, and policing. Routers and managed switches implement QoS policies to differentiate between voice, video, and data traffic.
Implementation Approaches
Managing network devices requires different strategies depending on scale, automation requirements, and infrastructure complexity. Each approach offers specific advantages for different operational contexts.
Command-Line Interface Management: Network devices expose CLI interfaces through SSH or Telnet connections. Administrators send text commands to configure interfaces, routing protocols, VLANs, and security policies. This approach provides direct control and works universally across vendors, though it requires parsing text output and lacks standardization across different platforms.
# Conceptual CLI interaction pattern
require 'net/ssh'
class DeviceCLI
def initialize(host, username, password)
@host = host
@username = username
@password = password
end
def execute_command(command)
output = ""
Net::SSH.start(@host, @username, password: @password) do |ssh|
output = ssh.exec!(command)
end
output
end
def get_interface_status
output = execute_command("show interface status")
parse_interface_output(output)
end
private
def parse_interface_output(text)
# Parse device-specific text output
interfaces = []
text.each_line do |line|
if line =~ /^(\w+\d+\/\d+)\s+(\w+)/
interfaces << { name: $1, status: $2 }
end
end
interfaces
end
end
SNMP Monitoring and Configuration: Simple Network Management Protocol provides standardized access to device metrics and configuration. SNMP uses a management information base (MIB) that defines available data objects. Network monitoring systems poll devices for statistics like interface utilization, error rates, and CPU load. SNMP traps send alerts when specific conditions occur.
REST API Integration: Modern network devices offer RESTful APIs that return structured JSON or XML data. API-based management eliminates text parsing complexity and provides programmatic access to all device features. This approach scales well for automation and integrates naturally with modern orchestration systems.
# REST API interaction pattern
require 'net/http'
require 'json'
class DeviceAPI
def initialize(base_url, api_token)
@base_url = base_url
@api_token = api_token
end
def get_interfaces
uri = URI("#{@base_url}/api/v1/interfaces")
request = Net::HTTP::Get.new(uri)
request['Authorization'] = "Bearer #{@api_token}"
request['Content-Type'] = 'application/json'
response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
http.request(request)
end
JSON.parse(response.body)
end
def configure_interface(interface_name, config)
uri = URI("#{@base_url}/api/v1/interfaces/#{interface_name}")
request = Net::HTTP::Put.new(uri)
request['Authorization'] = "Bearer #{@api_token}"
request['Content-Type'] = 'application/json'
request.body = config.to_json
response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
http.request(request)
end
response.code == '200'
end
end
api = DeviceAPI.new('https://router.example.com', 'token123')
interfaces = api.get_interfaces
# => [{"name"=>"eth0", "status"=>"up", "speed"=>"1000"}]
Network Configuration Management Systems: Dedicated configuration management tools like Ansible, Puppet, and Chef provide declarative approaches to device management. These systems define desired states rather than imperative commands, handle idempotency, and maintain configuration version control. They abstract vendor-specific differences through modules and plugins.
Controller-Based SDN Approaches: Software-Defined Networking separates the control plane from the data plane. Centralized controllers make routing and forwarding decisions, pushing flow rules to network devices. SDN enables dynamic network reconfiguration, traffic engineering, and programmatic network control through northbound APIs.
Ruby Implementation
Ruby applications interact with network devices through various gems and libraries that abstract protocol complexity. Different gems target specific use cases from simple SNMP polling to comprehensive device automation.
SNMP Operations: The snmp gem provides Ruby bindings for SNMP operations. Applications can retrieve device metrics, monitor interface statistics, and receive trap notifications. SNMP v2c uses community strings for authentication, while SNMP v3 adds encryption and user-based security.
require 'snmp'
class NetworkMonitor
def initialize(host, community = 'public')
@host = host
@community = community
end
def get_system_info
SNMP::Manager.open(host: @host, community: @community) do |manager|
response = manager.get([
'sysDescr.0',
'sysUpTime.0',
'sysName.0'
])
response.each_varbind do |vb|
puts "#{vb.name}: #{vb.value}"
end
end
end
def get_interface_stats(interface_index)
SNMP::Manager.open(host: @host, community: @community) do |manager|
response = manager.get([
"ifDescr.#{interface_index}",
"ifInOctets.#{interface_index}",
"ifOutOctets.#{interface_index}",
"ifSpeed.#{interface_index}"
])
stats = {}
response.each_varbind do |vb|
oid_parts = vb.name.to_s.split('.')
metric = oid_parts[0]
stats[metric] = vb.value.to_s
end
stats
end
end
def walk_interface_table
interfaces = []
SNMP::Manager.open(host: @host, community: @community) do |manager|
manager.walk('ifDescr') do |row|
row.each do |vb|
index = vb.name.to_s.split('.').last
interfaces << {
index: index,
description: vb.value.to_s
}
end
end
end
interfaces
end
end
monitor = NetworkMonitor.new('192.168.1.1')
stats = monitor.get_interface_stats(1)
# => {"ifDescr"=>"eth0", "ifInOctets"=>"12345678", ...}
SSH-Based Configuration: The net-ssh gem enables Ruby applications to establish SSH connections and execute commands on network devices. Applications send configuration commands, retrieve output, and parse responses. This approach works with any device supporting SSH regardless of vendor.
require 'net/ssh'
class RouterConfig
def initialize(host, username, password)
@host = host
@username = username
@password = password
end
def configure_interface(interface, ip_address, subnet_mask)
commands = [
"configure terminal",
"interface #{interface}",
"ip address #{ip_address} #{subnet_mask}",
"no shutdown",
"end",
"write memory"
]
output = execute_commands(commands)
output.include?("Building configuration")
end
def add_static_route(network, mask, next_hop)
commands = [
"configure terminal",
"ip route #{network} #{mask} #{next_hop}",
"end",
"write memory"
]
execute_commands(commands)
end
def get_running_config
execute_command("show running-config")
end
private
def execute_commands(command_list)
full_output = ""
Net::SSH.start(@host, @username, password: @password) do |ssh|
command_list.each do |cmd|
output = ssh.exec!(cmd)
full_output += output
end
end
full_output
end
def execute_command(command)
Net::SSH.start(@host, @username, password: @password) do |ssh|
ssh.exec!(command)
end
end
end
router = RouterConfig.new('192.168.1.1', 'admin', 'password')
router.configure_interface('GigabitEthernet0/1', '10.0.1.1', '255.255.255.0')
router.add_static_route('10.0.2.0', '255.255.255.0', '10.0.1.254')
HTTP API Clients: Network devices with REST APIs accept HTTP requests with JSON payloads. Ruby's net/http library or gems like httparty and faraday simplify API interactions. Applications authenticate with tokens or certificates, send configuration changes, and receive structured responses.
require 'httparty'
class SwitchAPI
include HTTParty
base_uri 'https://switch.example.com/api'
def initialize(api_key)
@options = {
headers: {
'Authorization' => "Bearer #{api_key}",
'Content-Type' => 'application/json'
},
verify: false # For testing only - verify certs in production
}
end
def create_vlan(vlan_id, name)
body = {
vlan_id: vlan_id,
name: name
}.to_json
response = self.class.post('/vlans', @options.merge(body: body))
response.success?
end
def assign_vlan_to_port(port, vlan_id)
body = {
access_vlan: vlan_id,
mode: 'access'
}.to_json
response = self.class.put("/interfaces/#{port}", @options.merge(body: body))
response.success?
end
def get_port_statistics(port)
response = self.class.get("/interfaces/#{port}/statistics", @options)
if response.success?
JSON.parse(response.body)
else
nil
end
end
def get_mac_address_table
response = self.class.get('/mac-address-table', @options)
if response.success?
JSON.parse(response.body)
else
[]
end
end
end
switch = SwitchAPI.new('api-key-here')
switch.create_vlan(100, 'Production')
switch.assign_vlan_to_port('eth1/0/1', 100)
stats = switch.get_port_statistics('eth1/0/1')
# => {"rx_bytes"=>123456, "tx_bytes"=>789012, ...}
Device Discovery and Scanning: Ruby applications can discover network devices through ARP table examination, LLDP protocol parsing, or active scanning. The ruby-nmap gem wraps the nmap network scanner for device discovery and port scanning.
require 'nmap/command'
class NetworkDiscovery
def initialize(subnet)
@subnet = subnet
end
def discover_devices
devices = []
Nmap::Command.run do |nmap|
nmap.targets = @subnet
nmap.verbose = false
nmap.xml = 'scan_results.xml'
nmap.each_host do |host|
devices << {
ip: host.ip,
hostname: host.hostname,
status: host.status,
ports: extract_ports(host)
}
end
end
devices
end
def identify_network_devices(devices)
devices.select do |device|
# Common network device ports
has_network_ports = device[:ports].any? do |port|
[22, 23, 80, 443, 161, 830].include?(port[:number])
end
has_network_ports
end
end
private
def extract_ports(host)
ports = []
host.each_port do |port|
ports << {
number: port.number,
protocol: port.protocol,
state: port.state,
service: port.service
}
end
ports
end
end
discovery = NetworkDiscovery.new('192.168.1.0/24')
all_devices = discovery.discover_devices
network_devices = discovery.identify_network_devices(all_devices)
# => [{ip: "192.168.1.1", hostname: "router.local", ...}]
Practical Examples
Network device interaction patterns vary based on operational requirements. These examples demonstrate common scenarios developers encounter when building network automation or monitoring systems.
Monitoring Interface Status: Applications periodically check interface operational status to detect failures or degradation. This pattern collects statistics, identifies anomalies, and triggers alerts when thresholds exceed acceptable values.
class InterfaceMonitor
def initialize(device)
@device = device
@baseline = {}
end
def establish_baseline
stats = @device.get_all_interfaces
stats.each do |interface|
@baseline[interface[:name]] = {
rx_rate: interface[:rx_bytes_per_sec],
tx_rate: interface[:tx_bytes_per_sec],
errors: interface[:errors],
drops: interface[:drops]
}
end
end
def check_for_anomalies
current = @device.get_all_interfaces
anomalies = []
current.each do |interface|
name = interface[:name]
baseline = @baseline[name]
next unless baseline
# Check for elevated error rates
if interface[:errors] > baseline[:errors] * 2
anomalies << {
interface: name,
type: :error_rate,
baseline: baseline[:errors],
current: interface[:errors]
}
end
# Check for unexpected utilization drops
if interface[:rx_rate] < baseline[:rx_rate] * 0.5 && baseline[:rx_rate] > 1000
anomalies << {
interface: name,
type: :utilization_drop,
baseline: baseline[:rx_rate],
current: interface[:rx_rate]
}
end
# Check for link status changes
if interface[:status] == 'down' && baseline[:status] == 'up'
anomalies << {
interface: name,
type: :link_down,
message: "Interface went down"
}
end
end
anomalies
end
def generate_alert(anomalies)
return if anomalies.empty?
anomalies.each do |anomaly|
puts "ALERT: #{anomaly[:interface]} - #{anomaly[:type]}"
puts " Details: #{anomaly}"
end
end
end
Automated VLAN Provisioning: Networks with dynamic requirements need programmatic VLAN creation and assignment. This pattern creates VLANs, assigns ports, and configures trunking across multiple switches.
class VLANProvisioner
def initialize(switches)
@switches = switches
end
def provision_vlan(vlan_id, vlan_name, access_ports, trunk_ports)
results = []
@switches.each do |switch|
result = {
switch: switch.hostname,
vlan_created: false,
access_ports_configured: [],
trunk_ports_configured: []
}
# Create VLAN on switch
if switch.create_vlan(vlan_id, vlan_name)
result[:vlan_created] = true
end
# Configure access ports
access_ports.each do |port|
if switch.configure_access_port(port, vlan_id)
result[:access_ports_configured] << port
end
end
# Configure trunk ports to carry this VLAN
trunk_ports.each do |port|
if switch.add_vlan_to_trunk(port, vlan_id)
result[:trunk_ports_configured] << port
end
end
results << result
end
results
end
def deprovision_vlan(vlan_id)
@switches.each do |switch|
# Remove VLAN from all trunk ports first
switch.get_trunk_ports.each do |port|
switch.remove_vlan_from_trunk(port, vlan_id)
end
# Remove access port assignments
switch.get_ports_by_vlan(vlan_id).each do |port|
switch.configure_access_port(port, 1) # Move to default VLAN
end
# Delete VLAN
switch.delete_vlan(vlan_id)
end
end
def verify_vlan_consistency(vlan_id)
inconsistencies = []
vlan_configs = @switches.map do |switch|
{
switch: switch.hostname,
vlan_exists: switch.vlan_exists?(vlan_id),
access_ports: switch.get_ports_by_vlan(vlan_id),
trunk_ports: switch.get_trunk_ports_with_vlan(vlan_id)
}
end
# Check if VLAN exists on all switches
missing_vlan = vlan_configs.select { |config| !config[:vlan_exists] }
if missing_vlan.any?
inconsistencies << {
type: :missing_vlan,
switches: missing_vlan.map { |c| c[:switch] }
}
end
# Check for orphaned access ports (VLAN on one switch but not others)
vlan_configs.each do |config|
if config[:access_ports].any? && !config[:vlan_exists]
inconsistencies << {
type: :orphaned_ports,
switch: config[:switch],
ports: config[:access_ports]
}
end
end
inconsistencies
end
end
Router Failover Detection: Applications monitor router availability and routing table changes to detect failover events. This pattern tracks active routes, identifies when backup paths activate, and measures convergence time.
class RouterFailoverMonitor
def initialize(primary_router, backup_router)
@primary = primary_router
@backup = backup_router
@state = :primary_active
@failover_events = []
end
def check_router_state
primary_up = router_reachable?(@primary)
backup_up = router_reachable?(@backup)
new_state = determine_state(primary_up, backup_up)
if new_state != @state
record_state_change(@state, new_state)
@state = new_state
end
@state
end
def verify_routing_convergence(destination_network)
primary_route = @primary.get_route(destination_network)
backup_route = @backup.get_route(destination_network)
{
primary: {
reachable: !primary_route.nil?,
next_hop: primary_route&.next_hop,
metric: primary_route&.metric
},
backup: {
reachable: !backup_route.nil?,
next_hop: backup_route&.next_hop,
metric: backup_route&.metric
},
converged: routes_match?(primary_route, backup_route)
}
end
def measure_failover_time(test_interval = 1)
start_time = Time.now
# Force primary router down (in test environment)
simulate_failure(@primary)
# Wait for backup to converge
until backup_has_route?
sleep test_interval
break if (Time.now - start_time) > 60 # Timeout after 60 seconds
end
convergence_time = Time.now - start_time
{
convergence_time: convergence_time,
within_target: convergence_time < 10, # Target: 10 seconds
events: @failover_events
}
end
private
def router_reachable?(router)
system("ping -c 1 -W 1 #{router.ip_address} > /dev/null 2>&1")
end
def determine_state(primary_up, backup_up)
case [primary_up, backup_up]
when [true, true] then :both_active
when [true, false] then :primary_active
when [false, true] then :backup_active
when [false, false] then :both_down
end
end
def record_state_change(old_state, new_state)
@failover_events << {
timestamp: Time.now,
from: old_state,
to: new_state
}
end
def routes_match?(route1, route2)
return false if route1.nil? || route2.nil?
route1.next_hop == route2.next_hop
end
def backup_has_route?
@backup.get_default_route&.active?
end
end
MAC Address Table Management: Switches maintain MAC address tables that map hardware addresses to physical ports. Applications query these tables for device location tracking, security monitoring, and troubleshooting.
class MACTableAnalyzer
def initialize(switch)
@switch = switch
end
def find_device_location(mac_address)
mac_table = @switch.get_mac_table
entry = mac_table.find { |e| e[:mac] == mac_address }
return nil unless entry
{
mac_address: entry[:mac],
port: entry[:port],
vlan: entry[:vlan],
type: entry[:type], # dynamic or static
last_seen: entry[:age]
}
end
def detect_mac_flapping
# MAC flapping occurs when same MAC appears on multiple ports
mac_table = @switch.get_mac_table
mac_by_port = Hash.new { |h, k| h[k] = [] }
mac_table.each do |entry|
mac_by_port[entry[:mac]] << entry[:port]
end
flapping = mac_by_port.select { |mac, ports| ports.uniq.length > 1 }
flapping.map do |mac, ports|
{
mac_address: mac,
ports: ports.uniq,
likely_cause: diagnose_flapping(ports.uniq)
}
end
end
def identify_security_violations(authorized_macs)
mac_table = @switch.get_mac_table
unauthorized = mac_table.reject do |entry|
authorized_macs.include?(entry[:mac])
end
unauthorized.map do |entry|
{
mac_address: entry[:mac],
port: entry[:port],
vlan: entry[:vlan],
first_seen: entry[:age],
risk_level: assess_risk(entry)
}
end
end
def track_device_mobility(mac_address, interval = 60)
locations = []
loop do
location = find_device_location(mac_address)
if location
locations << {
timestamp: Time.now,
port: location[:port],
vlan: location[:vlan]
}
# Check if device moved
if locations.length > 1
previous = locations[-2]
current = locations[-1]
if previous[:port] != current[:port]
puts "Device moved: #{previous[:port]} -> #{current[:port]}"
end
end
end
sleep interval
end
end
private
def diagnose_flapping(ports)
if ports.length == 2
:possible_loop
elsif ports.length > 2
:spanning_tree_issue
else
:unknown
end
end
def assess_risk(entry)
# Example risk assessment logic
if entry[:vlan] == 1 # Default VLAN
:medium
elsif entry[:port].start_with?('Gig') # Trunk port
:high
else
:low
end
end
end
Tools & Ecosystem
Network device management requires specialized tools and libraries that handle protocol complexity and vendor-specific behaviors. The Ruby ecosystem provides gems for various network management tasks.
SNMP Libraries: The snmp gem implements SNMP v1, v2c, and v3 protocols. It provides synchronous and asynchronous operations, bulk requests, and trap handling. Applications use SNMP for monitoring, threshold-based alerting, and metric collection.
# Advanced SNMP monitoring with bulk requests
require 'snmp'
class SNMPBulkMonitor
def initialize(hosts, community)
@hosts = hosts
@community = community
end
def bulk_collect_interface_stats
results = {}
@hosts.each do |host|
SNMP::Manager.open(host: host, community: @community) do |manager|
# Bulk request for efficiency
response = manager.get_bulk(0, 10, [
'ifDescr',
'ifInOctets',
'ifOutOctets',
'ifInErrors',
'ifOutErrors'
])
results[host] = process_bulk_response(response)
end
end
results
end
private
def process_bulk_response(response)
interfaces = Hash.new { |h, k| h[k] = {} }
response.each_varbind do |vb|
oid_parts = vb.name.to_s.split('.')
metric_name = oid_parts[0]
interface_index = oid_parts[-1]
interfaces[interface_index][metric_name] = vb.value.to_s
end
interfaces
end
end
SSH and Telnet Libraries: Net::SSH handles encrypted connections to network devices. Net::Telnet provides fallback for older equipment without SSH support. These gems support interactive sessions, command execution, and output parsing.
REST API Clients: HTTParty and Faraday simplify HTTP API interactions. These gems handle authentication, request formatting, response parsing, and error handling. They support both synchronous and asynchronous operations.
Network Analysis Tools: PacketFu creates and parses network packets at the protocol level. RubyNetworkMap generates network topology diagrams from device data. These tools assist with network discovery and documentation.
Configuration Management Integration: Knife plugins for Chef and Ansible modules written in Ruby enable network device configuration through existing automation frameworks. These integrations apply configuration management principles to network infrastructure.
Monitoring and Alerting: The prometheus-client gem exports network metrics to Prometheus monitoring systems. Telegraf plugins written in Ruby collect device statistics and forward them to time-series databases.
Integration & Interoperability
Network devices integrate with software systems through standardized protocols and APIs. Applications must account for vendor differences, protocol limitations, and operational constraints.
Multi-Vendor Environments: Different manufacturers implement protocols differently. Cisco IOS, Juniper JunOS, and Arista EOS use distinct CLI syntaxes despite serving similar functions. Applications handle vendor variations through abstraction layers or device-specific adapters.
class DeviceFactory
def self.create(host, type, credentials)
case type
when :cisco
CiscoDevice.new(host, credentials)
when :juniper
JuniperDevice.new(host, credentials)
when :arista
AristaDevice.new(host, credentials)
else
GenericDevice.new(host, credentials)
end
end
end
class CiscoDevice
def configure_interface(interface, ip, mask)
commands = [
"configure terminal",
"interface #{interface}",
"ip address #{ip} #{mask}",
"no shutdown",
"end"
]
execute_commands(commands)
end
end
class JuniperDevice
def configure_interface(interface, ip, mask)
prefix_length = mask_to_prefix(mask)
commands = [
"configure",
"set interfaces #{interface} unit 0 family inet address #{ip}/#{prefix_length}",
"commit"
]
execute_commands(commands)
end
private
def mask_to_prefix(mask)
# Convert 255.255.255.0 to 24
mask.split('.').map(&:to_i).map { |o| o.to_s(2) }.join.count('1')
end
end
Protocol Translation: Applications convert between different management protocols. An API gateway might expose REST endpoints that translate to SNMP or CLI commands. This pattern enables modern applications to interact with legacy devices.
Event Stream Integration: Network devices generate events for link state changes, threshold violations, and security incidents. Applications consume these events through SNMP traps, syslog messages, or streaming telemetry APIs. Event processing systems correlate device events with application metrics for comprehensive monitoring.
Configuration Synchronization: Networks with redundant devices require configuration consistency. Applications maintain configuration repositories, detect drift, and reconcile differences. Version control systems track configuration changes and enable rollback.
Orchestration Integration: Container orchestration platforms like Kubernetes integrate with network devices for service mesh implementations and load balancing. SDN controllers receive service deployment events and configure network paths automatically.
Reference
Device Type Comparison
| Feature | Hub | Switch | Router |
|---|---|---|---|
| OSI Layer | 1 (Physical) | 2 (Data Link) | 3 (Network) |
| Forwarding Basis | None (broadcasts all) | MAC address | IP address |
| Collision Domains | Single shared domain | Per-port isolation | Separates networks |
| Broadcast Domains | Single domain | Single per VLAN | Separates domains |
| Intelligence | No decision-making | MAC learning | Routing decisions |
| Typical Use | Legacy/obsolete | LAN switching | Inter-network routing |
| Throughput | Limited by collision | Full duplex per port | Limited by routing |
Common Management Protocols
| Protocol | Port | Purpose | Authentication |
|---|---|---|---|
| SSH | 22 | Encrypted CLI access | Username/password, keys |
| Telnet | 23 | Unencrypted CLI access | Username/password |
| SNMP v2c | 161 | Monitoring/management | Community string |
| SNMP v3 | 161 | Secure monitoring | User-based, encrypted |
| HTTP/HTTPS | 80/443 | Web interface | Username/password, tokens |
| NETCONF | 830 | XML-based config | SSH-based auth |
| RESTCONF | 443 | RESTful config | HTTPS-based auth |
| Syslog | 514 | Event logging | None (UDP) |
Ruby Gem Reference
| Gem | Purpose | Key Features |
|---|---|---|
| snmp | SNMP protocol implementation | v1/v2c/v3, walks, traps |
| net-ssh | SSH client | Command execution, file transfer |
| net-telnet | Telnet client | Legacy device access |
| httparty | HTTP API client | REST API interaction |
| ruby-nmap | Network scanning | Device discovery |
| packetfu | Packet crafting | Protocol-level access |
Standard SNMP OIDs
| OID | Description | Type |
|---|---|---|
| 1.3.6.1.2.1.1.1.0 | sysDescr - System description | String |
| 1.3.6.1.2.1.1.3.0 | sysUpTime - System uptime | TimeTicks |
| 1.3.6.1.2.1.1.5.0 | sysName - System name | String |
| 1.3.6.1.2.1.2.2.1.2 | ifDescr - Interface description | String |
| 1.3.6.1.2.1.2.2.1.8 | ifOperStatus - Interface status | Integer |
| 1.3.6.1.2.1.2.2.1.10 | ifInOctets - Bytes received | Counter |
| 1.3.6.1.2.1.2.2.1.16 | ifOutOctets - Bytes transmitted | Counter |
| 1.3.6.1.2.1.2.2.1.14 | ifInErrors - Input errors | Counter |
Common Port Assignments
| Service | Port | Protocol | Purpose |
|---|---|---|---|
| FTP Data | 20 | TCP | File transfer data |
| FTP Control | 21 | TCP | File transfer commands |
| SSH | 22 | TCP | Secure shell |
| Telnet | 23 | TCP | Remote terminal |
| SMTP | 25 | TCP | Email transmission |
| DNS | 53 | TCP/UDP | Name resolution |
| HTTP | 80 | TCP | Web traffic |
| HTTPS | 443 | TCP | Secure web traffic |
| SNMP | 161 | UDP | Network management |
| SNMP Trap | 162 | UDP | SNMP notifications |
Router Configuration Checklist
| Task | Configuration Item | Verification Command |
|---|---|---|
| Hostname | Device identification | show running-config |
| Interfaces | IP addressing, masks | show ip interface brief |
| Routing | Static or dynamic routes | show ip route |
| NAT | Address translation | show ip nat translations |
| ACLs | Access control lists | show access-lists |
| DHCP | Address assignment | show ip dhcp binding |
| DNS | Name resolution | show hosts |
| Time | NTP synchronization | show ntp status |
Switch Configuration Checklist
| Task | Configuration Item | Verification Command |
|---|---|---|
| Hostname | Device identification | show running-config |
| VLANs | Virtual LAN creation | show vlan brief |
| Trunk Ports | Inter-switch links | show interfaces trunk |
| Access Ports | End device ports | show interfaces status |
| STP | Spanning tree | show spanning-tree |
| Port Security | MAC filtering | show port-security |
| SNMP | Monitoring access | show snmp |
| Management IP | Remote access | show ip interface |
Interface Status Values
| Status | Description | Typical Cause |
|---|---|---|
| up/up | Line and protocol up | Normal operation |
| up/down | Line up, protocol down | Layer 2 issue, encapsulation |
| down/down | Line and protocol down | Cable disconnected, shutdown |
| administratively down | Interface disabled | Manual shutdown |
| err-disabled | Error condition | Port security, BPDU guard |