Merge branch 'master' of github.com:jclehner/nmrpflash
This commit is contained in:
commit
c0c951f4a8
8 changed files with 195 additions and 50 deletions
7
Makefile
7
Makefile
|
@ -1,13 +1,14 @@
|
|||
CC ?= gcc
|
||||
PKG_CONFIG ?= pkg-config
|
||||
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)
|
||||
|
||||
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
|
||||
|
||||
ifeq ($(shell uname -s),Darwin)
|
||||
|
|
33
README-R7000.md
Normal file
33
README-R7000.md
Normal file
|
@ -0,0 +1,33 @@
|
|||
Some helpful hints for putting firmware on the Netgear R7000
|
||||
============================================================
|
||||
|
||||
* As of the writing of this, July 2020, the R7000's web interface does not let you downgrade its firmware, or run 3rd party firmware on it.
|
||||
* Older versions of the R7000's firmware do allow you to flash 3rd party firmware.
|
||||
* You can use nrmpflash to downgrade router's firmware, for example R7000-V1.0.3.56_1.1.25.
|
||||
|
||||
Here is an example set of steps
|
||||
1. Plug in your router, go through the regular stock web interface setup. Note if the router's IP address is now 192.168.1.1 or 10.0.0.1
|
||||
2. Connect computer your computer to LAN1 with an ethernet cable
|
||||
3. At the command prompt on your computer, run:
|
||||
`sudo nmrpflash -v -i YOUR_ADAPTER_NAME -f R7000-V1.0.3.56_1.1.25.chk -t 10000 -T 10000 -A 10.0.0.2 -a 10.0.0.1`
|
||||
* Note 1: The instructions from README.md that tell you how to find YOUR_ADAPTER_NAME.
|
||||
* Note 2: if your router's IP address was 192.168.1.1 then swap out 10.0.0.x with 192.168.1.x for the two IP addresses above
|
||||
4. Right after running the command, power on your router. Your router checks for the nmrpflash server on boot. If all goes well you should see this:
|
||||
|
||||
```
|
||||
sudo nmrpflash -v -i enp0s25 -f R7000-V1.0.3.56_1.1.25.chk -t 10000 -T 10000 -A 10.0.0.2 -a 10.0.0.1
|
||||
Adding 10.0.0.2 to interface enp0s25.
|
||||
Advertising NMRP server on enp0s25 ... /
|
||||
Received configuration request from ab:cd:ef:12:34:56.
|
||||
Sending configuration: 10.0.0.1/24.
|
||||
Received upload request without filename.
|
||||
Using remote filename 'R7000-V1.0.3.56_1.1.25.chk'.
|
||||
Uploading R7000-V1.0.3.56_1.1.25.chk ... OK
|
||||
Waiting for remote to respond.
|
||||
Received keep-alive request (19).
|
||||
Remote finished. Closing connection.
|
||||
Reboot your device now.
|
||||
|
||||
```
|
||||
5. Reboot the device. You now have old firwmare, congratulations.
|
||||
|
63
README.md
63
README.md
|
@ -3,7 +3,7 @@ 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, DNG3700v2, R6220, R7000, D7000, WNR3500, R6400 and R6800, but is likely to be compatible
|
||||
EX2700, EX6120, EX6150v2, DNG3700v2, R6220, R7000, D7000, WNR3500, R6400 and R6800, WNDR3800, but is likely to be compatible
|
||||
with many other Netgear devices.
|
||||
|
||||
Prebuilt binaries for Linux, ~OS X~ macOS and Windows are available
|
||||
|
@ -13,16 +13,17 @@ Prebuilt binaries for Linux, ~OS X~ macOS and Windows are available
|
|||
```
|
||||
Usage: nmrpflash [OPTIONS...]
|
||||
|
||||
Options (-i and -f and/or -c are mandatory):
|
||||
Options (-i, and -f or -c are mandatory):
|
||||
-a <ipaddr> IP address to assign to target device
|
||||
-A <ipaddr> IP address to assign to interface
|
||||
-A <ipaddr> IP address to assign to selected interface
|
||||
-B Blind mode (don't wait for response packets)
|
||||
-c <command> Command to run before (or instead of) TFTP upload
|
||||
-f <firmware> Firmware file
|
||||
-F <filename> Remote filename to use during TFTP upload
|
||||
-i <interface> Network interface directly connected to device
|
||||
-m <mac> MAC address of target device (xx:xx:xx:xx:xx:xx)
|
||||
-M <netmask> Subnet mask to assign to target device
|
||||
-t <timeout> Timeout (in milliseconds) for regular messages
|
||||
-t <timeout> Timeout (in milliseconds) for NMRP packets
|
||||
-T <timeout> Time (seconds) to wait after successfull TFTP upload
|
||||
-p <port> Port to use for TFTP upload
|
||||
-R <region> Set device region (NA, WW, GR, PR, RU, BZ, IN, KO, JP)
|
||||
|
@ -38,6 +39,12 @@ Your Netgear router must be connected to your network using an
|
|||
Ethernet cable. The device running `nmrpflash` must be connected
|
||||
to the same network, using either Wi-Fi or Ethernet.
|
||||
|
||||
Usage sequence of events:
|
||||
1. Turn off the router
|
||||
2. Connect ethernet cable from computer to router's LAN1
|
||||
3. Run nmrpflash on command line
|
||||
4. Turn on the router.
|
||||
|
||||
All available network interfaces can be listed using
|
||||
|
||||
```
|
||||
|
@ -93,9 +100,16 @@ C:\> net start npf
|
|||
|
||||
###### "No response after 60 seconds. Bailing out."
|
||||
|
||||
The router did not respond. Try rebooting the device and run `nmrpflash` again.
|
||||
You could also try running `nmrpflash` with `-m` and specify your router's
|
||||
MAC address. It's also possible that your device does not support the NMRP protocol.
|
||||
The router did not respond. Always run `nmrpflash` in the sequence
|
||||
described above!
|
||||
|
||||
If that still doesn't work, you can try "blind mode", which can be
|
||||
invoked using `-B`. Note that you also have to specify your router's
|
||||
mac address using `-m xx:xx:xx:xx:xx:xx`. Also beware that in this mode,
|
||||
careful timing between running `nmrpflash` and turning on the router may
|
||||
be required!
|
||||
|
||||
It's also possible that your device does not support the NMRP protocol.
|
||||
|
||||
###### "Timeout while waiting for ACK(0)/OACK."
|
||||
|
||||
|
@ -157,6 +171,36 @@ By default, file transfers using TFTP are limited to `65535 * 512` bytes
|
|||
(almost 32 MiB). Uploading files exceeding this limit might fail, depending
|
||||
on the device.
|
||||
|
||||
###### "Ignoring extra upload request."
|
||||
|
||||
Extraneous upload requests are usually sent by the device if the image validation
|
||||
failed. Some possible causes are:
|
||||
|
||||
* If you downloaded a firmware that's contained in an archive (a `.zip` for
|
||||
example), you must extract this file, and then use the contained firmware file
|
||||
as the argument to the `-f` parameter. Some examples for file extensions used
|
||||
for firmware: `.chk`, `.bin`, `.trx`, `.img`.
|
||||
|
||||
* Some devices prevent you from downgrading the firmware. See if it works with
|
||||
the latest version available for your device. If you're already using the latest
|
||||
version, it might be possible to patch the version info of the firmware file. A
|
||||
future version of `nmrpflash` might incorporate an auto-patch feature for these
|
||||
cases.
|
||||
|
||||
* Your device might expect a different image format for `nmrpflash` than when
|
||||
flashing via the web interface.
|
||||
|
||||
###### "bind: Cannot assign requested address"
|
||||
|
||||
Specify the address of the router, and address of your computer, using
|
||||
`-A` and `-a`. For example:
|
||||
|
||||
`-A 10.0.0.2 -a 10.0.0.1`
|
||||
|
||||
or
|
||||
|
||||
`-A 192.168.1.2 -a 192.168.1.1`
|
||||
|
||||
### Building and installing
|
||||
###### Linux, Mac OS X, BSDs
|
||||
|
||||
|
@ -173,4 +217,9 @@ project file (`nmrpflash.dev`). Download the latest
|
|||
and extract it into the root folder of the `nmrpflash` sources.
|
||||
|
||||
|
||||
### Donate
|
||||
|
||||
You can [buy me a coffee](https://www.buymeacoffee.com/jclehner) if you want, but please consider
|
||||
donating the money for charity instead - [Médecins Sans Frontiers](https://www.msf.org/donate) comes to mind,
|
||||
but any other organization, local or international, that you think deserves support will do. Thank you!
|
||||
|
||||
|
|
27
main.c
27
main.c
|
@ -28,16 +28,17 @@ void usage(FILE *fp)
|
|||
fprintf(fp,
|
||||
"Usage: nmrpflash [OPTIONS...]\n"
|
||||
"\n"
|
||||
"Options (-i, -f and/or -c are mandatory):\n"
|
||||
"Options (-i, and -f or -c are mandatory):\n"
|
||||
" -a <ipaddr> IP address to assign to target device\n"
|
||||
" -A <ipaddr> IP address to assign to seleted interface\n"
|
||||
" -A <ipaddr> IP address to assign to selected interface\n"
|
||||
" -B Blind mode (don't wait for response packets)\n"
|
||||
" -c <command> Command to run before (or instead of) TFTP upload\n"
|
||||
" -f <firmware> Firmware file\n"
|
||||
" -F <filename> Remote filename to use during TFTP upload\n"
|
||||
" -i <interface> Network interface directly connected to device\n"
|
||||
" -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 regular messages\n"
|
||||
" -t <timeout> Timeout (in milliseconds) for NMRP packets\n"
|
||||
" -T <timeout> Time (seconds) to wait after successfull TFTP upload\n"
|
||||
" -p <port> Port to use for TFTP upload\n"
|
||||
#ifdef NMRPFLASH_SET_REGION
|
||||
|
@ -128,9 +129,9 @@ void require_admin()
|
|||
int main(int argc, char **argv)
|
||||
{
|
||||
int c, val, max;
|
||||
int list = 0;
|
||||
bool list = false, have_dest_mac = false;
|
||||
struct nmrpd_args args = {
|
||||
.rx_timeout = 200,
|
||||
.rx_timeout = 200 * 1000,
|
||||
.ul_timeout = 5 * 60 * 1000,
|
||||
.tftpcmd = NULL,
|
||||
.file_local = NULL,
|
||||
|
@ -143,6 +144,7 @@ int main(int argc, char **argv)
|
|||
.op = NMRP_UPLOAD_FW,
|
||||
.port = 69,
|
||||
.region = NULL,
|
||||
.blind = false,
|
||||
};
|
||||
#ifdef NMRPFLASH_WINDOWS
|
||||
char *newpath = NULL;
|
||||
|
@ -179,7 +181,7 @@ int main(int argc, char **argv)
|
|||
|
||||
opterr = 0;
|
||||
|
||||
while ((c = getopt(argc, argv, "a:A:c:f:F:i:m:M:p:R:t:T:hLVvU")) != -1) {
|
||||
while ((c = getopt(argc, argv, "a:A:Bc:f:F:i:m:M:p:R:t:T:hLVvU")) != -1) {
|
||||
max = 0x7fffffff;
|
||||
switch (c) {
|
||||
case 'a':
|
||||
|
@ -188,6 +190,9 @@ int main(int argc, char **argv)
|
|||
case 'A':
|
||||
args.ipaddr_intf = optarg;
|
||||
break;
|
||||
case 'B':
|
||||
args.blind = true;
|
||||
break;
|
||||
case 'c':
|
||||
args.tftpcmd = optarg;
|
||||
break;
|
||||
|
@ -202,6 +207,7 @@ int main(int argc, char **argv)
|
|||
break;
|
||||
case 'm':
|
||||
args.mac = optarg;
|
||||
have_dest_mac = true;
|
||||
break;
|
||||
case 'M':
|
||||
args.ipmask = optarg;
|
||||
|
@ -227,7 +233,7 @@ int main(int argc, char **argv)
|
|||
if (c == 'p') {
|
||||
args.port = val;
|
||||
} else if (c == 't') {
|
||||
args.rx_timeout = val;
|
||||
args.rx_timeout = val * 1000;
|
||||
} else if (c == 'T') {
|
||||
args.ul_timeout = val * 1000;
|
||||
}
|
||||
|
@ -241,7 +247,7 @@ int main(int argc, char **argv)
|
|||
++verbosity;
|
||||
break;
|
||||
case 'L':
|
||||
list = 1;
|
||||
list = true;
|
||||
break;
|
||||
case 'h':
|
||||
usage(stdout);
|
||||
|
@ -267,6 +273,11 @@ int main(int argc, char **argv)
|
|||
return 1;
|
||||
}
|
||||
|
||||
if (args.blind && !have_dest_mac) {
|
||||
fprintf(stderr, "Error: use of -B requires -m <mac>.\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifndef NMRPFLASH_FUZZ
|
||||
if (!list && ((!args.file_local && !args.tftpcmd) || !args.intf)) {
|
||||
usage(stderr);
|
||||
|
|
88
nmrp.c
88
nmrp.c
|
@ -357,11 +357,11 @@ int nmrp_do(struct nmrpd_args *args)
|
|||
uint16_t region;
|
||||
char *filename;
|
||||
time_t beg;
|
||||
int i, status, ulreqs, expect, upload_ok, autoip, kareqs;
|
||||
int i, timeout, status, ulreqs, expect, upload_ok, autoip, ka_reqs, fake;
|
||||
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;
|
||||
|
@ -385,8 +385,13 @@ int nmrp_do(struct nmrpd_args *args)
|
|||
|
||||
if (!args->ipaddr) {
|
||||
autoip = true;
|
||||
/* The MAC of the device that was used to test this utility starts
|
||||
* with a4:2b:8c, hence 164 (0xa4) and 183 (0x2b + 0x8c)
|
||||
/* A random IP address. The MAC of the first device that was
|
||||
* used to test this utility starts with a4:2b:8c, so we use
|
||||
* 164 (0xa4) and 183 (0x2b + 0x8c).
|
||||
*
|
||||
* These addresses should not cause collisions on most networks,
|
||||
* and if they do, the user is probably "poweruser" enough to
|
||||
* be able to use the -a and -A options.
|
||||
*/
|
||||
args->ipaddr = "10.164.183.252";
|
||||
|
||||
|
@ -477,6 +482,8 @@ int nmrp_do(struct nmrpd_args *args)
|
|||
|
||||
i = 0;
|
||||
upload_ok = 0;
|
||||
fake = 0;
|
||||
timeout = args->blind ? 10 : NMRP_INITIAL_TIMEOUT;
|
||||
beg = time_monotonic();
|
||||
|
||||
while (!g_interrupted) {
|
||||
|
@ -486,7 +493,6 @@ int nmrp_do(struct nmrpd_args *args)
|
|||
i = (i + 1) & 3;
|
||||
|
||||
if (pkt_send(sock, &tx) < 0) {
|
||||
xperror("sendto");
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
@ -504,18 +510,34 @@ int nmrp_do(struct nmrpd_args *args)
|
|||
} else {
|
||||
/* because we don't want nmrpflash's exit status to be zero */
|
||||
status = 1;
|
||||
if ((time_monotonic() - beg) >= NMRP_INITIAL_TIMEOUT) {
|
||||
printf("\nNo response after 60 seconds. Bailing out.\n");
|
||||
goto out;
|
||||
if ((time_monotonic() - beg) >= timeout) {
|
||||
printf("\nNo response after %d seconds. ", timeout);
|
||||
if (!args->blind) {
|
||||
printf("Bailing out.\n");
|
||||
goto out;
|
||||
} else {
|
||||
// we're blind, so fake a response from the MAC specified by -m
|
||||
memcpy(rx.eh.ether_shost, dest, 6);
|
||||
msg_init(&rx.msg, NMRP_C_CONF_REQ);
|
||||
printf("Continuing blindly.");
|
||||
fake = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
|
||||
memcpy(tx.eh.ether_dhost, rx.eh.ether_shost, 6);
|
||||
|
||||
if (ethsock_arp_add(sock, rx.eh.ether_shost, ipaddr.s_addr, &arp_undo) != 0) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
expect = NMRP_C_CONF_REQ;
|
||||
ulreqs = 0;
|
||||
kareqs = 0;
|
||||
ka_reqs = 0;
|
||||
|
||||
while (!g_interrupted) {
|
||||
if (expect != NMRP_C_NONE && rx.msg.code != expect) {
|
||||
|
@ -537,18 +559,14 @@ int nmrp_do(struct nmrpd_args *args)
|
|||
msg_mkconfack(&tx.msg, ipaddr.s_addr, ipmask.s_addr, region);
|
||||
expect = NMRP_C_TFTP_UL_REQ;
|
||||
|
||||
printf("Received configuration request from %s.\n",
|
||||
mac_to_str(rx.eh.ether_shost));
|
||||
|
||||
memcpy(tx.eh.ether_dhost, rx.eh.ether_shost, 6);
|
||||
if (!fake) {
|
||||
printf("Received configuration request from %s.\n",
|
||||
mac_to_str(rx.eh.ether_shost));
|
||||
}
|
||||
|
||||
printf("Sending configuration: %s/%d.\n",
|
||||
args->ipaddr, bitcount(ipmask.s_addr));
|
||||
|
||||
if (ethsock_arp_add(sock, rx.eh.ether_shost, ipaddr.s_addr, &arp_undo) != 0) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
break;
|
||||
case NMRP_C_TFTP_UL_REQ:
|
||||
if (!upload_ok) {
|
||||
|
@ -575,7 +593,9 @@ int nmrp_do(struct nmrpd_args *args)
|
|||
printf("Received upload request: filename '%s'.\n", filename);
|
||||
} else if (!args->file_remote) {
|
||||
args->file_remote = leafname(args->file_local);
|
||||
printf("Received upload request without filename.\n");
|
||||
if (!fake) {
|
||||
printf("Received upload request without filename.\n");
|
||||
}
|
||||
}
|
||||
|
||||
status = 0;
|
||||
|
@ -621,6 +641,10 @@ int nmrp_do(struct nmrpd_args *args)
|
|||
}
|
||||
|
||||
if (!status) {
|
||||
if (args->blind) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
printf("Waiting for remote to respond.\n");
|
||||
upload_ok = 1;
|
||||
ethsock_set_timeout(sock, args->ul_timeout);
|
||||
|
@ -636,7 +660,7 @@ int nmrp_do(struct nmrpd_args *args)
|
|||
case NMRP_C_KEEP_ALIVE_REQ:
|
||||
tx.msg.code = NMRP_C_KEEP_ALIVE_ACK;
|
||||
ethsock_set_timeout(sock, args->ul_timeout);
|
||||
printf("\rReceived keep-alive request (%d). ", ++kareqs);
|
||||
printf("\rReceived keep-alive request (%d). ", ++ka_reqs);
|
||||
break;
|
||||
case NMRP_C_CLOSE_REQ:
|
||||
tx.msg.code = NMRP_C_CLOSE_ACK;
|
||||
|
@ -651,18 +675,13 @@ int nmrp_do(struct nmrpd_args *args)
|
|||
}
|
||||
|
||||
if (tx.msg.code != NMRP_C_NONE) {
|
||||
if (pkt_send(sock, &tx) < 0) {
|
||||
xperror("sendto");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (tx.msg.code == NMRP_C_CLOSE_REQ) {
|
||||
if (pkt_send(sock, &tx) != 0 || tx.msg.code == NMRP_C_CLOSE_REQ) {
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if (rx.msg.code == NMRP_C_CLOSE_REQ) {
|
||||
if (kareqs) {
|
||||
if (ka_reqs) {
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
|
@ -673,10 +692,21 @@ int nmrp_do(struct nmrpd_args *args)
|
|||
status = pkt_recv(sock, &rx);
|
||||
if (status) {
|
||||
if (status == 2) {
|
||||
fprintf(stderr, "Timeout while waiting for %s.\n",
|
||||
msg_code_str(expect));
|
||||
if (!args->blind) {
|
||||
fprintf(stderr, "Timeout while waiting for %s.\n",
|
||||
msg_code_str(expect));
|
||||
goto out;
|
||||
}
|
||||
|
||||
// fake response
|
||||
msg_init(&rx.msg, expect);
|
||||
memcpy(rx.eh.ether_shost, tx.eh.ether_dhost, 6);
|
||||
fake = 1;
|
||||
} else {
|
||||
goto out;
|
||||
}
|
||||
goto out;
|
||||
} else {
|
||||
fake = 0;
|
||||
}
|
||||
|
||||
ethsock_set_timeout(sock, args->rx_timeout);
|
||||
|
|
5
nmrpd.h
5
nmrpd.h
|
@ -62,6 +62,10 @@
|
|||
#define MIN(a, b) ((a) < (b) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
#ifndef MAX
|
||||
#define MAX(a, b) ((a) > (b) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
#ifndef PACKED
|
||||
#define PACKED __attribute__((packed))
|
||||
#endif
|
||||
|
@ -92,6 +96,7 @@ struct nmrpd_args {
|
|||
const char *intf;
|
||||
const char *mac;
|
||||
enum nmrp_op op;
|
||||
bool blind;
|
||||
uint16_t port;
|
||||
const char *region;
|
||||
};
|
||||
|
|
19
tftp.c
19
tftp.c
|
@ -317,6 +317,8 @@ inline bool tftp_is_valid_filename(const char *filename)
|
|||
return strlen(filename) <= 255 && is_netascii(filename);
|
||||
}
|
||||
|
||||
static const char *spinner = "\\|/-";
|
||||
|
||||
int tftp_put(struct nmrpd_args *args)
|
||||
{
|
||||
struct sockaddr_in addr;
|
||||
|
@ -327,6 +329,8 @@ int tftp_put(struct nmrpd_args *args)
|
|||
const char *file_remote = args->file_remote;
|
||||
char *val, *end;
|
||||
bool rollover;
|
||||
const unsigned rx_timeout = MAX(args->rx_timeout / (args->blind ? 50 : 5), 2000);
|
||||
const unsigned max_timeouts = args->blind ? 3 : 5;
|
||||
|
||||
sock = -1;
|
||||
ret = -1;
|
||||
|
@ -383,6 +387,7 @@ int tftp_put(struct nmrpd_args *args)
|
|||
xperror("inet_addr");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
addr.sin_port = htons(args->port);
|
||||
|
||||
blksize = 512;
|
||||
|
@ -429,6 +434,10 @@ int tftp_put(struct nmrpd_args *args)
|
|||
}
|
||||
}
|
||||
|
||||
printf("%c ", spinner[block & 3]);
|
||||
fflush(stdout);
|
||||
printf("\b\b");
|
||||
|
||||
pkt_mknum(tx, DATA);
|
||||
pkt_mknum(tx + 2, block);
|
||||
len = read(fd, tx + 4, blksize);
|
||||
|
@ -463,11 +472,17 @@ int tftp_put(struct nmrpd_args *args)
|
|||
}
|
||||
}
|
||||
|
||||
ret = tftp_recvfrom(sock, rx, &port, args->rx_timeout, blksize + 4);
|
||||
ret = tftp_recvfrom(sock, rx, &port, rx_timeout, blksize + 4);
|
||||
if (ret < 0) {
|
||||
goto cleanup;
|
||||
} else if (!ret) {
|
||||
if (++timeouts < 5 || (!block && timeouts < 10)) {
|
||||
if (++timeouts < max_timeouts || (!block && timeouts < (max_timeouts * 4))) {
|
||||
continue;
|
||||
} else if (args->blind) {
|
||||
timeouts = 0;
|
||||
// fake an ACK packet
|
||||
pkt_mknum(rx, ACK);
|
||||
pkt_mknum(rx + 2, block);
|
||||
continue;
|
||||
} else if (block) {
|
||||
fprintf(stderr, "Timeout while waiting for ACK(%d).\n", block);
|
||||
|
|
|
@ -52,13 +52,14 @@ function nmrp_dissect_opt(opt, buffer, tree)
|
|||
return
|
||||
end
|
||||
|
||||
tree:add(opt_len_f, buffer(2, 2))
|
||||
|
||||
if opt == 0x01 or opt == 0x0181 then
|
||||
tree:add(buffer(4), "Value: " .. buffer(4):string())
|
||||
elseif opt == 0x02 then
|
||||
tree:add(buffer(4, 4), "Address: " .. tostring(buffer(4, 4):ipv4()))
|
||||
tree:add(buffer(8, 4), "Netmask: " .. tostring(buffer(8, 4):ipv4()))
|
||||
else
|
||||
tree:add(opt_len_f, buffer(2, 2))
|
||||
tree:add(opt_data_f, buffer(4, buffer:len() - 4))
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Add table
Reference in a new issue