Previous working directory in Windows Command Prompt

Using bash in *nix has a handy feature: If you are in one directory and you switch to another one, you can use  cd -  to go back to the previous directory. My everyday computer is Windows 11 and I was longing to have that ability. I went back to an old tool called DOSKEY that was originally released in 1991 with MS-DOS 5. It's still around 33 years later (as of this writing).

One of doskey’s features is macros. They are roughly equivalent to aliases in *nix. Here's how I made something close to   cd -  work:
  1. Edit your registry to set a program to auto-run whenver you open a cmd.exe shell. Do this by adding a new String value to HKLM\SOFTWARE\Microsoft\Command Processor called Autorun. Put your program in as the Value data. In my example, I use "C:\Batch\cmd.cmd"


  2. I have a line in that file:
    doskey /macrofile=c:\batch\doskey.macros
  3. In the doskey.macros file, I have the following contents:
    cd = set OLDPWD=%CD% & cd $*
    cd- = set OLDPWD=%CD% & cd %OLDPWD%

It's not exactly equivalent to  cd - , but pretty close... just leave out the space between cd and -. Note that if you change directories without using cd and a space, for example by using the chdir command or by using  cd..  (with no space), it will break the   cd-  hack.

Which port for DHCP?

For a long time, I never remembered which UDP port was for the DHCP server and which was for the client. I finally came up with a trick... you have to have a server in place before you can have any clients, right? Therefore, the first port, 67, is the port the server listens on. The second port, 68, is the source port the client uses.

TCP, UDP, and the Crossover

I often see only-tcp or only-udp allowed in firewalls for certain protocols that work best with both. We have to continue to keep our eyes on the industry to see where things are going so we can be most efficient. Below are some examples, listed with the primary/traditional protocol, then the reason why the other one should also be allowed. In many cases, things will work without allowing the "secondary" protocol, but their efficiency may be hampered.
  • https (tcp/443) - Since its inception, https has been a tcp protocol. However, in recent years, and especially with the advent of HTTP/3, allowing only tcp is not good enough. Even before HTTP/3, DTLS has made a tcp-only stance not good enough in regards to https.
  • dns (udp/53) - The intro to RFC 7766 says it perfectly: Most DNS transactions take place over UDP. TCP is always used for full zone transfers (using AXFR) and is often used for messages whose sizes exceed the DNS protocol's original 512-byte limit. The growing deployment of DNS Security (DNSSEC) and IPv6 has increased response sizes and therefore the use of TCP. I have seen situations where AWS responds with data longer than 512 bytes, and it's not uncommon to find TXT records (e.g., for SPF) to exceed that length as well.
  • rdp (tcp/3389) - Microsoft's Remote Desktop Protocol works better if both tcp and udp are allowed. It has supported udp since version 8.0 and it creates a smoother experience.
  • ldap (tcp/389) - Microsoft is now starting to use ldap over udp in certain scenarios.
There are surely a lot more, and the list will surely grow, but I just thought I'd comment on a few...

The Case of the Roaming Windows Domain-Joined Laptop

The title is inspired by Mark Russinovich's great series “The Case of the Unexplained.” He is a technical wizard, and I am definitely not even in the same ballpark. But, inspiration is inspiration, so here we go.

I have a work laptop that is joined to our Active Directory domain. When I would bring it home it would take about 90 seconds to unlock. I finally took a packet capture via tcpdump on my home router running OpenWRT in order to see what the heck it was doing for that long.

I knew it would be trying to query DNS and I also knew that it would not find what it was looking for, since it queries, via SRV records, various services in the _mscdc zone of your domain. For example: _ldap._tcp.dc._mscdc.mydomain.me. Sure enough, those responses quickly answered with a “no such name.” So that's not causing the slowdown (well, very slightly, but nothing really worth mentioning).

Because DNS wasn't working, it started try alternate methods of locating a domain controller. It started sending NetBIOS Name Service broadcasts on UDP port 137. It also started sending multicast queries to 224.0.0.252 on UDP port 5355, which is Link-Local Multicast Name Resolution. I wondered if I disabled both of those methods if it would increase my unlock speed. It did! If I'm on the LAN (or VPN'ed in), DNS works just fine, so I don't need these fallback methods. Perhaps there's more I could have done, but I was satisfied with my results. The method behind those results I explain in the next paragraph...

Disabling NetBIOS over TCP/IP Manually and via DHCP

To disable NetBIOS over TCP/IP manually, go into the TCP/IP settings in Windows 7/8/10. Go to Advanced, WINS, Disable NetBIOS over TCP/IP.

For DHCP, you can search the Internet for how to disable this via various DHCP server software. Since I run OpenWRT at home, I'll focus on that. DHCP option 43 is the “vendor specific” attribute. As for the other parts of it, I won't go into that at this point. OpenWRT runs dnsmasq for IPv4 DHCP. The syntax for setting NetBIOS via option 43 for dnsmasq can be found here. To adapt that to OpenWRT, just add the following line to /etc/config/dhcp under the config dhcp 'lan' context:

config dhcp 'lan'
  list 'dhcp_option' '43.01:04:00:00:00:02'

Disabling Link-Local Multicast Name Resolution

There is no DHCP option for disabling Link-Local Multicast Name Resolution, so it has to be done on the device itself via registry entry at:

HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\DNSClient

Create a DWORD value called EnableMulticast with a value of 0.

Hopefully your domain computer “logs in” and unlocks faster via cached credentials, even when you're out of communication with a domain controller.

The Verbization of Protocols, or "PuTTY" is Not a Verb

Warning, this entry is filed under "rant."

PuTTY is a wonderful terminal emulator. I use the Windows version all the time for launching ssh sessions. I also use it for serial console connectivity, telnet (if I have to), and testing raw remote tcp sockets.

Sometimes I hear people, particularly Windows admins, refer to "puttying in" to a system running ssh services. Sorry, no, "putty" is not a verb. Let's look at the wonderfully flexible English language a bit...

We convert nouns to verbs all the time. We even convert companies or products into verbs sometimes. For example, when I lived in India, people never referred to "making copies," they always referred to "Xeroxing." But in IT, we convert protocols, not company or product names, into verbs. Here are some examples:

  • Telnet: "I telnet'ed into that router but couldn't find anything wrong with the configuration."
  • rdp: "Just rdp [or remote] to that server and restart the Splunk agent."
  • ftp: "You just have to ftp into that server to see that the file is over 500 megs."
  • ssh: "I ssh'd [pronounced ess-ess-ayched] into that server to see what was spiking the CPU."
    Not this: "I puttyed (puttied?) into that server to demonstrate that I don't know the difference between a program that uses a protocol and a protocol itself."
Sometimes just a "verbicized" noun isn't good enough... it doesn't stand alone well as a verb. Some examples:
  • smtp:
    • Bad: "SMTP into the server to see if it's an open relay."
    • Good: "Open an SMTP session to that mail server and see if it's an open relay."
  • snmp:
    • Bad: "SNMP to that host to see its uptime." (we could get into a debate over connection-oriented [tcp] versus connectionless [udp] on this one)
    • Good: "Run an SNMP query against that host to see its uptime."
  • cifs:
    • Bad: "cifs into that Windows server from Linux using smbclient."
    • Good: "Initiate a cifs transfer to a Windows share from Linux via smbclient."
  • Citrix:
    • Bad: "Citrix into that server."
    • Good: "Establish a Citrix/ICA/XenApp session to see if the firewall rules are correct."
  • etc., etc.
So let's just remember: never turn a piece of software into a verb. Protocols, fine, but unless a particular program is the only thing that can use a protocol (which is never true for very long), let's make the protocol the verb. That means there is no "puttying into"--only "ssh'ing into."

/End rant.

windump and pcap for Windows and interface name enumeration

Tonight I took the plunge: I moved from winpcap and windump from Riverbed (formerly from CACE and before that from Politecnico di Torino) to npcap. There are lots of great reasons discussed on the npcap page, not to mention that winpcap hasn't had an update since 2013.

Even though I installed it with winpcap compatibility, I still got an error when running windump. That was fixed by installing WinDump for Npcap (see the Releases section for pre-compiled binaries).

It has always bothered me that enumerating interfaces using windump -D was more luck and trial-and-error than actually being able to see which interface you want to dump. So I wrote a little batch file called listif.cmd that will give me a nice list so I can run windump -i # to dump my packets. Besides windump itself, it doesn't require anything that doesn't come with Windows.

@echo off

setlocal ENABLEDELAYEDEXPANSION

set LIST=%temp%\getmac-list.txt

echo Getting available adapter list...
getmac /fo csv /v > %LIST%

echo Resolving available adapter list...
for /f "tokens=1,3 delims=.{}" %%a in ('windump -D') do (
 for /f "tokens=1,2 delims=," %%m in ('findstr "%%b" %LIST% 2^>nul') do (
  set CONN_NAME=%%m
  set ADAPTER_NAME=%%n
  echo  %%a. !CONN_NAME:"=! (!ADAPTER_NAME:"=!^)
 )
)

First Hop Redundancy Protocol ARP Problem

Let me start by saying that this article is Cisco-specific, though it applies to IOS, IOS-XE, and NX-OS. I’ve not used IOS-XR, so I don’t know about that one.

When using an FHRP, like HSRP or VRRP, you can’t “force” a router to cause another device to update its ARP table simply by pinging it, as you can with an actual interface IP address. This could create a situation where you want to convert a single router into two redundant routers, but you don’t have access to clear the ARP table on the other devices in the network.

Sometimes it’s not even necessary to worry about MAC changes. For example, imagine I have an ASA with an address of 10.91.50.1 pointing to 10.91.50.254 for its next-hop router. I have one router with interface Gi0/0 configured as 10.91.50.254 with a MAC address of f40f.1bbf.01b0. Let’s say I change the interface address to 10.91.50.252 and make 10.91.50.254 the VRRP address, which yields a MAC address of 0000.5e00.015b. The ASA will continue to think that 10.91.50.254 has a MAC address of f40f.1bbf.01b0, that is until its ARP cache times that entry out. And this is perfectly okay! The router will continue forwarding those packets on. When the ARP cache times out and the ASA does an ARP request for 10.91.50.254, it will learn the new VRRP MAC address of 0000.5e00.015b and all will be well.

But what if you want to test failover before you have a chance to let the ASA time-out its ARP table? Or what if you don’t have access to the ASA to see what it has in its ARP table (is it pointed to the burned-in MAC or the VRRP MAC)?

In that case, maybe we can “force” an update on the ASA (or whatever else) without having access to it. Let’s try (from the router):
router# ping 10.91.50.1 source 10.91.50.254
% Invalid source address- IP address not on any of our up interfaces
Unfortunately, it doesn’t let us. However, if you do an extended ping, it does let you:
router# ping
Protocol [ip]:
Target IP address: 10.91.50.1
Repeat count [5]:
Datagram size [100]:
Timeout in seconds [2]:
Extended commands [n]: y
Ingress ping [n]:
Source address or interface: 10.91.50.254
Type of service [0]:
Set DF bit in IP header? [no]:
Validate reply data? [no]:
Data pattern [0x0000ABCD]:
Loose, Strict, Record, Timestamp, Verbose[none]:
Sweep range of sizes [n]:
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 10.91.50.1, timeout is 2 seconds:
Packet sent with a source address of 10.91.50.254
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 1/2/4 ms
Boom, ARP table updated on remote device. I would say that the fact you can’t ping it while specifying an FHRP source interface from the command-line but you can ping specifying an FHRP source from extended ping is an oversight on behalf of the Cisco engineers. Oh well, it is what it is.

By the way, this works on IOS for both HSRP and VRRP addresses. On my Nexus 7010, version 6.2(16), you can even specify the source IP address from the command-line, instead of having to go through the extended ping interaction. For example: ping 10.200.5.218 source 10.91.50.254.

Previous working directory in Windows Command Prompt

Using bash in *nix has a handy feature: If you are in one directory and you switch to another one, you can use   cd -  to go back to the pr...