Exemple #1
0
static void function2 (struct _file_ * file, signed index, flag_t flags) 

{
	static signed image = 0;
	static signed origin = ~0;
	static signed offset = 0;
	struct nvm_header2 nvm_header;
	if (read (file->file, &nvm_header, sizeof (nvm_header)) != sizeof (nvm_header)) 
	{
		error (1, errno, NVM_HDR_CANTREAD, file->name, image);
	}
	if (LE16TOH (nvm_header.MajorVersion) != 1) 
	{
		error (1, 0, NVM_HDR_VERSION, file->name, image);
	}
	if (LE16TOH (nvm_header.MinorVersion) != 1) 
	{
		error (1, 0, NVM_HDR_VERSION, file->name, image);
	}
	if (checksum32 (&nvm_header, sizeof (nvm_header), 0)) 
	{
		error (1, 0, NVM_HDR_CHECKSUM, file->name, image);
	}
	if (~nvm_header.PrevHeader) 
	{
		error (1, 0, NVM_HDR_LINK, file->name, image);
	}
	if (~nvm_header.NextHeader) 
	{
		error (1, 0, NVM_HDR_LINK, file->name, image);
	}
	nvm_header.PrevHeader = HTOLE32 (origin);
	origin = offset;
	if (index) 
	{
		offset += sizeof (nvm_header);
		offset += LE32TOH (nvm_header.ImageLength);
		nvm_header.NextHeader = HTOLE32 (offset);
	}
	nvm_header.HeaderChecksum = 0;
	nvm_header.HeaderChecksum = checksum32 (&nvm_header, sizeof (nvm_header), 0);
	if (write (STDOUT_FILENO, &nvm_header, sizeof (nvm_header)) != sizeof (nvm_header)) 
	{
		error (1, errno, NVM_HDR_CANTSAVE, file->name, image);
	}
	copyimage (file, LE32TOH (nvm_header.ImageLength), image);
	image++;
	return;
}
Exemple #2
0
static void function1 (struct _file_ * file, signed index, flag_t flags) 

{
	static signed image = 0;
	static uint32_t offset = 0;
	struct nvm_header1 nvm_header;
	if (read (file->file, &nvm_header, sizeof (nvm_header)) != sizeof (nvm_header)) 
	{
		error (1, errno, NVM_HDR_CANTREAD, file->name, image);
	}
	if (LE32TOH (nvm_header.HEADERVERSION) != 0x60000000) 
	{
		error (1, 0, NVM_HDR_VERSION, file->name, image);
	}
	if (checksum32 (&nvm_header, sizeof (nvm_header), 0)) 
	{
		error (1, 0, NVM_HDR_CHECKSUM, file->name, image);
	}
	if (nvm_header.NEXTHEADER) 
	{
		error (1, 0, NVM_HDR_LINK, file->name, image);
	}
	if (index) 
	{
		offset += sizeof (nvm_header);
		offset += LE32TOH (nvm_header.IMAGELENGTH);
		nvm_header.NEXTHEADER = HTOLE32 (offset);
	}
	nvm_header.HEADERCHECKSUM = 0;
	nvm_header.HEADERCHECKSUM = checksum32 (&nvm_header, sizeof (nvm_header), 0);
	if (write (STDOUT_FILENO, &nvm_header, sizeof (nvm_header)) != sizeof (nvm_header)) 
	{
		error (1, errno, NVM_HDR_CANTSAVE, file->name, image);
	}
	copyimage (file, LE32TOH (nvm_header.IMAGELENGTH), image);
	return;
}
Exemple #3
0
signed ReadPIB (struct int6k *int6k) 

{

	struct channel * channel = (struct channel *)(int6k->channel);
	struct message * message = (struct message *)(int6k->message);
#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 RESERVED1 [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

	uint32_t extent = 0;
	uint32_t offset = 0;
	signed length = INT6K_BLOCKSIZE;
	Request (int6k, "Read Parameters from Device");
	if (lseek (int6k->pib.file, 0, SEEK_SET)) 
	{
		error ((int6k->flags & INT6K_BAILOUT), errno, "Can't rewind %s", filepart (int6k->pib.name));
		return (1);
	}
	memset (message, 0, sizeof (struct message));
	do 
	{
		EthernetHeader (&message->ethernet, channel->peer, channel->host);
		IntellonHeader (&message->intellon, (VS_RD_MOD | MMTYPE_REQ));
		int6k->packetsize = ETHER_MIN_LEN;
		request->MODULEID = VS_MODULE_PIB;
		request->MLENGTH = HTOLE16 (length);
		request->MOFFSET = HTOLE32 (offset);
		if (SendMME (int6k) <= 0) 
		{
			error ((int6k->flags & INT6K_BAILOUT), ECANCELED, INT6K_CANTSEND);
			return (-1);
		}
		if (ReadMME (int6k, (VS_RD_MOD | MMTYPE_CNF)) <= 0) 
		{
			error ((int6k->flags & INT6K_BAILOUT), ECANCELED, INT6K_CANTREAD);
			return (-1);
		}
		if (confirm->MSTATUS) 
		{
			Failure (int6k, INT6K_WONTDOIT);
			return (-1);
		}

#if 1

		if (LE16TOH (confirm->MLENGTH) != length) 
		{
			Failure (int6k, INT6K_ERR_LENGTH);
			return (-1);
		}
		if (LE32TOH (confirm->MOFFSET) != offset) 
		{
			Failure (int6k, INT6K_ERR_OFFSET);
			return (-1);
		}

#else

		if (LE16TOH (confirm->MLENGTH) != length) 
		{
			error ((int6k->flags & INT6K_BAILOUT), 0, INT6K_ERR_LENGTH);
			length = INT6K_BLOCKSIZE;
			offset = 0;
			continue;
		}
		if (LE32TOH (confirm->MOFFSET) != offset) 
		{
			error ((int6k->flags & INT6K_BAILOUT), 0, INT6K_ERR_OFFSET);
			length = INT6K_BLOCKSIZE;
			offset = 0;
			continue;
		}

#endif

		length = LE16TOH (confirm->MLENGTH);
		offset = LE32TOH (confirm->MOFFSET);
		if (checksum_32 (confirm->BUFFER, length, confirm->CHKSUM)) 
		{
			error ((int6k->flags & INT6K_BAILOUT), ECANCELED, "Bad Packet Checksum");
			return (-1);
		}
		if (offset == extent) 
		{
			struct header_pib * header_pib = (struct header_pib *) (confirm->BUFFER);
			extent = header_pib->PIBLENGTH;
		}
		if ((offset + length) > extent) 
		{
			length = extent - offset;
		}
		if (lseek (int6k->pib.file, offset, SEEK_SET) != offset) 
		{
			error ((int6k->flags & INT6K_BAILOUT), errno, "can't seek %s", filepart (int6k->pib.name));
			return (-1);
		}
		if (write (int6k->pib.file, confirm->BUFFER, length) < length) 
		{
			error ((int6k->flags & INT6K_BAILOUT), errno, "can't save %s", filepart (int6k->pib.name));
			return (-1);
		}
		offset += length;
	}
	while (offset < extent);
	Confirm (int6k, "Read %s", int6k->pib.name);
	return (0);
}
Exemple #4
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);
}
signed WriteExecuteFirmware1 (struct plc * plc, unsigned module, const struct nvm_header1 * nvm_header) 

{
	struct channel * channel = (struct channel *)(plc->channel);
	struct message * message = (struct message *)(plc->message);

#ifndef __GNUC__
#pragma pack (push,1)
#endif

	struct __packed vs_write_execute_request 
	{
		struct ethernet_std ethernet;
		struct qualcomm_std qualcomm;
		uint32_t CLIENT_SESSION_ID;
		uint32_t SERVER_SESSION_ID;
		uint32_t FLAGS;
		uint8_t ALLOWED_MEM_TYPES [8];
		uint32_t TOTAL_LENGTH;
		uint32_t CURR_PART_LENGTH;
		uint32_t CURR_PART_OFFSET;
		uint32_t START_ADDR;
		uint32_t CHECKSUM;
		uint8_t RESERVED2 [8];
		uint8_t IMAGE [PLC_MODULE_SIZE];
	}
	* request = (struct vs_write_execute_request *) (message);
	struct __packed vs_write_execute_confirm 
	{
		struct ethernet_std ethernet;
		struct qualcomm_std qualcomm;
		uint32_t MSTATUS;
		uint32_t CLIENT_SESSION_ID;
		uint32_t SERVER_SESSION_ID;
		uint32_t FLAGS;
		uint8_t ALLOWED_MEM_TYPES [8];
		uint32_t TOTAL_LENGTH;
		uint32_t CURR_PART_LENGTH;
		uint32_t CURR_PART_OFFSET;
		uint32_t START_ADDR;
		uint32_t CHECKSUM;
		uint8_t RESERVED2 [8];
		uint32_t CURR_PART_ABSOLUTE_ADDR;
		uint32_t ABSOLUTE_START_ADDR;
	}
	* confirm = (struct vs_write_execute_confirm *) (message);

#ifndef __GNUC__
#pragma pack (pop)
#endif

	unsigned action = PLC_MODULE_ABSOLUTE;
	uint32_t length = PLC_MODULE_SIZE;
	uint32_t offset = LE32TOH (nvm_header->IMAGEADDRESS);
	uint32_t extent = LE32TOH (nvm_header->IMAGELENGTH);
	Request (plc, "Write %s (%d) (%08X:%d)", plc->NVM.name, module, offset, extent);
	while (extent) 
	{
		memset (message, 0, sizeof (* message));
		EthernetHeader (&request->ethernet, channel->peer, channel->host, channel->type);
		QualcommHeader (&request->qualcomm, 0, (VS_WRITE_AND_EXECUTE_APPLET | MMTYPE_REQ));
		if (length > extent) 
		{
			Request (plc, "Start %s (%d) (%08X)", plc->NVM.name, module, LE32TOH (nvm_header->ENTRYPOINT));
			length = extent;
			action |= PLC_MODULE_EXECUTE;
		}
		if (read (plc->NVM.file, request->IMAGE, length) != (signed)(length)) 
		{
			error (1, errno, FILE_CANTREAD, plc->NVM.name);
		}
		request->CLIENT_SESSION_ID = HTOLE32 (plc->cookie);
		request->SERVER_SESSION_ID = HTOLE32 (0);
		request->FLAGS = HTOLE32 (action);
		request->ALLOWED_MEM_TYPES [0] = 1;
		request->TOTAL_LENGTH = nvm_header->IMAGELENGTH;
		request->CURR_PART_LENGTH = HTOLE32 (length);
		request->CURR_PART_OFFSET = HTOLE32 (offset);
		request->START_ADDR = nvm_header->ENTRYPOINT;
		request->CHECKSUM = nvm_header->IMAGECHECKSUM;
		plc->packetsize = sizeof (* request);
		if (SendMME (plc) <= 0) 
		{
			error ((plc->flags & PLC_BAILOUT), errno, CHANNEL_CANTSEND);
			return (-1);
		}
		if (ReadMME (plc, 0, (VS_WRITE_AND_EXECUTE_APPLET | MMTYPE_CNF)) <= 0) 
		{
			error ((plc->flags & PLC_BAILOUT), errno, CHANNEL_CANTREAD);
			return (-1);
		}
		if (confirm->MSTATUS) 
		{
			Failure (plc, PLC_WONTDOIT);
			return (-1);
		}
		if (LE32TOH (confirm->CURR_PART_LENGTH) != length) 
		{
			error ((plc->flags & PLC_BAILOUT), 0, PLC_ERR_LENGTH);
			return (-1);
		}
		if (LE32TOH (confirm->CURR_PART_OFFSET) != offset) 
		{
			error ((plc->flags & PLC_BAILOUT), 0, PLC_ERR_OFFSET);
			return (-1);
		}
		offset += length;
		extent -= length;
	}
	return (0);
}
Exemple #6
0
signed SetProperty (struct plc * plc, struct plcproperty * plcproperty)

{
	struct channel * channel = (struct channel *)(plc->channel);
	struct message * message = (struct message *)(plc->message);

#ifndef __GNUC__
#pragma pack (push,1)
#endif

	struct __packed vs_set_property_request
	{
		struct ethernet_hdr ethernet;
		struct qualcomm_hdr qualcomm;
		uint32_t COOKIE;
		uint8_t OPTION;
		uint8_t RESERVED [3];
		uint32_t PROP_VERSION;
		uint32_t PROP_NUMBER;
		uint32_t DATA_LENGTH;
		uint8_t DATA_BUFFER [256];
	}
	* request = (struct vs_set_property_request *) (message);
	struct __packed vs_set_property_confirm
	{
		struct ethernet_hdr ethernet;
		struct qualcomm_hdr qualcomm;
		uint32_t MSTATUS;
		uint32_t COOKIE;
	}
	* confirm = (struct vs_set_property_confirm *) (message);

#ifndef __GNUC__
#pragma pack (pop)
#endif

	Request (plc, "Set Property");
	memset (message, 0, sizeof (* message));
	EthernetHeader (&request->ethernet, channel->peer, channel->host, channel->type);
	QualcommHeader (&request->qualcomm, 0, (VS_SET_PROPERTY | MMTYPE_REQ));
	request->COOKIE = HTOLE32 (plc->cookie);
	request->OPTION = plcproperty->PROP_OPTION;
	request->PROP_VERSION = HTOLE32 (plcproperty->PROP_VERSION);
	request->PROP_NUMBER = HTOLE32 (plcproperty->PROP_NUMBER);
	request->DATA_LENGTH = HTOLE32 (plcproperty->DATA_LENGTH);
	memcpy (&request->DATA_BUFFER, &plcproperty->DATA_BUFFER, plcproperty->DATA_LENGTH);
	plc->packetsize = sizeof (* request);
	if (SendMME (plc) <= 0)
	{
		error (PLC_EXIT (plc), errno, CHANNEL_CANTSEND);
		return (-1);
	}
	while (ReadMME (plc, 0, (VS_SET_PROPERTY | MMTYPE_CNF)) > 0)
	{
		if (confirm->MSTATUS)
		{
			Failure (plc, PLC_WONTDOIT);
			continue;
		}
	}
	return (0);
}
Exemple #7
0
void set32bitmap (uint32_t * map, unsigned bit) 

{
	map [bit / _bits (* map)] |= HTOLE32 (1 << (bit % _bits (* map)));
	return;
}
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);
}
		uint8_t LINEFREQ;
		uint32_t SDRAMSIZE;
		uint8_t AUTHMODE;
	}
	* attributes = (struct attributes *)(confirm->MBUFFER);

#ifndef __GNUC__
#pragma pack (pop)
#endif

	Request (plc, "Fetch Device Attributes");
	memset (message, 0, sizeof (* message));
	EthernetHeader (&request->ethernet, channel->peer, channel->host, channel->type);
	QualcommHeader (&request->qualcomm, 0, (VS_OP_ATTRIBUTES | MMTYPE_REQ));
	plc->packetsize = (ETHER_MIN_LEN - ETHER_CRC_LEN);
	request->COOKIE = HTOLE32 (plc->cookie);
	request->RTYPE = 0;
	if (SendMME (plc) <= 0)
	{
		error (PLC_EXIT (plc), errno, CHANNEL_CANTSEND);
		return (-1);
	}
	while (ReadMME (plc, 0, (VS_OP_ATTRIBUTES | MMTYPE_CNF)) > 0)
	{
		static char const * frequency [] =
		{
			"Unknown frequency",
			"50Hz",
			"60Hz",
		};
		static char const * zero_cross [] =
signed WriteExecuteParameters1 (struct plc * plc, unsigned module, const struct nvm_header1 * nvm_header)

{
	struct channel * channel = (struct channel *)(plc->channel);
	struct message * message = (struct message *)(plc->message);

#ifndef __GNUC__
#pragma pack (push,1)
#endif

	struct nvm_header1 nvm_manifest;
	struct __packed vs_write_execute_request
	{
		struct ethernet_hdr ethernet;
		struct qualcomm_hdr qualcomm;
		uint32_t CLIENT_SESSION_ID;
		uint32_t SERVER_SESSION_ID;
		uint32_t FLAGS;
		uint8_t ALLOWED_MEM_TYPES [8];
		uint32_t TOTAL_LENGTH;
		uint32_t CURR_PART_LENGTH;
		uint32_t CURR_PART_OFFSET;
		uint32_t START_ADDR;
		uint32_t CHECKSUM;
		uint8_t RESERVED2 [8];
		uint8_t IMAGE [PLC_MODULE_SIZE];
	}
	* request = (struct vs_write_execute_request *) (message);
	struct __packed vs_write_execute_confirm
	{
		struct ethernet_hdr ethernet;
		struct qualcomm_hdr qualcomm;
		uint32_t MSTATUS;
		uint32_t CLIENT_SESSION_ID;
		uint32_t SERVER_SESSION_ID;
		uint32_t FLAGS;
		uint8_t ALLOWED_MEM_TYPES [8];
		uint32_t TOTAL_LENGTH;
		uint32_t CURR_PART_LENGTH;
		uint32_t CURR_PART_OFFSET;
		uint32_t START_ADDR;
		uint32_t CHECKSUM;
		uint8_t RESERVED2 [8];
		uint32_t CURR_PART_ABSOLUTE_ADDR;
		uint32_t ABSOLUTE_START_ADDR;
	}
	* confirm = (struct vs_write_execute_confirm *) (message);

#ifndef __GNUC__
#pragma pack (pop)
#endif

	uint32_t length = PLC_MODULE_SIZE;
	uint32_t offset = LE32TOH (nvm_header->IMAGEADDRESS);
	uint32_t extent = LE32TOH (nvm_header->IMAGELENGTH);

#if 0

	Request (plc, "Write %s (%d) (%08X:%d)", plc->PIB.name, module, offset, extent);

#else

/*
 *	adjust the file extent to include the the manifest image header, the manifest image, the PIB
 *	image header and the PIB image; this should in principle, equal the PIB filesize for Panther
 *	and Lynx .pib files;
 */

	if (lseek (plc->PIB.file, 0, SEEK_SET))
	{
		error (1, errno, FILE_CANTHOME, plc->PIB.name);
	}
	if (read (plc->PIB.file, &nvm_manifest, sizeof (nvm_manifest)) != sizeof (nvm_manifest))
	{
		error (1, errno, FILE_CANTREAD, plc->PIB.name);
	}
	extent += sizeof (* nvm_header);
	extent += LE32TOH (nvm_manifest.IMAGELENGTH);
	extent += sizeof (* nvm_header);
	Request (plc, "Write %s (%d) (%08X:%d)", plc->PIB.name, module, offset, extent);

#endif

	while (extent)
	{
		memset (message, 0, sizeof (* message));
		EthernetHeader (&request->ethernet, channel->peer, channel->host, channel->type);
		QualcommHeader (&request->qualcomm, 0, (VS_WRITE_AND_EXECUTE_APPLET | MMTYPE_REQ));
		if (length > extent)
		{
			length = extent;
		}
		if (read (plc->PIB.file, request->IMAGE, length) != (signed)(length))
		{
			error (1, errno, FILE_CANTREAD, plc->PIB.name);
		}
		request->CLIENT_SESSION_ID = HTOLE32 (plc->cookie);
		request->SERVER_SESSION_ID = HTOLE32 (0);
		request->FLAGS = HTOLE32 (PLC_MODULE_ABSOLUTE);
		request->ALLOWED_MEM_TYPES [0] = 1;
		request->TOTAL_LENGTH = nvm_header->IMAGELENGTH;
		request->CURR_PART_LENGTH = HTOLE32 (length);
		request->CURR_PART_OFFSET = HTOLE32 (offset);
		request->START_ADDR = nvm_header->ENTRYPOINT;
		request->CHECKSUM = nvm_header->IMAGECHECKSUM;
		plc->packetsize = sizeof (* request);
		if (SendMME (plc) <= 0)
		{
			error (PLC_EXIT (plc), errno, CHANNEL_CANTSEND);
			return (-1);
		}
		if (ReadMME (plc, 0, (VS_WRITE_AND_EXECUTE_APPLET | MMTYPE_CNF)) <= 0)
		{
			error (PLC_EXIT (plc), errno, CHANNEL_CANTREAD);
			return (-1);
		}
		if (confirm->MSTATUS)
		{
			Failure (plc, PLC_WONTDOIT);
			return (-1);
		}
		if (LE32TOH (confirm->CURR_PART_LENGTH) != length)
		{
			error (PLC_EXIT (plc), 0, PLC_ERR_LENGTH);
			return (-1);
		}
		if (LE32TOH (confirm->CURR_PART_OFFSET) != offset)
		{
			error (PLC_EXIT (plc), 0, PLC_ERR_OFFSET);
			return (-1);
		}
		offset += length;
		extent -= length;
	}
	return (0);
}
Exemple #11
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);
}
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);
}
Exemple #13
0
signed GetProperty (struct plc * plc, struct plcproperty * plcproperty) 

{
	struct channel * channel = (struct channel *)(plc->channel);
	struct message * message = (struct message *)(plc->message);

#ifndef __GNUC__
#pragma pack (push,1)
#endif

	struct __packed vs_get_property_request 
	{
		struct ethernet_std ethernet;
		struct qualcomm_std qualcomm;
		uint32_t COOKIE;
		uint8_t DATA_FORMAT;
		uint8_t PROP_FORMAT;
		uint8_t RESERVED [2];
		uint32_t PROP_VERSION;
		uint32_t PROP_LENGTH;
		uint8_t PROP_NUMBER;
	}
	* request = (struct vs_get_property_request *) (message);
	struct __packed vs_get_property_confirm 
	{
		struct ethernet_std ethernet;
		struct qualcomm_std qualcomm;
		uint32_t MSTATUS;
		uint32_t COOKIE;
		uint8_t DATA_FORMAT;
		uint8_t RESERVED [3];
		uint32_t DATA_LENGTH;
		uint32_t DATA_BUFFER [1];
	}
	* confirm = (struct vs_get_property_confirm *) (message);

#ifndef __GNUC__
#pragma pack (pop)
#endif

	Request (plc, "Get Property");
	memset (message, 0, sizeof (* message));
	EthernetHeader (&request->ethernet, channel->peer, channel->host, HOMEPLUG_MTYPE);
	QualcommHeader (&request->qualcomm, 0, (VS_GET_PROPERTY | MMTYPE_REQ));
	request->COOKIE = HTOLE32 (plc->cookie);
	request->DATA_FORMAT = plcproperty->DATA_FORMAT;
	request->PROP_FORMAT = plcproperty->PROP_FORMAT;
	request->PROP_VERSION = HTOLE32 (plcproperty->PROP_VERSION);
	request->PROP_LENGTH = HTOLE32 (plcproperty->PROP_LENGTH);
	request->PROP_NUMBER = HTOLE32 (plcproperty->PROP_NUMBER);
	plc->packetsize = (ETHER_MIN_LEN - ETHER_CRC_LEN);
	if (SendMME (plc) <= 0) 
	{
		error ((plc->flags & PLC_BAILOUT), errno, CHANNEL_CANTSEND);
		return (-1);
	}
	while (ReadMME (plc, 0, (VS_GET_PROPERTY | MMTYPE_CNF)) > 0) 
	{
		if (confirm->MSTATUS) 
		{
			Failure (plc, PLC_WONTDOIT);
			continue;
		}
		if (plcproperty->DATA_FORMAT == PLC_FORMAT_BIN) 
		{
			binout (confirm->DATA_BUFFER, confirm->DATA_LENGTH, ' ', '\n', stdout);
			continue;
		}
		if (plcproperty->DATA_FORMAT == PLC_FORMAT_HEX) 
		{
			hexout (confirm->DATA_BUFFER, confirm->DATA_LENGTH, ' ', '\n', stdout);
			continue;
		}
		if (plcproperty->DATA_FORMAT == PLC_FORMAT_DEC) 
		{
			decout (confirm->DATA_BUFFER, confirm->DATA_LENGTH, ' ', '\n', stdout);
			continue;
		}
		if (plcproperty->DATA_FORMAT == PLC_FORMAT_ASC) 
		{
			chrout (confirm->DATA_BUFFER, confirm->DATA_LENGTH, '.', '\n', stdout);
			continue;
		}
	}
	return (0);
}
Exemple #14
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;
}
Exemple #15
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 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);
}
Exemple #17
0
u_int32_t
gzip_global(u_int8_t *data, u_int32_t size,
	int decomp, u_int8_t **out, int size_hint)
{
	/* decomp indicates whether we compress (0) or decompress (1) */
	z_stream zbuf;
	u_int8_t *output;
	u_int32_t count, result;
	int error, i, j;
	struct deflate_buf buf[ZBUF];
	u_int32_t crc;
	u_int32_t isize = 0, icrc = 0;

	DPRINTF(("gzip_global: decomp %d, size %d\n", decomp, size));

	memset(&zbuf, 0, sizeof(z_stream));
	zbuf.zalloc = ocf_zalloc;
	zbuf.zfree = ocf_zfree;
	zbuf.opaque = Z_NULL;

	if (!decomp) {
		/* compress */
		DPRINTF(("gzip_global: compress malloc %d + %d + %d = %d\n",
				size, sizeof(gzip_header), GZIP_TAIL_SIZE,
				size + sizeof(gzip_header) + GZIP_TAIL_SIZE));

		buf[0].size = size;
		crc = crc32(0, data, size);
		DPRINTF(("gzip_compress: size %d, crc 0x%x\n", size, crc));
		zbuf.avail_in = size;	/* Total length of data to be processed */
		zbuf.next_in = data;	/* data that is going to be processed */
	} else {
		/* decompress */
		/* check the gzip header */
		if (size <= sizeof(gzip_header) + GZIP_TAIL_SIZE) {
			/* Not enough data for the header & tail */
			DPRINTF(("gzip_global: not enough data (%d)\n",
					size));
			return 0;
		}

		/* XXX this is pretty basic,
		 * needs to be expanded to ignore MTIME, OS, 
		 * but still ensure flags are 0.
		 * Q. Do we need to support the flags and 
		 * optional header fields? Likely.
		 * XXX add flag and field support too.
		 */
		if (memcmp(data, gzip_header, sizeof(gzip_header)) != 0) {
			DPRINTF(("gzip_global: unsupported gzip header (%02x%02x)\n",
					data[0], data[1]));
			return 0;
		} else {
			DPRINTF(("gzip_global.%d: gzip header ok\n",__LINE__));
		}

		memcpy(&isize, &data[size-sizeof(uint32_t)], sizeof(uint32_t));
		LE32TOH(isize);
		memcpy(&icrc, &data[size-2*sizeof(uint32_t)], sizeof(uint32_t));
		LE32TOH(icrc);

		DPRINTF(("gzip_global: isize = %d (%02x %02x %02x %02x)\n",
				isize,
				data[size-4],
				data[size-3],
				data[size-2],
				data[size-1]));

		buf[0].size = isize;
		crc = crc32(0, NULL, 0);	/* get initial crc value */

		/* skip over the gzip header */
		zbuf.next_in = data + sizeof(gzip_header);

		/* actual payload size stripped of gzip header and tail */
		zbuf.avail_in = size - sizeof(gzip_header) - GZIP_TAIL_SIZE;
	}

	buf[0].out = malloc(buf[0].size, M_CRYPTO_DATA, M_NOWAIT);
	if (buf[0].out == NULL)
		return 0;
	zbuf.next_out = buf[0].out;
	zbuf.avail_out = buf[0].size;
	DPRINTF(("zbuf avail_in %d, avail_out %d\n",
			zbuf.avail_in, zbuf.avail_out));
	i = 1;

	error = decomp ? inflateInit2(&zbuf, window_inflate) :
	    deflateInit2(&zbuf, Z_DEFAULT_COMPRESSION, Z_METHOD,
		    window_deflate, Z_MEMLEVEL, Z_DEFAULT_STRATEGY);

	if (error != Z_OK) {
		printf("deflateInit2() failed\n");
		goto bad2;
	}
	for (;;) {
		DPRINTF(("pre: %s in:%d out:%d\n", decomp ? "deflate()" : "inflate()", 
				zbuf.avail_in, zbuf.avail_out));
		error = decomp ? inflate(&zbuf, Z_SYNC_FLUSH) :
				 deflate(&zbuf, Z_FINISH);
		DPRINTF(("post: %s in:%d out:%d\n", decomp ? "deflate()" : "inflate()", 
				zbuf.avail_in, zbuf.avail_out));
		if (error == Z_STREAM_END) /* success */
			break;
		/*
		 * XXX compensate for a zlib problem:
		 * -sys/net/zlib.c has a bug which makes that Z_BUF_ERROR is
		 *  set after successful decompression under rare conditions.
		 */
		else if (decomp && error == Z_BUF_ERROR
			 && zbuf.avail_in == 0 && zbuf.avail_out != 0)
				break;
		else if (error != Z_OK)
			goto bad;
		else if (zbuf.avail_out == 0) {
			/* we need more output space, allocate size */
			int nextsize = buf[i-1].size * 2;
			if (i == ZBUF || nextsize > 1000000)
				goto bad;
			buf[i].out = malloc(nextsize, M_CRYPTO_DATA, M_NOWAIT);
			if (buf[i].out == NULL)
				goto bad;
			zbuf.next_out = buf[i].out;
			zbuf.avail_out = buf[i].size = nextsize;
			i++;
		}
	}

	if (decomp) {
		count = result = zbuf.total_out;
	} else {
		/* need room for header, CRC, and ISIZE */
		result = zbuf.total_out + sizeof(gzip_header) + GZIP_TAIL_SIZE;
		count = zbuf.total_out;
	}

	DPRINTF(("gzip_global: in %d -> out %d\n", size, result));

	*out = malloc(result, M_CRYPTO_DATA, M_NOWAIT);
	if (*out == NULL)
		goto bad;
	output = *out;
	if (decomp)
		inflateEnd(&zbuf);
	else {
		deflateEnd(&zbuf);

		/* fill in gzip header */
		memcpy(output, gzip_header, sizeof(gzip_header));
		output += sizeof(gzip_header);
	}
	for (j = 0; j < i; j++) {
		if (decomp) {
			/* update crc for decompressed data */
			crc = crc32(crc, buf[j].out, MIN(count, buf[j].size));
		}
		if (count > buf[j].size) {
			memcpy(output, buf[j].out, buf[j].size);
			output += buf[j].size;
			free(buf[j].out, M_CRYPTO_DATA);
			count -= buf[j].size;
		} else {
			/* it should be the last buffer */
			memcpy(output, buf[j].out, count);
			output += count;
			free(buf[j].out, M_CRYPTO_DATA);
			count = 0;
		}
	}

	if (!decomp) {
		/* fill in CRC and ISIZE */
		HTOLE32(crc);
		memcpy(output, &crc, sizeof(uint32_t));
		HTOLE32(size);
		memcpy(output + sizeof(uint32_t), &size, sizeof(uint32_t));

		DPRINTF(("gzip_global: size = 0x%x (%02x %02x %02x %02x)\n",
				size,
				output[7],
				output[3],
				output[5],
				output[4]));
	} else {
		if (crc != icrc || result != isize) {
			DPRINTF(("gzip_global: crc/size mismatch\n"));
			free(*out, M_CRYPTO_DATA);
			*out = NULL;
			return 0;
		}
	}

	return result;

bad:
	if (decomp)
		inflateEnd(&zbuf);
	else
		deflateEnd(&zbuf);
bad2:
	*out = NULL;
	for (j = 0; j < i; j++)
		free(buf[j].out, M_CRYPTO_DATA);
	return 0;
}
Exemple #18
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);
}
Exemple #19
0
static signed psin (struct _file_ * pib)

{
	unsigned index = 0;
	unsigned count = 0;
	unsigned limit = pibscalers (pib);
	uint32_t value = 0;
	signed c;
	if ((limit != INT_CARRIERS) && (limit != AMP_CARRIERS) && (limit != PLC_CARRIERS))
	{
		error (1, 0, "Don't understand this PIB's prescaler format");
	}
	if (limit == INT_CARRIERS)
	{
		if (lseek (pib->file, INT_PRESCALER_OFFSET, SEEK_SET) != INT_PRESCALER_OFFSET)
		{
			error (1, errno, FILE_CANTSEEK, pib->name);
		}
	}
	else if (limit == PLC_CARRIERS)
	{
		if (lseek (pib->file, QCA_PRESCALER_OFFSET, SEEK_SET) != QCA_PRESCALER_OFFSET)
		{
			error (1, errno, FILE_CANTSEEK, pib->name);
		}
	}
	while ((c = getc (stdin)) != EOF)
	{
		if (isspace (c))
		{
			continue;
		}
		if ((c == '#') || (c == ';'))
		{
			do
			{
				c = getc (stdin);
			}
			while (nobreak (c));
			continue;
		}
		index = 0;
		while (isdigit (c))
		{
			index *= 10;
			index += c - '0';
			c = getc (stdin);
		}
		if (index != count)
		{
			error (1, ECANCELED, "Carrier %d out of order", index);
		}
		if (index >= limit)
		{
			error (1, EOVERFLOW, "Too many prescalers");
		}
		while (isblank (c))
		{
			c = getc (stdin);
		}
		value = 0;
		while (isxdigit (c))
		{
			value *= 16;
			value += todigit (c);
			c = getc (stdin);
		}
		if (limit == INT_CARRIERS)
		{
			value = HTOLE32 (value);
			if (write (pib->file, &value, sizeof (value)) != sizeof (value))
			{
				error (1, errno, "Can't save %s", pib->name);
			}
		}
		else if (limit == AMP_CARRIERS)
		{
			if (value & ~0x03FF)
			{
				error (1, errno, "Position %d has invalid prescaler value", index);
			}
			if (ar7x00_psin (pib, value, index))
			{
				error (1, errno, "Can't update %s", pib->name);
			}
		}
		else if (limit == PLC_CARRIERS)
		{
			uint8_t tmp = value & 0xff;
			if (write (pib->file, &tmp, sizeof (tmp)) != sizeof (tmp))
			{
				error (1, errno, "Can't save %s", pib->name);
			}
		}

		while (nobreak (c))
		{
			c = getc (stdin);
		};
		count++;
	}
	return (0);
}
Exemple #20
0
int
ubsec_process(struct cryptop *crp)
{
	struct ubsec_q *q = NULL;
	int card, err = 0, i, j, s, nicealign;
	struct ubsec_softc *sc;
	struct cryptodesc *crd1, *crd2, *maccrd, *enccrd;
	int encoffset = 0, macoffset = 0, cpskip, cpoffset;
	int sskip, dskip, stheend, dtheend;
	int16_t coffset;
	struct ubsec_session *ses, key;
	struct ubsec_dma *dmap = NULL;
	u_int16_t flags = 0;
	int ivlen = 0, keylen = 0;

	if (crp == NULL || crp->crp_callback == NULL) {
		ubsecstats.hst_invalid++;
		return (EINVAL);
	}
	card = UBSEC_CARD(crp->crp_sid);
	if (card >= ubsec_cd.cd_ndevs || ubsec_cd.cd_devs[card] == NULL) {
		ubsecstats.hst_invalid++;
		return (EINVAL);
	}

	sc = ubsec_cd.cd_devs[card];

	s = splnet();

	if (SIMPLEQ_EMPTY(&sc->sc_freequeue)) {
		ubsecstats.hst_queuefull++;
		splx(s);
		err = ENOMEM;
		goto errout2;
	}

	q = SIMPLEQ_FIRST(&sc->sc_freequeue);
	SIMPLEQ_REMOVE_HEAD(&sc->sc_freequeue, q_next);
	splx(s);

	dmap = q->q_dma; /* Save dma pointer */
	bzero(q, sizeof(struct ubsec_q));
	bzero(&key, sizeof(key));

	q->q_sesn = UBSEC_SESSION(crp->crp_sid);
	q->q_dma = dmap;
	ses = &sc->sc_sessions[q->q_sesn];

	if (crp->crp_flags & CRYPTO_F_IMBUF) {
		q->q_src_m = (struct mbuf *)crp->crp_buf;
		q->q_dst_m = (struct mbuf *)crp->crp_buf;
	} else if (crp->crp_flags & CRYPTO_F_IOV) {
		q->q_src_io = (struct uio *)crp->crp_buf;
		q->q_dst_io = (struct uio *)crp->crp_buf;
	} else {
		err = EINVAL;
		goto errout;	/* XXX we don't handle contiguous blocks! */
	}

	bzero(&dmap->d_dma->d_mcr, sizeof(struct ubsec_mcr));

	dmap->d_dma->d_mcr.mcr_pkts = htole16(1);
	dmap->d_dma->d_mcr.mcr_flags = 0;
	q->q_crp = crp;

	crd1 = crp->crp_desc;
	if (crd1 == NULL) {
		err = EINVAL;
		goto errout;
	}
	crd2 = crd1->crd_next;

	if (crd2 == NULL) {
		if (crd1->crd_alg == CRYPTO_MD5_HMAC ||
		    crd1->crd_alg == CRYPTO_SHA1_HMAC) {
			maccrd = crd1;
			enccrd = NULL;
		} else if (crd1->crd_alg == CRYPTO_3DES_CBC ||
		    crd1->crd_alg == CRYPTO_AES_CBC) {
			maccrd = NULL;
			enccrd = crd1;
		} else {
			err = EINVAL;
			goto errout;
		}
	} else {
		if ((crd1->crd_alg == CRYPTO_MD5_HMAC ||
		    crd1->crd_alg == CRYPTO_SHA1_HMAC) &&
		    (crd2->crd_alg == CRYPTO_3DES_CBC ||
		    crd2->crd_alg == CRYPTO_AES_CBC) &&
		    ((crd2->crd_flags & CRD_F_ENCRYPT) == 0)) {
			maccrd = crd1;
			enccrd = crd2;
		} else if ((crd1->crd_alg == CRYPTO_3DES_CBC ||
		    crd1->crd_alg == CRYPTO_AES_CBC) &&
		    (crd2->crd_alg == CRYPTO_MD5_HMAC ||
		    crd2->crd_alg == CRYPTO_SHA1_HMAC) &&
		    (crd1->crd_flags & CRD_F_ENCRYPT)) {
			enccrd = crd1;
			maccrd = crd2;
		} else {
			/*
			 * We cannot order the ubsec as requested
			 */
			err = EINVAL;
			goto errout;
		}
	}

	if (enccrd) {
		if (enccrd->crd_alg == CRYPTO_AES_CBC) {
			if ((sc->sc_flags & UBS_FLAGS_AES) == 0) {
				err = EINVAL;
				goto errout;
			}
			flags |= htole16(UBS_PKTCTX_ENC_AES);
			switch (enccrd->crd_klen) {
			case 128:
			case 192:
			case 256:
				keylen = enccrd->crd_klen / 8;
				break;
			default:
				err = EINVAL;
				goto errout;
			}
			ivlen = 16;
		} else {
			flags |= htole16(UBS_PKTCTX_ENC_3DES);
			ivlen = 8;
			keylen = 24;
		}

		encoffset = enccrd->crd_skip;

		if (enccrd->crd_flags & CRD_F_ENCRYPT) {
			if (enccrd->crd_flags & CRD_F_IV_EXPLICIT)
				bcopy(enccrd->crd_iv, key.ses_iv, ivlen);
			else
				arc4random_buf(key.ses_iv, ivlen);

			if ((enccrd->crd_flags & CRD_F_IV_PRESENT) == 0) {
				if (crp->crp_flags & CRYPTO_F_IMBUF)
					err = m_copyback(q->q_src_m,
					    enccrd->crd_inject,
					    ivlen, key.ses_iv, M_NOWAIT);
				else if (crp->crp_flags & CRYPTO_F_IOV)
					cuio_copyback(q->q_src_io,
					    enccrd->crd_inject,
					    ivlen, key.ses_iv);
				if (err)
					goto errout;
			}
		} else {
			flags |= htole16(UBS_PKTCTX_INBOUND);

			if (enccrd->crd_flags & CRD_F_IV_EXPLICIT)
				bcopy(enccrd->crd_iv, key.ses_iv, ivlen);
			else if (crp->crp_flags & CRYPTO_F_IMBUF)
				m_copydata(q->q_src_m, enccrd->crd_inject,
				    ivlen, (caddr_t)key.ses_iv);
			else if (crp->crp_flags & CRYPTO_F_IOV)
				cuio_copydata(q->q_src_io,
				    enccrd->crd_inject, ivlen,
				    (caddr_t)key.ses_iv);
		}

		for (i = 0; i < (keylen / 4); i++)
			key.ses_key[i] = ses->ses_key[i];
		for (i = 0; i < (ivlen / 4); i++)
			SWAP32(key.ses_iv[i]);
	}

	if (maccrd) {
		macoffset = maccrd->crd_skip;

		if (maccrd->crd_alg == CRYPTO_MD5_HMAC)
			flags |= htole16(UBS_PKTCTX_AUTH_MD5);
		else
			flags |= htole16(UBS_PKTCTX_AUTH_SHA1);

		for (i = 0; i < 5; i++) {
			key.ses_hminner[i] = ses->ses_hminner[i];
			key.ses_hmouter[i] = ses->ses_hmouter[i];

			HTOLE32(key.ses_hminner[i]);
			HTOLE32(key.ses_hmouter[i]);
		}
	}

	if (enccrd && maccrd) {
		/*
		 * ubsec cannot handle packets where the end of encryption
		 * and authentication are not the same, or where the
		 * encrypted part begins before the authenticated part.
		 */
		if (((encoffset + enccrd->crd_len) !=
		    (macoffset + maccrd->crd_len)) ||
		    (enccrd->crd_skip < maccrd->crd_skip)) {
			err = EINVAL;
			goto errout;
		}
		sskip = maccrd->crd_skip;
		cpskip = dskip = enccrd->crd_skip;
		stheend = maccrd->crd_len;
		dtheend = enccrd->crd_len;
		coffset = enccrd->crd_skip - maccrd->crd_skip;
		cpoffset = cpskip + dtheend;
#ifdef UBSEC_DEBUG
		printf("mac: skip %d, len %d, inject %d\n",
 		    maccrd->crd_skip, maccrd->crd_len, maccrd->crd_inject);
		printf("enc: skip %d, len %d, inject %d\n",
		    enccrd->crd_skip, enccrd->crd_len, enccrd->crd_inject);
		printf("src: skip %d, len %d\n", sskip, stheend);
		printf("dst: skip %d, len %d\n", dskip, dtheend);
		printf("ubs: coffset %d, pktlen %d, cpskip %d, cpoffset %d\n",
		    coffset, stheend, cpskip, cpoffset);
#endif
	} else {
		cpskip = dskip = sskip = macoffset + encoffset;
		dtheend = stheend = (enccrd)?enccrd->crd_len:maccrd->crd_len;
		cpoffset = cpskip + dtheend;
		coffset = 0;
	}

	if (bus_dmamap_create(sc->sc_dmat, 0xfff0, UBS_MAX_SCATTER,
		0xfff0, 0, BUS_DMA_NOWAIT, &q->q_src_map) != 0) {
		err = ENOMEM;
		goto errout;
	}
	if (crp->crp_flags & CRYPTO_F_IMBUF) {
		if (bus_dmamap_load_mbuf(sc->sc_dmat, q->q_src_map,
		    q->q_src_m, BUS_DMA_NOWAIT) != 0) {
			bus_dmamap_destroy(sc->sc_dmat, q->q_src_map);
			q->q_src_map = NULL;
			err = ENOMEM;
			goto errout;
		}
	} else if (crp->crp_flags & CRYPTO_F_IOV) {
		if (bus_dmamap_load_uio(sc->sc_dmat, q->q_src_map,
		    q->q_src_io, BUS_DMA_NOWAIT) != 0) {
			bus_dmamap_destroy(sc->sc_dmat, q->q_src_map);
			q->q_src_map = NULL;
			err = ENOMEM;
			goto errout;
		}
	}
	nicealign = ubsec_dmamap_aligned(q->q_src_map);

	dmap->d_dma->d_mcr.mcr_pktlen = htole16(stheend);

#ifdef UBSEC_DEBUG
	printf("src skip: %d\n", sskip);
#endif
	for (i = j = 0; i < q->q_src_map->dm_nsegs; i++) {
		struct ubsec_pktbuf *pb;
		bus_size_t packl = q->q_src_map->dm_segs[i].ds_len;
		bus_addr_t packp = q->q_src_map->dm_segs[i].ds_addr;

		if (sskip >= packl) {
			sskip -= packl;
			continue;
		}

		packl -= sskip;
		packp += sskip;
		sskip = 0;

		if (packl > 0xfffc) {
			err = EIO;
			goto errout;
		}

		if (j == 0)
			pb = &dmap->d_dma->d_mcr.mcr_ipktbuf;
		else
			pb = &dmap->d_dma->d_sbuf[j - 1];

		pb->pb_addr = htole32(packp);

		if (stheend) {
			if (packl > stheend) {
				pb->pb_len = htole32(stheend);
				stheend = 0;
			} else {
				pb->pb_len = htole32(packl);
				stheend -= packl;
			}
		} else
			pb->pb_len = htole32(packl);

		if ((i + 1) == q->q_src_map->dm_nsegs)
			pb->pb_next = 0;
		else
			pb->pb_next = htole32(dmap->d_alloc.dma_paddr +
			    offsetof(struct ubsec_dmachunk, d_sbuf[j]));
		j++;
	}

	if (enccrd == NULL && maccrd != NULL) {
		dmap->d_dma->d_mcr.mcr_opktbuf.pb_addr = 0;
		dmap->d_dma->d_mcr.mcr_opktbuf.pb_len = 0;
		dmap->d_dma->d_mcr.mcr_opktbuf.pb_next =
		    htole32(dmap->d_alloc.dma_paddr +
		    offsetof(struct ubsec_dmachunk, d_macbuf[0]));
#ifdef UBSEC_DEBUG
		printf("opkt: %x %x %x\n",
		    dmap->d_dma->d_mcr.mcr_opktbuf.pb_addr,
		    dmap->d_dma->d_mcr.mcr_opktbuf.pb_len,
		    dmap->d_dma->d_mcr.mcr_opktbuf.pb_next);
#endif
	} else {
Exemple #21
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);
}
Exemple #22
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 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 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 WriteFirmware1 (struct plc * plc, unsigned module, const struct nvm_header1 * nvm_header)

{
	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_mem_request
	{
		struct ethernet_hdr ethernet;
		struct qualcomm_hdr qualcomm;
		uint32_t MOFFSET;
		uint32_t MLENGTH;
		uint8_t BUFFER [PLC_RECORD_SIZE];
	}
	* request = (struct vs_wr_mem_request *) (message);
	struct __packed vs_wr_mem_confirm
	{
		struct ethernet_hdr ethernet;
		struct qualcomm_hdr qualcomm;
		uint8_t MSTATUS;
		uint32_t MOFFSET;
		uint32_t MLENGTH;
	}
	* confirm = (struct vs_wr_mem_confirm *) (message);

#ifndef __GNUC__
#pragma pack (pop)
#endif

	uint32_t length = PLC_RECORD_SIZE;
	uint32_t offset = LE32TOH (nvm_header->IMAGEADDRESS);
	uint32_t extent = LE32TOH (nvm_header->IMAGELENGTH);
	Request (plc, "Write %s (%d) (%08X:%d)", plc->NVM.name, module, offset, extent);
	while (extent)
	{
		memset (message, 0, sizeof (* message));
		EthernetHeader (&request->ethernet, channel->peer, channel->host, channel->type);
		QualcommHeader (&request->qualcomm, 0, (VS_WR_MEM | MMTYPE_REQ));
		if (length > extent)
		{
			length = extent;
		}
		if (read (plc->NVM.file, request->BUFFER, length) != (signed)(length))
		{
			error (1, errno, FILE_CANTREAD, plc->NVM.name);
		}
		request->MLENGTH = HTOLE32 (length);
		request->MOFFSET = HTOLE32 (offset);
		plc->packetsize = sizeof (* request);
		if (SendMME (plc) <= 0)
		{
			error (PLC_EXIT (plc), errno, CHANNEL_CANTSEND);
			return (-1);
		}
		if (ReadMME (plc, 0, (VS_WR_MEM | MMTYPE_CNF)) <= 0)
		{
			error (PLC_EXIT (plc), errno, CHANNEL_CANTREAD);
			return (-1);
		}
		if (confirm->MSTATUS)
		{
			Failure (plc, PLC_WONTDOIT);
			return (-1);
		}
		if (LE32TOH (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);
}
Exemple #26
0
signed VersionInfo2 (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_sw_ver_request
	{
		struct ethernet_hdr ethernet;
		struct qualcomm_hdr qualcomm;
		uint32_t COOKIE;
	}
	* request = (struct vs_sw_ver_request *) (message);
	struct __packed vs_sw_ver_confirm
	{
		struct ethernet_hdr ethernet;
		struct qualcomm_hdr qualcomm;
		uint8_t MSTATUS;
		uint8_t MDEVICE_CLASS;
		uint8_t MVERLENGTH;
		char MVERSION [254];
		uint32_t IDENT;
		uint32_t STEPPING_NUM;
		uint32_t COOKIE;
		uint32_t RSVD [6];
	}
	* confirm = (struct vs_sw_ver_confirm *) (message);

#ifndef __GNUC__
#pragma pack (pop)
#endif

	Request (plc, "Request Version Information");
	memset (message, 0, sizeof (* message));
	EthernetHeader (&request->ethernet, channel->peer, channel->host, channel->type);
	QualcommHeader (&request->qualcomm, 0, (VS_SW_VER | MMTYPE_REQ));
	request->COOKIE = HTOLE32 (plc->cookie);
	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_SW_VER | MMTYPE_CNF)) > 0)
	{

#if 0

		fprintf (stderr, "DEVICE CLASS (%d)\n", LE32TOH (confirm->MDEVICE_CLASS));
		fprintf (stderr, "VERSION LENGTH (%d)\n", LE32TOH (confirm->MVERLENGTH));
		fprintf (stderr, "VERSION STRING [%s]\n", LE32TOH (confirm->MVERSION));
		fprintf (stderr, "IDENT [0x%08X]\n", LE32TOH (confirm->IDENT));
		fprintf (stderr, "STEPPING NUMBER [0x%08X]\n", LE32TOH (confirm->STEPPING_NUM));
		fprintf (stderr, "COOKIE [0x%08X]\n", LE32TOH (confirm->COOKIE));

#endif

		if (confirm->MSTATUS)
		{
			Failure (plc, PLC_WONTDOIT);
			continue;
		}
		chipset (confirm);
		Display (plc, "%s %s", chipsetname (confirm->MDEVICE_CLASS), confirm->MVERSION);
	}
	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);
}
Exemple #28
0
static signed ReadVLANIDs (struct plc * plc, uint32_t offset, uint32_t length)

{
	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;
		uint32_t DATA_LENGTH;
		uint32_t DATA_OFFSET;
		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;
		uint32_t DATA_LENGTH;
		uint32_t DATA_OFFSET;
		uint8_t DATA [PLC_MODULE_SIZE];
	}
	* 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_GET;
	request->MVERSION = PLCFWD_VER;
	request->DATA_OFFSET = HTOLE32 (offset);
	request->DATA_LENGTH = HTOLE32 (length);
	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;
		}
		hexview (confirm->DATA, LE32TOH (confirm->DATA_OFFSET), LE32TOH (confirm->DATA_LENGTH), stdout);
	}
	return (0);
}
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);
}
signed ModuleRead (struct plc * plc, struct _file_ * file, 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 timer = channel->timeout;
	uint16_t length = PLC_MODULE_SIZE;
	uint32_t offset = 0;
	Request (plc, "Read Module from %s", source? "Flash": "Memory");
	if (lseek (file->file, 0, SEEK_SET) == -1)
	{
		error (PLC_EXIT (plc), errno, FILE_CANTHOME, file->name);
		return (-1);
	}
	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 0
#if defined (__GNUC__)
#warning "Debug code active in module ModuleRead"
#endif

		fprintf (stderr, "----- \n");
		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));
		fprintf (stderr, "\n");

#endif

		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);
			return (-1);
		}
		channel->timeout = timer;

#if 0
#if defined (__GNUC__)
#warning "Debug code active in module ModuleRead"
#endif

		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 (confirm->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 (confirm->MODULE_SPEC.MODULE_OFFSET));
		fprintf (stderr, "\n");

#endif

		if (LE16TOH (confirm->MSTATUS))
		{
			Failure (plc, PLC_WONTDOIT);
			return (-1);
		}
		length = LE16TOH (confirm->MODULE_SPEC.MODULE_LENGTH);
		offset = LE32TOH (confirm->MODULE_SPEC.MODULE_OFFSET);
		if (write (file->file, confirm->MODULE_DATA, length) != (signed)(length))
		{
			error (PLC_EXIT (plc), errno, FILE_CANTSAVE, file->name);
			return (-1);
		}
		offset += length;
	}
	return (0);
}