Compare commits

...

10 commits

Author SHA1 Message Date
Penelope Gwen
8419c9a1ca debianization 2025-08-13 10:31:27 -07:00
Joseph C. Lehner
8fc58598dd Fix build errors 2025-03-21 16:06:04 +01:00
Joseph C. Lehner
17942bc3f1 Simplify macOS release builds 2025-03-19 18:40:10 +01:00
Joseph C. Lehner
dd7b5c0c96 Bump version 2025-03-19 10:28:24 +01:00
Joseph C. Lehner
d5420cba8e Update readme 2025-03-19 10:27:54 +01:00
Joseph C. Lehner
a27b7462a5 Add hints for sendto() errors 2025-03-19 10:19:54 +01:00
Joseph C. Lehner
924ff34d1b Add more hints
In response to #156 and #164.
2025-03-07 08:46:32 +01:00
Joseph C. Lehner
a8cf411561 nmrp_discard: clarify messages 2025-02-13 10:49:52 +01:00
Joseph C. Lehner
b7a4b588b7 Update copyright years 2025-01-04 22:39:36 +01:00
Joseph C. Lehner
b06895d00f Add AU region
Addresses #162
2024-12-23 10:13:18 +01:00
22 changed files with 534 additions and 29 deletions

View file

@ -5,7 +5,6 @@ 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 ?=
MACOS_SDK ?= macosx15.0
NPCAP_SDK = 1.13
ARCH := $(shell uname -m)
LINUXDEPLOY = ./linuxdeploy-$(ARCH).AppImage
@ -43,15 +42,16 @@ else
LDFLAGS += -lpcap
ifeq ($(shell uname -s),Darwin)
AFL=afl-clang
SYSROOT ?= $(shell xcrun --sdk $(MACOS_SDK) --show-sdk-path)
LDFLAGS += -framework CoreFoundation
TARGETS ?= -arch x86_64 -arch arm64
CFLAGS += $(TARGETS)
LDFLAGS += -framework CoreFoundation $(TARGETS)
endif
endif
.PHONY: clean install release release/macos release/linux release/win32
nmrpflash$(SUFFIX): $(nmrpflash_OBJ)
$(CC) $(CFLAGS) -o nmrpflash$(SUFFIX) $(nmrpflash_OBJ) $(LDFLAGS)
$(CC) $^ -o $@ $(LDFLAGS)
tftptest:
CFLAGS=-DNMRPFLASH_TFTP_TEST make clean nmrpflash
@ -93,12 +93,8 @@ nmrpflash-$(ARCH).AppImage: $(LINUXDEPLOY) release
mkdir -p $(APPDIR)
$(LINUXDEPLOY) --appdir $(APPDIR) -e nmrpflash -i nmrpflash.svg -o appimage --create-desktop-file
release/macos:
CFLAGS="-isysroot $(SYSROOT) -target arm64-apple-macos11" SUFFIX=".arm64" make release
CFLAGS="-isysroot $(SYSROOT) -target x86_64-apple-macos10.8" SUFFIX=".x86_64" make release
lipo -create -output nmrpflash nmrpflash.x86_64 nmrpflash.arm64
release/macos: release
zip nmrpflash-$(VERSION)-macos.zip nmrpflash
rm -f nmrpflash.x86_64 nmrpflash.arm64
release/linux: release
zip nmrpflash-$(VERSION)-linux.zip nmrpflash

View file

@ -6,7 +6,7 @@ nmrpflash - Netgear Unbrick Utility
`nmrpflash` uses Netgear's [NMRP protocol](https://web.archive.org/web/www.chubb.wattle.id.au/PeterChubb/nmrp.html)
to flash a new firmware image to a compatible device. It has been successfully tested with
various models (D7000, DNG3700v2, EX2700, EX6100v2, EX6120, EX6150v2, EX8000, R6020, R6080, R6100, R6220, R6400, R7000,
R7000P, R6800, R8000, R8000P, R8500, RAX40, RAX75, RBR40, RBS40, RBR50, RBS50, SRR60, SRS60, WAX202, WNDR3800, WNDR4300, WNDR4500v3,
R7000P, R6800, R8000, R8000P, R8500, RAX40, RAX75, RBR40, RBS40, RBR50, RBR50v2, RBS50, SRR60, SRS60, WAX202, WNDR3800, WNDR4300, WNDR4500v3,
WNDR4700, WNR3500), but is likely to be compatible with most other Netgear devices as well.
`mmrpflash` is cross-platform, working on Linux, macOS, Windows, the BSDs, and possibly other POSIX compatible systems.

30
debian/changelog vendored Normal file
View file

@ -0,0 +1,30 @@
nmrpflash (0.9.25-1) unstable; urgency=medium
* new upstream release
-- Penelope Gwen <support@pogmom.me> Mon, 11 Aug 2025 17:55:53 +0000
nmrpflash (0.9.14-16-ge95526d-4) unstable; urgency=medium
* changelog: correct typo in Helmut's name
-- Damyan Ivanov <dmn@debian.org> Sun, 10 May 2020 10:19:58 +0000
nmrpflash (0.9.14-16-ge95526d-3) unstable; urgency=medium
* add patch from Helmut Grohne helping cross-building (Closes: #960165)
-- Damyan Ivanov <dmn@debian.org> Sun, 10 May 2020 07:43:27 +0000
nmrpflash (0.9.14-16-ge95526d-2) unstable; urgency=medium
* use UTC date when passing date to pod2man, making the build reproducible.
Thanks to Chris Lamb. (Closes: #958381)
-- Damyan Ivanov <dmn@debian.org> Tue, 21 Apr 2020 14:38:57 +0000
nmrpflash (0.9.14-16-ge95526d-1) unstable; urgency=medium
* Initial release (Closes: #956867 -- ITP)
-- Damyan Ivanov <dmn@debian.org> Sun, 19 Apr 2020 06:34:46 +0000

28
debian/control vendored Normal file
View file

@ -0,0 +1,28 @@
Source: nmrpflash
Section: otherosfs
Priority: optional
Maintainer: Penelope Gwen <support@pogmom.me>
Build-Depends: debhelper-compat (= 12),
libnl-3-dev,
libnl-route-3-dev,
libpcap-dev,
pkg-config
Standards-Version: 4.5.0
Homepage: https://github.com/jclehner/nmrpflash
Vcs-Browser: https://salsa.debian.org/debian/nmrpflash
Vcs-Git: https://salsa.debian.org/debian/nmrpflash.git
Rules-Requires-Root: no
Package: nmrpflash
Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}
Description: firmware flash utility for Netgear devices
nmrpflash uses Netgear's NMRP protocol
(https://web.archive.org/web/www.chubb.wattle.id.au/PeterChubb/nmrp.html)
to flash a new firmware image to a compatible device. It has been
successfully tested with various models (D7000, DNG3700v2, EX2700,
EX6100v2, EX6120, EX6150v2, EX8000, R6020, R6080, R6100, R6220,
R6400, R7000, R7000P, R6800, R8000, R8000P, R8500, RAX40, RAX75,
RBR40, RBS40, RBR50, RBR50v2, RBS50, SRR60, SRS60, WAX202, WNDR3800,
WNDR4300, WNDR4500v3, WNDR4700, WNR3500), but is likely to be
compatible with most other Netgear devices as well.

29
debian/copyright vendored Normal file
View file

@ -0,0 +1,29 @@
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: nmrpflash
Upstream-Contact: Joseph Lehner <joseph.c.lehner@gmail.com>
Source: https://github.com/jclehner/nmrpflash
Files: *
Copyright: 2016 Joseph Lehner <joseph.c.lehner@gmail.com>
License: GPL-3+
Files: debian/*
Copyright: 2020 Damyan Ivanov <dmn@debian.org>
License: GPL-3+
License: GPL-3+
nmrpflash is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
.
nmrpflash is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
.
You should have received a copy of the GNU General Public License
along with nmrpflash. If not, see <http://www.gnu.org/licenses/>.
.
On a Debian system, the full text of the license is available at
/usr/share/common-licenses/GPL-3

142
debian/nmrpflash.1 vendored Normal file
View file

@ -0,0 +1,142 @@
.\" -*- mode: troff; coding: utf-8 -*-
.\" Automatically generated by Pod::Man 5.0102 (Pod::Simple 3.45)
.\"
.\" Standard preamble:
.\" ========================================================================
.de Sp \" Vertical space (when we can't use .PP)
.if t .sp .5v
.if n .sp
..
.de Vb \" Begin verbatim text
.ft CW
.nf
.ne \\$1
..
.de Ve \" End verbatim text
.ft R
.fi
..
.\" \*(C` and \*(C' are quotes in nroff, nothing in troff, for use with C<>.
.ie n \{\
. ds C` ""
. ds C' ""
'br\}
.el\{\
. ds C`
. ds C'
'br\}
.\"
.\" Escape single quotes in literal strings from groff's Unicode transform.
.ie \n(.g .ds Aq \(aq
.el .ds Aq '
.\"
.\" If the F register is >0, we'll generate index entries on stderr for
.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
.\" entries marked with X<> in POD. Of course, you'll have to process the
.\" output yourself in some meaningful fashion.
.\"
.\" Avoid warning from groff about undefined register 'F'.
.de IX
..
.nr rF 0
.if \n(.g .if rF .nr rF 1
.if (\n(rF:(\n(.g==0)) \{\
. if \nF \{\
. de IX
. tm Index:\\$1\t\\n%\t"\\$2"
..
. if !\nF==2 \{\
. nr % 0
. nr F 2
. \}
. \}
.\}
.rr rF
.\" ========================================================================
.\"
.IX Title "NMRPFLASH 1"
.TH NMRPFLASH 1 2025-08-11 "nmrpflash 0.9.25" "nmrpflash documentation"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
.nh
.SH NAME
nmrpflash \-\- firmware flash utility for Netgear devices
.SH USAGE
.IX Header "USAGE"
nmrpflash [\fIOPTION\fR...]
.SH OPTIONS
.IX Header "OPTIONS"
\&\fB\-i\fR, and \fB\-f\fR or \fB\-c\fR are mandatory
.IP "\fB\-a\fR \fIipaddr\fR" 4
.IX Item "-a ipaddr"
IP address to assign to target device
.IP "\fB\-A\fR \fIipaddr\fR" 4
.IX Item "-A ipaddr"
IP address to assign to selected interface
.IP \fB\-B\fR 4
.IX Item "-B"
Blind mode (don't wait for response packets)
.IP "\fB\-c\fR \fIcommand\fR" 4
.IX Item "-c command"
Command to run before (or instead of) TFTP upload
.IP "\fB\-f\fR \fIfirmware\fR" 4
.IX Item "-f firmware"
Firmware file
.IP "\fB\-F\fR \fIfilename\fR" 4
.IX Item "-F filename"
Remote filename to use during TFTP upload
.IP "\fB\-i\fR \fIinterface\fR" 4
.IX Item "-i interface"
Network interface directly connected to device
.IP "\fB\-m\fR \fImac\fR" 4
.IX Item "-m mac"
MAC address of target device (xx:xx:xx:xx:xx:xx)
.IP "\fB\-M\fR \fInetmask\fR" 4
.IX Item "-M netmask"
Subnet mask to assign to target device
.IP "\fB\-t\fR \fItimeout\fR" 4
.IX Item "-t timeout"
Timeout (in milliseconds) for NMRP packets
.IP "\fB\-T\fR \fItimeout\fR" 4
.IX Item "-T timeout"
Time (seconds) to wait after successful TFTP upload
.IP "\fB\-p\fR \fIport\fR" 4
.IX Item "-p port"
Port to use for TFTP upload
.IP "\fB\-R\fR \fIregion\fR" 4
.IX Item "-R region"
Set device region (NA, WW, GR, PR, RU, BZ, IN, KO, JP)
.IP \fB\-v\fR 4
.IX Item "-v"
Be verbose
.IP \fB\-V\fR 4
.IX Item "-V"
Print version and exit
.IP \fB\-L\fR 4
.IX Item "-L"
List network interfaces
.IP \fB\-h\fR 4
.IX Item "-h"
Show this screen
.SH EXAMPLES
.IX Header "EXAMPLES"
(run as root)
.PP
.Vb 1
\& # nmrpflash \-i eth0 \-f firmware.bin
.Ve
.PP
When using \-c, the environment variables IP, PORT, NETMASK
and MAC are set to the device IP address, TFTP port, subnet
mask and MAC address, respectively.
.SH "COPYRIGHT & LICENSE"
.IX Header "COPYRIGHT & LICENSE"
nmrpflash Copyright (C) 2016 Joseph C. Lehner
.PP
nmrpflash is free software, licensed under the GNU GPLv3.
Source code at <https://github.com/jclehner/nmrpflash>
.PP
This documentation was created by Damyan Ivanov dmn@debian.org from the
\&\f(CW\*(C`nmrpflash\*(C'\fR help text. Licensed under the same terms as the upstream source
code.

1
debian/nmrpflash.manpages vendored Normal file
View file

@ -0,0 +1 @@
debian/nmrpflash.1

104
debian/nmrpflash.pod vendored Normal file
View file

@ -0,0 +1,104 @@
=head1 NAME
nmrpflash -- firmware flash utility for Netgear devices
=head1 USAGE
nmrpflash [I<OPTION>...]
=head1 OPTIONS
B<-i>, and B<-f> or B<-c> are mandatory
=over
=item B<-a> I<ipaddr>
IP address to assign to target device
=item B<-A> I<ipaddr>
IP address to assign to selected interface
=item B<-B>
Blind mode (don't wait for response packets)
=item B<-c> I<command>
Command to run before (or instead of) TFTP upload
=item B<-f> I<firmware>
Firmware file
=item B<-F> I<filename>
Remote filename to use during TFTP upload
=item B<-i> I<interface>
Network interface directly connected to device
=item B<-m> I<mac>
MAC address of target device (xx:xx:xx:xx:xx:xx)
=item B<-M> I<netmask>
Subnet mask to assign to target device
=item B<-t> I<timeout>
Timeout (in milliseconds) for NMRP packets
=item B<-T> I<timeout>
Time (seconds) to wait after successful TFTP upload
=item B<-p> I<port>
Port to use for TFTP upload
=item B<-R> I<region>
Set device region (NA, WW, GR, PR, RU, BZ, IN, KO, JP)
=item B<-v>
Be verbose
=item B<-V>
Print version and exit
=item B<-L>
List network interfaces
=item B<-h>
Show this screen
=back
=head1 EXAMPLES
(run as root)
# nmrpflash -i eth0 -f firmware.bin
When using -c, the environment variables IP, PORT, NETMASK
and MAC are set to the device IP address, TFTP port, subnet
mask and MAC address, respectively.
=head1 COPYRIGHT & LICENSE
nmrpflash Copyright (C) 2016 Joseph C. Lehner
nmrpflash is free software, licensed under the GNU GPLv3.
Source code at L<https://github.com/jclehner/nmrpflash>
This documentation was created by Damyan Ivanov L<dmn@debian.org> from the
C<nmrpflash> help text. Licensed under the same terms as the upstream source
code.

13
debian/pack-upstream-snapshot.sh vendored Normal file
View file

@ -0,0 +1,13 @@
#!/bin/sh
set -e
set -u
BRANCH=upstream/master
PKG=nmrpflash
VER=$(git describe --always $BRANCH|sed 's/^v//')
ORIG_TAR="../${PKG}_${VER}.orig.tar.gz"
git archive --format=tar "--prefix=$PKG-$VER/" "$BRANCH" \
| gzip -9 -n > "$ORIG_TAR"
echo "$ORIG_TAR ready."

24
debian/patches/cross-pkg-config.patch vendored Normal file
View file

@ -0,0 +1,24 @@
Description: improve cross-building by honoring PKG_CONFIG from env
Author: Helmut Grohne
Bug-Debian: https://bugs.debian.org/960165
Bug: https://github.com/jclehner/nmrpflash/pull/37
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,5 @@
CC ?= gcc
+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)
LIBS = -lpcap
@@ -6,8 +7,8 @@ CFLAGS += -Wall -g -DNMRPFLASH_VERSION=\
LDFLAGS += $(LIBS)
ifeq ($(shell uname -s),Linux)
- CFLAGS += $(shell pkg-config libnl-route-3.0 --cflags)
- LIBS += $(shell pkg-config libnl-route-3.0 --libs)
+ CFLAGS += $(shell $(PKG_CONFIG) libnl-route-3.0 --cflags)
+ LIBS += $(shell $(PKG_CONFIG) libnl-route-3.0 --libs)
endif
nmrpflash_OBJ = nmrp.o tftp.o ethsock.o main.o util.o

20
debian/patches/init-intf_addr.patch vendored Normal file
View file

@ -0,0 +1,20 @@
Description: avoid possible use of uninitialized intf_addr in nmrp_do()
Silences a warning by gcc:
.
nmrp.c:462:7: warning: intf_addr may be used uninitialized in this function [-Wmaybe-uninitialized]
462 | if (ethsock_ip_add(sock, intf_addr, ipmask.s_addr, &ip_undo) != 0) {
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Author: Damyan Ivanov <dmn@debian.org>
Forwarded: https://github.com/jclehner/nmrpflash/pull/34
--- a/nmrp.c
+++ b/nmrp.c
@@ -360,7 +360,7 @@ int nmrp_do(struct nmrpd_args *args)
struct ethsock *sock;
struct ethsock_ip_undo *ip_undo = NULL;
struct ethsock_arp_undo *arp_undo = NULL;
- uint32_t intf_addr;
+ uint32_t intf_addr = 0;
void (*sigh_orig)(int);
struct in_addr ipaddr;
struct in_addr ipmask;

4
debian/patches/series vendored Normal file
View file

@ -0,0 +1,4 @@
spelling.patch
init-intf_addr.patch
standalone-version.patch
cross-pkg-config.patch

16
debian/patches/spelling.patch vendored Normal file
View file

@ -0,0 +1,16 @@
Description: small typo in help text
successfull → successful
Author: Damyan Ivanov <dmn@debian.org>
Forwarded: https://github.com/jclehner/nmrpflash/pull/32
--- a/main.c
+++ b/main.c
@@ -41,7 +41,7 @@ void usage(FILE *fp)
" -m <mac> MAC address of target device (xx:xx:xx:xx:xx:xx)\n"
" -M <netmask> Subnet mask to assign to target device\n"
" -t <timeout> Timeout (in milliseconds) for NMRP packets\n"
- " -T <timeout> Time (seconds) to wait after successfull TFTP upload\n"
+ " -T <timeout> Time (seconds) to wait after successful TFTP upload\n"
" -p <port> Port to use for TFTP upload\n"
#ifdef NMRPFLASH_SET_REGION
" -R <region> Set device region (NA, WW, GR, PR, RU, BZ, IN, KO, JP)\n"

25
debian/patches/standalone-version.patch vendored Normal file
View file

@ -0,0 +1,25 @@
Describe: support compiling outside git checkout
When building nmrpflash for Debian, there is no 'git' command available, and
there is no '.git' directory either. This makes the build emit warnings from
the $(shell) calls in VERSION variable in the Makefile and breaks the '-V'
option.
.
The change in this patch accounts for missing 'git' command and resorts to
using a STANDALONE_VERSION environment variable which in turn is provided by
the package build mechanics.
.
This change has no effect when git command and the '.git' directory are
available.
Author: Damyan Ivanov <dmn@debian.org>
https://github.com/jclehner/nmrpflash/pull/35
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
CC ?= gcc
PREFIX ?= /usr/local
-VERSION = $(shell git describe --always | tail -c +2)
+VERSION := $(shell if [ -d .git ] && which git 2>&1 > /dev/null; then git describe --always | tail -c +2; else echo $$STANDALONE_VERSION; fi)
LIBS = -lpcap
CFLAGS += -Wall -g -DNMRPFLASH_VERSION=\"$(VERSION)\"
LDFLAGS += $(LIBS)

29
debian/rules vendored Executable file
View file

@ -0,0 +1,29 @@
#!/usr/bin/make -f
#export DH_VERBOSE = 1
export DPKG_EXPORT_BUILDFAGS=true
include /usr/share/dpkg/pkg-info.mk
include /usr/share/dpkg/buildflags.mk
include /usr/share/dpkg/vendor.mk
export DEB_BUILD_MAINT_OPTIONS = hardening=+all
export STANDALONE_VERSION="$(DEB_VERSION) ($(DEB_VENDOR))"
%:
dh $@
override_dh_auto_build:
CFLAGS="$(CPPFLAGS) $(CFLAGS)" dh_auto_build
MANUALS=debian/nmrpflash.1
debian/nmrpflash.1: debian/nmrpflash.pod
pod2man -c "nmrpflash documentation" \
--release "nmrpflash $(DEB_VERSION_UPSTREAM)" \
--date "$(shell date --utc --date=@$(SOURCE_DATE_EPOCH) +%Y-%m-%d)" \
$< > $@
override_dh_auto_install:: $(MANUALS)
mkdir -p debian/$(DEB_SOURCE)/usr/bin
$(MAKE) install PREFIX=debian/$(DEB_SOURCE)/usr

1
debian/source/format vendored Normal file
View file

@ -0,0 +1 @@
3.0 (quilt)

8
debian/watch vendored Normal file
View file

@ -0,0 +1,8 @@
version=4
# PGP signature mangle, so foo.tar.gz has foo.tar.gz.sig
#opts="pgpsigurlmangle=s%$%.sig%"
opts="filenamemangle=s%(?:.*?)?v?(\d[\d.]*)\.tar\.gz%nmrpflash-$1.tar.gz%" \
https://github.com/jclehner/nmrpflash/tags \
(?:.*?/)?v?(\d[\d.]*)\.tar\.gz debian uupdate

37
main.c
View file

@ -43,7 +43,7 @@ void usage(FILE *fp)
" -T <timeout> Time (seconds) to wait after successfull TFTP upload [%d s]\n"
" -p <port> Port to use for TFTP upload [%d]\n"
#ifdef NMRPFLASH_SET_REGION
" -R <region> Set device region (NA, WW, GR, PR, RU, BZ, IN, KO, JP)\n"
" -R <region> Set device region (NA, WW, GR, PR, RU, BZ, IN, KO, JP, AU)\n"
#endif
" -S <n> Skip <n> bytes of the firmware file\n"
#ifdef NMRPFLASH_TFTP_TEST
@ -71,7 +71,7 @@ void usage(FILE *fp)
"and MAC set to the device IP address, TFTP port, subnet mask and MAC address,\n"
"respectively.\n"
"\n"
"nmrpflash %s, Copyright (C) 2016-2024 Joseph C. Lehner\n"
"nmrpflash %s, Copyright (C) 2016-2025 Joseph C. Lehner\n"
"nmrpflash is free software, licensed under the GNU GPLv3.\n"
"Source code at https://github.com/jclehner/nmrpflash\n"
"\n"
@ -311,13 +311,32 @@ int main(int argc, char **argv)
val = ethsock_list_all();
} else {
val = nmrp_do(&args);
if (val != 0 && args.maybe_invalid_firmware_file) {
fprintf(stderr,
"\n"
"Firmware file rejected by remote device. Possible causes:\n"
"- Wrong firmware file (model number correct?)\n"
"- Wrong file format (e.g. .chk vs .trx file)\n"
"- Downgrading to a lower version number\n");
if (val != 0) {
if (args.hints & NMRP_MAYBE_FIRMWARE_INVALID) {
fprintf(stderr,
"\n"
"Firmware file rejected by router. Possible causes:\n"
"- Wrong firmware file (model number correct?)\n"
"- Wrong file format (e.g. .chk vs .trx file)\n"
"- Downgrading to a lower version number\n");
} else if (args.hints & NMRP_NO_ETHERNET_CONNECTION) {
fprintf(stderr,
"No Ethernet connection detected. Possible causes:\n"
"- Wrong Ethernet port - try others there's more than one\n"
"- Bad Ethernet cable\n"
"- Hardware issue\n");
} else if (args.hints & NMRP_NO_NMRP_RESPONSE) {
fprintf(stderr,
"No response from router. Possible causes/fixes:\n"
"- Unsupported router\n"
"- Wrong Ethernet port - try others if there's more than one\n"
"- Try holding reset button for a few seconds while powering on router\n");
} else if (args.hints & NMRP_TFTP_XMIT_BLK0_FAILURE) {
fprintf(stderr,
"Failed to send/receive initial TFTP packet. Possible fixes:\n"
"- Disable firewall, or add an exception for nmrpflash\n"
"- Manually specify IP addresses using `-a` and/or `-A`");
}
}
}

17
nmrp.c
View file

@ -113,6 +113,7 @@ static uint16_t to_region_code(const char *region)
REGION_CODE("IN", 0x0007);
REGION_CODE("KO", 0x0008);
REGION_CODE("JP", 0x0009);
REGION_CODE("AU", 0x000a);
#undef REGION_CODE
return 0;
}
@ -380,9 +381,9 @@ bool nmrp_discard(struct ethsock *sock)
int ret = pkt_recv(sock, &rx);
if (ret == 0) {
if (rx.msg.code != NMRP_C_CONF_REQ && rx.msg.code != NMRP_C_TFTP_UL_REQ) {
printf("Discarding unexpected %s packet\n", msg_code_str(rx.msg.code));
printf("Discarding unexpected %s packet.\n", msg_code_str(rx.msg.code));
} else if (verbosity > 1) {
printf("Discarding %s packet\n", msg_code_str(rx.msg.code));
printf("Discarding late %s packet.\n", msg_code_str(rx.msg.code));
}
}
@ -411,7 +412,7 @@ int nmrp_do(struct nmrpd_args *args)
struct in_addr ipaddr;
struct in_addr ipmask;
args->maybe_invalid_firmware_file = false;
args->hints = 0;
if (args->op != NMRP_UPLOAD_FW) {
fprintf(stderr, "Operation not implemented.\n");
@ -511,6 +512,7 @@ int nmrp_do(struct nmrpd_args *args)
if (unplugged) {
if (!g_interrupted) {
args->hints |= NMRP_NO_ETHERNET_CONNECTION;
fprintf(stderr, "Error: Ethernet cable is unplugged.\n");
goto out;
} else {
@ -596,8 +598,11 @@ int nmrp_do(struct nmrpd_args *args)
status = 1;
if ((time_monotonic() - beg) >= timeout) {
printf("\nNo response after %d seconds. ", timeout);
args->hints |= NMRP_NO_NMRP_RESPONSE;
if (!args->blind || !was_plugged_in) {
if (!was_plugged_in) {
args->hints |= NMRP_NO_ETHERNET_CONNECTION;
printf("Ethernet cable unplugged. ");
}
@ -640,7 +645,7 @@ int nmrp_do(struct nmrpd_args *args)
msg_code_str(rx.msg.code), msg_code_str(expect));
if (ulreqs && expect == NMRP_C_TFTP_UL_REQ && rx.msg.code == NMRP_C_CONF_REQ) {
args->maybe_invalid_firmware_file = true;
args->hints |= NMRP_MAYBE_FIRMWARE_INVALID;
}
if (++unexpected > 5) {
@ -676,7 +681,7 @@ int nmrp_do(struct nmrpd_args *args)
break;
case NMRP_C_TFTP_UL_REQ:
if (++ulreqs > 1) {
args->maybe_invalid_firmware_file = true;
args->hints |= NMRP_MAYBE_FIRMWARE_INVALID;
}
if (ulreqs > NMRP_MAX_UL_REQS) {
@ -754,7 +759,7 @@ int nmrp_do(struct nmrpd_args *args)
// file has been rejected. this feature is only implemented
// by some bootloaders.
expect = NMRP_C_TFTP_UL_REQ;
args->maybe_invalid_firmware_file = true;
args->hints |= NMRP_MAYBE_FIRMWARE_INVALID;
} else {
goto out;
}

View file

@ -87,6 +87,11 @@
#define NMRP_ETH_TIMEOUT_S 60
#define NMRP_MAX_UL_REQS 3
#define NMRP_MAYBE_FIRMWARE_INVALID (1 << 0)
#define NMRP_NO_ETHERNET_CONNECTION (1 << 1)
#define NMRP_NO_NMRP_RESPONSE (1 << 2)
#define NMRP_TFTP_XMIT_BLK0_FAILURE (1 << 3)
struct eth_hdr {
uint8_t ether_dhost[6];
uint8_t ether_shost[6];
@ -117,7 +122,7 @@ struct nmrpd_args {
uint16_t port;
const char *region;
off_t offset;
bool maybe_invalid_firmware_file;
int hints;
struct ethsock *sock;
};

View file

@ -18,7 +18,7 @@
<Add option="-Wall" />
<Add option="-std=c99" />
<Add option="-m32" />
<Add option='-DNMRPFLASH_VERSION=\&quot;0.9.24\&quot;' />
<Add option='-DNMRPFLASH_VERSION=\&quot;0.9.25\&quot;' />
<Add option="-DWINVER=0x0600" />
<Add option="-D_WIN32_WINNT=0x0600" />
<Add option="-DWIN32_LEAN_AND_MEAN" />

10
tftp.c
View file

@ -240,13 +240,15 @@ static ssize_t tftp_recvfrom(int sock, char *pkt, uint16_t* port,
}
static ssize_t tftp_sendto(int sock, char *pkt, size_t len,
struct sockaddr_in *dst)
struct sockaddr_in *dst, struct nmrpd_args* args)
{
ssize_t sent;
bool is_xrq = false;
switch (pkt_num(pkt)) {
case RRQ:
case WRQ:
is_xrq = true;
case OACK:
len = pkt_xrqlen(pkt);
break;
@ -275,6 +277,9 @@ static ssize_t tftp_sendto(int sock, char *pkt, size_t len,
#ifndef NMRPFLASH_FUZZ
sent = sendto(sock, pkt, len, 0, (struct sockaddr*)dst, sizeof(*dst));
if (sent < 0) {
if (is_xrq) {
args->hints |= NMRP_TFTP_XMIT_BLK0_FAILURE;
}
sock_perror("sendto");
}
#else
@ -489,7 +494,7 @@ ssize_t tftp_put(struct nmrpd_args *args)
bytes += len;
}
ret = tftp_sendto(sock, tx, len, &addr);
ret = tftp_sendto(sock, tx, len, &addr, args);
if (ret < 0) {
goto cleanup;
}
@ -530,6 +535,7 @@ ssize_t tftp_put(struct nmrpd_args *args)
fprintf(stderr, "Timeout while waiting for ACK(%d).\n", block);
} else {
fprintf(stderr, "Timeout while waiting for ACK(0)/OACK.\n");
args->hints |= NMRP_TFTP_XMIT_BLK0_FAILURE;
}
ret = -1;
goto cleanup;