static void assemble (flag_t flags) { extern signed c; c = mygetc (); while (c != EOF) { if (isspace (c)) { do { c = mygetc (); } while (isspace (c)); continue; } if ((c == '#') || (c == ';')) { do { c = mygetc (); } while (nobreak (c)); continue; } phy = integer (16); reg = integer (16); data = integer (16); mask = integer (16); instr = MDIO16_INSTR (1, 1, phy, reg, 2); write (STDOUT_FILENO, &instr, sizeof (instr)); data = HTOLE16 (data & 0xFFFF); write (STDOUT_FILENO, &data, sizeof (data)); mask = HTOLE16 (mask & 0xFFFF); write (STDOUT_FILENO, &mask, sizeof (mask)); count++; if (_anyset (flags, MDIO_VERBOSE)) { fprintf (stderr, "INSTR=0x%04X DATA=0x%04X MASK=0x%04X\n", instr, data, mask); } if ((c == ';') || (c == EOF)) { c = mygetc (); continue; } if (_allclr (flags, MDIO_SILENCE)) { error (1, 0, "Illegal character or missing terminator: line %d col %d", row, col); } } return; }
static signed DefaultVLANIDs (struct plc * plc, struct item list [], unsigned items) { struct channel * channel = (struct channel *)(plc->channel); struct message * message = (struct message *)(plc->message); #ifndef __GNUC__ #pragma pack (push,1) #endif struct __packed vs_forward_config_request { struct ethernet_hdr ethernet; struct qualcomm_hdr qualcomm; uint8_t RESERVED1; uint8_t MREQUEST; uint8_t MVERSION; uint32_t RESERVED2; uint16_t VLANID; uint16_t RESERVED3; } * request = (struct vs_forward_config_request *) (message); struct __packed vs_forward_config_confirm { struct ethernet_hdr ethernet; struct qualcomm_hdr qualcomm; uint8_t RESERVED1; uint8_t RESULTCODE; uint8_t OPERATION; uint8_t MVERSION; uint32_t RESERVED2; } * confirm = (struct vs_forward_config_confirm *) (message); #ifndef __GNUC__ #pragma pack (pop) #endif memset (message, 0, sizeof (* message)); EthernetHeader (&request->ethernet, channel->peer, channel->host, channel->type); QualcommHeader (&request->qualcomm, 0, (VS_FORWARD_CONFIG | MMTYPE_REQ)); request->MREQUEST = PLCFWD_SET; request->MVERSION = PLCFWD_VER; request->VLANID = HTOLE16 (list [0].VLANID [0]); plc->packetsize = (ETHER_MIN_LEN - ETHER_CRC_LEN); if (SendMME (plc) <= 0) { error (PLC_EXIT (plc), errno, CHANNEL_CANTSEND); return (-1); } while (ReadMME (plc, 0, (VS_FORWARD_CONFIG | MMTYPE_CNF)) > 0) { if (confirm->RESULTCODE) { Failure (plc, PLC_WONTDOIT); continue; } } return (0); }
signed ar7x00_psin (struct _file_ * pib, uint32_t value, uint32_t index) { off_t offset = AMP_PRESCALER_OFFSET + (index * 10 / 8); uint8_t bit_offset = (index * 10) % 8; uint16_t tmp; if (lseek (pib->file, offset, SEEK_SET) != offset) { return (-1); } if (read (pib->file, &tmp, sizeof (tmp)) != sizeof (tmp)) { return (-1); } if (lseek (pib->file, offset, SEEK_SET) != offset) { return (-1); } value &= 0x03FF; tmp = LE16TOH (tmp); tmp &= ~(0x03FF << bit_offset); tmp |= value << bit_offset; tmp = HTOLE16 (tmp); if (write (pib->file, &tmp, sizeof (tmp)) != sizeof (tmp)) { return (-1); } return (0); }
signed QualcommHeader (struct qualcomm_hdr * header, uint8_t MMV, uint16_t MMTYPE) { header->MMV = MMV; header->MMTYPE = HTOLE16 (MMTYPE); header->OUI [0] = 0x00; header->OUI [1] = 0xB0; header->OUI [2] = 0x52; return (sizeof (* header)); }
signed evse_cm_slac_match (struct session * session, struct channel * channel, struct message * message) { struct cm_slac_match_request * request = (struct cm_slac_match_request *) (message); struct cm_slac_match_confirm * confirm = (struct cm_slac_match_confirm *) (message); while (readmessage (channel, message, HOMEPLUG_MMV, (CM_SLAC_MATCH | MMTYPE_REQ)) > 0) { if (! memcmp (session->RunID, request->MatchVarField.RunID, sizeof (session->RunID))) { slac_debug (session, 0, __func__, "<-- CM_SLAC_MATCH.REQ"); memcpy (session->PEV_ID, request->MatchVarField.PEV_ID, sizeof (session->PEV_ID)); memcpy (session->PEV_MAC, request->MatchVarField.PEV_MAC, sizeof (session->PEV_MAC)); memcpy (session->RunID, request->MatchVarField.RunID, sizeof (session->RunID)); #if SLAC_DEBUG if (_anyset (session->flags, SLAC_VERBOSE)) { char string [256]; slac_debug (session, 0, __func__, "CM_SLAC_MATCH.REQ.APPLICATION_TYPE %d", request->APPLICATION_TYPE); slac_debug (session, 0, __func__, "CM_SLAC_MATCH.REQ.SECURITY_TYPE %d", request->SECURITY_TYPE); slac_debug (session, 0, __func__, "CM_SLAC_MATCH.REQ.MVFLength %d", LE16TOH (request->MVFLength)); slac_debug (session, 0, __func__, "CM_SLAC_MATCH.REQ.PEV_ID %s", HEXSTRING (string, request->MatchVarField.PEV_ID)); slac_debug (session, 0, __func__, "CM_SLAC_MATCH.REQ.PEV_MAC %s", HEXSTRING (string, request->MatchVarField.PEV_MAC)); slac_debug (session, 0, __func__, "CM_SLAC_MATCH.REQ.EVSE_ID %s", HEXSTRING (string, request->MatchVarField.EVSE_ID)); slac_debug (session, 0, __func__, "CM_SLAC_MATCH.REQ.EVSE_MAC %s", HEXSTRING (string, request->MatchVarField.EVSE_MAC)); slac_debug (session, 0, __func__, "CM_SLAC_MATCH.REQ.RunID %s", HEXSTRING (string, request->MatchVarField.RunID)); } #endif slac_debug (session, 0, __func__, "--> CM_SLAC_MATCH.CNF"); memset (message, 0, sizeof (* message)); EthernetHeader (& confirm->ethernet, session->PEV_MAC, channel->host, channel->type); HomePlugHeader1 (& confirm->homeplug, HOMEPLUG_MMV, (CM_SLAC_MATCH | MMTYPE_CNF)); confirm->APPLICATION_TYPE = session->APPLICATION_TYPE; confirm->SECURITY_TYPE = session->SECURITY_TYPE; confirm->MVFLength = HTOLE16 (sizeof (confirm->MatchVarField)); memcpy (confirm->MatchVarField.PEV_ID, session->PEV_ID, sizeof (confirm->MatchVarField.PEV_ID)); memcpy (confirm->MatchVarField.PEV_MAC, session->PEV_MAC, sizeof (confirm->MatchVarField.PEV_MAC)); memcpy (confirm->MatchVarField.EVSE_ID, session->EVSE_ID, sizeof (confirm->MatchVarField.EVSE_ID)); memcpy (confirm->MatchVarField.EVSE_MAC, session->EVSE_MAC, sizeof (confirm->MatchVarField.EVSE_MAC)); memcpy (confirm->MatchVarField.RunID, session->RunID, sizeof (confirm->MatchVarField.RunID)); memcpy (confirm->MatchVarField.NID, session->NID, sizeof (confirm->MatchVarField.NID)); memcpy (confirm->MatchVarField.NMK, session->NMK, sizeof (confirm->MatchVarField.NMK)); if (sendmessage (channel, message, sizeof (* confirm)) <= 0) { return (slac_debug (session, 1, __func__, CHANNEL_CANTSEND)); } return (0); } } return (slac_debug (session, session->exit, __func__, "<-- CM_SLAC_MATCH.REQ ?")); }
signed Antiphon (struct plc * plc, byte source [], byte target []) { struct channel * channel = (struct channel *)(plc->channel); struct message * message = (struct message *)(plc->message); #ifndef __GNUC__ #pragma pack (push,1) #endif struct __packed vs_fr_lbk_request { struct ethernet_std ethernet; struct qualcomm_std qualcomm; uint8_t DURATION; uint8_t RESERVED; uint16_t LENGTH; uint8_t PACKET [1038]; } * request = (struct vs_fr_lbk_request *) (message); #ifndef __GNUC__ #pragma pack (pop) #endif if (_allclr (plc->flags, PLC_SILENCE)) { char sourcename [ETHER_ADDR_LEN * 3]; char targetname [ETHER_ADDR_LEN * 3]; hexdecode (source, ETHER_ADDR_LEN, sourcename, sizeof (sourcename)); hexdecode (target, ETHER_ADDR_LEN, targetname, sizeof (targetname)); fprintf (stderr, "%s %s %s\n", channel->ifname, sourcename, targetname); } memset (message, 0, sizeof (* message)); EthernetHeader (&message->ethernet, source, channel->host, HOMEPLUG_MTYPE); QualcommHeader (&message->qualcomm, 0, (VS_FR_LBK | MMTYPE_REQ)); request->DURATION = plc->timer; request->LENGTH = HTOLE16 (sizeof (request->PACKET)); memset (request->PACKET, 0xA5, sizeof (request->PACKET)); EthernetHeader (request->PACKET, target, source, ETHERTYPE_IP); plc->packetsize = sizeof (* request); if (SendMME (plc) <= 0) { error (1, errno, CHANNEL_CANTSEND); } if (ReadMME (plc, 0, (VS_FR_LBK | MMTYPE_CNF)) <= 0) { error (1, errno, CHANNEL_CANTREAD); } sleep (plc->timer); return (0); }
signed FirmwareMessage (void const * memory) { const struct message * message = (const struct message *)(memory); #ifndef __GNUC__ #pragma pack (push,1) #endif static struct qualcomm_hdr header_arpc = { 0, 0, { 0x00, 0xB0, 0x52 } }; struct __packed vs_arpc_indicate { struct ethernet_hdr ethernet; struct qualcomm_hdr qualcomm; uint16_t RDATALENGTH; uint8_t RDATAOFFSET; uint8_t RDATA [1]; } * indicate = (struct vs_arpc_indicate *)(message); #ifndef __GNUC__ #pragma pack (pop) #endif header_arpc.MMTYPE = HTOLE16 (VS_ARPC | MMTYPE_IND); if (!memcmp (&indicate->qualcomm, &header_arpc, sizeof (header_arpc))) { ARPCPrint (stderr, &indicate->RDATA [indicate->RDATAOFFSET], LE16TOH (indicate->RDATALENGTH) - indicate->RDATAOFFSET); return (-1); } return (0); }
static signed pibchain2 (void const * memory, char const * filename, flag_t flags) { struct nvm_header2 * nvm_header; uint32_t origin = ~0; uint32_t offset = 0; signed module = 0; do { nvm_header = (struct nvm_header2 *)((char *)(memory) + offset); if (LE16TOH (nvm_header->MajorVersion) != 1) { if (_allclr (flags, NVM_SILENCE)) { error (0, errno, NVM_HDR_VERSION, filename, module); } return (-1); } if (LE16TOH (nvm_header->MinorVersion) != 1) { if (_allclr (flags, NVM_SILENCE)) { error (0, errno, NVM_HDR_VERSION, filename, module); } return (-1); } if (LE32TOH (nvm_header->PrevHeader) != origin) { if (_allclr (flags, NVM_SILENCE)) { error (0, errno, NVM_HDR_LINK, filename, module); } return (-1); } if (checksum32 (nvm_header, sizeof (* nvm_header), 0)) { error (0, 0, NVM_HDR_CHECKSUM, filename, module); return (-1); } origin = offset; offset += sizeof (* nvm_header); if (LE32TOH (nvm_header->ImageType) == NVM_IMAGE_PIB) { struct pib_header * pib_header = (struct pib_header *)((char *)(memory) + offset); pib_header->PIBLENGTH = HTOLE16((uint16_t)(LE32TOH(nvm_header->ImageLength))); pibpeek2 ((char *)(memory) + offset); pib_header->PIBLENGTH = 0; break; } if (checksum32 ((char *)(memory) + offset, LE32TOH (nvm_header->ImageLength), nvm_header->ImageChecksum)) { if (_allclr (flags, NVM_SILENCE)) { error (0, errno, NVM_IMG_CHECKSUM, filename, module); } return (-1); } offset += LE32TOH (nvm_header->ImageLength); module++; } while (~nvm_header->NextHeader); return (0); }
signed Identity2 (struct plc * plc) { struct channel * channel = (struct channel *)(plc->channel); struct message * message = (struct message *)(plc->message); #ifndef __GNUC__ #pragma pack (push,1) #endif struct __packed vs_module_operation_read_request { struct ethernet_hdr ethernet; struct qualcomm_hdr qualcomm; uint32_t RESERVED; uint8_t NUM_OP_DATA; struct __packed { uint16_t MOD_OP; uint16_t MOD_OP_DATA_LEN; uint32_t MOD_OP_RSVD; uint16_t MODULE_ID; uint16_t MODULE_SUB_ID; uint16_t MODULE_LENGTH; uint32_t MODULE_OFFSET; } MODULE_SPEC; } * request = (struct vs_module_operation_read_request *)(message); struct __packed vs_module_operation_read_confirm { struct ethernet_hdr ethernet; struct qualcomm_hdr qualcomm; uint16_t MSTATUS; uint16_t ERR_REC_CODE; uint32_t RESERVED; uint8_t NUM_OP_DATA; struct __packed { uint16_t MOD_OP; uint16_t MOD_OP_DATA_LEN; uint32_t MOD_OP_RSVD; uint16_t MODULE_ID; uint16_t MODULE_SUB_ID; uint16_t MODULE_LENGTH; uint32_t MODULE_OFFSET; } MODULE_SPEC; uint8_t MODULE_DATA [PLC_MODULE_SIZE]; } * confirm = (struct vs_module_operation_read_confirm *)(message); #ifndef __GNUC__ #pragma pack (pop) #endif memset (message, 0, sizeof (* message)); EthernetHeader (&request->ethernet, channel->peer, channel->host, channel->type); QualcommHeader (&request->qualcomm, 0, (VS_MODULE_OPERATION | MMTYPE_REQ)); plc->packetsize = (ETHER_MIN_LEN - ETHER_CRC_LEN); request->NUM_OP_DATA = 1; request->MODULE_SPEC.MOD_OP = HTOLE16 (0); request->MODULE_SPEC.MOD_OP_DATA_LEN = HTOLE16 (sizeof (request->MODULE_SPEC)); request->MODULE_SPEC.MOD_OP_RSVD = HTOLE32 (0); request->MODULE_SPEC.MODULE_ID = HTOLE16 (PLC_MODULEID_PARAMETERS); request->MODULE_SPEC.MODULE_SUB_ID = HTOLE16 (0); request->MODULE_SPEC.MODULE_LENGTH = HTOLE16 (PLC_MODULE_SIZE); request->MODULE_SPEC.MODULE_OFFSET = HTOLE32 (0); if (SendMME (plc) <= 0) { error (PLC_EXIT (plc), errno, CHANNEL_CANTSEND); return (-1); } if (ReadMME (plc, 0, (VS_MODULE_OPERATION | MMTYPE_CNF)) <= 0) { error (PLC_EXIT (plc), errno, CHANNEL_CANTREAD); return (-1); } if (confirm->MSTATUS) { Failure (plc, PLC_WONTDOIT); return (-1); } pibchain2 (confirm->MODULE_DATA, "device", plc->flags); return (0); }
signed ReadParameterBlock (struct plc * plc, void * memory, size_t extent) { uint8_t * buffer = (uint8_t *)(memory); struct channel * channel = (struct channel *)(plc->channel); struct message * message = (struct message *)(plc->message); #ifndef __GNUC__ #pragma pack (push,1) #endif struct __packed vs_rd_mod_request { struct ethernet_hdr ethernet; struct qualcomm_hdr qualcomm; uint8_t MODULEID; uint8_t MACCESS; uint16_t MLENGTH; uint32_t MOFFSET; uint8_t MSECRET [16]; } * request = (struct vs_rd_mod_request *) (message); struct __packed vs_rd_mod_confirm { struct ethernet_hdr ethernet; struct qualcomm_hdr qualcomm; uint8_t MSTATUS; uint8_t RESERVED1 [3]; uint8_t MODULEID; uint8_t RESERVED; uint16_t MLENGTH; uint32_t MOFFSET; uint32_t CHKSUM; uint8_t BUFFER [PLC_RECORD_SIZE]; } * confirm = (struct vs_rd_mod_confirm *) (message); #ifndef __GNUC__ #pragma pack (pop) #endif uint16_t length = 0; uint32_t offset = 0; signed actual = PLC_RECORD_SIZE; do { memset (message, 0, sizeof (* message)); EthernetHeader (&request->ethernet, channel->peer, channel->host, channel->type); QualcommHeader (&request->qualcomm, 0, (VS_RD_MOD | MMTYPE_REQ)); request->MODULEID = VS_MODULE_PIB; request->MLENGTH = HTOLE16 (actual); request->MOFFSET = HTOLE32 (offset); plc->packetsize = (ETHER_MIN_LEN - ETHER_CRC_LEN); if (SendMME (plc) <= 0) { error (PLC_EXIT (plc), errno, CHANNEL_CANTSEND); return (-1); } if (ReadMME (plc, 0, (VS_RD_MOD | MMTYPE_CNF)) <= 0) { error (PLC_EXIT (plc), errno, CHANNEL_CANTREAD); return (-1); } if (confirm->MSTATUS) { error (PLC_EXIT (plc), ECANCELED, PLC_WONTDOIT); return (-1); } if (LE16TOH (confirm->MLENGTH) != actual) { Failure (plc, PLC_ERR_LENGTH); return (-1); } if (LE32TOH (confirm->MOFFSET) != offset) { Failure (plc, PLC_ERR_OFFSET); return (-1); } actual = LE16TOH (confirm->MLENGTH); offset = LE32TOH (confirm->MOFFSET); if (checksum32 (confirm->BUFFER, actual, confirm->CHKSUM)) { error (PLC_EXIT (plc), ECANCELED, "Bad Packet Checksum"); return (-1); } if (offset == length) { struct pib_header * pib_header = (struct pib_header *) (confirm->BUFFER); length = LE16TOH (pib_header->PIBLENGTH); } if ((offset + actual) > length) { actual = length - offset; } memcpy (buffer + offset, confirm->BUFFER, actual); offset += actual; extent -= actual; } while (offset < length); return (offset); }
static signed PrintWatchdogReport (struct plc * plc, char const * version) { struct channel * channel = (struct channel *)(plc->channel); struct message * message = (struct message *)(plc->message); #ifndef __GNUC__ #pragma pack (push,1) #endif struct __packed vs_wd_rpt_request { struct ethernet_hdr ethernet; struct qualcomm_hdr qualcomm; uint16_t SESSIONID; uint8_t CLR; } * request = (struct vs_wd_rpt_request *) (message); struct __packed vs_wd_rpt_ind { struct ethernet_hdr ethernet; struct qualcomm_hdr qualcomm; uint8_t MSTATUS; uint16_t SESSIONID; uint8_t NUMPARTS; uint8_t CURPART; uint16_t RDATALENGTH; uint8_t RDATAOFFSET; uint8_t RDATA [1]; } * indicate = (struct vs_wd_rpt_ind *) (message); #ifndef __GNUC__ #pragma pack (pop) #endif memset (message, 0, sizeof (* message)); EthernetHeader (&request->ethernet, channel->peer, channel->host, channel->type); QualcommHeader (&request->qualcomm, 0, (VS_WD_RPT | MMTYPE_REQ)); plc->packetsize = (ETHER_MIN_LEN - ETHER_CRC_LEN); request->SESSIONID = HTOLE16 (plc->cookie); request->CLR = plc->readaction; if (SendMME (plc) <= 0) { error (PLC_EXIT (plc), errno, CHANNEL_CANTSEND); return (-1); } printf ("<WatchdogReport>"); do { if (ReadMME (plc, 0, (VS_WD_RPT | MMTYPE_IND)) < 0) { error (PLC_EXIT (plc), errno, CHANNEL_CANTREAD); return (-1); } if (indicate->MSTATUS) { Failure (plc, PLC_WONTDOIT); return (-1); } printf ("<Packet>"); printf ("<Version>%s</Version>", version); printf ("<OUI>%s</OUI>", "00B052"); printf ("<Status>0</Status>"); printf ("<SessionId>0</SessionId>"); printf ("<NumParts>%d</NumParts>", indicate->NUMPARTS); printf ("<CurPart>%d</CurPart>", indicate->CURPART); printf ("<DataLength>%d</DataLength>", LE16TOH (indicate->RDATALENGTH)); printf ("<DataOffset>%d</DataOffset>", indicate->RDATAOFFSET); printf ("<Data>"); b64dump (indicate->RDATA + indicate->RDATAOFFSET, LE16TOH (indicate->RDATALENGTH) - indicate->RDATAOFFSET, 0, stdout); printf ("</Data>"); printf ("</Packet>"); } while (indicate->CURPART < indicate->NUMPARTS); printf ("</WatchdogReport>"); return (0); }
signed ModuleDump (struct plc * plc, uint16_t source, uint16_t module, uint16_t submodule) { struct channel * channel = (struct channel *)(plc->channel); struct message * message = (struct message *)(plc->message); #ifndef __GNUC__ #pragma pack (push,1) #endif struct __packed vs_module_operation_read_request { struct ethernet_hdr ethernet; struct qualcomm_hdr qualcomm; uint32_t RESERVED; uint8_t NUM_OP_DATA; struct __packed { uint16_t MOD_OP; uint16_t MOD_OP_DATA_LEN; uint32_t MOD_OP_RSVD; uint16_t MODULE_ID; uint16_t MODULE_SUB_ID; uint16_t MODULE_LENGTH; uint32_t MODULE_OFFSET; } MODULE_SPEC; } * request = (struct vs_module_operation_read_request *)(message); struct __packed vs_module_operation_read_confirm { struct ethernet_hdr ethernet; struct qualcomm_hdr qualcomm; uint16_t MSTATUS; uint16_t ERR_REC_CODE; uint32_t RESERVED; uint8_t NUM_OP_DATA; struct __packed { uint16_t MOD_OP; uint16_t MOD_OP_DATA_LEN; uint32_t MOD_OP_RSVD; uint16_t MODULE_ID; uint16_t MODULE_SUB_ID; uint16_t MODULE_LENGTH; uint32_t MODULE_OFFSET; } MODULE_SPEC; uint8_t MODULE_DATA [PLC_MODULE_SIZE]; } * confirm = (struct vs_module_operation_read_confirm *)(message); #ifndef __GNUC__ #pragma pack (pop) #endif unsigned offset = 0; unsigned length = PLC_MODULE_SIZE; unsigned timer = channel->timeout; Request (plc, "Read Module from Flash"); while (length == PLC_MODULE_SIZE) { memset (message, 0, sizeof (* message)); EthernetHeader (&request->ethernet, channel->peer, channel->host, channel->type); QualcommHeader (&request->qualcomm, 0, (VS_MODULE_OPERATION | MMTYPE_REQ)); plc->packetsize = (ETHER_MIN_LEN - ETHER_CRC_LEN); request->NUM_OP_DATA = 1; request->MODULE_SPEC.MOD_OP = HTOLE16 (source); request->MODULE_SPEC.MOD_OP_DATA_LEN = HTOLE16 (sizeof (request->MODULE_SPEC)); request->MODULE_SPEC.MOD_OP_RSVD = HTOLE32 (0); request->MODULE_SPEC.MODULE_ID = HTOLE16 (module); request->MODULE_SPEC.MODULE_SUB_ID = HTOLE16 (submodule); request->MODULE_SPEC.MODULE_LENGTH = HTOLE16 (length); request->MODULE_SPEC.MODULE_OFFSET = HTOLE32 (offset); if (SendMME (plc) <= 0) { error (PLC_EXIT (plc), errno, CHANNEL_CANTSEND); return (-1); } channel->timeout = PLC_MODULE_READ_TIMEOUT; if (ReadMME (plc, 0, (VS_MODULE_OPERATION | MMTYPE_CNF)) <= 0) { error (PLC_EXIT (plc), errno, CHANNEL_CANTREAD); channel->timeout = timer; return (-1); } channel->timeout = timer; if (confirm->MSTATUS) { Failure (plc, PLC_WONTDOIT); return (-1); } length = LE16TOH (confirm->MODULE_SPEC.MODULE_LENGTH); offset = LE32TOH (confirm->MODULE_SPEC.MODULE_OFFSET); hexview (confirm->MODULE_DATA, LE32TOH (confirm->MODULE_SPEC.MODULE_OFFSET), LE16TOH (confirm->MODULE_SPEC.MODULE_LENGTH), stdout); offset += length; } return (0); }
signed pev_cm_set_key (struct session * session, struct channel * channel, struct message * message) { #ifndef __GNUC__ #pragma pack(push,1) #endif struct __packed cm_set_key_request { struct ethernet_hdr ethernet; struct homeplug_fmi homeplug; uint8_t KEYTYPE; uint32_t MYNOUNCE; uint32_t YOURNOUNCE; uint8_t PID; uint16_t PRN; uint8_t PMN; uint8_t CCOCAP; uint8_t NID [SLAC_NID_LEN]; uint8_t NEWEKS; uint8_t NEWKEY [SLAC_NMK_LEN]; uint8_t RSVD [3]; } * request = (struct cm_set_key_request *) (message); struct __packed cm_set_key_confirm { struct ethernet_hdr ethernet; struct homeplug_fmi homeplug; uint8_t RESULT; uint32_t MYNOUNCE; uint32_t YOURNOUNCE; uint8_t PID; uint16_t PRN; uint8_t PMN; uint8_t CCOCAP; uint8_t RSVD [27]; } * confirm = (struct cm_set_key_confirm *) (message); #ifndef __GNUC__ #pragma pack (pop) #endif memset (message, 0, sizeof (* message)); slac_debug (session, 0, __func__, "--> CM_SET_KEY.REQ"); EthernetHeader (& request->ethernet, channel->peer, channel->host, channel->type); HomePlugHeader1 (& request->homeplug, HOMEPLUG_MMV, (CM_SET_KEY | MMTYPE_REQ)); request->KEYTYPE = SLAC_CM_SETKEY_KEYTYPE; memset (& request->MYNOUNCE, 0xAA, sizeof (request->MYNOUNCE)); memset (& request->YOURNOUNCE, 0x00, sizeof (request->YOURNOUNCE)); request->PID = SLAC_CM_SETKEY_PID; request->PRN = HTOLE16 (SLAC_CM_SETKEY_PRN); request->PMN = SLAC_CM_SETKEY_PMN; request->CCOCAP = SLAC_CM_SETKEY_CCO; memcpy (request->NID, session->NID, sizeof (request->NID)); request->NEWEKS = SLAC_CM_SETKEY_EKS; memcpy (request->NEWKEY, session->NMK, sizeof (request->NEWKEY)); #if SLAC_DEBUG if (_anyset (session->flags, SLAC_VERBOSE)) { char string [1024]; slac_debug (session, 0, __func__, "CM_SET_KEY.KEYTYPE %d", request->KEYTYPE); slac_debug (session, 0, __func__, "CM_SET_KEY.MYNOUNCE %s", hexstring (string, sizeof (string), & request->MYNOUNCE, sizeof (request->MYNOUNCE))); slac_debug (session, 0, __func__, "CM_SET_KEY.YOURNOUNCE %s", hexstring (string, sizeof (string), & request->YOURNOUNCE, sizeof (request->MYNOUNCE))); slac_debug (session, 0, __func__, "CM_SET_KEY.PID %d", request->PID); slac_debug (session, 0, __func__, "CM_SET_KEY.PRN %d", LE32TOH (request->PRN)); slac_debug (session, 0, __func__, "CM_SET_KEY.PMN %d", request->PMN); slac_debug (session, 0, __func__, "CM_SET_KEY.CCoCAP %d", request->CCOCAP); slac_debug (session, 0, __func__, "CM_SET_KEY.NID %s", HEXSTRING (string, request->NID)); slac_debug (session, 0, __func__, "CM_SET_KEY.NEWEKS %d", request->NEWEKS); slac_debug (session, 0, __func__, "CM_SET_KEY.NEWKEY %s", HEXSTRING (string, request->NEWKEY)); } #endif if (sendpacket (channel, request, sizeof (* request)) <= 0) { return (slac_debug (session, 1, __func__, CHANNEL_CANTSEND)); } while (readpacket (channel, confirm, sizeof (* confirm)) > 0) { if (ntohs (confirm->ethernet.MTYPE) != ETH_P_HPAV) { slac_debug (session, session->exit, __func__, "Ignore MTYPE 0x%04X", htons (confirm->ethernet.MTYPE)); continue; } if (confirm->homeplug.MMV != HOMEPLUG_MMV) { slac_debug (session, session->exit, __func__, "Ignore MMV 0x%02X", confirm->homeplug.MMV); continue; } if (LE32TOH (confirm->homeplug.MMTYPE) != (CM_SET_KEY | MMTYPE_CNF)) { slac_debug (session, session->exit, __func__, "Ignore MMTYPE 0x%04X", LE32TOH (confirm->homeplug.MMTYPE)); continue; } slac_debug (session, 0, __func__, "<-- CM_SET_KEY.CNF"); if (! confirm->RESULT) { return (slac_debug (session, session->exit, __func__, "Can't set keys")); } #if SLAC_DEBUG if (_anyset (session->flags, SLAC_VERBOSE)) { char string [1024]; slac_debug (session, 0, __func__, "CM_SET_KEY.RESULT %d", confirm->RESULT); slac_debug (session, 0, __func__, "CM_SET_KEY.MYNOUNCE %s", hexstring (string, sizeof (string), & confirm->MYNOUNCE, sizeof (confirm->MYNOUNCE))); slac_debug (session, 0, __func__, "CM_SET_KEY.YOURNOUNCE %s", hexstring (string, sizeof (string), & confirm->YOURNOUNCE, sizeof (confirm->MYNOUNCE))); slac_debug (session, 0, __func__, "CM_SET_KEY.PID %d", confirm->PID); slac_debug (session, 0, __func__, "CM_SET_KEY.PRN %d", LE32TOH (confirm->PRN)); slac_debug (session, 0, __func__, "CM_SET_KEY.PMN %d", confirm->PMN); slac_debug (session, 0, __func__, "CM_SET_KEY.CCoCAP %d", confirm->CCOCAP); } #endif return (0); } return (slac_debug (session, session->exit, __func__, "<-- CM_SET_KEY.CNF ?")); }
static signed RemoveVLANIDs (struct plc * plc, struct item list [], unsigned items) { struct channel * channel = (struct channel *)(plc->channel); struct message * message = (struct message *)(plc->message); #ifndef __GNUC__ #pragma pack (push,1) #endif struct __packed vs_forward_config_request { struct ethernet_hdr ethernet; struct qualcomm_hdr qualcomm; uint8_t RESERVED1; uint8_t MREQUEST; uint8_t MVERSION; uint32_t RESERVED2; uint16_t ITEMS; struct item LIST [1]; } * request = (struct vs_forward_config_request *) (message); struct __packed vs_forward_config_confirm { struct ethernet_hdr ethernet; struct qualcomm_hdr qualcomm; uint8_t RESERVED1; uint8_t RESULTCODE; uint8_t OPERATION; uint8_t MVERSION; uint32_t RESERVED2; } * confirm = (struct vs_forward_config_confirm *) (message); #ifndef __GNUC__ #pragma pack (pop) #endif struct item * item = request->LIST; memset (message, 0, sizeof (* message)); EthernetHeader (&request->ethernet, channel->peer, channel->host, channel->type); QualcommHeader (&request->qualcomm, 0, (VS_FORWARD_CONFIG | MMTYPE_REQ)); request->MREQUEST = PLCFWD_REM; request->MVERSION = PLCFWD_VER; request->ITEMS = HTOLE16 (items); while (items--) { unsigned count; memcpy (item->MAC_ADDR, list->MAC_ADDR, sizeof (item->MAC_ADDR)); item->NUM_VLANIDS = HTOLE16 (list->NUM_VLANIDS); for (count = 0; count < list->NUM_VLANIDS; count++) { item->VLANID [count] = HTOLE16 (list->VLANID [count]); } // item++; item = (struct item *)(&item->VLANID [count]); list++; } plc->packetsize = (signed)((uint8_t *)(item) - (uint8_t *)(request)); if (SendMME (plc) <= 0) { error (PLC_EXIT (plc), errno, CHANNEL_CANTSEND); return (-1); } while (ReadMME (plc, 0, (VS_FORWARD_CONFIG | MMTYPE_CNF)) > 0) { if (confirm->RESULTCODE) { Failure (plc, PLC_WONTDOIT); continue; } } return (0); }
signed WritePIB (struct plc * plc) { struct channel * channel = (struct channel *)(plc->channel); struct message * message = (struct message *)(plc->message); #ifndef __GNUC__ #pragma pack (push,1) #endif struct __packed vs_wr_mod_request { struct ethernet_hdr ethernet; struct qualcomm_hdr qualcomm; uint8_t MODULEID; uint8_t RESERVED; uint16_t MLENGTH; uint32_t MOFFSET; uint32_t MCHKSUM; uint8_t MBUFFER [PLC_RECORD_SIZE]; } * request = (struct vs_wr_mod_request *) (message); struct __packed vs_wr_mod_confirm { struct ethernet_hdr ethernet; struct qualcomm_hdr qualcomm; uint8_t MSTATUS; uint8_t MODULEID; uint8_t RESERVED; uint16_t MLENGTH; uint32_t MOFFSET; } * confirm = (struct vs_wr_mod_confirm *) (message); #ifndef __GNUC__ #pragma pack (pop) #endif uint16_t length = PLC_RECORD_SIZE; uint32_t extent = lseek (plc->PIB.file, 0, SEEK_END); uint32_t offset = lseek (plc->PIB.file, 0, SEEK_SET); Request (plc, "Write %s to scratch", plc->PIB.name); while (extent) { memset (message, 0, sizeof (* message)); EthernetHeader (&request->ethernet, channel->peer, channel->host, channel->type); QualcommHeader (&request->qualcomm, 0, (VS_WR_MOD | MMTYPE_REQ)); if (length > extent) { length = extent; } if (read (plc->PIB.file, request->MBUFFER, length) != length) { error (1, errno, FILE_CANTREAD, plc->PIB.name); } request->MODULEID = VS_MODULE_PIB; request->RESERVED = 0; request->MLENGTH = HTOLE16 (length); request->MOFFSET = HTOLE32 (offset); request->MCHKSUM = checksum32 (request->MBUFFER, length, 0); plc->packetsize = sizeof (* request); if (SendMME (plc) <= 0) { error (PLC_EXIT (plc), errno, CHANNEL_CANTSEND); return (-1); } if (ReadMME (plc, 0, (VS_WR_MOD | MMTYPE_CNF)) <= 0) { error (PLC_EXIT (plc), errno, CHANNEL_CANTREAD); return (-1); } if (confirm->MSTATUS) { Failure (plc, PLC_WONTDOIT); return (-1); } if (LE16TOH (confirm->MLENGTH) != length) { error (PLC_EXIT (plc), 0, PLC_ERR_LENGTH); length = PLC_RECORD_SIZE; offset = 0; continue; } if (LE32TOH (confirm->MOFFSET) != offset) { error (PLC_EXIT (plc), 0, PLC_ERR_OFFSET); length = PLC_RECORD_SIZE; offset = 0; continue; } extent -= length; offset += length; } return (0); }
signed ModuleSession (struct plc * plc, unsigned modules, struct vs_module_spec * vs_module_spec) { struct channel * channel = (struct channel *)(plc->channel); struct message * message = (struct message *)(plc->message); #ifndef __GNUC__ #pragma pack (push,1) #endif struct __packed vs_module_operation_start_request { struct ethernet_std ethernet; struct qualcomm_std qualcomm; uint32_t RESERVED1; uint8_t NUM_OP_DATA; struct __packed { uint16_t MOD_OP; uint16_t MOD_OP_DATA_LEN; uint32_t MOD_OP_RSVD; uint32_t MOD_OP_SESSION_ID; uint8_t NUM_MODULES; } MODULE_SPEC; struct vs_module_spec MOD_OP_SPEC [10]; } * request = (struct vs_module_operation_start_request *)(message); struct __packed vs_module_operation_start_confirm { struct ethernet_std ethernet; struct qualcomm_std qualcomm; uint16_t MSTATUS; uint16_t ERR_REC_CODE; uint32_t RESERVED; uint8_t NUM_OP_DATA; struct __packed { uint16_t MOD_OP; uint16_t MOD_OP_DATA_LEN; uint32_t MOD_OP_RSVD; uint32_t MOD_OP_SESSION_ID; uint8_t NUM_MODULES; } MODULE_SPEC; struct __packed { uint16_t MOD_STATUS; uint16_t ERR_REC_CODE; } MOD_OP_DATA [1]; } * confirm = (struct vs_module_operation_start_confirm *)(message); #ifndef __GNUC__ #pragma pack (pop) #endif unsigned timer = channel->timeout; struct vs_module_spec * request_spec = (struct vs_module_spec *)(&request->MOD_OP_SPEC); Request (plc, "Start Module Write Session"); memset (message, 0, sizeof (* message)); EthernetHeader (&request->ethernet, channel->peer, channel->host, channel->type); QualcommHeader (&request->qualcomm, 0, (VS_MODULE_OPERATION | MMTYPE_REQ)); plc->packetsize = sizeof (* request); request->NUM_OP_DATA = 1; request->MODULE_SPEC.MOD_OP = HTOLE16 (PLC_MOD_OP_START_SESSION); request->MODULE_SPEC.MOD_OP_DATA_LEN = HTOLE16 ((uint16_t)(sizeof (request->MODULE_SPEC)) + modules * sizeof (struct vs_module_spec)); request->MODULE_SPEC.MOD_OP_SESSION_ID = HTOLE32 (plc->cookie); request->MODULE_SPEC.NUM_MODULES = modules; while (modules--) { request_spec->MODULE_ID = HTOLE16 (vs_module_spec->MODULE_ID); request_spec->MODULE_SUB_ID = HTOLE16 (vs_module_spec->MODULE_SUB_ID); request_spec->MODULE_LENGTH = HTOLE32 (vs_module_spec->MODULE_LENGTH); request_spec->MODULE_CHKSUM = vs_module_spec->MODULE_CHKSUM; vs_module_spec++; request_spec++; } if (SendMME (plc) <= 0) { error ((plc->flags & PLC_BAILOUT), errno, CHANNEL_CANTSEND); return (-1); } channel->timeout = PLC_MODULE_REQUEST_TIMEOUT; if (ReadMME (plc, 0, (VS_MODULE_OPERATION | MMTYPE_CNF)) <= 0) { error ((plc->flags & PLC_BAILOUT), errno, CHANNEL_CANTREAD); channel->timeout = timer; return (-1); } channel->timeout = timer; if (confirm->MSTATUS) { Failure (plc, PLC_WONTDOIT); return (-1); } return (0); }
signed ReadParameters1 (struct plc * plc) { struct channel * channel = (struct channel *)(plc->channel); struct message * message = (struct message *)(plc->message); #ifndef __GNUC__ #pragma pack (push,1) #endif struct __packed vs_rd_mod_request { struct ethernet_std ethernet; struct qualcomm_std qualcomm; uint8_t MODULEID; uint8_t MACCESS; uint16_t MLENGTH; uint32_t MOFFSET; uint8_t MSECRET [16]; } * request = (struct vs_rd_mod_request *) (message); struct __packed vs_rd_mod_confirm { struct ethernet_std ethernet; struct qualcomm_std qualcomm; uint8_t MSTATUS; uint8_t RESERVED1 [3]; uint8_t MODULEID; uint8_t RESERVED; uint16_t MLENGTH; uint32_t MOFFSET; uint32_t CHKSUM; uint8_t BUFFER [PLC_RECORD_SIZE]; } * confirm = (struct vs_rd_mod_confirm *) (message); #ifndef __GNUC__ #pragma pack (pop) #endif uint32_t extent = 0; uint32_t offset = 0; uint16_t length = PLC_RECORD_SIZE; Request (plc, "Read Parameters from Device"); if (lseek (plc->pib.file, 0, SEEK_SET)) { error ((plc->flags & PLC_BAILOUT), errno, FILE_CANTHOME, plc->pib.name); return (1); } do { memset (message, 0, sizeof (* message)); EthernetHeader (&request->ethernet, channel->peer, channel->host, channel->type); QualcommHeader (&request->qualcomm, 0, (VS_RD_MOD | MMTYPE_REQ)); plc->packetsize = (ETHER_MIN_LEN - ETHER_CRC_LEN); request->MODULEID = VS_MODULE_PIB; request->MLENGTH = HTOLE16 (length); request->MOFFSET = HTOLE32 (offset); if (SendMME (plc) <= 0) { error ((plc->flags & PLC_BAILOUT), errno, CHANNEL_CANTSEND); return (-1); } if (ReadMME (plc, 0, (VS_RD_MOD | MMTYPE_CNF)) <= 0) { error ((plc->flags & PLC_BAILOUT), errno, CHANNEL_CANTREAD); return (-1); } if (confirm->MSTATUS) { Failure (plc, PLC_WONTDOIT); return (-1); } if (LE16TOH (confirm->MLENGTH) != length) { error ((plc->flags & PLC_BAILOUT), 0, PLC_ERR_LENGTH); return (-1); } if (LE32TOH (confirm->MOFFSET) != offset) { error ((plc->flags & PLC_BAILOUT), 0, PLC_ERR_OFFSET); return (-1); } length = LE16TOH (confirm->MLENGTH); offset = LE32TOH (confirm->MOFFSET); if (checksum32 (confirm->BUFFER, length, confirm->CHKSUM)) { error ((plc->flags & PLC_BAILOUT), ECANCELED, "Bad Packet Checksum"); return (-1); } if (offset == extent) { struct pib_header * pib_header = (struct pib_header *) (confirm->BUFFER); extent = LE16TOH (pib_header->PIBLENGTH); } if ((offset + length) > extent) { length = extent - offset; } if (lseek (plc->pib.file, offset, SEEK_SET) != (signed)(offset)) { error ((plc->flags & PLC_BAILOUT), errno, FILE_CANTSEEK, plc->pib.name); return (-1); } if (write (plc->pib.file, confirm->BUFFER, length) != (signed)(length)) { error ((plc->flags & PLC_BAILOUT), errno, FILE_CANTSAVE, plc->pib.name); return (-1); } offset += length; } while (offset < extent); Confirm (plc, "Read %s", plc->pib.name); return (0); }
signed CPLFirmware::Read (CPLChannel * channel) { ointellon intellon; uint8_t message [ETHER_MAX_LEN]; #ifndef __GNUC__ #pragma pack (push,1) #endif struct __packed vs_rd_mod_request { struct header_eth ethernet; struct header_int intellon; uint8_t MODULEID; uint8_t MACCESS; uint16_t MLENGTH; uint32_t MOFFSET; uint8_t MSECRET [16]; } * request = (struct vs_rd_mod_request *) (message); struct __packed vs_rd_mod_confirm { struct header_eth ethernet; struct header_int intellon; uint8_t MSTATUS; uint8_t RES [3]; uint8_t MODULEID; uint8_t RESERVED; uint16_t MLENGTH; uint32_t MOFFSET; uint32_t CHKSUM; uint8_t BUFFER [INT6K_BLOCKSIZE]; } * confirm = (struct vs_rd_mod_confirm *) (message); #ifndef __GNUC__ #pragma pack (pop) #endif uint16_t extent = 0; uint16_t length = oINTELLON_BLOCKSIZE; uint32_t offset = 0; intellon.ImportPeerAddress (channel->PeerAddress ()); intellon.ImportHostAddress (channel->HostAddress ()); intellon.SetMessageType (VS_RD_MOD | MMTYPE_REQ); do { std::memset (message, 0, sizeof (message)); request = (struct vs_rd_mod_request *)(intellon.ExportHeader (message)); confirm = (struct vs_rd_mod_confirm *)(request); request->MODULEID = VS_MODULE_MAC; request->MLENGTH = HTOLE16 (length); request->MOFFSET = HTOLE32 (offset); if (channel->SendMessage (message, ETHER_MIN_LEN) <= 0) { oerror::error (0, ECANCELED, CPLCHANNEL_CANTSEND); return (-1); } if (channel->ReadMessage (message, sizeof (message)) <= 0) { oerror::error (0, ECANCELED, CPLCHANNEL_CANTREAD); return (-1); } if (confirm->MSTATUS) { oerror::error (0, ECANCELED, CPLCHANNEL_WONTDOIT); return (-1); } #if 1 if (LE16TOH (confirm->MLENGTH) != length) { oerror::error (0, ECANCELED, oINTELLON_BAD_LENGTH); return (-1); } if (LE32TOH (confirm->MOFFSET) != offset) { oerror::error (0, ECANCELED, oINTELLON_BAD_LENGTH); return (-1); } #else if (LE16TOH (confirm->MLENGTH) != length) { oerror::error (0, EIO, oINTELLON_BAD_LENGTH); this->mlength = INT6K_BLOCKSIZE; this->moffset = 0; continue; } if (LE32TOH (confirm->MOFFSET) != this->moffset) { oerror::error (0, EIO, oINTELLON_BAD_OFFSET); this->mlength = INT6K_BLOCKSIZE; this->moffset = 0; continue; } #endif length = LE16TOH (confirm->MLENGTH); offset = LE32TOH (confirm->MOFFSET); if (omemory::checksum32 (confirm->MBUFFER, length, confirm->MCHKSUM)) { oerror::error (0, ECANCELED, "Bad Message Checksum"); return (-1); } if (offset == extent) { CPLFirmware::Header * header = (CPLFirmware::Header *)(confirm->BUFFER); if (checksum_32 (header, sizeof (CPLFirmware::Header), 0)) { oerror::error (0, ECANCELED, "Bad Header Checksum"); return (-1); } if (header_nvm->HEADERVERSION != NVM_HEADER_VERSION) { oerror::error (0, ECANCELED, "Bad Header Version"); return (-1); } extent += sizeof (CPLFirmware::Header); extent += LE32TOH (header_nvm->IMAGELENGTH); header = LE16TOH (header_nvm->NEXTHEADER); } if ((offset + length) > extent) { length = extent - offset; } std::memcpy (this->mbuffer + offset, confirm->MBUFFER, length); offset += length; extent -= length; } while ((header) || (offset < extent)); return (0); }
signed pev_cm_slac_param (struct session * session, struct channel * channel, struct message * message) { extern byte const broadcast [ETHER_ADDR_LEN]; struct cm_slac_param_request * request = (struct cm_slac_param_request *) (message); struct cm_slac_param_confirm * confirm = (struct cm_slac_param_confirm *) (message); slac_debug (session, 0, __func__, "--> CM_SLAC_PARAM.REQ"); memset (message, 0, sizeof (* message)); EthernetHeader (& request->ethernet, broadcast, channel->host, channel->type); HomePlugHeader1 (& request->homeplug, HOMEPLUG_MMV, (CM_SLAC_PARAM | MMTYPE_REQ)); request->APPLICATION_TYPE = session->APPLICATION_TYPE; request->SECURITY_TYPE = session->SECURITY_TYPE; memcpy (request->RunID, session->RunID, sizeof (request->RunID)); request->CipherSuite [0] = HTOLE16 ((uint16_t) (session->counter)); if (sendmessage (channel, message, (ETHER_MIN_LEN - ETHER_CRC_LEN)) <= 0) { return (slac_debug (session, 1, __func__, CHANNEL_CANTSEND)); } while (readmessage (channel, message, HOMEPLUG_MMV, (CM_SLAC_PARAM | MMTYPE_CNF)) > 0) { if (! memcmp (session->RunID, confirm->RunID, sizeof (session->RunID))) { slac_debug (session, 0, __func__, "<-- CM_SLAC_PARAM.CNF"); if (confirm->APPLICATION_TYPE != session->APPLICATION_TYPE) { slac_debug (session, session->exit, __func__, "Unexpected APPLICATION_TYPE"); } if (confirm->SECURITY_TYPE != session->SECURITY_TYPE) { slac_debug (session, session->exit, __func__, "Unexpected SECURITY_TYPE"); } if (_anyset (session->flags, SLAC_COMPARE)) { if (LE16TOH (confirm->CipherSuite) != (uint16_t) (session->counter)) { slac_debug (session, session->exit, __func__, "session->counter mismatch! PEV=(%d) EVSE=(%d)", LE16TOH (confirm->CipherSuite), session->counter); } } #if SLAC_DEBUG if (_anyset (session->flags, SLAC_VERBOSE)) { char string [256]; slac_debug (session, 0, __func__, "CM_SLAC_PARAM.CNF.MSOUND_TARGET %s", HEXSTRING (string, confirm->MSOUND_TARGET)); slac_debug (session, 0, __func__, "CM_SLAC_PARAM.CNF.NUM_SOUNDS %d", confirm->NUM_SOUNDS); slac_debug (session, 0, __func__, "CM_SLAC_PARAM.CNF.TIME_OUT %d", confirm->TIME_OUT); slac_debug (session, 0, __func__, "CM_SLAC_PARAM.CNF.RESP_TYPE %d", confirm->RESP_TYPE); slac_debug (session, 0, __func__, "CM_SLAC_PARAM.CNF.FORWARDING_STA %s", HEXSTRING (string, confirm->FORWARDING_STA)); slac_debug (session, 0, __func__, "CM_SLAC_PARAM.CNF.APPLICATION_TYPE %d", confirm->APPLICATION_TYPE); slac_debug (session, 0, __func__, "CM_SLAC_PARAM.CNF.SECURITY_TYPE %d", confirm->SECURITY_TYPE); slac_debug (session, 0, __func__, "CM_SLAC_PARAM.CNF.RunID %s", HEXSTRING (string, confirm->RunID)); slac_debug (session, 0, __func__, "CM_SLAC_PARAM.CNF.CipherSuite %d", confirm->CipherSuite); } #endif memcpy (session->FORWARDING_STA, confirm->FORWARDING_STA, sizeof (session->FORWARDING_STA)); memcpy (session->MSOUND_TARGET, confirm->MSOUND_TARGET, sizeof (session->MSOUND_TARGET)); session->NUM_SOUNDS = confirm->NUM_SOUNDS; session->TIME_OUT = confirm->TIME_OUT; session->RESP_TYPE = confirm->RESP_TYPE; return (0); } } return (slac_debug (session, 0, __func__, "<-- CM_SLAC_PARAM.CNF ?")); }
int main (int argc, char const * argv []) { extern struct channel channel; static char const * optv [] = { "ei:qrst:T:vV:", "action operand condition [...] control volatility [device] [...]\n\n where a condition is: field operator value", "Qualcomm Atheros Stream MakeRules Utility", "e\tredirect stderr to stdout", #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 "q\tquiet mode", "r\tread rules from device", "s\tdisplay symbol tables", "t n\tread timeout is (n) milliseconds [" LITERAL (CHANNEL_TIMEOUT) "]", "T x\tinserted vlan tag is x [" LITERAL (PLCRULE_VLAN_TAG) "]", "v\tverbose mode", "V n\tcspec version is n [" LITERAL (PLCRULE_CSPEC_VERSION) "]", (char const *) (0) }; #include "../plc/plc.c" struct cspec cspec; struct MMERule rule; signed c; memset (& rule, 0, sizeof (rule)); memset (& cspec, 0, sizeof (cspec)); cspec.VLAN_TAG = PLCRULE_VLAN_TAG; cspec.CSPEC_VERSION = PLCRULE_CSPEC_VERSION; 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))) { switch (c) { case 'e': dup2 (STDOUT_FILENO, STDERR_FILENO); break; case 'i': #if defined (WINPCAP) || defined (LIBPCAP) channel.ifindex = atoi (optarg); #else channel.ifname = optarg; #endif break; case 'q': _setbits (channel.flags, CHANNEL_SILENCE); _setbits (plc.flags, PLC_SILENCE); break; case 'r': _setbits (plc.flags, PLC_ANALYSE); break; case 's': printf ("\n"); printf (" Controls are "); codelist (controls, SIZEOF (controls), COMMA, QUOTE, stdout); printf (".\n"); printf (" Volatilities are "); codelist (volatilities, SIZEOF (volatilities), COMMA, QUOTE, stdout); printf (".\n"); printf (" Actions are "); codelist (actions, SIZEOF (actions), COMMA, QUOTE, stdout); printf (".\n"); printf (" Operands are "); codelist (operands, SIZEOF (operands), COMMA, QUOTE, stdout); printf (".\n"); printf (" Fields are "); codelist (fields, SIZEOF (fields), COMMA, QUOTE, stdout); printf (".\n"); printf (" Operators are "); codelist (operators, SIZEOF (operators), COMMA, QUOTE, stdout); printf (".\n"); printf (" States are "); codelist (states, SIZEOF (states), COMMA, QUOTE, stdout); printf (".\n"); printf ("\n"); return (0); case 't': channel.timeout = (signed) (uintspec (optarg, 0, UINT_MAX)); break; case 'T': cspec.VLAN_TAG = (uint32_t) (basespec (optarg, 16, sizeof (cspec.VLAN_TAG))); cspec.VLAN_TAG = htonl (cspec.VLAN_TAG); break; case 'v': _setbits (channel.flags, CHANNEL_VERBOSE); _setbits (plc.flags, PLC_VERBOSE); break; case 'V': cspec.CSPEC_VERSION = (uint16_t) (basespec (optarg, 10, sizeof (cspec.CSPEC_VERSION))); cspec.CSPEC_VERSION = HTOLE16 (cspec.CSPEC_VERSION); break; default: break; } } argc -= optind; argv += optind; if (_allclr (plc.flags, PLC_ANALYSE)) { if (ParseRule (& argc, & argv, & rule, & cspec) == -1) { error (1, 0, "invalid rule"); } } openchannel (& channel); if (! (plc.message = malloc (sizeof (* plc.message)))) { error (1, errno, PLC_NOMEMORY); } if (! argc) { if (_anyset (plc.flags, PLC_ANALYSE)) { ReadRules (& plc); } else { MakeRule (& plc, & rule); } } while ((argc) && (* argv)) { if (! hexencode (channel.peer, sizeof (channel.peer), synonym (* argv, devices, SIZEOF (devices)))) { error (1, errno, PLC_BAD_MAC, * argv); } if (_anyset (plc.flags, PLC_ANALYSE)) { ReadRules (& plc); } else { MakeRule (& plc, & rule); } argc--; argv++; } free (plc.message); closechannel (& channel); exit (0); }
static signed PrintRawWatchdogReport (struct plc * plc) { struct channel * channel = (struct channel *)(plc->channel); struct message * message = (struct message *)(plc->message); #ifndef __GNUC__ #pragma pack (push,1) #endif struct __packed vs_wd_rpt_request { struct ethernet_hdr ethernet; struct qualcomm_hdr qualcomm; uint16_t SESSIONID; uint8_t CLR; } * request = (struct vs_wd_rpt_request *) (message); struct __packed vs_wd_rpt_indicate { struct ethernet_hdr ethernet; struct qualcomm_hdr qualcomm; uint8_t MSTATUS; uint16_t SESSIONID; uint8_t NUMPARTS; uint8_t CURPART; uint16_t RDATALENGTH; uint8_t RDATAOFFSET; uint8_t RDATA [1]; } * indicate = (struct vs_wd_rpt_indicate *) (message); #ifndef __GNUC__ #pragma pack (pop) #endif memset (message, 0, sizeof (* message)); EthernetHeader (&request->ethernet, channel->peer, channel->host, channel->type); QualcommHeader (&request->qualcomm, 0, (VS_WD_RPT | MMTYPE_REQ)); plc->packetsize = (ETHER_MIN_LEN - ETHER_CRC_LEN); request->SESSIONID = HTOLE16 (plc->cookie); request->CLR = plc->readaction; if (SendMME (plc) <= 0) { error (PLC_EXIT (plc), errno, CHANNEL_CANTSEND); return (-1); } do { printf ("%d %d\n", LE16TOH (indicate->RDATALENGTH), indicate->RDATAOFFSET); if (ReadMME (plc, 0, (VS_WD_RPT | MMTYPE_IND)) <= 0) { error (PLC_EXIT (plc), errno, CHANNEL_CANTREAD); return (-1); } printf ("%d %d\n", LE16TOH (indicate->RDATALENGTH), indicate->RDATAOFFSET); if (indicate->MSTATUS) { Failure (plc, PLC_WONTDOIT); return (-1); } printf ("%d %d\n", LE16TOH (indicate->RDATALENGTH), indicate->RDATAOFFSET); write (STDOUT_FILENO, indicate->RDATA + indicate->RDATAOFFSET, LE16TOH (indicate->RDATALENGTH) - indicate->RDATAOFFSET); } while (indicate->CURPART < indicate->NUMPARTS); return (0); }
signed ModuleWrite (struct plc * plc, struct _file_ * file, unsigned index, struct vs_module_spec * vs_module_spec) { struct channel * channel = (struct channel *)(plc->channel); struct message * message = (struct message *)(plc->message); #ifndef __GNUC__ #pragma pack (push,1) #endif struct __packed vs_module_operation_write_request { struct ethernet_std ethernet; struct qualcomm_std qualcomm; uint32_t RESERVED; uint8_t NUM_OP_DATA; struct __packed { uint16_t MOD_OP; uint16_t MOD_OP_DATA_LEN; uint32_t MOD_OP_RSVD; uint32_t MOD_OP_SESSION_ID; uint8_t MODULE_IDX; uint16_t MODULE_ID; uint16_t MODULE_SUB_ID; uint16_t MODULE_LENGTH; uint32_t MODULE_OFFSET; } MODULE_SPEC; uint8_t MODULE_DATA [PLC_MODULE_SIZE]; } * request = (struct vs_module_operation_write_request *)(message); struct __packed vs_module_operation_write_confirm { struct ethernet_std ethernet; struct qualcomm_std qualcomm; uint16_t MSTATUS; uint16_t ERR_REC_CODE; uint32_t RESERVED; uint8_t NUM_OP_DATA; struct __packed { uint16_t MOD_OP; uint16_t MOD_OP_DATA_LEN; uint32_t MOD_OP_RSVD; uint32_t MOD_OP_SESSION_ID; uint8_t MODULE_IDX; uint16_t MODULE_ID; uint16_t MODULE_SUB_ID; uint16_t MODULE_LENGTH; uint32_t MODULE_OFFSET; } MODULE_SPEC; } * confirm = (struct vs_module_operation_write_confirm *)(message); #ifndef __GNUC__ #pragma pack (pop) #endif unsigned timeout = channel->timeout; uint16_t length = PLC_MODULE_SIZE; uint32_t extent = vs_module_spec->MODULE_LENGTH; uint32_t offset = 0; Request (plc, "Flash %s", file->name); while (extent) { memset (message, 0, sizeof (* message)); EthernetHeader (&request->ethernet, channel->peer, channel->host, HOMEPLUG_MTYPE); QualcommHeader (&request->qualcomm, 0, (VS_MODULE_OPERATION | MMTYPE_REQ)); plc->packetsize = sizeof (struct vs_module_operation_write_request); if (length > extent) { length = extent; } if (read (file->file, request->MODULE_DATA, length) != length) { error (1, errno, FILE_CANTREAD, file->name); } request->NUM_OP_DATA = 1; request->MODULE_SPEC.MOD_OP = HTOLE16 (PLC_MOD_OP_WRITE_MODULE); request->MODULE_SPEC.MOD_OP_DATA_LEN = HTOLE16 (sizeof (request->MODULE_SPEC) + sizeof (request->MODULE_DATA)); request->MODULE_SPEC.MOD_OP_SESSION_ID = HTOLE32 (plc->cookie); request->MODULE_SPEC.MODULE_IDX = index; request->MODULE_SPEC.MODULE_ID = HTOLE16 (vs_module_spec->MODULE_ID); request->MODULE_SPEC.MODULE_SUB_ID = HTOLE16 (vs_module_spec->MODULE_SUB_ID); request->MODULE_SPEC.MODULE_LENGTH = HTOLE16 (length); request->MODULE_SPEC.MODULE_OFFSET = HTOLE32 (offset); #if 0 fprintf (stderr, "RESERVED 0x%08X\n", LE32TOH (request->RESERVED)); fprintf (stderr, "NUM_OP_DATA %d\n", request->NUM_OP_DATA); fprintf (stderr, "MOD_OP 0x%02X\n", LE16TOH (request->MODULE_SPEC.MOD_OP)); fprintf (stderr, "MOD_OP_DATA_LEN %d\n", LE16TOH (request->MODULE_SPEC.MOD_OP_DATA_LEN)); fprintf (stderr, "RESERVED 0x%08X\n", LE32TOH (request->MODULE_SPEC.MOD_OP_RSVD)); fprintf (stderr, "MODULE_ID 0x%04X\n", LE16TOH (request->MODULE_SPEC.MODULE_ID)); fprintf (stderr, "MODULE_SUB_ID 0x%04X\n", LE16TOH (request->MODULE_SPEC.MODULE_SUB_ID)); fprintf (stderr, "MODULE_LENGTH %d\n", LE16TOH (request->MODULE_SPEC.MODULE_LENGTH)); fprintf (stderr, "MODULE_OFFSET 0x%08X\n", LE32TOH (request->MODULE_SPEC.MODULE_OFFSET)); #endif if (SendMME (plc) <= 0) { error ((plc->flags & PLC_BAILOUT), errno, CHANNEL_CANTSEND); return (-1); } channel->timeout = PLC_MODULE_WRITE_TIMEOUT; if (ReadMME (plc, 0, (VS_MODULE_OPERATION | MMTYPE_CNF)) <= 0) { error ((plc->flags & PLC_BAILOUT), errno, CHANNEL_CANTREAD); channel->timeout = timeout; return (-1); } channel->timeout = timeout; #if 0 fprintf (stderr, "MSTATUS 0x%04X\n", LE16TOH (confirm->MSTATUS)); fprintf (stderr, "ERROR_REC_CODE %d\n", LE16TOH (confirm->ERR_REC_CODE)); fprintf (stderr, "RESERVED 0x%08X\n", LE32TOH (confirm->RESERVED)); fprintf (stderr, "NUM_OP_DATA %d\n", confirm->NUM_OP_DATA); fprintf (stderr, "MOD_OP 0x%02X\n", LE16TOH (request->MODULE_SPEC.MOD_OP)); fprintf (stderr, "MOD_OP_DATA_LEN %d\n", LE16TOH (confirm->MODULE_SPEC.MOD_OP_DATA_LEN)); fprintf (stderr, "RESERVED 0x%08X\n", LE32TOH (confirm->MODULE_SPEC.MOD_OP_RSVD)); fprintf (stderr, "MODULE_ID 0x%04X\n", LE16TOH (confirm->MODULE_SPEC.MODULE_ID)); fprintf (stderr, "MODULE_SUB_ID 0x%04X\n", LE16TOH (confirm->MODULE_SPEC.MODULE_SUB_ID)); fprintf (stderr, "MODULE_LENGTH %d\n", LE16TOH (confirm->MODULE_SPEC.MODULE_LENGTH)); fprintf (stderr, "MODULE_OFFSET 0x%08X\n", LE32TOH (request->MODULE_SPEC.MODULE_OFFSET)); #endif if (confirm->MSTATUS) { Failure (plc, PLC_WONTDOIT); return (-1); } if (LE16TOH (confirm->MODULE_SPEC.MODULE_LENGTH) != length) { error ((plc->flags & PLC_BAILOUT), 0, PLC_ERR_LENGTH); return (-1); } if (LE32TOH (confirm->MODULE_SPEC.MODULE_OFFSET) != offset) { error ((plc->flags & PLC_BAILOUT), 0, PLC_ERR_OFFSET); return (-1); } extent -= length; offset += length; } return (0); }
static signed PrintCheckpointReport (struct plc * plc, char const * version) { struct channel * channel = (struct channel *)(plc->channel); struct message * message = (struct message *)(plc->message); #ifndef __GNUC__ #pragma pack (push,1) #endif struct __packed vs_cp_rpt_request { struct ethernet_hdr ethernet; struct qualcomm_hdr qualcomm; uint16_t SESSIONID; uint8_t CLR; } * request = (struct vs_cp_rpt_request *) (message); struct __packed vs_cp_rpt_ind { struct ethernet_hdr ethernet; struct qualcomm_hdr qualcomm; uint8_t MSTATUS; uint8_t MAJORVERSION; uint8_t MINORVERSION; uint8_t RESERVED [14]; uint16_t SESSIONID; uint32_t TOTALBUFFERSIZE; uint32_t BLOCKOFFSET; uint32_t BYTEINDEXOFNEXTPOSITION; uint8_t NUMPARTS; uint8_t CURPART; uint16_t RDATALENGTH; uint8_t RDATAOFFSET; uint8_t RDATA [1]; } * indicate = (struct vs_cp_rpt_ind *) (message); #ifndef __GNUC__ #pragma pack (pop) #endif memset (message, 0, sizeof (* message)); EthernetHeader (&request->ethernet, channel->peer, channel->host, channel->type); QualcommHeader (&request->qualcomm, 0, (VS_CP_RPT | MMTYPE_REQ)); plc->packetsize = (ETHER_MIN_LEN - ETHER_CRC_LEN); request->SESSIONID = HTOLE16 (plc->cookie); request->CLR = plc->readaction; if (SendMME (plc) <= 0) { error (PLC_EXIT (plc), errno, CHANNEL_CANTSEND); return (-1); } printf ("<CheckpointReport>"); do { if (ReadMME (plc, 0, (VS_CP_RPT | MMTYPE_IND)) <= 0) { error (PLC_EXIT (plc), errno, CHANNEL_CANTREAD); return (-1); } if (_anyset (indicate->MSTATUS, MSTATUS_STATUS)) { Failure (plc, PLC_WONTDOIT); return (-1); } printf ("<Packet>"); printf ("<Version>%s</Version>", version); printf ("<Status>0</Status>"); printf ("<MajorVersionBit>%d</MajorVersionBit>", indicate->MSTATUS & MSTATUS_MAJORVERSION? 1:0); printf ("<BufferIsLocked>%d</BufferIsLocked>", indicate->MSTATUS & MSTATUS_BUFFERISLOCKED? 1:0); printf ("<AutoLockOnResetIsOn>%d</AutoLockOnResetIsOn>", indicate->MSTATUS & MSTATUS_AUTOLOCKONRESET? 1:0); printf ("<UnsolicitedUpdatesIsOn>%d</UnsolicitedUpdatesIsOn>", indicate->MSTATUS & MSTATUS_UNSOLICITEDUPDATES? 1:0); printf ("<Unsolicited>%d</Unsolicited>", indicate->MSTATUS & MSTATUS_UNSOLICITED? 1:0); printf ("<MajorVersion>%d</MajorVersion>", indicate->MAJORVERSION); printf ("<MinorVersion>%d</MinorVersion>", indicate->MINORVERSION); printf ("<Reserved1>0</Reserved1>"); printf ("<Reserved2>0</Reserved2>"); printf ("<Reserved3>0</Reserved3>"); printf ("<Reserved4>0</Reserved4>"); printf ("<SessionId>1</SessionId>"); printf ("<TotalBufferSize>%d</TotalBufferSize>", LE32TOH (indicate->TOTALBUFFERSIZE)); printf ("<BlockOffset>%d</BlockOffset>", LE32TOH (indicate->BLOCKOFFSET)); printf ("<ByteIndexOfNextPos>%d</ByteIndexOfNextPos>", LE32TOH (indicate->BYTEINDEXOFNEXTPOSITION)); printf ("<NumParts>%d</NumParts>", indicate->NUMPARTS); printf ("<CurPart>%d</CurPart>", indicate->CURPART); printf ("<RDataLength>%d</RDataLength>", LE16TOH (indicate->RDATALENGTH)); printf ("<RDataOffset>%d</RDataOffset>", indicate->RDATAOFFSET); printf ("<RData>"); b64dump (indicate->RDATA + indicate->RDATAOFFSET, LE16TOH (indicate->RDATALENGTH), 0, stdout); printf ("</RData>"); printf ("</Packet>"); } while (indicate->CURPART < indicate->NUMPARTS); printf ("</CheckpointReport>"); return (0); }
size_t memencode (void * memory, size_t extent, char const * format, char const * string) { if (!strcmp (format, "byte")) { uint8_t * number = (uint8_t *)(memory); if (extent < sizeof (* number)) { error (1, ECANCELED, "Overflow at %s %s", format, string); } * number = (uint8_t)(basespec (string, 0, sizeof (* number))); return (sizeof (* number)); } if (!strcmp (format, "word")) { uint16_t * number = (uint16_t *)(memory); if (extent < sizeof (* number)) { error (1, ECANCELED, "Overflow at %s %s", format, string); } * number = (uint16_t)(basespec (string, 0, sizeof (* number))); * number = HTOLE16 (* number); return (sizeof (* number)); } if (!strcmp (format, "long")) { uint32_t * number = (uint32_t *)(memory); if (extent < sizeof (* number)) { error (1, ECANCELED, "Overflow at %s %s", format, string); } * number = (uint32_t)(basespec (string, 0, sizeof (* number))); * number = HTOLE32 (* number); return (sizeof (* number)); } if (!strcmp (format, "huge")) { uint64_t * number = (uint64_t *)(memory); if (extent < sizeof (* number)) { error (1, ECANCELED, "Overflow at %s %s", format, string); } * number = (uint64_t)(basespec (string, 0, sizeof (* number))); * number = HTOLE64 (* number); return (sizeof (* number)); } if (!strcmp (format, "text")) { extent = (unsigned)(strlen (string)); memcpy (memory, string, extent); return (extent); } if (!strcmp (format, "data")) { extent = (unsigned)(dataspec (string, memory, extent)); return (extent); } if (!strcmp (format, "fill")) { extent = (unsigned)(uintspec (string, 0, extent)); memset (memory, ~0, extent); return (extent); } if (!strcmp (format, "zero")) { extent = (unsigned)(uintspec (string, 0, extent)); memset (memory, 0, extent); return (extent); } if (!strcmp (format, "skip")) { extent = (unsigned)(uintspec (string, 0, extent)); return (extent); } #if 1 /* * tr-069 specific fields that don't really belong in the PIB; */ if (!strcmp (format, "adminusername") || !strcmp (format, "adminpassword") || !strcmp (format, "accessusername")) { return (memstring (memory, extent, format, string, PIB_NAME_LEN + 1)); } if (!strcmp (format, "accesspassword")) { return (memstring (memory, extent, format, string, PIB_HFID_LEN + 1)); } if (!strcmp (format, "username") || !strcmp (format, "password") || !strcmp (format, "url")) { return (memstring (memory, extent, format, string, PIB_TEXT_LEN + 1)); } #endif #if 1 /* * HPAV specific fields that belong in the PIB; */ if (!strcmp (format, "hfid")) { return (memstring (memory, extent, format, string, PIB_HFID_LEN)); } if (!strcmp (format, "mac")) { return (bytespec (string, memory, ETHER_ADDR_LEN)); } if (!strcmp (format, "key")) { return (bytespec (string, memory, PIB_KEY_LEN)); } #endif error (1, ENOTSUP, "%s", format); return (0); }
signed ReadFirmware1 (struct plc * plc) { struct channel * channel = (struct channel *)(plc->channel); struct message * message = (struct message *)(plc->message); #ifndef __GNUC__ #pragma pack (push,1) #endif struct __packed vs_rd_mod_request { struct ethernet_hdr ethernet; struct qualcomm_hdr qualcomm; uint8_t MODULEID; uint8_t MACCESS; uint16_t MLENGTH; uint32_t MOFFSET; uint8_t MSECRET [16]; } * request = (struct vs_rd_mod_request *) (message); struct __packed vs_rd_mod_confirm { struct ethernet_hdr ethernet; struct qualcomm_hdr qualcomm; uint8_t MSTATUS; uint8_t RES [3]; uint8_t MODULEID; uint8_t RESERVED; uint16_t MLENGTH; uint32_t MOFFSET; uint32_t CHKSUM; uint8_t BUFFER [PLC_RECORD_SIZE]; } * confirm = (struct vs_rd_mod_confirm *) (message); #ifndef __GNUC__ #pragma pack (pop) #endif uint32_t header = 0; uint32_t extent = 0; uint32_t offset = 0; uint16_t length = PLC_RECORD_SIZE; Request (plc, "Read Firmware from Device"); if (lseek (plc->nvm.file, 0, SEEK_SET)) { error (PLC_EXIT (plc), errno, FILE_CANTHOME, plc->nvm.name); return (1); } do { memset (message, 0, sizeof (* message)); EthernetHeader (&request->ethernet, channel->peer, channel->host, channel->type); QualcommHeader (&request->qualcomm, 0, (VS_RD_MOD | MMTYPE_REQ)); plc->packetsize = (ETHER_MIN_LEN - ETHER_CRC_LEN); request->MODULEID = VS_MODULE_MAC; request->MLENGTH = HTOLE16 (length); request->MOFFSET = HTOLE32 (offset); if (SendMME (plc) <= 0) { error (PLC_EXIT (plc), errno, CHANNEL_CANTSEND); return (-1); } if (ReadMME (plc, 0, (VS_RD_MOD | MMTYPE_CNF)) <= 0) { error (PLC_EXIT (plc), errno, CHANNEL_CANTREAD); return (-1); } if (confirm->MSTATUS) { Failure (plc, PLC_WONTDOIT); return (-1); } if (LE16TOH (confirm->MLENGTH) != length) { error (PLC_EXIT (plc), 0, PLC_ERR_LENGTH); return (-1); } if (LE32TOH (confirm->MOFFSET) != offset) { error (PLC_EXIT (plc), 0, PLC_ERR_OFFSET); return (-1); } length = LE16TOH (confirm->MLENGTH); offset = LE32TOH (confirm->MOFFSET); if (checksum32 (confirm->BUFFER, length, confirm->CHKSUM)) { error (PLC_EXIT (plc), ECANCELED, "Bad Packet Checksum"); return (-1); } if (offset == extent) { struct nvm_header1 * nvm_header = (struct nvm_header1 *)(confirm->BUFFER); if (checksum32 (nvm_header, sizeof (* nvm_header), 0)) { error (PLC_EXIT (plc), ECANCELED, "Bad Header Checksum"); return (-1); } if (LE32TOH (nvm_header->HEADERVERSION) != 0x60000000) { error (PLC_EXIT (plc), ECANCELED, "Bad Header Version"); return (-1); } extent += sizeof (* nvm_header); extent += LE32TOH (nvm_header->IMAGELENGTH); header = LE32TOH (nvm_header->NEXTHEADER); } if ((offset + length) > extent) { length = extent - offset; } if (lseek (plc->nvm.file, offset, SEEK_SET) != (off_t)(offset)) { error (PLC_EXIT (plc), errno, FILE_CANTSEEK, plc->nvm.name); return (-1); } if (write (plc->nvm.file, confirm->BUFFER, length) != (signed)(length)) { error (PLC_EXIT (plc), errno, FILE_CANTSEEK, plc->nvm.name); return (-1); } offset += length; length = 1024; } while ((header) || (offset < extent)); Confirm (plc, "Read %s", plc->nvm.name); return (0); }
signed ModuleCommit (struct plc * plc, uint32_t options) { struct channel * channel = (struct channel *)(plc->channel); struct message * message = (struct message *)(plc->message); #ifndef __GNUC__ #pragma pack (push,1) #endif struct __packed vs_module_operation_commit_request { struct ethernet_std ethernet; struct qualcomm_std qualcomm; uint32_t RESERVED; uint8_t NUM_OP_DATA; struct __packed { uint16_t MOD_OP; uint16_t MOD_OP_DATA_LEN; uint32_t MOD_OP_RSVD; uint32_t MOD_OP_SESSION_ID; uint32_t COMMIT_CODE; } request; uint8_t RSVD [20]; } * request = (struct vs_module_operation_commit_request *)(message); struct __packed vs_module_operation_commit_confirm { struct ethernet_std ethernet; struct qualcomm_std qualcomm; uint16_t MSTATUS; uint16_t ERR_REC_CODE; uint32_t RESERVED1; uint8_t NUM_OP_DATA; struct __packed { uint16_t MOD_OP; uint16_t MOD_OP_DATA_LEN; uint32_t MOD_OP_RSVD; uint32_t MOD_OP_SESSION_ID; uint32_t COMMIT_CODE; uint8_t NUM_MODULES; } request; struct __packed { uint16_t MOD_STATUS; uint16_t ERR_REC_CODE; } MOD_OP_DATA [1]; } * confirm = (struct vs_module_operation_commit_confirm *)(message); #ifndef __GNUC__ #pragma pack (pop) #endif unsigned timer = channel->timeout; Request (plc, "Close Session"); memset (message, 0, sizeof (* message)); EthernetHeader (&request->ethernet, channel->peer, channel->host, channel->type); QualcommHeader (&request->qualcomm, 0, (VS_MODULE_OPERATION | MMTYPE_REQ)); plc->packetsize = (ETHER_MIN_LEN - ETHER_CRC_LEN); request->NUM_OP_DATA = 1; request->request.MOD_OP = HTOLE16 (PLC_MOD_OP_CLOSE_SESSION); request->request.MOD_OP_DATA_LEN = HTOLE16 (sizeof (request->request) + sizeof (request->RSVD)); request->request.MOD_OP_SESSION_ID = HTOLE32 (plc->cookie); request->request.COMMIT_CODE = HTOLE32 (options); if (SendMME (plc) <= 0) { error ((plc->flags & PLC_BAILOUT), errno, CHANNEL_CANTSEND); return (-1); } channel->timeout = PLC_MODULE_WRITE_TIMEOUT; if (ReadMME (plc, 0, (VS_MODULE_OPERATION | MMTYPE_CNF)) <= 0) { error ((plc->flags & PLC_BAILOUT), errno, CHANNEL_CANTREAD); channel->timeout = timer; return (-1); } channel->timeout = timer; if (confirm->MSTATUS) { Failure (plc, PLC_WONTDOIT); return (-1); } return (0); }
signed Identity1 (struct plc * plc) { struct channel * channel = (struct channel *)(plc->channel); struct message * message = (struct message *)(plc->message); #ifndef __GNUC__ #pragma pack (push,1) #endif struct __packed vs_rd_mod_request { struct ethernet_hdr ethernet; struct qualcomm_hdr qualcomm; uint8_t MODULEID; uint8_t MACCESS; uint16_t MLENGTH; uint32_t MOFFSET; uint8_t MSECRET [16]; } * request = (struct vs_rd_mod_request *) (message); struct __packed vs_rd_mod_confirm { struct ethernet_hdr ethernet; struct qualcomm_hdr qualcomm; uint8_t MSTATUS; uint8_t RES [3]; uint8_t MODULEID; uint8_t RESERVED; uint16_t MLENGTH; uint32_t MOFFSET; uint32_t MCHKSUM; uint8_t BUFFER [PLC_RECORD_SIZE]; } * confirm = (struct vs_rd_mod_confirm *) (message); #ifndef __GNUC__ #pragma pack (pop) #endif Request (plc, "Device Identity"); memset (message, 0, sizeof (* message)); EthernetHeader (&request->ethernet, channel->peer, channel->host, channel->type); QualcommHeader (&request->qualcomm, 0, (VS_RD_MOD | MMTYPE_REQ)); plc->packetsize = (ETHER_MIN_LEN - ETHER_CRC_LEN); request->MODULEID = VS_MODULE_PIB; request->MLENGTH = HTOLE16 (sizeof (confirm->BUFFER)); request->MOFFSET = HTOLE32 (0); if (SendMME (plc) <= 0) { error (PLC_EXIT (plc), errno, CHANNEL_CANTSEND); return (-1); } while (ReadMME (plc, 0, (VS_RD_MOD | MMTYPE_CNF)) > 0) { if (confirm->MSTATUS) { Failure (plc, PLC_WONTDOIT); continue; } Confirm (plc, "-------"); pibpeek1 (confirm->BUFFER); } return (0); }
static signed mdio (struct channel * channel, uint8_t mode, uint8_t phy, uint8_t reg, uint16_t * data) { struct message message; signed packetsize; #ifndef __GNUC__ #pragma pack (push,1) #endif struct __packed vs_mdio_command_request { struct ethernet_hdr ethernet; struct qualcomm_hdr qualcomm; uint8_t OPERATION; uint8_t PHY; uint8_t REG; uint16_t DATA; } * request = (struct vs_mdio_command_request *)(&message); struct __packed vs_mdio_command_confirm { struct ethernet_hdr ethernet; struct qualcomm_hdr qualcomm; uint8_t MSTATUS; uint16_t DATA; uint8_t PHY; uint8_t REG; } * confirm = (struct vs_mdio_command_confirm *)(&message); #ifndef __GNUC__ #pragma pack (pop) #endif memset (&message, 0, sizeof (message)); EthernetHeader (&request->ethernet, channel->peer, channel->host, channel->type); QualcommHeader (&request->qualcomm, 0, (VS_MDIO_COMMAND | MMTYPE_REQ)); request->OPERATION = mode; request->PHY = phy; request->REG = reg; request->DATA = HTOLE16 (*data); #if 1 printf (" phy 0x%02X", phy); printf (" reg 0x%02X", reg); printf (" data 0x%04X", * data); printf ("\n"); #endif if (sendpacket (channel, &message, (ETHER_MIN_LEN - ETHER_CRC_LEN)) == -1) { error (1, errno, CHANNEL_CANTSEND); } while ((packetsize = readpacket (channel, &message, sizeof (message))) > 0) { if (UnwantedMessage (&message, packetsize, 0, (VS_MDIO_COMMAND | MMTYPE_CNF))) { continue; } if (confirm->MSTATUS) { error (0, 0, "%s (%0X): %s", MMECode (confirm->qualcomm.MMTYPE, confirm->MSTATUS), confirm->MSTATUS, PLC_WONTDOIT); continue; } *data = confirm->DATA; return (0); } return (-1); }
signed WriteMOD (struct plc * plc, uint8_t module, void const * memory, size_t extent) { struct channel * channel = (struct channel *)(plc->channel); struct message * message = (struct message *)(plc->message); #ifndef __GNUC__ #pragma pack (push,1) #endif struct __packed vs_wr_mod_request { struct ethernet_hdr ethernet; struct qualcomm_hdr qualcomm; uint8_t MODULEID; uint8_t MACCESS; uint16_t MLENGTH; uint32_t MOFFSET; uint32_t MCHKSUM; uint8_t MBUFFER [PLC_RECORD_SIZE]; } * request = (struct vs_wr_mod_request *) (message); struct __packed vs_wr_mod_confirm { struct ethernet_hdr ethernet; struct qualcomm_hdr qualcomm; uint8_t MSTATUS; uint8_t MODULEID; uint8_t MACCESS; uint16_t MLENGTH; uint32_t MOFFSET; } * confirm = (struct vs_wr_mod_confirm *) (message); #ifndef __GNUC__ #pragma pack (pop) #endif uint32_t length = PLC_RECORD_SIZE; uint32_t offset = 0; while (extent) { memset (message, 0, sizeof (* message)); EthernetHeader (&request->ethernet, channel->peer, channel->host, channel->type); QualcommHeader (&request->qualcomm, 0, (VS_WR_MOD | MMTYPE_REQ)); if (length > extent) { length = (signed)(extent); } memcpy (request->MBUFFER, (byte *)(memory) + offset, length); request->MODULEID = module; request->MACCESS = 0; request->MLENGTH = HTOLE16 (length); request->MOFFSET = HTOLE32 (offset); request->MCHKSUM = checksum32 (request->MBUFFER, length, 0); plc->packetsize = sizeof (* request); if (SendMME (plc) <= 0) { error (PLC_EXIT (plc), errno, CHANNEL_CANTSEND); return (-1); } if (ReadMME (plc, 0, (VS_WR_MOD | MMTYPE_CNF)) <= 0) { error (PLC_EXIT (plc), errno, CHANNEL_CANTREAD); return (-1); } if (confirm->MSTATUS) { Failure (plc, PLC_WONTDOIT); return (-1); } if (LE16TOH (confirm->MLENGTH) != length) { error (PLC_EXIT (plc), 0, PLC_ERR_LENGTH); return (-1); } if (LE32TOH (confirm->MOFFSET) != offset) { error (PLC_EXIT (plc), 0, PLC_ERR_OFFSET); return (-1); } offset += length; extent -= length; } return (0); }
static void ReadKey1 (struct channel * channel, unsigned c, int key) { struct message message; static signed count = 0; signed packetsize; #ifndef __GNUC__ #pragma pack (push,1) #endif struct __packed vs_rd_mod_request { struct ethernet_hdr ethernet; struct qualcomm_hdr qualcomm; uint8_t MODULEID; uint8_t RESERVED; uint16_t MLENGTH; uint32_t MOFFSET; uint8_t DAK [16]; } * request = (struct vs_rd_mod_request *)(&message); struct __packed vs_rd_mod_confirm { struct ethernet_hdr ethernet; struct qualcomm_hdr qualcomm; uint8_t MSTATUS; uint8_t RESERVED1 [3]; uint8_t MODULEID; uint8_t RESERVED2; uint16_t MLENGTH; uint32_t MOFFSET; uint32_t MCHKSUM; struct simple_pib pib; } * confirm = (struct vs_rd_mod_confirm *)(&message); #ifndef __GNUC__ #pragma pack (pop) #endif memset (&message, 0, sizeof (message)); EthernetHeader (&request->ethernet, channel->peer, channel->host, channel->type); QualcommHeader (&request->qualcomm, 0, (VS_RD_MOD | MMTYPE_REQ)); request->MODULEID = VS_MODULE_PIB; request->MLENGTH = HTOLE16 (PLC_RECORD_SIZE); request->MOFFSET = HTOLE32 (0); if (sendpacket (channel, &message, (ETHER_MIN_LEN - ETHER_CRC_LEN)) < 0) { error (1, errno, CHANNEL_CANTSEND); } while ((packetsize = readpacket (channel, &message, sizeof (message))) > 0) { if (UnwantedMessage (&message, packetsize, 0, (VS_RD_MOD | MMTYPE_CNF))) { continue; } if (confirm->MSTATUS) { error (0, 0, "%s (%0X): ", MMECode (confirm->qualcomm.MMTYPE, confirm->MSTATUS), confirm->MSTATUS); continue; } if (count++ > 0) { putc (c, stdout); } if (key == INT6KID_MAC) { hexout (confirm->pib.MAC, sizeof (confirm->pib.MAC), HEX_EXTENDER, 0, stdout); continue; } if (key == INT6KID_DAK) { hexout (confirm->pib.DAK, sizeof (confirm->pib.DAK), HEX_EXTENDER, 0, stdout); continue; } if (key == INT6KID_NMK) { hexout (confirm->pib.NMK, sizeof (confirm->pib.NMK), HEX_EXTENDER, 0, stdout); continue; } if (key == INT6KID_MFG) { confirm->pib.MFG [PIB_HFID_LEN - 1] = (char)(0); printf ("%s", confirm->pib.MFG); continue; } if (key == INT6KID_USR) { confirm->pib.USR [PIB_HFID_LEN - 1] = (char)(0); printf ("%s", confirm->pib.USR); continue; } if (key == INT6KID_NET) { confirm->pib.NET [PIB_HFID_LEN - 1] = (char)(0); printf ("%s", confirm->pib.NET); continue; } } if (packetsize < 0) { error (1, errno, CHANNEL_CANTREAD); } return; }