diff --git a/CHANGELOG b/CHANGELOG index 168c1310b..b55020243 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -161,6 +161,9 @@ o [NSE] Remove db2-discover, as its functionality was performed by service broadcast-db2-discover. http://seclists.org/nmap-dev/2014/q3/415 [Daniel Miller] +o Cache dnet names not found on Windows when enumerating interfaces in the + Windows Registry. Reduces startup times. [Elon Natovich] + o [NSE] Make smb-ls able to leverage results from smb-enum-shares or list of shares specified on command line. [Pierre Lalet] diff --git a/libnetutil/netutil.cc b/libnetutil/netutil.cc index 535066011..4ba6f22d7 100644 --- a/libnetutil/netutil.cc +++ b/libnetutil/netutil.cc @@ -3960,6 +3960,11 @@ int DnetName2PcapName(const char *dnetdev, char *pcapdev, int pcapdevlen) { } *NCC = NULL; static int NCCsz = 0; static int NCCcapacity = 0; + static struct NameNotFoundCache { + char dnetd[64]; + } *NNFC = NULL; + static int NNFCsz = 0; + static int NNFCcapacity = 0; int i; char tmpdev[128]; @@ -3971,6 +3976,13 @@ int DnetName2PcapName(const char *dnetdev, char *pcapdev, int pcapdevlen) { sizeof(*NCC)); NCCsz = 0; } + if (!NNFC) { + NNFCcapacity = 5; + NNFC = + (struct NameNotFoundCache *) safe_zalloc(NNFCcapacity * + sizeof(*NNFC)); + NNFCsz = 0; + } // First check if the name is already in the cache for (i = 0; i < NCCsz; i++) { if (strcmp(NCC[i].dnetd, dnetdev) == 0) { @@ -3978,12 +3990,28 @@ int DnetName2PcapName(const char *dnetdev, char *pcapdev, int pcapdevlen) { return 1; } } - + // Check if the name is already in the name not found cache + for (i = 0; i < NNFCsz; i++) { + if (strcmp(NNFC[i].dnetd, dnetdev) == 0) { + return 0; + } + } // OK, so it isn't in the cache. Let's ask dnet for it. -/* Converts a dnet interface name (ifname) to its pcap equivalent, which is stored in -pcapdev (up to a length of pcapdevlen). Returns 0 and fills in pcapdev if successful. */ - if (eth_get_pcap_devname(dnetdev, tmpdev, sizeof(tmpdev)) != 0) - return 0; + /* Converts a dnet interface name (ifname) to its pcap equivalent, which is stored in + pcapdev (up to a length of pcapdevlen). Returns 1 and fills in pcapdev if successful. */ + if (eth_get_pcap_devname(dnetdev, tmpdev, sizeof(tmpdev)) != 0) { + // We've got it. Let's add it to the not found cache + if (NNFCsz >= NNFCcapacity) { + NNFCcapacity <<= 2; + NNFC = + (struct NameNotFoundCache *) safe_realloc(NNFC, + NNFCcapacity * + sizeof(*NNFC)); + } + Strncpy(NNFC[NNFCsz].dnetd, dnetdev, sizeof(NNFC[0].dnetd)); + NNFCsz++; + return 0; + } // We've got it. Let's add it to the cache if (NCCsz >= NCCcapacity) {