Add blind mode (-B)
authorJoseph C. Lehner <joseph.c.lehner@gmail.com>
Sun, 1 Mar 2020 19:08:37 +0000 (20:08 +0100)
committerJoseph C. Lehner <joseph.c.lehner@gmail.com>
Sun, 1 Mar 2020 19:08:37 +0000 (20:08 +0100)
main.c
nmrp.c
nmrpd.h

diff --git a/main.c b/main.c
index 2ef20524c420c74b248bd53fa7b8690cce01b7c1..6dda5e8072fdb4d1b3186216687617da4c9a05bf 100644 (file)
--- a/main.c
+++ b/main.c
@@ -33,6 +33,7 @@ void usage(FILE *fp)
                        "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"
@@ -130,7 +131,7 @@ 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,
                .ul_timeout = 5 * 60 * 1000,
@@ -145,6 +146,7 @@ int main(int argc, char **argv)
                .op = NMRP_UPLOAD_FW,
                .port = 69,
                .region = NULL,
+               .blind = false,
        };
 #ifdef NMRPFLASH_WINDOWS
        char *newpath = NULL;
@@ -181,7 +183,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':
@@ -190,6 +192,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;
@@ -204,6 +209,7 @@ int main(int argc, char **argv)
                                break;
                        case 'm':
                                args.mac = optarg;
+                               have_dest_mac = true;
                                break;
                        case 'M':
                                args.ipmask = optarg;
@@ -243,7 +249,7 @@ int main(int argc, char **argv)
                                ++verbosity;
                                break;
                        case 'L':
-                               list = 1;
+                               list = true;
                                break;
                        case 'h':
                                usage(stdout);
@@ -269,6 +275,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);
diff --git a/nmrp.c b/nmrp.c
index 49070e948adf2889f09ec735517b5ae6471ca3f1..25e3addb80a27a9592f6010f63603584a7a02fda 100644 (file)
--- a/nmrp.c
+++ b/nmrp.c
@@ -356,7 +356,7 @@ 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, kareqs;
        struct ethsock *sock;
        struct ethsock_ip_undo *ip_undo = NULL;
        struct ethsock_arp_undo *arp_undo = NULL;
@@ -472,9 +472,11 @@ int nmrp_do(struct nmrpd_args *args)
        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) {
@@ -483,12 +485,6 @@ int nmrp_do(struct nmrpd_args *args)
                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;
                }
@@ -507,14 +503,19 @@ 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 {
+                                       printf("Continuing blindly.");
+                                       break;
+                               }
                        }
                }
        }
 
-
        printf("\n");
 
        memcpy(tx.eh.ether_dhost, rx.eh.ether_shost, 6);
@@ -679,7 +680,13 @@ int nmrp_do(struct nmrpd_args *args)
                                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);
diff --git a/nmrpd.h b/nmrpd.h
index 0773777c5e255e894b3f90950a7255fa97c40eb0..086d2af93448d0ae8ae5f714bc601cb296a64105 100644 (file)
--- a/nmrpd.h
+++ b/nmrpd.h
@@ -92,6 +92,7 @@ struct nmrpd_args {
        const char *intf;
        const char *mac;
        enum nmrp_op op;
+       bool blind;
        uint16_t port;
        const char *region;
 };