diff --git a/Makefile b/Makefile index 5fe6841..73dc1f4 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,8 @@ PKG_CONFIG ?= pkg-config PREFIX ?= /usr/local VERSION := $(shell if [ -d .git ] && which git 2>&1 > /dev/null; then git describe --always | tail -c +2; else echo $$STANDALONE_VERSION; fi) CFLAGS += -Wall -g -DNMRPFLASH_VERSION=\"$(VERSION)\" -SUFFIX ?= +SUFFIX ?= +MACOS_SDK = macosx11.1 ifeq ($(shell uname -s),Linux) CFLAGS += $(shell $(PKG_CONFIG) libnl-route-3.0 --cflags) @@ -14,6 +15,7 @@ endif ifeq ($(shell uname -s),Darwin) AFL=afl-clang + CFLAGS+= -isysroot $(shell xcrun --sdk $(MACOS_SDK) --show-sdk-path) else AFL=afl-gcc endif diff --git a/README.md b/README.md index 43fbbeb..c74544b 100644 --- a/README.md +++ b/README.md @@ -4,10 +4,10 @@ nmrpflash - Netgear Unbrick Utility ==================================== `nmrpflash` uses Netgear's [NMRP protocol](http://www.chubb.wattle.id.au/PeterChubb/nmrp.html) -to flash a new firmware image to a compatible device. It has been successfully used on a Netgear -EX2700, EX6100v2, EX6120, EX6150v2, DNG3700v2, R6100, R6220, R7000, D7000, WNR3500, R6080, R6400 -and R6800, R8000, R8500, WNDR3800, WNDR4500v3 but is likely to be compatible with many other Netgear -devices. +to flash a new firmware image to a compatible device. It has been successfully used with the +Netgear D7000, DNG3700v2, EX2700, EX6100v2, EX6120, EX6150v2, R6080, R6100, R6220, R6400, R7000, R7000P +R6800, R8000, R8000P, R8500, WNDR3800, WNDR4300, WNDR4500v3 WNR3500, but is likely to be compatible with +many other Netgear devices as well. Prebuilt binaries for Linux, macOS and Windows are available [here](https://github.com/jclehner/nmrpflash/releases) ([Npcap](https://nmap.org/npcap/#download) is required on Windows). FreeBSD packages can be fetched and installed using the @@ -125,8 +125,7 @@ C:\> net start npf ###### "No response after 60 seconds. Bailing out." -The router did not respond. **Always run `nmrpflash` in the sequence -described above!** +**Always run `nmrpflash` in the sequence described above!** You can try specifying the MAC address using `-m xx:xx:xx:xx:xx:xx`, or, if that still doesn't work, "blind mode" using `-B`. Note that @@ -203,7 +202,7 @@ flashing via the web interface. ###### "Timeout while waiting for 0000." after "Waiting for remote to respond." This could indicate that the device hasn't finished flashing, after the default timeout -(15 minutes`). Try increasing the timeout, using the `-T ` option, +(15 minutes). Try increasing the timeout, using the `-T ` option, for example use `-T 1800` to specify a timeout of 30 minutes. ###### "bind: Cannot assign requested address" @@ -247,12 +246,9 @@ $ pkg install nmrpflash ###### Windows -The repository includes a -[CodeBlocks](https://www.codeblocks.org/) -project file (`nmrpflash.cbp`). Download the latest -[Npcap SDK](https://nmap.org/npcap/) -and extract it into the a folder named `Npcap` in the source's root -directory. +The repository includes a [CodeBlocks](https://www.codeblocks.org/) project +file (`nmrpflash.cbp`). Download the latest [Npcap SDK](https://nmap.org/npcap/) +and extract it into the a folder named `Npcap` in the source's root directory. ### Donate diff --git a/ethsock.c b/ethsock.c index c795360..c77911a 100644 --- a/ethsock.c +++ b/ethsock.c @@ -599,6 +599,7 @@ struct ethsock *ethsock_create(const char *intf, uint16_t protocol) struct ethsock *sock; bool is_bridge = false; int err; + int promisc; #ifdef NMRPFLASH_WINDOWS intf = intf_name_to_wpcap(intf); @@ -616,11 +617,21 @@ struct ethsock *ethsock_create(const char *intf, uint16_t protocol) buf[0] = '\0'; sock->intf = intf; - sock->pcap = pcap_open_live(sock->intf, BUFSIZ, 1, 1, buf); - if (!sock->pcap) { - fprintf(stderr, "%s.\n", buf); - goto cleanup; - } + promisc = true; + + do { + sock->pcap = pcap_open_live(sock->intf, BUFSIZ, promisc, 1, buf); + if (!sock->pcap) { + if (!promisc) { + fprintf(stderr, "Error: %s.\n", buf); + goto cleanup; + } else { + fprintf(stderr, "Warning: failed to enable promiscous mode.\n"); + promisc = false; + continue; + } + } + } while (!sock->pcap); if (*buf) { fprintf(stderr, "Warning: %s.\n", buf); @@ -859,7 +870,7 @@ static int ethsock_arp(struct ethsock *sock, uint8_t *hwaddr, uint32_t ipaddr, s #elif defined(NMRPFLASH_WINDOWS) return DeleteIpNetEntry(&arp) ? 0 : -1; #else - return systemf("arp -d %s", inet_ntoa(addr)); + return systemf("arp -d %s &> /dev/null", inet_ntoa(addr)); #endif } diff --git a/main.c b/main.c index 02c3e8b..161f46b 100644 --- a/main.c +++ b/main.c @@ -21,6 +21,7 @@ #include #include #include +#include #include "nmrpd.h" void usage(FILE *fp) @@ -70,17 +71,19 @@ void usage(FILE *fp) "and MAC are set to the device IP address, TFTP port, subnet\n" "mask and MAC address, respectively.\n" "\n" - "nmrpflash %s, Copyright (C) 2016-2021 Joseph C. Lehner\n" + "nmrpflash %s, Copyright (C) 2016-2022 Joseph C. Lehner\n" "nmrpflash is free software, licensed under the GNU GPLv3.\n" "Source code at https://github.com/jclehner/nmrpflash\n" - "\n", + "\n" + "%s\n", NMRP_DEFAULT_IP_REMOTE, NMRP_DEFAULT_IP_LOCAL, NMRP_DEFAULT_SUBNET, NMRP_DEFAULT_RX_TIMEOUT_MS, NMRP_DEFAULT_UL_TIMEOUT_S, NMRP_DEFAULT_TFTP_PORT, - NMRPFLASH_VERSION + NMRPFLASH_VERSION, + pcap_lib_version() ); } diff --git a/nmrp.c b/nmrp.c index 3833597..1d4935b 100644 --- a/nmrp.c +++ b/nmrp.c @@ -254,7 +254,7 @@ static uint8_t *ethsock_get_hwaddr_fake(struct ethsock* sock) static int pkt_send(struct ethsock *sock, struct nmrp_pkt *pkt) { - return ethsock_send(sock, pkt, sizeof(*pkt)); + return ethsock_send(sock, pkt, sizeof(pkt->eh) + ntohs(pkt->msg.len)); } static int pkt_recv(struct ethsock *sock, struct nmrp_pkt *pkt) diff --git a/nmrpflash.cbp b/nmrpflash.cbp index 3f32a89..f1397f0 100644 --- a/nmrpflash.cbp +++ b/nmrpflash.cbp @@ -18,7 +18,7 @@ - +