Ejemplo n.º 1
0
Archivo: packet.c Proyecto: estock/spot
int packet_read (SESSION * session, PHEADER * h, unsigned char **payload)
{
	int ret;
	int packet_len;
	unsigned char nonce[4];
	unsigned char *ptr;

	packet_len = 0;
	if ((ret = block_read (session->ap_sock, h, 3)) != 3) {
		DSFYDEBUG
			("packet_read(): read short count %d, expected 3 (header)\n",
			 ret);
		return -1;
	}

	*(unsigned int *) nonce = htonl (session->key_recv_IV);
	shn_nonce (&session->shn_recv, nonce, 4);

	shn_decrypt (&session->shn_recv, (unsigned char *) h, 3);

#ifdef DEBUG_PACKETS
	DSFYDEBUG ("packet_read(): cmd=%d [0x%02x], len=%d [0x%04x]\n",
		   h->cmd, h->cmd, ntohs (h->len), ntohs (h->len));
	logdata ("recv-hdr", session->key_recv_IV, (unsigned char *) h, 3);
#endif

	/* Length of payload */
	h->len = ntohs (h->len);
	packet_len = h->len;

	/* Account for MAC */
	packet_len += 4;

	ptr = (unsigned char *) malloc (packet_len);
	if ((*payload = ptr) == NULL)
		return -1;

	if ((ret =
	     block_read (session->ap_sock, ptr, packet_len)) != packet_len) {
		DSFYDEBUG
			("packet_read(cmd=0x%02x): read short count %d, expected %d\n",
			 h->cmd, ret, packet_len);
		return -1;
	}

	shn_decrypt (&session->shn_recv, *payload, packet_len);

#ifdef DEBUG_PACKETS
	logdata ("recv-dec", session->key_recv_IV, *payload, h->len);
#endif

	/* Increment IV */
	session->key_recv_IV++;

	return 0;
}
Ejemplo n.º 2
0
int packet_read_and_process(sp_session *session) {
	fd_set rfds;
	struct timeval tv;
	int ret;
	struct buf *packet;
	PHEADER header;
	unsigned char nonce[4];


	if(session->packet == NULL)
		session->packet = buf_new();
	else if(session->packet->len == session->packet->size)
		buf_extend(session->packet, session->packet->size);


	FD_ZERO(&rfds);
	FD_SET(session->sock, &rfds);
	
	tv.tv_sec = 0;
	tv.tv_usec = 64 * 1000;

	ret = select(session->sock + 1, &rfds, NULL, NULL, &tv);
	if(ret <= 0)
		return ret;


	ret = recv(session->sock,
			session->packet->ptr + session->packet->len, 
			session->packet->size - session->packet->len, 0);
	if(ret <= 0)
		return -1;


	/* We need a complete packet header of three bytes */
	session->packet->len += ret;
	while(session->packet->len >= 3) {

		/* Set nonce for Shannon */
		*(unsigned int *)nonce = htonl(session->key_recv_IV);
		shn_nonce(&session->shn_recv, nonce, 4);


		/* Decrypt the packet header */
		memcpy(&header, session->packet->ptr, 3);
		shn_decrypt(&session->shn_recv, (unsigned char *)&header, 3);


		/* Make sure we have the entire payload aswell as the MAC */
		header.len = ntohs(header.len);
		DSFYDEBUG("%d bytes buffered, header.cmd=0x%02x, header.len=%d\n",
			session->packet->len, header.cmd, header.len);
		if(session->packet->len < 3 + header.len + 4)
			break;


		/* Extract the full packet, leaving eventual additional data as is */
		packet = buf_consume(session->packet, 3 + header.len + 4);


		/* Copy back the decrypted header and decrypt the payload */
		memcpy(packet->ptr, &header, 3);
		shn_decrypt(&session->shn_recv, packet->ptr + 3, header.len);


		/* Increment receiving IV */
		session->key_recv_IV++;


		if(handle_packet(session, header.cmd, packet->ptr + 3, header.len)) {
			DSFYDEBUG("handle_packet() failed with an error\n");
			return -1;
		}
	}


	return 0;
}