Ejemplo n.º 1
0
/* Parses a packet. */
static gboolean
iseries_parse_packet (wtap * wth, FILE_T fh, struct wtap_pkthdr *phdr,
                      Buffer *buf, int *err, gchar **err_info)
{
  iseries_t *iseries = (iseries_t *)wth->priv;
  gint64     cur_off;
  gboolean   isValid, isCurrentPacket;
  int        num_items_scanned, line, pktline, buflen;
  int        pkt_len, pktnum, hr, min, sec;
  char       direction[2], destmac[13], srcmac[13], type[5], csec[9+1];
  char       data[ISERIES_LINE_LENGTH * 2];
  int        offset;
  char      *ascii_buf;
  int        ascii_offset;
  struct tm  tm;

  /*
   * Check for packet headers in first 3 lines this should handle page breaks
   * situations and the header lines output at each page throw and ensure we
   * read both the captured and packet lengths.
   */
  isValid = FALSE;
  for (line = 1; line < ISERIES_PKT_LINES_TO_CHECK; line++)
    {
      if (file_gets (data, ISERIES_LINE_LENGTH, fh) == NULL)
        {
          *err = file_error (fh, err_info);
          return FALSE;
        }
      /* Convert UNICODE data to ASCII */
      if (iseries->format == ISERIES_FORMAT_UNICODE)
        {
         iseries_UNICODE_to_ASCII ((guint8 *)data, ISERIES_LINE_LENGTH);
        }
      ascii_strup_inplace (data);
      num_items_scanned =
        sscanf (data,
                "%*[ \n\t]%6d%*[ *\n\t]%1s%*[ \n\t]%6d%*[ \n\t]%2d:%2d:%2d.%9[0-9]%*[ \n\t]"
                "%12s%*[ \n\t]%12s%*[ \n\t]ETHV2%*[ \n\t]TYPE:%*[ \n\t]%4s",
                &pktnum, direction, &pkt_len, &hr, &min, &sec, csec, destmac,
                srcmac, type);
      if (num_items_scanned == 10)
        {
          /* OK! We found the packet header line */
          isValid = TRUE;
          /*
           * XXX - The Capture length returned by the iSeries trace doesn't
           * seem to include the Ethernet header, so we add its length here.
           */
          pkt_len += 14;
          break;
        }
    }

  /*
   * If no packet header found we exit at this point and inform the user.
   */
  if (!isValid)
    {
      *err = WTAP_ERR_BAD_FILE;
      *err_info = g_strdup ("iseries: packet header isn't valid");
      return FALSE;
    }

  phdr->rec_type = REC_TYPE_PACKET;
  phdr->presence_flags = WTAP_HAS_CAP_LEN;

  /*
   * If we have Wiretap Header then populate it here
   *
   * Timer resolution on the iSeries is hardware dependent.  We determine
   * the resolution based on how many digits we see.
   */
  if (iseries->have_date)
    {
      phdr->presence_flags |= WTAP_HAS_TS;
      tm.tm_year        = 100 + iseries->year;
      tm.tm_mon         = iseries->month - 1;
      tm.tm_mday        = iseries->day;
      tm.tm_hour        = hr;
      tm.tm_min         = min;
      tm.tm_sec         = sec;
      tm.tm_isdst       = -1;
      phdr->ts.secs = mktime (&tm);
      csec[sizeof(csec) - 1] = '\0';
      switch (strlen(csec))
        {
          case 0:
            phdr->ts.nsecs = 0;
            break;
          case 1:
            phdr->ts.nsecs = atoi(csec) * 100000000;
            break;
          case 2:
            phdr->ts.nsecs = atoi(csec) * 10000000;
            break;
          case 3:
            phdr->ts.nsecs = atoi(csec) * 1000000;
            break;
          case 4:
            phdr->ts.nsecs = atoi(csec) * 100000;
            break;
          case 5:
            phdr->ts.nsecs = atoi(csec) * 10000;
            break;
          case 6:
            phdr->ts.nsecs = atoi(csec) * 1000;
            break;
          case 7:
            phdr->ts.nsecs = atoi(csec) * 100;
            break;
          case 8:
            phdr->ts.nsecs = atoi(csec) * 10;
            break;
          case 9:
            phdr->ts.nsecs = atoi(csec);
            break;
        }
    }

  phdr->len                       = pkt_len;
  phdr->pkt_encap                 = WTAP_ENCAP_ETHERNET;
  phdr->pseudo_header.eth.fcs_len = -1;

  ascii_buf = (char *)g_malloc (ISERIES_PKT_ALLOC_SIZE);
  g_snprintf(ascii_buf, ISERIES_PKT_ALLOC_SIZE, "%s%s%s", destmac, srcmac, type);
  ascii_offset = 14*2; /* 14-byte Ethernet header, 2 characters per byte */

  /*
   * Start reading packet contents
   */
  isCurrentPacket = TRUE;

  /* loop through packet lines and breakout when the next packet header is read */
  pktline = 0;
  while (isCurrentPacket)
    {
      pktline++;
      /* Read the next line */
      if (file_gets (data, ISERIES_LINE_LENGTH, fh) == NULL)
        {
          *err = file_error (fh, err_info);
          if (*err == 0)
            {
              /* Hit the EOF without an error */
              break;
            }
          goto errxit;
        }

      /* Convert UNICODE data to ASCII and determine line length */
      if (iseries->format == ISERIES_FORMAT_UNICODE)
        {
         buflen = iseries_UNICODE_to_ASCII ((guint8 *)data, ISERIES_LINE_LENGTH);
        }
      else
        {
          /* Else bytes to rewind is just length of ASCII string */
          buflen = (int) strlen (data);
        }

      /*
       * Skip leading white space.
       */
      for (offset = 0; g_ascii_isspace(data[offset]); offset++)
        ;

      /*
       * The higher-level header information starts at an offset of
       * 22 characters.  The header tags are 14 characters long.
       *
       * XXX - for IPv6, if the next header isn't the last header,
       * the intermediate headers do *NOT* appear to be shown in
       * the dump file *at all*, so the packet *cannot* be
       * reconstructed!
       */
      if (offset == 22)
        {
          if (strncmp(data + 22, "IP Header  :  ", 14) == 0 ||
              strncmp(data + 22, "IPv6 Header:  ", 14) == 0 ||
              strncmp(data + 22, "ARP Header :  ", 14) == 0 ||
              strncmp(data + 22, "TCP Header :  ", 14) == 0 ||
              strncmp(data + 22, "UDP Header :  ", 14) == 0 ||
              strncmp(data + 22, "ICMP Header:  ", 14) == 0 ||
              strncmp(data + 22, "ICMPv6  Hdr:  ", 14) == 0 ||
              strncmp(data + 22, "Option  Hdr:  ", 14) == 0)
            {
              ascii_offset = append_hex_digits(ascii_buf, ascii_offset,
                                               ISERIES_PKT_ALLOC_SIZE - 1,
                                               data + 22 + 14, err,
                                               err_info);
              if (ascii_offset == -1)
                {
                  /* Bad line. */
                  return FALSE;
                }
              continue;
            }
        }

      /*
       * Is this a data line?
       *
       * The "Data" starts at an offset of 8.
       */
      if (offset == 9)
        {
          if (strncmp(data + 9, "Data . . . . . :  ", 18) == 0)
            {
              ascii_offset = append_hex_digits(ascii_buf, ascii_offset,
                                               ISERIES_PKT_ALLOC_SIZE - 1,
                                               data + 9 + 18, err,
                                               err_info);
              if (ascii_offset == -1)
                {
                  /* Bad line. */
                  return FALSE;
                }
              continue;
            }
        }

      /*
       * Is this a continuation of a previous header or data line?
       * That's blanks followed by hex digits; first try the
       * "no column separators" form.
       *
       * Continuations of header lines begin at an offset of 36;
       * continuations of data lines begin at an offset of 27.
       */
      if (offset == 36 || offset == 27)
        {
          ascii_offset = append_hex_digits(ascii_buf, ascii_offset,
                                           ISERIES_PKT_ALLOC_SIZE - 1,
                                           data + offset, err,
                                           err_info);
          if (ascii_offset == -1)
            {
              /* Bad line. */
              return FALSE;
            }
          continue;
        }

      /*
       * If we see the identifier for the next packet then rewind and set
       * isCurrentPacket FALSE
       */
      ascii_strup_inplace (data);
      /* If packet header found return the offset */
      num_items_scanned =
          sscanf (data+78,
          "%*[ \n\t]ETHV2%*[ .:\n\t]TYPE%*[ .:\n\t]%4s",type);
      if ((num_items_scanned == 1) && pktline > 1)
        {
          isCurrentPacket = FALSE;
          cur_off = file_tell( fh);
          if (cur_off == -1)
            {
              /* Error. */
              *err = file_error (fh, err_info);
              goto errxit;
            }
          if (file_seek (fh, cur_off - buflen, SEEK_SET, err) == -1)
            {
              /* XXX: need to set err_info ?? */
              goto errxit;
            }
        }
    }
  ascii_buf[ascii_offset] = '\0';

  /*
   * Make the captured length be the amount of bytes we've read (which
   * is half the number of characters of hex dump we have).
   *
   * XXX - this can happen for IPv6 packets if the next header isn't the
   * last header.
   */
  phdr->caplen = ((guint32) strlen (ascii_buf))/2;

  /* Make sure we have enough room for the packet. */
  ws_buffer_assure_space (buf, ISERIES_MAX_PACKET_LEN);
  /* Convert ascii data to binary and return in the frame buffer */
  iseries_parse_hex_string (ascii_buf, ws_buffer_start_ptr (buf), strlen (ascii_buf));

  /* free buffer allocs and return */
  *err = 0;
  g_free (ascii_buf);
  return TRUE;

errxit:
  g_free (ascii_buf);
  return FALSE;
}
Ejemplo n.º 2
0
static int
read_packet_header(FILE_T fh, union wtap_pseudo_header *pseudo_header, 
    packet_entry_header *packet_header, int *err, gchar **err_info)
{
    int offset;
    int bytes_read;
    guint i;
    tlv_header tlvh;
    int seek_increment;
    tlv_wireless_info wireless_header;

    offset = 0;

    /* pull off the packet header */
    bytes_read = file_read(packet_header, sizeof *packet_header, fh);
    if (bytes_read != sizeof *packet_header) {
        *err = file_error(fh, err_info);
        if (*err != 0)
            return -1;
        return 0;    /* EOF */
    }
    offset += bytes_read;
    PACKET_ENTRY_HEADER_FROM_LE_IN_PLACE(*packet_header);

    /* check the packet's magic number */
    if (packet_header->packet_magic != observer_packet_magic) {

        /*
         * Some files are zero-padded at the end. There is no warning of this
         * in the previous packet header information, such as setting
         * offset_to_next_packet to zero. So detect this situation by treating
         * an all-zero header as a sentinel. Return EOF when it is encountered,
         * rather than treat it as a bad record.
         */
        for (i = 0; i < sizeof *packet_header; i++) {
            if (((guint8*) packet_header)[i] != 0)
                break;
        }
        if (i == sizeof *packet_header) {
            *err = 0;
            return 0;    /* EOF */
        }

        *err = WTAP_ERR_BAD_FILE;
        *err_info = g_strdup_printf("Observer: bad record: Invalid magic number 0x%08x",
            packet_header->packet_magic);
        return -1;
    }

    /* process extra information */
    for (i = 0; i < packet_header->number_of_information_elements; i++) {
        /* read the TLV header */
        bytes_read = file_read(&tlvh, sizeof tlvh, fh);
        if (bytes_read != sizeof tlvh) {
            *err = file_error(fh, err_info);
            if (*err == 0)
                *err = WTAP_ERR_SHORT_READ;
            return -1;
        }
        offset += bytes_read;
        TLV_HEADER_FROM_LE_IN_PLACE(tlvh);

        if (tlvh.length < sizeof tlvh) {
            *err = WTAP_ERR_BAD_FILE;
            *err_info = g_strdup_printf("Observer: bad record (TLV length %u < %lu)",
                tlvh.length, (unsigned long)sizeof tlvh);
            return -1;
        }

        /* process (or skip over) the current TLV */
        switch (tlvh.type) {
        case INFORMATION_TYPE_WIRELESS:
            bytes_read = file_read(&wireless_header, sizeof wireless_header, fh);
            if (bytes_read != sizeof wireless_header) {
                *err = file_error(fh, err_info);
                if(*err == 0)
                    *err = WTAP_ERR_SHORT_READ;
                return -1;
            }
            /* update the pseudo header */
            pseudo_header->ieee_802_11.fcs_len = 0;
            pseudo_header->ieee_802_11.channel = wireless_header.frequency;
            pseudo_header->ieee_802_11.data_rate = wireless_header.rate;
            pseudo_header->ieee_802_11.signal_level = wireless_header.strengthPercent;
            offset += bytes_read;
            break;
        default:
            /* skip the TLV data */
            seek_increment = tlvh.length - (int)sizeof tlvh;
            if (seek_increment > 0) {
                if (file_seek(fh, seek_increment, SEEK_CUR, err) == -1)
                    return -1;
            }
            offset += seek_increment;
        }
    }

    return offset;
}
Ejemplo n.º 3
0
/* XXX - return -1 on I/O error and actually do something with 'err'. */
int csids_open(wtap *wth, int *err, gchar **err_info)
{
  /* There is no file header. There is only a header for each packet
   * so we read a packet header and compare the caplen with iplen. They
   * should always be equal except with the wierd byteswap version.
   *
   * THIS IS BROKEN-- anytime the caplen is 0x0101 or 0x0202 up to 0x0505
   * this will byteswap it. I need to fix this. XXX --mlh
   */

  int tmp,iplen,bytesRead;

  gboolean byteswap = FALSE;
  struct csids_header hdr;
  csids_t *csids;

  /* check the file to make sure it is a csids file. */
  bytesRead = file_read( &hdr, sizeof( struct csids_header), wth->fh );
  if( bytesRead != sizeof( struct csids_header) ) {
    *err = file_error( wth->fh, err_info );
    if( *err != 0 ) {
      return -1;
    } else {
      return 0;
    }
  }
  if( hdr.zeropad != 0 || hdr.caplen == 0 ) {
	return 0;
  }
  hdr.seconds = pntohl( &hdr.seconds );
  hdr.caplen = pntohs( &hdr.caplen );
  bytesRead = file_read( &tmp, 2, wth->fh );
  if( bytesRead != 2 ) {
    *err = file_error( wth->fh, err_info );
    if( *err != 0 ) {
      return -1;
    } else {
      return 0;
    }
  }
  bytesRead = file_read( &iplen, 2, wth->fh );
  if( bytesRead != 2 ) {
    *err = file_error( wth->fh, err_info );
    if( *err != 0 ) {
      return -1;
    } else {
      return 0;
    }
  }
  iplen = pntohs(&iplen);

  if ( iplen == 0 )
    return(0);

  /* if iplen and hdr.caplen are equal, default to no byteswap. */
  if( iplen > hdr.caplen ) {
    /* maybe this is just a byteswapped version. the iplen ipflags */
    /* and ipid are swapped. We cannot use the normal swaps because */
    /* we don't know the host */
    iplen = BSWAP16(iplen);
    if( iplen <= hdr.caplen ) {
      /* we know this format */
      byteswap = TRUE;
    } else {
      /* don't know this one */
      return 0;
    }
  } else {
    byteswap = FALSE;
  }

  /* no file header. So reset the fh to 0 so we can read the first packet */
  if (file_seek(wth->fh, 0, SEEK_SET, err) == -1)
    return -1;

  csids = (csids_t *)g_malloc(sizeof(csids_t));
  wth->priv = (void *)csids;
  csids->byteswapped = byteswap;
  wth->file_encap = WTAP_ENCAP_RAW_IP;
  wth->file_type = WTAP_FILE_CSIDS;
  wth->snapshot_length = 0; /* not known */
  wth->subtype_read = csids_read;
  wth->subtype_seek_read = csids_seek_read;
  wth->tsprecision = WTAP_FILE_TSPREC_SEC;

  return 1;
}
Ejemplo n.º 4
0
int lanalyzer_open(wtap *wth, int *err, gchar **err_info)
{
	int bytes_read;
	char LE_record_type[2];
	char LE_record_length[2];
	char summary[210];
	guint16 board_type, mxslc;
	guint16 record_type, record_length;
	guint8 cr_day, cr_month;
	guint16 cr_year;
	struct tm tm;
	lanalyzer_t *lanalyzer;

	errno = WTAP_ERR_CANT_READ;
	bytes_read = file_read(LE_record_type, 1, 2, wth->fh);
	bytes_read += file_read(LE_record_length, 1, 2, wth->fh);
	if (bytes_read != 4) {
		*err = file_error(wth->fh);
		if (*err != 0)
			return -1;
		return 0;
	}
	wth->data_offset += 4;
	record_type = pletohs(LE_record_type);
	record_length = pletohs(LE_record_length); /* make sure to do this for while() loop */

	if (record_type != RT_HeaderRegular && record_type != RT_HeaderCyclic) {
		return 0;
	}

	/* If we made it this far, then the file is a LANAlyzer file.
	 * Let's get some info from it. Note that we get wth->snapshot_length
	 * from a record later in the file. */
	wth->file_type = WTAP_FILE_LANALYZER;
	lanalyzer = (lanalyzer_t *)g_malloc(sizeof(lanalyzer_t));;
	wth->priv = (void *)lanalyzer;
	wth->subtype_read = lanalyzer_read;
	wth->subtype_seek_read = lanalyzer_seek_read;
	wth->snapshot_length = 0;
	wth->tsprecision = WTAP_FILE_TSPREC_NSEC;

	/* Read records until we find the start of packets */
	while (1) {
		if (file_seek(wth->fh, record_length, SEEK_CUR, err) == -1) {
			g_free(wth->priv);
			return -1;
		}
		wth->data_offset += record_length;
		errno = WTAP_ERR_CANT_READ;
		bytes_read = file_read(LE_record_type, 1, 2, wth->fh);
		bytes_read += file_read(LE_record_length, 1, 2, wth->fh);
		if (bytes_read != 4) {
			*err = file_error(wth->fh);
			if (*err != 0) {
				g_free(wth->priv);
				return -1;
			}
			g_free(wth->priv);
			return 0;
		}
		wth->data_offset += 4;

		record_type = pletohs(LE_record_type);
		record_length = pletohs(LE_record_length);

		/*g_message("Record 0x%04X Length %d", record_type, record_length);*/
		switch (record_type) {
			/* Trace Summary Record */
			case RT_Summary:
				errno = WTAP_ERR_CANT_READ;
				bytes_read = file_read(summary, 1, sizeof summary,
				    wth->fh);
				if (bytes_read != sizeof summary) {
					*err = file_error(wth->fh);
					if (*err != 0) {
						g_free(wth->priv);
						return -1;
					}
					g_free(wth->priv);
					return 0;
				}
				wth->data_offset += sizeof summary;

				/* Assume that the date of the creation of the trace file
				 * is the same date of the trace. Lanalyzer doesn't
				 * store the creation date/time of the trace, but only of
				 * the file. Unless you traced at 11:55 PM and saved at 00:05
				 * AM, the assumption that trace.date == file.date is true.
				 */
				cr_day = summary[0];
				cr_month = summary[1];
				cr_year = pletohs(&summary[2]);
				/*g_message("Day %d Month %d Year %d (%04X)", cr_day, cr_month,
						cr_year, cr_year);*/

				/* Get capture start time. I learned how to do
				 * this from Guy's code in ngsniffer.c
				 */
				tm.tm_year = cr_year - 1900;
				tm.tm_mon = cr_month - 1;
				tm.tm_mday = cr_day;
				tm.tm_hour = 0;
				tm.tm_min = 0;
				tm.tm_sec = 0;
				tm.tm_isdst = -1;
				lanalyzer->start = mktime(&tm);
				/*g_message("Day %d Month %d Year %d", tm.tm_mday,
						tm.tm_mon, tm.tm_year);*/
				mxslc = pletohs(&summary[30]);
				wth->snapshot_length = mxslc;

				record_length = 0; /* to fake the next iteration of while() */
				board_type = pletohs(&summary[188]);
				switch (board_type) {
					case BOARD_325:
						wth->file_encap = WTAP_ENCAP_ETHERNET;
						break;
					case BOARD_325TR:
						wth->file_encap = WTAP_ENCAP_TOKEN_RING;
						break;
					default:
						g_free(wth->priv);
						*err = WTAP_ERR_UNSUPPORTED_ENCAP;
						*err_info = g_strdup_printf("lanalyzer: board type %u unknown",
						    board_type);
						return -1;
				}
				break;

			/* Trace Packet Data Record */
			case RT_PacketData:
				/* Go back header number ob ytes so that lanalyzer_read
				 * can read this header */
				if (file_seek(wth->fh, -bytes_read, SEEK_CUR, err) == -1) {
					g_free(wth->priv);
					return -1;
				}
				wth->data_offset -= bytes_read;
				return 1;

			default:
				; /* no action */
		}
	}
}
Ejemplo n.º 5
0
/* Read the next packet */
static gboolean netmon_read(wtap *wth, int *err, gchar **err_info,
    gint64 *data_offset)
{
	netmon_t *netmon = (netmon_t *)wth->priv;
	guint32	packet_size = 0;
	guint32 orig_size = 0;
	int	bytes_read;
	union {
		struct netmonrec_1_x_hdr hdr_1_x;
		struct netmonrec_2_x_hdr hdr_2_x;
	}	hdr;
	int	hdr_size = 0;
	int	trlr_size;
	gint64	rec_offset;
	guint8	*data_ptr;
	gint64	delta = 0;	/* signed - frame times can be before the nominal start */
	gint64	t;
	time_t	secs;
	guint32	nsecs;

again:
	/* Have we reached the end of the packet data? */
	if (netmon->current_frame >= netmon->frame_table_size) {
		/* Yes.  We won't need the frame table any more;
		   free it. */
		g_free(netmon->frame_table);
		netmon->frame_table = NULL;
		*err = 0;	/* it's just an EOF, not an error */
		return FALSE;
	}

	/* Seek to the beginning of the current record, if we're
	   not there already (seeking to the current position
	   may still cause a seek and a read of the underlying file,
	   so we don't want to do it unconditionally).

	   Yes, the current record could be before the previous
	   record.  At least some captures put the trailer record
	   with statistics as the first physical record in the
	   file, but set the frame table up so it's the last
	   record in sequence. */
	rec_offset = netmon->frame_table[netmon->current_frame];
	if (file_tell(wth->fh) != rec_offset) {
		if (file_seek(wth->fh, rec_offset, SEEK_SET, err) == -1)
			return FALSE;
	}
	netmon->current_frame++;

	/* Read record header. */
	switch (netmon->version_major) {

	case 1:
		hdr_size = sizeof (struct netmonrec_1_x_hdr);
		break;

	case 2:
		hdr_size = sizeof (struct netmonrec_2_x_hdr);
		break;
	}
	errno = WTAP_ERR_CANT_READ;

	bytes_read = file_read(&hdr, hdr_size, wth->fh);
	if (bytes_read != hdr_size) {
		*err = file_error(wth->fh, err_info);
		if (*err == 0 && bytes_read != 0) {
			*err = WTAP_ERR_SHORT_READ;
		}
		return FALSE;
	}

	switch (netmon->version_major) {

	case 1:
		orig_size = pletohs(&hdr.hdr_1_x.orig_len);
		packet_size = pletohs(&hdr.hdr_1_x.incl_len);
		break;

	case 2:
		orig_size = pletohl(&hdr.hdr_2_x.orig_len);
		packet_size = pletohl(&hdr.hdr_2_x.incl_len);
		break;
	}
	if (packet_size > WTAP_MAX_PACKET_SIZE) {
		/*
		 * Probably a corrupt capture file; don't blow up trying
		 * to allocate space for an immensely-large packet.
		 */
		*err = WTAP_ERR_BAD_FILE;
		*err_info = g_strdup_printf("netmon: File has %u-byte packet, bigger than maximum of %u",
		    packet_size, WTAP_MAX_PACKET_SIZE);
		return FALSE;
	}

	*data_offset = file_tell(wth->fh);

	/*
	 * If this is an ATM packet, the first
	 * "sizeof (struct netmon_atm_hdr)" bytes have destination and
	 * source addresses (6 bytes - MAC addresses of some sort?)
	 * and the VPI and VCI; read them and generate the pseudo-header
	 * from them.
	 */
	switch (wth->file_encap) {

	case WTAP_ENCAP_ATM_PDUS:
		if (packet_size < sizeof (struct netmon_atm_hdr)) {
			/*
			 * Uh-oh, the packet isn't big enough to even
			 * have a pseudo-header.
			 */
			*err = WTAP_ERR_BAD_FILE;
			*err_info = g_strdup_printf("netmon: ATM file has a %u-byte packet, too small to have even an ATM pseudo-header",
			    packet_size);
			return FALSE;
		}
		if (!netmon_read_atm_pseudoheader(wth->fh, &wth->phdr.pseudo_header,
		    err, err_info))
			return FALSE;	/* Read error */

		/*
		 * Don't count the pseudo-header as part of the packet.
		 */
		orig_size -= (guint)sizeof (struct netmon_atm_hdr);
		packet_size -= (guint)sizeof (struct netmon_atm_hdr);
		break;

	default:
		break;
	}

	buffer_assure_space(wth->frame_buffer, packet_size);
	data_ptr = buffer_start_ptr(wth->frame_buffer);
	if (!netmon_read_rec_data(wth->fh, data_ptr, packet_size, err,
	    err_info))
		return FALSE;	/* Read error */

	switch (netmon->version_major) {

	case 1:
		/*
		 * According to Paul Long, this offset is unsigned.
		 * It's 32 bits, so the maximum value will fit in
		 * a gint64 such as delta, even after multiplying
		 * it by 1000000.
		 *
		 * pletohl() returns a guint32; we cast it to gint64
		 * before multiplying, so that the product doesn't
		 * overflow a guint32.
		 */
		delta = ((gint64)pletohl(&hdr.hdr_1_x.ts_delta))*1000000;
		break;

	case 2:
		/*
		 * OK, this is weird.  Microsoft's documentation
		 * says this is in microseconds and is a 64-bit
		 * unsigned number, but it can be negative; they
		 * say what appears to amount to "treat it as an
		 * unsigned number, multiply it by 10, and then
		 * interpret the resulting 64-bit quantity as a
		 * signed number".  That operation can turn a
		 * value with the uppermost bit 0 to a value with
		 * the uppermost bit 1, hence turning a large
		 * positive number-of-microseconds into a small
		 * negative number-of-100-nanosecond-increments.
		 */
		delta = pletohll(&hdr.hdr_2_x.ts_delta)*10;

		/*
		 * OK, it's now a signed value in 100-nanosecond
		 * units.  Now convert it to nanosecond units.
		 */
		delta *= 100;
		break;
	}
	secs = 0;
	t = netmon->start_nsecs + delta;
	while (t < 0) {
		/*
		 * Propagate a borrow into the seconds.
		 * The seconds is a time_t, and can be < 0
		 * (unlikely, as Windows didn't exist before
		 * January 1, 1970, 00:00:00 UTC), while the
		 * nanoseconds should be positive, as in
		 * "nanoseconds since the instant of time
		 * represented by the seconds".
		 *
		 * We do not want t to be negative, as, according
		 * to the C90 standard, "if either operand [of /
		 * or %] is negative, whether the result of the
		 * / operator is the largest integer less than or
		 * equal to the algebraic quotient or the smallest
		 * greater than or equal to the algebraic quotient
		 * is implementation-defined, as is the sign of
		 * the result of the % operator", and we want
		 * the result of the division and remainder
		 * operations to be the same on all platforms.
		 */
		t += 1000000000;
		secs--;
	}
	secs += (time_t)(t/1000000000);
	nsecs = (guint32)(t%1000000000);
	wth->phdr.presence_flags = WTAP_HAS_TS|WTAP_HAS_CAP_LEN;
	wth->phdr.ts.secs = netmon->start_secs + secs;
	wth->phdr.ts.nsecs = nsecs;
	wth->phdr.caplen = packet_size;
	wth->phdr.len = orig_size;

	/*
	 * For version 2.1 and later, there's additional information
	 * after the frame data.
	 */
	trlr_size = (int)netmon_trailer_size(netmon);
	if (trlr_size != 0) {
		/*
		 * I haz a trailer.
		 */
		wth->phdr.pkt_encap = netmon_read_rec_trailer(wth->fh,
		    trlr_size, err, err_info);
		if (wth->phdr.pkt_encap == -1)
			return FALSE;	/* error */
		if (wth->phdr.pkt_encap == 0)
			goto again;
		netmon_set_pseudo_header_info(wth->phdr.pkt_encap,
		    &wth->phdr.pseudo_header, data_ptr, packet_size);
	} else {
		netmon_set_pseudo_header_info(wth->file_encap,
		    &wth->phdr.pseudo_header, data_ptr, packet_size);
	}

	return TRUE;
}
Ejemplo n.º 6
0
int lanalyzer_open(wtap *wth, int *err, gchar **err_info)
{
	int bytes_read;
	LA_RecordHeader rec_header;
	char header_fixed[2];
	char *comment;
	char summary[210];
	guint16 board_type, mxslc;
	guint16 record_type, record_length;
	guint8 cr_day, cr_month;
	guint16 cr_year;
	struct tm tm;
	lanalyzer_t *lanalyzer;

	errno = WTAP_ERR_CANT_READ;
	bytes_read = file_read(&rec_header, LA_RecordHeaderSize, wth->fh);
	if (bytes_read != LA_RecordHeaderSize) {
		*err = file_error(wth->fh, err_info);
		if (*err != 0 && *err != WTAP_ERR_SHORT_READ)
			return -1;
		return 0;
	}
	record_type = pletoh16(rec_header.record_type);
	record_length = pletoh16(rec_header.record_length); /* make sure to do this for while() loop */

	if (record_type != RT_HeaderRegular && record_type != RT_HeaderCyclic) {
		return 0;
	}

	/* Read the major and minor version numbers */
	if (record_length < 2) {
		/*
		 * Not enough room for the major and minor version numbers.
		 * Just treat that as a "not a LANalyzer file" indication.
		 */
		return 0;
	}
	bytes_read = file_read(&header_fixed, sizeof header_fixed, wth->fh);
	if (bytes_read != sizeof header_fixed) {
		*err = file_error(wth->fh, err_info);
		if (*err != 0 && *err != WTAP_ERR_SHORT_READ)
			return -1;
		return 0;
	}
	record_length -= sizeof header_fixed;

	if (record_length != 0) {
		/* Read the rest of the record as a comment. */
		comment = (char *)g_malloc(record_length + 1);
		bytes_read = file_read(comment, record_length, wth->fh);
		if (bytes_read != record_length) {
			*err = file_error(wth->fh, err_info);
			if (*err != 0 && *err != WTAP_ERR_SHORT_READ)
				return -1;
			return 0;
		}
		comment[record_length] = '\0';
		wth->shb_hdr.opt_comment = comment;
	}

	/* If we made it this far, then the file is a LANAlyzer file.
	 * Let's get some info from it. Note that we get wth->snapshot_length
	 * from a record later in the file. */
	wth->file_type_subtype = WTAP_FILE_TYPE_SUBTYPE_LANALYZER;
	lanalyzer = (lanalyzer_t *)g_malloc(sizeof(lanalyzer_t));
	wth->priv = (void *)lanalyzer;
	wth->subtype_read = lanalyzer_read;
	wth->subtype_seek_read = lanalyzer_seek_read;
	wth->snapshot_length = 0;
	wth->tsprecision = WTAP_FILE_TSPREC_NSEC;

	/* Read records until we find the start of packets */
	while (1) {
		errno = WTAP_ERR_CANT_READ;
		bytes_read = file_read(&rec_header, LA_RecordHeaderSize, wth->fh);
		if (bytes_read != LA_RecordHeaderSize) {
			*err = file_error(wth->fh, err_info);
			if (*err == 0)
				*err = WTAP_ERR_SHORT_READ;
			return -1;
		}

		record_type = pletoh16(rec_header.record_type);
		record_length = pletoh16(rec_header.record_length);

		/*g_message("Record 0x%04X Length %d", record_type, record_length);*/
		switch (record_type) {
			/* Trace Summary Record */
			case RT_Summary:
				errno = WTAP_ERR_CANT_READ;
				bytes_read = file_read(summary, sizeof summary,
				    wth->fh);
				if (bytes_read != sizeof summary) {
					*err = file_error(wth->fh, err_info);
					if (*err == 0)
						*err = WTAP_ERR_SHORT_READ;
					return -1;
				}

				/* Assume that the date of the creation of the trace file
				 * is the same date of the trace. Lanalyzer doesn't
				 * store the creation date/time of the trace, but only of
				 * the file. Unless you traced at 11:55 PM and saved at 00:05
				 * AM, the assumption that trace.date == file.date is true.
				 */
				cr_day = summary[0];
				cr_month = summary[1];
				cr_year = pletoh16(&summary[2]);
				/*g_message("Day %d Month %d Year %d (%04X)", cr_day, cr_month,
						cr_year, cr_year);*/

				/* Get capture start time. I learned how to do
				 * this from Guy's code in ngsniffer.c
				 */
				tm.tm_year = cr_year - 1900;
				tm.tm_mon = cr_month - 1;
				tm.tm_mday = cr_day;
				tm.tm_hour = 0;
				tm.tm_min = 0;
				tm.tm_sec = 0;
				tm.tm_isdst = -1;
				lanalyzer->start = mktime(&tm);
				/*g_message("Day %d Month %d Year %d", tm.tm_mday,
						tm.tm_mon, tm.tm_year);*/
				mxslc = pletoh16(&summary[30]);
				wth->snapshot_length = mxslc;

				board_type = pletoh16(&summary[188]);
				switch (board_type) {
					case BOARD_325:
						wth->file_encap = WTAP_ENCAP_ETHERNET;
						break;
					case BOARD_325TR:
						wth->file_encap = WTAP_ENCAP_TOKEN_RING;
						break;
					default:
						*err = WTAP_ERR_UNSUPPORTED_ENCAP;
						*err_info = g_strdup_printf("lanalyzer: board type %u unknown",
						    board_type);
						return -1;
				}
				break;

			/* Trace Packet Data Record */
			case RT_PacketData:
				/* Go back header number of bytes so that lanalyzer_read
				 * can read this header */
				if (file_seek(wth->fh, -LA_RecordHeaderSize, SEEK_CUR, err) == -1) {
					return -1;
				}
				return 1;

			default:
				if (file_seek(wth->fh, record_length, SEEK_CUR, err) == -1) {
					return -1;
				}
				break;
		}
	}
}
Ejemplo n.º 7
0
wtap_open_return_val
nettrace_3gpp_32_423_file_open(wtap *wth, int *err, gchar **err_info)
{
	char magic_buf[512]; /* increase buffer size when needed */
	int bytes_read;
	char *curr_pos;
	nettrace_3gpp_32_423_file_info_t *file_info;
	wtap_open_return_val temp_val;


	bytes_read = file_read(magic_buf, 512, wth->fh);

	if (bytes_read < 0) {
		*err = file_error(wth->fh, err_info);
		return WTAP_OPEN_ERROR;
	}
	if (bytes_read == 0){
		return WTAP_OPEN_NOT_MINE;
	}

	if (memcmp(magic_buf, xml_magic, sizeof(xml_magic)) != 0){
		return WTAP_OPEN_NOT_MINE;
	}
	/* File header should contain something like fileFormatVersion="32.423 V8.1.0" */
	curr_pos = strstr(magic_buf, "fileFormatVersion");

	if (!curr_pos){
		return WTAP_OPEN_NOT_MINE;
	}
	curr_pos += 19;
	if (memcmp(curr_pos, Threegpp_doc_no, sizeof(Threegpp_doc_no)) != 0){
		return WTAP_OPEN_NOT_MINE;
	}

	if (file_seek(wth->fh, 0, SEEK_SET, err) == -1)
		return WTAP_OPEN_ERROR;

	/* Ok it's our file, open a temp file and do the conversion */
	file_info = g_new0(nettrace_3gpp_32_423_file_info_t, 1);
	temp_val = create_temp_pcapng_file(wth, err, err_info, file_info);

	if (temp_val != WTAP_OPEN_MINE){
		return temp_val;
	}

	if (file_seek(wth->fh, 0, SEEK_SET, err) == -1)
		return WTAP_OPEN_ERROR;

	/* Copy data from the temp file wth */
	wth->shb_hdr.opt_comment = file_info->wth_tmp_file->shb_hdr.opt_comment;
	wth->shb_hdr.shb_hardware = file_info->wth_tmp_file->shb_hdr.shb_hardware;
	wth->shb_hdr.shb_os = file_info->wth_tmp_file->shb_hdr.shb_os;
	wth->shb_hdr.shb_user_appl = file_info->wth_tmp_file->shb_hdr.shb_user_appl;

	wth->file_type_subtype = WTAP_FILE_TYPE_SUBTYPE_NETTRACE_3GPP_32_423;
	wth->file_encap = file_info->wth_tmp_file->file_encap;
	wth->file_tsprec = file_info->wth_tmp_file->file_tsprec;
	wth->subtype_read = nettrace_read;
	wth->subtype_seek_read = nettrace_seek_read;
	wth->subtype_close = nettrace_close;
	wth->snapshot_length = 0;

	wth->priv = (void*)file_info;

	return WTAP_OPEN_MINE;

}
Ejemplo n.º 8
0
static void seek_handler (int fd, unsigned position) {
  struct file_struct * file_seeking = get_file(fd);
  file_seek(file_seeking->sys_file, position);
}
Ejemplo n.º 9
0
static uint16_t sendfile_interrupt(FAR struct net_driver_s *dev, FAR void *pvconn,
                                   FAR void *pvpriv, uint16_t flags)
{
  FAR struct tcp_conn_s *conn = (FAR struct tcp_conn_s *)pvconn;
  FAR struct sendfile_s *pstate = (FAR struct sendfile_s *)pvpriv;
  int ret;

#ifdef CONFIG_NETDEV_MULTINIC
  /* The TCP socket is connected and, hence, should be bound to a device.
   * Make sure that the polling device is the own that we are bound to.
   */

  DEBUGASSERT(conn->dev != NULL);
  if (dev != conn->dev)
    {
      return flags;
    }
#endif

  nllvdbg("flags: %04x acked: %d sent: %d\n",
          flags, pstate->snd_acked, pstate->snd_sent);

  /* Check for a loss of connection */

  if ((flags & TCP_DISCONN_EVENTS) != 0)
    {
      /* Report not connected */

      nlldbg("Lost connection\n");

      net_lostconnection(pstate->snd_sock, flags);
      pstate->snd_sent = -ENOTCONN;
      goto end_wait;
    }

  /* We get here if (1) not all of the data has been ACKed, (2) we have been
   * asked to retransmit data, (3) the connection is still healthy, and (4)
   * the outgoing packet is available for our use.  In this case, we are
   * now free to send more data to receiver -- UNLESS the buffer contains
   * unprocessing incoming data.  In that event, we will have to wait for the
   * next polling cycle.
   */

  if ((flags & TCP_NEWDATA) == 0 && pstate->snd_sent < pstate->snd_flen)
    {
      /* Get the amount of data that we can send in the next packet */

      uint32_t sndlen = pstate->snd_flen - pstate->snd_sent;

      if (sndlen > conn->mss)
        {
          sndlen = conn->mss;
        }

      /* Check if we have "space" in the window */

      if ((pstate->snd_sent - pstate->snd_acked + sndlen) < conn->winsize)
        {
          uint32_t seqno;

          /* Then set-up to send that amount of data. (this won't actually
           * happen until the polling cycle completes).
           */

          ret = file_seek(pstate->snd_file,
                          pstate->snd_foffset + pstate->snd_sent, SEEK_SET);
          if (ret < 0)
            {
              int errcode = get_errno();
              nlldbg("failed to lseek: %d\n", errcode);
              pstate->snd_sent = -errcode;
              goto end_wait;
            }

          ret = file_read(pstate->snd_file, dev->d_appdata, sndlen);
          if (ret < 0)
            {
              int errcode = get_errno();
              nlldbg("failed to read from input file: %d\n", errcode);
              pstate->snd_sent = -errcode;
              goto end_wait;
            }

          dev->d_sndlen = sndlen;

          /* Set the sequence number for this packet.  NOTE:  The network updates
           * sndseq on recept of ACK *before* this function is called.  In that
           * case sndseq will point to the next unacknowledge byte (which might
           * have already been sent).  We will overwrite the value of sndseq
           * here before the packet is sent.
           */

          seqno = pstate->snd_sent + pstate->snd_isn;
          nllvdbg("SEND: sndseq %08x->%08x len: %d\n", conn->sndseq, seqno, ret);

          tcp_setsequence(conn->sndseq, seqno);

          /* Check if the destination IP address is in the ARP  or Neighbor
           * table.  If not, then the send won't actually make it out... it
           * will be replaced with an ARP request or Neighbor Solicitation.
           */

          if (pstate->snd_sent != 0 || sendfile_addrcheck(conn))
            {
              /* Update the amount of data sent (but not necessarily ACKed) */

              pstate->snd_sent += sndlen;
              nllvdbg("pid: %d SEND: acked=%d sent=%d flen=%d\n", getpid(),
                     pstate->snd_acked, pstate->snd_sent, pstate->snd_flen);
            }
        }
      else
        {
          nlldbg("Window full, wait for ack\n");
          goto wait;
        }
    }

#ifdef CONFIG_NET_SOCKOPTS
  /* All data has been send and we are just waiting for ACK or re-transmit
   * indications to complete the send.  Check for a timeout.
   */

  if (sendfile_timeout(pstate))
    {
      /* Yes.. report the timeout */

      nlldbg("SEND timeout\n");
      pstate->snd_sent = -ETIMEDOUT;
      goto end_wait;
    }
#endif /* CONFIG_NET_SOCKOPTS */

  if (pstate->snd_sent >= pstate->snd_flen
      && pstate->snd_acked < pstate->snd_flen)
    {
      /* All data has been sent, but there are outstanding ACK's */

      goto wait;
    }

end_wait:

  /* Do not allow any further callbacks */

  pstate->snd_datacb->flags   = 0;
  pstate->snd_datacb->priv    = NULL;
  pstate->snd_datacb->event   = NULL;

  /* Wake up the waiting thread */

  sem_post(&pstate->snd_sem);

wait:
  return flags;
}
Ejemplo n.º 10
0
static gint detect_version(wtap *wth, int *err, gchar **err_info)
{
    gint     bytes_read;
    guint16  payload_length;
    guint16  try_header_size;
    guint8  *buffer;
    gint64   file_offset;
    guint32  log_length;
    guint32  tag_length;
    guint16  tmp;

    file_offset = file_tell(wth->fh);

    bytes_read = file_read(&tmp, 2, wth->fh);
    if (bytes_read != 2) {
        *err = file_error(wth->fh, err_info);
        if (*err == 0 && bytes_read != 0)
            *err = WTAP_ERR_SHORT_READ;
        return -1;
    }
    payload_length = pletoh16(&tmp);

    bytes_read = file_read(&tmp, 2, wth->fh);
    if (bytes_read != 2) {
        *err = file_error(wth->fh, err_info);
        if (*err == 0 && bytes_read != 0)
            *err = WTAP_ERR_SHORT_READ;
        return -1;
    }
    try_header_size = pletoh16(&tmp);

    buffer = (guint8 *) g_malloc(5 * 4 + payload_length);
    bytes_read = file_read(buffer, 5 * 4 + payload_length, wth->fh);
    if (bytes_read != 5 * 4 + payload_length) {
        if (bytes_read != 4 * 4 + payload_length) {
            *err = file_error(wth->fh, err_info);
            if (*err == 0 && bytes_read != 0)
                *err = WTAP_ERR_SHORT_READ;
            g_free(buffer);
            return -1;
        }
    }

    if (try_header_size == 24) {
        tag_length = (guint32)strlen(buffer + 5 * 4 + 1) + 1;
        log_length = (guint32)strlen(buffer + 5 * 4 + 1 + tag_length) + 1;
        if (payload_length == 1 + tag_length + log_length) {
            g_free(buffer);
            return 2;
        }
    }

    tag_length = (guint32)strlen(buffer + 4 * 4 + 1) + 1;
    log_length = (guint32)strlen(buffer + 4 * 4 + 1 + tag_length) + 1;
    if (payload_length == 1 + tag_length + log_length) {
        if (file_seek(wth->fh, file_offset + 4 * 4 + 1 + tag_length + log_length, SEEK_SET, err) == -1) {
            g_free(buffer);
            return -1;
        }
        g_free(buffer);
        return 1;
    }

    g_free(buffer);
    return 0;
}
Ejemplo n.º 11
0
static gboolean stanag4607_read_file(wtap *wth, FILE_T fh, struct wtap_pkthdr *phdr,
                               Buffer *buf, int *err, gchar **err_info)
{
  stanag4607_t *stanag4607 = (stanag4607_t *)wth->priv;
  guint32 millisecs, secs, nsecs;
  gint64 offset = 0;
  guint8 stanag_pkt_hdr[37];
  guint32 packet_size;

  *err = 0;

  /* Combined packet header and segment header */
  if (!wtap_read_bytes_or_eof(fh, stanag_pkt_hdr, sizeof stanag_pkt_hdr, err, err_info))
    return FALSE;
  offset += sizeof stanag_pkt_hdr;

  if (!is_valid_id(pntoh16(&stanag_pkt_hdr[0]))) {
    *err = WTAP_ERR_BAD_FILE;
    *err_info = g_strdup("Bad version number");
    return FALSE;
  }

  phdr->rec_type = REC_TYPE_PACKET;

  /* The next 4 bytes are the packet length */
  packet_size = pntoh32(&stanag_pkt_hdr[2]);
  phdr->caplen = packet_size;
  phdr->len = packet_size;

  /* Sadly, the header doesn't contain times; but some segments do */
  /* So, get the segment header, which is just past the 32-byte header. */
  phdr->presence_flags = WTAP_HAS_TS;

  /* If no time specified, it's the last baseline time */
  phdr->ts.secs = stanag4607->base_secs;
  phdr->ts.nsecs = 0;
  millisecs = 0;

#define MISSION_SEGMENT 1
#define DWELL_SEGMENT 2
#define JOB_DEFINITION_SEGMENT 5
#define PLATFORM_LOCATION_SEGMENT 13
  if (MISSION_SEGMENT == stanag_pkt_hdr[32]) {
    guint8 mseg[39];
    struct tm tm;

    if (!wtap_read_bytes(fh, &mseg, sizeof mseg, err, err_info))
      return FALSE;
    offset += sizeof mseg;

    tm.tm_year = pntoh16(&mseg[35]) - 1900;
    tm.tm_mon = mseg[37] - 1;
    tm.tm_mday = mseg[38];
    tm.tm_hour = 0;
    tm.tm_min = 0;
    tm.tm_sec = 0;
    tm.tm_isdst = -1;
    stanag4607->base_secs = mktime(&tm);
    phdr->ts.secs = stanag4607->base_secs;
  }
  else if (PLATFORM_LOCATION_SEGMENT == stanag_pkt_hdr[32]) {
    if (!wtap_read_bytes(fh, &millisecs, sizeof millisecs, err, err_info))
      return FALSE;
    offset += sizeof millisecs;
    millisecs = g_ntohl(millisecs);
  }
  else if (DWELL_SEGMENT == stanag_pkt_hdr[32]) {
    guint8 dseg[19];
    if (!wtap_read_bytes(fh, &dseg, sizeof dseg, err, err_info))
      return FALSE;
    offset += sizeof dseg;
    millisecs = pntoh32(&dseg[15]);
  }
  if (0 != millisecs) {
    secs = millisecs/1000;
    nsecs = (millisecs - 1000 * secs) * 1000000;
    phdr->ts.secs = stanag4607->base_secs + secs;
    phdr->ts.nsecs = nsecs;
  }

  /* wind back to the start of the packet ... */
  if (file_seek(fh, - offset, SEEK_CUR, err) == -1)
    return FALSE;

  return wtap_read_packet_bytes(fh, buf, packet_size, err, err_info);
}
Ejemplo n.º 12
0
//! This function fills an ASCII buffer with the current text line of opened file
//!
//! @param     b_unicode      true to return a unicode string (UTF16), ASCII otherwise over there
//! @param     string         string used to store text line
//! @param     u16_str_size   maximum size of string (unit character, 1B for ASCII, 2B for unicode)
//!
//! @return    size of the line (may be < or > at u16_str_size)
//! @return    0, in case of error
//!
//! @verbatim
//! This routine remove the character '\n' '\r'
//! @endverbatim
//!
uint16_t   reader_txt_get_line( bool b_unicode, FS_STRING string , uint16_t u16_str_size )
{
    uint8_t    utf8[UNI_MAX_UTF8_SIZE];
    uint8_t    size_utf8_buf=0;
    uint8_t    size_utf8_dec=0;
    uint16_t   u16_size_line = 1;   // 1 to compute null terminator
    uint16_t   u16_unicode;
    bool  b_error = false;

    nav_checkdisk_disable();   // To optimize speed

    while( 0 == file_eof() && !b_error )
    {
        // Get a unicode value
        switch( fs_g_nav_entry.u8_txt_format )
        {
        case UNI_TYPE_UTF8:
            // Remove UTF8 codes used
            if( 0 != size_utf8_dec )
            {
                uint8_t u8_i;
                for( u8_i=0; u8_i<(UNI_MAX_UTF8_SIZE-size_utf8_dec); u8_i++ )
                {
                    utf8[u8_i]=utf8[u8_i+size_utf8_dec];
                }
                size_utf8_buf -= size_utf8_dec;
                size_utf8_dec =0;
            }
            // Complete UTF8 array
            size_utf8_buf += file_read_buf( &utf8[size_utf8_buf], (UNI_MAX_UTF8_SIZE-size_utf8_buf) );
            // Decode UTF8 to unicode
            size_utf8_dec = utf8_to_unicode( &utf8[0], &u16_unicode );
            break;

        case UNI_TYPE_UTF16BE:
            MSB(u16_unicode) = file_getc();
            LSB(u16_unicode) = file_getc();
            if (LSB(u16_unicode) == (FS_EOF & 0xFF) && fs_g_status != FS_ERR_EOF)
                b_error = true;
            break;

        case UNI_TYPE_UTF16LE:
            LSB(u16_unicode) = file_getc();
            MSB(u16_unicode) = file_getc();
            if (MSB(u16_unicode) == (FS_EOF & 0xFF) && fs_g_status != FS_ERR_EOF)
                b_error = true;
            break;

        default: // ASCII or other
            u16_unicode = file_getc();
            if (u16_unicode == FS_EOF && fs_g_status != FS_ERR_EOF)
                b_error = true;
            break;
        }

        // Check character to remove
        if( '\r' == u16_unicode )
            continue;   // Ignore character

        // Check end of line
        if((  0  == u16_unicode )
                || ('\n' == u16_unicode ) )
            break;      // End of line

        u16_size_line++;
        // Fill string
        if( 1 < u16_str_size )
        {
            if( b_unicode )
            {
                ((FS_STR_UNICODE)string)[0] = u16_unicode;
            } else {
                string[0] = u16_unicode;
            }
            string += (b_unicode? 2 : 1 );
            u16_str_size--;
        }
    }
    // HERE, the line is read

    if( UNI_TYPE_UTF8 == fs_g_nav_entry.u8_txt_format )
    {
        // Re position cursor on next UTF8
        file_seek( (size_utf8_buf-size_utf8_dec) , FS_SEEK_CUR_RE );
    }

    // Handle error cases
    if (b_error)
    {
        nav_checkdisk_enable();
        return 0;
    }

    // Add Null terminate
    if( 0 != u16_str_size )
    {
        if( b_unicode )
        {
            ((FS_STR_UNICODE)string)[0] = 0;
        } else {
            string[0] = 0;
        }
    }
    nav_checkdisk_enable();
    return u16_size_line;
}
Ejemplo n.º 13
0
int libpcap_open(wtap *wth, int *err, gchar **err_info)
{
	int bytes_read;
	guint32 magic;
	struct pcap_hdr hdr;
	gboolean byte_swapped;
	gboolean modified;
	gboolean aix;
	int file_encap;
	gint64 first_packet_offset;
	libpcap_t *libpcap;

	/* Read in the number that should be at the start of a "libpcap" file */
	errno = WTAP_ERR_CANT_READ;
	bytes_read = file_read(&magic, sizeof magic, wth->fh);
	if (bytes_read != sizeof magic) {
		*err = file_error(wth->fh, err_info);
		if (*err != 0 && *err != WTAP_ERR_SHORT_READ)
			return -1;
		return 0;
	}

	switch (magic) {

	case PCAP_MAGIC:
		/* Host that wrote it has our byte order, and was running
		   a program using either standard or ss990417 libpcap. */
		byte_swapped = FALSE;
		modified = FALSE;
		wth->tsprecision = WTAP_FILE_TSPREC_USEC;
		break;

	case PCAP_MODIFIED_MAGIC:
		/* Host that wrote it has our byte order, and was running
		   a program using either ss990915 or ss991029 libpcap. */
		byte_swapped = FALSE;
		modified = TRUE;
		wth->tsprecision = WTAP_FILE_TSPREC_USEC;
		break;

	case PCAP_SWAPPED_MAGIC:
		/* Host that wrote it has a byte order opposite to ours,
		   and was running a program using either standard or
		   ss990417 libpcap. */
		byte_swapped = TRUE;
		modified = FALSE;
		wth->tsprecision = WTAP_FILE_TSPREC_USEC;
		break;

	case PCAP_SWAPPED_MODIFIED_MAGIC:
		/* Host that wrote it out has a byte order opposite to
		   ours, and was running a program using either ss990915
		   or ss991029 libpcap. */
		byte_swapped = TRUE;
		modified = TRUE;
		wth->tsprecision = WTAP_FILE_TSPREC_USEC;
		break;

	case PCAP_NSEC_MAGIC:
		/* Host that wrote it has our byte order, and was writing
		   the file in a format similar to standard libpcap
		   except that the time stamps have nanosecond resolution. */
		byte_swapped = FALSE;
		modified = FALSE;
		wth->tsprecision = WTAP_FILE_TSPREC_NSEC;
		break;

	case PCAP_SWAPPED_NSEC_MAGIC:
		/* Host that wrote it out has a byte order opposite to
		   ours, and was writing the file in a format similar to
		   standard libpcap except that the time stamps have
		   nanosecond resolution. */
		byte_swapped = TRUE;
		modified = FALSE;
		wth->tsprecision = WTAP_FILE_TSPREC_NSEC;
		break;

	default:
		/* Not a "libpcap" type we know about. */
		return 0;
	}

	/* Read the rest of the header. */
	errno = WTAP_ERR_CANT_READ;
	bytes_read = file_read(&hdr, sizeof hdr, wth->fh);
	if (bytes_read != sizeof hdr) {
		*err = file_error(wth->fh, err_info);
		if (*err == 0)
			*err = WTAP_ERR_SHORT_READ;
		return -1;
	}

	if (byte_swapped) {
		/* Byte-swap the header fields about which we care. */
		hdr.version_major = BSWAP16(hdr.version_major);
		hdr.version_minor = BSWAP16(hdr.version_minor);
		hdr.snaplen = BSWAP32(hdr.snaplen);
		hdr.network = BSWAP32(hdr.network);
	}
	if (hdr.version_major < 2) {
		/* We only support version 2.0 and later. */
		*err = WTAP_ERR_UNSUPPORTED;
		*err_info = g_strdup_printf("pcap: major version %u unsupported",
		    hdr.version_major);
		return -1;
	}

	/*
	 * AIX's non-standard tcpdump uses a minor version number of 2.
	 * Unfortunately, older versions of libpcap might have used
	 * that as well.
	 *
	 * The AIX libpcap uses RFC 1573 ifType values rather than
	 * DLT_ values in the header; the ifType values for LAN devices
	 * are:
	 *
	 *	Ethernet	6
	 *	Token Ring	9
	 *	FDDI		15
	 *
	 * which correspond to DLT_IEEE802 (used for Token Ring),
	 * DLT_PPP, and DLT_SLIP_BSDOS, respectively.  The ifType value
	 * for a loopback interface is 24, which currently isn't
	 * used by any version of libpcap I know about (and, as
	 * tcpdump.org are assigning DLT_ values above 100, and
	 * NetBSD started assigning values starting at 50, and
	 * the values chosen by other libpcaps appear to stop at
	 * 19, it's probably not going to be used by any libpcap
	 * in the future).
	 *
	 * We shall assume that if the minor version number is 2, and
	 * the network type is 6, 9, 15, or 24, that it's AIX libpcap.
	 *
	 * I'm assuming those older versions of libpcap didn't
	 * use DLT_IEEE802 for Token Ring, and didn't use DLT_SLIP_BSDOS
	 * as that came later.  It may have used DLT_PPP, however, in
	 * which case we're out of luck; we assume it's Token Ring
	 * in AIX libpcap rather than PPP in standard libpcap, as
	 * you're probably more likely to be handing an AIX libpcap
	 * token-ring capture than an old (pre-libpcap 0.4) PPP capture
	 * to Wireshark.
	 */
	aix = FALSE;	/* assume it's not AIX */
	if (hdr.version_major == 2 && hdr.version_minor == 2) {
		switch (hdr.network) {

		case 6:
			hdr.network = 1;	/* DLT_EN10MB, Ethernet */
			aix = TRUE;
			break;

		case 9:
			hdr.network = 6;	/* DLT_IEEE802, Token Ring */
			aix = TRUE;
			break;

		case 15:
			hdr.network = 10;	/* DLT_FDDI, FDDI */
			aix = TRUE;
			break;

		case 24:
			hdr.network = 0;	/* DLT_NULL, loopback */
			aix = TRUE;
			break;
		}
	}

	file_encap = wtap_pcap_encap_to_wtap_encap(hdr.network);
	if (file_encap == WTAP_ENCAP_UNKNOWN) {
		*err = WTAP_ERR_UNSUPPORTED_ENCAP;
		*err_info = g_strdup_printf("pcap: network type %u unknown or unsupported",
		    hdr.network);
		return -1;
	}

	/* This is a libpcap file */
	libpcap = (libpcap_t *)g_malloc(sizeof(libpcap_t));
	libpcap->byte_swapped = byte_swapped;
	libpcap->version_major = hdr.version_major;
	libpcap->version_minor = hdr.version_minor;
	wth->priv = (void *)libpcap;
	wth->subtype_read = libpcap_read;
	wth->subtype_seek_read = libpcap_seek_read;
	wth->file_encap = file_encap;
	wth->snapshot_length = hdr.snaplen;

	/* In file format version 2.3, the order of the "incl_len" and
	   "orig_len" fields in the per-packet header was reversed,
	   in order to match the BPF header layout.

	   Therefore, in files with versions prior to that, we must swap
	   those two fields.

	   Unfortunately, some files were, according to a comment in the
	   "libpcap" source, written with version 2.3 in their headers
	   but without the interchanged fields, so if "incl_len" is
	   greater than "orig_len" - which would make no sense - we
	   assume that we need to swap them in version 2.3 files
	   as well.

	   In addition, DG/UX's tcpdump uses version 543.0, and writes
	   the two fields in the pre-2.3 order. */
	switch (hdr.version_major) {

	case 2:
		if (hdr.version_minor < 3)
			libpcap->lengths_swapped = SWAPPED;
		else if (hdr.version_minor == 3)
			libpcap->lengths_swapped = MAYBE_SWAPPED;
		else
			libpcap->lengths_swapped = NOT_SWAPPED;
		break;

	case 543:
		libpcap->lengths_swapped = SWAPPED;
		break;

	default:
		libpcap->lengths_swapped = NOT_SWAPPED;
		break;
	}

	/*
	 * Is this AIX format?
	 */
	if (aix) {
		/*
		 * Yes.  Skip all the tests for other mutant formats,
		 * and for the ERF link-layer header type, and set the
		 * precision to nanosecond precision.
		 */
		wth->file_type = WTAP_FILE_PCAP_AIX;
		wth->tsprecision = WTAP_FILE_TSPREC_NSEC;
		return 1;
	}

	/*
	 * No.  Let's look at the header for the first record,
	 * and see if, interpreting it as a standard header (if the
	 * magic number was standard) or a modified header (if the
	 * magic number was modified), the position where it says the
	 * header for the *second* record is contains a corrupted header.
	 *
	 * If so, then:
	 *
	 *	If this file had the standard magic number, it may be
	 *	an ss990417 capture file - in that version of Alexey's
	 *	patch, the packet header format was changed but the
	 *	magic number wasn't, and, alas, Red Hat appear to have
	 *	picked up that version of the patch for RH 6.1, meaning
	 *	RH 6.1 has a tcpdump that writes out files that can't
	 *	be read by any software that expects non-modified headers
	 *	if the magic number isn't the modified magic number (e.g.,
	 *	any normal version of tcpdump, and Wireshark if we don't
	 *	do this gross heuristic).
	 *
	 *	If this file had the modified magic number, it may be
	 *	an ss990915 capture file - in that version of Alexey's
	 *	patch, the magic number was changed, but the record
	 *	header had some extra fields, and, alas, SuSE appear
	 *	to have picked up that version of the patch for SuSE
	 *	6.3, meaning that programs expecting the standard per-
	 *	packet header in captures with the modified magic number
	 *	can't read dumps from its tcpdump.
	 *
	 * Oh, and if it has the standard magic number, it might, instead,
	 * be a Nokia libpcap file, so we may need to try that if
	 * neither normal nor ss990417 headers work.
	 */
	if (modified) {
		/*
		 * Well, we have the magic number from Alexey's
		 * later two patches.
		 *
		 * Try ss991029, the last of his patches, first.
		 */
		wth->file_type = WTAP_FILE_PCAP_SS991029;
		first_packet_offset = file_tell(wth->fh);
		switch (libpcap_try(wth, err)) {

		case BAD_READ:
			/*
			 * Well, we couldn't even read it.
			 * Give up.
			 */
			return -1;

		case THIS_FORMAT:
			/*
			 * Well, it looks as if it might be 991029.
			 * Put the seek pointer back, and finish.
			 */
			if (file_seek(wth->fh, first_packet_offset, SEEK_SET, err) == -1) {
				return -1;
			}
			goto done;

		case OTHER_FORMAT:
			/*
			 * Try the next format.
			 */
			break;
		}

		/*
		 * Well, it's not completely unreadable,
		 * but it's not ss991029.  Try ss990915;
		 * there are no other types to try after that,
		 * so we put the seek pointer back and treat
		 * it as 990915.
		 */
		wth->file_type = WTAP_FILE_PCAP_SS990915;
		if (file_seek(wth->fh, first_packet_offset, SEEK_SET, err) == -1) {
			return -1;
		}
	} else {
		/*
		 * Well, we have the standard magic number.
		 *
		 * Try the standard format first.
		 */
		if(wth->tsprecision == WTAP_FILE_TSPREC_NSEC) {
			wth->file_type = WTAP_FILE_PCAP_NSEC;
		} else {
			wth->file_type = WTAP_FILE_PCAP;
		}
		first_packet_offset = file_tell(wth->fh);
		switch (libpcap_try(wth, err)) {

		case BAD_READ:
			/*
			 * Well, we couldn't even read it.
			 * Give up.
			 */
			return -1;

		case THIS_FORMAT:
			/*
			 * Well, it looks as if it might be a standard
			 * libpcap file.
			 * Put the seek pointer back, and finish.
			 */
			if (file_seek(wth->fh, first_packet_offset, SEEK_SET, err) == -1) {
				return -1;
			}
			goto done;

		case OTHER_FORMAT:
			/*
			 * Try the next format.
			 */
			break;
		}

		/*
		 * Well, it's not completely unreadable, but it's not
		 * a standard file.  Put the seek pointer back and try
		 * ss990417.
		 */
		wth->file_type = WTAP_FILE_PCAP_SS990417;
		if (file_seek(wth->fh, first_packet_offset, SEEK_SET, err) == -1) {
			return -1;
		}
		switch (libpcap_try(wth, err)) {

		case BAD_READ:
			/*
			 * Well, we couldn't even read it.
			 * Give up.
			 */
			return -1;

		case THIS_FORMAT:
			/*
			 * Well, it looks as if it might be ss990417.
			 * Put the seek pointer back, and finish.
			 */
			if (file_seek(wth->fh, first_packet_offset, SEEK_SET, err) == -1) {
				return -1;
			}
			goto done;

		case OTHER_FORMAT:
			/*
			 * Try the next format.
			 */
			break;
		}

		/*
		 * Well, it's not completely unreadable,
		 * but it's not a standard file *nor* is it ss990417.
		 * Try it as a Nokia file; there are no other types
		 * to try after that, so we put the seek pointer back
		 * and treat it as a Nokia file.
		 */
		wth->file_type = WTAP_FILE_PCAP_NOKIA;
		if (file_seek(wth->fh, first_packet_offset, SEEK_SET, err) == -1) {
			return -1;
		}
	}

done:
	/*
	 * We treat a DLT_ value of 13 specially - it appears that in
	 * Nokia libpcap format, it's some form of ATM with what I
	 * suspect is a pseudo-header (even though Nokia's IPSO is
	 * based on FreeBSD, which #defines DLT_SLIP_BSDOS as 13).
	 *
	 * If this is a Nokia capture, treat 13 as WTAP_ENCAP_ATM_PDUS,
	 * rather than as what we normally treat it.
	 */
	if (wth->file_type == WTAP_FILE_PCAP_NOKIA && hdr.network == 13)
		wth->file_encap = WTAP_ENCAP_ATM_PDUS;

	if (wth->file_encap == WTAP_ENCAP_ERF) {
		/*
		 * Populate set of interface IDs for ERF format.
		 * Currently, this *has* to be done at open time.
		 */
		erf_populate_interfaces(wth);
	}
	return 1;
}
Ejemplo n.º 14
0
/* Try to read the first two records of the capture file. */
static libpcap_try_t libpcap_try(wtap *wth, int *err)
{
	/*
	 * pcaprec_ss990915_hdr is the largest header type.
	 */
	struct pcaprec_ss990915_hdr first_rec_hdr, second_rec_hdr;


	/*
	 * Attempt to read the first record's header.
	 */
	if (libpcap_read_header(wth, err, NULL, &first_rec_hdr) == -1) {
		if (*err == 0 || *err == WTAP_ERR_SHORT_READ) {
			/*
			 * EOF or short read - assume the file is in this
			 * format.
			 * When our client tries to read the first packet
			 * they will presumably get the same EOF or short
			 * read.
			 */
			return THIS_FORMAT;
		}

		if (*err == WTAP_ERR_BAD_FILE) {
			/*
			 * The first record is bogus, so this is probably
			 * a corrupt file.  Assume the file is in this
			 * format.  When our client tries to read the
			 * first packet they will presumably get the
			 * same bogus record.
			 */
			return THIS_FORMAT;
		}

		/*
		 * Some other error, e.g. an I/O error; just give up.
		 */
		return BAD_READ;
	}

	/*
	 * Now skip over the first record's data, under the assumption
	 * that the header is sane.
	 */
	if (file_seek(wth->fh, first_rec_hdr.hdr.incl_len, SEEK_CUR, err) == -1)
		return BAD_READ;

	/*
	 * Now attempt to read the second record's header.
	 */
	if (libpcap_read_header(wth, err, NULL, &second_rec_hdr) == -1) {
		if (*err == 0 || *err == WTAP_ERR_SHORT_READ) {
			/*
			 * EOF or short read - assume the file is in this
			 * format.
			 * When our client tries to read the second packet
			 * they will presumably get the same EOF or short
			 * read.
			 */
			return THIS_FORMAT;
		}

		if (*err == WTAP_ERR_BAD_FILE) {
			/*
			 * The second record is bogus; maybe it's a
			 * Capture File From Hell, and what looks like
			 * the "header" of the next packet is actually
			 * random junk from the middle of a packet.
			 * Try the next format; if we run out of formats,
			 * it probably *is* a corrupt file.
			 */
			return OTHER_FORMAT;
		}

		/*
		 * Some other error, e.g. an I/O error; just give up.
		 */
		return BAD_READ;
	}

	/*
	 * OK, the first two records look OK; assume this is the
	 * right format.
	 */
	return THIS_FORMAT;
}
Ejemplo n.º 15
0
/* Parses a packet. */
static gboolean
iseries_parse_packet (wtap * wth, FILE_T fh, struct wtap_pkthdr *phdr,
                      Buffer *buf, int *err, gchar **err_info)
{
  iseries_t *iseries = (iseries_t *)wth->priv;
  gint64     cur_off;
  gboolean   isValid, isCurrentPacket;
  int        num_items_scanned, line, pktline, buflen;
  int        pkt_len, pktnum, hr, min, sec;
  char       direction[2], destmac[13], srcmac[13], type[5];
  guint32    csec;
  char       data[ISERIES_LINE_LENGTH * 2];
  int        offset;
  char      *ascii_buf;
  int        ascii_offset;
  struct tm  tm;

  /*
   * Check for packet headers in first 3 lines this should handle page breaks
   * situations and the header lines output at each page throw and ensure we
   * read both the captured and packet lengths.
   */
  isValid = FALSE;
  for (line = 1; line < ISERIES_PKT_LINES_TO_CHECK; line++)
    {
      if (file_gets (data, ISERIES_LINE_LENGTH, fh) == NULL)
        {
          *err = file_error (fh, err_info);
          return FALSE;
        }
      /* Convert UNICODE data to ASCII */
      if (iseries->format == ISERIES_FORMAT_UNICODE)
        {
         iseries_UNICODE_to_ASCII ((guint8 *)data, ISERIES_LINE_LENGTH);
        }
      ascii_strup_inplace (data);
      num_items_scanned =
        sscanf (data,
                "%*[ \n\t]%6d%*[ *\n\t]%1s%*[ \n\t]%6d%*[ \n\t]%2d:%2d:%2d.%9u%*[ \n\t]"
                "%12s%*[ \n\t]%12s%*[ \n\t]ETHV2%*[ \n\t]TYPE:%*[ \n\t]%4s",
                &pktnum, direction, &pkt_len, &hr, &min, &sec, &csec, destmac,
                srcmac, type);
      if (num_items_scanned == 10)
        {
          if (pktnum < 0)
            {
              *err = WTAP_ERR_BAD_FILE;
              *err_info = g_strdup ("iseries: packet header has a negative packet number");
              return FALSE;
            }

          if (pkt_len < 0)
            {
              *err = WTAP_ERR_BAD_FILE;
              *err_info = g_strdup ("iseries: packet header has a negative packet length");
              return FALSE;
            }

          if (hr < 0)
            {
              *err = WTAP_ERR_BAD_FILE;
              *err_info = g_strdup ("iseries: packet header has a negative hour in the time stamp");
              return FALSE;
            }

          if (hr > 23)
            {
              *err = WTAP_ERR_BAD_FILE;
              *err_info = g_strdup ("iseries: packet header has a hour in the time stamp greater than 23");
              return FALSE;
            }

          if (min < 0)
            {
              *err = WTAP_ERR_BAD_FILE;
              *err_info = g_strdup ("iseries: packet header has a negative minute in the time stamp");
              return FALSE;
            }

          if (min > 59)
            {
              *err = WTAP_ERR_BAD_FILE;
              *err_info = g_strdup ("iseries: packet header has a minute in the time stamp greater than 59");
              return FALSE;
            }

          if (sec < 0)
            {
              *err = WTAP_ERR_BAD_FILE;
              *err_info = g_strdup ("iseries: packet header has a negative second in the time stamp");
              return FALSE;
            }

          /*
           * Yes, 60, even though the time-conversion routines on most OSes
           * might not handle leap seconds.
           */
          if (sec > 60)
            {
              *err = WTAP_ERR_BAD_FILE;
              *err_info = g_strdup ("iseries: packet header has a second in the time stamp greater than 60");
              return FALSE;
            }

          if (strlen(destmac) != 12)
            {
              *err = WTAP_ERR_BAD_FILE;
              *err_info = g_strdup ("iseries: packet header has a destination MAC address shorter than 6 bytes");
              return FALSE;
            }

          if (strlen(srcmac) != 12)
            {
              *err = WTAP_ERR_BAD_FILE;
              *err_info = g_strdup ("iseries: packet header has a source MAC address shorter than 6 bytes");
              return FALSE;
            }

          if (strlen(type) != 4)
            {
              *err = WTAP_ERR_BAD_FILE;
              *err_info = g_strdup ("iseries: packet header has an Ethernet type/length field than 2 bytes");
              return FALSE;
            }

          /* OK! We found the packet header line */
          isValid = TRUE;
          /*
           * XXX - The Capture length returned by the iSeries trace doesn't
           * seem to include the Ethernet header, so we add its length here.
           *
           * Check the length first, just in case it's *so* big that, after
           * adding the Ethernet header length, it overflows.
           */
          if (pkt_len > WTAP_MAX_PACKET_SIZE_STANDARD - 14)
            {
              /*
               * Probably a corrupt capture file; don't blow up trying
               * to allocate space for an immensely-large packet, and
               * don't think it's a really *small* packet because it
               * overflowed.  (Calculate the size as a 64-bit value in
               * the error message, to avoid an overflow.)
               */
              *err = WTAP_ERR_BAD_FILE;
              *err_info = g_strdup_printf("iseries: File has %" G_GUINT64_FORMAT "-byte packet, bigger than maximum of %u",
                                          (guint64)pkt_len + 14,
                                          WTAP_MAX_PACKET_SIZE_STANDARD);
              return FALSE;
            }
          pkt_len += 14;
          break;
        }
    }

  /*
   * If no packet header found we exit at this point and inform the user.
   */
  if (!isValid)
    {
      *err = WTAP_ERR_BAD_FILE;
      *err_info = g_strdup ("iseries: packet header isn't valid");
      return FALSE;
    }

  phdr->rec_type = REC_TYPE_PACKET;
  phdr->presence_flags = WTAP_HAS_CAP_LEN;

  /*
   * If we have Wiretap Header then populate it here
   *
   * Timer resolution on the iSeries is hardware dependent.  We determine
   * the resolution based on how many digits we see.
   */
  if (iseries->have_date)
    {
      phdr->presence_flags |= WTAP_HAS_TS;
      tm.tm_year        = 100 + iseries->year;
      tm.tm_mon         = iseries->month - 1;
      tm.tm_mday        = iseries->day;
      tm.tm_hour        = hr;
      tm.tm_min         = min;
      tm.tm_sec         = sec;
      tm.tm_isdst       = -1;
      phdr->ts.secs = mktime (&tm);
      phdr->ts.nsecs = csec * csec_multiplier(csec);
    }

  phdr->len                       = pkt_len;
  phdr->pkt_encap                 = WTAP_ENCAP_ETHERNET;
  phdr->pseudo_header.eth.fcs_len = -1;

  /*
   * Allocate a buffer big enough to hold the claimed packet length
   * worth of byte values; each byte will be two hex digits, so the
   * buffer's size should be twice the packet length.
   *
   * (There is no need to null-terminate the buffer.)
   */
  ascii_buf = (char *)g_malloc (pkt_len*2);
  ascii_offset = 0;

  /*
   * Copy in the Ethernet header.
   *
   * The three fields have already been checked to have the right length
   * (6 bytes, hence 12 characters, of hex-dump destination and source
   * addresses, and 2 bytes, hence 4 characters, of hex-dump type/length).
   *
   * pkt_len is guaranteed to be >= 14, so 2*pkt_len is guaranteed to be
   * >= 28, so we don't need to do any bounds checking.
   */
  memcpy(&ascii_buf[0], destmac, 12);
  ascii_offset += 12;
  memcpy(&ascii_buf[12], srcmac, 12);
  ascii_offset += 12;
  memcpy(&ascii_buf[24], type, 4);
  ascii_offset += 4;

  /*
   * Start reading packet contents
   */
  isCurrentPacket = TRUE;

  /* loop through packet lines and breakout when the next packet header is read */
  pktline = 0;
  while (isCurrentPacket)
    {
      pktline++;
      /* Read the next line */
      if (file_gets (data, ISERIES_LINE_LENGTH, fh) == NULL)
        {
          *err = file_error (fh, err_info);
          if (*err == 0)
            {
              /* Hit the EOF without an error */
              break;
            }
          goto errxit;
        }

      /* Convert UNICODE data to ASCII and determine line length */
      if (iseries->format == ISERIES_FORMAT_UNICODE)
        {
         buflen = iseries_UNICODE_to_ASCII ((guint8 *)data, ISERIES_LINE_LENGTH);
        }
      else
        {
          /* Else bytes to rewind is just length of ASCII string */
          buflen = (int) strlen (data);
        }

      /*
       * Skip leading white space.
       */
      for (offset = 0; g_ascii_isspace(data[offset]); offset++)
        ;

      /*
       * The higher-level header information starts at an offset of
       * 22 characters.  The header tags are 14 characters long.
       *
       * XXX - for IPv6, if the next header isn't the last header,
       * the intermediate headers do *NOT* appear to be shown in
       * the dump file *at all*, so the packet *cannot* be
       * reconstructed!
       */
      if (offset == 22)
        {
          if (strncmp(data + 22, "IP Header  :  ", 14) == 0 ||
              strncmp(data + 22, "IPv6 Header:  ", 14) == 0 ||
              strncmp(data + 22, "ARP Header :  ", 14) == 0 ||
              strncmp(data + 22, "TCP Header :  ", 14) == 0 ||
              strncmp(data + 22, "UDP Header :  ", 14) == 0 ||
              strncmp(data + 22, "ICMP Header:  ", 14) == 0 ||
              strncmp(data + 22, "ICMPv6  Hdr:  ", 14) == 0 ||
              strncmp(data + 22, "Option  Hdr:  ", 14) == 0)
            {
              ascii_offset = append_hex_digits(ascii_buf, ascii_offset,
                                               pkt_len*2,
                                               data + 22 + 14, err,
                                               err_info);
              if (ascii_offset == -1)
                {
                  /* Bad line. */
                  return FALSE;
                }
              continue;
            }
        }

      /*
       * Is this a data line?
       *
       * The "Data" starts at an offset of 8.
       */
      if (offset == 9)
        {
          if (strncmp(data + 9, "Data . . . . . :  ", 18) == 0)
            {
              ascii_offset = append_hex_digits(ascii_buf, ascii_offset,
                                               pkt_len*2,
                                               data + 9 + 18, err,
                                               err_info);
              if (ascii_offset == -1)
                {
                  /* Bad line. */
                  return FALSE;
                }
              continue;
            }
        }

      /*
       * Is this a continuation of a previous header or data line?
       * That's blanks followed by hex digits; first try the
       * "no column separators" form.
       *
       * Continuations of header lines begin at an offset of 36;
       * continuations of data lines begin at an offset of 27.
       */
      if (offset == 36 || offset == 27)
        {
          ascii_offset = append_hex_digits(ascii_buf, ascii_offset,
                                           pkt_len*2,
                                           data + offset, err,
                                           err_info);
          if (ascii_offset == -1)
            {
              /* Bad line. */
              return FALSE;
            }
          continue;
        }

      /*
       * If we see the identifier for the next packet then rewind and set
       * isCurrentPacket FALSE
       */
      ascii_strup_inplace (data);
      /* If packet header found return the offset */
      num_items_scanned =
          sscanf (data+78,
          "%*[ \n\t]ETHV2%*[ .:\n\t]TYPE%*[ .:\n\t]%4s",type);
      if ((num_items_scanned == 1) && pktline > 1)
        {
          isCurrentPacket = FALSE;
          cur_off = file_tell( fh);
          if (cur_off == -1)
            {
              /* Error. */
              *err = file_error (fh, err_info);
              goto errxit;
            }
          if (file_seek (fh, cur_off - buflen, SEEK_SET, err) == -1)
            {
              /* XXX: need to set err_info ?? */
              goto errxit;
            }
        }
    }

  /*
   * Make the captured length be the amount of bytes we've read (which
   * is half the number of characters of hex dump we have).
   *
   * XXX - this can happen for IPv6 packets if the next header isn't the
   * last header.
   */
  phdr->caplen = ((guint32) ascii_offset)/2;

  /* Make sure we have enough room for the packet. */
  ws_buffer_assure_space (buf, phdr->caplen);
  /* Convert ascii data to binary and return in the frame buffer */
  iseries_parse_hex_string (ascii_buf, ws_buffer_start_ptr (buf), ascii_offset);

  /* free buffer allocs and return */
  *err = 0;
  g_free (ascii_buf);
  return TRUE;

errxit:
  g_free (ascii_buf);
  return FALSE;
}
Ejemplo n.º 16
0
static gboolean stanag4607_read_file(wtap *wth, FILE_T fh, wtap_rec *rec,
                               Buffer *buf, int *err, gchar **err_info)
{
  stanag4607_t *stanag4607 = (stanag4607_t *)wth->priv;
  guint32 millisecs, secs, nsecs;
  gint64 offset = 0;
  guint8 stanag_pkt_hdr[PKT_HDR_SIZE+SEG_HDR_SIZE];
  guint32 packet_size;

  *err = 0;

  /* Combined packet header and segment header */
  if (!wtap_read_bytes_or_eof(fh, stanag_pkt_hdr, sizeof stanag_pkt_hdr, err, err_info))
    return FALSE;
  offset += sizeof stanag_pkt_hdr;

  if (!is_valid_id(pntoh16(&stanag_pkt_hdr[0]))) {
    *err = WTAP_ERR_BAD_FILE;
    *err_info = g_strdup("Bad version number");
    return FALSE;
  }

  rec->rec_type = REC_TYPE_PACKET;

  /* The next 4 bytes are the packet length */
  packet_size = pntoh32(&stanag_pkt_hdr[2]);
  if (packet_size > WTAP_MAX_PACKET_SIZE_STANDARD) {
    /*
     * Probably a corrupt capture file; don't blow up trying
     * to allocate space for an immensely-large packet.
     */
    *err = WTAP_ERR_BAD_FILE;
    *err_info = g_strdup_printf("stanag4607: File has %" G_GUINT32_FORMAT "d-byte packet, "
      "bigger than maximum of %u", packet_size, WTAP_MAX_PACKET_SIZE_STANDARD);
    return FALSE;
  }
  if (packet_size < PKT_HDR_SIZE+SEG_HDR_SIZE) {
    /*
     * Probably a corrupt capture file; don't, for example, loop
     * infinitely if the size is zero.
     */
    *err = WTAP_ERR_BAD_FILE;
    *err_info = g_strdup_printf("stanag4607: File has %" G_GUINT32_FORMAT "d-byte packet, "
      "smaller than minimum of %u", packet_size, PKT_HDR_SIZE+SEG_HDR_SIZE);
    return FALSE;
  }
  rec->rec_header.packet_header.caplen = packet_size;
  rec->rec_header.packet_header.len = packet_size;

  /* Sadly, the header doesn't contain times; but some segments do */
  /* So, get the segment header, which is just past the 32-byte header. */
  rec->presence_flags = WTAP_HAS_TS;

  /* If no time specified, it's the last baseline time */
  rec->ts.secs = stanag4607->base_secs;
  rec->ts.nsecs = 0;
  millisecs = 0;

#define MISSION_SEGMENT 1
#define DWELL_SEGMENT 2
#define JOB_DEFINITION_SEGMENT 5
#define PLATFORM_LOCATION_SEGMENT 13
  if (MISSION_SEGMENT == stanag_pkt_hdr[32]) {
    guint8 mseg[39];
    struct tm tm;

    if (!wtap_read_bytes(fh, &mseg, sizeof mseg, err, err_info))
      return FALSE;
    offset += sizeof mseg;

    tm.tm_year = pntoh16(&mseg[35]) - 1900;
    tm.tm_mon = mseg[37] - 1;
    tm.tm_mday = mseg[38];
    tm.tm_hour = 0;
    tm.tm_min = 0;
    tm.tm_sec = 0;
    tm.tm_isdst = -1;
    stanag4607->base_secs = mktime(&tm);
    rec->ts.secs = stanag4607->base_secs;
  }
  else if (PLATFORM_LOCATION_SEGMENT == stanag_pkt_hdr[32]) {
    if (!wtap_read_bytes(fh, &millisecs, sizeof millisecs, err, err_info))
      return FALSE;
    offset += sizeof millisecs;
    millisecs = g_ntohl(millisecs);
  }
  else if (DWELL_SEGMENT == stanag_pkt_hdr[32]) {
    guint8 dseg[19];
    if (!wtap_read_bytes(fh, &dseg, sizeof dseg, err, err_info))
      return FALSE;
    offset += sizeof dseg;
    millisecs = pntoh32(&dseg[15]);
  }
  if (0 != millisecs) {
    secs = millisecs/1000;
    nsecs = (millisecs - 1000 * secs) * 1000000;
    rec->ts.secs = stanag4607->base_secs + secs;
    rec->ts.nsecs = nsecs;
  }

  /* wind back to the start of the packet ... */
  if (file_seek(fh, - offset, SEEK_CUR, err) == -1)
    return FALSE;

  return wtap_read_packet_bytes(fh, buf, packet_size, err, err_info);
}
Ejemplo n.º 17
0
wtap_open_return_val
pppdump_open(wtap *wth, int *err, gchar **err_info)
{
	guint8		buffer[6];	/* Looking for: 0x07 t3 t2 t1 t0 ID */
	pppdump_t	*state;

	/* There is no file header, only packet records. Fortunately for us,
	* timestamp records are separated from packet records, so we should
	* find an "initial time stamp" (i.e., a "reset time" record, or
	* record type 0x07) at the beginning of the file. We'll check for
	* that, plus a valid record following the 0x07 and the four bytes
	* representing the timestamp.
	*/

	if (!wtap_read_bytes(wth->fh, buffer, sizeof(buffer),
	    err, err_info)) {
		if (*err != WTAP_ERR_SHORT_READ)
			return WTAP_OPEN_ERROR;
		return WTAP_OPEN_NOT_MINE;
	}

	if (buffer[0] == PPPD_RESET_TIME &&
			(buffer[5] == PPPD_SENT_DATA ||
			 buffer[5] == PPPD_RECV_DATA ||
			 buffer[5] == PPPD_TIME_STEP_LONG ||
			 buffer[5] == PPPD_TIME_STEP_SHORT ||
			 buffer[5] == PPPD_RESET_TIME)) {

		goto my_file_type;
	}
	else {
		return WTAP_OPEN_NOT_MINE;
	}

  my_file_type:

	if (file_seek(wth->fh, 5, SEEK_SET, err) == -1)
		return WTAP_OPEN_ERROR;

	state = (pppdump_t *)g_malloc(sizeof(pppdump_t));
	wth->priv = (void *)state;
	state->timestamp = pntoh32(&buffer[1]);
	state->tenths = 0;

	init_state(state);

	state->offset = 5;
	wth->file_encap = WTAP_ENCAP_PPP_WITH_PHDR;
	wth->file_type_subtype = WTAP_FILE_TYPE_SUBTYPE_PPPDUMP;

	wth->snapshot_length = PPPD_BUF_SIZE; /* just guessing */
	wth->subtype_read = pppdump_read;
	wth->subtype_seek_read = pppdump_seek_read;
	wth->subtype_close = pppdump_close;
	wth->file_tsprec = WTAP_TSPREC_DSEC;

	state->seek_state = g_new(pppdump_t,1);

	/* If we have a random stream open, we're going to be reading
	   the file randomly; set up a GPtrArray of pointers to
	   information about how to retrieve the data for each packet. */
	if (wth->random_fh != NULL)
		state->pids = g_ptr_array_new();
	else
		state->pids = NULL;
	state->pkt_cnt = 0;

	return WTAP_OPEN_MINE;
}
Ejemplo n.º 18
0
wtap_open_return_val k12_open(wtap *wth, int *err, gchar **err_info) {
    k12_src_desc_t* rec;
    guint8 header_buffer[K12_FILE_HDR_LEN];
    guint8* read_buffer;
    guint32 type;
    long offset;
    long len;
    guint port_type;
    guint32 rec_len;
    guint32 hwpart_len;
    guint32 name_len;
    guint32 stack_len;
    guint i;
    k12_t* file_data;

#ifdef DEBUG_K12
    gchar* env_level = getenv("K12_DEBUG_LEVEL");
    env_file = getenv("K12_DEBUG_FILENAME");
    if ( env_file ) {
        dbg_out = ws_fopen(env_file,"w");
        if (dbg_out == NULL) {
                dbg_out = stderr;
                K12_DBG(1,("unable to open K12 DEBUG FILENAME for writing!  Logging to standard error"));
        }
    }
    else
        dbg_out = stderr;
    if ( env_level ) debug_level = (unsigned int)strtoul(env_level,NULL,10);
    K12_DBG(1,("k12_open: ENTER debug_level=%u",debug_level));
#endif

    if ( !wtap_read_bytes(wth->fh,header_buffer,K12_FILE_HDR_LEN,err,err_info) ) {
        K12_DBG(1,("k12_open: FILE HEADER TOO SHORT OR READ ERROR"));
        if (*err != WTAP_ERR_SHORT_READ) {
            return WTAP_OPEN_ERROR;
        }
        return WTAP_OPEN_NOT_MINE;
    }

    if ( memcmp(header_buffer,k12_file_magic,8) != 0 ) {
        K12_DBG(1,("k12_open: BAD MAGIC"));
        return WTAP_OPEN_NOT_MINE;
    }

    offset = K12_FILE_HDR_LEN;

    file_data = new_k12_file_data();

    file_data->file_len = pntoh32( header_buffer + 0x8);
    if (memiszero(header_buffer + 0x10, K12_FILE_HDR_LEN - 0x10)) {
        /*
         * The rest of the file header is all zeroes.  That means
         * this is a file written by the old Wireshark code, and
         * a count of records in the file is at an offset of 0x0C.
         */
        file_data->num_of_records = pntoh32( header_buffer + 0x0C );
    } else {
        /*
         * There's at least one non-zero byte in the rest of the
         * header.  The value 8192 is at 0xC (page size?), and
         * what appears to be the number of records in the file
         * is at an offset of 0x24 and at an offset of 0x2c.
         *
         * If the two values are not the same, we fail; if that's
         * the case, we need to see the file to figure out which
         * of those two values, if any, is the count.
         */
        file_data->num_of_records = pntoh32( header_buffer + K12_FILE_HDR_RECORD_COUNT_1 );
        if ( file_data->num_of_records != pntoh32( header_buffer + K12_FILE_HDR_RECORD_COUNT_2 ) ) {
            *err = WTAP_ERR_BAD_FILE;
            *err_info = g_strdup_printf("k12: two different record counts, %u at 0x%02x and %u at 0x%02x",
                                        file_data->num_of_records,
                                        K12_FILE_HDR_RECORD_COUNT_1,
                                        pntoh32( header_buffer + K12_FILE_HDR_RECORD_COUNT_2 ),
                                        K12_FILE_HDR_RECORD_COUNT_2 );
            return WTAP_OPEN_ERROR;
        }
    }

    K12_DBG(5,("k12_open: FILE_HEADER OK: offset=%x file_len=%i records=%i",
            offset,
            file_data->file_len,
            file_data->num_of_records ));

    do {
        if ( file_data->num_of_records == 0 ) {
            *err = WTAP_ERR_SHORT_READ;
            destroy_k12_file_data(file_data);
            return WTAP_OPEN_ERROR;
        }

        len = get_record(file_data, wth->fh, offset, FALSE, err, err_info);

        if ( len < 0 ) {
            K12_DBG(1,("k12_open: BAD HEADER RECORD",len));
            destroy_k12_file_data(file_data);
            return WTAP_OPEN_ERROR;
        }
        if ( len == 0 ) {
            K12_DBG(1,("k12_open: BAD HEADER RECORD",len));
            *err = WTAP_ERR_SHORT_READ;
            destroy_k12_file_data(file_data);
            return WTAP_OPEN_ERROR;
        }

        read_buffer = file_data->seq_read_buff;

        rec_len = pntoh32( read_buffer + K12_RECORD_LEN );
        if (rec_len < K12_RECORD_TYPE + 4) {
            /* Record isn't long enough to have a type field */
            *err = WTAP_ERR_BAD_FILE;
            *err_info = g_strdup_printf("k12_open: record length %u < %u",
                                        rec_len, K12_RECORD_TYPE + 4);
            return WTAP_OPEN_ERROR;
        }
        type = pntoh32( read_buffer + K12_RECORD_TYPE );

        if ( (type & K12_MASK_PACKET) == K12_REC_PACKET ||
             (type & K12_MASK_PACKET) == K12_REC_D0020) {
            /*
             * we are at the first packet record, rewind and leave.
             */
            if (file_seek(wth->fh, offset, SEEK_SET, err) == -1) {
                destroy_k12_file_data(file_data);
                return WTAP_OPEN_ERROR;
            }
            K12_DBG(5,("k12_open: FIRST PACKET offset=%x",offset));
            break;
        }

        switch (type) {

        case K12_REC_SRCDSC:
        case K12_REC_SRCDSC2:
            rec = g_new0(k12_src_desc_t,1);

            if (rec_len < K12_SRCDESC_HWPART) {
                /*
                 * Record isn't long enough to have the fixed-length portion
                 * of the source descriptor field.
                 */
                *err = WTAP_ERR_BAD_FILE;
                *err_info = g_strdup_printf("k12_open: source descriptor record length %u < %u",
                                            rec_len, K12_SRCDESC_HWPART);
                destroy_k12_file_data(file_data);
                g_free(rec);
                return WTAP_OPEN_ERROR;
            }
            port_type = read_buffer[K12_SRCDESC_PORT_TYPE];
            hwpart_len = pntoh16( read_buffer + K12_SRCDESC_HWPARTLEN );
            name_len = pntoh16( read_buffer + K12_SRCDESC_NAMELEN );
            stack_len = pntoh16( read_buffer + K12_SRCDESC_STACKLEN );

            rec->input = pntoh32( read_buffer + K12_RECORD_SRC_ID );

            K12_DBG(5,("k12_open: INTERFACE RECORD offset=%x interface=%x",offset,rec->input));

            if (name_len == 0) {
                K12_DBG(5,("k12_open: failed (name_len == 0 in source description"));
                destroy_k12_file_data(file_data);
                g_free(rec);
                return WTAP_OPEN_NOT_MINE;
            }
            if (stack_len == 0) {
                K12_DBG(5,("k12_open: failed (stack_len == 0 in source description"));
                destroy_k12_file_data(file_data);
                g_free(rec);
                return WTAP_OPEN_NOT_MINE;
            }
            if (rec_len < K12_SRCDESC_HWPART + hwpart_len + name_len + stack_len) {
                /*
                 * Record isn't long enough to have the full source descriptor
                 * field, including the variable-length parts.
                 */
                *err = WTAP_ERR_BAD_FILE;
                *err_info = g_strdup_printf("k12_open: source descriptor record length %u < %u (%u + %u + %u + %u)",
                                            rec_len,
                                            K12_SRCDESC_HWPART + hwpart_len + name_len + stack_len,
                                            K12_SRCDESC_HWPART, hwpart_len, name_len, stack_len);
                destroy_k12_file_data(file_data);
                g_free(rec);
                return WTAP_OPEN_ERROR;
            }

            if (hwpart_len) {
                if (hwpart_len < 4) {
                    /* Hardware part isn't long enough to have a type field */
                    *err = WTAP_ERR_BAD_FILE;
                    *err_info = g_strdup_printf("k12_open: source descriptor hardware part length %u < 4",
                                                hwpart_len);
                    destroy_k12_file_data(file_data);
                    g_free(rec);
                    return WTAP_OPEN_ERROR;
                }
                switch(( rec->input_type = pntoh32( read_buffer + K12_SRCDESC_HWPART + K12_SRCDESC_HWPARTTYPE ) )) {
                    case K12_PORT_DS0S:
                        /* This appears to be variable-length */
                        rec->input_info.ds0mask = 0x00000000;
                        if (hwpart_len > K12_SRCDESC_DS0_MASK) {
                            for (i = 0; i < hwpart_len - K12_SRCDESC_DS0_MASK; i++) {
                                rec->input_info.ds0mask |= ( *(read_buffer + K12_SRCDESC_HWPART + K12_SRCDESC_DS0_MASK + i) == 0xff ) ? 1U<<(31-i) : 0x0;
                            }
                        }
                        break;
                    case K12_PORT_ATMPVC:
                        if (hwpart_len < K12_SRCDESC_ATM_VCI + 2) {
                            /* Hardware part isn't long enough to have ATM information */
                            *err = WTAP_ERR_BAD_FILE;
                            *err_info = g_strdup_printf("k12_open: source descriptor hardware part length %u < %u",
                                                        hwpart_len,
                                                        K12_SRCDESC_ATM_VCI + 2);
                            destroy_k12_file_data(file_data);
                            g_free(rec);
                            return WTAP_OPEN_ERROR;
                        }

                        rec->input_info.atm.vp = pntoh16( read_buffer + K12_SRCDESC_HWPART + K12_SRCDESC_ATM_VPI );
                        rec->input_info.atm.vc = pntoh16( read_buffer + K12_SRCDESC_HWPART + K12_SRCDESC_ATM_VCI );
                        break;
                    default:
                        break;
                }
            } else {
                /* Record viewer generated files don't have this information */
                if (port_type >= 0x14
                    && port_type <= 0x17) {
                    /* For ATM2_E1DS1, ATM2_E3DS3,
                       ATM2_STM1EL and ATM2_STM1OP */
                    rec->input_type = K12_PORT_ATMPVC;
                    rec->input_info.atm.vp = 0;
                    rec->input_info.atm.vc = 0;
                }
            }

            if (read_buffer[K12_SRCDESC_HWPART + hwpart_len + name_len - 1] != '\0') {
                *err = WTAP_ERR_BAD_FILE;
                *err_info = g_strdup("k12_open: source descriptor record contains non-null-terminated link-layer name");
                destroy_k12_file_data(file_data);
                g_free(rec);
                return WTAP_OPEN_ERROR;
            }
            if (read_buffer[K12_SRCDESC_HWPART + hwpart_len + name_len + stack_len - 1] != '\0') {
                *err = WTAP_ERR_BAD_FILE;
                *err_info = g_strdup("k12_open: source descriptor record contains non-null-terminated stack path");
                destroy_k12_file_data(file_data);
                g_free(rec);
                return WTAP_OPEN_ERROR;
            }
            rec->input_name = (gchar *)g_memdup(read_buffer + K12_SRCDESC_HWPART + hwpart_len, name_len);
            rec->stack_file = (gchar *)g_memdup(read_buffer + K12_SRCDESC_HWPART + hwpart_len + name_len, stack_len);

            ascii_strdown_inplace (rec->stack_file);

            g_hash_table_insert(file_data->src_by_id,GUINT_TO_POINTER(rec->input),rec);
            g_hash_table_insert(file_data->src_by_name,rec->stack_file,rec);
            break;

        case K12_REC_STK_FILE:
            K12_DBG(1,("k12_open: K12_REC_STK_FILE"));
            K12_DBG(1,("Field 1: 0x%08x",pntoh32( read_buffer + 0x08 )));
            K12_DBG(1,("Field 2: 0x%08x",pntoh32( read_buffer + 0x0c )));
            K12_ASCII_DUMP(1, read_buffer, rec_len, 16);
            break;

        default:
            K12_DBG(1,("k12_open: RECORD TYPE 0x%08x",type));
            break;
        }
        offset += len;
        file_data->num_of_records--;
    } while(1);

    wth->file_type_subtype = WTAP_FILE_TYPE_SUBTYPE_K12;
    wth->file_encap = WTAP_ENCAP_K12;
    wth->snapshot_length = 0;
    wth->subtype_read = k12_read;
    wth->subtype_seek_read = k12_seek_read;
    wth->subtype_close = k12_close;
    wth->priv = (void *)file_data;
    wth->file_tsprec = WTAP_TSPREC_NSEC;

    return WTAP_OPEN_MINE;
}
Ejemplo n.º 19
0
/* Read the next packet */
static gboolean netmon_read(wtap *wth, int *err, gchar **err_info,
    gint64 *data_offset)
{
	netmon_t *netmon = (netmon_t *)wth->priv;
	gint64	rec_offset;

again:
	/* Have we reached the end of the packet data? */
	if (netmon->current_frame >= netmon->frame_table_size) {
		/* Yes.  We won't need the frame table any more;
		   free it. */
		g_free(netmon->frame_table);
		netmon->frame_table = NULL;
		*err = 0;	/* it's just an EOF, not an error */
		return FALSE;
	}

	/* Seek to the beginning of the current record, if we're
	   not there already (seeking to the current position
	   may still cause a seek and a read of the underlying file,
	   so we don't want to do it unconditionally).

	   Yes, the current record could be before the previous
	   record.  At least some captures put the trailer record
	   with statistics as the first physical record in the
	   file, but set the frame table up so it's the last
	   record in sequence. */
	rec_offset = netmon->frame_table[netmon->current_frame];
	if (file_tell(wth->fh) != rec_offset) {
		if (file_seek(wth->fh, rec_offset, SEEK_SET, err) == -1)
			return FALSE;
	}
	netmon->current_frame++;

	*data_offset = file_tell(wth->fh);

	if (!netmon_process_rec_header(wth, wth->fh, &wth->phdr,
	    err, err_info))
		return FALSE;

	if (!wtap_read_packet_bytes(wth->fh, wth->frame_buffer,
	    wth->phdr.caplen, err, err_info))
		return FALSE;	/* Read error */

	/*
	 * For version 2.1 and later, there's additional information
	 * after the frame data.
	 */
	switch (netmon_process_rec_trailer(netmon, wth->fh, &wth->phdr,
	    err, err_info)) {

	case RETRY:
		goto again;

	case SUCCESS:
		break;

	case FAILURE:
		return FALSE;
	}

	netmon_set_pseudo_header_info(wth->phdr.pkt_encap,
	    &wth->phdr.pseudo_header, wth->frame_buffer, wth->phdr.caplen);
	return TRUE;
}
Ejemplo n.º 20
0
int nettl_open(wtap *wth, int *err, gchar **err_info)
{
    struct nettl_file_hdr file_hdr;
    guint16 dummy[2];
    int subsys;
    int bytes_read;
    nettl_t *nettl;

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

    /* Read in the string that should be at the start of a HP file */
    errno = WTAP_ERR_CANT_READ;
    bytes_read = file_read(file_hdr.magic, MAGIC_SIZE, wth->fh);
    if (bytes_read != MAGIC_SIZE) {
    	*err = file_error(wth->fh, err_info);
	if (*err != 0 && *err != WTAP_ERR_SHORT_READ)
	    return -1;
	return 0;
    }

    if (memcmp(file_hdr.magic, nettl_magic_hpux9, MAGIC_SIZE) &&
        memcmp(file_hdr.magic, nettl_magic_hpux10, MAGIC_SIZE)) {
	return 0;
    }

    /* Read the rest of the file header */
    bytes_read = file_read(file_hdr.file_name, FILE_HDR_SIZE - MAGIC_SIZE,
			   wth->fh);
    if (bytes_read != FILE_HDR_SIZE - MAGIC_SIZE) {
	*err = file_error(wth->fh, err_info);
	if (*err == 0)
	    *err = WTAP_ERR_SHORT_READ;
	return -1;
    }

    /* This is an nettl file */
    wth->file_type_subtype = WTAP_FILE_TYPE_SUBTYPE_NETTL;
    nettl = g_new(nettl_t,1);
    wth->priv = (void *)nettl;
    if (file_hdr.os_vers[2] == '1' && file_hdr.os_vers[3] == '1')
	nettl->is_hpux_11 = TRUE;
    else
	nettl->is_hpux_11 = FALSE;
    wth->subtype_read = nettl_read;
    wth->subtype_seek_read = nettl_seek_read;
    wth->snapshot_length = 0;	/* not available */

    /* read the first header to take a guess at the file encap */
    bytes_read = file_read(dummy, 4, wth->fh);
    if (bytes_read != 4) {
        if (*err != 0) {
            return -1;
        }
        if (bytes_read != 0) {
            *err = WTAP_ERR_SHORT_READ;
            return -1;
        }
        return 0;
    }

    subsys = g_ntohs(dummy[1]);
    switch (subsys) {
        case NETTL_SUBSYS_HPPB_FDDI :
        case NETTL_SUBSYS_EISA_FDDI :
        case NETTL_SUBSYS_PCI_FDDI :
        case NETTL_SUBSYS_HSC_FDDI :
		wth->file_encap = WTAP_ENCAP_NETTL_FDDI;
		break;
        case NETTL_SUBSYS_TOKEN :
        case NETTL_SUBSYS_PCI_TR :
		wth->file_encap = WTAP_ENCAP_NETTL_TOKEN_RING;
		break;
        case NETTL_SUBSYS_NS_LS_IP :
        case NETTL_SUBSYS_NS_LS_LOOPBACK :
        case NETTL_SUBSYS_NS_LS_TCP :
        case NETTL_SUBSYS_NS_LS_UDP :
        case NETTL_SUBSYS_NS_LS_IPV6 :
		wth->file_encap = WTAP_ENCAP_NETTL_RAW_IP;
		break;
        case NETTL_SUBSYS_NS_LS_ICMP :
		wth->file_encap = WTAP_ENCAP_NETTL_RAW_ICMP;
		break;
        case NETTL_SUBSYS_NS_LS_ICMPV6 :
		wth->file_encap = WTAP_ENCAP_NETTL_RAW_ICMPV6;
		break;
        case NETTL_SUBSYS_NS_LS_TELNET :
		wth->file_encap = WTAP_ENCAP_NETTL_RAW_TELNET;
		break;
	default:
		/* If this assumption is bad, the read will catch it */
		wth->file_encap = WTAP_ENCAP_NETTL_ETHERNET;
    }

    if (file_seek(wth->fh, FILE_HDR_SIZE, SEEK_SET, err) == -1) {
	return -1;
    }
    wth->tsprecision = WTAP_FILE_TSPREC_USEC;

    return 1;
}
Ejemplo n.º 21
0
/*
 * See
 *
 *	http://www.opengroup.org/onlinepubs/9638599/apdxf.htm
 *
 * for the "dlpi.h" header file specified by The Open Group, which lists
 * the DL_ values for various protocols; Solaris 7 uses the same values.
 *
 * See
 *
 *	http://www.iana.org/assignments/snoop-datalink-types/snoop-datalink-types.xml
 *
 * for the IETF list of snoop datalink types.
 *
 * The page at
 *
 *	http://mrpink.lerc.nasa.gov/118x/support.html
 *
 * had links to modified versions of "tcpdump" and "libpcap" for SUNatm
 * DLPI support; they suggested that the 3.0 verson of SUNatm uses those
 * values.  The Wayback Machine archived that page, but not the stuff
 * to which it linked, unfortunately.
 *
 * It also has a link to "convert.c", which is a program to convert files
 * from the format written by the "atmsnoop" program that comes with the
 * SunATM package to regular "snoop" format, claims that "SunATM 2.1 claimed
 * to be DL_FDDI (don't ask why).  SunATM 3.0 claims to be DL_IPATM, which
 * is 0x12".
 *
 * It also says that "ATM Mac header is 12 bytes long.", and seems to imply
 * that in an "atmsnoop" file, the header contains 2 bytes (direction and
 * VPI?), 2 bytes of VCI, 6 bytes of something, and 2 bytes of Ethernet
 * type; if those 6 bytes are 2 bytes of DSAP, 2 bytes of LSAP, 1 byte
 * of LLC control, and 3 bytes of SNAP OUI, that'd mean that an ATM
 * pseudo-header in an "atmsnoop" file is probably 1 byte of direction,
 * 1 byte of VPI, and 2 bytes of VCI.
 *
 * The aforementioned page also has a link to some capture files from
 * "atmsnoop"; this version of "snoop.c" appears to be able to read them.
 *
 * Source to an "atmdump" package, which includes a modified version of
 * "libpcap" to handle SunATM DLPI and an ATM driver for FreeBSD, and
 * also includes "atmdump", which is a modified "tcpdump", was available
 * at
 *
 *	ftp://ftp.cs.ndsu.nodak.edu/pub/freebsd/atm/atm-bpf.tgz
 *
 * (the host name is no longer valid) and that code also indicated that
 * DL_IPATM is used, and that an ATM packet handed up from the Sun driver
 * for the Sun SBus ATM card on Solaris 2.5.1 has 1 byte of direction,
 * 1 byte of VPI, 2 bytes of VCI, and then the ATM PDU, and suggests that
 * the direction flag is 0x80 for "transmitted" (presumably meaning
 * DTE->DCE) and presumably not 0x80 for "received" (presumably meaning
 * DCE->DTE).  That code was used as the basis for the SunATM support in
 * later versions of libpcap and tcpdump, and it worked at the time the
 * development was done with the SunATM code on the system on which the
 * development was done.
 *
 * In fact, the "direction" byte appears to have some other stuff, perhaps
 * a traffic type, in the lower 7 bits, with the 8th bit indicating the
 * direction.  That appears to be the case.
 *
 * I don't know what the encapsulation of any of the other types is, so I
 * leave them all as WTAP_ENCAP_UNKNOWN, except for those for which Brian
 * Ginsbach has supplied information about the way UNICOS/mp uses them.
 * I also don't know whether "snoop" can handle any of them (it presumably
 * can't handle ATM, otherwise Sun wouldn't have supplied "atmsnoop"; even
 * if it can't, this may be useful reference information for anybody doing
 * code to use DLPI to do raw packet captures on those network types.
 *
 * Once upon a time
 *
 *	http://web.archive.org/web/20010906213807/http://www.shomiti.com/support/TNCapFileFormat.htm
 *
 * gave information on Shomiti's mutant flavor of snoop; Shomiti's Web site
 * is no longer available on the Wayback Machine.  For some unknown reason,
 * they decided not to just Go With The DLPI Flow, and instead used the types
 * unspecified in RFC 1461 for their own nefarious purposes, such as
 * distinguishing 10MB from 100MB from 1000MB Ethernet and distinguishing
 * 4MB from 16MB Token Ring, and distinguishing both of them from the
 * "Shomiti" versions of same.
 */
int snoop_open(wtap *wth, int *err, gchar **err_info)
{
	int bytes_read;
	char magic[sizeof snoop_magic];
	struct snoop_hdr hdr;
	struct snooprec_hdr rec_hdr;
	guint padbytes;
	gboolean is_shomiti;
	static const int snoop_encap[] = {
		WTAP_ENCAP_ETHERNET,	/* IEEE 802.3 */
		WTAP_ENCAP_UNKNOWN,	/* IEEE 802.4 Token Bus */
		WTAP_ENCAP_TOKEN_RING,
		WTAP_ENCAP_UNKNOWN,	/* IEEE 802.6 Metro Net */
		WTAP_ENCAP_ETHERNET,
		WTAP_ENCAP_UNKNOWN,	/* HDLC */
		WTAP_ENCAP_UNKNOWN,	/* Character Synchronous, e.g. bisync */
		WTAP_ENCAP_UNKNOWN,	/* IBM Channel-to-Channel */
		WTAP_ENCAP_FDDI_BITSWAPPED,
		WTAP_ENCAP_NULL,	/* Other */
		WTAP_ENCAP_UNKNOWN,	/* Frame Relay LAPF */
		WTAP_ENCAP_UNKNOWN,	/* Multi-protocol over Frame Relay */
		WTAP_ENCAP_UNKNOWN,	/* Character Async (e.g., SLIP and PPP?) */
		WTAP_ENCAP_UNKNOWN,	/* X.25 Classical IP */
		WTAP_ENCAP_NULL,	/* software loopback */
		WTAP_ENCAP_UNKNOWN,	/* not defined in "dlpi.h" */
		WTAP_ENCAP_IP_OVER_FC,	/* Fibre Channel */
		WTAP_ENCAP_UNKNOWN,	/* ATM */
		WTAP_ENCAP_ATM_PDUS,	/* ATM Classical IP */
		WTAP_ENCAP_UNKNOWN,	/* X.25 LAPB */
		WTAP_ENCAP_UNKNOWN,	/* ISDN */
		WTAP_ENCAP_UNKNOWN,	/* HIPPI */
		WTAP_ENCAP_UNKNOWN,	/* 100VG-AnyLAN Ethernet */
		WTAP_ENCAP_UNKNOWN,	/* 100VG-AnyLAN Token Ring */
		WTAP_ENCAP_UNKNOWN,	/* "ISO 8802/3 and Ethernet" */
		WTAP_ENCAP_UNKNOWN,	/* 100BaseT (but that's just Ethernet) */
		WTAP_ENCAP_IP_OVER_IB,	/* Infiniband */
	};
	#define NUM_SNOOP_ENCAPS (sizeof snoop_encap / sizeof snoop_encap[0])
	#define SNOOP_PRIVATE_BIT 0x80000000
	static const int snoop_private_encap[] = {
		WTAP_ENCAP_UNKNOWN,	/* Not Used */
		WTAP_ENCAP_UNKNOWN,	/* IPv4 Tunnel Link */
		WTAP_ENCAP_UNKNOWN,	/* IPv6 Tunnel Link */
		WTAP_ENCAP_UNKNOWN,	/* Virtual network interface */
		WTAP_ENCAP_UNKNOWN,	/* IEEE 802.11 */
		WTAP_ENCAP_IPNET,	/* ipnet(7D) link */
		WTAP_ENCAP_UNKNOWN,	/* IPMP stub interface */
		WTAP_ENCAP_UNKNOWN,	/* 6to4 Tunnel Link */
	};
	#define NUM_SNOOP_PRIVATE_ENCAPS (sizeof snoop_private_encap / sizeof snoop_private_encap[0])
	static const int shomiti_encap[] = {
		WTAP_ENCAP_ETHERNET,	/* IEEE 802.3 */
		WTAP_ENCAP_UNKNOWN,	/* IEEE 802.4 Token Bus */
		WTAP_ENCAP_TOKEN_RING,
		WTAP_ENCAP_UNKNOWN,	/* IEEE 802.6 Metro Net */
		WTAP_ENCAP_ETHERNET,
		WTAP_ENCAP_UNKNOWN,	/* HDLC */
		WTAP_ENCAP_UNKNOWN,	/* Character Synchronous, e.g. bisync */
		WTAP_ENCAP_UNKNOWN,	/* IBM Channel-to-Channel */
		WTAP_ENCAP_FDDI_BITSWAPPED,
		WTAP_ENCAP_UNKNOWN,	/* Other */
		WTAP_ENCAP_ETHERNET,	/* Fast Ethernet */
		WTAP_ENCAP_TOKEN_RING,	/* 4MB 802.5 token ring */
		WTAP_ENCAP_ETHERNET,	/* Gigabit Ethernet */
		WTAP_ENCAP_TOKEN_RING,	/* "IEEE 802.5 Shomiti" */
		WTAP_ENCAP_TOKEN_RING,	/* "4MB IEEE 802.5 Shomiti" */
		WTAP_ENCAP_UNKNOWN,	/* Other */
		WTAP_ENCAP_UNKNOWN,	/* Other */
		WTAP_ENCAP_UNKNOWN,	/* Other */
		WTAP_ENCAP_IEEE_802_11_WITH_RADIO, /* IEEE 802.11 with Radio Header */
		WTAP_ENCAP_ETHERNET,	/* 10 Gigabit Ethernet */
	};
	#define NUM_SHOMITI_ENCAPS (sizeof shomiti_encap / sizeof shomiti_encap[0])
	int file_encap;
	gint64 saved_offset;

	/* Read in the string that should be at the start of a "snoop" file */
	errno = WTAP_ERR_CANT_READ;
	bytes_read = file_read(magic, sizeof magic, wth->fh);
	if (bytes_read != sizeof magic) {
		*err = file_error(wth->fh, err_info);
		if (*err != 0 && *err != WTAP_ERR_SHORT_READ)
			return -1;
		return 0;
	}

	if (memcmp(magic, snoop_magic, sizeof snoop_magic) != 0) {
		return 0;
	}

	/* Read the rest of the header. */
	errno = WTAP_ERR_CANT_READ;
	bytes_read = file_read(&hdr, sizeof hdr, wth->fh);
	if (bytes_read != sizeof hdr) {
		*err = file_error(wth->fh, err_info);
		if (*err == 0)
			*err = WTAP_ERR_SHORT_READ;
		return -1;
	}

	/*
	 * Make sure it's a version we support.
	 */
	hdr.version = g_ntohl(hdr.version);
	switch (hdr.version) {

	case 2:		/* Solaris 2.x and later snoop, and Shomiti
			   Surveyor prior to 3.0, or 3.0 and later
			   with NDIS card */
	case 3:		/* Surveyor 3.0 and later, with Shomiti CMM2 hardware */
	case 4:		/* Surveyor 3.0 and later, with Shomiti GAM hardware */
	case 5:		/* Surveyor 3.0 and later, with Shomiti THG hardware */
		break;

	default:
		*err = WTAP_ERR_UNSUPPORTED;
		*err_info = g_strdup_printf("snoop: version %u unsupported", hdr.version);
		return -1;
	}

	/*
	 * Oh, this is lovely.
	 *
	 * I suppose Shomiti could give a bunch of lawyerly noise about
	 * how "well, RFC 1761 said they were unassigned, and that's
	 * the standard, not the DLPI header file, so it's perfectly OK
	 * for us to use them, blah blah blah", but it's still irritating
	 * as hell that they used the unassigned-in-RFC-1761 values for
	 * their own purposes - especially given that Sun also used
	 * one of them in atmsnoop.
	 *
	 * We can't determine whether it's a Shomiti capture based on
	 * the version number, as, according to their documentation on
	 * their capture file format, Shomiti uses a version number of 2
	 * if the data "was captured using an NDIS card", which presumably
	 * means "captured with an ordinary boring network card via NDIS"
	 * as opposed to "captured with our whizzo special capture
	 * hardware".
	 *
	 * The only way I can see to determine that is to check how much
	 * padding there is in the first packet - if there's enough
	 * padding for a Shomiti trailer, it's probably a Shomiti
	 * capture, and otherwise, it's probably from Snoop.
	 */

	/*
	 * Start out assuming it's not a Shomiti capture.
	 */
	is_shomiti = FALSE;

	/* Read first record header. */
	saved_offset = file_tell(wth->fh);
	errno = WTAP_ERR_CANT_READ;
	bytes_read = file_read(&rec_hdr, sizeof rec_hdr, wth->fh);
	if (bytes_read != sizeof rec_hdr) {
		*err = file_error(wth->fh, err_info);
		if (*err == 0)
			*err = WTAP_ERR_SHORT_READ;
		return -1;

		/*
		 * The file ends after the record header, which means this
		 * is a capture with no packets.
		 *
		 * We assume it's a snoop file; the actual type of file is
		 * irrelevant, as there are no records in it, and thus no
		 * extra information if it's a Shomiti capture, and no
		 * link-layer headers whose type we have to know, and no
		 * Ethernet frames that might have an FCS.
		 */
	} else {
		/*
		 * Compute the number of bytes of padding in the
		 * record.  If it's at least the size of a Shomiti
		 * trailer record, we assume this is a Shomiti
		 * capture.  (Some atmsnoop captures appear
		 * to have 4 bytes of padding, and at least one
		 * snoop capture appears to have 6 bytes of padding;
		 * the Shomiti header is larger than either of those.)
		 */
		if (g_ntohl(rec_hdr.rec_len) >
		    (sizeof rec_hdr + g_ntohl(rec_hdr.incl_len))) {
			/*
			 * Well, we have padding; how much?
			 */
			padbytes = g_ntohl(rec_hdr.rec_len) -
			    ((guint)sizeof rec_hdr + g_ntohl(rec_hdr.incl_len));

			/*
			 * Is it at least the size of a Shomiti trailer?
			 */
			is_shomiti =
			    (padbytes >= sizeof (struct shomiti_trailer));
		}
	}

	/*
	 * Seek back to the beginning of the first record.
	 */
	if (file_seek(wth->fh, saved_offset, SEEK_SET, err) == -1)
		return -1;

	hdr.network = g_ntohl(hdr.network);
	if (is_shomiti) {
		if (hdr.network >= NUM_SHOMITI_ENCAPS
		    || shomiti_encap[hdr.network] == WTAP_ENCAP_UNKNOWN) {
			*err = WTAP_ERR_UNSUPPORTED_ENCAP;
			*err_info = g_strdup_printf("snoop: Shomiti network type %u unknown or unsupported",
			    hdr.network);
			return -1;
		}
		file_encap = shomiti_encap[hdr.network];

		/* This is a Shomiti file */
		wth->file_type_subtype = WTAP_FILE_TYPE_SUBTYPE_SHOMITI;
	} else if (hdr.network & SNOOP_PRIVATE_BIT) {
		if ((hdr.network^SNOOP_PRIVATE_BIT) >= NUM_SNOOP_PRIVATE_ENCAPS
		    || snoop_private_encap[hdr.network^SNOOP_PRIVATE_BIT] == WTAP_ENCAP_UNKNOWN) {
			*err = WTAP_ERR_UNSUPPORTED_ENCAP;
			*err_info = g_strdup_printf("snoop: private network type %u unknown or unsupported",
			    hdr.network);
			return -1;
		}
		file_encap = snoop_private_encap[hdr.network^SNOOP_PRIVATE_BIT];

		/* This is a snoop file */
		wth->file_type_subtype = WTAP_FILE_TYPE_SUBTYPE_SNOOP;
	} else {
		if (hdr.network >= NUM_SNOOP_ENCAPS
		    || snoop_encap[hdr.network] == WTAP_ENCAP_UNKNOWN) {
			*err = WTAP_ERR_UNSUPPORTED_ENCAP;
			*err_info = g_strdup_printf("snoop: network type %u unknown or unsupported",
			    hdr.network);
			return -1;
		}
		file_encap = snoop_encap[hdr.network];

		/* This is a snoop file */
		wth->file_type_subtype = WTAP_FILE_TYPE_SUBTYPE_SNOOP;
	}

	/*
	 * We don't currently use the extra information in Shomiti
	 * records, so we use the same routines to read snoop and
	 * Shomiti files.
	 */
	wth->subtype_read = snoop_read;
	wth->subtype_seek_read = snoop_seek_read;
	wth->file_encap = file_encap;
	wth->snapshot_length = 0;	/* not available in header */
	wth->tsprecision = WTAP_FILE_TSPREC_USEC;
	return 1;
}
Ejemplo n.º 22
0
static gboolean
nettl_read_rec(wtap *wth, FILE_T fh, struct wtap_pkthdr *phdr, Buffer *buf,
		int *err, gchar **err_info)
{
    union wtap_pseudo_header *pseudo_header = &phdr->pseudo_header;
    nettl_t *nettl = (nettl_t *)wth->priv;
    gboolean fddihack = FALSE;
    int bytes_read;
    struct nettlrec_hdr rec_hdr;
    guint16 hdr_len;
    struct nettlrec_ns_ls_drv_eth_hdr drv_eth_hdr;
    guint32 length, caplen;
    int subsys;
    guint padlen;
    int datalen;
    guint8 dummyc[16];
    int bytes_to_read;
    guint8 *pd;
    guint8 dummy[3];

    errno = WTAP_ERR_CANT_READ;
    bytes_read = file_read(&rec_hdr.hdr_len, sizeof rec_hdr.hdr_len, fh);
    if (bytes_read != sizeof rec_hdr.hdr_len) {
	*err = file_error(fh, err_info);
	if (*err == 0 && bytes_read != 0)
	    *err = WTAP_ERR_SHORT_READ;
	return FALSE;
    }
    hdr_len = g_ntohs(rec_hdr.hdr_len);
    if (hdr_len < NETTL_REC_HDR_LEN) {
    	*err = WTAP_ERR_BAD_FILE;
	*err_info = g_strdup_printf("nettl: record header length %u too short",
	    hdr_len);
	return FALSE;
    }
    bytes_read = file_read(&rec_hdr.subsys, NETTL_REC_HDR_LEN - 2, fh);
    if (bytes_read != NETTL_REC_HDR_LEN - 2) {
	*err = file_error(fh, err_info);
	if (*err == 0)
	    *err = WTAP_ERR_SHORT_READ;
	return FALSE;
    }
    subsys = g_ntohs(rec_hdr.subsys);
    hdr_len -= NETTL_REC_HDR_LEN;
    if (file_seek(fh, hdr_len, SEEK_CUR, err) == -1)
	return FALSE;

    if ( (pntoh32(&rec_hdr.kind) & NETTL_HDR_PDU_MASK) == 0 ) {
        /* not actually a data packet (PDU) trace record */
        phdr->pkt_encap = WTAP_ENCAP_NETTL_RAW_IP;
        length = pntoh32(&rec_hdr.length);
        caplen = pntoh32(&rec_hdr.caplen);
        padlen = 0;
    } else switch (subsys) {
	case NETTL_SUBSYS_LAN100 :
	case NETTL_SUBSYS_EISA100BT :
	case NETTL_SUBSYS_BASE100 :
	case NETTL_SUBSYS_GSC100BT :
	case NETTL_SUBSYS_PCI100BT :
	case NETTL_SUBSYS_SPP100BT :
	case NETTL_SUBSYS_100VG :
	case NETTL_SUBSYS_GELAN :
	case NETTL_SUBSYS_BTLAN :
	case NETTL_SUBSYS_INTL100 :
	case NETTL_SUBSYS_IGELAN :
	case NETTL_SUBSYS_IETHER :
	case NETTL_SUBSYS_IXGBE :
	case NETTL_SUBSYS_HSSN :
	case NETTL_SUBSYS_IGSSN :
	case NETTL_SUBSYS_ICXGBE :
	case NETTL_SUBSYS_IEXGBE :
	case NETTL_SUBSYS_IOCXGBE :
	case NETTL_SUBSYS_IQXGBE :
	case NETTL_SUBSYS_HPPB_FDDI :
	case NETTL_SUBSYS_EISA_FDDI :
        case NETTL_SUBSYS_PCI_FDDI :
        case NETTL_SUBSYS_HSC_FDDI :
        case NETTL_SUBSYS_TOKEN :
        case NETTL_SUBSYS_PCI_TR :
	case NETTL_SUBSYS_NS_LS_IP :
	case NETTL_SUBSYS_NS_LS_LOOPBACK :
	case NETTL_SUBSYS_NS_LS_TCP :
	case NETTL_SUBSYS_NS_LS_UDP :
	case NETTL_SUBSYS_HP_APAPORT :
	case NETTL_SUBSYS_HP_APALACP :
	case NETTL_SUBSYS_NS_LS_IPV6 :
	case NETTL_SUBSYS_NS_LS_ICMPV6 :
	case NETTL_SUBSYS_NS_LS_ICMP :
	case NETTL_SUBSYS_NS_LS_TELNET :
	case NETTL_SUBSYS_NS_LS_SCTP :
	    if( (subsys == NETTL_SUBSYS_NS_LS_IP)
	     || (subsys == NETTL_SUBSYS_NS_LS_LOOPBACK)
	     || (subsys == NETTL_SUBSYS_NS_LS_UDP)
	     || (subsys == NETTL_SUBSYS_NS_LS_TCP)
	     || (subsys == NETTL_SUBSYS_NS_LS_SCTP)
	     || (subsys == NETTL_SUBSYS_NS_LS_IPV6)) {
		phdr->pkt_encap = WTAP_ENCAP_NETTL_RAW_IP;
	    } else if (subsys == NETTL_SUBSYS_NS_LS_ICMP) {
		phdr->pkt_encap = WTAP_ENCAP_NETTL_RAW_ICMP;
	    } else if (subsys == NETTL_SUBSYS_NS_LS_ICMPV6) {
		phdr->pkt_encap = WTAP_ENCAP_NETTL_RAW_ICMPV6;
	    } else if (subsys == NETTL_SUBSYS_NS_LS_TELNET) {
		phdr->pkt_encap = WTAP_ENCAP_NETTL_RAW_TELNET;
	    } else if( (subsys == NETTL_SUBSYS_HPPB_FDDI)
		    || (subsys == NETTL_SUBSYS_EISA_FDDI)
		    || (subsys == NETTL_SUBSYS_PCI_FDDI)
		    || (subsys == NETTL_SUBSYS_HSC_FDDI) ) {
		phdr->pkt_encap = WTAP_ENCAP_NETTL_FDDI;
	    } else if( (subsys == NETTL_SUBSYS_PCI_TR)
		    || (subsys == NETTL_SUBSYS_TOKEN) ) {
		phdr->pkt_encap = WTAP_ENCAP_NETTL_TOKEN_RING;
	    } else {
		phdr->pkt_encap = WTAP_ENCAP_NETTL_ETHERNET;
	    }

	    length = pntoh32(&rec_hdr.length);
	    caplen = pntoh32(&rec_hdr.caplen);

	    /* HPPB FDDI has different inbound vs outbound trace records */
	    if (subsys == NETTL_SUBSYS_HPPB_FDDI) {
                if (pntoh32(&rec_hdr.kind) == NETTL_HDR_PDUIN) {
                    /* inbound is very strange...
                       there are an extra 3 bytes after the DSAP and SSAP
                       for SNAP frames ???
                    */
                    fddihack=TRUE;
                    padlen = 0;
                } else {
	            /* outbound appears to have variable padding */
		    bytes_read = file_read(dummyc, 9, fh);
		    if (bytes_read != 9) {
			*err = file_error(fh, err_info);
			if (*err == 0)
			    *err = WTAP_ERR_SHORT_READ;
			return FALSE;
		    }
                    /* padding is usually either a total 11 or 16 bytes??? */
		    padlen = (int)dummyc[8];
		    if (file_seek(fh, padlen, SEEK_CUR, err) == -1)
			return FALSE;
		    padlen += 9;
		}
	    } else if ( (subsys == NETTL_SUBSYS_PCI_FDDI)
	             || (subsys == NETTL_SUBSYS_EISA_FDDI)
	             || (subsys == NETTL_SUBSYS_HSC_FDDI) ) {
	        /* other flavor FDDI cards have an extra 3 bytes of padding */
                if (file_seek(fh, 3, SEEK_CUR, err) == -1)
                    return FALSE;
                padlen = 3;
	    } else if (subsys == NETTL_SUBSYS_NS_LS_LOOPBACK) {
	        /* LOOPBACK has an extra 26 bytes of padding */
                if (file_seek(fh, 26, SEEK_CUR, err) == -1)
                    return FALSE;
                padlen = 26;
            } else if (subsys == NETTL_SUBSYS_NS_LS_SCTP) {
                /*
                 * SCTP 8 byte header that we will ignore...
                 * 32 bit integer defines format
                 *   1 = Log
                 *   2 = ASCII
                 *   3 = Binary (PDUs should be Binary format)
                 * 32 bit integer defines type
                 *   1 = Inbound
                 *   2 = Outbound
                 */
                if (file_seek(fh, 8, SEEK_CUR, err) == -1)
                    return FALSE;
                padlen = 8;
	    } else {
	    	padlen = 0;
	    }
	    break;

	case NETTL_SUBSYS_NS_LS_DRIVER :
	    /* XXX we dont know how to identify this as ethernet frames, so
	       we assumes everything is. We will crash and burn for anything else */
	    /* for encapsulated 100baseT we do this */
	    phdr->pkt_encap = WTAP_ENCAP_NETTL_ETHERNET;
	    bytes_read = file_read(&drv_eth_hdr, NS_LS_DRV_ETH_HDR_LEN, fh);
	    if (bytes_read != NS_LS_DRV_ETH_HDR_LEN) {
		*err = file_error(fh, err_info);
		if (*err == 0)
		    *err = WTAP_ERR_SHORT_READ;
		return FALSE;
	    }

	    length = pntoh16(&drv_eth_hdr.length);
	    caplen = pntoh16(&drv_eth_hdr.caplen);
	    /*
	     * XXX - is there a length field that would give the length
	     * of this header, so that we don't have to check for
	     * nettl files from HP-UX 11?
	     *
	     * And what are the extra two bytes?
	     */
            if (nettl->is_hpux_11) {
                if (file_seek(fh, 2, SEEK_CUR, err) == -1) return FALSE;
            }
	    padlen = 0;
	    break;

	case NETTL_SUBSYS_SX25L2:
	case NETTL_SUBSYS_SX25L3:
	    /*
	     * XXX - is the 24-byte padding actually a header with
	     * packet lengths, time stamps, etc., just as is the case
	     * for NETTL_SUBSYS_NS_LS_DRIVER?  It might be
	     *
	     *    guint8	caplen[2];
	     *    guint8	length[2];
	     *    guint8	xxc[4];
	     *    guint8	sec[4];
	     *    guint8	usec[4];
	     *    guint8	xxd[4];
	     *
	     * or something such as that - if it has 4 bytes before that
	     * (making it 24 bytes), it'd be like struct
	     * nettlrec_ns_ls_drv_eth_hdr but with 2 more bytes at the end.
	     *
	     * And is "from_dce" at xxa[0] in the nettlrec_hdr structure?
	     */
	    phdr->pkt_encap = WTAP_ENCAP_NETTL_X25;
	    length = pntoh32(&rec_hdr.length);
	    caplen = pntoh32(&rec_hdr.caplen);
	    padlen = 24;	/* sizeof (struct nettlrec_sx25l2_hdr) - NETTL_REC_HDR_LEN + 4 */
	    if (file_seek(fh, padlen, SEEK_CUR, err) == -1)
		return FALSE;
	    break;

	default:
            /* We're going to assume it's ethernet if we don't recognize the
               subsystem -- We'll probably spew junks and core if it isn't... */
	    wth->file_encap = WTAP_ENCAP_PER_PACKET;
	    phdr->pkt_encap = WTAP_ENCAP_NETTL_ETHERNET;
            length = pntoh32(&rec_hdr.length);
            caplen = pntoh32(&rec_hdr.caplen);
            padlen = 0;
            break;
    }

    if (length < padlen) {
	*err = WTAP_ERR_BAD_FILE;
	*err_info = g_strdup_printf("nettl: packet length %u in record header too short, less than %u",
	    length, padlen);
	return FALSE;
    }
    phdr->rec_type = REC_TYPE_PACKET;
    phdr->presence_flags = WTAP_HAS_TS|WTAP_HAS_CAP_LEN;
    phdr->len = length - padlen;
    if (caplen < padlen) {
	*err = WTAP_ERR_BAD_FILE;
	*err_info = g_strdup_printf("nettl: captured length %u in record header too short, less than %u",
	    caplen, padlen);
	return FALSE;
    }
    datalen = caplen - padlen;
    phdr->caplen = datalen;
    phdr->ts.secs = pntoh32(&rec_hdr.sec);
    phdr->ts.nsecs = pntoh32(&rec_hdr.usec) * 1000;

    pseudo_header->nettl.subsys   = subsys;
    pseudo_header->nettl.devid    = pntoh32(&rec_hdr.devid);
    pseudo_header->nettl.kind     = pntoh32(&rec_hdr.kind);
    pseudo_header->nettl.pid      = pntoh32(&rec_hdr.pid);
    pseudo_header->nettl.uid      = pntoh16(&rec_hdr.uid);

    if (phdr->caplen > WTAP_MAX_PACKET_SIZE) {
	/*
	 * Probably a corrupt capture file; don't blow up trying
	 * to allocate space for an immensely-large packet.
	 */
	*err = WTAP_ERR_BAD_FILE;
	*err_info = g_strdup_printf("nettl: File has %u-byte packet, bigger than maximum of %u",
	    phdr->caplen, WTAP_MAX_PACKET_SIZE);
	return FALSE;
    }

    /*
     * Read the packet data.
     */
    buffer_assure_space(buf, datalen);
    pd = buffer_start_ptr(buf);
    errno = WTAP_ERR_CANT_READ;
    if (fddihack) {
        /* read in FC, dest, src, DSAP and SSAP */
        bytes_to_read = 15;
        if (bytes_to_read > datalen)
            bytes_to_read = datalen;
        bytes_read = file_read(pd, bytes_to_read, fh);
        if (bytes_read != bytes_to_read) {
            if (*err == 0)
                *err = WTAP_ERR_SHORT_READ;
            return FALSE;
        }
        datalen -= bytes_read;
        if (datalen == 0) {
            /* There's nothing past the FC, dest, src, DSAP and SSAP */
            return TRUE;
        }
        if (pd[13] == 0xAA) {
            /* it's SNAP, have to eat 3 bytes??? */
            bytes_to_read = 3;
            if (bytes_to_read > datalen)
                bytes_to_read = datalen;
            bytes_read = file_read(dummy, bytes_to_read, fh);
            if (bytes_read != bytes_to_read) {
                if (*err == 0)
                    *err = WTAP_ERR_SHORT_READ;
                return FALSE;
            }
            datalen -= bytes_read;
            if (datalen == 0) {
                /* There's nothing past the FC, dest, src, DSAP, SSAP, and 3 bytes to eat */
		return TRUE;
	    }
        }
        bytes_read = file_read(pd + 15, datalen, fh);
    } else
        bytes_read = file_read(pd, datalen, fh);

    if (bytes_read != datalen) {
	*err = file_error(fh, err_info);
	if (*err == 0)
	    *err = WTAP_ERR_SHORT_READ;
	return FALSE;
    }
    return TRUE;
}
Ejemplo n.º 23
0
int netmon_open(wtap *wth, int *err, gchar **err_info)
{
	int bytes_read;
	char magic[MAGIC_SIZE];
	struct netmon_hdr hdr;
	int file_type;
	struct tm tm;
	guint32 frame_table_offset;
	guint32 frame_table_length;
	guint32 frame_table_size;
	guint32 *frame_table;
#ifdef WORDS_BIGENDIAN
	unsigned int i;
#endif
	netmon_t *netmon;

	/* Read in the string that should be at the start of a Network
	 * Monitor file */
	errno = WTAP_ERR_CANT_READ;
	bytes_read = file_read(magic, MAGIC_SIZE, wth->fh);
	if (bytes_read != MAGIC_SIZE) {
		*err = file_error(wth->fh, err_info);
		if (*err != 0 && *err != WTAP_ERR_SHORT_READ)
			return -1;
		return 0;
	}

	if (memcmp(magic, netmon_1_x_magic, MAGIC_SIZE) != 0 &&
	    memcmp(magic, netmon_2_x_magic, MAGIC_SIZE) != 0) {
		return 0;
	}

	/* Read the rest of the header. */
	errno = WTAP_ERR_CANT_READ;
	bytes_read = file_read(&hdr, sizeof hdr, wth->fh);
	if (bytes_read != sizeof hdr) {
		*err = file_error(wth->fh, err_info);
		if (*err == 0)
			*err = WTAP_ERR_SHORT_READ;
		return -1;
	}

	switch (hdr.ver_major) {

	case 1:
		file_type = WTAP_FILE_NETMON_1_x;
		break;

	case 2:
		file_type = WTAP_FILE_NETMON_2_x;
		break;

	default:
		*err = WTAP_ERR_UNSUPPORTED;
		*err_info = g_strdup_printf("netmon: major version %u unsupported", hdr.ver_major);
		return -1;
	}

	hdr.network = pletohs(&hdr.network);
	if (hdr.network >= NUM_NETMON_ENCAPS
	    || netmon_encap[hdr.network] == WTAP_ENCAP_UNKNOWN) {
		*err = WTAP_ERR_UNSUPPORTED_ENCAP;
		*err_info = g_strdup_printf("netmon: network type %u unknown or unsupported",
		    hdr.network);
		return -1;
	}

	/* This is a netmon file */
	wth->file_type = file_type;
	netmon = (netmon_t *)g_malloc(sizeof(netmon_t));
	wth->priv = (void *)netmon;
	wth->subtype_read = netmon_read;
	wth->subtype_seek_read = netmon_seek_read;
	wth->subtype_sequential_close = netmon_sequential_close;

	/* NetMon capture file formats v2.1+ use per-packet encapsulation types.  NetMon 3 sets the value in
	 * the header to 1 (Ethernet) for backwards compability. */
	if((hdr.ver_major == 2 && hdr.ver_minor >= 1) || hdr.ver_major > 2)
		wth->file_encap = WTAP_ENCAP_PER_PACKET;
	else
		wth->file_encap = netmon_encap[hdr.network];

	wth->snapshot_length = 0;	/* not available in header */
	/*
	 * Convert the time stamp to a "time_t" and a number of
	 * milliseconds.
	 */
	tm.tm_year = pletohs(&hdr.ts_year) - 1900;
	tm.tm_mon = pletohs(&hdr.ts_month) - 1;
	tm.tm_mday = pletohs(&hdr.ts_day);
	tm.tm_hour = pletohs(&hdr.ts_hour);
	tm.tm_min = pletohs(&hdr.ts_min);
	tm.tm_sec = pletohs(&hdr.ts_sec);
	tm.tm_isdst = -1;
	netmon->start_secs = mktime(&tm);
	/*
	 * XXX - what if "secs" is -1?  Unlikely, but if the capture was
	 * done in a time zone that switches between standard and summer
	 * time sometime other than when we do, and thus the time was one
	 * that doesn't exist here because a switch from standard to summer
	 * time zips over it, it could happen.
	 *
	 * On the other hand, if the capture was done in a different time
	 * zone, this won't work right anyway; unfortunately, the time
	 * zone isn't stored in the capture file (why the hell didn't
	 * they stuff a FILETIME, which is the number of 100-nanosecond
	 * intervals since 1601-01-01 00:00:00 "UTC", there, instead
	 * of stuffing a SYSTEMTIME, which is time-zone-dependent, there?).
	 */
	netmon->start_nsecs = pletohs(&hdr.ts_msec)*1000000;

	netmon->version_major = hdr.ver_major;
	netmon->version_minor = hdr.ver_minor;

	/*
	 * Get the offset of the frame index table.
	 */
	frame_table_offset = pletohl(&hdr.frametableoffset);

	/*
	 * It appears that some NetMon 2.x files don't have the
	 * first packet starting exactly 128 bytes into the file.
	 *
	 * Furthermore, it also appears that there are "holes" in
	 * the file, i.e. frame N+1 doesn't always follow immediately
	 * after frame N.
	 *
	 * Therefore, we must read the frame table, and use the offsets
	 * in it as the offsets of the frames.
	 */
	frame_table_length = pletohl(&hdr.frametablelength);
	frame_table_size = frame_table_length / (guint32)sizeof (guint32);
	if ((frame_table_size * sizeof (guint32)) != frame_table_length) {
		*err = WTAP_ERR_BAD_FILE;
		*err_info = g_strdup_printf("netmon: frame table length is %u, which is not a multiple of the size of an entry",
		    frame_table_length);
		g_free(netmon);
		return -1;
	}
	if (frame_table_size == 0) {
		*err = WTAP_ERR_BAD_FILE;
		*err_info = g_strdup_printf("netmon: frame table length is %u, which means it's less than one entry in size",
		    frame_table_length);
		g_free(netmon);
		return -1;
	}
	/*
	 * XXX - clamp the size of the frame table, so that we don't
	 * attempt to allocate a huge frame table and fail.
	 *
	 * Given that file offsets in the frame table are 32-bit,
	 * a NetMon file cannot be bigger than 2^32 bytes.
	 * Given that a NetMon 1.x-format packet header is 8 bytes,
	 * that means a NetMon file cannot have more than
	 * 512*2^20 packets.  We'll pick that as the limit for
	 * now; it's 1/8th of a 32-bit address space, which is
	 * probably not going to exhaust the address space all by
	 * itself, and probably won't exhaust the backing store.
	 */
	if (frame_table_size > 512*1024*1024) {
		*err = WTAP_ERR_BAD_FILE;
		*err_info = g_strdup_printf("netmon: frame table length is %u, which is larger than we support",
		    frame_table_length);
		g_free(netmon);
		return -1;
	}
	if (file_seek(wth->fh, frame_table_offset, SEEK_SET, err) == -1) {
		g_free(netmon);
		return -1;
	}
	frame_table = (guint32 *)g_malloc(frame_table_length);
	errno = WTAP_ERR_CANT_READ;
	bytes_read = file_read(frame_table, frame_table_length, wth->fh);
	if ((guint32)bytes_read != frame_table_length) {
		*err = file_error(wth->fh, err_info);
		if (*err == 0)
			*err = WTAP_ERR_SHORT_READ;
		g_free(frame_table);
		g_free(netmon);
		return -1;
	}
	netmon->frame_table_size = frame_table_size;
	netmon->frame_table = frame_table;

#ifdef WORDS_BIGENDIAN
	/*
	 * OK, now byte-swap the frame table.
	 */
	for (i = 0; i < frame_table_size; i++)
		frame_table[i] = pletohl(&frame_table[i]);
#endif

	/* Set up to start reading at the first frame. */
	netmon->current_frame = 0;
	switch (netmon->version_major) {

	case 1:
		/*
		 * Version 1.x of the file format supports
		 * millisecond precision.
		 */
		wth->tsprecision = WTAP_FILE_TSPREC_MSEC;
		break;

	case 2:
		/*
		 * Version 1.x of the file format supports
		 * 100-nanosecond precision; we don't
		 * currently support that, so say
		 * "nanosecond precision" for now.
		 */
		wth->tsprecision = WTAP_FILE_TSPREC_NSEC;
		break;
	}
	return 1;
}
Ejemplo n.º 24
0
/* Seeks to the beginning of the next packet, and returns the
   byte offset at which the header for that packet begins.
   Returns -1 on failure. */
static gint64 ascend_seek(wtap *wth, int *err, gchar **err_info)
{
  int byte;
  gint64 date_off = -1, cur_off, packet_off;
  size_t string_level[ASCEND_MAGIC_STRINGS];
  guint string_i = 0, type = 0;
  guint excessive_read_count = 262144;

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

  while (((byte = file_getc(wth->fh)) != EOF)) {
    excessive_read_count--;

    if (!excessive_read_count) {
      *err = 0;
      return -1;
    }

    for (string_i = 0; string_i < ASCEND_MAGIC_STRINGS; string_i++) {
      const gchar *strptr = ascend_magic[string_i].strptr;
      size_t len          = strlen(strptr);

      if (byte == *(strptr + string_level[string_i])) {
        string_level[string_i]++;
        if (string_level[string_i] >= len) {
          cur_off = file_tell(wth->fh);
          if (cur_off == -1) {
            /* Error. */
            *err = file_error(wth->fh, err_info);
            return -1;
          }

          /* Date: header is a special case. Remember the offset,
             but keep looking for other headers. */
	  if (strcmp(strptr, ASCEND_DATE) == 0) {
            date_off = cur_off - len;
          } else {
            if (date_off == -1) {
              /* Back up over the header we just read; that's where a read
                 of this packet should start. */
              packet_off = cur_off - len;
            } else {
              /* This packet has a date/time header; a read of it should
                 start at the beginning of *that* header. */
              packet_off = date_off;
            }

            type = ascend_magic[string_i].type;
            goto found;
          }
        }
      } else {
        string_level[string_i] = 0;
      }
    }
  }

  *err = file_error(wth->fh, err_info);
  return -1;

found:
  /*
   * Move to where the read for this packet should start, and return
   * that seek offset.
   */
  if (file_seek(wth->fh, packet_off, SEEK_SET, err) == -1)
    return -1;

  wth->phdr.pseudo_header.ascend.type = type;

  return packet_off;
}
Ejemplo n.º 25
0
int network_instruments_open(wtap *wth, int *err, gchar **err_info)
{
    int bytes_read;
    int offset;
    capture_file_header file_header;
    guint i;
    tlv_header tlvh;
    int seek_increment;
    int header_offset;
    packet_entry_header packet_header;
    observer_dump_private_state * private_state = NULL;

    errno = WTAP_ERR_CANT_READ;
    offset = 0;

    /* read in the buffer file header */
    bytes_read = file_read(&file_header, sizeof file_header, wth->fh);
    if (bytes_read != sizeof file_header) {
        *err = file_error(wth->fh, err_info);
        if (*err != 0)
            return -1;
        return 0;
    }
    offset += bytes_read;
    CAPTURE_FILE_HEADER_FROM_LE_IN_PLACE(file_header);

    /* check if version info is present */
    if (memcmp(file_header.observer_version, network_instruments_magic, true_magic_length)!=0) {
        return 0;
    }

    /* initialize the private state */
    private_state = (observer_dump_private_state *) g_malloc(sizeof(observer_dump_private_state));
    private_state->time_format = TIME_INFO_LOCAL;
    wth->priv = (void *) private_state;

    /* get the location of the first packet */
    /* v15 and newer uses high byte offset, in previous versions it will be 0 */
    header_offset = file_header.offset_to_first_packet + ((int)(file_header.offset_to_first_packet_high_byte)<<16);

    /* process extra information */
    for (i = 0; i < file_header.number_of_information_elements; i++) {
        /* for safety break if we've reached the first packet */
        if (offset >= header_offset)
            break;

        /* read the TLV header */
        bytes_read = file_read(&tlvh, sizeof tlvh, wth->fh);
        if (bytes_read != sizeof tlvh) {
            *err = file_error(wth->fh, err_info);
            if (*err == 0)
                *err = WTAP_ERR_SHORT_READ;
            return -1;
        }
        offset += bytes_read;
        TLV_HEADER_FROM_LE_IN_PLACE(tlvh);

        if (tlvh.length < sizeof tlvh) {
            *err = WTAP_ERR_BAD_FILE;
            *err_info = g_strdup_printf("Observer: bad record (TLV length %u < %lu)",
                tlvh.length, (unsigned long)sizeof tlvh);
            return -1;
        }

        /* process (or skip over) the current TLV */
        switch (tlvh.type) {
        case INFORMATION_TYPE_TIME_INFO:
            bytes_read = file_read(&private_state->time_format, sizeof private_state->time_format, wth->fh);
            if (bytes_read != sizeof private_state->time_format) {
                *err = file_error(wth->fh, err_info);
                if(*err == 0)
                    *err = WTAP_ERR_SHORT_READ;
                return -1;
            }
            private_state->time_format = GUINT32_FROM_LE(private_state->time_format);
            offset += bytes_read;
            break;
        default:
            seek_increment = tlvh.length - (int)sizeof tlvh;
            if (seek_increment > 0) {
                if (file_seek(wth->fh, seek_increment, SEEK_CUR, err) == -1)
                    return -1;
            }
            offset += seek_increment;
        }
    }

    /* get to the first packet */
    if (header_offset < offset) {
        *err = WTAP_ERR_BAD_FILE;
        *err_info = g_strdup_printf("Observer: bad record (offset to first packet %d < %d)",
            header_offset, offset);
        return FALSE;
    }
    seek_increment = header_offset - offset;
    if (seek_increment > 0) {
        if (file_seek(wth->fh, seek_increment, SEEK_CUR, err) == -1)
            return -1;
    }

    /* pull off the packet header */
    bytes_read = file_read(&packet_header, sizeof packet_header, wth->fh);
    if (bytes_read != sizeof packet_header) {
        *err = file_error(wth->fh, err_info);
        if (*err != 0)
            return -1;
        return 0;
    }
    PACKET_ENTRY_HEADER_FROM_LE_IN_PLACE(packet_header);

    /* check the packet's magic number */
    if (packet_header.packet_magic != observer_packet_magic) {
        *err = WTAP_ERR_UNSUPPORTED_ENCAP;
        *err_info = g_strdup_printf("Observer: unsupported packet version %ul", packet_header.packet_magic);
        return -1;
    }

    /* check the data link type */
    if (observer_to_wtap_encap(packet_header.network_type) == WTAP_ENCAP_UNKNOWN) {
        *err = WTAP_ERR_UNSUPPORTED_ENCAP;
        *err_info = g_strdup_printf("Observer: network type %u unknown or unsupported", packet_header.network_type);
        return -1;
    }
    wth->file_encap = observer_to_wtap_encap(packet_header.network_type);

    /* set up the rest of the capture parameters */
    private_state->packet_count = 0;
    private_state->network_type = wtap_to_observer_encap(wth->file_encap);
    wth->subtype_read = observer_read;
    wth->subtype_seek_read = observer_seek_read;
    wth->subtype_close = NULL;
    wth->subtype_sequential_close = NULL;
    wth->snapshot_length = 0;    /* not available in header */
    wth->tsprecision = WTAP_FILE_TSPREC_NSEC;
    wth->file_type = WTAP_FILE_NETWORK_INSTRUMENTS;

    /* reset the pointer to the first packet */
    if (file_seek(wth->fh, header_offset, SEEK_SET, err) == -1)
        return -1;

    init_gmt_to_localtime_offset();

    return 1;
}
Ejemplo n.º 26
0
/* convert file using GNU recode library
   returns 0 on success, nonzero error code otherwise */
int
convert_recode(File *file,
               EncaEncoding from_enc)
{
  RECODE_REQUEST request;
  RECODE_TASK task;
  File *tempfile = NULL;
  bool success;
  const char *encreq;

  /* Allocate librecode outer if we are called first time. */
  if (outer == NULL) {
    if ((outer = recode_new_outer(false)) == NULL) {
      fprintf(stderr, "%s: recode library doesn't like us\n",
                      program_name);
      return ERR_LIBCOM;
    }
  }

  /* Construct recode request string,
     try to mimic surfaceless converter now. */
  {
    EncaEncoding enc;

    enc.charset = from_enc.charset;
    enc.surface = from_enc.surface | ENCA_SURFACE_REMOVE;
    encreq = format_request_string(enc, options.target_enc,
                                   ENCA_SURFACE_EOL_LF);
  }
  /* Create a recode request from it. */
  request = get_recode_request(encreq);
  if (request == NULL)
    return ERR_CANNOT;

  /* Now we have to distinguish between file and stdin, namely because
   * in case of stdin, it's first part is already loaded in the buffer. */
  if (file->name != NULL) {
    /* File is a regular file.
       Since recode doesn't recode files in place, we make a temporary file
       and copy contents of file fname to it. */
    if (file_seek(file, 0, SEEK_SET) != 0)
      return ERR_IOFAIL;
    file->buffer->pos = 0;

    if ((tempfile = file_temporary(file->buffer, 1)) == NULL
        || copy_and_convert(file, tempfile, NULL) != 0
        || file_seek(file, 0, SEEK_SET) != 0
        || file_seek(tempfile, 0, SEEK_SET) != 0
        || file_truncate(file, 0) != 0) {
      file_free(tempfile);
      return ERR_IOFAIL;
    }

    /* Create a task from the request. */
    task = recode_new_task(request);
    task->fail_level = enca_recode_fail_level;
    task->abort_level = RECODE_SYSTEM_ERROR;
    task->input.name = NULL;
    task->input.file = tempfile->stream;
    task->output.name = NULL;
    task->output.file = file->stream;

    /* Now run conversion temporary file -> original. */
    success = recode_perform_task(task);

    /* If conversion wasn't successfull, original file is probably damaged
       (damned librecode!) try to restore it from the temporary copy. */
    if (!success) {
      if (task->error_so_far >= RECODE_SYSTEM_ERROR) {
        fprintf(stderr, "%s: librecode probably damaged file `%s'. "
                        "Trying to recover... ",
                        program_name,
                        file->name);
        tempfile->buffer->pos = 0;
        if (file_seek(tempfile, 0, SEEK_SET) != -1
            && file_seek(file, 0, SEEK_SET) != -1
            && file_truncate(file, file->size) == 0
            && copy_and_convert(tempfile, file, NULL) == 0)
          fprintf(stderr, "succeeded.\n");
        else
          fprintf(stderr, "failed\n");
      }
      else
        print_recode_warning(task->error_so_far, file->name);
    }

    recode_delete_task(task);
    file_free(tempfile);
  }
  else {
    /* File is stdin.
       First recode begining saved in io_buffer, then append rest of stdin. */
    enum recode_error errmax = RECODE_NO_ERROR;

    /* Create a task from the request.
     * Set it up for buffer -> stdout conversion */
    task = recode_new_task(request);
    task->fail_level = enca_recode_fail_level;
    task->abort_level = RECODE_SYSTEM_ERROR;
    task->input.name = NULL;
    task->input.file = NULL;
    task->input.buffer = (char*)file->buffer->data;
    task->input.cursor = (char*)file->buffer->data;
    task->input.limit = (char*)file->buffer->data + file->buffer->pos;
    task->output.name = NULL;
    task->output.file = stdout;

    success = recode_perform_task(task);
    if (!success) {
      if (task->error_so_far >= RECODE_SYSTEM_ERROR) {
        fprintf(stderr, "%s: librecode probably damaged `%s'. "
                        "No way to recover in a pipe.\n",
                        program_name,
                        ffname_r(NULL));
        recode_delete_task(task);
        return ERR_IOFAIL;
      }
      else
        errmax = task->error_so_far;
    }
    recode_delete_task(task);

    /* Create a task from the request.
     * Set it up for stdin -> stdout conversion */
    task = recode_new_task(request);
    task->fail_level = enca_recode_fail_level;
    task->abort_level = RECODE_SYSTEM_ERROR;
    task->input.name = NULL;
    task->input.file = stdin;
    task->output.name = NULL;
    task->output.file = stdout;

    success = recode_perform_task(task);
    if (!success) {
      if (task->error_so_far >= RECODE_SYSTEM_ERROR) {
        fprintf(stderr, "%s: librecode probably damaged `%s'. "
                        "No way to recover in a pipe.\n",
                        program_name,
                        ffname_r(NULL));
        recode_delete_task(task);
        return ERR_IOFAIL;
      }
      else {
        if (errmax < task->error_so_far)
          errmax = task->error_so_far;
      }
    }
    if (errmax >= enca_recode_fail_level)
      print_recode_warning(errmax, ffname_r(NULL));

    recode_delete_task(task);
  }

  /* return ERR_IOFAIL on failure since it means file-related problems */
  return success ? ERR_OK : ERR_IOFAIL;
}
Ejemplo n.º 27
0
/* Read packet data for random access.
   This gets the packet data and rebuilds the pseudo header so that
   the direction flag works. */
static gboolean visual_seek_read (wtap *wth, gint64 seek_off,
    struct wtap_pkthdr *phdr, guint8 *pd, int len,
    int *err, gchar **err_info)
{
    union wtap_pseudo_header *pseudo_header = &phdr->pseudo_header;
    struct visual_pkt_hdr vpkt_hdr;
    struct visual_atm_hdr vatm_hdr;
    int phdr_size = sizeof(vpkt_hdr);
    int ahdr_size = sizeof(vatm_hdr);
    int bytes_read;
    int header_size;

    /* Get the size of the visual packet header to skip */
    header_size = sizeof(struct visual_pkt_hdr);

    /* If ATM capture, need to skip over visual ATM packet header too */
    if (wth->file_encap == WTAP_ENCAP_ATM_PDUS)
    {
       header_size += (int)sizeof(struct visual_atm_hdr);
    }
    
    /* Seek to the packet header */
    if (file_seek(wth->random_fh, seek_off - header_size,
                  SEEK_SET, err) == -1)
        return FALSE;

    /* Read the packet header to get the status flags. */
    errno = WTAP_ERR_CANT_READ;
    bytes_read = file_read(&vpkt_hdr, phdr_size, wth->random_fh);
    if (bytes_read != phdr_size) {
    	*err = file_error(wth->random_fh, err_info);
    	if (*err == 0)
    	    *err = WTAP_ERR_SHORT_READ;
        return FALSE;
    }
    
    /* Check for additional ATM packet header */
    if (wth->file_encap == WTAP_ENCAP_ATM_PDUS)
    {
       /* Read the atm packet header */
       errno = WTAP_ERR_CANT_READ;
       bytes_read = file_read(&vatm_hdr, ahdr_size, wth->random_fh);
       if (bytes_read != ahdr_size)
       {
           *err = file_error(wth->fh, err_info);
           if (*err == 0 && bytes_read != 0)
           {
               *err = WTAP_ERR_SHORT_READ;
           }
           return FALSE;
       }
    }

    /* Read the packet data. */
    errno = WTAP_ERR_CANT_READ;
    bytes_read = file_read(pd, len, wth->random_fh);
    if (bytes_read != len) {
    	if (*err == 0)
    	    *err = WTAP_ERR_SHORT_READ;
        return FALSE;
    }

    /* Set the pseudo_header. */
    visual_set_pseudo_header(wth->file_encap, &vpkt_hdr, &vatm_hdr, pseudo_header);

    return TRUE;
}
Ejemplo n.º 28
0
/* Opens a file and prepares a wtap struct.
   If "do_random" is TRUE, it opens the file twice; the second open
   allows the application to do random-access I/O without moving
   the seek offset for sequential I/O, which is used by Wireshark
   so that it can do sequential I/O to a capture file that's being
   written to as new packets arrive independently of random I/O done
   to display protocol trees for packets when they're selected. */
wtap* wtap_open_offline(const char *filename, int *err, char **err_info,
			gboolean do_random)
{
	struct stat statb;
	wtap	*wth;
	unsigned int	i;
	gboolean use_stdin = FALSE;

	/* open standard input if filename is '-' */
	if (strcmp(filename, "-") == 0)
		use_stdin = TRUE;

	/* First, make sure the file is valid */
	if (use_stdin) {
		if (fstat(0, &statb) < 0) {
			*err = errno;
			return NULL;
		}
	} else {
		if (ws_stat(filename, &statb) < 0) {
			*err = errno;
			return NULL;
		}
	}
	if (S_ISFIFO(statb.st_mode)) {
		/*
		 * Opens of FIFOs are allowed only when not opening
		 * for random access.
		 *
		 * XXX - currently, we do seeking when trying to find
		 * out the file type, so we don't actually support
		 * opening FIFOs.  However, we may eventually
		 * do buffering that allows us to do at least some
		 * file type determination even on pipes, so we
		 * allow FIFO opens and let things fail later when
		 * we try to seek.
		 */
		if (do_random) {
			*err = WTAP_ERR_RANDOM_OPEN_PIPE;
			return NULL;
		}
	} else if (S_ISDIR(statb.st_mode)) {
		/*
		 * Return different errors for "this is a directory"
		 * and "this is some random special file type", so
		 * the user can get a potentially more helpful error.
		 */
		*err = EISDIR;
		return NULL;
	} else if (! S_ISREG(statb.st_mode)) {
		*err = WTAP_ERR_NOT_REGULAR_FILE;
		return NULL;
	}

	/*
	 * We need two independent descriptors for random access, so
	 * they have different file positions.  If we're opening the
	 * standard input, we can only dup it to get additional
	 * descriptors, so we can't have two independent descriptors,
	 * and thus can't do random access.
	 */
	if (use_stdin && do_random) {
		*err = WTAP_ERR_RANDOM_OPEN_STDIN;
		return NULL;
	}

	errno = ENOMEM;
	wth = (wtap *)g_malloc(sizeof(wtap));
	if (wth == NULL) {
		*err = errno;
		return NULL;
	}

	/* Open the file */
	errno = WTAP_ERR_CANT_OPEN;
	if (use_stdin) {
		/*
		 * We dup FD 0, so that we don't have to worry about
		 * an fclose or gzclose of wth->fh closing the standard
		 * input of the process.
		 */
		wth->fd = ws_dup(0);
#ifdef _WIN32
		_setmode(wth->fd, O_BINARY);
#endif
	} else
		wth->fd = ws_open(filename, O_RDONLY|O_BINARY, 0000 /* no creation so don't matter */);
	if (wth->fd < 0) {
		*err = errno;
		g_free(wth);
		return NULL;
	}
	if (!(wth->fh = filed_open(wth->fd, "rb"))) {
		*err = errno;
		ws_close(wth->fd);
		g_free(wth);
		return NULL;
	}

	if (do_random) {
		if (!(wth->random_fh = file_open(filename, "rb"))) {
			*err = errno;
			file_close(wth->fh);
			g_free(wth);
			return NULL;
		}
	} else
		wth->random_fh = NULL;

	/* initialization */
	wth->file_encap = WTAP_ENCAP_UNKNOWN;
	wth->data_offset = 0;
	wth->subtype_sequential_close = NULL;
	wth->subtype_close = NULL;
	wth->tsprecision = WTAP_FILE_TSPREC_USEC;
	wth->priv = NULL;

	init_open_routines();

	/* Try all file types */
	for (i = 0; i < open_routines_arr->len; i++) {
		/* Seek back to the beginning of the file; the open routine
		   for the previous file type may have left the file
		   position somewhere other than the beginning, and the
		   open routine for this file type will probably want
		   to start reading at the beginning.

		   Initialize the data offset while we're at it. */
		if (file_seek(wth->fh, 0, SEEK_SET, err) == -1) {
			/* I/O error - give up */
			if (wth->random_fh != NULL)
				file_close(wth->random_fh);
			file_close(wth->fh);
			g_free(wth);
			return NULL;
		}
		wth->data_offset = 0;

		switch ((*open_routines[i])(wth, err, err_info)) {

		case -1:
			/* I/O error - give up */
			if (wth->random_fh != NULL)
				file_close(wth->random_fh);
			file_close(wth->fh);
			g_free(wth);
			return NULL;

		case 0:
			/* No I/O error, but not that type of file */
			break;

		case 1:
			/* We found the file type */
			goto success;
		}
	}

	/* Well, it's not one of the types of file we know about. */
	if (wth->random_fh != NULL)
		file_close(wth->random_fh);
	file_close(wth->fh);
	g_free(wth);
	*err = WTAP_ERR_FILE_UNKNOWN_FORMAT;
	return NULL;

success:
	wth->frame_buffer = (struct Buffer *)g_malloc(sizeof(struct Buffer));
	buffer_init(wth->frame_buffer, 1500);
	return wth;
}
Ejemplo n.º 29
0
/*
 * XXX - it would probably be cleaner to use a UCS-2 flavor of file_gets(),
 * rather than file_gets(), if we're reading a UCS-2 file.
 */
wtap_open_return_val
iseries_open (wtap * wth, int *err, gchar ** err_info)
{
  gint offset;
  char magic[ISERIES_LINE_LENGTH];

  /*
   * Check that file starts with a valid iSeries COMMS TRACE header
   * by scanning for it in the first line
   */
  if (!wtap_read_bytes (wth->fh, &magic, sizeof magic, err, err_info))
    {
      if (*err != WTAP_ERR_SHORT_READ)
        return WTAP_OPEN_ERROR;
      return WTAP_OPEN_NOT_MINE;
    }

  /*
   * Check if this is a little-endian UCS-2 Unicode formatted file by scanning
   * for the magic string
   */
  offset=0;
  while ((unsigned int)offset < (ISERIES_LINE_LENGTH - (sizeof iseries_hdr_magic_le_ucs_2)))
    {
      if (memcmp (magic + offset, iseries_hdr_magic_le_ucs_2, sizeof iseries_hdr_magic_le_ucs_2) == 0) {
        if (file_seek (wth->fh, 0, SEEK_SET, err) == -1)
          {
            return WTAP_OPEN_ERROR;
          }
        /*
         * Do some basic sanity checking to ensure we can handle the
         * contents of this trace
         */
        if (!iseries_check_file_type (wth, err, err_info, ISERIES_FORMAT_UNICODE))
          {
            if (*err == 0)
              return WTAP_OPEN_NOT_MINE;
            else
              return WTAP_OPEN_ERROR;
          }

        wth->file_encap        = WTAP_ENCAP_ETHERNET;
        wth->file_type_subtype = WTAP_FILE_TYPE_SUBTYPE_ISERIES;
        wth->snapshot_length   = 0;
        wth->subtype_read      = iseries_read;
        wth->subtype_seek_read = iseries_seek_read;
        wth->file_tsprec       = WTAP_TSPREC_USEC;

        if (file_seek (wth->fh, 0, SEEK_SET, err) == -1)
          {
            return WTAP_OPEN_ERROR;
          }
        return WTAP_OPEN_MINE;
      }
      offset += 1;
    }

    /*
     * Check if this is a ASCII formatted file by scanning for the magic string
     */
    offset=0;
    while ((unsigned int)offset < (ISERIES_LINE_LENGTH - sizeof iseries_hdr_magic_ascii))
      {
        if (memcmp (magic + offset, iseries_hdr_magic_ascii, sizeof iseries_hdr_magic_ascii) == 0)
          {
            if (file_seek (wth->fh, 0, SEEK_SET, err) == -1)
              {
                return WTAP_OPEN_ERROR;
              }
            /*
             * Do some basic sanity checking to ensure we can handle the
             * contents of this trace
             */
            if (!iseries_check_file_type (wth, err, err_info, ISERIES_FORMAT_ASCII))
              {
                if (*err == 0)
                  return WTAP_OPEN_NOT_MINE;
                else
                  return WTAP_OPEN_ERROR;
              }

            wth->file_encap        = WTAP_ENCAP_ETHERNET;
            wth->file_type_subtype = WTAP_FILE_TYPE_SUBTYPE_ISERIES;
            wth->snapshot_length   = 0;
            wth->subtype_read      = iseries_read;
            wth->subtype_seek_read = iseries_seek_read;
            wth->file_tsprec       = WTAP_TSPREC_USEC;

            if (file_seek (wth->fh, 0, SEEK_SET, err) == -1)
              {
                return WTAP_OPEN_ERROR;
              }
            return WTAP_OPEN_MINE;
          }
        offset += 1;
      }

    /* Neither ASCII or UNICODE so not supported */
    return WTAP_OPEN_NOT_MINE;
    }
Ejemplo n.º 30
0
long file_seek(FILEH handle, long pointer, int method) {

	return(file_seek(handle, pointer, method));
}