"Options (-i, -f and/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"
+ " -B Blind mode (don't wait for NMRP responses)\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"
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,
.ul_timeout = 5 * 60 * 1000,
.op = NMRP_UPLOAD_FW,
.port = 69,
.region = NULL,
+ .blind = false,
};
#ifdef NMRPFLASH_WINDOWS
char *newpath = NULL;
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':
case 'A':
args.ipaddr_intf = optarg;
break;
+ case 'B':
+ args.blind = true;
+ break;
case 'c':
args.tftpcmd = optarg;
break;
break;
case 'm':
args.mac = optarg;
+ have_dest_mac = true;
break;
case 'M':
args.ipmask = optarg;
++verbosity;
break;
case 'L':
- list = 1;
+ list = true;
break;
case 'h':
usage(stdout);
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);
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, kareqs;
struct ethsock *sock;
struct ethsock_ip_undo *ip_undo = NULL;
struct ethsock_arp_undo *arp_undo = NULL;
memcpy(tx.eh.ether_dhost, dest, 6);
tx.eh.ether_type = htons(ETH_P_NMRP);
+ msg_mkadvertise(&tx.msg, "NTGR");
i = 0;
upload_ok = 0;
+ timeout = args->blind ? 10 : NMRP_INITIAL_TIMEOUT;
beg = time_monotonic();
while (!g_interrupted) {
fflush(stdout);
i = (i + 1) & 3;
- msg_mkadvertise(&tx.msg, "NTGR");
- if (pkt_send(sock, &tx) < 0) {
- goto out;
- }
-
- msg_mkconfack(&tx.msg, ipaddr.s_addr, ipmask.s_addr, region);
if (pkt_send(sock, &tx) < 0) {
goto out;
}
} 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 {
+ printf("Continuing blindly.");
+ break;
+ }
}
}
}
-
printf("\n");
memcpy(tx.eh.ether_dhost, rx.eh.ether_shost, 6);
fprintf(stderr, "Timeout while waiting for %s.\n",
msg_code_str(expect));
}
- goto out;
+
+ if (!args->blind) {
+ goto out;
+ } else {
+ // fake a response
+ msg_init(&rx.msg, expect);
+ }
}
ethsock_set_timeout(sock, args->rx_timeout);