Generate Cisco Packet Tracer 9 network topologies programmatically — from a Python script or an AI prompt.
No GUI. No manual dragging. Just describe your network, run the script, open the .pkt.
Cisco Packet Tracer saves topologies as encrypted, compressed XML (.pkt files). This toolkit reverse-engineers that format so you can:
- Generate complete, openable
.pktfiles from Python code - Define buildings, devices, and cables in plain code
- Inject real IOS/IOS-XE configs into devices at generation time
- Use it as a base for AI-driven network topology generation
Tested against Packet Tracer 9.0.0.0810.
PKT_Generator_V1.0/
├── generator_base.py ← main library (import from here)
├── pkt_tool.py ← encrypt/decrypt .pkt files
├── assets/
│ ├── components.xml ← PT9 device donor (all device types)
│ └── generic_shell.xml ← minimal PT9 document skeleton
├── README.md ← this file
├── AI_KNOWLEDGE_BASE.md ← deep technical reference for AI agents
├── PORT_NAMES.md ← empirically verified port names per device type
└── WORKFLOW.md ← step-by-step generation workflow
- Python 3.10+
- Standard library only (no pip installs)
- Cisco Packet Tracer 9 (to open the output)
cd PKT_Generator_V1.0
python3 generator_base.py
# → ../labs/example_two_buildings.pktOpen labs/example_two_buildings.pkt in Packet Tracer 9.
Create a script that imports from generator_base.py:
import sys
from pathlib import Path
sys.path.insert(0, str(Path(__file__).parent / "PKT_Generator_V1.0"))
from generator_base import PhysicalWorld, clone_device, set_physical, build_link, generate
# 1. Define physical world
world = PhysicalWorld()
world.add_city("Campus")
world.add_building("DataCenter", city="Campus")
world.add_building("BuildingA", city="Campus")
# 2. Clone devices (type, hostname, x, y, ios_config_lines)
router = clone_device("Router", "CoreRouter", "400", "200", [
"hostname CoreRouter",
"interface GigabitEthernet0/0/0",
" ip address 10.0.1.1 255.255.255.0",
" no shutdown",
"end",
])
switch = clone_device("Switch", "SW_A", "200", "350", None)
pc = clone_device("Pc", "PC_1", "100", "500", None)
# 3. Place devices in physical world
phys, pp = world.inject_rack("DataCenter", "CoreRouter"); set_physical(router["el"], phys, pp)
phys, pp = world.inject_rack("BuildingA", "SW_A"); set_physical(switch["el"], phys, pp)
phys, pp = world.inject_floor("BuildingA", "PC_1"); set_physical(pc["el"], phys, pp)
# 4. Wire cables
def wire(links_el):
build_link(links_el, router, "GigabitEthernet0/0/0", switch, "GigabitEthernet0/1")
build_link(links_el, switch, "FastEthernet0/1", pc, "FastEthernet0")
# 5. Generate
generate("labs/my_topology.pkt", [router, switch, pc], world, wire)dtype |
PT9 Model | Key Port Names |
|---|---|---|
Router |
PT8200 | GigabitEthernet0/0/0 … 0/0/3 |
Switch |
2960-24TT | FastEthernet0/1…0/24, GigabitEthernet0/1…0/2 |
Pc |
PC-PT | FastEthernet0 |
Laptop |
Laptop-PT | FastEthernet0 |
Server |
Server-PT | FastEthernet0 |
ISA |
ISA-3000 | GigabitEthernet1/1, GigabitEthernet1/2 (not 0/x) |
NetworkController |
WLC | GigabitEthernet0, GigabitEthernet1 |
WirelessEndDevice |
Access Point | Wireless0 |
MCUComponent |
IoT MCU | Wireless0 |
Cloud |
Cloud-PT-Empty | Port0 |
See PORT_NAMES.md for the full table with common mistakes called out.
Manages the physical workspace tree (buildings, rooms, racks).
world = PhysicalWorld()
world.add_city("CityName")
world.add_building("BuildingName", city="CityName")
phys, pp = world.inject_rack("BuildingName", "DeviceName") # router/switch/server
phys, pp = world.inject_floor("BuildingName", "DeviceName") # PC/laptop/AP/IoTClones a device from assets/components.xml, patches all unique IDs, and optionally injects IOS config.
Returns a dict: {"el": Element, "ref": save_ref_id, "mem": dev_addr, "name": name}
Writes WORKSPACE/PHYSICAL and WORKSPACE/PHYSICAL_CPUR into a device element. Always call after inject_rack or inject_floor.
Adds a copper straight-through cable between two devices. dev_a and dev_b are clone_device() result dicts.
Assembles the final XML, enforces the correct PT9 element order, and calls pkt_tool.py to produce the .pkt.
.pkt files are Twofish/EAX encrypted + zlib compressed XML. The encryption key is hardcoded in Packet Tracer itself. pkt_tool.py (included) handles both directions:
# Inspect any .pkt file
python3 pkt_tool.py decode -o output.xml input.pkt
# Re-encrypt after editing
python3 pkt_tool.py encode -o output.pkt input.xmlPT9 enforces strict schema validation on load — wrong element order, missing required fields, or incorrect port names cause silent rejection ("not compatible" or infinite loading). The generator handles all of this automatically.
If you are an AI being asked to generate a topology using this toolkit:
- Read
AI_KNOWLEDGE_BASE.md— it contains the full PT9 XML schema, ID generation rules, error table, and debugging strategy - Read
PORT_NAMES.md— verify every port name before wiring a cable - Use
generator_base.pyas-is — do not rewrite helper functions - Always call
inject_rack()orinject_floor()for every device, thenset_physical()immediately after - Never set
VERSIONto anything other than9.0.0.0810
| Symptom | Likely Cause | Fix |
|---|---|---|
| "corrupted Physical Workspace data" | UUID chain mismatch between PHYSICAL and PW tree |
Call set_physical() with the exact values returned by inject_rack/floor |
| File hangs on "Please wait. Opening file…" | Wrong node TYPE codes or missing geometry in PW | Use PhysicalWorld — do not build PHYSICALWORKSPACE manually |
| "not compatible with this version" | Wrong port name, or missing IS_MANAGED_IN_RACK_VIEW / second TYPE in cable |
Check PORT_NAMES.md; use build_link() |
| "requires version X.X" | Wrong VERSION tag |
Must be 9.0.0.0810 |
Divide-and-conquer: generate with all devices but no links → then add links one by one → the first failing file identifies the bad cable.
This toolkit was developed through systematic reverse-engineering of Cisco Packet Tracer 9's file format — decoding native .pkt files, comparing XML structures, and empirically testing device/port/element combinations until files opened reliably. The work included:
- Cracking the encryption scheme (Twofish/EAX, existing tool)
- Mapping the required XML element order (21 top-level tags, strict)
- Discovering the correct
PHYSICALWORKSPACETYPE codes and geometry values - Verifying port names for every device type by trial and error in PT9
- Identifying the two required-but-undocumented cable fields
MIT