Beispiel #1
0
void speed_test_bps(struct etherate *eth)
{

    int16_t tx_ret = 0;
    int16_t rx_len = 0;

    // Get clock times for the speed limit restriction and starting time
    clock_gettime(CLOCK_MONOTONIC_RAW, &eth->params.elapsed_time);

    // Tx test loop
    while (*eth->speed_test.testBase <= *eth->speed_test.testMax)
    {

        clock_gettime(CLOCK_MONOTONIC_RAW, &eth->params.current_time);

        // One second has passed
        if ((eth->params.current_time.tv_sec - eth->params.elapsed_time.tv_sec) >= 1)
        {
            eth->params.s_elapsed += 1;
            eth->speed_test.b_speed   = (((double)eth->speed_test.b_tx-eth->speed_test.b_tx_prev) * 8) / 1000 / 1000;
            eth->speed_test.b_tx_prev = eth->speed_test.b_tx;
            eth->speed_test.f_speed   = (eth->params.f_tx_count - eth->params.f_tx_count_prev);
            eth->params.f_tx_count_prev = eth->params.f_tx_count;

            printf("%" PRIu64 "\t\t%.2f\t\t%" PRIu64 "\t\t%" PRIu64"\t\t%" PRIu64 "\n",
                   eth->params.s_elapsed,
                   eth->speed_test.b_speed,
                   (eth->speed_test.b_tx / 1024) / 1024,
                   (eth->speed_test.f_speed),
                   eth->params.f_tx_count);

            if (eth->speed_test.b_speed > eth->speed_test.b_speed_max)
                eth->speed_test.b_speed_max = eth->speed_test.b_speed;

            if (eth->speed_test.f_speed > eth->speed_test.f_speed_max)
                eth->speed_test.f_speed_max = eth->speed_test.f_speed;

            eth->speed_test.b_speed_avg += eth->speed_test.b_speed;
            eth->speed_test.f_speed_avg += eth->speed_test.f_speed;
            eth->params.elapsed_time.tv_sec  = eth->params.current_time.tv_sec;
            eth->params.elapsed_time.tv_nsec = eth->params.current_time.tv_nsec;

            eth->speed_test.b_tx_speed_prev = 0;

        } else {

            // Poll has been disabled in favour of a non-blocking recv (for now)
            rx_len = recv(eth->intf.sock_fd, eth->frm.rx_buffer,
                          eth->params.f_size_total, MSG_DONTWAIT);

            if (rx_len > 0) {

                // Running in ACK mode
                if (eth->params.f_ack)
                {

                    if (ntohl(*eth->frm.rx_tlv_value) == VALUE_TEST_SUB_TLV &&
                        ntohs(*eth->frm.rx_sub_tlv_type) == TYPE_ACKINDEX)
                    {

                        eth->params.f_rx_count    += 1;
                        eth->params.f_waiting_ack = false;

                        // Record if the frame is in-order, early or late
                        if (likely(ntohll(*eth->frm.rx_sub_tlv_value) == eth->params.f_rx_count)) {
                            eth->params.f_rx_ontime  += 1;
                        } else if (ntohll(*eth->frm.rx_sub_tlv_value) > eth->params.f_rx_count) {
                            eth->params.f_rx_early   += 1;
                        } else if (ntohll(*eth->frm.rx_sub_tlv_value) < eth->params.f_rx_count) {
                            eth->params.f_rx_late    += 1;
                        }

                    } else if (ntohs(*eth->frm.rx_tlv_type) == TYPE_APPLICATION &&
                               ntohl(*eth->frm.rx_tlv_value) == VALUE_DYINGGASP) {

                        printf("\nRx host has quit\n");
                        speed_test_results(eth);
                        return;

                    // Received a non-test frame
                    } else {
                        eth->params.f_rx_other += 1;
                    }

                // Not running in ACK mode
                } else if (ntohs(*eth->frm.rx_tlv_type) == TYPE_APPLICATION &&
                           ntohll(*eth->frm.rx_tlv_value) == VALUE_DYINGGASP) {

                    printf("\nRx host has quit\n");
                    speed_test_results(eth);
                    return;

                // Received a non-test frame
                } else {
                    eth->params.f_rx_other += 1;
                }

            } else { // rx_len <= 0
                if (errno != EAGAIN || errno != EWOULDBLOCK)
                    perror("Speed test Rx error ");
            }

            // If it hasn't been 1 second yet, send more test frames
            if (eth->params.f_waiting_ack == false)
            {

                // Check if sending another frame exceeds the max speed configured
                if ((eth->speed_test.b_tx_speed_prev + eth->params.f_size_total) <= eth->speed_test.b_tx_speed_max)
                {

                    build_sub_tlv(&eth->frm, htons(TYPE_FRAMEINDEX), 
                                  htonll(eth->params.f_tx_count+1));

                    tx_ret = send(eth->intf.sock_fd,
                                  eth->frm.tx_buffer,
                                  eth->params.f_size_total,
                                  MSG_DONTWAIT);

                    if (tx_ret > 0)
                    {
                        eth->params.f_tx_count += 1;
                        eth->speed_test.b_tx += eth->params.f_size_total;
                        eth->speed_test.b_tx_speed_prev += eth->params.f_size_total;
                        if (eth->params.f_ack) eth->params.f_waiting_ack = true;

                    } else {

                        if (errno != EAGAIN || errno != EWOULDBLOCK)
                        {
                            perror("Speed test Tx error ");
                            return;
                        }
                        
                    }

                }

            }


        } // End of current_time.tv_sec - ts_elapsed_TIME.tv_sec

    } // *testBase<=*testMax

}
Beispiel #2
0
static int ssa_db_tbl_load(char *dir_path, struct ssa_db *p_ssa_db,
			   uint64_t tbl_idx, enum ssa_db_helper_mode mode)
{
	FILE *fd;
	struct db_table_def table_def, field_table_def;
	struct db_dataset dataset, field_dataset;
	int var_size_recs = 0;
	char buffer[SSA_DB_HELPER_PATH_MAX] = {};

	/* table definition loading */
	sprintf(buffer, "%s/%s", dir_path, SSA_DB_HELPER_TABLE_DEF_NAME);
	fd = fopen(buffer, SSA_DB_HELPER_FILE_READ_MODE_TXT);
	if (!fd) {
		ssa_log_err(SSA_LOG_DEFAULT, "Failed opening %s file\n", buffer);
		return -1;
	}
	ssa_db_table_def_load(fd, &table_def);
	fclose(fd);

	ssa_db_table_def_insert(p_ssa_db->p_def_tbl,
				&p_ssa_db->db_table_def,
				table_def.version, table_def.size,
				table_def.type, table_def.access,
				table_def.id.db, table_def.id.table,
				table_def.id.field, table_def.name,
				ntohl(table_def.record_size),
				ntohl(table_def.ref_table_id));

	if (table_def.record_size == DB_VARIABLE_SIZE)
		var_size_recs = 1;

	/* data dataset loading */
	sprintf(buffer, "%s/%s", dir_path, SSA_DB_HELPER_DATASET_NAME);
	fd = fopen(buffer, SSA_DB_HELPER_FILE_READ_MODE_TXT);
	if (!fd) {
		ssa_log_err(SSA_LOG_DEFAULT, "Failed opening %s file\n", buffer);
		return -1;
	}
	ssa_db_dataset_load(fd, &dataset);
	fclose(fd);

	ssa_db_dataset_init(&p_ssa_db->p_db_tables[tbl_idx],
			    dataset.version, dataset.size,
			    dataset.access, dataset.id.db,
			    dataset.id.table, dataset.id.field,
			    ntohll(dataset.epoch), ntohll(dataset.set_size),
			    ntohll(dataset.set_offset),
			    ntohll(dataset.set_count));

	if (!var_size_recs) {
		/* field table definition loading */
		sprintf(buffer, "%s/%s", dir_path, SSA_DB_HELPER_FIELD_DEF_NAME);
		fd = fopen(buffer, SSA_DB_HELPER_FILE_READ_MODE_TXT);
		if (!fd) {
			ssa_log_err(SSA_LOG_DEFAULT, "Failed opening %s file\n", buffer);
			return -1;
		}
		ssa_db_table_def_load(fd, &field_table_def);
		fclose(fd);

		ssa_db_table_def_insert(p_ssa_db->p_def_tbl,
					&p_ssa_db->db_table_def,
					field_table_def.version,
					field_table_def.size,
					field_table_def.type,
					field_table_def.access,
					field_table_def.id.db,
					field_table_def.id.table,
					field_table_def.id.field,
					field_table_def.name,
					ntohl(field_table_def.record_size),
					ntohl(field_table_def.ref_table_id));

		/* field dataset loading */
		sprintf(buffer, "%s/%s", dir_path, SSA_DB_HELPER_FIELDS_DATASET_NAME);
		fd = fopen(buffer, SSA_DB_HELPER_FILE_READ_MODE_TXT);
		if (!fd) {
			ssa_log_err(SSA_LOG_DEFAULT, "Failed opening %s file\n", buffer);
			return -1;
		}
		ssa_db_dataset_load(fd, &field_dataset);
		fclose(fd);

		ssa_db_dataset_init(&p_ssa_db->p_db_field_tables[tbl_idx],
				    field_dataset.version, field_dataset.size,
				    field_dataset.access, field_dataset.id.db,
				    field_dataset.id.table, field_dataset.id.field,
				    ntohll(field_dataset.epoch),
				    ntohll(field_dataset.set_size),
				    ntohll(field_dataset.set_offset),
				    ntohll(field_dataset.set_count));

		sprintf(buffer, "%s/%s", dir_path, SSA_DB_HELPER_FIELDS_NAME);
		fd = fopen(buffer, SSA_DB_HELPER_FILE_READ_MODE_TXT);
		if (!fd) {
			ssa_log_err(SSA_LOG_DEFAULT, "Failed opening %s file\n", buffer);
			return -1;
		}
		ssa_db_field_tbl_load(fd, &field_dataset,
				      p_ssa_db->pp_field_tables[tbl_idx]);
		fclose(fd);
	}

	/* TODO (optional): add distinguish between added and removed records */
	sprintf(buffer, "%s/%s", dir_path, SSA_DB_HELPER_DATA_NAME);
	if (mode == SSA_DB_HELPER_STANDARD)
		fd = fopen(buffer, SSA_DB_HELPER_FILE_READ_MODE_BIN);
	else
		fd = fopen(buffer, SSA_DB_HELPER_FILE_READ_MODE_TXT);
	if (!fd) {
		ssa_log_err(SSA_LOG_DEFAULT, "Failed opening %s file\n", buffer);
		return -1;
	}
	if (var_size_recs)
		ssa_db_rec_tbl_load_var_size(fd, mode, &table_def,&dataset,
					     p_ssa_db->pp_tables[tbl_idx]);
	else
		ssa_db_rec_tbl_load(fd, mode, &table_def,
				    &dataset, p_ssa_db->pp_tables[tbl_idx],
				    &field_dataset,
				    (struct db_field_def *)p_ssa_db->pp_field_tables[tbl_idx]);

	fclose(fd);

	return 0;
}
Beispiel #3
0
/** Unmarshals the next content of an MBuffer into a OmlValue
 *
 * \param mbuf MBuffer to read from
 * \param value pointer to OmlValue to unmarshall the read data into
 * \return 1 if successful, 0 otherwise
 */
int
unmarshal_value(MBuffer *mbuf, OmlValue *value)
{
  if (mbuf_rd_remaining(mbuf) == 0) {
    logerror("Tried to unmarshal a value from the buffer, but didn't receive enough data to do that\n");
    return 0;
  }

  int type = mbuf_read_byte (mbuf);
  if (type == -1) return 0;

  switch (type) {
  case LONG_T: {
    uint8_t buf [LONG_T_SIZE];

    if (mbuf_read (mbuf, buf, LENGTH (buf)) == -1)
    {
      logerror("Failed to unmarshal OML_LONG_VALUE; not enough data?\n");
      return 0;
    }

    uint32_t hv = ntohl(*((uint32_t*)buf));
    int32_t v = (int32_t)(hv);

    /*
     * The server no longer needs to know about OML_LONG_VALUE, as the
     * marshalling process now maps OML_LONG_VALUE into OML_INT32_VALUE
     * (by truncating to [INT_MIN, INT_MAX].  Therefore, unmarshall a
     * LONG_T value into an OML_INT32_VALUE object.
     */
    oml_value_set_type(value, OML_INT32_VALUE);
    omlc_set_int32(*oml_value_get_value(value), v);
    break;
  }
  case INT32_T:
  case UINT32_T:
  case INT64_T:
  case UINT64_T: {
    uint8_t buf [UINT64_T_SIZE]; // Maximum integer size
    OmlValueT oml_type = protocol_type_map[type];
    if (mbuf_read (mbuf, buf, protocol_size_map[type]) == -1) {
      logerror("Failed to unmarshall %d value; not enough data?\n", type);
      return 0;
    }
    oml_value_set_type(value, oml_type);
    switch (type) {
    case INT32_T:
      omlc_set_int32(*oml_value_get_value(value), ntohl(*((int32_t*)buf)));
      logdebug3("Unmarshalled %s %" PRId32 "\n", oml_type_to_s(oml_type), omlc_get_int32(*oml_value_get_value(value)));
      break;

    case UINT32_T:
      omlc_set_uint32(*oml_value_get_value(value), ntohl(*((uint32_t*)buf)));
      logdebug3("Unmarshalled %s %" PRIu32 "\n", oml_type_to_s(oml_type), omlc_get_uint32(*oml_value_get_value(value)));
      break;

    case INT64_T:
      omlc_set_int64(*oml_value_get_value(value), ntohll(*((int64_t*)buf)));
      logdebug3("Unmarshalled %s %" PRId64 "\n", oml_type_to_s(oml_type), omlc_get_int64(*oml_value_get_value(value)));
      break;

    case UINT64_T:
      omlc_set_uint64(*oml_value_get_value(value), ntohll(*((uint64_t*)buf)));
      logdebug3("Unmarshalled %s %" PRIu64 "\n", oml_type_to_s(oml_type), omlc_get_uint64(*oml_value_get_value(value)));
      break;

    default:
      logerror("Integer morphed, something magic has just happened\n");
      return 0;
    }
    break;
  }
  case DOUBLE_T: {
    uint8_t buf [DOUBLE_T_SIZE];
    OmlValueT oml_type = protocol_type_map[type];
    if (mbuf_read (mbuf, buf, LENGTH (buf)) == -1)
    {
      logerror("Failed to unmarshal OML_DOUBLE_VALUE; not enough data?\n");
      return 0;
    }

    int hmant = (int)ntohl(*((uint32_t*)buf));
    double mant = hmant * 1.0 / (1 << BIG_L);
    int exp = (int8_t) buf[4];
    double v = ldexp(mant, exp);
    oml_value_set_type(value, oml_type);
    omlc_set_double(*oml_value_get_value(value), v);
    logdebug3("Unmarshalled double %f\n", omlc_get_double(*oml_value_get_value(value)));
    break;
  }
  case DOUBLE_NAN: {
    OmlValueT oml_type = protocol_type_map[type];
    mbuf_read_skip(mbuf, DOUBLE_T_SIZE); /* The data is irrelevant */
    oml_value_set_type(value, oml_type);
    omlc_set_double(*oml_value_get_value(value), NAN);
    logdebug("Received NaN\n");
    break;
  }
  case STRING_T: {
    int len = 0;
    uint8_t buf [STRING_T_MAX_SIZE];

    len = mbuf_read_byte (mbuf);

    if (len == -1 || mbuf_read (mbuf, buf, len) == -1)
    {
      logerror("Failed to unmarshal OML_STRING_VALUE; not enough data?\n");
      return 0;
    }

    oml_value_set_type(value, OML_STRING_VALUE);
    omlc_set_string_copy(*oml_value_get_value(value), buf, len);
    logdebug3("Unmarshalled string '%s' of length %d\n", omlc_get_string_ptr(*oml_value_get_value(value)), len);
    break;
  }
  case BLOB_T: {
    uint32_t n_len;

    if (mbuf_read (mbuf, (uint8_t*)&n_len, 4) == -1) {
      logerror ("Failed to unmarshal OML_BLOB_VALUE length field; not enough data?\n");
      return 0;
    }

    size_t len = ntohl (n_len);
    size_t remaining = mbuf_rd_remaining (mbuf);

    if (len > remaining) {
      logerror ("Failed to unmarshal OML_BLOB_VALUE data:  not enough data available "
                "(wanted %d, but only have %d bytes\n",
                len, remaining);
      return 0;
    }

    void *ptr = mbuf_rdptr (mbuf);
    oml_value_set_type(value, OML_BLOB_VALUE);
    omlc_set_blob (*oml_value_get_value(value), ptr, len); /*XXX*/
    logdebug3("Unmarshalled blob of size %d\n", len);
    mbuf_read_skip (mbuf, len);
    break;
  }

  case GUID_T: {
    uint64_t nv64;
    uint8_t buf[GUID_T_SIZE];
    if(mbuf_read(mbuf, buf, GUID_T_SIZE) == -1) {
      logerror("Failed to unmarshall OML_GUID_VALUE data; not enough data?\n");
      return 0;
    }
    memcpy(&nv64, buf, sizeof(nv64));
    oml_value_set_type(value, OML_GUID_VALUE);
    omlc_set_guid(*oml_value_get_value(value), ntohll(nv64));
    logdebug3("Unmarshalled GUID %" PRIu64 "\n", omlc_get_guid(*oml_value_get_value(value)));
    break;
  }

  case BOOL_FALSE_T:
  case BOOL_TRUE_T:
    oml_value_set_type(value, OML_BOOL_VALUE);
    omlc_set_bool(*oml_value_get_value(value),
                  (type == BOOL_TRUE_T)?OMLC_BOOL_TRUE:OMLC_BOOL_FALSE);
    logdebug3("Unmarshalled boolean %d\n", OMLC_BOOL_TRUE == omlc_get_bool(*oml_value_get_value(value)));
    break;

  case VECTOR_T: {
    uint16_t i, nof_elts;
    int type = mbuf_read_byte(mbuf);
    if(-1 == type) {
      logerror("%s(): failed to unmarshall VECTOR_T length\n", __func__);
      return 0;
    }
    if(mbuf_read(mbuf,(uint8_t*)(&nof_elts), sizeof(nof_elts)) == -1) {
      logerror("%s(): failed to unmarshall VECTOR_T length\n", __func__);
      return 0;
    }
    nof_elts = ntohs(nof_elts);

    OmlValueT oml_type = vector_type_map[type];
    OmlValueU *v = oml_value_get_value(value);
    switch(type) {
    case INT32_T:
    case UINT32_T: {
      size_t bytes = nof_elts * sizeof(uint32_t);
      uint32_t *elts = oml_calloc(nof_elts, sizeof(uint32_t));
      if(mbuf_read(mbuf, (uint8_t*)(elts), nof_elts * sizeof(uint32_t)) == -1) {
        logerror("%s(): failed to unmarshall OML_VECTOR_(U)INT32_VALUE\n", __func__);
        return 0;
      }
      for(i = 0; i < nof_elts; i++)
        elts[i] = ntohl(elts[i]);
      oml_value_set_type(value, oml_type);
      omlc_set_vector_ptr(*v, elts);
      omlc_set_vector_length(*v, bytes);
      omlc_set_vector_size(*v, bytes);
      omlc_set_vector_nof_elts(*v, nof_elts);
      omlc_set_vector_elt_size(*v, sizeof(uint32_t));
      break;
    }
    case INT64_T:
    case UINT64_T:
    case DOUBLE64_T: {
      size_t bytes = nof_elts * sizeof(uint64_t);
      uint64_t *elts = oml_calloc(nof_elts, sizeof(uint64_t));
      if(mbuf_read(mbuf, (uint8_t*)(elts), nof_elts * sizeof(uint64_t)) == -1) {
        logerror("%s(): failed to unmarshall OML_VECTOR_(U)INT64_VALUE\n", __func__);
        return 0;
      }
      for(i = 0; i < nof_elts; i++)
        elts[i] = ntohll(elts[i]);
      oml_value_set_type(value, oml_type);
      omlc_set_vector_ptr(*v, elts);
      omlc_set_vector_length(*v, bytes);
      omlc_set_vector_size(*v, bytes);
      omlc_set_vector_nof_elts(*v, nof_elts);
      omlc_set_vector_elt_size(*v, sizeof(uint64_t));
      break;
    }
    case BOOL_T: {
      uint8_t y[nof_elts];
      size_t bytes = nof_elts * sizeof(bool);
      bool *elts = oml_calloc(nof_elts, sizeof(bool));
      if(mbuf_read(mbuf, y, nof_elts) == -1) {
        logerror("%s(): failed to unmarshall OML_VECTOR_BOOL_VALUE\n", __func__);
        return 0;
      }
      for(i = 0; i < nof_elts; i++)
        elts[i] = ((BOOL_TRUE_T == y[i]) ? true : false);
      oml_value_set_type(value, oml_type);
      omlc_set_vector_ptr(*v, elts);
      omlc_set_vector_length(*v, bytes);
      omlc_set_vector_size(*v, bytes);
      omlc_set_vector_nof_elts(*v, nof_elts);
      omlc_set_vector_elt_size(*v, sizeof(bool));
      break;
    }
    default:
      logerror("%s(): bad type for array (t=%d)\n", __func__, type);
      break;
    }
    break;
  }

  default:
    logerror("%s: Unsupported value type '%d'\n", __FUNCTION__, type);
    return 0;
  }

  return 1;
}
Beispiel #4
0
static nl_catd
loadCat(__const char *catpath)
{
	MCHeaderT       header;
	MCCatT          *cat;
	MCSetT          *set;
	int32_t         i;
	off_t           nextSet;
	int             saverr;
	int		fd;

	if ((cat = (MCCatT *)malloc(sizeof(MCCatT))) == NULL)
		return (NLERR);

	if ((fd = open(catpath, O_RDONLY | O_CLOEXEC)) == -1) {
		saverr = errno;
		free(cat);
		errno = saverr;
		return (NLERR);
	}

	if ((cat->fp = fdopen(fd, "r")) == NULL) {
		saverr = errno;
		close(fd);
		free(cat);
		errno = saverr;
		return (NLERR);
	}

	if (fread(&header, sizeof(header), 1, cat->fp) != 1 ||
	    strncmp(header.magic, MCMagic, MCMagicLen) != 0)
		CORRUPT();

	if (ntohl(header.majorVer) != MCMajorVer) {
		(void)fclose(cat->fp);
		free(cat);
		if (OSSwapInt32(ntohl(header.majorVer)) == MCMajorVer) {
		    (void)fprintf(stderr, "%s: %s is the wrong byte ordering.\n", _errowner, catpath);
		} else {
		    (void)fprintf(stderr, "%s: %s is version %d, we need %d.\n", _errowner, catpath, (int)ntohl(header.majorVer), MCMajorVer);
		}
		NLRETERR(EFTYPE);
	}
	if (ntohl(header.numSets) <= 0) {
		(void)fclose(cat->fp);
		free(cat);
		(void)fprintf(stderr, "%s: %s has %d sets!\n",
		    _errowner, catpath, (int)ntohl(header.numSets));
		NLRETERR(EFTYPE);
	}

	cat->numSets = ntohl(header.numSets);
	if ((cat->sets = (MCSetT *)malloc(sizeof(MCSetT) * cat->numSets)) ==
	    NULL)
		NOSPACE();

	nextSet = ntohll(header.firstSet);
	for (i = 0; i < cat->numSets; ++i) {
		if (fseeko(cat->fp, nextSet, SEEK_SET) == -1) {
			__nls_free_resources(cat, i);
			CORRUPT();
		}

		/* read in the set header */
		set = cat->sets + i;
		if (fread(set, sizeof(*set), 1, cat->fp) != 1) {
			__nls_free_resources(cat, i);
			CORRUPT();
		}

		/* if it's invalid, skip over it (and backup 'i') */
		if (set->invalid) {
			--i;
			nextSet = ntohll(set->nextSet);
			continue;
		}
		set->invalid = TRUE;
		nextSet = ntohll(set->nextSet);
	}

	return ((nl_catd) cat);
}
Beispiel #5
0
static void ssa_db_rec_tbl_dump(FILE *fd, enum ssa_db_helper_mode mode,
				struct db_table_def *p_data_tbl_def,
				struct db_dataset *p_dataset, void *p_data_tbl,
				struct db_dataset *p_dataset_field,
				struct db_field_def *p_field_tbl)
{
	struct db_field_def *p_field_rec;
	uint8_t *p_data_rec, *p_data_field;
	uint64_t i, k, j;

	for (i = 0; i < ntohll(p_dataset->set_count); i++) {
		p_data_rec = (uint8_t *)((uint8_t *)p_data_tbl + i * ntohl(p_data_tbl_def->record_size));
		if (mode == SSA_DB_HELPER_STANDARD) {
			for (k = 0; k < ntohl(p_data_tbl_def->record_size); k++)
				fprintf(fd, "%c", *(char *)((char *)p_data_rec + k));
		} else {
			for (k = 0; k < ntohll(p_dataset_field->set_count); k++) {
				p_field_rec = &p_field_tbl[k];
				p_data_field = p_data_rec + ntohl(p_field_rec->field_offset) / 8;

				if (mode == SSA_DB_HELPER_HUMAN)
					fprintf(fd, "%s ", p_field_rec->name);

				switch (p_field_rec->type) {
				case DBF_TYPE_U8:
					for (j = 0; j < ntohl(p_field_rec->field_size) / 8; j++) {
						if (j > 0)
							fprintf(fd, SSA_DB_HELPER_ARRAY_DELIMITER);
						fprintf(fd, "%" SCNu8 "",
							*((uint8_t *)(p_data_field + j)));
					}
					break;
				case DBF_TYPE_U16:
					for (j = 0; j < ntohl(p_field_rec->field_size) / 16; j++) {
						if (j > 0)
							fprintf(fd, SSA_DB_HELPER_ARRAY_DELIMITER);
						fprintf(fd, "%" SCNu16 "",
							*((uint16_t *)(p_data_field + (j * 2))));
					}
					break;
				case DBF_TYPE_U32:
					for (j = 0; j < ntohl(p_field_rec->field_size) / 32; j++) {
						if (j > 0)
							fprintf(fd, SSA_DB_HELPER_ARRAY_DELIMITER);
						fprintf(fd, "%" PRIx32 "",
							*((uint32_t *)(p_data_field + (j * 4))));
					}
					break;
				case DBF_TYPE_U64:
					for (j = 0; j < ntohl(p_field_rec->field_size) / 64; j++) {
						if (j > 0)
							fprintf(fd, SSA_DB_HELPER_ARRAY_DELIMITER);
						fprintf(fd, "0x%" PRIx64 "",
							*((uint64_t *)(p_data_field + (j * 8))));
					}
					break;
				case DBF_TYPE_NET16:
					for (j = 0; j < ntohl(p_field_rec->field_size) / 16; j++) {
						if (j > 0)
							fprintf(fd, SSA_DB_HELPER_ARRAY_DELIMITER);
						fprintf(fd, "%" SCNu16 "",
							ntohs(*((uint16_t *)(p_data_field + (j * 2)))));
					}
					break;
				case DBF_TYPE_NET32:
					for (j = 0; j < ntohl(p_field_rec->field_size) / 32; j++) {
						if (j > 0)
							fprintf(fd, SSA_DB_HELPER_ARRAY_DELIMITER);
						fprintf(fd, "%" PRIx32 "",
							ntohl(*((uint32_t *)(p_data_field + (j * 4)))));
					}
					break;
				case DBF_TYPE_NET64:
					for (j = 0; j < ntohl(p_field_rec->field_size) / 64; j++) {
						if (j > 0)
							fprintf(fd, SSA_DB_HELPER_ARRAY_DELIMITER);
						fprintf(fd, "0x%" PRIx64 "",
							ntohll(*((uint64_t *)(p_data_field + (j * 8)))));
					}
					break;
				case DBF_TYPE_NET128:
					/* TODO: add 128 bit handling */
					break;
				case DBF_TYPE_STRING:
					fprintf(fd, "%s",
						((char *)(p_data_field)));
					break;
				default:
					ssa_log_err(SSA_LOG_DEFAULT, "Unknown field type\n");
					break;
				}

				if (k < ntohll(p_dataset_field->set_count) &&
				    mode == SSA_DB_HELPER_DEBUG)
					fprintf(fd, SSA_DB_HELPER_DELIMITER);

				if (k < ntohll(p_dataset_field->set_count) - 1 &&
				    mode == SSA_DB_HELPER_HUMAN)
					fprintf(fd, " ");
			}
		}
		fprintf(fd, "\n");
	}
}
Beispiel #6
0
static void
dispatch_socket_msg(struct otu *u, const struct skynet_socket_message * message, int sz) {
	struct skynet_context * ctx = u->ctx;

	switch(message->type) {

	case SKYNET_SOCKET_TYPE_CONNECT: {
		assert (message->id == u->service_id);
		break;
		}

	case SKYNET_SOCKET_TYPE_UDP: {
		char* pkt = message->buffer;
		int pkt_sz = message->ud;
		int addr_sz = 0;
		const char * addr = skynet_socket_udp_address(message, &addr_sz);
		char* last_err = NULL;

		//Ver len check
		if(pkt_sz < sizeof(ot_pkt_hdr_t)){
			last_err = "1.ShortHdr.";
			goto exit_drop;
		}

		ot_pkt_hdr_t *hdr = (ot_pkt_hdr_t *)pkt;
		u16_t hdr_len = ntohs(hdr->len);

		if(hdr_len > pkt_sz || hdr_len < sizeof(ot_pkt_hdr_t) || hdr_len > OT_PACKET_SIZE_MAX){		//len check
			last_err = "2.HdrLenErr.";
			goto exit_drop;
		}

		if(hdr->proto_ver != OT_PROTO_VER_V3A){
			last_err = "3.HdrVerErr.";
			goto exit_drop;
		}

#define HDR_ONLY (hdr_len == sizeof(ot_pkt_hdr_t))
#define DID_IS_BROADCAST (IS_ALL_FF(hdr->did.byte, sizeof(hdr->did.byte)))

		if(HDR_ONLY){

			//时间戳请求处理
			if(DID_IS_BROADCAST){	

				hdr->ts = htonl(skynet_now()/100 + skynet_starttime());

				//int err = 
				skynet_socket_udp_send(ctx, message->id, addr, pkt, pkt_sz);

			}

			//保活
			else {

 				uint64_t did64 = ntohll(hdr->did.u64);
				int idx = hashid64_lookup(&u->hash, did64);
				if (idx >= 0) {
					struct udp_peer *p = &u->peer[idx];
					(void)p;
					//dispatch_msg(u, p, message->id, message->buffer, message->ud);
					goto exit_drop;

				} else {

					//todo 提交DID未知请求
					goto exit_drop;
				}


			}


		}


		break;


		//get key, decrypt packet.

		//dispatch_msg


exit_drop:
		skynet_free(message->buffer);

		break;
	}


	default:
		skynet_error(ctx, "OTU: unknown type(%d)", message->type);
		break;
	}
}
Beispiel #7
0
int cli_parse_show_stats(int argc, char **argv)
{
    int ret = 0;
    int msgs = 0;
    int opt;
    int opt_idx = 0;
    char lip_addr[16], rip_addr[16];
    uint32_t i = 0;
    uint32_t request_length, reply_length;
    cmdif_request_show_stats request;
    cmdif_reply_show_stats reply;

    memset(&request, 0, sizeof(request));
    request.hdr.xid = htonl(UINT32_MAX * rand());
    request.hdr.cmd = CMDIF_CMD_SHOW_STATS;
    request.hdr.length = htons(sizeof(request));
    memset(&reply, 0, sizeof(reply));
    memset(lip_addr, '\0', sizeof(lip_addr));
    memset(rip_addr, '\0', sizeof(rip_addr));

    while(1){
        opt = getopt_long(argc, argv, "hv", cli_cmd_ss_options, &opt_idx);
        if(opt == -1){
            break;
        }

        switch(opt){
        case CLI_CMD_RS_TX:
            request.cmd_options = CMDIF_CMD_STATS_OPTS_TX;
            break;
        case CLI_CMD_RS_RX:
            request.cmd_options = CMDIF_CMD_STATS_OPTS_RX;
            break;
        case 'v':
            log_set_level(LOG_DEBUG);
            break;
        case '?':
        default:
            ret = -1;
            break;
        }
    }

    if(ret < 0){
        return -1;
    }

    log_debug("request: xid = %u", ntohl(request.hdr.xid));

    request.cmd_options = htons(request.cmd_options);

    request_length = sizeof(request);
    reply_length = sizeof(reply);
    ret = cli_exec_cmd(&request, &request_length,
                       &reply, &reply_length);
    if(ret < 0){
        log_err("cannot execute a command.");
        return -1;
    }
    msgs++;

    log_debug("reply: xid = %u, status = %u, options = 0x%04x, n_stats = %u",
              ntohl(reply.hdr.xid), reply.hdr.status, ntohs(reply.cmd_options),
              ntohl(reply.n_stats));

    if(ntohl(reply.n_stats) == 0){
        return 0;
    }

    printf("ip_dst,tp_dst,ip_src,tp_src,n_pkts,n_octets\n");

    while(reply.hdr.status == CMDIF_STATUS_OK){
        for(i=0; i<ntohl(reply.n_stats); i++){
/*
            printf("%08x,%u,%08x,%u,%u,%llu\n",
                   ntohl(reply.st[i].lip), ntohs(reply.st[i].lport),
                   ntohl(reply.st[i].rip), ntohs(reply.st[i].rport),
                   ntohl(reply.st[i].n_pkts), ntohll(reply.st[i].n_octets));
*/
            printf("%s,%u,%s,%u,%u,%llu\n",
                   ultoipaddr(ntohl(reply.st[i].lip), lip_addr),
                   ntohs(reply.st[i].lport),
                   ultoipaddr(ntohl(reply.st[i].rip), rip_addr),
                   ntohs(reply.st[i].rport),
                   ntohl(reply.st[i].n_pkts), ntohll(reply.st[i].n_octets));
        }

        log_debug("cmd_options = %x", ntohs(reply.cmd_options));
        if((ntohs(reply.cmd_options) & CMDIF_CMD_STATS_CONTINUE) == 0){
            break;
        }

        memset(&reply, 0, sizeof(reply));
        ret = cli_exec_cmd_more_reply(&request, &request_length,
                                      &reply, &reply_length);
        if(ret < 0){
            log_err("cannot execute a command.");
            log_err("%u messages received.", msgs);
            return -1;
        }
        
        msgs++;

        log_debug("reply: xid = %u, status = %u, options = 0x%04x, n_stats = %u",
                  ntohl(reply.hdr.xid), reply.hdr.status, ntohs(reply.cmd_options),
                  ntohl(reply.n_stats));
    }

    log_debug("%u messages received.", msgs);

    return 0;
}
Beispiel #8
0
struct ssa_db *ssa_db_copy(struct ssa_db const * const ssa_db)
{
	uint64_t *field_cnt = NULL, *rec_cnt = NULL;
	struct ssa_db *ssa_db_copy = NULL;
	size_t *rec_size = NULL;
	uint64_t tbl_cnt, i, j;

	if (!ssa_db || !ssa_db->p_def_tbl ||
	    !ssa_db->p_db_field_tables || !ssa_db->pp_field_tables ||
	    !ssa_db->p_db_tables || !ssa_db->pp_tables)
		goto out;

	tbl_cnt = ssa_db->data_tbl_cnt;

	field_cnt = (uint64_t *) malloc(tbl_cnt * sizeof(*field_cnt));
	if (!field_cnt)
		goto out;

	rec_cnt = (uint64_t *) malloc(tbl_cnt * sizeof(*rec_cnt));
	if (!rec_cnt)
		goto err1;

	rec_size = (size_t *) malloc(tbl_cnt * sizeof(*rec_size));
	if (!rec_size)
		goto err2;

	for (i = 0; i < tbl_cnt; i++) {
		field_cnt[i] = ntohll(ssa_db->p_db_field_tables[i].set_count);
		rec_cnt[i] = ntohll(ssa_db->p_db_tables[i].set_count);

		for (j = 0; j < ntohll(ssa_db->db_table_def.set_count); j++) {
			if (ssa_db->p_def_tbl[j].id.table ==
			    ssa_db->p_db_tables[i].id.table) {
				rec_size[i] = ntohl(ssa_db->p_def_tbl[j].record_size);
				break;
			}
		}
	}

	ssa_db_copy = ssa_db_alloc(rec_cnt, rec_size, field_cnt, tbl_cnt);
	if (!ssa_db_copy)
		goto err3;

	ssa_db_copy->db_def = ssa_db->db_def;

	ssa_db_copy->db_table_def = ssa_db->db_table_def;
	memcpy(ssa_db_copy->p_def_tbl, ssa_db->p_def_tbl,
	       ntohll(ssa_db->db_table_def.set_size));

	ssa_db_copy->data_tbl_cnt = tbl_cnt;

	memcpy(ssa_db_copy->p_db_field_tables, ssa_db->p_db_field_tables,
	       tbl_cnt * sizeof(*ssa_db_copy->p_db_field_tables));

	memcpy(ssa_db_copy->p_db_tables, ssa_db->p_db_tables,
	       tbl_cnt * sizeof(*ssa_db_copy->p_db_tables));

	for (i = 0; i < tbl_cnt; i++) {
		if (ssa_db->pp_field_tables[i])
			memcpy(ssa_db_copy->pp_field_tables[i], ssa_db->pp_field_tables[i],
			       ntohll(ssa_db->p_db_field_tables[i].set_size));
		memcpy(ssa_db_copy->pp_tables[i], ssa_db->pp_tables[i],
		       ntohll(ssa_db->p_db_tables[i].set_size));
	}

err3:
	free(rec_size);
err2:
	free(rec_cnt);
err1:
	free(field_cnt);
out:
	return ssa_db_copy;
}
Beispiel #9
0
/*
 * Connection established.
 * We get here for both outgoing and incoming connection.
 */
void
rdsv3_ib_cm_connect_complete(struct rdsv3_connection *conn,
    struct rdma_cm_event *event)
{
	const struct rdsv3_ib_connect_private *dp = NULL;
	struct rdsv3_ib_connection *ic = conn->c_transport_data;
	struct rdsv3_ib_device *rds_ibdev =
	    ib_get_client_data(ic->i_cm_id->device, &rdsv3_ib_client);
	struct ib_qp_attr qp_attr;
	int err;

	RDSV3_DPRINTF2("rdsv3_ib_cm_connect_complete",
	    "Enter conn: %p event: %p", conn, event);

	if (event->param.conn.private_data_len >= sizeof (*dp)) {
		dp = event->param.conn.private_data;

		/* make sure it isn't empty data */
		if (dp->dp_protocol_major) {
			rdsv3_ib_set_protocol(conn,
			    RDS_PROTOCOL(dp->dp_protocol_major,
			    dp->dp_protocol_minor));
			rdsv3_ib_set_flow_control(conn,
			    ntohl(dp->dp_credit));
		}
	}

	if (conn->c_version < RDS_PROTOCOL(3, 1)) {
		RDSV3_DPRINTF2("rdsv3_ib_cm_connect_complete",
		    "RDS/IB: Connection to %u.%u.%u.%u version %u.%u failed",
		    NIPQUAD(conn->c_faddr),
		    RDS_PROTOCOL_MAJOR(conn->c_version),
		    RDS_PROTOCOL_MINOR(conn->c_version));
		rdsv3_conn_destroy(conn);
		return;
	} else {
		RDSV3_DPRINTF2("rdsv3_ib_cm_connect_complete",
		    "RDS/IB: connected to %u.%u.%u.%u version %u.%u%s",
		    NIPQUAD(conn->c_faddr),
		    RDS_PROTOCOL_MAJOR(conn->c_version),
		    RDS_PROTOCOL_MINOR(conn->c_version),
		    ic->i_flowctl ? ", flow control" : "");
	}

	ASSERT(ic->i_soft_cq == NULL);
	ic->i_soft_cq = rdsv3_af_intr_thr_create(rdsv3_ib_tasklet_fn,
	    (void *)ic, SCQ_INTR_BIND_CPU, rds_ibdev->aft_hcagp,
	    ic->i_cq->ibt_cq);
	if (rdsv3_enable_snd_cq) {
		ic->i_snd_soft_cq = rdsv3_af_intr_thr_create(
		    rdsv3_ib_snd_tasklet_fn,
		    (void *)ic, SCQ_INTR_BIND_CPU, rds_ibdev->aft_hcagp,
		    ic->i_snd_cq->ibt_cq);
	}
	/* rdsv3_ib_refill_fn is expecting i_max_recv_alloc set */
	ic->i_max_recv_alloc = rdsv3_ib_sysctl_max_recv_allocation;
	ic->i_refill_rq = rdsv3_af_thr_create(rdsv3_ib_refill_fn, (void *)conn,
	    SCQ_WRK_BIND_CPU, rds_ibdev->aft_hcagp);
	rdsv3_af_grp_draw(rds_ibdev->aft_hcagp);

	(void) ib_req_notify_cq(ic->i_cq, IB_CQ_SOLICITED);
	if (rdsv3_enable_snd_cq) {
		(void) ib_req_notify_cq(ic->i_snd_cq, IB_CQ_NEXT_COMP);
	}

	/*
	 * Init rings and fill recv. this needs to wait until protocol
	 * negotiation
	 * is complete, since ring layout is different from 3.0 to 3.1.
	 */
	rdsv3_ib_send_init_ring(ic);
	rdsv3_ib_recv_init_ring(ic);
	/*
	 * Post receive buffers - as a side effect, this will update
	 * the posted credit count.
	 */
	(void) rdsv3_ib_recv_refill(conn, 1);

	/* Tune RNR behavior */
	rdsv3_ib_tune_rnr(ic, &qp_attr);

	qp_attr.qp_state = IB_QPS_RTS;
	err = ib_modify_qp(ic->i_cm_id->qp, &qp_attr, IB_QP_STATE);
	if (err)
		RDSV3_DPRINTF2("rdsv3_ib_cm_connect_complete",
		    "ib_modify_qp(IB_QP_STATE, RTS): err=%d", err);

	/* update ib_device with this local ipaddr & conn */
	err = rdsv3_ib_update_ipaddr(rds_ibdev, conn->c_laddr);
	if (err)
		RDSV3_DPRINTF2("rdsv3_ib_cm_connect_complete",
		    "rdsv3_ib_update_ipaddr failed (%d)", err);
	rdsv3_ib_add_conn(rds_ibdev, conn);

	/*
	 * If the peer gave us the last packet it saw, process this as if
	 * we had received a regular ACK.
	 */
	if (dp && dp->dp_ack_seq)
		rdsv3_send_drop_acked(conn, ntohll(dp->dp_ack_seq), NULL);

	rdsv3_connect_complete(conn);

	RDSV3_DPRINTF2("rdsv3_ib_cm_connect_complete",
	    "Return conn: %p event: %p",
	    conn, event);
}
Beispiel #10
0
/* Composes 'fm' so that executing it will implement 'learn' given that the
 * packet being processed has 'flow' as its flow.
 *
 * Uses 'ofpacts' to store the flow mod's actions.  The caller must initialize
 * 'ofpacts' and retains ownership of it.  'fm->ofpacts' will point into the
 * 'ofpacts' buffer.
 *
 * The caller has to actually execute 'fm'. */
void
learn_execute(const struct ofpact_learn *learn, const struct flow *flow,
              struct ofputil_flow_mod *fm, struct ofpbuf *ofpacts)
{
    const struct ofpact_learn_spec *spec;

    match_init_catchall(&fm->match);
    fm->priority = learn->priority;
    fm->cookie = htonll(0);
    fm->cookie_mask = htonll(0);
    fm->new_cookie = learn->cookie;
    fm->modify_cookie = fm->new_cookie != OVS_BE64_MAX;
    fm->table_id = learn->table_id;
    fm->command = OFPFC_MODIFY_STRICT;
    fm->idle_timeout = learn->idle_timeout;
    fm->hard_timeout = learn->hard_timeout;
    fm->importance = 0;
    fm->buffer_id = UINT32_MAX;
    fm->out_port = OFPP_NONE;
    fm->flags = 0;
    if (learn->flags & NX_LEARN_F_SEND_FLOW_REM) {
        fm->flags |= OFPUTIL_FF_SEND_FLOW_REM;
    }
    fm->ofpacts = NULL;
    fm->ofpacts_len = 0;

    if (learn->fin_idle_timeout || learn->fin_hard_timeout) {
        struct ofpact_fin_timeout *oft;

        oft = ofpact_put_FIN_TIMEOUT(ofpacts);
        oft->fin_idle_timeout = learn->fin_idle_timeout;
        oft->fin_hard_timeout = learn->fin_hard_timeout;
    }

    OFPACT_LEARN_SPEC_FOR_EACH (spec, learn) {
        struct ofpact_set_field *sf;
        union mf_subvalue value;

        if (spec->src_type == NX_LEARN_SRC_FIELD) {
            mf_read_subfield(&spec->src, flow, &value);
        } else {
            mf_subvalue_from_value(&spec->dst, &value,
                                   ofpact_learn_spec_imm(spec));
        }

        switch (spec->dst_type) {
        case NX_LEARN_DST_MATCH:
            mf_write_subfield(&spec->dst, &value, &fm->match);
            break;

        case NX_LEARN_DST_LOAD:
            sf = ofpact_put_reg_load(ofpacts, spec->dst.field, NULL, NULL);
            bitwise_copy(&value, sizeof value, 0,
                         sf->value, spec->dst.field->n_bytes, spec->dst.ofs,
                         spec->n_bits);
            bitwise_one(ofpact_set_field_mask(sf), spec->dst.field->n_bytes,
                        spec->dst.ofs, spec->n_bits);
            break;

        case NX_LEARN_DST_OUTPUT:
            if (spec->n_bits <= 16
                || is_all_zeros(value.u8, sizeof value - 2)) {
                ofp_port_t port = u16_to_ofp(ntohll(value.integer));

                if (ofp_to_u16(port) < ofp_to_u16(OFPP_MAX)
                    || port == OFPP_IN_PORT
                    || port == OFPP_FLOOD
                    || port == OFPP_LOCAL
                    || port == OFPP_ALL) {
                    ofpact_put_OUTPUT(ofpacts)->port = port;
                }
            }
            break;
        }
    }

    fm->ofpacts = ofpacts->data;
    fm->ofpacts_len = ofpacts->size;
}
Beispiel #11
0
/*
 *	Return values:
 *	 0 - equal ssa_db structures
 *	 1 - different ssa_db structures
 *	-1 - invalid ssa_db structures
 */
int ssa_db_cmp(struct ssa_db const * const ssa_db1, struct ssa_db const * const ssa_db2)
{
	uint64_t i, j;
	int ret = 0;

	if (!ssa_db1 ||				!ssa_db2 ||
	    !ssa_db1->p_def_tbl ||		!ssa_db2->p_def_tbl ||
	    !ssa_db1->p_db_field_tables ||	!ssa_db2->p_db_field_tables ||
	    !ssa_db1->pp_field_tables ||	!ssa_db2->pp_field_tables ||
	    !ssa_db1->p_db_tables ||		!ssa_db2->p_db_tables ||
	    !ssa_db1->pp_tables ||		!ssa_db2->pp_tables) {
		ret = -1;
		goto out;
	}

	if (ssa_db_def_cmp(&ssa_db1->db_def, &ssa_db2->db_def) ||
	    ssa_db_dataset_cmp(&ssa_db1->db_table_def, &ssa_db2->db_table_def)) {
		ret = 1;
		goto out;
	}

	for (i = 0; i < ntohll(ssa_db1->db_table_def.set_count); i++) {
		if (ssa_db_tbl_def_cmp(&ssa_db1->p_def_tbl[i],
				       &ssa_db2->p_def_tbl[i])) {
			ret = 1;
			goto out;
		}
	}

	if (ssa_db1->data_tbl_cnt != ssa_db2->data_tbl_cnt) {
		ret = 1;
		goto out;
	}

	for (i = 0; i < ssa_db1->data_tbl_cnt; i++) {
		struct db_dataset *dataset1 = &ssa_db1->p_db_field_tables[i];
		struct db_dataset *dataset2 = &ssa_db2->p_db_field_tables[i];

		if (ssa_db_dataset_cmp(dataset1, dataset2)) {
			ret = 1;
			goto out;
		}

		for (j = 0; j < ntohll(dataset1->set_count); j++) {
			if (ssa_db_field_def_cmp(&ssa_db1->pp_field_tables[i][j],
						 &ssa_db2->pp_field_tables[i][j])) {
				ret = 1;
				goto out;
			}
		}
	}

	for (i = 0; i < ssa_db1->data_tbl_cnt; i ++) {
		struct db_dataset *dataset1 = &ssa_db1->p_db_tables[i];
		struct db_dataset *dataset2 = &ssa_db2->p_db_tables[i];

		if (ssa_db_dataset_cmp(dataset1, dataset2)) {
			ret = 1;
			goto out;
		}

		if (memcmp(ssa_db1->pp_tables[i], ssa_db2->pp_tables[i],
			   ntohll(dataset1->set_size))) {
			ret = 1;
			goto out;
		}
	}

out:
	return ret;
}
Beispiel #12
0
/* Appends a description of 'learn' to 's', in the format that ovs-ofctl(8)
 * describes. */
void
learn_format(const struct ofpact_learn *learn, struct ds *s)
{
    const struct ofpact_learn_spec *spec;
    struct match match;

    match_init_catchall(&match);

    ds_put_format(s, "%slearn(%s%stable=%s%"PRIu8,
                  colors.learn, colors.end, colors.special, colors.end,
                  learn->table_id);
    if (learn->idle_timeout != OFP_FLOW_PERMANENT) {
        ds_put_format(s, ",%sidle_timeout=%s%"PRIu16,
                      colors.param, colors.end, learn->idle_timeout);
    }
    if (learn->hard_timeout != OFP_FLOW_PERMANENT) {
        ds_put_format(s, ",%shard_timeout=%s%"PRIu16,
                      colors.param, colors.end, learn->hard_timeout);
    }
    if (learn->fin_idle_timeout) {
        ds_put_format(s, ",%sfin_idle_timeout=%s%"PRIu16,
                      colors.param, colors.end, learn->fin_idle_timeout);
    }
    if (learn->fin_hard_timeout) {
        ds_put_format(s, "%s,fin_hard_timeout=%s%"PRIu16,
                      colors.param, colors.end, learn->fin_hard_timeout);
    }
    if (learn->priority != OFP_DEFAULT_PRIORITY) {
        ds_put_format(s, "%s,priority=%s%"PRIu16,
                      colors.special, colors.end, learn->priority);
    }
    if (learn->flags & NX_LEARN_F_SEND_FLOW_REM) {
        ds_put_format(s, ",%ssend_flow_rem%s", colors.value, colors.end);
    }
    if (learn->flags & NX_LEARN_F_DELETE_LEARNED) {
        ds_put_format(s, ",%sdelete_learned%s", colors.value, colors.end);
    }
    if (learn->cookie != 0) {
        ds_put_format(s, ",%scookie=%s%#"PRIx64,
                      colors.param, colors.end, ntohll(learn->cookie));
    }

    OFPACT_LEARN_SPEC_FOR_EACH (spec, learn) {
        unsigned int n_bytes = DIV_ROUND_UP(spec->n_bits, 8);
        ds_put_char(s, ',');

        switch (spec->src_type | spec->dst_type) {
        case NX_LEARN_SRC_IMMEDIATE | NX_LEARN_DST_MATCH: {
            if (spec->dst.ofs == 0
                && spec->dst.n_bits == spec->dst.field->n_bits) {
                union mf_value value;

                memset(&value, 0, sizeof value);
                memcpy(&value.b[spec->dst.field->n_bytes - n_bytes],
                       ofpact_learn_spec_imm(spec), n_bytes);
                ds_put_format(s, "%s%s=%s", colors.param,
                              spec->dst.field->name, colors.end);
                mf_format(spec->dst.field, &value, NULL, s);
            } else {
                ds_put_format(s, "%s", colors.param);
                mf_format_subfield(&spec->dst, s);
                ds_put_format(s, "=%s", colors.end);
                ds_put_hex(s, ofpact_learn_spec_imm(spec), n_bytes);
            }
            break;
        }
        case NX_LEARN_SRC_FIELD | NX_LEARN_DST_MATCH:
            ds_put_format(s, "%s", colors.param);
            mf_format_subfield(&spec->dst, s);
            ds_put_format(s, "%s", colors.end);
            if (spec->src.field != spec->dst.field ||
                spec->src.ofs != spec->dst.ofs) {
                ds_put_format(s, "%s=%s", colors.param, colors.end);
                mf_format_subfield(&spec->src, s);
            }
            break;

        case NX_LEARN_SRC_IMMEDIATE | NX_LEARN_DST_LOAD:
            ds_put_format(s, "%sload:%s", colors.special, colors.end);
            ds_put_hex(s, ofpact_learn_spec_imm(spec), n_bytes);
            ds_put_format(s, "%s->%s", colors.special, colors.end);
            mf_format_subfield(&spec->dst, s);
            break;

        case NX_LEARN_SRC_FIELD | NX_LEARN_DST_LOAD:
            ds_put_format(s, "%sload:%s", colors.special, colors.end);
            mf_format_subfield(&spec->src, s);
            ds_put_format(s, "%s->%s", colors.special, colors.end);
            mf_format_subfield(&spec->dst, s);
            break;

        case NX_LEARN_SRC_FIELD | NX_LEARN_DST_OUTPUT:
            ds_put_format(s, "%soutput:%s", colors.special, colors.end);
            mf_format_subfield(&spec->src, s);
            break;
        }
    }
Beispiel #13
0
/**
 * creates new connection element
 * and initializes values with given IPFIX record
 * NOTE: all values are *copied*, no reference will be kept to original IPFIX record
 * @param connTimeout time in seconds when connection element times out
 */
Connection::Connection(IpfixDataRecord* record)
	: srcOctets(0), dstOctets(0),
	  srcPackets(0), dstPackets(0),
	  srcTcpControlBits(0), dstTcpControlBits(0),
	  srcPayload(0), srcPayloadLen(0),
	  dstPayload(0), dstPayloadLen(0),
	  dpaForcedExport(0), dpaFlowCount(0),
	  dpaReverseStart(0)
{
	// convert IpfixDataRecord to Connection
	TemplateInfo::FieldInfo* fi = record->templateInfo->getFieldInfo(IPFIX_TYPEID_sourceIPv4Address, 0);
	if (fi != 0) {
		srcIP = *(uint32_t*)(record->data + fi->offset);
	} else {
		msg(MSG_INFO, "failed to determine source ip for record, assuming 0.0.0.0");
		srcIP = 0;
	}
	fi = record->templateInfo->getFieldInfo(IPFIX_TYPEID_destinationIPv4Address, 0);
	if (fi != 0) {
		dstIP = *(uint32_t*)(record->data + fi->offset);
	} else {
		msg(MSG_INFO, "failed to determine destination ip for record, assuming 0.0.0.0");
		dstIP = 0;
	}
	fi = record->templateInfo->getFieldInfo(IPFIX_TYPEID_sourceTransportPort, 0);
	if (fi != 0) {
		srcPort = *(uint16_t*)(record->data + fi->offset);
	} else {
		msg(MSG_INFO, "failed to determine source port for record, assuming 0");
		srcPort = 0;
	}
	fi = record->templateInfo->getFieldInfo(IPFIX_TYPEID_destinationTransportPort, 0);
	if (fi != 0) {
		dstPort = *(uint16_t*)(record->data + fi->offset);
	} else {
		msg(MSG_INFO, "failed to determine destination port for record, assuming 0");
		srcPort = 0;
	}
	fi = record->templateInfo->getFieldInfo(IPFIX_TYPEID_protocolIdentifier, 0);
	if (fi != 0) {
		protocol = *(uint8_t*)(record->data + fi->offset);
	} else {
		msg(MSG_INFO, "failed to determine protocol for record, using 0");
		protocol = 0;
	}

	fi = record->templateInfo->getFieldInfo(IPFIX_TYPEID_flowStartNanoseconds, 0);
	if (fi != 0) {
		convertNtp64(*(uint64_t*)(record->data + fi->offset), srcTimeStart);
	} else {
		fi = record->templateInfo->getFieldInfo(IPFIX_TYPEID_flowStartMilliseconds, 0);
		if (fi != 0) {
			srcTimeStart = ntohll(*(uint64_t*)(record->data + fi->offset));
		} else {
			fi = record->templateInfo->getFieldInfo(IPFIX_TYPEID_flowStartSeconds, 0);
			if (fi != 0) {
				srcTimeStart = ntohl(*(uint32_t*)(record->data + fi->offset));
				srcTimeStart *= 1000;
			} else {
				srcTimeStart = 0;
			}
		}
	}
	fi = record->templateInfo->getFieldInfo(IPFIX_TYPEID_flowEndNanoseconds, 0);
	if (fi != 0) {
		convertNtp64(*(uint64_t*)(record->data + fi->offset), srcTimeEnd);
	} else {
		fi = record->templateInfo->getFieldInfo(IPFIX_TYPEID_flowEndMilliseconds, 0);
		if (fi != 0) {
			srcTimeEnd = ntohll(*(uint64_t*)(record->data + fi->offset));
		} else {
			fi = record->templateInfo->getFieldInfo(IPFIX_TYPEID_flowEndSeconds, 0);
			if (fi != 0) {
				srcTimeEnd = ntohl(*(uint32_t*)(record->data + fi->offset));
				srcTimeEnd *= 1000;
			} else {
				srcTimeEnd = 0;
			}
		}
	}
	fi = record->templateInfo->getFieldInfo(IPFIX_TYPEID_flowStartNanoseconds, IPFIX_PEN_reverse);
	if (fi != 0) {
		convertNtp64(*(uint64_t*)(record->data + fi->offset), dstTimeStart);
	} else {
		fi = record->templateInfo->getFieldInfo(IPFIX_TYPEID_flowStartMilliseconds, IPFIX_PEN_reverse);
		if (fi != 0) {
			dstTimeStart = ntohll(*(uint64_t*)(record->data + fi->offset));
		} else {
			fi = record->templateInfo->getFieldInfo(IPFIX_TYPEID_flowStartSeconds, IPFIX_PEN_reverse);
			if (fi != 0) {
				dstTimeStart = ntohl(*(uint32_t*)(record->data + fi->offset));
				dstTimeStart *= 1000;
			} else {
				dstTimeStart = 0;
			}
		}
	}
	fi = record->templateInfo->getFieldInfo(IPFIX_TYPEID_flowEndNanoseconds, IPFIX_PEN_reverse);
	if (fi != 0) {
		convertNtp64(*(uint64_t*)(record->data + fi->offset), dstTimeEnd);
	} else {
		fi = record->templateInfo->getFieldInfo(IPFIX_TYPEID_flowEndMilliseconds, IPFIX_PEN_reverse);
		if (fi != 0) {
			dstTimeEnd = ntohll(*(uint64_t*)(record->data + fi->offset));
		} else {
			fi = record->templateInfo->getFieldInfo(IPFIX_TYPEID_flowEndSeconds, IPFIX_PEN_reverse);
			if (fi != 0) {
				dstTimeEnd = ntohl(*(uint32_t*)(record->data + fi->offset));
				dstTimeEnd *= 1000;
			} else {
				dstTimeEnd = 0;
			}
		}
	}
	fi = record->templateInfo->getFieldInfo(IPFIX_TYPEID_octetDeltaCount, 0);
	if (fi != 0) srcOctets = *(uint64_t*)(record->data + fi->offset);
	fi = record->templateInfo->getFieldInfo(IPFIX_TYPEID_octetDeltaCount, IPFIX_PEN_reverse);
	if (fi != 0) dstOctets = *(uint64_t*)(record->data + fi->offset);
	fi = record->templateInfo->getFieldInfo(IPFIX_TYPEID_packetDeltaCount, 0);
	if (fi != 0) srcPackets = *(uint64_t*)(record->data + fi->offset);
	fi = record->templateInfo->getFieldInfo(IPFIX_TYPEID_packetDeltaCount, IPFIX_PEN_reverse);
	if (fi != 0) dstPackets = *(uint64_t*)(record->data + fi->offset);
	fi = record->templateInfo->getFieldInfo(IPFIX_TYPEID_tcpControlBits, 0);
	if (fi != 0) srcTcpControlBits = *(uint8_t*)(record->data + fi->offset);
	fi = record->templateInfo->getFieldInfo(IPFIX_TYPEID_tcpControlBits, IPFIX_PEN_reverse);
	if (fi != 0) dstTcpControlBits = *(uint8_t*)(record->data + fi->offset);
	fi = record->templateInfo->getFieldInfo(IPFIX_ETYPEID_frontPayload, IPFIX_PEN_vermont);
	if (fi != 0 && fi->type.length) {
		TemplateInfo::FieldInfo* filen = record->templateInfo->getFieldInfo(IPFIX_ETYPEID_frontPayloadLen, IPFIX_PEN_vermont);
		if (filen != 0)
			srcPayloadLen = ntohl(*(uint32_t*)(record->data + filen->offset));
		else
			srcPayloadLen = fi->type.length;
		srcPayload = new char[srcPayloadLen];
		memcpy(srcPayload, record->data + fi->offset, srcPayloadLen);
	}
	fi = record->templateInfo->getFieldInfo(IPFIX_ETYPEID_frontPayload, IPFIX_PEN_vermont|IPFIX_PEN_reverse);
	if (fi != 0 && fi->type.length) {
		TemplateInfo::FieldInfo* filen = record->templateInfo->getFieldInfo(IPFIX_ETYPEID_frontPayloadLen, IPFIX_PEN_vermont|IPFIX_PEN_reverse);
		if (filen != 0)
			dstPayloadLen = ntohl(*(uint32_t*)(record->data + filen->offset));
		else
			dstPayloadLen = fi->type.length;
		dstPayload = new char[dstPayloadLen];
		memcpy(dstPayload, record->data + fi->offset, dstPayloadLen);
	}
	fi = record->templateInfo->getFieldInfo(IPFIX_ETYPEID_frontPayloadPktCount, IPFIX_PEN_vermont);
	if (fi != 0) srcPayloadPktCount= *(uint32_t*)(record->data + fi->offset);
	fi = record->templateInfo->getFieldInfo(IPFIX_ETYPEID_dpaForcedExport, IPFIX_PEN_vermont);
	if (fi != 0) dpaForcedExport = *(uint8_t*)(record->data + fi->offset);
	fi = record->templateInfo->getFieldInfo(IPFIX_ETYPEID_dpaReverseStart, IPFIX_PEN_vermont);
	if (fi != 0) dpaReverseStart = *(uint8_t*)(record->data + fi->offset);
	fi = record->templateInfo->getFieldInfo(IPFIX_ETYPEID_dpaFlowCount, IPFIX_PEN_vermont);
	if (fi != 0) dpaFlowCount = ntohl(*(uint32_t*)(record->data + fi->offset));
	fi = record->templateInfo->getFieldInfo(IPFIX_ETYPEID_transportOctetDeltaCount, IPFIX_PEN_vermont);
	if (fi != 0) srcTransOctets = ntohll(*(uint64_t*)(record->data + fi->offset));
	fi = record->templateInfo->getFieldInfo(IPFIX_ETYPEID_transportOctetDeltaCount, IPFIX_PEN_vermont|IPFIX_PEN_reverse);
	if (fi != 0) dstTransOctets = ntohll(*(uint64_t*)(record->data + fi->offset));
}
Beispiel #14
0
int nfnlmsg_queue_msg_parse(struct nlmsghdr *nlh,
			    struct nfnl_queue_msg **result)
{
	struct nfnl_queue_msg *msg;
	struct nlattr *tb[NFQA_MAX+1];
	struct nlattr *attr;
	int err;

	msg = nfnl_queue_msg_alloc();
	if (!msg)
		return -NLE_NOMEM;

	msg->ce_msgtype = nlh->nlmsg_type;

	err = nlmsg_parse(nlh, sizeof(struct nfgenmsg), tb, NFQA_MAX,
			  queue_policy);
	if (err < 0)
		goto errout;

	nfnl_queue_msg_set_group(msg, nfnlmsg_res_id(nlh));
	nfnl_queue_msg_set_family(msg, nfnlmsg_family(nlh));

	attr = tb[NFQA_PACKET_HDR];
	if (attr) {
		struct nfqnl_msg_packet_hdr *hdr = nla_data(attr);

		nfnl_queue_msg_set_packetid(msg, ntohl(hdr->packet_id));
		if (hdr->hw_protocol)
			nfnl_queue_msg_set_hwproto(msg, hdr->hw_protocol);
		nfnl_queue_msg_set_hook(msg, hdr->hook);
	}

	attr = tb[NFQA_MARK];
	if (attr)
		nfnl_queue_msg_set_mark(msg, ntohl(nla_get_u32(attr)));

	attr = tb[NFQA_TIMESTAMP];
	if (attr) {
		struct nfqnl_msg_packet_timestamp *timestamp = nla_data(attr);
		struct timeval tv;

		tv.tv_sec = ntohll(timestamp->sec);
		tv.tv_usec = ntohll(timestamp->usec);
		nfnl_queue_msg_set_timestamp(msg, &tv);
	}

	attr = tb[NFQA_IFINDEX_INDEV];
	if (attr)
		nfnl_queue_msg_set_indev(msg, ntohl(nla_get_u32(attr)));

	attr = tb[NFQA_IFINDEX_OUTDEV];
	if (attr)
		nfnl_queue_msg_set_outdev(msg, ntohl(nla_get_u32(attr)));

	attr = tb[NFQA_IFINDEX_PHYSINDEV];
	if (attr)
		nfnl_queue_msg_set_physindev(msg, ntohl(nla_get_u32(attr)));

	attr = tb[NFQA_IFINDEX_PHYSOUTDEV];
	if (attr)
		nfnl_queue_msg_set_physoutdev(msg, ntohl(nla_get_u32(attr)));

	attr = tb[NFQA_HWADDR];
	if (attr) {
		struct nfqnl_msg_packet_hw *hw = nla_data(attr);

		nfnl_queue_msg_set_hwaddr(msg, hw->hw_addr,
					  ntohs(hw->hw_addrlen));
	}

	attr = tb[NFQA_PAYLOAD];
	if (attr) {
		err = nfnl_queue_msg_set_payload(msg, nla_data(attr),
						 nla_len(attr));
		if (err < 0)
			goto errout;
	}

	*result = msg;
	return 0;

errout:
	nfnl_queue_msg_put(msg);
	return err;
}
Beispiel #15
0
uint64_t Netutil::ReadInt64(char* buff)
{
	uint64_t val = ntohll(*(uint64_t*)buff);
	return val;
}
Beispiel #16
0
static void IndexKVFile(const char* kvPath,
                        const char* backIndexPath,
                        const char* indexPath,
                        couchstore_json_reducer reducer)
{
    couchstore_error_t errcode;
    CouchStoreIndex* index = NULL;

    try(couchstore_create_index(indexPath, &index));
    try(couchstore_index_add(kvPath, COUCHSTORE_VIEW_PRIMARY_INDEX, reducer, index));
    try(couchstore_index_add(backIndexPath, COUCHSTORE_VIEW_BACK_INDEX, 0, index));
    try(couchstore_close_index(index));

cleanup:
    assert(errcode == 0);
}


static void ReadIndexFile(const char *indexPath)
{
    // See write_index_header in couch_index.c
    FILE *file = fopen(indexPath, "rb");
    fseek(file, 0, SEEK_END);
    long eof = ftell(file);
    long headerPos = eof - (eof % 4096);    // go to last 4KB boundary
    printf("Index header is at 0x%lx\n", headerPos);
    fseek(file, headerPos, SEEK_SET);

    // Header starts with a "1" byte, a length, and a CRC checksum:
    uint8_t flag;
    check_read(fread(&flag, 1, 1, file));
    assert_eq(flag, 1);
    uint32_t headerLength, headerChecksum;
    check_read(fread(&headerLength, sizeof(headerLength), 1, file));
    headerLength = ntohl(headerLength);
    check_read(fread(&headerChecksum, sizeof(headerChecksum), 1, file));
    headerChecksum = htonl(headerChecksum);
    assert_eq(headerPos + headerLength + 1 + 4, eof);

    // Next is the root count:
    uint32_t nRoots;
    check_read(fread(&nRoots, sizeof(nRoots), 1, file));
    nRoots = ntohl(nRoots);
    assert_eq(nRoots, 2);

    for (uint32_t root = 0; root < nRoots; ++root) {
        // The root has a type, size, node pointer, subtree size, and reduce data:
        uint8_t indexType; // really a couchstore_index_type
        check_read(fread(&indexType, 1, 1, file));
        assert_eq(indexType, root);  // i.e. first root is type 0, second is type 1
        uint16_t rootSize;
        check_read(fread(&rootSize, sizeof(rootSize), 1, file));
        rootSize = ntohs(rootSize);
        assert(rootSize >= 12);
        assert(rootSize < headerLength);
        uint64_t pointer = 0;
        uint64_t subtreesize = 0;
        check_read(fread((char*)&pointer + 2, 6, 1, file));
        check_read(fread((char*)&subtreesize + 2, 6, 1, file));
        pointer = ntohll(pointer);
        subtreesize = ntohll(subtreesize);
        sized_buf reduce = {NULL, rootSize - 12};
        reduce.buf = malloc(reduce.size);
        check_read(fread(reduce.buf, reduce.size, 1, file));

        printf("\tRoot: type=%d, pointer=%llu, subtreesize=%llu, reduce=%llu bytes\n",
               indexType, pointer, subtreesize, (uint64_t)reduce.size);
        assert((cs_off_t)pointer < headerPos);
        assert((cs_off_t)subtreesize < headerPos);

        // Examine the reduce values in the root node:
        assert(reduce.size >= 5 + 1024/8);
        uint64_t subtreeCount = 0;
        memcpy((uint8_t*)&subtreeCount + 3, reduce.buf, 5);
        subtreeCount = ntohll(subtreeCount);
        printf("\t      SubTreeCount = %llu\n", subtreeCount);
        assert_eq(subtreeCount, 1000);

        printf("\t      Bitmap = <");
        for (int i = 0; i < 128; ++i) {
            printf("%.02x", (uint8_t)reduce.buf[5 + i]);
            if (i % 4 == 3)
                printf(" ");
        }
        printf(">\n");

        if (indexType == COUCHSTORE_VIEW_PRIMARY_INDEX) {
            // JSON reductions:
            assert(reduce.size > 5 + 1024/8 + 2);
            char* jsonReduceStart = reduce.buf + 5 + 1024/8;
            sized_buf jsonReduce = {jsonReduceStart + 2, ntohs(*(uint16_t*)jsonReduceStart)};
            assert(jsonReduce.size < 1000);
            printf("\t      JSONReduction = '%.*s'\n", (int)jsonReduce.size, jsonReduce.buf);

            const char* expectedReduce = "{\"count\":1000,\"max\":99.51,\"min\":0.18,\"sum\":49547.93,\"sumsqr\":3272610.9289}";
            assert_eq(jsonReduce.size, strlen(expectedReduce));
            assert(strncmp(jsonReduce.buf, expectedReduce, strlen(expectedReduce)) == 0);
        }
    }

    assert_eq(ftell(file), eof);
    fclose(file);
}


void TestCouchIndexer(void) {
    fprintf(stderr, "Indexer: ");
    srandom(42);  // to get a consistent sequence of random numbers
    GenerateKVFile(KVPATH, 1000);
    srandom(42);  // to get a consistent sequence of random numbers
    GenerateBackIndexKVFile(KVBACKPATH, 1000);
    IndexKVFile(KVPATH, KVBACKPATH, INDEXPATH, COUCHSTORE_REDUCE_STATS);
    ReadIndexFile(INDEXPATH);
    unlink(KVPATH);
    unlink(INDEXPATH);
    fprintf(stderr, "OK\n");
}
Beispiel #17
0
STATUS FNC::Recv()
{
    struct sockaddr_in fromAddr;
    socklen_t fromAddrLen = sizeof fromAddr;

    int n = recvfrom(m_recvSocket, (char *)&m_recvPkt, sizeof m_recvPkt, 0,
		     (struct sockaddr *)&fromAddr, &fromAddrLen);
    if (n == -1) {
	perror("FRC_NetworkCommunication::Recv::recvfrom");
	return ERROR;
    }

    if (m_recvAddr.sin_addr.s_addr == INADDR_ANY) {
	// fill in my own address based on:
	// DS at 10.TE.AM.xx
	// robot at 10.TE.AM.2
	in_addr_t ipaddr = ntohl(fromAddr.sin_addr.s_addr);
	ipaddr = (ipaddr & 0xFFFFFF00) | 0x02;
	m_recvAddr.sin_addr.s_addr = htonl(ipaddr);
	m_sendAddr.sin_addr.s_addr = htonl(ipaddr);
    }

    m_pcap->write_record(&fromAddr, &m_recvAddr, (char *)&m_recvPkt, n);

    if (n != sizeof m_recvPkt) {
	printf("FRC_NetworkCommunication::Recv: wrong size (%d)\n", n);
	return OK;
    }

    uint32_t recvCRC = ntohl(m_recvPkt.crc);
    m_recvPkt.crc = 0;
    uint32_t calcCRC = crc32(0, Z_NULL, 0);
    calcCRC = crc32(calcCRC, (uint8_t *)&m_recvPkt, sizeof m_recvPkt);

    if (calcCRC != recvCRC) {
	printf("FRC_NetworkCommunication::Recv: bad checksum "
	       "(received 0x%08x, calculated 0x%08x)\n", recvCRC, calcCRC);
	return OK;
    }

    // unpack and copy data to m_recvData
    {
	// begin critical section
	Synchronized sync(m_dataMutex);

	// clear the work area for safety
	memset(&m_recvData, 0, sizeof m_recvData);

	// unpack common header elements
	m_recvData.packetIndex		= ntohs(m_recvPkt.ctrl.packetIndex);

	m_recvData.reset		= m_recvPkt.ctrl.reset;
	m_recvData.notEStop		= m_recvPkt.ctrl.notEStop;
	m_recvData.enabled		= m_recvPkt.ctrl.enabled;
	m_recvData.autonomous		= m_recvPkt.ctrl.autonomous;
	m_recvData.fmsAttached		= m_recvPkt.ctrl.fmsAttached;
	m_recvData.resync		= m_recvPkt.ctrl.resync;
	m_recvData.test			= m_recvPkt.ctrl.test;
	m_recvData.checkVersions	= m_recvPkt.ctrl.checkVersions;

	m_recvData.dsDigitalIn		= m_recvPkt.ctrl.dsDigitalIn;
	m_recvData.teamID		= ntohs(m_recvPkt.ctrl.teamID);
	m_recvData.dsID_Alliance	= m_recvPkt.ctrl.dsID_Alliance;
	m_recvData.dsID_Position	= m_recvPkt.ctrl.dsID_Position;
#if 0
	printf("pkt %u ctrl 0x%02x dig in 0x%02x team %u position %c%c\n",
	       m_recvData.packetIndex, m_recvData.control,
	       m_recvData.dsDigitalIn, m_recvData.teamID,
	       m_recvData.dsID_Alliance, m_recvData.dsID_Position);
#endif

	// unpack data for each of the 4 possible joysticks
	m_recvData.stick0Axis1		= m_recvPkt.ctrl.stick0Axis1;
	m_recvData.stick0Axis2		= m_recvPkt.ctrl.stick0Axis2;
	m_recvData.stick0Axis3		= m_recvPkt.ctrl.stick0Axis3;
	m_recvData.stick0Axis4		= m_recvPkt.ctrl.stick0Axis4;
	m_recvData.stick0Axis5		= m_recvPkt.ctrl.stick0Axis5;
	m_recvData.stick0Axis6		= m_recvPkt.ctrl.stick0Axis6;
	m_recvData.stick0Buttons	= ntohs(m_recvPkt.ctrl.stick0Buttons);
#if 0
	printf("stick0: %02x %02x %02x %02x %02x %02x %04x\n",
		m_recvData.stick0Axis1, m_recvData.stick0Axis2,
		m_recvData.stick0Axis3, m_recvData.stick0Axis4,
		m_recvData.stick0Axis5, m_recvData.stick0Axis6,
		m_recvData.stick0Buttons);
#endif
	m_recvData.stick1Axis1		= m_recvPkt.ctrl.stick1Axis1;
	m_recvData.stick1Axis2		= m_recvPkt.ctrl.stick1Axis2;
	m_recvData.stick1Axis3		= m_recvPkt.ctrl.stick1Axis3;
	m_recvData.stick1Axis4		= m_recvPkt.ctrl.stick1Axis4;
	m_recvData.stick1Axis5		= m_recvPkt.ctrl.stick1Axis5;
	m_recvData.stick1Axis6		= m_recvPkt.ctrl.stick1Axis6;
	m_recvData.stick1Buttons	= ntohs(m_recvPkt.ctrl.stick1Buttons);
#if 0
	printf("stick1: %02x %02x %02x %02x %02x %02x %04x\n",
		m_recvData.stick1Axis1, m_recvData.stick1Axis2,
		m_recvData.stick1Axis3, m_recvData.stick1Axis4,
		m_recvData.stick1Axis5, m_recvData.stick1Axis6,
		m_recvData.stick1Buttons);
#endif
	m_recvData.stick2Axis1		= m_recvPkt.ctrl.stick2Axis1;
	m_recvData.stick2Axis2		= m_recvPkt.ctrl.stick2Axis2;
	m_recvData.stick2Axis3		= m_recvPkt.ctrl.stick2Axis3;
	m_recvData.stick2Axis4		= m_recvPkt.ctrl.stick2Axis4;
	m_recvData.stick2Axis5		= m_recvPkt.ctrl.stick2Axis5;
	m_recvData.stick2Axis6		= m_recvPkt.ctrl.stick2Axis6;
	m_recvData.stick2Buttons	= ntohs(m_recvPkt.ctrl.stick2Buttons);
#if 0
	printf("stick2: %02x %02x %02x %02x %02x %02x %04x\n",
		m_recvData.stick2Axis1, m_recvData.stick2Axis2,
		m_recvData.stick2Axis3, m_recvData.stick2Axis4,
		m_recvData.stick2Axis5, m_recvData.stick2Axis6,
		m_recvData.stick2Buttons);
#endif
	m_recvData.stick3Axis1		= m_recvPkt.ctrl.stick3Axis1;
	m_recvData.stick3Axis2		= m_recvPkt.ctrl.stick3Axis2;
	m_recvData.stick3Axis3		= m_recvPkt.ctrl.stick3Axis3;
	m_recvData.stick3Axis4		= m_recvPkt.ctrl.stick3Axis4;
	m_recvData.stick3Axis5		= m_recvPkt.ctrl.stick3Axis5;
	m_recvData.stick3Axis6		= m_recvPkt.ctrl.stick3Axis6;
	m_recvData.stick3Buttons	= ntohs(m_recvPkt.ctrl.stick3Buttons);
#if 0
	printf("stick3: %02x %02x %02x %02x %02x %02x %04x\n",
		m_recvData.stick3Axis1, m_recvData.stick3Axis2,
		m_recvData.stick3Axis3, m_recvData.stick3Axis4,
		m_recvData.stick3Axis5, m_recvData.stick3Axis6,
		m_recvData.stick3Buttons);
#endif

	// unpack the four analog input channels
	m_recvData.analog1		= ntohs(m_recvPkt.ctrl.analog1);
	m_recvData.analog2		= ntohs(m_recvPkt.ctrl.analog2);
	m_recvData.analog3		= ntohs(m_recvPkt.ctrl.analog3);
	m_recvData.analog4		= ntohs(m_recvPkt.ctrl.analog4);
#if 0
	printf("analog: %04x %04x %04x %04x\n",
		m_recvData.analog1, m_recvData.analog2,
		m_recvData.analog3, m_recvData.analog4);
#endif

	// unpack the cRIO and FPGA checksums (?)
#if (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
# define ntohll(x) ((uint64_t)(x))
#elif (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
# define ntohll(x) \
	((uint64_t)((((uint64_t)(x) & 0x00000000000000ffLLU) << 56) | \
		    (((uint64_t)(x) & 0x000000000000ff00LLU) << 40) | \
		    (((uint64_t)(x) & 0x0000000000ff0000LLU) << 24) | \
		    (((uint64_t)(x) & 0x00000000ff000000LLU) <<  8) | \
		    (((uint64_t)(x) & 0x000000ff00000000LLU) >>  8) | \
		    (((uint64_t)(x) & 0x0000ff0000000000LLU) >> 24) | \
		    (((uint64_t)(x) & 0x00ff000000000000LLU) >> 40) | \
		    (((uint64_t)(x) & 0xff00000000000000LLU) >> 56)))
#else
#error __BYTE_ORDER__ must be __ORDER_BIG_ENDIAN__ or __ORDER_LITTLE_ENDIAN__
#endif

	m_recvData.cRIOChecksum		= ntohll(m_recvPkt.ctrl.cRIOChecksum);
#if 0
	printf("cRIO checksum: %08lx%08lx\n",
	    (unsigned long)(m_recvData.cRIOChecksum >> 32),
	    (unsigned long)(m_recvData.cRIOChecksum));
#endif
	m_recvData.FPGAChecksum0	= ntohl(m_recvPkt.ctrl.FPGAChecksum0);
	m_recvData.FPGAChecksum1	= ntohl(m_recvPkt.ctrl.FPGAChecksum1);
	m_recvData.FPGAChecksum2	= ntohl(m_recvPkt.ctrl.FPGAChecksum2);
	m_recvData.FPGAChecksum3	= ntohl(m_recvPkt.ctrl.FPGAChecksum3);
#if 0
	printf("FPGA checksums: %08x %08x %08x %08x\n",
		m_recvData.FPGAChecksum0, m_recvData.FPGAChecksum1,
		m_recvData.FPGAChecksum2, m_recvData.FPGAChecksum3);
#endif

	// unpack the DS version string
	// ASCII string, mmddyyvv ("vv"="version" aka "build number")
	memcpy(m_recvData.versionData, m_recvPkt.ctrl.versionData, 8);
#if 0
	printf("DS version %.2s.%.2s.%.2s.%.2s\n",
		&m_recvData.versionData[0], &m_recvData.versionData[2],
		&m_recvData.versionData[4], &m_recvData.versionData[6]);
#endif

	// copy the dynamic extensions
	// we don't know the internal structure of these, so clients are
	// responsible for unpacking their own data
	memcpy(m_extData, m_recvPkt.extData, sizeof m_extData);

	// save sender's address for reply
	memcpy(&m_fromAddr, &fromAddr, sizeof m_fromAddr);

	// tell DriverStation object that new data is available
	if (m_dataAvailable) semFlush(m_dataAvailable);

	// end critical section
    }

    return OK;
}
Beispiel #18
0
static
void binary_deserialize(int8_t thrift_typeID, PHPInputTransport& transport, zval* return_value, HashTable* fieldspec) {
    ZVAL_NULL(return_value);

    switch (thrift_typeID) {
    case T_STOP:
    case T_VOID:
        RETURN_NULL();
        return;
    case T_STRUCT: {
        zval* val_ptr = zend_hash_str_find(fieldspec, "class", sizeof("class")-1);
        if (val_ptr == nullptr) {
            throw_tprotocolexception("no class type in spec", INVALID_DATA);
            skip_element(T_STRUCT, transport);
            RETURN_NULL();
        }

        char* structType = Z_STRVAL_P(val_ptr);
        // Create an object in PHP userland based on our spec
        createObject(structType, return_value);
        if (Z_TYPE_P(return_value) == IS_NULL) {
            // unable to create class entry
            skip_element(T_STRUCT, transport);
            RETURN_NULL();
        }

        zval* spec = zend_read_static_property(Z_OBJCE_P(return_value), "_TSPEC", sizeof("_TSPEC")-1, false);
        if (Z_TYPE_P(spec) != IS_ARRAY) {
            char errbuf[128];
            snprintf(errbuf, 128, "spec for %s is wrong type: %d\n", structType, Z_TYPE_P(spec));
            throw_tprotocolexception(errbuf, INVALID_DATA);
            RETURN_NULL();
        }
        binary_deserialize_spec(return_value, transport, Z_ARRVAL_P(spec));
        return;
    }
    break;
    case T_BOOL: {
        uint8_t c;
        transport.readBytes(&c, 1);
        RETURN_BOOL(c != 0);
    }
    //case T_I08: // same numeric value as T_BYTE
    case T_BYTE: {
        uint8_t c;
        transport.readBytes(&c, 1);
        RETURN_LONG((int8_t)c);
    }
    case T_I16: {
        uint16_t c;
        transport.readBytes(&c, 2);
        RETURN_LONG((int16_t)ntohs(c));
    }
    case T_I32: {
        uint32_t c;
        transport.readBytes(&c, 4);
        RETURN_LONG((int32_t)ntohl(c));
    }
    case T_U64:
    case T_I64: {
        uint64_t c;
        transport.readBytes(&c, 8);
        RETURN_LONG((int64_t)ntohll(c));
    }
    case T_DOUBLE: {
        union {
            uint64_t c;
            double d;
        } a;
        transport.readBytes(&(a.c), 8);
        a.c = ntohll(a.c);
        RETURN_DOUBLE(a.d);
    }
    //case T_UTF7: // aliases T_STRING
    case T_UTF8:
    case T_UTF16:
    case T_STRING: {
        uint32_t size = transport.readU32();
        if (size) {
            char strbuf[size+1];
            transport.readBytes(strbuf, size);
            strbuf[size] = '\0';
            ZVAL_STRINGL(return_value, strbuf, size);
        } else {
            ZVAL_EMPTY_STRING(return_value);
        }
        return;
    }
    case T_MAP: { // array of key -> value
        uint8_t types[2];
        transport.readBytes(types, 2);
        uint32_t size = transport.readU32();
        array_init(return_value);

        zval *val_ptr;
        val_ptr = zend_hash_str_find(fieldspec, "key", sizeof("key")-1);
        HashTable* keyspec = Z_ARRVAL_P(val_ptr);
        val_ptr = zend_hash_str_find(fieldspec, "val", sizeof("val")-1);
        HashTable* valspec = Z_ARRVAL_P(val_ptr);

        for (uint32_t s = 0; s < size; ++s) {
            zval key, value;

            binary_deserialize(types[0], transport, &key, keyspec);
            binary_deserialize(types[1], transport, &value, valspec);
            if (Z_TYPE(key) == IS_LONG) {
                zend_hash_index_update(Z_ARR_P(return_value), Z_LVAL(key), &value);
            } else {
                if (Z_TYPE(key) != IS_STRING) convert_to_string(&key);
                zend_hash_update(Z_ARR_P(return_value), Z_STR(key), &value);
            }
        }
        return; // return_value already populated
    }
    case T_LIST: { // array with autogenerated numeric keys
        int8_t type = transport.readI8();
        uint32_t size = transport.readU32();
        zval *val_ptr = zend_hash_str_find(fieldspec, "elem", sizeof("elem")-1);
        HashTable* elemspec = Z_ARRVAL_P(val_ptr);

        array_init(return_value);
        for (uint32_t s = 0; s < size; ++s) {
            zval value;
            binary_deserialize(type, transport, &value, elemspec);
            zend_hash_next_index_insert(Z_ARR_P(return_value), &value);
        }
        return;
    }
    case T_SET: { // array of key -> TRUE
        uint8_t type;
        uint32_t size;
        transport.readBytes(&type, 1);
        transport.readBytes(&size, 4);
        size = ntohl(size);
        zval *val_ptr = zend_hash_str_find(fieldspec, "elem", sizeof("elem")-1);
        HashTable* elemspec = Z_ARRVAL_P(val_ptr);

        array_init(return_value);

        for (uint32_t s = 0; s < size; ++s) {
            zval key, value;
            ZVAL_UNDEF(&value);

            binary_deserialize(type, transport, &key, elemspec);

            if (Z_TYPE(key) == IS_LONG) {
                zend_hash_index_update(Z_ARR_P(return_value), Z_LVAL(key), &value);
            } else {
                if (Z_TYPE(key) != IS_STRING) convert_to_string(&key);
                zend_hash_update(Z_ARR_P(return_value), Z_STR(key), &value);
            }
        }
        return;
    }
    };

    char errbuf[128];
    sprintf(errbuf, "Unknown thrift typeID %d", thrift_typeID);
    throw_tprotocolexception(errbuf, INVALID_DATA);
}
static int parse_part_values (void **ret_buffer, size_t *ret_buffer_len,
    value_t **ret_values, int *ret_num_values)
{
  char *buffer = *ret_buffer;
  size_t buffer_len = *ret_buffer_len;

  uint16_t tmp16;
  size_t exp_size;
  int   i;

  uint16_t pkg_length;
  uint16_t pkg_type;
  uint16_t pkg_numval;

  uint8_t *pkg_types;
  value_t *pkg_values;

  if (buffer_len < 15)
  {
    NOTICE ("network plugin: packet is too short: "
        "buffer_len = %zu", buffer_len);
    return (-1);
  }

  memcpy ((void *) &tmp16, buffer, sizeof (tmp16));
  buffer += sizeof (tmp16);
  pkg_type = ntohs (tmp16);

  memcpy ((void *) &tmp16, buffer, sizeof (tmp16));
  buffer += sizeof (tmp16);
  pkg_length = ntohs (tmp16);

  memcpy ((void *) &tmp16, buffer, sizeof (tmp16));
  buffer += sizeof (tmp16);
  pkg_numval = ntohs (tmp16);

  assert (pkg_type == TYPE_VALUES);

  exp_size = 3 * sizeof (uint16_t)
    + pkg_numval * (sizeof (uint8_t) + sizeof (value_t));
  if ((buffer_len < 0) || (buffer_len < exp_size))
  {
    WARNING ("network plugin: parse_part_values: "
        "Packet too short: "
        "Chunk of size %zu expected, "
        "but buffer has only %zu bytes left.",
        exp_size, buffer_len);
    return (-1);
  }

  if (pkg_length != exp_size)
  {
    WARNING ("network plugin: parse_part_values: "
        "Length and number of values "
        "in the packet don't match.");
    return (-1);
  }

  pkg_types = (uint8_t *) malloc (pkg_numval * sizeof (uint8_t));
  pkg_values = (value_t *) malloc (pkg_numval * sizeof (value_t));
  if ((pkg_types == NULL) || (pkg_values == NULL))
  {
    sfree (pkg_types);
    sfree (pkg_values);
    ERROR ("network plugin: parse_part_values: malloc failed.");
    return (-1);
  }

  memcpy ((void *) pkg_types, (void *) buffer, pkg_numval * sizeof (uint8_t));
  buffer += pkg_numval * sizeof (uint8_t);
  memcpy ((void *) pkg_values, (void *) buffer, pkg_numval * sizeof (value_t));
  buffer += pkg_numval * sizeof (value_t);

  for (i = 0; i < pkg_numval; i++)
  {
    switch (pkg_types[i])
    {
      case DS_TYPE_COUNTER:
        pkg_values[i].counter = (counter_t) ntohll (pkg_values[i].counter);
        break;

      case DS_TYPE_GAUGE:
        pkg_values[i].gauge = (gauge_t) ntohd (pkg_values[i].gauge);
        break;

      case DS_TYPE_DERIVE:
        pkg_values[i].derive = (derive_t) ntohll (pkg_values[i].derive);
        break;

      case DS_TYPE_ABSOLUTE:
        pkg_values[i].absolute = (absolute_t) ntohll (pkg_values[i].absolute);
        break;

      default:
        NOTICE ("network plugin: parse_part_values: "
      "Don't know how to handle data source type %"PRIu8,
      pkg_types[i]);
        sfree (pkg_types);
        sfree (pkg_values);
        return (-1);
    } /* switch (pkg_types[i]) */
  }

  *ret_buffer     = buffer;
  *ret_buffer_len = buffer_len - pkg_length;
  *ret_num_values = pkg_numval;
  *ret_values     = pkg_values;

  sfree (pkg_types);

  return (0);
} /* int parse_part_values */
Beispiel #20
0
/*
 *	Convert diameter attributes to our VALUE_PAIR's
 */
static VALUE_PAIR *diameter2vp(REQUEST *request, SSL *ssl,
			       const uint8_t *data, size_t data_len)
{
	uint32_t	attr;
	uint32_t	vendor;
	uint32_t	length;
	size_t		offset;
	size_t		size;
	size_t		data_left = data_len;
	VALUE_PAIR	*first = NULL;
	VALUE_PAIR	**last = &first;
	VALUE_PAIR	*vp;

	while (data_left > 0) {
		rad_assert(data_left <= data_len);
		memcpy(&attr, data, sizeof(attr));
		data += 4;
		attr = ntohl(attr);
		vendor = 0;

		memcpy(&length, data, sizeof(length));
		data += 4;
		length = ntohl(length);

		/*
		 *	A "vendor" flag, with a vendor ID of zero,
		 *	is equivalent to no vendor.  This is stupid.
		 */
		offset = 8;
		if ((length & (1 << 31)) != 0) {
			memcpy(&vendor, data, sizeof(vendor));
			vendor = ntohl(vendor);

			data += 4; /* skip the vendor field, it's zero */
			offset += 4; /* offset to value field */

			if (attr > 65535) goto next_attr;
			if (vendor > FR_MAX_VENDOR) goto next_attr;
		}

		/*
		 *	FIXME: Handle the M bit.  For now, we assume that
		 *	some other module takes care of any attribute
		 *	with the M bit set.
		 */
		
		/*
		 *	Get the length.
		 */
		length &= 0x00ffffff;

		/*
		 *	Get the size of the value portion of the
		 *	attribute.
		 */
		size = length - offset;

		/*
		 *	Vendor attributes can be larger than 255.
		 *	Normal attributes cannot be.
		 */
		if ((attr > 255) && (vendor == 0)) {
			RDEBUG2W("Skipping Diameter attribute %u",
				attr);
			goto next_attr;
		}

		/*
		 * EAP-Message AVPs can be larger than 253 octets.
		 */
		if ((size > 253) && !((vendor == 0) && (attr == PW_EAP_MESSAGE))) {
			RDEBUG2W("diameter2vp skipping long attribute %u", attr);
			goto next_attr;
		}

		/*
		 *	RADIUS VSAs are handled as Diameter attributes
		 *	with Vendor-Id == 0, and the VSA data packed
		 *	into the "String" field as per normal.
		 *
		 *	EXCEPT for the MS-CHAP attributes.
		 */
		if ((vendor == 0) && (attr == PW_VENDOR_SPECIFIC)) {
			ssize_t decoded;
			uint8_t buffer[256];

			buffer[0] = PW_VENDOR_SPECIFIC;
			buffer[1] = size + 2;
			memcpy(buffer + 2, data, size);

			vp = NULL;
			decoded = rad_attr2vp(NULL, NULL, NULL,
					      buffer, size + 2, &vp);
			if (decoded < 0) {
				RDEBUG2E("diameter2vp failed decoding attr: %s",
					fr_strerror());
				goto do_octets;
			}

			if ((size_t) decoded != size + 2) {
				RDEBUG2E("diameter2vp failed to entirely decode VSA");
				pairfree(&vp);
				goto do_octets;
			}

			*last = vp;
			do {
				last = &(vp->next);
				vp = vp->next;
			} while (vp != NULL);

			goto next_attr;
		}

		/*
		 *	Create it.  If this fails, it's because we're OOM.
		 */
	do_octets:
		vp = paircreate(attr, vendor);
		if (!vp) {
			RDEBUG2("Failure in creating VP");
			pairfree(&first);
			return NULL;
		}

		/*
		 *	If it's a type from our dictionary, then
		 *	we need to put the data in a relevant place.
		 */
		switch (vp->da->type) {
		case PW_TYPE_INTEGER:
		case PW_TYPE_DATE:
			if (size != vp->length) {
				const DICT_ATTR *da;

				/*
				 *	Bad format.  Create a "raw"
				 *	attribute.
				 */
		raw:
				if (vp) pairfree(&vp);
				da = dict_attrunknown(attr, vendor, TRUE);
				if (!da) return NULL;
				vp = pairalloc(NULL, da);
				if (size >= 253) size = 253;
				vp->length = size;
				memcpy(vp->vp_octets, data, vp->length);
				break;
			}
			memcpy(&vp->vp_integer, data, vp->length);

			/*
			 *	Stored in host byte order: change it.
			 */
			vp->vp_integer = ntohl(vp->vp_integer);
			break;

		case PW_TYPE_INTEGER64:
			if (size != vp->length) goto raw;
			memcpy(&vp->vp_integer64, data, vp->length);

			/*
			 *	Stored in host byte order: change it.
			 */
			vp->vp_integer64 = ntohll(vp->vp_integer64);
			break;

		case PW_TYPE_IPADDR:
			if (size != vp->length) {
				RDEBUG2("Invalid length attribute %d",
				       attr);
				pairfree(&first);
				pairfree(&vp);
				return NULL;
			}
		  memcpy(&vp->vp_ipaddr, data, vp->length);

		  /*
		   *	Stored in network byte order: don't change it.
		   */
		  break;

		case PW_TYPE_BYTE:
			if (size != vp->length) goto raw;
			vp->vp_integer = data[0];
			break;

		case PW_TYPE_SHORT:
			if (size != vp->length) goto raw;
			vp->vp_integer = (data[0] * 256) + data[1];
			break;

		case PW_TYPE_SIGNED:
			if (size != vp->length) goto raw;
			memcpy(&vp->vp_signed, data, vp->length);
			vp->vp_signed = ntohl(vp->vp_signed);
			break;

		case PW_TYPE_IPV6ADDR:
			if (size != vp->length) goto raw;
			memcpy(&vp->vp_ipv6addr, data, vp->length);
			break;

		case PW_TYPE_IPV6PREFIX:
			if (size != vp->length) goto raw;
			memcpy(&vp->vp_ipv6prefix, data, vp->length);
			break;

			/*
			 *	String, octet, etc.  Copy the data from the
			 *	value field over verbatim.
			 */
		case PW_TYPE_OCTETS:
			if (attr == PW_EAP_MESSAGE) {
				const uint8_t *eap_message = data;

				/*
				 *	vp exists the first time around.
				 */
				while (1) {
					vp->length = size;
					if (vp->length > 253) vp->length = 253;
					memcpy(vp->vp_octets, eap_message,
					       vp->length);

					size -= vp->length;
					eap_message += vp->length;

					*last = vp;
					last = &(vp->next);

					if (size == 0) break;

					vp = paircreate(attr, vendor);
					if (!vp) {
						RDEBUG2("Failure in creating VP");
						pairfree(&first);
						return NULL;
					}
				}

				goto next_attr;
			} /* else it's another kind of attribute */
			/* FALL-THROUGH */

		default:
			if (size >= 253) size = 253;
			vp->length = size;
			memcpy(vp->vp_strvalue, data, vp->length);
			break;
		}

		/*
		 *	User-Password is NUL padded to a multiple
		 *	of 16 bytes.  Let's chop it to something
		 *	more reasonable.
		 *
		 *	NOTE: This means that the User-Password
		 *	attribute CANNOT EVER have embedded zeros in it!
		 */
		if ((vp->da->vendor == 0) && (vp->da->attr == PW_USER_PASSWORD)) {
			/*
			 *	If the password is exactly 16 octets,
			 *	it won't be zero-terminated.
			 */
			vp->vp_strvalue[vp->length] = '\0';
			vp->length = strlen(vp->vp_strvalue);
		}

		/*
		 *	Ensure that the client is using the
		 *	correct challenge.  This weirdness is
		 *	to protect against against replay
		 *	attacks, where anyone observing the
		 *	CHAP exchange could pose as that user,
		 *	by simply choosing to use the same
		 *	challenge.
		 *
		 *	By using a challenge based on
		 *	information from the current session,
		 *	we can guarantee that the client is
		 *	not *choosing* a challenge.
		 *
		 *	We're a little forgiving in that we
		 *	have loose checks on the length, and
		 *	we do NOT check the Id (first octet of
		 *	the response to the challenge)
		 *
		 *	But if the client gets the challenge correct,
		 *	we're not too worried about the Id.
		 */
		if (((vp->da->vendor == 0) && (vp->da->attr == PW_CHAP_CHALLENGE)) ||
		    ((vp->da->vendor == VENDORPEC_MICROSOFT) && (vp->da->attr == PW_MSCHAP_CHALLENGE))) {
			uint8_t	challenge[16];

			if ((vp->length < 8) ||
			    (vp->length > 16)) {
				RDEBUG("Tunneled challenge has invalid length");
				pairfree(&first);
				pairfree(&vp);
				return NULL;
			}

			eapttls_gen_challenge(ssl, challenge,
					      sizeof(challenge));
			
			if (memcmp(challenge, vp->vp_octets,
				   vp->length) != 0) {
				RDEBUG("Tunneled challenge is incorrect");
				pairfree(&first);
				pairfree(&vp);
				return NULL;
			}
		}

		/*
		 *	Update the list.
		 */
		*last = vp;
		last = &(vp->next);

	next_attr:
		/*
		 *	Catch non-aligned attributes.
		 */
		if (data_left == length) break;

		/*
		 *	The length does NOT include the padding, so
		 *	we've got to account for it here by rounding up
		 *	to the nearest 4-byte boundary.
		 */
		length += 0x03;
		length &= ~0x03;

		rad_assert(data_left >= length);
		data_left -= length;
		data += length - offset; /* already updated */
	}

	/*
	 *	We got this far.  It looks OK.
	 */
	return first;
}
Beispiel #21
0
size_t Variant::deserialize(const unsigned char *buffer, size_t size)
{
    if (buffer != NULL && size > 0)
    {
        Variant::Type type = static_cast<Variant::Type>(*buffer);
        ++buffer;

        switch (type)
        {
            case UINT8:
            {
                typedef uint8_t Type;

                if ((size - 1) < sizeof(Type))
                    return 0;
                else
                {
                    setUint8(static_cast<Type>(*buffer));
                    size = sizeof(Type) + 1;
                }

                break;
            }

            case INT8:
            {
                typedef uint8_t Type;

                if ((size - 1) < sizeof(Type))
                    return 0;
                else
                {
                    setInt8(static_cast<Type>(*buffer));
                    size = sizeof(Type) + 1;
                }

                break;
            }

            case UINT16:
            {
                typedef uint16_t Type;

                if ((size - 1) < sizeof(Type))
                    return 0;
                else
                {
                    setUint16(ntohs(*reinterpret_cast<const Type *>(buffer)));
                    size = sizeof(Type) + 1;
                }

                break;
            }

            case INT16:
            {
                typedef int16_t Type;

                if ((size - 1) < sizeof(Type))
                    return 0;
                else
                {
                    setInt16(ntohs(*reinterpret_cast<const Type *>(buffer)));
                    size = sizeof(Type) + 1;
                }

                break;
            }

            case UINT32:
            {
                typedef uint32_t Type;

                if ((size - 1) < sizeof(Type))
                    return 0;
                else
                {
                    setUint32(ntohl(*reinterpret_cast<const Type *>(buffer)));
                    size = sizeof(Type) + 1;
                }

                break;
            }

            case INT32:
            {
                typedef int32_t Type;

                if ((size - 1) < sizeof(Type))
                    return 0;
                else
                {
                    setInt32(ntohl(*reinterpret_cast<const Type *>(buffer)));
                    size = sizeof(Type) + 1;
                }

                break;
            }

            case UINT64:
            {
                typedef uint64_t Type;

                if ((size - 1) < sizeof(Type))
                    return 0;
                else
                {
                    setUint64(ntohll(*reinterpret_cast<const Type *>(buffer)));
                    size = sizeof(Type) + 1;
                }

                break;
            }

            case INT64:
            {
                typedef int64_t Type;

                if ((size - 1) < sizeof(Type))
                    return 0;
                else
                {
                    setInt64(ntohll(*reinterpret_cast<const Type *>(buffer)));
                    size = sizeof(Type) + 1;
                }

                break;
            }

            case FLOAT:
            {
                typedef uint32_t Type;

                if ((size - 1) < sizeof(Type))
                    return 0;
                else
                {
                    setFloat(ntohf(*reinterpret_cast<const Type *>(buffer)));
                    size = sizeof(Type) + 1;
                }

                break;
            }

            case DOUBLE:
            {
                typedef uint64_t Type;

                if ((size - 1) < sizeof(Type))
                    return 0;
                else
                {
                    setDouble(ntohd(*reinterpret_cast<const Type *>(buffer)));
                    size = sizeof(Type) + 1;
                }
                break;
            }

            case BOOL:
            {
                typedef bool Type;

                if ((size - 1) < sizeof(Type))
                    return 0;
                else
                {
                    setBool(*reinterpret_cast<const Type *>(buffer));
                    size = sizeof(Type) + 1;
                }

                break;
            }

            case CHAR:
            {
                typedef char Type;

                if ((size - 1) < sizeof(Type))
                    return 0;
                else
                {
                    setChar(*reinterpret_cast<const Type *>(buffer));
                    size = sizeof(Type) + 1;
                }

                break;
            }

            case STRING:
            {
                typedef uint32_t Type;

                if ((size - 1) < sizeof(Type))
                    return 0;
                else
                {
                    Type len = ntohl(*reinterpret_cast<const Type *>(buffer));

                    if (len > 0 && len <= ((size - 1) - sizeof(Type)))
                        setString(reinterpret_cast<const char *>(buffer + sizeof(Type)), len);

                    size = sizeof(Type) + 1 + len;
                }

                break;
            }

            case BINARY:
            {
                typedef uint32_t Type;

                if ((size - 1) < sizeof(Type))
                    return 0;
                else
                {
                    Type len = ntohl(*reinterpret_cast<const Type *>(buffer));

                    if (len > 0 && len <= ((size - 1) - sizeof(Type)))
                        setBinary(reinterpret_cast<const unsigned char *>(buffer + sizeof(Type)), len);

                    size = sizeof(Type) + 1 + len;
                }

                break;
            }
        }

        return size;
    }

    return 0;
}
Beispiel #22
0
tmap_sff_header_t *
tmap_sff_header_read(tmap_file_t *fp)
{
  tmap_sff_header_t *h = NULL;
  uint32_t n = 0;

  h = tmap_calloc(1, sizeof(tmap_sff_header_t), "h");

  if(1 != tmap_file_fread(&h->magic, sizeof(uint32_t), 1, fp)
     || 1 != tmap_file_fread(&h->version, sizeof(uint32_t), 1, fp)
     || 1 != tmap_file_fread(&h->index_offset, sizeof(uint64_t), 1, fp)
     || 1 != tmap_file_fread(&h->index_length, sizeof(uint32_t), 1, fp)
     || 1 != tmap_file_fread(&h->n_reads, sizeof(uint32_t), 1, fp)
     || 1 != tmap_file_fread(&h->gheader_length, sizeof(uint16_t), 1, fp)
     || 1 != tmap_file_fread(&h->key_length, sizeof(uint16_t), 1, fp)
     || 1 != tmap_file_fread(&h->flow_length, sizeof(uint16_t), 1, fp)
     || 1 != tmap_file_fread(&h->flowgram_format, sizeof(uint8_t), 1, fp)) {
      tmap_error("tmap_file_fread", Exit, ReadFileError);
  }
  n += 4*sizeof(uint32_t) + sizeof(uint64_t) + 3*sizeof(uint16_t) + sizeof(uint8_t);

  // convert values from big-endian
  h->magic = ntohl(h->magic);
  h->version = ntohl(h->version);
  h->index_offset = ntohll(h->index_offset);
  h->index_length = ntohl(h->index_length);
  h->n_reads = ntohl(h->n_reads);
  h->gheader_length = ntohs(h->gheader_length);
  h->key_length = ntohs(h->key_length);
  h->flow_length = ntohs(h->flow_length);

  if(TMAP_SFF_MAGIC != h->magic) {
      tmap_error("SFF magic number did not match", Exit, ReadFileError);
  }
  if(h->version != TMAP_SFF_VERSION) {
      tmap_error("SFF version number did not match", Exit, ReadFileError);
  }

  h->flow = tmap_string_init(h->flow_length+1);
  h->key = tmap_string_init(h->key_length+1);

  if(h->flow_length != tmap_file_fread(h->flow->s, sizeof(char), h->flow_length, fp)
     || h->key_length != tmap_file_fread(h->key->s, sizeof(char), h->key_length, fp)) {
      tmap_error("tmap_file_fread", Exit, ReadFileError);
  }
  n += sizeof(char)*(h->flow_length + h->key_length);

  // set the length and null-terminator
  h->flow->l = h->flow_length;
  h->key->l = h->key_length;
  h->flow->s[h->flow->l]='\0';
  h->key->s[h->key->l]='\0';

  n += tmap_sff_read_padding(fp, n);

#ifdef TMAP_SFF_DEBUG
  tmap_sff_header_print(stderr, h);
#endif

  if(h->gheader_length != n) {
      tmap_error("SFF global header length did not match", Exit, ReadFileError);
  }

  return h;
}
Beispiel #23
0
static void
proto_session_hdr_unmarshall_sver(Proto_Session *s, Proto_StateVersion *v)
{
    v->raw = ntohll(s->rhdr.sver.raw);
}
Beispiel #24
0
uint64_t ovs_ntohll(uint64_t v) {
    return ntohll(v);
}
Beispiel #25
0
static void ssa_db_rec_tbl_load(FILE *fd, enum ssa_db_helper_mode mode,
				struct db_table_def *p_data_tbl_def,
				struct db_dataset *p_dataset, void *p_data_tbl,
				struct db_dataset *p_dataset_field,
				struct db_field_def *p_field_tbl)
{
	struct db_field_def *p_field_rec;
	uint64_t i, k, j;
	uint8_t *p_data_rec, *p_data_field;
	char c;

	if (mode != SSA_DB_HELPER_STANDARD && mode != SSA_DB_HELPER_DEBUG)
		return;

	for (i = 0; i < ntohll(p_dataset->set_count); i++) {
		p_data_rec = (uint8_t *)((uint8_t *)p_data_tbl + i * ntohl(p_data_tbl_def->record_size));
		if (mode == SSA_DB_HELPER_STANDARD) {
			for (k = 0; k < ntohl(p_data_tbl_def->record_size); k++) {
				FSCANF_SINGLE(fd, "%c", &c, i, p_data_tbl_def->name);
				memcpy(p_data_rec + k, &c, sizeof(c));
			}
		} else {
			for (k = 0; k < ntohll(p_dataset_field->set_count); k++) {
				p_field_rec = &p_field_tbl[k];
				p_data_field = p_data_rec + ntohl(p_field_rec->field_offset) / 8;

				switch (p_field_rec->type) {
				case DBF_TYPE_U8:
					for (j = 0; j < ntohl(p_field_rec->field_size) / 8; j++) {
						if (j == (ntohl(p_field_rec->field_size) / 8) - 1) {
							FSCANF_SINGLE(fd, "%" SCNu8 SSA_DB_HELPER_DELIMITER,
								      ((uint8_t *)p_data_field + j), i,
								      p_data_tbl_def->name);
						} else {
							FSCANF_SINGLE(fd, "%" SCNu8 SSA_DB_HELPER_ARRAY_DELIMITER,
								      ((uint8_t *)p_data_field + j), i,
								      p_data_tbl_def->name);
						}
					}
					break;
				case DBF_TYPE_U16:
					for (j = 0; j < ntohl(p_field_rec->field_size) / 16; j++) {
						if (j == (ntohl(p_field_rec->field_size) / 16) - 1) {
							FSCANF_SINGLE(fd, "%" SCNu16 SSA_DB_HELPER_DELIMITER,
								      ((uint16_t *)p_data_field + (j * 2)), i,
								      p_data_tbl_def->name);
						} else {
							FSCANF_SINGLE(fd, "%" SCNu16 SSA_DB_HELPER_ARRAY_DELIMITER,
								      ((uint16_t *)p_data_field + (j * 2)), i,
								      p_data_tbl_def->name);
						}
					}
					break;
				case DBF_TYPE_U32:
					for (j = 0; j < ntohl(p_field_rec->field_size) / 32; j++) {
						if (j == (ntohl(p_field_rec->field_size) / 32) - 1) {
							FSCANF_SINGLE(fd, "%" PRIx32 SSA_DB_HELPER_DELIMITER,
								      ((uint32_t *)p_data_field + (j * 4)), i,
								      p_data_tbl_def->name);
						} else {
							FSCANF_SINGLE(fd, "%" PRIx32 SSA_DB_HELPER_ARRAY_DELIMITER,
								      ((uint32_t *)p_data_field + (j * 4)), i,
								      p_data_tbl_def->name);
						}
					}
					break;
				case DBF_TYPE_U64:
					for (j = 0; j < ntohl(p_field_rec->field_size) / 64; j++) {
						if (j == (ntohl(p_field_rec->field_size) / 64) - 1) {
							FSCANF_SINGLE(fd, "0x%" PRIx64 SSA_DB_HELPER_DELIMITER,
								      ((uint64_t *)p_data_field + (j * 8)), i,
								      p_data_tbl_def->name);
						} else {
							FSCANF_SINGLE(fd, "0x%" PRIx64 SSA_DB_HELPER_ARRAY_DELIMITER,
								      ((uint64_t *)p_data_field + (j * 8)), i,
								      p_data_tbl_def->name);
						}
					}
					break;
				case DBF_TYPE_NET16:
					for (j = 0; j < ntohl(p_field_rec->field_size) / 16; j++) {
						if (j == (ntohl(p_field_rec->field_size) / 16) - 1) {
							FSCANF_SINGLE(fd, "%" SCNu16 SSA_DB_HELPER_DELIMITER,
								      ((uint16_t *)p_data_field + (j * 2)), i,
								      p_data_tbl_def->name);
						} else {
							FSCANF_SINGLE(fd, "%" SCNu16 SSA_DB_HELPER_ARRAY_DELIMITER,
								      ((uint16_t *)p_data_field + (j * 2)), i,
								      p_data_tbl_def->name);
						}
						*((uint16_t *)p_data_field + (j * 2)) =
								htons(*((uint16_t *)p_data_field + (j * 2)));
					}
					break;
				case DBF_TYPE_NET32:
					for (j = 0; j < ntohl(p_field_rec->field_size) / 32; j++) {
						if (j == (ntohl(p_field_rec->field_size) / 32) - 1) {
							FSCANF_SINGLE(fd, "%" PRIx32 SSA_DB_HELPER_DELIMITER,
								      ((uint32_t *)p_data_field + (j * 4)), i,
								      p_data_tbl_def->name);
						} else {
							FSCANF_SINGLE(fd, "%" PRIx32 SSA_DB_HELPER_ARRAY_DELIMITER,
								      ((uint32_t *)p_data_field + (j * 4)), i,
								      p_data_tbl_def->name);
						}
						*((uint32_t *)p_data_field + (j * 4)) =
								htonl(*((uint32_t *)p_data_field + (j * 4)));
					}
					break;
				case DBF_TYPE_NET64:
					for (j = 0; j < ntohl(p_field_rec->field_size) / 64; j++) {
						if (j == (ntohl(p_field_rec->field_size) / 64) - 1) {
							FSCANF_SINGLE(fd, "0x%" PRIx64 SSA_DB_HELPER_DELIMITER,
								      ((uint64_t *)p_data_field + (j * 8)), i,
								      p_data_tbl_def->name);
						} else {
							FSCANF_SINGLE(fd, "0x%" PRIx64 SSA_DB_HELPER_ARRAY_DELIMITER,
								      ((uint64_t *)p_data_field + (j * 8)), i,
								      p_data_tbl_def->name);
						}
						*((uint64_t *)p_data_field + (j * 8)) =
								htonll(*((uint64_t *)p_data_field + (j * 8)));
					}
					break;
				case DBF_TYPE_NET128:
					/* TODO: add 128 bit handling */
					break;
				case DBF_TYPE_STRING:
					FSCANF_SINGLE(fd, "%s" SSA_DB_HELPER_DELIMITER, ((char *) p_data_field), i, p_data_tbl_def->name);
					break;
				default:
					ssa_log_err(SSA_LOG_DEFAULT, "Unknown field type\n");
					break;
				}
			}
		}

		/* moving file descriptor 1 byte forward due to '\n' char at the end of line */
		fseek(fd, 1, SEEK_CUR);
	}
}
Beispiel #26
0
int main(int argc, char **argv)
{
  int pr[2];
  int sk;
  int nbd;
  int blocksize = 1024;

  char chunk[CHUNK];
  struct nbd_request request;
  struct nbd_reply reply;

  u64 size;
  u64 from;
  u32 len;
  /*  */
  int file, oldfile = -1;
  u32 offset;
  unsigned char *ptr = NULL;

  if(argc<3){
    printf("Usage: %s nbdevice gzfile\n",argv[0]);
    exit(1);
  }

  /* memory for one decompressed block */
  all = malloc(1024*88064);

  if(argc == 3){
    int nb, fid;
    char buf[512];

    /* find an approximate size */
    for (nb = 0; ; nb++) {
      sprintf(buf, "%s%03d", argv[2], nb);
      if ((fid=open(buf, O_RDONLY)) == -1) {
        break;
      }
      close(fid);
    }
    if (nb == 0) {
      fprintf(stderr,"%s: unable open compressed file %s\n",argv[0], buf);
      exit(1);
    }
    size = (u64)88064*(u64)1024*nb;
  } else {
    exit(1);
  }

  if(socketpair(AF_UNIX, SOCK_STREAM, 0, pr)){
    fprintf(stderr,"%s: unable to create socketpair: %s\n",argv[0],strerror(errno));
    exit(1);
  }

  switch(fork()){
  case -1 :
    fprintf(stderr,"%s: unable to fork: %s\n",argv[0],strerror(errno));
    exit(1);
    break;

  case 0 : /* child */
    close(pr[0]);

    sk=pr[1];

    nbd=open(argv[1], O_RDWR);
    if(nbd<0){
      fprintf(stderr,"%s: unable to open %s: %s\n",argv[0],argv[1],strerror(errno));
      exit(1);
    }

    if (ioctl(nbd, NBD_SET_BLKSIZE, (unsigned long)blocksize) < 0) {
      fprintf(stderr, "NBD_SET_BLKSIZE failed\n");
      exit(1);
    }

    if ((ioctl(nbd, NBD_SET_SIZE_BLOCKS, (unsigned long)(size/blocksize))) < 0) {
      fprintf(stderr, "NBD_SET_SIZE_BLOKS failed\n");
      exit(1);
    }

    ioctl(nbd, NBD_CLEAR_SOCK);

    if(ioctl(nbd,NBD_SET_SOCK,sk)<0){
      fprintf(stderr,"%s: failed to set socket for %s: %s\n",argv[0],argv[1],strerror(errno));
      exit(1);
    }

    if(ioctl(nbd,NBD_DO_IT)<0){
      fprintf(stderr,"%s: block device %s terminated: %s\n",argv[0],argv[1],strerror(errno));
    }

    ioctl(nbd, NBD_CLEAR_QUE);
    ioctl(nbd, NBD_CLEAR_SOCK);

    exit(0);

    break;
  }

  /* only parent here, child always exits */

  close(pr[1]);
  sk=pr[0];

  reply.magic=htonl(NBD_REPLY_MAGIC);
  reply.error=htonl(0);

  BUFFER = malloc(24064);
  Bitmap = malloc(24064 - 2048);
  IN = malloc(INSIZE);

  sleep(1);

  while(1){

    if(read(sk,&request,sizeof(request))!=sizeof(request)){
      fprintf(stderr,"%s: incomplete request\n",argv[0]);
    }

    memcpy(reply.handle,request.handle,sizeof(reply.handle));

    len=ntohl(request.len);
    from=ntohll(request.from);

#ifdef TRACE
    fprintf(stderr,"%s: len=%d, from=%Ld\n",argv[0],len,from);
#endif

    if(request.magic!=htonl(NBD_REQUEST_MAGIC)){
      fprintf(stderr,"%s: bad magic\n",argv[0]);
      reply.error=htonl(EIO); /* is that the right way of doing things ? */
    }

    /* write resquest */
    if(ntohl(request.type) == 1){
      // fprintf(stderr,"%s: unsupported write request (len=%d)\n",argv[0], len);
      readit(sk, chunk, len);
      /* fake write */
      reply.error=htonl(0);
      len = 0;
      memcpy(chunk,&reply,sizeof(struct nbd_reply));
      if(write(sk,chunk,len+sizeof(struct nbd_reply))!=(len+sizeof(struct nbd_reply))){
        fprintf(stderr,"%s: write failed: %s\n",argv[0],strerror(errno));
      }
      continue;
    }

    /* disc request */
    if(ntohl(request.type) == 2){
      fprintf(stderr,"%s: unsupported disc request\n",argv[0]);
      reply.error=htonl(EROFS);
    }

    if(len+sizeof(struct nbd_reply)>CHUNK){
      fprintf(stderr,"%s: request too long (%d)\n",argv[0], len+sizeof(struct nbd_reply));
      //reply.error=htonl(EIO);
    }

    /* read request */
    if(reply.error==htonl(0)){
      int remain = len;
      int offset2 = 0;

      /* which chunk to open */
      file = from / (88064*1024);
      offset = from % (88064*1024);

      while (remain > 0) {
        u32 cpylen;

        if (oldfile != file) {
          decompress_file(argv[2], file, offset);
          oldfile = file;
        }

        ptr = &all[offset];

        if (offset + remain >= 88064*1024) {
          /* request on a block boundary */
          cpylen = (88064*1024)-offset;
          remain -= cpylen;
          file++;
          offset = 0;
        } else {
          /* request within a block */
          cpylen = remain;
          remain = 0;
        }

        /* copy the data */
        memcpy(chunk+sizeof(struct nbd_reply)+offset2, ptr, cpylen);
        offset2 += cpylen;
      }
    } else {
      len=0;
    }

    /* copy the reply header */
    memcpy(chunk,&reply,sizeof(struct nbd_reply));
    /* send data to kernel */
    if(write(sk,chunk,len+sizeof(struct nbd_reply))!=(len+sizeof(struct nbd_reply))){
      fprintf(stderr,"%s: write failed: %s\n",argv[0],strerror(errno));
    }
  }

  exit(0);
}
Beispiel #27
0
bool read_literals(char *oldpos, size_t size, Header* h)
{
	int i, j;
	int n = 0;
	char type;
	uint32_t str_length;
	uint32_t ref;
	char *startpos = oldpos + h->size * 4;
	char *curpos = startpos;
	while (!eofreached)
	{
		type = *curpos++;
		if (eofreached)
		{
			break;
		}
		n++;
		switch (type)
		{
			case TYPE_NUM:
				curpos += 8;
				break;
			case TYPE_NUM | TYPE_SHORT:
				curpos += 3;
				break;
			case TYPE_STR:
			case TYPE_IDENT:
				memcpy(&str_length, curpos, 4);
				curpos += 4 + ntohl(str_length);
				break;
			case TYPE_STR | TYPE_SHORT:
			case TYPE_IDENT | TYPE_SHORT:
				str_length = (unsigned char)*curpos++;
				curpos += str_length;
				break;
			case TYPE_PAIR:
				curpos += 6;
				break;
			case TYPE_FRAC:
				curpos += 16;
				break;
			case TYPE_FRAC | TYPE_SHORT:
				curpos += 2;
				break;
			case TYPE_LIST:
				memcpy(&str_length, curpos, 4);
				curpos += 4 + 3 * ntohl(str_length);
				break;
			case TYPE_DICT:
				memcpy(&str_length, curpos, 4);
				curpos += 4 + 6 * ntohl(str_length);
				break;
		}
	}
	V* arr = calloc(n, sizeof(V));
	V t;
	curpos = startpos;
	for (i = 0; i < n; i++)
	{
		type = *curpos++;
		if (type == TYPE_NUM)
		{
			union double_or_uint64_t d;
			memcpy(&d, curpos, 8);
			curpos += 8;
			d.i = ntohll(d.i);
			t = double_to_value(d.d);
		}
		else if (type == (TYPE_NUM | TYPE_SHORT))
		{
			ref = 0;
			memcpy(((char*)&ref) + 1, curpos, 3);
			ref = ntohl(ref);
			curpos += 3;
			t = int_to_value(ref);
		}
		else if (type == TYPE_STR)
		{
			memcpy(&str_length, curpos, 4);
			curpos += 4;
			str_length = ntohl(str_length);
			if (!valid_utf8(str_length, curpos))
			{
				set_error_msg("wrong encoding for string literal, should be UTF-8");
				return false;
			}
			t = str_to_string(str_length, curpos);
			curpos += str_length;
		}
		else if (type == TYPE_IDENT)
		{
			memcpy(&str_length, curpos, 4);
			curpos += 4;
			str_length = ntohl(str_length);
			char data[str_length + 1];
			memcpy(&data, curpos, str_length);
			data[str_length] = '\0';
			t = lookup_ident(str_length, data);
			curpos += str_length;
		}
		else if (type == (TYPE_STR | TYPE_SHORT))
		{
			str_length = (unsigned char)*curpos++;
			if (!valid_utf8(str_length, curpos))
			{
				set_error_msg("wrong encoding for string literal, should be UTF-8");
				return false;
			}
			t = str_to_string(str_length, curpos);
			curpos += str_length;
		}
		else if (type == (TYPE_IDENT | TYPE_SHORT))
		{
			str_length = *curpos++;
			char data[str_length + 1];
			memcpy(&data, curpos, str_length);
			data[str_length] = '\0';
			t = lookup_ident(str_length, data);
			curpos += str_length;
		}
		else if (type == TYPE_PAIR)
		{
			ref = 0;
			memcpy(((char*)&ref) + 1, curpos, 3);
			ref = ntohl(ref);
			if (ref >= i)
			{
				set_error_msg("illegal pair detected");
				return false;
			}
			V v1 = arr[ref];

			ref = 0;
			memcpy(((char*)&ref) + 1, curpos + 3, 3);
			ref = ntohl(ref);
			if (ref >= i)
			{
				set_error_msg("illegal pair detected");
				return false;
			}
			V v2 = arr[ref];

			t = new_pair(v1, v2);
			curpos += 6;
		}
		else if (type == TYPE_FRAC)
		{
			int64_t numer;
			int64_t denom;
			memcpy(&numer, curpos, 8);
			numer = ntohll(numer);
			memcpy(&denom, curpos + 8, 8);
			denom = ntohll(denom);
			t = new_frac(numer, denom);
			curpos += 16;
		}
		else if (type == (TYPE_FRAC | TYPE_SHORT))
		{
			int8_t numer;
			uint8_t denom;
			numer = *curpos++;
			denom = *curpos++;
			t = new_frac(numer, denom);
		}
		else if (type == TYPE_LIST)
		{
			memcpy(&str_length, curpos, 4);
			str_length = ntohl(str_length);
			t = new_list();
			curpos += 4;
			if (str_length > 0)
			{
				uint32_t size = 64;
				while (size < str_length) size <<= 1;
				toStack(t)->size = size;
				toStack(t)->used = str_length;
				toStack(t)->nodes = calloc(size, sizeof(V));
				for (j = 0; j < str_length; j++)
				{
					ref = 0;
					memcpy(((char*)&ref) + 1, curpos, 3);
					ref = ntohl(ref);
					toStack(t)->nodes[j] = intToV((uint64_t)ref);
					curpos += 3;
				}
			}
		}
		else if (type == TYPE_DICT)
		{
			memcpy(&str_length, curpos, 4);
			curpos += 4;
			str_length = ntohl(str_length);
			t = new_dict();
			if (str_length > 0)
			{
				uint32_t size = 16;
				while (size < str_length) size <<= 1;
				toHashMap(t)->size = size;
				toHashMap(t)->used = str_length;
				toHashMap(t)->map = (Bucket**)curpos;
			}
			curpos += 6 * str_length;
		}
		else
		{
			set_error_msg("Unknown literal type.");
			return false;
		}
		arr[i] = t;
	}

	for (i = 0; i < n; i++)
	{
		t = arr[i];
		switch(getType(t))
		{
			case TYPE_LIST:
				for (j = 0; j < toStack(t)->used; j++)
				{
					toStack(t)->nodes[j] = arr[toInt(toStack(t)->nodes[j])];
				}
				break;
			case TYPE_DICT:
				if (toHashMap(t)->map)
				{
					curpos = ((char*)toHashMap(t)->map);

					toHashMap(t)->map = NULL;
					str_length = toHashMap(t)->used; //worst abuse of variable name ever Y/Y?
					toHashMap(t)->used = 0;
					for (j = 0; j < str_length; j++)
					{
						ref = 0;
						memcpy(((char*)&ref) + 1, curpos, 3);
						ref = ntohl(ref);
						V key = arr[ref];

						ref = 0;
						memcpy(((char*)&ref) + 1, curpos + 3, 3);
						ref = ntohl(ref);
						V value = arr[ref];

						set_hashmap(toHashMap(t), key, value);

						curpos += 6;
					}
				}
				break;
		}
	}

	h->n_literals = n;
	h->literals = arr;
	return true;
}
Beispiel #28
0
Variant binary_deserialize(int8_t thrift_typeID, PHPInputTransport& transport,
                           CArrRef fieldspec) {
  Variant ret;
  switch (thrift_typeID) {
    case T_STOP:
    case T_VOID:
      return uninit_null();
    case T_STRUCT: {
      Variant val;
      if ((val = fieldspec.rvalAt(PHPTransport::s_class)).isNull()) {
        throw_tprotocolexception("no class type in spec", INVALID_DATA);
        skip_element(T_STRUCT, transport);
        return uninit_null();
      }
      String structType = val.toString();
      ret = createObject(structType);
      if (ret.isNull()) {
        // unable to create class entry
        skip_element(T_STRUCT, transport);
        return uninit_null();
      }
      Variant spec = f_hphp_get_static_property(structType, s_TSPEC, false);
      if (!spec.is(KindOfArray)) {
        char errbuf[128];
        snprintf(errbuf, 128, "spec for %s is wrong type: %d\n",
                 structType.data(), ret.getType());
        throw_tprotocolexception(String(errbuf, CopyString), INVALID_DATA);
        return uninit_null();
      }
      binary_deserialize_spec(ret.toObject(), transport, spec.toArray());
      return ret;
    } break;
    case T_BOOL: {
      uint8_t c;
      transport.readBytes(&c, 1);
      return c != 0;
    }
  //case T_I08: // same numeric value as T_BYTE
    case T_BYTE: {
      uint8_t c;
      transport.readBytes(&c, 1);
      return Variant((int8_t)c);
    }
    case T_I16: {
      uint16_t c;
      transport.readBytes(&c, 2);
      return Variant((int16_t)ntohs(c));
    }
    case T_I32: {
      uint32_t c;
      transport.readBytes(&c, 4);
      return Variant((int32_t)ntohl(c));
    }
    case T_U64:
    case T_I64: {
      uint64_t c;
      transport.readBytes(&c, 8);
      return Variant((int64_t)ntohll(c));
    }
    case T_DOUBLE: {
      union {
        uint64_t c;
        double d;
      } a;
      transport.readBytes(&(a.c), 8);
      a.c = ntohll(a.c);
      return a.d;
    }
    case T_FLOAT: {
      union {
        uint32_t c;
        float d;
      } a;
      transport.readBytes(&(a.c), 4);
      a.c = ntohl(a.c);
      return a.d;
    }
    //case T_UTF7: // aliases T_STRING
    case T_UTF8:
    case T_UTF16:
    case T_STRING: {
      uint32_t size = transport.readU32();
      if (size && (size + 1)) {
        String s = String(size, ReserveString);
        char* strbuf = s.bufferSlice().ptr;
        transport.readBytes(strbuf, size);
        return s.setSize(size);
      } else {
        return "";
      }
    }
    case T_MAP: { // array of key -> value
      uint8_t types[2];
      transport.readBytes(types, 2);
      uint32_t size = transport.readU32();

      Array keyspec = fieldspec.rvalAt(PHPTransport::s_key,
                                       AccessFlags::Error_Key).toArray();
      Array valspec = fieldspec.rvalAt(PHPTransport::s_val,
                                       AccessFlags::Error_Key).toArray();
      ret = Array::Create();

      for (uint32_t s = 0; s < size; ++s) {
        Variant key = binary_deserialize(types[0], transport, keyspec);
        Variant value = binary_deserialize(types[1], transport, valspec);
        ret.set(key, value);
      }
      return ret; // return_value already populated
    }
    case T_LIST: { // array with autogenerated numeric keys
      int8_t type = transport.readI8();
      uint32_t size = transport.readU32();
      Variant elemvar = fieldspec.rvalAt(PHPTransport::s_elem,
                                         AccessFlags::Error_Key);
      Array elemspec = elemvar.toArray();
      ret = Array::Create();

      for (uint32_t s = 0; s < size; ++s) {
        Variant value = binary_deserialize(type, transport, elemspec);
        ret.append(value);
      }
      return ret;
    }
    case T_SET: { // array of key -> TRUE
      uint8_t type;
      uint32_t size;
      transport.readBytes(&type, 1);
      transport.readBytes(&size, 4);
      size = ntohl(size);
      Variant elemvar = fieldspec.rvalAt(PHPTransport::s_elem,
                                         AccessFlags::Error_Key);
      Array elemspec = elemvar.toArray();
      ret = Array::Create();

      for (uint32_t s = 0; s < size; ++s) {
        Variant key = binary_deserialize(type, transport, elemspec);

        if (key.isInteger()) {
          ret.set(key, true);
        } else {
          ret.set(key.toString(), true);
        }
      }
      return ret;
    }
  };

  char errbuf[128];
  sprintf(errbuf, "Unknown thrift typeID %d", thrift_typeID);
  throw_tprotocolexception(String(errbuf, CopyString), INVALID_DATA);
  return uninit_null();
}
Beispiel #29
0
/* Appends a string representation of 'match' to 's'.  If 'priority' is
 * different from OFP_DEFAULT_PRIORITY, includes it in 's'. */
void
match_format(const struct match *match, struct ds *s, unsigned int priority)
{
    const struct flow_wildcards *wc = &match->wc;
    size_t start_len = s->length;
    const struct flow *f = &match->flow;
    bool skip_type = false;
    bool skip_proto = false;

    int i;

    BUILD_ASSERT_DECL(FLOW_WC_SEQ == 20);

    if (priority != OFP_DEFAULT_PRIORITY) {
        ds_put_format(s, "priority=%u,", priority);
    }

    if (wc->masks.skb_mark) {
        ds_put_format(s, "skb_mark=%#"PRIx32",", f->skb_mark);
    }

    if (wc->masks.skb_priority) {
        ds_put_format(s, "skb_priority=%#"PRIx32",", f->skb_priority);
    }

    if (wc->masks.dl_type) {
        skip_type = true;
        if (f->dl_type == htons(ETH_TYPE_IP)) {
            if (wc->masks.nw_proto) {
                skip_proto = true;
                if (f->nw_proto == IPPROTO_ICMP) {
                    ds_put_cstr(s, "icmp,");
                } else if (f->nw_proto == IPPROTO_TCP) {
                    ds_put_cstr(s, "tcp,");
                } else if (f->nw_proto == IPPROTO_UDP) {
                    ds_put_cstr(s, "udp,");
                } else {
                    ds_put_cstr(s, "ip,");
                    skip_proto = false;
                }
            } else {
                ds_put_cstr(s, "ip,");
            }
        } else if (f->dl_type == htons(ETH_TYPE_IPV6)) {
            if (wc->masks.nw_proto) {
                skip_proto = true;
                if (f->nw_proto == IPPROTO_ICMPV6) {
                    ds_put_cstr(s, "icmp6,");
                } else if (f->nw_proto == IPPROTO_TCP) {
                    ds_put_cstr(s, "tcp6,");
                } else if (f->nw_proto == IPPROTO_UDP) {
                    ds_put_cstr(s, "udp6,");
                } else {
                    ds_put_cstr(s, "ipv6,");
                    skip_proto = false;
                }
            } else {
                ds_put_cstr(s, "ipv6,");
            }
        } else if (f->dl_type == htons(ETH_TYPE_ARP)) {
            ds_put_cstr(s, "arp,");
        } else if (f->dl_type == htons(ETH_TYPE_RARP)) {
            ds_put_cstr(s, "rarp,");
        } else if (f->dl_type == htons(ETH_TYPE_MPLS)) {
            ds_put_cstr(s, "mpls,");
        } else if (f->dl_type == htons(ETH_TYPE_MPLS_MCAST)) {
            ds_put_cstr(s, "mplsm,");
        } else {
            skip_type = false;
        }
    }
    for (i = 0; i < FLOW_N_REGS; i++) {
        switch (wc->masks.regs[i]) {
        case 0:
            break;
        case UINT32_MAX:
            ds_put_format(s, "reg%d=0x%"PRIx32",", i, f->regs[i]);
            break;
        default:
            ds_put_format(s, "reg%d=0x%"PRIx32"/0x%"PRIx32",",
                          i, f->regs[i], wc->masks.regs[i]);
            break;
        }
    }

    format_flow_tunnel(s, match);

    switch (wc->masks.metadata) {
    case 0:
        break;
    case CONSTANT_HTONLL(UINT64_MAX):
        ds_put_format(s, "metadata=%#"PRIx64",", ntohll(f->metadata));
        break;
    default:
        ds_put_format(s, "metadata=%#"PRIx64"/%#"PRIx64",",
                      ntohll(f->metadata), ntohll(wc->masks.metadata));
        break;
    }
    if (wc->masks.in_port) {
        ds_put_cstr(s, "in_port=");
        ofputil_format_port(f->in_port, s);
        ds_put_char(s, ',');
    }
    if (wc->masks.vlan_tci) {
        ovs_be16 vid_mask = wc->masks.vlan_tci & htons(VLAN_VID_MASK);
        ovs_be16 pcp_mask = wc->masks.vlan_tci & htons(VLAN_PCP_MASK);
        ovs_be16 cfi = wc->masks.vlan_tci & htons(VLAN_CFI);

        if (cfi && f->vlan_tci & htons(VLAN_CFI)
            && (!vid_mask || vid_mask == htons(VLAN_VID_MASK))
            && (!pcp_mask || pcp_mask == htons(VLAN_PCP_MASK))
            && (vid_mask || pcp_mask)) {
            if (vid_mask) {
                ds_put_format(s, "dl_vlan=%"PRIu16",",
                              vlan_tci_to_vid(f->vlan_tci));
            }
            if (pcp_mask) {
                ds_put_format(s, "dl_vlan_pcp=%d,",
                              vlan_tci_to_pcp(f->vlan_tci));
            }
        } else if (wc->masks.vlan_tci == htons(0xffff)) {
            ds_put_format(s, "vlan_tci=0x%04"PRIx16",", ntohs(f->vlan_tci));
        } else {
            ds_put_format(s, "vlan_tci=0x%04"PRIx16"/0x%04"PRIx16",",
                          ntohs(f->vlan_tci), ntohs(wc->masks.vlan_tci));
        }
    }
    format_eth_masked(s, "dl_src", f->dl_src, wc->masks.dl_src);
    format_eth_masked(s, "dl_dst", f->dl_dst, wc->masks.dl_dst);
    if (!skip_type && wc->masks.dl_type) {
        ds_put_format(s, "dl_type=0x%04"PRIx16",", ntohs(f->dl_type));
    }
    if (f->dl_type == htons(ETH_TYPE_IPV6)) {
        format_ipv6_netmask(s, "ipv6_src", &f->ipv6_src, &wc->masks.ipv6_src);
        format_ipv6_netmask(s, "ipv6_dst", &f->ipv6_dst, &wc->masks.ipv6_dst);
        if (wc->masks.ipv6_label) {
            if (wc->masks.ipv6_label == htonl(UINT32_MAX)) {
                ds_put_format(s, "ipv6_label=0x%05"PRIx32",",
                              ntohl(f->ipv6_label));
            } else {
                ds_put_format(s, "ipv6_label=0x%05"PRIx32"/0x%05"PRIx32",",
                              ntohl(f->ipv6_label),
                              ntohl(wc->masks.ipv6_label));
            }
        }
    } else if (f->dl_type == htons(ETH_TYPE_ARP) ||
               f->dl_type == htons(ETH_TYPE_RARP)) {
        format_ip_netmask(s, "arp_spa", f->nw_src, wc->masks.nw_src);
        format_ip_netmask(s, "arp_tpa", f->nw_dst, wc->masks.nw_dst);
    } else {
        format_ip_netmask(s, "nw_src", f->nw_src, wc->masks.nw_src);
        format_ip_netmask(s, "nw_dst", f->nw_dst, wc->masks.nw_dst);
    }
    if (!skip_proto && wc->masks.nw_proto) {
        if (f->dl_type == htons(ETH_TYPE_ARP) ||
            f->dl_type == htons(ETH_TYPE_RARP)) {
            ds_put_format(s, "arp_op=%"PRIu8",", f->nw_proto);
        } else {
            ds_put_format(s, "nw_proto=%"PRIu8",", f->nw_proto);
        }
    }
    if (f->dl_type == htons(ETH_TYPE_ARP) ||
        f->dl_type == htons(ETH_TYPE_RARP)) {
        format_eth_masked(s, "arp_sha", f->arp_sha, wc->masks.arp_sha);
        format_eth_masked(s, "arp_tha", f->arp_tha, wc->masks.arp_tha);
    }
    if (wc->masks.nw_tos & IP_DSCP_MASK) {
        ds_put_format(s, "nw_tos=%"PRIu8",", f->nw_tos & IP_DSCP_MASK);
    }
    if (wc->masks.nw_tos & IP_ECN_MASK) {
        ds_put_format(s, "nw_ecn=%"PRIu8",", f->nw_tos & IP_ECN_MASK);
    }
    if (wc->masks.nw_ttl) {
        ds_put_format(s, "nw_ttl=%"PRIu8",", f->nw_ttl);
    }
    if (wc->masks.mpls_lse & htonl(MPLS_LABEL_MASK)) {
        ds_put_format(s, "mpls_label=%"PRIu32",",
                 mpls_lse_to_label(f->mpls_lse));
    }
    if (wc->masks.mpls_lse & htonl(MPLS_TC_MASK)) {
        ds_put_format(s, "mpls_tc=%"PRIu8",",
                 mpls_lse_to_tc(f->mpls_lse));
    }
    if (wc->masks.mpls_lse & htonl(MPLS_TTL_MASK)) {
        ds_put_format(s, "mpls_ttl=%"PRIu8",",
                 mpls_lse_to_ttl(f->mpls_lse));
    }
    if (wc->masks.mpls_lse & htonl(MPLS_BOS_MASK)) {
        ds_put_format(s, "mpls_bos=%"PRIu8",",
                 mpls_lse_to_bos(f->mpls_lse));
    }
    switch (wc->masks.nw_frag) {
    case FLOW_NW_FRAG_ANY | FLOW_NW_FRAG_LATER:
        ds_put_format(s, "nw_frag=%s,",
                      f->nw_frag & FLOW_NW_FRAG_ANY
                      ? (f->nw_frag & FLOW_NW_FRAG_LATER ? "later" : "first")
                      : (f->nw_frag & FLOW_NW_FRAG_LATER ? "<error>" : "no"));
        break;

    case FLOW_NW_FRAG_ANY:
        ds_put_format(s, "nw_frag=%s,",
                      f->nw_frag & FLOW_NW_FRAG_ANY ? "yes" : "no");
        break;

    case FLOW_NW_FRAG_LATER:
        ds_put_format(s, "nw_frag=%s,",
                      f->nw_frag & FLOW_NW_FRAG_LATER ? "later" : "not_later");
        break;
    }
    if (f->dl_type == htons(ETH_TYPE_IP) &&
        f->nw_proto == IPPROTO_ICMP) {
        format_be16_masked(s, "icmp_type", f->tp_src, wc->masks.tp_src);
        format_be16_masked(s, "icmp_code", f->tp_dst, wc->masks.tp_dst);
    } else if (f->dl_type == htons(ETH_TYPE_IPV6) &&
               f->nw_proto == IPPROTO_ICMPV6) {
        format_be16_masked(s, "icmp_type", f->tp_src, wc->masks.tp_src);
        format_be16_masked(s, "icmp_code", f->tp_dst, wc->masks.tp_dst);
        format_ipv6_netmask(s, "nd_target", &f->nd_target,
                            &wc->masks.nd_target);
        format_eth_masked(s, "nd_sll", f->arp_sha, wc->masks.arp_sha);
        format_eth_masked(s, "nd_tll", f->arp_tha, wc->masks.arp_tha);
    } else {
        format_be16_masked(s, "tp_src", f->tp_src, wc->masks.tp_src);
        format_be16_masked(s, "tp_dst", f->tp_dst, wc->masks.tp_dst);
    }

    if (s->length > start_len && ds_last(s) == ',') {
        s->length--;
    }
}
Beispiel #30
0
void speed_test_rx(struct etherate *eth)
{

    int16_t tx_ret = 0;
    int16_t rx_len = 0;

    // Wait for the first test frame to be received before starting the test loop
    uint8_t first_frame = false;
    while (!first_frame)
    {

        rx_len = recv(eth->intf.sock_fd, eth->frm.rx_buffer,
                      eth->params.f_size_total, MSG_PEEK);

        // Check if this is an Etherate test frame
        if (ntohl(*eth->frm.rx_tlv_value) == VALUE_TEST_SUB_TLV &&
            ntohs(*eth->frm.rx_sub_tlv_type) == TYPE_FRAMEINDEX)
        {

            first_frame = true;

        }  else {

           // If the frame is not an Etherate frame it needs to be
           // "consumed" otherwise the next MSG_PEEK will show the
           // same frame:
           rx_len = recv(eth->intf.sock_fd, eth->frm.rx_buffer,
                         eth->params.f_size_total, MSG_DONTWAIT);

        }

    }

    clock_gettime(CLOCK_MONOTONIC_RAW, &eth->params.elapsed_time);

    // Rx test loop
    while (*eth->speed_test.testBase <= *eth->speed_test.testMax)
    {

        clock_gettime(CLOCK_MONOTONIC_RAW, &eth->params.current_time);

        // If one second has passed
        if ((eth->params.current_time.tv_sec - eth->params.elapsed_time.tv_sec) >= 1)
        {
            eth->params.s_elapsed += 1;
            eth->speed_test.b_speed   = (double)(eth->speed_test.b_rx - eth->speed_test.b_rx_prev) * 8 / 1000000;
            eth->speed_test.b_rx_prev = eth->speed_test.b_rx;
            eth->speed_test.f_speed   = (eth->params.f_rx_count - eth->params.f_rx_count_prev);
            eth->params.f_rx_count_prev = eth->params.f_rx_count;

            printf("%" PRIu64 "\t\t%.2f\t\t%" PRIu64 "\t\t%" PRIu64 "\t\t%" PRIu64 "\n",
                   eth->params.s_elapsed,
                   eth->speed_test.b_speed,
                   (eth->speed_test.b_rx / 1024) / 1024,
                   (eth->speed_test.f_speed),
                   eth->params.f_rx_count);

            if (eth->speed_test.b_speed > eth->speed_test.b_speed_max)
                eth->speed_test.b_speed_max = eth->speed_test.b_speed;

            if (eth->speed_test.f_speed > eth->speed_test.f_speed_max)
                eth->speed_test.f_speed_max = eth->speed_test.f_speed;

            eth->speed_test.b_speed_avg += eth->speed_test.b_speed;
            eth->speed_test.f_speed_avg += eth->speed_test.f_speed;
            eth->params.elapsed_time.tv_sec = eth->params.current_time.tv_sec;
            eth->params.elapsed_time.tv_nsec = eth->params.current_time.tv_nsec;

        }

        // Poll has been disabled in favour of a non-blocking recv (for now)
        rx_len = recv(eth->intf.sock_fd,
                      eth->frm.rx_buffer,
                      eth->params.f_size_total,
                      MSG_DONTWAIT);

        if (rx_len > 0)
        {

            // Check if this is an Etherate test frame
            if (likely(ntohl(*eth->frm.rx_tlv_value) == VALUE_TEST_SUB_TLV &&
                ntohs(*eth->frm.rx_sub_tlv_type) == TYPE_FRAMEINDEX))
            {

                // If a VLAN tag is used Linux helpfully strips it off
                if (eth->frm.vlan_id != VLAN_ID_DEF) rx_len += 4;

                // Update test stats
                eth->params.f_rx_count += 1;
                eth->speed_test.b_rx += rx_len;

                // Record if the frame is in-order, early or late
                if (likely(ntohll(*eth->frm.rx_sub_tlv_value) == eth->params.f_rx_count)) {
                    eth->params.f_rx_ontime  += 1;
                } else if (ntohll(*eth->frm.rx_sub_tlv_value) > eth->params.f_rx_count) {
                    eth->params.f_rx_early   += 1;
                } else if (ntohll(*eth->frm.rx_sub_tlv_value) < eth->params.f_rx_count) {
                    eth->params.f_rx_late    += 1;
                }

                // If running in ACK mode Rx needs to ACK to Tx host
                if (eth->params.f_ack)
                {

                    build_sub_tlv(&eth->frm, htons(TYPE_ACKINDEX),
                                  *eth->frm.rx_sub_tlv_value);

                    tx_ret = send(eth->intf.sock_fd,
                                  eth->frm.tx_buffer,
                                  eth->params.f_size_total,
                                  MSG_DONTWAIT);

                    if (tx_ret > 0)
                    {
                        eth->params.f_tx_count += 1;
                    } else {

                        if (errno != EAGAIN || errno != EWOULDBLOCK)
                        {
                            perror("Speed test Tx error ");
                            return;
                        }
                        
                    }

                    
                }

            } else {
                // Received a non-test frame
                eth->params.f_rx_other += 1;
            }

            // Check if Tx host has quit/died;
            if (unlikely(ntohl(*eth->frm.rx_tlv_value) == VALUE_DYINGGASP))
            {

                printf("\nTx host has quit\n");
                speed_test_results(eth);
                return;

            }
                  

        } else { // rx_len <= 0
            if (errno != EAGAIN || errno != EWOULDBLOCK)
                perror("Speed test Rx error ");
        }


    } // *testBase<=*testMax

}