Aut inveniam viam aut faciam

Regular Expressions For SecureCRT Keyword Highlighting – Update

This is an update to my previous post on syntax highlighting in SecureCRT.  I’ve focused on highlighting the output of show commands, but not “show run”.  I don’t specifically try to match the configuration.  I find that doing so causes the output of “show logging” to be over highlighted with different colors making it hard to read.  It’s easy to over highlight and ruin the entire point of it.  I have temporarily added entries to look for configuration problems in the past, such as allowing telnet, using password 7 hashes, or SNMPv1 read/write strings.  But I’ve found it’s easier and quicker to search through the backed up device configurations and address the issue all at once.
 
I’ve updated the regular expressions to include:
– Works with with IOS, IOS-XE, and NXOS.
– Works fairly well with XR.  Matching the output of “show logging” needs more work.
– Works fairly well with ASAs.  The ASAs use a time format of 0:00:00.  They end up partially matching the RT / RD regular expression.  If you are not working with L3VPNs, you can delete that regular expression and modify the Time regular expression to match the ASA’s format.  Otherwise, the fix would be to use a separate .ini file with the ASAs.
– Match Hundred, Forty, TwentyFive, and Ten GigabitEthernet interfaces.
– Match switch stack switch/slot/port interfaces, router slot/subslot/port interfaces, FEX chassis_id/slot/port interfaces, breakout cable chassis_id/slot/port/breakout_port interfaces, and XR rack/slot/module/port interfaces.
– Reduced the interface regular expressions to two lines (my personal list had grown to 14 lines).
– Changed the Privileged EXEC prompt regular expression to match anything with A-Z, a-z, 0-9,a dash, underscore, forward slash, or colon.  If you use other characters in your hostname, you’ll have to make the appropriate changes.  The User EXEC prompt is not matched.
– Added MAC addresses to the Time regular expression line.  If I didn’t, one of the Time regular expressions would match part of the MAC address turning that part grey and one of the RT/RD regular expressions would match another part of the same MAC address turning that part blue.  While I was at it, I added VOIP phone and access point device IDs that are displayed in the output of “show cdp neighbors”.
– Changed the order of the lines.  This is to allow the global configuration prompt to display “config” in yellow.  It also allows me to override the greedy “(not(.*)?” regular expression.  I was tired of seeing “notconnect” and “notifications” in red.
– Added regular expressions to match unwanted, partial matches.  I thing turn these white or the default text color.
 
The regular expressions are based on syntax used with Python. https://docs.python.org/3/library/re.html
 
SecureCRT does not support using spaces in regular expressions.  Which sucks.  Matching spaces would be handy for matching within the OSPF database, EIGRP topology, or the BGP neighbor information.  I’ve found example configurations that try to use the hexcodes for a space, such as \x20.  That doesn’t work for me.  Using the hexcode for a dash works, \x2d.  *shrug*  There are many references in the VanDyke forums that the performance hit was too large.
 
As much as I complain about not being able to match across spaces and, I’ve tried to get my list of regular expressions to work with a SSH/terminal program that does allow syntax highlighting matches with spaces.  Wow.  Talk about greedy matches.  “Why is my entire screen blue?!?!”  It’d take some time to completely rethink, rewrite, and test what I’m matching.
 
With SecureCRT, the following are considered word delimiters:

`~!#$%^&*()+=:;<>,.?/\[]{}|’
 
Order matters.  Generally, match the more specific (longer) before the less specific (shorter).  Otherwise, you’ll get partial matches.  For example, match “errors” before “error” before “err”.  Unless, of course, you want to override more specific matches.  For example, match emergencies, alerts, and critical log messages with %\w*\-[012]\-\w*.
 
Python regular expressions are greedy.  This means that it will try to match as much as possible.  This allows “(errors|error|err)” to be shortened to “(err(ors|or)?” or “(err(or(s)?)?” or “(err(.*)?)”.
 
I’m still using the one line regular expressions for IPv6 and IPv4 addresses from the book Regular Expressions Cookbook, 2nd Edition by Steven Levithan, Jan Goyvaerts.
 
There are some false matches.  I use the “Case match” option to reduce them as much as possible.  Still, things such as “B”, “R”, and “DR” still show up in some odd places.  Meh.  NXOS gets a few weird matches as well.  With EIGRP on NXOS, “internal” and “external” are lowercase in the output of “show ip route”.  Matching them causes those words to appear green in some weird places.  The ASAs use a time format that doesn’t follow any of the other Cisco device families.
 
The colors I use are meant for a dark (black) background with white text.  Because of this, dark colors are avoided.  I’ve tried to group the output of some protocols together:  BGP – blue, RIP – red, OSPF – orange, EIGRP – evergreen (but evergreen is too dark, so a lighter shade of green).
 
Not listed below are some personal regular expressions.  It’s common for route-map names, named ACLs, and other user defined names to be partially matched.  I create regular expressions to match those and then color them depending on their purpose.
 
If you don’t want to configured the highlight keywords in SecureCRT, you can use this .ini file.  For OS X, copy the .ini file into the following directory:

/Users/username/Library/Application/Support/VanDyke/SecureCRT/Config/Keywords/.
 
For Windows, the directory is located in %APPDATA%, which should be:

C:\Users\username\AppData\Roaming\VanDyke\Config|Keywords>.
 
In Linux, copy the .ini file into:

/home/username/.vandyke/SecureCRT/Config/Keywords/.
 
http://download.feralpacket.org/feralpacket.ini
 
NOTE –  Information that will not age well:
– Linux syntax highlighting support is in pre-release for version 8.6.  If your license for SecureCRT is current, you can request access to a pre-release.  Information can be found in the VanDyke forums.  Or you can wait for 8.6 to be released.
– The regular expressions I’m using to get rid of unwanted, partial matches doesn’t work with the latest version of SecureCRT for OS X.  It works in the latest Windows and Linux versions.  From the SecureCRT_History.txt of the 8.6 pre-release, “Change the keyword highlighting regular expression algorithm to honor the order of the configured keywords.”  Hopefully, that fixes the issue.


SecureCRT Settings:
- Session Options -> Terminal -> Appearance
-> Current color scheme
-> White / Black
-> Highlight keywords
-> Name: feralpacket
-> Style: Color is checked
- Keyword List Properties
-> Match case is checked
- To set for the default session:
-> Global Options -> General -> Default Session
-> Edit Default Settings...

 
Screenshots:

Prompt

Prompt

Logs

OSPF

RIB

MPLS

EIGRP

v6RIB
 

The Regular Expressions:

! Get rid of unwanted, partial matches. Turn them white.
(Stub\-Routing|Process\-tag|Dual\-active|\(R\)|inactive\-\if\-config|snmp\-ipv6\-dhcp\-relay|dot1q\-tunnel|route-tag|fddi\-default|H/W|hsrp\-Vl\d{1,4}\-\d{1,4}|B,T|B,R|notify|A\.B\.C\.D|forwarding\-table|repair\-paths|forwarding\-adjacency)
(passive\-interface)

! IPv4-mapped IPv6 Addresses and SAF Identifier Numbers
((\d{1,5}:){2}[0-9A-F]{1,8}(\.[0-9A-F]{1,8}){3}|(::FFFF)?::?(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9]))

! VPNv6 Addresses
\[\d{1,10}:\d{1,10}\](?:(?:[0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4}|(?=(?:[0-9A-Fa-f]{0,4}:){0,7}[0-9A-Fa-f]{0,4}(?![:.\w]))(([0-9A-Fa-f]{1,4}:){1,7}|:)((:[0-9A-Fa-f]{1,4}){1,7}|:)|(?:[0-9A-Fa-f]{1,4}:){7}:|:(:[0-9A-Fa-f]{1,4}){7})(?![:.\w])
\[\d{1,3}(\.\d{1,3}){3}:\d{1,10}\](?:(?:[0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4}|(?=(?:[0-9A-Fa-f]{0,4}:){0,7}[0-9A-Fa-f]{0,4}(?![:.\w]))(([0-9A-Fa-f]{1,4}:){1,7}|:)((:[0-9A-Fa-f]{1,4}){1,7}|:)|(?:[0-9A-Fa-f]{1,4}:){7}:|:(:[0-9A-Fa-f]{1,4}){7})(?![:.\w])

! VPNv4 Addresses
(\d{1,10}:){2}(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])
(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9]):\d{1,10}:(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])

! IPv6 Addresses
(?:(?:[0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4}|(?=(?:[0-9A-Fa-f]{0,4}:){0,7}[0-9A-Fa-f]{0,4}(?![:.\w]))(([0-9A-Fa-f]{1,4}:){1,7}|:)((:[0-9A-Fa-f]{1,4}){1,7}|:)|(?:[0-9A-Fa-f]{1,4}:){7}:|:(:[0-9A-Fa-f]{1,4}){7})(?![:.\w])

! MAC Addresses and Time
((\w{2}:){5}\w{2}|(\w{4}\.){2}\w{4}|SEP\w{12}|AP(\w{4}\.){2}\w{4}|(2[0-3]|[01][0-9])(:([0-5]?[0-9])){2,3}\.\d{3}|(2[0-3]|[01][0-9])(:([0-5]?[0-9])){1,2}|\dy\d{1,2}w|\d{1,3}w\dd|\d{1,4}d\d{2}h|year(s)?|week(s)?|day(s)?|hour(s)?|minutes)

! ASN:nn RD or RT
((RT:)?\d{1,10}:\d{2,10}|(RT:)?\d{1,10}:[1-9])

! IP-address:nn RD or RT
(RT:)?(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9]):\d{2,5}|(RT:)?(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9]):[1-9])

! IPv4 Addresses
(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])

! Interfaces
((Hundred|TwentyFive)GigE\d{1,3}(/\d{1,3})*(\.\d{1,10})*|((Forty|Ten)*Gigabit|Fast)*Ethernet\d{1,3}(/\d{1,3})*(\.\d{1,10})*|(Internal\-(Control|Data)|Management|Serial|Twe|Eth|Hu|Tw|Fo|Te|Gi|Fa|Et|Se)\d{1,3}(/\d{1,3})*(\.\d{1,10})*)
((Virtual\-(Template|Access)|(P|p)ort-channel|Multilink|Loopback|Tunnel|Dialer|Vlan|mgmt|Null|NVI|BVI|Po|Mu|Lo|Tu|Di|Vl)\d{1,4})

! Possible warning and other things that deserve attention
(?:((E|e)rr(ors|or)?)|reset|act/unsup|dhcp|DHCP|mismatch|drop(s|ped|ping)?|runts|CRC|collision(s)?|LRN|learning|listening|LIS|unsynchronized|(R|r)eason|SYN(SENT|RCVD))
(?:Peer\(STP\)|Shr|pvst|ieee|mstp|Bound\(PVST\)|INIT|TFTP|Mbgp|LAPB|l2ckt\(\d{1,10}\)|DCE|DTE|passive|\[ANY\]|RIB\-failure|discriminator|Standby|disable(d)?|unnumbered)
(?:aggregate(d|\/\w*)|atomic\-aggregate|\[V\]|ATTEMPT|INIT|2WAY|EXCHANGE|LOADING|\(global\)|(T|t)ag|key-chain|backup\/repair|repair|v2\/D|v2\/SD|(W|w)arning)
(?:Condition\-map|Advertise\-map|no\-advertise|no\-export|local\-AS|internet|reached\(\d*\)|n-802.1q|monitoring|inactive|config(.*)?\)|notconnec(t)?|notifications)

! Bad responses
(?:(D|d)own|DOWN|(F|f)ail(ed|ure)?|not(.*)?|bad|never|BLK|fddi|n\-isl|isl|blocking|\(tdp\)|tdp|TDP|(I|i)nvalid|err\-disable(d)?|unusable|a\-half|half|a\-10|\(SD\)|\(D\))
(?:denied|DENIED|deny|infinity|inaccessible|\*ROOT_Inc|BKN\*|\*LOOP_Inc|wrong|
K[2456]=1|cannot|MM_NO_STATE|MM_KEY_EXCH|UP\-NO\-IKE|Idle|ERROR:)

! Good responses
(?:rstp|best|CIST|QM_IDLE|(IP|L|CDP)CP\+|CHAP\+|PAP\+|(IP|L|CDP)CP\[Open\]|our_master|UP\-ACTIVE|permit|(G|g)ood|(O|o)k|uptime|0x2102|0x102|0xF|Established|ESTAB|enable(d)?|READY|AUTHORIZED|SUCCESS(FUL)?|CONNECT(ION|ED)?)
(?:\*\>|FWD|(R|r)oot|802\.1q|dot1q|connected|LocalT|yes|\(SU\)|\(RU\)|\(bndl\)|\(P\)|forwarding|synchronized|(A|a)ctive|ACTIVE|rapid\-pvst|(U|u)p|UP|FULL|.*\.(?:bin|img|pkg|packages\.conf|vm)|.*\-mz\..*)

! Bad - emergancies, alerts, and critical log messages
%\w*\-[012]\-\w*

! BGP
(Cost:pre\-bestpath|0x880\d):\d{1,10}:\d{1,10}
(bgp|BGP|B|IGP|incomplete|\d{2,7}\/nolabel\(\w*\)|RR\-client|Originato|cluster\-id|Cluster\-id|Cluster|Route\-Reflector)
(%BGP\-\d\-\w*|%BGP_SESSION\-\d\-\w*|%ROUTING\-\BGP\-\d\-\w*|%ROUTING\-\BGP_VRF\-\d\-\w*)

! OSPFv2 and OSPFv3
(OSPF_VL\d{1,2}|OSPF_SL\d{1,2}|VL\d{1,2}|SL\d{1,2}|Type\-\d|ospf|OSPF|O|IA|E[12]|N[12]|P2P|P2MP|BDR|DR|ABR|ASBR|LOOP)
(DROTHER|POINT_TO_POINT|POINT_TO_MULTIPOINT|BROADCAST|NON_BROADCAST|LOOPBACK|
SHAM_LINK|3101|1587|transit|Transit|nssa|NSSA|stub|Stub|Superbackbone)
(OSPFv3_VL\d{1,2}|OSPFv3\-\d{1,5}\-IPv6|ospfv3|OSPFv3|OI|OE[12]|ON[12]|V6\-Bit|E\-Bit|R\-bit|DC\-Bit|opaque|DROTH)
(%OSPF\-\d\-\w*|%OSPFV3\-\d\-\w*|%ROUTING\-OSPF\-\d\-\w*|%ROUTING\-OSPFv3_RIB\-\d\-\w*)

! NHRP and DMVPN
(DT[12]|T2|NHRP|H|p|EXp|IX|D/ur|(multi\-)?GRE/IP(v6)?|%DOMAIN\-\d\-\w*)

! EIGRP
(EIGRP\-(IPv|SFv)(4|6)|eigrp\-\w*|eigrp|((IP|IPv6)\-)?EIGRP|EX|D|K[13]=1|K[2456]=0|(I|i)nternal|(E|e)xternal|VR\(\w*\)|VR\(#AUTOCFG#\)|AS\(\d{1,5}\)|Passive)
(%DUAL\-\d\-\w*|%ROUTING\-\EIGRP\-\d\-\w*)

! RIP
(rip|RIP|R)
(%ROUTING-\-RIP\-\d\-\w*)

! PIM, MSDP, and IGMP
(PIM\/IPv4|RP\:|v2\/S|BSR)
(%PIM\-\d\-\w*|%MSDP\-\d\-\w*|%IGMP\-\d\-\w*|%ROUTING\-IPV4_IGMP\-\d\-\w*|%ROUTING\-\MSDP\-\d\-\w*)

! Hostnames and prompt
(^[A-Za-z0-9\-\(\)_/:]+\(|^[A-Za-z0-9\-\(\)_/:]+#)

! Routing table metrics
\[\d{1,3}/\d{1,12}\]

! EIGRP topology table metrics and ping responses
\(\d{1,12}/\d{1,12}\)

! LDP
(\(ldp\)|ldp|imp\-null|Pop|Label|Stack)
(%LDP\-\d\-\w*|%LSD\-\d\-\w*|%LDP\-\d\-\w*|%LSD\-\d\-\w*|%ROUTING\-LDP\-\d\-\w*|%ROUTING\-\MPLS_TE\-\d\-\w*)

! IPv6 Neighbor Discovery
%IPV6_ND\-\d\-\w*

! Various log messages I turn green
(%AUTHMGR\-\d\-SUCCESS|%DOT1X\-\d\-SUCCESS|%MAB\-\d\-SUCCESS)

! Various log messages I turn red
(%AUTHMGR\-\d\-SECURITY_VIOLATION|%AUTHMGR\-\d\-FAIL|%DOT1X\-\d\-FAIL|%MAB\-\d\-FAIL|%CRYPTO\-\d\-RECVD_PKT_NOT_IPSEC)

! Various log messages I turn yellow
(%CDP\-\d\-\w*|%DHCP\-\d\-\w*|%SPANTREE\-\d\-\w*|%TDP\-\d\-\w*|%SW_DAI\-\d\-\w*|%SW_VLAN\-\d\-\w*|%SSH\-\d\-\w*)
(%PM\-d\-\w*|%STORM_CONTROL\-\d-\w*|%PV\-\d\-\w*|%SPANTREE_FAST\-\d\-\w*|%TRACK\-\d\-\w*|%REDUNDANCY\-\d\-\w*)
(%TRACKING\-\d\-\w*|%FR_EEK\-\d\-\w*|%HSRP\-\d\-\w*|%SNAT\-\d\-\w*|%SEC\-\d\-\w*|%IPRT\-\d\-\w*|%HA_CONFIG_SYNC\-\d\-\w*)
(%SYS\-\d\-\w*|%PARSER\-\d\-cfglog\w*|%ENVMON\-\d\-\w*|%EC\-\d\-\w*|%GLDP\-\d\-\w*|%PLATFORM_PM\-\d\-\w*)
(%CRYPTO\-\d\-\w*|%NHRP\-\d\-\w*|%SNMP\-\d\-\w*|%CP\-\d\-\w*|%HA_EM\-\d\-\w*|%TCP\-\d\-\w*|%STACKMGR\-\d\-\w*)
(%IP\-\d\-\w*|%ADJ\-\d\-\w*|%IKEV2\-\d\-\w*|%DHCP_SNOOPING\-\d\-\w*|%SEC_LOGIN\-\d\-\w*|%ILPOWER\-\d\-\w*)

! Catch-all for all other log messages
%\w*\-\d\-\w*

Comments are closed.

This entry was posted on Wednesday, July 24th, 2019 at 1:01 pm and is filed under CCIE. You can follow any responses to this entry through the RSS 2.0 feed. Responses are currently closed, but you can trackback from your own site.