Recovering a Cisco AP from ROMMON

While doing a bit of labbing with an old AP1230, I typed “erase flash:” and my muscle memory happily AP1230confirmed the command. This was slightly faster than my brain noticed that all I really wanted was “erase start” and I now had to reload IOS on this AP. I decided that this was a good opportunity to learn, so I power cycled the AP. This leaves you at the “ap:” prompt, which is the AP’s version of the “rommon 1>” prompt you may have seen on Cisco router or the “switch:” prompt on a Cisco switch.

Turns out loading a fresh binary is pretty painless on these. You set the IP address and netmask, initialize some subsystems, then extract the tar file into flash. The hardest part is dealing with the “– MORE –” prompts after every 23 files or directories. You have to babysit this process or it will time out at a MORE prompt and say something like this when you hit a key:

-- MORE --
extracting c1200-k9w7-mx.123-8.JEE/html/level/15/ap_network-if_ethernet.shtml.gz (4762 bytes)
Premature end of tar file

Then you get to try your transfer all over again.

So here’s some of the output from when I did this:

ap: set IP_ADDR 169.254.105.189

ap: set NETMASK 255.255.0.0

ap: tftp_init

ap: ether_init
Initializing ethernet port 0...

ap: flash_init
Initializing Flash..
...The flash is already initialized.

ap: tar -xtract tftp://169.254.105.188/c1200-k9w7-tar.123-8.JEE.tar flash:

extracting info (274 bytes)
c1200-k9w7-mx.123-8.JEE/ (directory) 0 (bytes)
c1200-k9w7-mx.123-8.JEE/html/ (directory) 0 (bytes)
c1200-k9w7-mx.123-8.JEE/html/level/ (directory) 0 (bytes)
c1200-k9w7-mx.123-8.JEE/html/level/1/ (directory) 0 (bytes)
extracting c1200-k9w7-mx.123-8.JEE/html/level/1/appsui.js (557 bytes)
extracting c1200-k9w7-mx.123-8.JEE/html/level/1/back.shtml (506 bytes)
extracting c1200-k9w7-mx.123-8.JEE/html/level/1/cookies.js (5026 bytes).
extracting c1200-k9w7-mx.123-8.JEE/html/level/1/forms.js (17486 bytes)...
extracting c1200-k9w7-mx.123-8.JEE/html/level/1/sitewide.js (15991 bytes)...
extracting c1200-k9w7-mx.123-8.JEE/html/level/1/stylesheet.css (3214 bytes)
extracting c1200-k9w7-mx.123-8.JEE/html/level/1/config.js (23591 bytes).....
extracting c1200-k9w7-mx.123-8.JEE/html/level/1/popup_capabilitycodes.shtml.gz (1015 bytes)
extracting c1200-k9w7-mx.123-8.JEE/html/level/1/filter.js.gz (1801 bytes)
extracting c1200-k9w7-mx.123-8.JEE/html/level/1/filter_vlan.js.gz (1315 bytes)
extracting c1200-k9w7-mx.123-8.JEE/html/level/1/filter_mac_ether.js.gz (1710 bytes)
extracting c1200-k9w7-mx.123-8.JEE/html/level/1/security.js.gz (957 bytes)
extracting c1200-k9w7-mx.123-8.JEE/html/level/1/vlan.js.gz (902 bytes)
extracting c1200-k9w7-mx.123-8.JEE/html/level/1/ssid.js.gz (3989 bytes)
extracting c1200-k9w7-mx.123-8.JEE/html/level/1/dot1x.js.gz (982 bytes)
extracting c1200-k9w7-mx.123-8.JEE/html/level/1/network-if.js.gz (1833 bytes)
-- MORE --
extracting c1200-k9w7-mx.123-8.JEE/html/level/1/stp.js.gz (911 bytes)
extracting c1200-k9w7-mx.123-8.JEE/html/level/1/ap_assoc.shtml.gz (6032 bytes).
extracting c1200-k9w7-mx.123-8.JEE/html/level/1/ap_event-log.shtml.gz (4366 bytes).
[...]
extracting c1200-k9w7-mx.123-8.JEE/info (274 bytes)
extracting info.ver (274 bytes)

You may need to remove a now invalid BOOT variable if you changed the IOS version for the AP. You can remove that with:

ap: unset BOOT

Now your AP happily boots and you are back in action. If the AP was configured with a static IP, you might be surprised that it still has that static IP. You might even try a variety of erase commands and discover that the IP address continues to persist! The IP is actually stored in an IOS environment variable at the boot loader level. If you want to go to rommon to look at these, you can switch to manual boot mode:

ap(config)#boot manual

This will cause the AP to always boot to rommon. To boot IOS from rommon, simply run:

ap: boot

Here’s what the IOS environment variables look like in the rommon:

ap: set
DEFAULT_ROUTER=10.0.0.1
ENABLE_BREAK=no
IOS_STATIC_DEFAULT_GATEWAY=192.0.2.1
IOS_STATIC_IP_ADDR=192.0.2.20
IOS_STATIC_NETMASK=255.255.255.0
IP_ADDR=10.0.0.1
MANUAL_BOOT=no
NETMASK=255.255.0.0
RELOAD_REASON=58

Notice the IOS_STATIC_ variables? You can “unset” them from the rommon. You can also reset the unit to factory defaults with the “write default-config” command:

ap#write default-config 
Erasing the nvram filesystem will remove all configuration files! Continue? [confirm]
[OK]
Erase of nvram: complete
ap#

This will remove your startup-config, too, not just the static IP. Either way, your mysterious static IP is now gone.

FIN

Leave a Reply