static inline bool
extract_uint64(serial_context *ser_cont, uint64_t *value)
{
	uint32_t in1, in2;

	if (!extract_uint32(ser_cont, &in1) || !extract_uint32(ser_cont, &in2)) {
		err("Error while reading 64-bit value");
		return false;
	}

	*value = (uint64_t)in1 << 32 | in2;
	return true;
}
static int extract_ping_reply_tsreply(uint8_t *buf, uint32_t *off,
				      const uint32_t len,
				      scamper_ping_reply_tsreply_t **out,
				      void *param)
{
  scamper_ping_reply_tsreply_t *tsreply;
  if(len - *off < 12)
    return -1;
  if((tsreply = scamper_ping_reply_tsreply_alloc()) == NULL)
    return -1;
  extract_uint32(buf, off, len, &tsreply->tso, NULL);
  extract_uint32(buf, off, len, &tsreply->tsr, NULL);
  extract_uint32(buf, off, len, &tsreply->tst, NULL);
  *out = tsreply;
  return 0;
}
static int extract_ping_reply_v4ts(const uint8_t *buf, uint32_t *off,
				   const uint32_t len,
				   scamper_ping_reply_v4ts_t **out,
				   void *param)
{
  scamper_addr_t *addr;
  uint8_t i, tsc, ipc;
  uint32_t u32;

  if(len - *off < 2)
    return -1;

  tsc = buf[(*off)++];
  ipc = buf[(*off)++];

  if((*out = scamper_ping_reply_v4ts_alloc(tsc, ipc)) == NULL)
    return -1;

  for(i=0; i<tsc; i++)
    {
      if(extract_uint32(buf, off, len, &u32, NULL) != 0)
	return -1;
      (*out)->tss[i] = u32;
    }

  for(i=0; i<ipc; i++)
    {
      if(extract_addr(buf, off, len, &addr, param) != 0)
	return -1;
      (*out)->ips[i] = addr;
    }

  return 0;
}
bool
GET_LIST_SIZE(serial_context *ser_cont, uint32_t *size)
{
	int32_t type = READ_CHAR(ser_cont->fd, ser_cont->line_no, ser_cont->col_no, ser_cont->bytes);

	if (type == EOF) {
		err("Error while reading list type");
		return false;
	}

	if (type == 0xdc) {
		uint16_t tmp;

		if (!extract_uint16(ser_cont, &tmp)) {
			err("Error while reading 16-bit list size");
			return false;
		}

		*size = tmp;
		return true;
	}

	if (type == 0xdd) {
		uint32_t tmp;

		if (!extract_uint32(ser_cont, &tmp)) {
			err("Error while reading 32-bit list size");
			return false;
		}

		*size = tmp;
		return true;
	}

	if ((type & 0xf0) == 0x90) {
		*size = type & 0x0f;
		return true;
	}

	err("Serialized value is not a list");
	return false;
}
int scamper_file_warts_tbit_read(scamper_file_t *sf, const warts_hdr_t *hdr,
				 scamper_tbit_t **tbit_out)
{
  scamper_tbit_t *tbit = NULL;
  warts_addrtable_t table;
  warts_state_t *state = scamper_file_getstate(sf);
  uint8_t *buf = NULL;
  uint16_t junk16;
  uint32_t junk32;
  uint32_t off = 0;
  uint32_t i;

  memset(&table, 0, sizeof(table));

  /* Read in the header */
  if(warts_read(sf, &buf, hdr->len) != 0)
    {
      goto err;
    }

  if(buf == NULL)
    {
      *tbit_out = NULL;
      return 0;
    }

  /* Allocate space for a tbit object */
  if((tbit = scamper_tbit_alloc()) == NULL)
    {
      goto err;
    }

  /* Read in the tbit data from the warts file */
  if(warts_tbit_params_read(tbit, &table, state, buf, &off, hdr->len) != 0)
    {
      goto err;
    }

  switch(tbit->type)
    {
    case SCAMPER_TBIT_TYPE_PMTUD:
      if((tbit->data = scamper_tbit_pmtud_alloc()) == NULL)
	goto err;
      break;

    case SCAMPER_TBIT_TYPE_NULL:
      if((tbit->data = scamper_tbit_null_alloc()) == NULL)
	goto err;
      break;
    }

  /* Determine how many tbit_pkts to read */
  if(tbit->pktc > 0)
    {
      /* Allocate the tbit_pkts array */
      if(scamper_tbit_pkts_alloc(tbit, tbit->pktc) != 0)
	goto err;

      /* For each tbit packet, read it and insert it into the tbit structure */
      for(i=0; i<tbit->pktc; i++)
        {
	  tbit->pkts[i] = warts_tbit_pkt_read(state, buf, &off, hdr->len);
	  if(tbit->pkts[i] == NULL)
	    goto err;
        }
    }

  for(;;)
    {
      if(extract_uint16(buf, &off, hdr->len, &junk16, NULL) != 0)
	goto err;
      if(junk16 == WARTS_TBIT_STRUCT_EOF)
	break;
      if(extract_uint32(buf, &off, hdr->len, &junk32, NULL) != 0)
	goto err;

      i = off;
      if(junk16 == WARTS_TBIT_STRUCT_TYPE)
	{
	  switch(tbit->type)
	    {
	    case SCAMPER_TBIT_TYPE_PMTUD:
	      if(warts_tbit_pmtud_read(tbit, &table, buf, &i, hdr->len) != 0)
		goto err;
	      break;

	    case SCAMPER_TBIT_TYPE_NULL:
	      if(warts_tbit_null_read(tbit, buf, &i, hdr->len) != 0)
		goto err;
	      break;
	    }
	}
      else if(junk16 == WARTS_TBIT_STRUCT_APP)
	{
	  if(tbit->app_proto == SCAMPER_TBIT_APP_HTTP)
	    {
	      if(warts_tbit_app_http_read(tbit, buf, &i, hdr->len) != 0)
		goto err;
	    }
	}

      off += junk32;
    }

  assert(off == hdr->len);
  warts_addrtable_clean(&table);
  *tbit_out = tbit;
  free(buf);
  return 0;

 err:
  warts_addrtable_clean(&table);
  if(buf != NULL) free(buf);
  if(tbit != NULL) scamper_tbit_free(tbit);
  return -1;
}
Example #6
0
/*
 * decoding functions
 */
static void nids_decode_data(struct nids_data_st *nd){

  unsigned char *b = nd->data;
  int packet_code;
  int divider;
  int status, bzerror;

  /*
   * The "divider" should be -1 for legacy products, but for the new
   * products that are bz2 compressed the first two bytes are "BZ".
   * In the first case we continue, but if the divider is not -1
   * we assume it is a new product and try to send it to libbz2.
   */
  divider = (int)extract_int16(b, 1);
  if(divider != -1){
    status = dcnids_bunz(&nd->data, &nd->data_size, &bzerror);
    if(status == 1)
      log_errx(1, "Error from libbz2: %d", bzerror);
    else if(status == -1)
      log_err(1, "Error from libbz2.");

    /* repoint b */
    b = nd->data;
  }

  divider = (int)extract_int16(b, 1);
  if(divider != -1)
    log_errx(1, "Corrupt file.");

  nd->psb.blockid = extract_uint16(b, 2);	/* should be 1 */
  nd->psb.blocklength = extract_uint32(b, 3);
  nd->psb.numlayers = extract_uint16(b, 5);
  b += 10;

  /* XXX
  fprintf(stdout, "\npsb: %d %u %d\n",
	  nd->psb.blockid,
	  nd->psb.blocklength,
	  nd->psb.numlayers);
  */

  nd->psb.psb_layer_blocklength = extract_uint32(b, 2);
  b += 6;

  /* XXX
  fprintf(stdout, "psb_layer_blocklength = %u\n",
	  nd->psb.psb_layer_blocklength);
  */

  /* start of display packets */
  packet_code = extract_uint16(b, 1);
  
  /*
   * XXX
   * To find out the product and packet codes:
   *  fprintf(stdout, "%d %d %d\n",
   *	  nd->nids_header.m_code,
   *	  nd->nids_header.pdb_code,
   *	  packet_code);
   * exit(0);
   */

  if((packet_code != NIDS_PACKET_RADIALS_AF1F) &&
     (packet_code != NIDS_PACKET_DIGITAL_RADIALS_16))
    log_errx(1, "Unsupported packet code: %d", packet_code);

  nd->radial_packet_header.packet_code = packet_code;
  nd->radial_packet_header.first_bin_index = extract_int16(b, 2);
  nd->radial_packet_header.numbins = extract_uint16(b, 3);
  nd->radial_packet_header.center_i = extract_int16(b, 4);
  nd->radial_packet_header.center_j = extract_int16(b, 5);
  nd->radial_packet_header.scale = extract_uint16(b, 6);
  nd->radial_packet_header.numradials = extract_uint16(b, 7);
  b += 14;

  /* XXX
  fprintf(stdout, "\n%x %d %d %d %d %d %d\n",
	  nd->radial_packet_header.packet_code,
	  nd->radial_packet_header.first_bin_index,
	  nd->radial_packet_header.numbins,
	  nd->radial_packet_header.center_i,
	  nd->radial_packet_header.center_j,
	  nd->radial_packet_header.scale,
	  nd->radial_packet_header.numradials);
  */

  /*
   * Here we extract the polygon data. Only the polygons that have 
   * level values within the specified limits will be included if
   * the option to use the filter is set. The filter is used only
   * for bref.
   */
  nd->polygon_map.flag_usefilter = 0;	/* default*/
  if(g.opt_filter == 1){
    nd->polygon_map.flag_usefilter = 1;

    /*
     * The limits depend on the product code.
     */
    if((nd->nids_header.pdb_code == NIDS_PDB_CODE_NXR) ||
       (nd->nids_header.pdb_code == NIDS_PDB_CODE_N0Z) ||
       (nd->nids_header.pdb_code == NIDS_PDB_CODE_NXQ)){
      nd->polygon_map.level_min = NIDS_BREF_LEVEL_MIN_VAL;
      nd->polygon_map.level_max = NIDS_BREF_LEVEL_MAX_VAL;
    } else if((nd->nids_header.pdb_code == NIDS_PDB_CODE_NXV) ||
	     (nd->nids_header.pdb_code == NIDS_PDB_CODE_NXU)){
      nd->polygon_map.level_min = NIDS_RVEL_LEVEL_MIN_VAL;
      nd->polygon_map.level_max = NIDS_RVEL_LEVEL_MAX_VAL;
    } else if((nd->nids_header.pdb_code == NIDS_PDB_CODE_NXP) ||
	      (nd->nids_header.pdb_code == NIDS_PDB_CODE_NTP)){
      nd->polygon_map.level_min = NIDS_NXP_LEVEL_MIN_VAL;
      nd->polygon_map.level_max = NIDS_NXP_LEVEL_MAX_VAL;
    } else if(nd->nids_header.pdb_code == NIDS_PDB_CODE_NXS){
      nd->polygon_map.level_min = NIDS_SRVEL_LEVEL_MIN_VAL;
      nd->polygon_map.level_max = NIDS_SRVEL_LEVEL_MAX_VAL;
    } else
	log_errx(1, "Unsupported value [%d] of nd->nids_header.pdb_code.",
		 nd->nids_header.pdb_code);
    /*
     * If the user specified min and max the use them.
     */
    if(g.level_min != g.level_max){
      nd->polygon_map.level_min = g.level_min;
      nd->polygon_map.level_max = g.level_max;
    }
  }

  /* 
   * The layout of the "run bins" in the radials depends on the packet type.
   */
  if(packet_code == NIDS_PACKET_RADIALS_AF1F)
    nids_decode_radials_af1f(nd);
  else if(packet_code == NIDS_PACKET_DIGITAL_RADIALS_16)
    nids_decode_digital_radials_16(nd);
  else {
    /* Already caught above */
    log_errx(1, "Unsupported packet code: %d", packet_code);
  }
}
Example #7
0
int dcnids_decode_header(struct nids_header_st *nheader){
  /*
   * This function returns the same error codes as nids_verify_header(),
   * namely 0, or a positive error code indicative of the failure.
   */
  int status;
  unsigned char *b;
  int n;
  struct tm tm;

  /* Go past the wmo header and to the start of the awips line */
  b = nheader->buffer;
  b += CTRLHDR_WMO_SIZE;
  
  for(n = 0; n < WMO_AWIPS_SIZE; ++n)
    nheader->awipsid[n] = tolower(*b++);

  nheader->awipsid[WMO_AWIPS_SIZE] = '\0';

  /* Go past the the wmo and awips headers */
  b = nheader->buffer;
  b += WMOAWIPS_HEADER_SIZE;

  nheader->m_code = extract_uint16(b, 1);
  nheader->m_days = extract_uint16(b, 2) - 1;
  nheader->m_seconds = extract_uint32(b, 3);

  /* msglength is the file length without headers or trailers */
  nheader->m_msglength = extract_uint32(b, 5); 
  nheader->m_source = extract_uint16(b, 7);
  nheader->m_destination = extract_uint16(b, 8);
  nheader->m_numblocks = extract_uint16(b, 9);

  nheader->pdb_divider = extract_int16(b, 10);

  nheader->pdb_lat = extract_int32(b, 11);
  nheader->pdb_lon = extract_int32(b, 13);

  nheader->pdb_height = extract_uint16(b, 15);
  nheader->pdb_code = extract_uint16(b, 16);    /* same as m_code */
  nheader->pdb_mode = extract_uint16(b, 17);

  nheader->pdb_version = extract_uint8(b, 54);
  nheader->pdb_symbol_block_offset = extract_uint32(b, 55) * 2;
  nheader->pdb_graphic_block_offset = extract_uint32(b, 57) * 2;
  nheader->pdb_tabular_block_offset = extract_uint32(b, 59) * 2;

  /* derived */
  nheader->lat = ((double)nheader->pdb_lat)/1000.0;
  nheader->lon = ((double)nheader->pdb_lon)/1000.0;
  nheader->unixseconds = nheader->m_days * 24 * 3600 + nheader->m_seconds;

  (void)gmtime_r(&nheader->unixseconds, &tm);
  nheader->year = tm.tm_year + 1900;
  nheader->month = tm.tm_mon + 1;
  nheader->day = tm.tm_mday;
  nheader->hour = tm.tm_hour;
  nheader->min = tm.tm_min;
  nheader->sec = tm.tm_sec;

  status = nids_verify_pdb_header(nheader);

  return(status);
}
bool
UNPACK_VALUE(serial_context *ser_cont, as_val **value)
{
	int32_t type = READ_CHAR(ser_cont->fd, ser_cont->line_no, ser_cont->col_no, ser_cont->bytes);

	if (type == EOF) {
		err("Error while reading value type");
		return false;
	}

	switch (type) {
	case 0xc0: // nil
		return unpack_nil(ser_cont, value);

	case 0xc3: // boolean true
		return unpack_boolean(ser_cont, true, value);

	case 0xc2: // boolean false
		return unpack_boolean(ser_cont, false, value);

	case 0xca: { // float
		float tmp;
		return extract_float(ser_cont, &tmp) && unpack_double(ser_cont, tmp, value);
	}

	case 0xcb: { // double
		double tmp;
		return extract_double(ser_cont, &tmp) && unpack_double(ser_cont, tmp, value);
	}

	case 0xd0: { // signed 8 bit integer
		int8_t tmp;
		return extract_uint8(ser_cont, (uint8_t *)&tmp) && unpack_integer(ser_cont, tmp, value);
	}
	case 0xcc: { // unsigned 8 bit integer
		uint8_t tmp;
		return extract_uint8(ser_cont, &tmp) && unpack_integer(ser_cont, tmp, value);
	}

	case 0xd1: { // signed 16 bit integer
		int16_t tmp;
		return extract_uint16(ser_cont, (uint16_t *)&tmp) && unpack_integer(ser_cont, tmp, value);
	}
	case 0xcd: { // unsigned 16 bit integer
		uint16_t tmp;
		return extract_uint16(ser_cont, &tmp) && unpack_integer(ser_cont, tmp, value);
	}

	case 0xd2: { // signed 32 bit integer
		int32_t tmp;
		return extract_uint32(ser_cont, (uint32_t *)&tmp) && unpack_integer(ser_cont, tmp, value);
	}
	case 0xce: { // unsigned 32 bit integer
		uint32_t tmp;
		return extract_uint32(ser_cont, &tmp) && unpack_integer(ser_cont, tmp, value);
	}

	case 0xd3: { // signed 64 bit integer
		int64_t tmp;
		return extract_uint64(ser_cont, (uint64_t *)&tmp) && unpack_integer(ser_cont, tmp, value);
	}
	case 0xcf: { // unsigned 64 bit integer
		uint64_t tmp;
		return extract_uint64(ser_cont, &tmp) && unpack_integer(ser_cont, (int64_t)tmp, value);
	}

	case 0xc4:
	case 0xd9: { // raw bytes with 8 bit header
		uint8_t size;
		return extract_uint8(ser_cont, &size) && unpack_blob(ser_cont, size, value);
	}
	case 0xc5:
	case 0xda: { // raw bytes with 16 bit header
		uint16_t size;
		return extract_uint16(ser_cont, &size) && unpack_blob(ser_cont, size, value);
	}
	case 0xc6:
	case 0xdb: { // raw bytes with 32 bit header
		uint32_t size;
		return extract_uint32(ser_cont, &size) && unpack_blob(ser_cont, size, value);
	}

	case 0xdc: { // list with 16 bit header
		uint16_t size;
		return extract_uint16(ser_cont, &size) && unpack_list(ser_cont, size, value);
	}
	case 0xdd: { // list with 32 bit header
		uint32_t size;
		return extract_uint32(ser_cont, &size) && unpack_list(ser_cont, size, value);
	}

	case 0xde: { // map with 16 bit header
		uint16_t size;
		return extract_uint16(ser_cont, &size) && unpack_map(ser_cont, size, value);
	}
	case 0xdf: { // map with 32 bit header
		uint32_t size;
		return extract_uint32(ser_cont, &size) && unpack_map(ser_cont, size, value);
	}

	default:
		if ((type & 0xe0) == 0xa0) { // raw bytes with 8 bit combined header
			return unpack_blob(ser_cont, type & 0x1f, value);
		}

		if ((type & 0xf0) == 0x80) { // map with 8 bit combined header
			return unpack_map(ser_cont, type & 0x0f, value);
		}

		if ((type & 0xf0) == 0x90) { // list with 8 bit combined header
			return unpack_list(ser_cont, type & 0x0f, value);
		}

		if (type < 0x80) { // 8 bit combined unsigned integer
			return unpack_integer(ser_cont, type, value);
		}

		if (type >= 0xe0) { // 8 bit combined signed integer
			return unpack_integer(ser_cont, type - 0xe0 - 32, value);
		}

		return false;
	}
}
static inline bool
extract_float(serial_context *ser_cont, float *value)
{
	return extract_uint32(ser_cont, (uint32_t *)value);
}