Me on GitHub

Here is a description of a few of the more interesting projects I have on GitHub:


The idea here was to generate a complete configuration for a Cisco switch deployed as an enterprise distribution switch. It was written with a Catalyst switch in mind, hence the name of the repository.

The complete configuration generated covers:

  • device configurations (boot image, hostname, HA)
  • logging (syslog)
  • AAA
  • SSH access
  • Layer 2 (VTP, VLANs, Spanning Tree, Port-channels)
  • Layer 3 (VLAN interfaces (SVIs), HSRP, Loopback interfaces, OSPF)
  • Netflow
  • QoS

All parameters come from YAML files.

Note that the code in the repository only generates the configuration as a text file – it doesn’t actually push the configuration out to the device.


Interface lists like “Gi2/1-8,Te1/1-4” and VLAN lists like “11-20,4001-4095” are commonly encountered when configuring network devices. For example, I have this in my ansible-catalyst repository:

# Layer-2 port channel downlinks to access layer
  - hostname: nyc-bldg03-4th-floor
      - pc_number: 1
        description: acc-sw-tyk-04
        pc_mode: active
        layer2_mode: trunk
        allowed_vlans: '3-250'
        members: 'Gi1/1-2,Gi5/1-2'

where we’re saying that interfaces Gi1/1, Gi1/2, Gi5/1 and Gi5/2 are in port-channel 1, and the port-channel carries VLAN IDs 3 through 250.

So I needed an Ansible lookup plugin that takes a string like “Gi2/1-8,Te1/1-4” and produces a list:


Here is the reddit thread where I announced this plugin to the world:


Demonstrates how to perform a specific network modification using different Network Automation techniques. This is the code repository that accompanies my article on Network Automation.

The code performs a simple task (creating a VLAN and associated configurations (IPv4 subnet, Layer 3 interface, OSPF)) using different automation tools/approaches: Netmiko, NTCONF/YANG, Chef, Puppet and Ansible.


One of my clients owned a handful of devices that weren’t capable of DHCP client functionality – these were simple embedded devices running some rudimentary IP stack that only supported static IP addresses. But this site had a Layer 8 issue: there was no real network administrator who I could talk to for setting aside a few DHCP reservations for these devices.

This situation was blocking me from doing what I was actually hired to do, so I wrote this horrible hack: a program that runs on a Linux machine and asks for DHCP leases “on behalf of” other devices. So I run the program, say, five times with five different MAC addresses, and the server gives me five different IP addresses, which I then assign to my dumb embedded devices.

Like I said, this is a horrible hack and many, many things could go wrong with it. Still, it did let me move forward with my work, and chances are that there are people out there who may run into a similar situation as I did.


Some random recipes for configuring Cisco IOS-XE devices using NETCONF/YANG. Well, OK, there’s just the one recipe in there – adding a new VLAN, pretty much what I did in the NETCONF section of the network-automation-demos repo.


Someone on reddit was looking for a way to take a PCAP, identify interesting packets, and then extract some interesting fields from each packet and put them into a CSV file.

So I wrote this as a demonstration. I was mildly surprised to see more than a few people interested in this, going by the stars.


To test the hosts3d program that I helped fix, I needed a way to create a PCAP that contained hundreds of TCP streams between several hosts, all starting at different times, and all transferring data at various rates. This repository contains a Python program that does this.

It can be used, for example, to test a NetFlow source and/or collector.

The user specifies the stream characteristics using a Python list like this:

stream_specs = (
    {'name' : 'Stream A',
     'server_ip' : '',
     'client_ip' : '',
     'server_mac' : '00:00:0c:01:01:14',
     'client_mac' : '00:00:0c:01:01:11',
     'server_port' : 80,
     'client_port' : 1050,
     'rate_bps' : 30 * 1000,
     'packet_length' : 1400,
     'duration' : 300,
     'start_at' : 0},

    {'name' : 'Stream B',
     'server_ip' : '',
     'client_ip' : '',
     'server_mac' : '00:00:0c:01:01:15',
     'client_mac' : '00:00:0c:01:01:13',
     'server_port' : 80,
     'client_port' : 1051,
     'rate_bps' : 1 * 1000 * 1000,
     'packet_length' : 580,
     'duration' : 120 - 10,
     'start_at' : 10},


If you’re a Linux desktop user, you probably know that you can record screencasts using the FFmpeg program. I wrote a wrapper in Python that takes care of invoking FFmpeg with the correct arguments, including the (topleft, bottomright) area of the screen to record.

I used screencast-wrapper to make a screencast video of how to use screencast-wrapper 🙂 Yeah, basically a screencast recording of me making a screencast recording.