int main(void)
{
	struct prot msg, tmp;
	char bindata[256] =
			"\x01\x00\x00\x00"
			"\x24\x00\x00\x00"
			"\x01\x00\x00\x00"
			"\x4F\x00\x00\x00"
			"some string data in a binary message\x00\x00\x00\x00"
			"A\x00\x00\x00\x00\x00\x00\x00"
			"more zero-terminated string data in a binary message, the best of both worlds?!\x00\x00";
	char shens[256];
	packet_decode(&msg, bindata);
	packet_encode(shens, &msg, sizeof shens);
	packet_decode(&tmp, shens);
	dump(bindata, sizeof bindata);
	printf(
		"\nid=%u, str1len=%u, str2len=%u, str3len=%u\n"
		"str1=\"%s\", str2=\"%s\", str3=\"%s\"\n",
		msg.head->id, msg.head->str1len, msg.head->str2len, 
		msg.head->str3len, msg.str1, msg.str2, msg.str3);
	dump(shens, sizeof shens);
	printf(
		"\nid=%u, str1len=%u, str2len=%u, str3len=%u\n"
		"str1=\"%s\", str2=\"%s\", str3=\"%s\"\n",
		tmp.head->id, tmp.head->str1len, tmp.head->str2len, 
		tmp.head->str3len, tmp.str1, tmp.str2, tmp.str3);
	return 0;
}
Example #2
0
int
packet_decode_pcap(Packet *packet, const uint8_t *pkt,
    const struct pcap_pkthdr *pkthdr)
{
    if (pkthdr == NULL)
        return -1;

    return packet_decode(packet, pkt, pkthdr->caplen);
}
END_TEST

START_TEST(test_packet_decode_with_zero_size)
{
    Packet *packet = packet_create( );

    int err = packet_decode(packet, pkt10, 0);

    fail_unless((err != 0), "packet_decode returned OK expected ERROR");

    packet_destroy(packet);
}
END_TEST

START_TEST(test_packet_decode_with_null_data_pointer)
{
    Packet *packet = packet_create( );

    int err = packet_decode(packet, NULL, sizeof pkt10);

    fail_unless((err != 0), "packet_decode returned OK expected ERROR");

    packet_destroy(packet);
}
END_TEST

/* XXX
 * This test isn't really supposed to be here but its the best way to
 * validate that the decode went through the entire packet */
START_TEST(test_packet_proto_count)
{
    Packet *packet = packet_create( );

    int err = packet_decode(packet, pkt10, sizeof pkt10);

    fail_unless((err == 0), "packet_decode returned ERROR");

    err = packet_proto_count(packet);
    fail_unless((err == 5), 
        "packet_proto_count(packet) returned %d, expected 5", err);

    unsigned i;
    Protocol *proto = packet_proto_first(packet, &i);
    fail_unless((packet_proto_proto(proto) == PROTO_ETH), 
        "layer %d not ETH");

    proto = packet_proto_next(packet, &i);
    fail_unless((packet_proto_proto(proto) == PROTO_PPPOE), 
        "layer %d not PPPOE");

    proto = packet_proto_next(packet, &i);
    fail_unless((packet_proto_proto(proto) == PROTO_PPP), 
        "layer %d not PPP");

    proto = packet_proto_next(packet, &i);
    fail_unless((packet_proto_proto(proto) == PROTO_IP4), 
        "layer %d not IP4");

    proto = packet_proto_next(packet, &i);
    fail_unless((packet_proto_proto(proto) == PROTO_TCP), 
        "layer %d not TCP");

    packet_destroy(packet);
}
int main(int argc,char *argv[]) {
    int argno;

    fprintf(stderr, "SPI decoder, V%s\n", VERSION);

    argno = HandleOptions(argc,argv);

    if (fileread) {
        if ((datfile = fopen(DATFILENAME,"r")) == NULL) // opne to read from .dat file
            fatal_err(DATFILENAME " open for read failed");
        fprintf(stderr, "Reading from " DATFILENAME "\n");
    }
    else {
        char dev_name[80];
        sprintf(dev_name, "\\\\.\\COM%d", comport);
        fprintf(stderr, "Opening serial port on %s...", dev_name);
        handle_serial = CreateFile(dev_name, GENERIC_READ | GENERIC_WRITE, 0, 0,
            OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
        if (handle_serial!=INVALID_HANDLE_VALUE) {
            dcbSerialParams.BaudRate = 115200;
            dcbSerialParams.ByteSize = 8;
            dcbSerialParams.StopBits = ONESTOPBIT;
            dcbSerialParams.Parity = NOPARITY;
            dcbSerialParams.DCBlength = sizeof(DCB);
            if(SetCommState(handle_serial, &dcbSerialParams) == 0) fatal_err("Error setting serial port parameters");
            timeouts.ReadIntervalTimeout =  100;  		// msec
            timeouts.ReadTotalTimeoutConstant = 200;    // msec
            timeouts.ReadTotalTimeoutMultiplier = 0;  // msec
            timeouts.WriteTotalTimeoutConstant = 50;
            timeouts.WriteTotalTimeoutMultiplier = 10;
            if(SetCommTimeouts(handle_serial, &timeouts) == 0) fatal_err("Error setting serial port timeouts");
            fprintf(stderr,"OK\n");
        }
        else fatal_err("Failed");
        if ((datfile = fopen(DATFILENAME,"a")) == NULL) // open to append to .dat file
            fatal_err(DATFILENAME " open for append failed");
    }

    if ((outfile = fopen(OUTFILENAME,"a")) == NULL) fatal_err(OUTFILENAME " open failed");
    if ((pktfile = fopen(PKTFILENAME,"a")) == NULL) fatal_err(PKTFILENAME " open failed");
    fprintf(pktfile, "\n");

    // atexit(cleanup);
    fprintf(stderr, "Starting.\n");

    while(!kbhit()) {
more_data:
        if (fileread) { // read from .dat file
            if (!fgets(line, MAX_LINE, datfile)) {
                output("***end of file");
                fprintf(stderr, "***end of file");
                cleanup();
                exit(0);
            }
            ++linecnt;
            bytes_read = strlen(line);
            output("got %d bytes from the file\n", bytes_read);
        }
        else {  // read from serial port
            // printf("reading serial port com%d...\n", comport);
            ReadFile(handle_serial, line, MAX_LINE, &bytes_read, NULL);
            line[bytes_read]='\0';
            if (bytes_read != 0) {
                output("got %d bytes from serial port\n", bytes_read);
                fprintf(stderr, "got %d bytes from the serial port\n", bytes_read);
                fprintf(datfile, "%s\n", line);
            }
        }

        if (strcmp(line, "SPI Sniffer\n") == 0) {
            fprintf(stderr, "\"SPI Sniffer\" header line read\n");
            continue;
        }
        // output("decode %n bytes: %s\n", bytes_read, line);
        lineptr = line;
        while (*lineptr != '\0') {
            skip_to_next_data();  // process input up to next master/slave data pair
            if (*lineptr == '\0')break;
next_command:
            if (!read_data_pair()) goto more_data;
            isread = master_data & 0x80; 	// "read register" flag bit
            isburst = master_data & 0x40;	// "burst" flag bit
            regnum = master_data & 0x3f;  	// register number 0 to 63

            if (isread) { //  config register read
                if (regnum >= 0x30 && regnum <= 0x3d && !isburst) { // no, is really command strobe
                    command_strobe();
                }
                else {
                    if(isburst){
                        if (regnum == 0x3f) { // read RX FIFO: receive packet
                            if (!chip_selected) exit_msg("burst RX FIFO write without chip selected", regnum);
                            show_config_reg("read", true);
                            packet.xmit = false;
                            while (1) { // show all burst read data from FIFO
                                if (!skip_timestamp()) goto next_command;
                                if (*lineptr == ']') break; // ends with chip unselect
                                if (!read_data_pair()) goto next_command;
                                output(" %02X", slave_data);
                                if (packet.length < MAX_PKT)	{
                                    packet.data[packet.length++] = slave_data;
                                }
                            }
                            output("\n");
                            packet_decode();
                        }
                        else  { // burst read of other than FIFO: consecutive config registers
                            if (!skip_to_next_data()) goto next_command;
                            while (1) {
                                if (!skip_timestamp()) goto next_command;
                                if (*lineptr == ']') break; // ends with chip unselect
                                if (!read_data_pair()) goto next_command;
                                regval = slave_data;
                                show_config_reg("read", false);
                                if (++regnum >= 0x40) exit_msg("burst read of too many config registers", regnum);
                            }
                        }
                    }
                    else { // regular single-register read
                        if (!read_data_pair()) goto next_command;
                        regval = slave_data;
                        show_config_reg("read", false);
                    }
                }
            }
            else { // register write
                if (regnum >= 0x30 && regnum <= 0x3d && !isburst) { // no, is really command strobe
                    command_strobe();
                }
                else if (regnum == 0x3e) { // write power table
                    if (isburst) {
                        if (!chip_selected) exit_msg("burst power table write without chip selected", regnum);
                        show_config_reg("write", true);
                        while (1) { // show all burst write data to power table
                            if (!skip_timestamp()) goto next_command;
                            if (*lineptr == ']') break; // ends with chip unselect
                            if (!read_data_pair()) goto next_command;
                            output(" %02X", master_data);
                        }
                        output("\n");
                    }
                    else { // non-burst write to power table
                        if (!read_data_pair()) goto next_command;
                        regval = master_data;
                        show_config_reg("write", false);
                    }
                }
                else if (regnum == 0x3f) { // write TX FIFO: transmit packet
                    if (!isburst) exit_msg("implement non-burst TX FIFO write", regnum);
                    if (!chip_selected) exit_msg("burst TX FIFO write without chip selected", regnum);
                    show_config_reg("write", true);
                    packet.xmit = true;
                    while (1) { // show all burst write data to FIFO
                        if (!skip_timestamp()) goto next_command;
                        if (*lineptr == ']') break; // ends with chip unselect
                        if (!read_data_pair()) goto next_command;
                        output(" %02X", master_data);
                        if (packet.length < MAX_PKT) {
                            packet.data[packet.length++] = master_data;
                        }
                    }
                    output("\n");
                    packet_decode();
                }
                else { // writing config register(s)
                    if (isburst) { // burst config register write
                        int bytes_bursted, bytes_changed, start_reg, end_reg;
                        bytes_bursted = 0;
                        bytes_changed = 0;
                        start_reg = regnum;
                        // output("burst config write\n");
                        if (!chip_selected) output("burst write without chip selected at reg %02X", regnum);
                        while (1) { // read all the burst write data
                            if (!skip_timestamp()) goto next_command;
                            if (*lineptr == ']') break; // ends with chip unselect
                            if (regnum > 0x2e) exit_msg("too much burst data", regnum);
                            if (!read_data_pair()) goto next_command;
                            new_config_regs[regnum++] = master_data;
                            ++bytes_bursted;
                        }
                        end_reg = regnum-1;
                        for (regnum=start_reg; regnum<end_reg; ++regnum) {  // show only those that changed
                            if ((new_config_regs[regnum] != current_config_regs[regnum])) {
                                regval = new_config_regs[regnum];
                                show_config_reg(" wrote", false);
                                current_config_regs[regnum] = new_config_regs[regnum];
                                ++bytes_changed;
                            }
                        }
                        show_delta_time();
                        output(" burst wrote %d registers, and %d changed\n", bytes_bursted, bytes_changed);
                    }
                    else {  // single register write
                        if (!read_data_pair()) goto next_command;
                        regval = master_data;
                        show_config_reg("write", false);
                        current_config_regs[regnum] = regval;
                    }
                }
            }
        }
    }
    return 0;
}
void setup( )
{
    packet = packet_create( );
    packet_decode(packet, pkt10, sizeof pkt10);
}
Example #8
0
/*!
  \brief This functions handles all incoing data from the ECU and validates
  its content for proper START/STOP/ESCAPING and allocates a FreeEMS_Packet
  structure for VALID packets and populates the required fields as needed
  \param buf is a pointer to the incoming data buffer
  \param len is the numbe of bytes to pull from the incoming buffer
  */
G_MODULE_EXPORT void handle_data(guchar *buf, gint len)
{
	static GAsyncQueue *queue = NULL;
	/* Statistic collection variables */
	static guchar packetBuffer[3000];
	static unsigned int packets = 0;
	static unsigned int charsDropped = 0;
	static unsigned int badChecksums = 0;
	static unsigned int badPackets = 0;
	static unsigned int goodChecksums = 0;
	static unsigned int startsInsidePacket = 0;
	static unsigned int totalFalseStartLost = 0;
	static unsigned int doubleStartByteOccurances = 0;
	static unsigned int strayDataBytesOccurances = 0;
	static unsigned int escapeBytesFound = 0;
	static unsigned int escapedStopBytesFound = 0;
	static unsigned int escapedStartBytesFound = 0;
	static unsigned int escapedEscapeBytesFound = 0;
	static unsigned int escapePairMismatches = 0;
	static unsigned long sumOfGoodPacketLengths = 0;
	/* Loop and state variables */
	static gboolean insidePacket = FALSE;
	static gboolean unescapeNext = FALSE;
	static unsigned int processed = 0;
	static unsigned char checksum = 0;
	static unsigned char lastChar = 0;
	static unsigned int currentPacketLength = 0;

	guchar character;
	gint i = 0;
	FreeEMS_Packet *packet = NULL;
	if (!queue)
		queue = (GAsyncQueue *)DATA_GET(global_data,"packet_queue");
	log_inbound_data_f(buf,len);

	for (i=0;i<len;i++)
	{
		character = buf[i];
		if (character == START_BYTE)
		{
			if (insidePacket)
			{
				startsInsidePacket++;
				if (currentPacketLength == 0)
				{
					doubleStartByteOccurances++;
				}
				else    
				{       
					totalFalseStartLost += currentPacketLength;
					strayDataBytesOccurances++;
				}
			}
			insidePacket = TRUE;
			checksum = 0;
			currentPacketLength = 0;
		}
		else if (insidePacket)
		{
			if (unescapeNext)
			{	/* Clear escaped byte next flag */
				unescapeNext = FALSE;
				if (character == ESCAPED_ESCAPE_BYTE)
				{
					checksum += ESCAPE_BYTE;
					lastChar = ESCAPE_BYTE;
					escapedEscapeBytesFound++;
					packetBuffer[currentPacketLength] = ESCAPE_BYTE;
					currentPacketLength++;
				}
				else if (character == ESCAPED_START_BYTE)
				{
					/* Store and checksum start byte */
					checksum += START_BYTE;
					lastChar = START_BYTE;
					escapedStartBytesFound++;
					packetBuffer[currentPacketLength] = START_BYTE;
					currentPacketLength++;
				}
				else if(character == ESCAPED_STOP_BYTE)
				{
					/* Store and checksum stop byte */
					checksum += STOP_BYTE;
					lastChar = STOP_BYTE;
					escapedStopBytesFound++;
					packetBuffer[currentPacketLength] = STOP_BYTE;
					currentPacketLength++;
				}else
				{
					/* Otherwise reset and record as data is bad */
					insidePacket = FALSE;
					checksum = 0;
					currentPacketLength = 0;
					escapePairMismatches++;
				}
			}
			else if (character == ESCAPE_BYTE)
			{
				/* Set flag to indicate that the next byte should be un-escaped. */
				unescapeNext = TRUE;
				escapeBytesFound++;
			}
			else if (character == STOP_BYTE)
			{
				packets++;
				/* Bring the checksum back to where it should be */
				checksum -= lastChar;

				/* Check that the checksum matches */
				if(checksum != lastChar)
				{
					badChecksums++;
					printf("Packet number %u ending of length %u at char number %u failed checksum! Received %u Calculated %u\n", packets, currentPacketLength, processed, lastChar, checksum);
				}
				else
				{
					goodChecksums++;
					/* Add the length to the SUM */
					sumOfGoodPacketLengths += currentPacketLength;
					/* Clear the state */
					packet = g_new0(FreeEMS_Packet, 1);
					packet->data = (guchar *)g_memdup(packetBuffer,currentPacketLength);
					packet->raw_length = currentPacketLength;
					mtxlog_packet(packet->data,packet->raw_length,FALSE);
					if (!packet_decode(packet))
					{
						printf("Packet fields don't make sense!\n");
						freeems_packet_cleanup(packet);
						badPackets++;
					}
					else if (queue)
					{
						g_async_queue_ref(queue);
						g_async_queue_push(queue,(gpointer)packet);
						g_async_queue_unref(queue);
					}
					else
						printf("packet queue not found!?!!\n");
				}
				insidePacket = FALSE;
				currentPacketLength= 0;
				checksum = 0;
			}
			else
			{
				/* If it isn't special checksum it! */
				checksum += character;
				lastChar = character;
				packetBuffer[currentPacketLength] = character;
				currentPacketLength++;
			}
		}
		else
			charsDropped++;
	}
}