int main (int argc, char const * argv []) { extern struct channel channel; extern void terminate (signo_t); static char const * optv [] = { "dFi:n:N:p:P:qS:t:vw:x", "-N file -P file [-S file]", "Qualcomm Atheros Panther/Lynx PLC Host Daemon", "d\texecute in background as daemon", "F [F]\tflash [force] non-volatile memory", #if defined (WINPCAP) || defined (LIBPCAP) "i n\thost interface is (n) [" LITERAL (CHANNEL_ETHNUMBER) "]", #else "i s\thost interface is (s) [" LITERAL (CHANNEL_ETHDEVICE) "]", #endif "n f\tread firmware from device into file (f)", "N f\tfirmware file is (f)", "p f\tread parameters from device into file (f)", "P f\tparameter file is (f)", "q\tquiet mode", "S f\tsoftloader file is (f)", "t n\tread timeout is (n) milliseconds [" LITERAL (CHANNEL_TIMEOUT) "]", "v\tverbose mode", "w n\twakeup every (n) seconds [" LITERAL (PLC_LONGTIME) "]", "x\texit on error", (char const *) (0) }; #include "../plc/plc.c" struct sigaction sa; char const * socketname = SOCKETNAME; signed c; if (getenv (PLCDEVICE)) { #if defined (WINPCAP) || defined (LIBPCAP) channel.ifindex = atoi (getenv (PLCDEVICE)); #else channel.ifname = strdup (getenv (PLCDEVICE)); #endif } optind = 1; plc.timer = PLC_LONGTIME; while ((c = getoptv (argc, argv, optv)) != -1) { switch (c) { case 'd': _setbits (plc.flags, PLC_DAEMON); break; case 'F': _setbits (plc.module, (VS_MODULE_MAC | VS_MODULE_PIB)); if (_anyset (plc.flags, PLC_FLASH_DEVICE)) { _setbits (plc.module, VS_MODULE_FORCE); } _setbits (plc.flags, PLC_FLASH_DEVICE); break; case 'i': #if defined (WINPCAP) || defined (LIBPCAP) channel.ifindex = atoi (optarg); #else channel.ifname = optarg; #endif break; case 'N': if (!checkfilename (optarg)) { error (1, EINVAL, "%s", optarg); } if ((plc.NVM.file = open (plc.NVM.name = optarg, O_BINARY|O_RDONLY)) == -1) { error (1, errno, "%s", plc.NVM.name); } if (nvmfile2 (&plc.NVM)) { error (1, errno, "Bad firmware file: %s", plc.NVM.name); } _setbits (plc.flags, PLC_WRITE_MAC); break; case 'n': if (!checkfilename (optarg)) { error (1, EINVAL, "%s", optarg); } if ((plc.nvm.file = open (plc.nvm.name = optarg, O_BINARY|O_CREAT|O_RDWR|O_TRUNC, FILE_FILEMODE)) == -1) { error (1, errno, "%s", plc.nvm.name); } break; case 'P': if (!checkfilename (optarg)) { error (1, EINVAL, "%s", optarg); } if ((plc.PIB.file = open (plc.PIB.name = optarg, O_BINARY|O_RDONLY)) == -1) { error (1, errno, "%s", plc.PIB.name); } if (pibfile2 (&plc.PIB)) { error (1, errno, "Bad parameter file: %s", plc.PIB.name); } _setbits (plc.flags, PLC_WRITE_PIB); break; case 'p': if (!checkfilename (optarg)) { error (1, EINVAL, "%s", optarg); } if ((plc.pib.file = open (plc.pib.name = optarg, O_BINARY|O_CREAT|O_RDWR|O_TRUNC, FILE_FILEMODE)) == -1) { error (1, errno, "%s", plc.pib.name); } break; case 'q': _setbits (channel.flags, CHANNEL_SILENCE); _setbits (plc.flags, PLC_SILENCE); break; case 'S': if (!checkfilename (optarg)) { error (1, EINVAL, "%s", optarg); } if ((plc.CFG.file = open (plc.CFG.name = optarg, O_BINARY|O_RDONLY)) == -1) { error (1, errno, "%s", plc.CFG.name); } if (nvmfile2 (&plc.CFG)) { error (1, errno, "Bad firmware file: %s", plc.CFG.name); } break; case 't': channel.timeout = (signed)(uintspec (optarg, 0, UINT_MAX)); break; case 'v': _setbits (channel.flags, CHANNEL_VERBOSE); _setbits (plc.flags, PLC_VERBOSE); break; case 'w': plc.timer = (unsigned)(uintspec (optarg, 1, 3600)); break; case 'x': _setbits (plc.flags, PLC_BAILOUT); break; default: break; } } argc -= optind; argv += optind; if (argc) { error (1, ENOTSUP, ERROR_TOOMANY); } if (plc.NVM.file == -1) { error (1, ECANCELED, "No host NVM file named"); } if (plc.PIB.file == -1) { error (1, ECANCELED, "No host PIB file named"); } if (plc.CFG.file == -1) { if (_anyset (plc.flags, PLC_FLASH_DEVICE)) { error (1, ECANCELED, "No Softloader file named"); } } if (plc.nvm.file == -1) { if ((plc.nvm.file = open (plc.nvm.name = NEWNVM, O_BINARY|O_CREAT|O_RDWR|O_TRUNC, FILE_FILEMODE)) == -1) { error (1, errno, "%s", plc.nvm.name); } } if (plc.pib.file == -1) { if ((plc.pib.file = open (plc.pib.name = NEWPIB, O_BINARY|O_CREAT|O_RDWR|O_TRUNC, FILE_FILEMODE)) == -1) { error (1, errno, "%s", plc.pib.name); } } #ifndef WIN32 if (_anyset (plc.flags, PLC_DAEMON)) { pid_t pid = fork (); if (pid < 0) { error (1, errno, "Can't start daemon"); } if (pid > 0) { exit (0); } } memset (&sa, 0, sizeof (struct sigaction)); sa.sa_handler = terminate; sigaction (SIGTERM, &sa, (struct sigaction *)(0)); sigaction (SIGQUIT, &sa, (struct sigaction *)(0)); sigaction (SIGTSTP, &sa, (struct sigaction *)(0)); sigaction (SIGINT, &sa, (struct sigaction *)(0)); sigaction (SIGHUP, &sa, (struct sigaction *)(0)); #endif openchannel (&channel); if (!(plc.message = malloc (sizeof (* plc.message)))) { error (1, errno, PLC_NOMEMORY); } function (&plc, socketname); free (plc.message); closechannel (&channel); exit (0); }
int main (int argc, char const * argv []) { extern struct channel channel; static char const * optv [] = { "eFi:N:p:P:qS:t:vx", "-N file -P file [device] [device] [...]", "Qualcomm Atheros Panther/Lynx Powerline Device Bootstrapper", "e\tredirect stderr to stdout", "F[F]\tFlash [Force] non-volatile memory after boot", #if defined (WINPCAP) || defined (LIBPCAP) "i n\thost interface is (n) [" OPTSTR (CHANNEL_ETHNUMBER) "]", #else "i s\thost interface is (s) [" OPTSTR (CHANNEL_ETHDEVICE) "]", #endif "N f\tfirmware file is (f)", "P f\tparameter file is (f)", "q\tquiet mode", "S f\tsoftloader file is (f)", "t n\tread timeout is (n) milliseconds [" OPTSTR (CHANNEL_TIMEOUT) "]", "v\tverbose mode", "x\texit on error", (char const *) (0) }; #include "../plc/plc.c" char firmware [PLC_VERSION_STRING]; signed c; if (getenv (PLCDEVICE)) { #if defined (WINPCAP) || defined (LIBPCAP) channel.ifindex = atoi (getenv (PLCDEVICE)); #else channel.ifname = strdup (getenv (PLCDEVICE)); #endif } optind = 1; while ((c = getoptv (argc, argv, optv)) != -1) { switch (c) { case 'e': dup2 (STDOUT_FILENO, STDERR_FILENO); break; case 'F': _setbits (plc.module, (VS_MODULE_MAC | VS_MODULE_PIB)); if (_anyset (plc.flags, PLC_FLASH_DEVICE)) { _setbits (plc.module, VS_MODULE_FORCE); } _setbits (plc.flags, PLC_FLASH_DEVICE); break; case 'i': #if defined (WINPCAP) || defined (LIBPCAP) channel.ifindex = atoi (optarg); #else channel.ifname = optarg; #endif break; case 'N': if (!checkfilename (optarg)) { error (1, EINVAL, "%s", optarg); } if ((plc.NVM.file = open (plc.NVM.name = optarg, O_BINARY|O_RDONLY)) == -1) { error (1, errno, "%s", plc.NVM.name); } if (nvmfile2 (&plc.NVM)) { error (1, errno, "Bad NVM file: %s", plc.NVM.name); } _setbits (plc.flags, PLC_WRITE_MAC); break; case 'P': if (!checkfilename (optarg)) { error (1, EINVAL, "%s", optarg); } if ((plc.PIB.file = open (plc.PIB.name = optarg, O_BINARY|O_RDONLY)) == -1) { error (1, errno, "%s", plc.PIB.name); } if (pibfile2 (&plc.PIB)) { error (1, errno, "Bad PIB file: %s", plc.PIB.name); } _setbits (plc.flags, PLC_WRITE_PIB); break; case 'q': _setbits (channel.flags, CHANNEL_SILENCE); _setbits (plc.flags, PLC_SILENCE); break; case 'S': if (!checkfilename (optarg)) { error (1, EINVAL, "%s", optarg); } if ((plc.CFG.file = open (plc.CFG.name = optarg, O_BINARY|O_RDONLY)) == -1) { error (1, errno, "%s", plc.CFG.name); } if (nvmfile2 (&plc.CFG)) { error (1, errno, "Bad NVM file: %s", plc.CFG.name); } break; case 't': channel.timeout = (signed)(uintspec (optarg, 0, UINT_MAX)); break; case 'v': _setbits (channel.flags, CHANNEL_VERBOSE); _setbits (plc.flags, PLC_VERBOSE); break; case 'x': _setbits (plc.flags, PLC_BAILOUT); break; default: break; } } argc -= optind; argv += optind; if (argc) { error (1, ENOTSUP, ERROR_TOOMANY); } openchannel (&channel); if (!(plc.message = malloc (sizeof (* plc.message)))) { error (1, errno, PLC_NOMEMORY); } if (WaitForStart (&plc, firmware, sizeof (firmware))) { Failure (&plc, PLC_NODETECT); exit (1); } if (plc.hardwareID < CHIPSET_INT6400) { Failure (&plc, "Device must be %s or later; Use program int6kboot instead.", chipsetname (CHIPSET_INT6400)); exit (1); } if (strcmp (firmware, "BootLoader")) { Failure (&plc, "Bootloader must be running"); exit (1); } if (plc.PIB.file == -1) { error (1, ECANCELED, "No Parameter file named"); } if (plc.NVM.file == -1) { error (1, ECANCELED, "No Firmware file named"); } if (plc.CFG.file == -1) { if (_anyset (plc.flags, PLC_FLASH_DEVICE)) { error (1, ECANCELED, "No Softloader file named"); } } if (!InitDevice2 (&plc)) { if (!BootDevice2 (&plc)) { if (_anyset (plc.flags, PLC_FLASH_DEVICE)) { FlashDevice2 (&plc); } } } free (plc.message); closechannel (&channel); exit (0); }
int main (int argc, char const * argv []) { extern struct channel channel; extern const struct key keys []; static char const * optv [] = { "abB:d:D:efFHi:IJ:K:l:mMn:N:p:P:QqrRS:t:Tvw:x", "device [device] [...]", "Qualcomm Atheros Panther/Lynx Powerline Device Manager", "a\tread Device Attributes using VS_OP_ATTRIBUTES", "B n\tperform pushbutton action (n) using MS_PB_ENC [1|2|3|'join'|'leave'|'status']", "d f\tdump and clear watchdog report to file (f) using VS_WD_RPT", "D x\tDevice Access Key (DAK) is (x) [" DAK1 "]", "e\tredirect stderr to stdout", "f\tread NVRAM Configuration using VS_GET_NVM", "F[F]\tflash [force] parameters and/or firmware using VS_MODULE_OPERATION", "H\tstop host action requests using VS_HST_ACTION.IND", #if defined (WINPCAP) || defined (LIBPCAP) "i n\thost interface is (n) [" OPTSTR (CHANNEL_ETHNUMBER) "]", #else "i s\thost interface is (s) [" OPTSTR (CHANNEL_ETHDEVICE) "]", #endif "I\tread device identity using VS_MODULE_OPERATION", "J x\tset NMK on remote device (x) via local device using VS_SET_KEY (see -K)", "K x\tNetwork Membership Key (NMK) is (x) [" NMK1 "]", "l n\tloop (n) times [" OPTSTR (PLCTOOL_LOOP) "]", "m\tread network membership information using VS_NW_INFO", "M\tset NMK on local device using VS_SET_KEY (see -K)", "n f\tread NVM from SDRAM to file (f) using VS_MODULE_OPERATION", "N f\twrite firmware file (f) to flash memory using VS_MODULE_OPERATION", "p f\tread PIB from SDRAM to file (f) using VS_MODULE_OPERATION", "P f\twrite parameter file (f) to flash memory using VS_MODULE_OPERATION", "q\tquiet mode", "Q\tquick flash (return immediately)", "r\tread hardware and firmware revision using VS_SW_VER", "R\treset device using VS_RS_DEV", "S f\twrite softloader file (f) to flash memory using VS_MODULE_OPERATION", "t n\tread timeout is (n) milliseconds [" OPTSTR (CHANNEL_TIMEOUT) "]", "T\trestore factory defaults using VS_FAC_DEFAULTS", "v\tverbose mode", "w n\tpause (n) seconds [" OPTSTR (PLCTOOL_WAIT) "]", "x\texit on error", (char const *) (0) }; #include "../plc/plc.c" signed loop = PLCTOOL_LOOP; signed wait = PLCTOOL_WAIT; signed c; if (getenv (PLCDEVICE)) { #if defined (WINPCAP) || defined (LIBPCAP) channel.ifindex = atoi (getenv (PLCDEVICE)); #else channel.ifname = strdup (getenv (PLCDEVICE)); #endif } optind = 1; while ((c = getoptv (argc, argv, optv)) != -1) { switch (c) { case 'a': _setbits (plc.flags, PLC_ATTRIBUTES); break; case 'B': _setbits (plc.flags, PLC_PUSH_BUTTON); plc.pushbutton = (unsigned)(uintspec (synonym (optarg, buttons, BUTTONS), 0, UCHAR_MAX)); break; case 'b': _setbits (plc.flags, PLC_REMOTEHOSTS); break; case 'd': _setbits (plc.flags, PLC_WATCHDOG_REPORT); if (!checkfilename (optarg)) { error (1, EINVAL, "%s", optarg); } if ((plc.rpt.file = open (plc.rpt.name = optarg, O_BINARY|O_CREAT|O_RDWR|O_TRUNC, FILE_FILEMODE)) == -1) { error (1, errno, "%s", plc.rpt.name); } #ifndef WIN32 chown (optarg, getuid (), getgid ()); #endif plc.readaction = 3; break; case 'D': if (!strcmp (optarg, "none")) { memcpy (plc.DAK, keys [0].DAK, sizeof (plc.DAK)); break; } if (!strcmp (optarg, "key1")) { memcpy (plc.DAK, keys [1].DAK, sizeof (plc.DAK)); break; } if (!strcmp (optarg, "key2")) { memcpy (plc.DAK, keys [2].DAK, sizeof (plc.DAK)); break; } if (!hexencode (plc.DAK, sizeof (plc.DAK), (char const *)(optarg))) { error (1, errno, PLC_BAD_DAK, optarg); } break; case 'e': dup2 (STDOUT_FILENO, STDERR_FILENO); break; case 'f': _setbits (plc.flags, PLC_NVRAM_INFO); break; case 'F': _setbits (plc.module, (VS_MODULE_MAC | VS_MODULE_PIB)); if (_anyset (plc.flags, PLC_FLASH_DEVICE)) { _setbits (plc.module, VS_MODULE_FORCE); } _setbits (plc.flags, PLC_FLASH_DEVICE); break; case 'H': _setbits (plc.flags, PLC_HOST_ACTION); break; case 'I': _setbits (plc.flags, PLC_READ_IDENTITY); break; case 'i': #if defined (WINPCAP) || defined (LIBPCAP) channel.ifindex = atoi (optarg); #else channel.ifname = optarg; #endif break; case 'J': if (!hexencode (plc.RDA, sizeof (plc.RDA), (char const *)(optarg))) { error (1, errno, PLC_BAD_MAC, optarg); } _setbits (plc.flags, PLC_SETREMOTEKEY); break; case 'K': if (!strcmp (optarg, "none")) { memcpy (plc.NMK, keys [0].NMK, sizeof (plc.NMK)); break; } if (!strcmp (optarg, "key1")) { memcpy (plc.NMK, keys [1].NMK, sizeof (plc.NMK)); break; } if (!strcmp (optarg, "key2")) { memcpy (plc.NMK, keys [2].NMK, sizeof (plc.NMK)); break; } if (!hexencode (plc.NMK, sizeof (plc.NMK), (char const *)(optarg))) { error (1, errno, PLC_BAD_NMK, optarg); } break; case 'M': _setbits (plc.flags, PLC_SETLOCALKEY); break; case 'l': loop = (unsigned)(uintspec (optarg, 0, UINT_MAX)); break; case 'm': _setbits (plc.flags, PLC_NETWORK); break; case 'N': if (!checkfilename (optarg)) { error (1, EINVAL, "%s", optarg); } if ((plc.NVM.file = open (plc.NVM.name = optarg, O_BINARY|O_RDONLY)) == -1) { error (1, errno, "%s", plc.NVM.name); } if (nvmfile2 (&plc.NVM)) { error (1, errno, "Bad image file: %s", plc.NVM.name); } _setbits (plc.flags, PLC_FLASH_DEVICE); break; case 'n': if (!checkfilename (optarg)) { error (1, EINVAL, "%s", optarg); } if ((plc.nvm.file = open (plc.nvm.name = optarg, O_BINARY|O_CREAT|O_RDWR|O_TRUNC, FILE_FILEMODE)) == -1) { error (1, errno, "%s", plc.nvm.name); } #ifndef WIN32 chown (optarg, getuid (), getgid ()); #endif _setbits (plc.flags, PLC_READ_MAC); break; case 'P': if (!checkfilename (optarg)) { error (1, EINVAL, "%s", optarg); } if ((plc.PIB.file = open (plc.PIB.name = optarg, O_BINARY|O_RDONLY)) == -1) { error (1, errno, "%s", plc.PIB.name); } if (pibfile2 (&plc.PIB)) { error (1, errno, "Bad image file: %s", plc.PIB.name); } _setbits (plc.flags, PLC_FLASH_DEVICE); break; case 'p': if (!checkfilename (optarg)) { error (1, EINVAL, "%s", optarg); } if ((plc.pib.file = open (plc.pib.name = optarg, O_BINARY|O_CREAT|O_RDWR|O_TRUNC, FILE_FILEMODE)) == -1) { error (1, errno, "%s", plc.pib.name); } #ifndef WIN32 chown (optarg, getuid (), getgid ()); #endif _setbits (plc.flags, PLC_READ_PIB); break; case 'Q': _setbits (plc.flags, PLC_QUICK_FLASH); break; case 'q': _setbits (channel.flags, CHANNEL_SILENCE); _setbits (plc.flags, PLC_SILENCE); break; case 'R': _setbits (plc.flags, PLC_RESET_DEVICE); break; case 'r': _setbits (plc.flags, PLC_VERSION); break; case 'S': if (!checkfilename (optarg)) { error (1, EINVAL, "%s", optarg); } if ((plc.CFG.file = open (plc.CFG.name = optarg, O_BINARY|O_RDONLY)) == -1) { error (1, errno, "%s", plc.CFG.name); } if (nvmfile2 (&plc.CFG)) { error (1, errno, "Bad image file: %s", plc.CFG.name); } _setbits (plc.flags, PLC_FLASH_DEVICE); break; case 't': channel.timeout = (signed)(uintspec (optarg, 0, UINT_MAX)); break; case 'T': _setbits (plc.flags, PLC_FACTORY_DEFAULTS); break; case 'v': _setbits (channel.flags, CHANNEL_VERBOSE); _setbits (plc.flags, PLC_VERBOSE); break; case 'V': _setbits (plc.flags, PLC_SNIFFER); plc.action = (uint8_t)(uintspec (optarg, 0, UCHAR_MAX)); break; case 'w': wait = (unsigned)(uintspec (optarg, 0, 3600)); break; case 'x': _setbits (plc.flags, PLC_BAILOUT); break; default: break; } } argc -= optind; argv += optind; if (argc != 1) { if (plc.nvm.file != -1) { error (1, ECANCELED, PLC_NODEVICE); } if (plc.pib.file != -1) { error (1, ECANCELED, PLC_NODEVICE); } if (plc.rpt.file != -1) { error (1, ECANCELED, PLC_NODEVICE); } } openchannel (&channel); if (!(plc.message = malloc (sizeof (* plc.message)))) { error (1, errno, PLC_NOMEMORY); } if (!argc) { manager (&plc, loop, wait); } while ((argc) && (* argv)) { if (!hexencode (channel.peer, sizeof (channel.peer), synonym (* argv, devices, SIZEOF (devices)))) { error (1, errno, PLC_BAD_MAC, * argv); } manager (&plc, loop, wait); argc--; argv++; } free (plc.message); closechannel (&channel); exit (0); }