modify usage() to optionally display help
[cfe_generate_password.git] / cfe_generate_password.c
index dd5beb4..c1378e4 100644 (file)
@@ -1,79 +1,66 @@
-/*
-  Generate Broadcom CFE seeds and passwords for many popular modem/router devices
-
-  Copyright 2015 TJ <hacker@iam.tj>
-  Licenced on the terms of the GNU General Public Licence version 3
-
-  To build:
-
-    gcc -o cfe_gen_pass cfe_generate_password.c
-
-  Or:
-
-    make
+static const char *title = \
+"Generate Broadcom CFE seeds and passwords for many popular modem/router devices\n"
+;
+static const float VERSION = 1.3f;
 
-  To use:
+static const char *copyright = \
+"Copyright 2015 TJ <hacker@iam.tj>\n"
+"Licenced on the terms of the GNU General Public Licence version 3\n"
+;
 
-    ./cfe_gen_pass [options]
+static const char *help = \
+"This tool can generate passwords for use with many devices that contain Broadcom Common Firmware Environment (CFE) bootbase which has a debug mode that is enabled using the 'ATEN 1 XXXXXXXX' command, where XXXXXXXX is an eight digit hexadecimal 'password'.\n\n"
 
-  This tool can generate passwords for use with many devices that contain
-  Broadcom Common Firmware Environment (CFE) bootbase which has a debug mode
-  that is enabled using the "ATEN 1 XXXXXXXX" command, where XXXXXXXX is an
-  eight digit hexadecimal 'password'.
+"It is NOT necessary to have the device generate a 'seed' using 'ATSE [MODEL-ID]' because this tool can generate the seed from the device's first (base) MAC address.\n\n"
 
-  It is NOT necessary to have the device generate a 'seed' using "ATSE [MODEL-ID]"
-  because this tool can generate the seed from the device's first (base) MAC address.
+"When the device generates a seed it combines the number of seconds since 1970-01-01 00:00:00 with the router MAC address. Both are encoded in a single 6-byte hexadecimal number\n\n"
 
-  When the device generates a seed it combines the number of seconds since 1970-01-01 00:00:00
-  with the router MAC address. Both are encoded in a single 6-byte hexadecimal
+"Each value is truncated to its 3 least significant bytes so, for example:\n\n"
 
-  Each value is truncated to its 3 least significant bytes so, for example:
+" $ date +%F.%T; echo \"obase=16;$(date +%s)\" | bc\n"
+" 2016-03-26.23:06:32\n"
+" 56F715F8\n\n"
 
-  $ date +%F.%T; echo "obase=16;$(date +%s)" | bc
-  2016-03-26.23:06:32
-  56F715F8
-  # MAC Address: EC:43:F6:46:C0:80
+"and MAC Address: EC:43:F6:46:C0:80\n\n"
 
-  becomes F715F8 concatenated with 46C080
+"becomes F715F8 concatenated with 46C080\n\n"
 
-  CFE> ATSE DSL-2492GNAU-B1BC
-  F715F846C080   <<<< last 3 bytes of MAC address
-  ^^^^^^
-  seconds since 1970-01-01 00:00:00 (2016-03-26 23:06:32)
+" CFE> ATSE DSL-2492GNAU-B1BC\n"
+" F715F846C080   <<<< last 3 bytes of MAC address\n"
+" ^^^^^^\n"
+"   seconds since 1970-01-01 00:00:00 (2016-03-26 23:06:32)\n\n"
 
-  *NOTE: the default seed after power-up is 000000 so no time value needs to be specifed
-  if "ATSE <model-id-string>" has not been executed on the device.
+"*NOTE: the default seed after power-up is 000000 so no time value needs to be specifed if 'ATSE <model-id-string>' has not been executed on the device.\n\n"
 
-  Access to the device's console via a serial UART port, or a network telnet/ssh session,
-  is required to enter the password.
+"Access to the device's console via a serial UART port, or a network telnet/ssh session, is required to enter the password.\n\n"
 
-  So, for a device with base MAC address (reported by the CFE during boot) E.g:
+"So, for a device with base MAC address (reported by the CFE during boot) E.g:\n\n"
 
-    CFE version 1.0.38-112.118 for BCM963268 (32bit,SP,BE)
-    ...
-    Base MAC Address                  : ec:43:f6:46:c0:80
-    ...
-    *** Press any key to stop auto run (1 seconds) ***
-    CFE>
+" CFE version 1.0.38-112.118 for BCM963268 (32bit,SP,BE)\n"
+"  ...\n"
+" Base MAC Address                  : ec:43:f6:46:c0:80\n"
+"  ...\n"
+" *** Press any key to stop auto run (1 seconds) ***\n"
+" CFE>\n\n"
 
-  Using this tool do:
+"Using this tool do:\n\n"
 
-    ./cfe_gen_pass -s ec:43:f6:46:c0:80 -p
+" ./cfe_gen_pass -s ec:43:f6:46:c0:80 -p\n\n"
 
-    MAC address: ec:43:f6:46:c0:80 Timestamp: 000000 Seed: 00000046c080 Password: 10f0a563
+" MAC address: ec:43:f6:46:c0:80 Timestamp: 000000 Seed: 00000046c080 Password: 10f0a563\n\n"
 
-  And on the device do:
+"And on the device do:\n\n"
 
-    CFE> ATEN 1 10f0a563
-    OK
-    *** command status = 0
+" CFE> ATEN 1 10f0a563\n"
+" OK\n"
+" *** command status = 0\n\n"
 
-  The tool can accept a timestamp as 8 hexadecimal characters (useful for testing the algorithm):
+"The tool can accept a timestamp as 8 hexadecimal characters (useful for testing the algorithm):\n\n"
 
-    ./cfe_gen_pass -t 0FF020 -s ec:43:f6:46:c0:80 -p
+" ./cfe_gen_pass -t 0FF020 -s ec:43:f6:46:c0:80 -p\n\n"
 
-    MAC address: ec:43:f6:46:c0:80 Timestamp: 0FF020 Seed: 0FF02046c080 Password: 110f65a3
- */
+"MAC address: ec:43:f6:46:c0:80 Timestamp: 0FF020 Seed: 0FF02046c080 Password: 110f65a3\n\n"
+;
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -81,7 +68,6 @@
 #include <string.h>
 #include <time.h>
 
-static const float VERSION = 1.3f;
 static const size_t TIMESTAMP_SIZE = 8;
 static const size_t SEED_SIZE = 12;
 static const size_t PASSWORD_SIZE = 8;
@@ -90,9 +76,9 @@ static const size_t MAC_ADDR_SIZE = 17;
 static const size_t DATESTRING_SIZE = 20;
 
 static void
-pr_usage()
+pr_usage(int verbose)
 {
-  fprintf(stderr, "%s\n",
+  fprintf(stderr,
     "Usage:\n"
     "  -v                   show version\n"
     "  -s 00:01:02:03:04:05 create seed from MAC address\n"
@@ -101,6 +87,9 @@ pr_usage()
     "  E.g. -s 01:02:03:04:05 \n"
     "       -s 01:02:03:04:05 -p\n"
     "       -p 000000030405\n"
+    "\n"
+    "%s",
+    verbose ? help : ""
   );
 }
 
@@ -117,7 +106,7 @@ pr_error_exit(unsigned int usage, const char *error, ...)
  va_end(args);
  fprintf(stderr, "Error: %s\n", error_message);
 
- if (usage) pr_usage();
+ if (usage) pr_usage(usage);
 
  exit(EXIT_FAILURE);
 }
@@ -188,7 +177,7 @@ main(int argc, char **argv, char **env)
   int result = 0;
 
   if (argc == 1) {
-    pr_usage();
+    pr_usage(0);
   }
   else {
     unsigned int arg;
@@ -240,7 +229,7 @@ main(int argc, char **argv, char **env)
       }
     }
     if (! opt_seed && ! opt_pass)
-      pr_usage();
+      pr_usage(0);
     else if (opt_seed && opt_seed != 2)
       pr_error_exit(1, "seed requires MAC-ADDRESS");
     else if (! opt_seed && opt_pass && opt_pass != 2)