示例#1
0
static int
read_packet_data(FILE_T fh, int offset_to_frame, int current_offset_from_packet_header, Buffer *buf,
    int length, int *err, char **err_info)
{
    int seek_increment;
    int bytes_consumed = 0;

    /* validate offsets */
    if (offset_to_frame < current_offset_from_packet_header) {
        *err = WTAP_ERR_BAD_FILE;
        *err_info = g_strdup_printf("Observer: bad record (offset to packet data %d < %d)",
            offset_to_frame, current_offset_from_packet_header);
        return -1;
    }

    /* skip to the packet data */
    seek_increment = offset_to_frame - current_offset_from_packet_header;
    if (seek_increment > 0) {
        if (file_seek(fh, seek_increment, SEEK_CUR, err) == -1) {
            return -1;
        }
        bytes_consumed += seek_increment;
    }

    /* set-up the packet buffer */
    ws_buffer_assure_space(buf, length);

    /* read in the packet data */
    if (!wtap_read_packet_bytes(fh, buf, length, err, err_info))
        return FALSE;
    bytes_consumed += length;

    return bytes_consumed;
}
示例#2
0
文件: buffer.c 项目: DHODoS/wireshark
void
ws_buffer_append(Buffer* buffer, guint8 *from, gsize bytes)
{
	ws_buffer_assure_space(buffer, bytes);
	memcpy(buffer->data + buffer->first_free, from, bytes);
	buffer->first_free += bytes;
}
示例#3
0
static gboolean logcat_text_read_packet(FILE_T fh, struct wtap_pkthdr *phdr,
        Buffer *buf, gint file_type) {
    gint8 *pd;
    gchar cbuff[WTAP_MAX_PACKET_SIZE];
    gchar *ret = NULL;

    do {
        ret = file_gets(cbuff, WTAP_MAX_PACKET_SIZE, fh);
    } while (NULL != ret && 3 > strlen(cbuff) && !file_eof(fh));

    if (NULL == ret || 3 > strlen(cbuff)) {
        return FALSE;
    }

    if (WTAP_FILE_TYPE_SUBTYPE_LOGCAT_LONG == file_type &&
            !g_regex_match_simple(SPECIAL_STRING, cbuff, (GRegexCompileFlags)((gint) G_REGEX_ANCHORED | (gint) G_REGEX_RAW), G_REGEX_MATCH_NOTEMPTY)) {
        gint64 file_off = 0;
        gchar lbuff[WTAP_MAX_PACKET_SIZE];
        int err;
        gchar *ret2 = NULL;

        file_off = file_tell(fh);
        ret2 = file_gets(lbuff,WTAP_MAX_PACKET_SIZE, fh);
        while (NULL != ret2 && 2 < strlen(lbuff) && !file_eof(fh)) {
            g_strlcat(cbuff,lbuff,WTAP_MAX_PACKET_SIZE);
            file_off = file_tell(fh);
            ret2 = file_gets(lbuff,WTAP_MAX_PACKET_SIZE, fh);
        }

        if(NULL == ret2 || 2 < strlen(lbuff)) {
            return FALSE;
        }

        file_seek(fh,file_off,SEEK_SET,&err);
    }

    phdr->rec_type = REC_TYPE_PACKET;
    phdr->caplen = (guint32)strlen(cbuff);
    phdr->len = phdr->caplen;

    ws_buffer_assure_space(buf, phdr->caplen + 1);
    pd = ws_buffer_start_ptr(buf);
    if ((WTAP_FILE_TYPE_SUBTYPE_LOGCAT_TIME == file_type
            || WTAP_FILE_TYPE_SUBTYPE_LOGCAT_THREADTIME == file_type
            || WTAP_FILE_TYPE_SUBTYPE_LOGCAT_LONG == file_type)
            && '-' != cbuff[0]) { /* the last part filters out the -- beginning of... lines */
        if (WTAP_FILE_TYPE_SUBTYPE_LOGCAT_LONG == file_type) {
            get_time(cbuff+2, phdr);
        } else {
            get_time(cbuff, phdr);
        }
    } else {
        phdr->presence_flags = 0;
        phdr->ts.secs = (time_t) 0;
        phdr->ts.nsecs = (int) 0;
    }
    memcpy(pd, cbuff, phdr->caplen + 1);
    return TRUE;
}
示例#4
0
/*
 * Read packet data into a Buffer, growing the buffer as necessary.
 *
 * This returns an error on a short read, even if the short read hit
 * the EOF immediately.  (The assumption is that each packet has a
 * header followed by raw packet data, and that we've already read the
 * header, so if we get an EOF trying to read the packet data, the file
 * has been cut short, even if the read didn't read any data at all.)
 */
gboolean
wtap_read_packet_bytes(FILE_T fh, Buffer *buf, guint length, int *err,
    gchar **err_info)
{
	ws_buffer_assure_space(buf, length);
	return wtap_read_bytes(fh, ws_buffer_start_ptr(buf), length, err,
	    err_info);
}
示例#5
0
static gboolean
wtap_full_file_read_file(wtap *wth, FILE_T fh, wtap_rec *rec, Buffer *buf, int *err, gchar **err_info)
{
	gint64 file_size;
	int packet_size = 0;
	const int block_size = 1024 * 1024;

	if ((file_size = wtap_file_size(wth, err)) == -1)
		return FALSE;

	if (file_size > G_MAXINT) {
		/*
		 * Avoid allocating space for an immensely-large file.
		 */
		*err = WTAP_ERR_BAD_FILE;
		*err_info = g_strdup_printf("%s: File has %" G_GINT64_MODIFIER "d-byte packet, bigger than maximum of %u",
				wtap_encap_name(wth->file_encap), file_size, G_MAXINT);
		return FALSE;
	}

	/*
	 * Compressed files might expand to a larger size than the actual file
	 * size. Try to read the full size and then read in smaller increments
	 * to avoid frequent memory reallocations.
	 */
	int buffer_size = block_size * (1 + (int)file_size / block_size);
	for (;;) {
		if (buffer_size <= 0) {
			*err = WTAP_ERR_BAD_FILE;
			*err_info = g_strdup_printf("%s: Uncompressed file is bigger than maximum of %u",
					wtap_encap_name(wth->file_encap), G_MAXINT);
			return FALSE;
		}
		ws_buffer_assure_space(buf, buffer_size);
		int nread = file_read(ws_buffer_start_ptr(buf) + packet_size, buffer_size - packet_size, fh);
		if (nread < 0) {
			*err = file_error(fh, err_info);
			if (*err == 0)
				*err = WTAP_ERR_BAD_FILE;
			return FALSE;
		}
		packet_size += nread;
		if (packet_size != buffer_size) {
			/* EOF */
			break;
		}
		buffer_size += block_size;
	}

	rec->rec_type = REC_TYPE_PACKET;
	rec->presence_flags = 0; /* yes, we have no bananas^Wtime stamp */
	rec->ts.secs = 0;
	rec->ts.nsecs = 0;
	rec->rec_header.packet_header.caplen = packet_size;
	rec->rec_header.packet_header.len = packet_size;

	return TRUE;
}
示例#6
0
/* Used to read packets in random-access fashion */
static gboolean
pppdump_seek_read(wtap *wth,
		 gint64 seek_off,
		 struct wtap_pkthdr *phdr,
		 Buffer *buf,
		 int *err,
		 gchar **err_info)
{
	int		num_bytes;
	guint8		*pd;
	direction_enum	direction;
	pppdump_t	*state;
	pkt_id		*pid;
	gint64		num_bytes_to_skip;

	state = (pppdump_t *)wth->priv;

	pid = (pkt_id *)g_ptr_array_index(state->pids, seek_off);
	if (!pid) {
		*err = WTAP_ERR_BAD_FILE;	/* XXX - better error? */
		*err_info = g_strdup("pppdump: PID not found for record");
		return FALSE;
	}

	if (file_seek(wth->random_fh, pid->offset, SEEK_SET, err) == -1)
		return FALSE;

	init_state(state->seek_state);
	state->seek_state->offset = pid->offset;

	ws_buffer_assure_space(buf, PPPD_BUF_SIZE);
	pd = ws_buffer_start_ptr(buf);

	/*
	 * We'll start reading at the first record containing data from
	 * this packet; however, that doesn't mean "collate()" will
	 * stop only when we've read that packet, as there might be
	 * data for packets going in the other direction as well, and
	 * we might finish processing one of those packets before we
	 * finish processing the packet we're reading.
	 *
	 * Therefore, we keep reading until we get a packet that's
	 * going in the direction we want.
	 */
	num_bytes_to_skip = pid->num_bytes_to_skip;
	do {
		if (!collate(state->seek_state, wth->random_fh, err, err_info,
		    pd, &num_bytes, &direction, NULL, num_bytes_to_skip))
			return FALSE;
		num_bytes_to_skip = 0;
	} while (direction != pid->dir);

	pppdump_set_phdr(phdr, num_bytes, pid->dir);

	return TRUE;
}
示例#7
0
/* Find the next packet and parse it; called from wtap_read(). */
static gboolean
pppdump_read(wtap *wth, int *err, gchar **err_info, gint64 *data_offset)
{
	int		num_bytes;
	direction_enum	direction;
	guint8		*buf;
	pppdump_t	*state;
	pkt_id		*pid;

	state = (pppdump_t *)wth->priv;

	/* If we have a random stream open, allocate a structure to hold
	   the information needed to read this packet's data again. */
	if (wth->random_fh != NULL) {
		pid = g_new(pkt_id, 1);
		if (!pid) {
			*err = errno;	/* assume a malloc failed and set "errno" */
			return FALSE;
		}
		pid->offset = 0;
	} else
		pid = NULL;	/* sequential only */

	ws_buffer_assure_space(wth->frame_buffer, PPPD_BUF_SIZE);
	buf = ws_buffer_start_ptr(wth->frame_buffer);

	if (!collate(state, wth->fh, err, err_info, buf, &num_bytes, &direction,
	    pid, 0)) {
		if (pid != NULL)
			g_free(pid);
		return FALSE;
	}

	if (pid != NULL)
		pid->dir = direction;

	if (pid != NULL)
		g_ptr_array_add(state->pids, pid);
	/* The user's data_offset is not really an offset, but a packet number. */
	*data_offset = state->pkt_cnt;
	state->pkt_cnt++;

	pppdump_set_phdr(&wth->phdr, num_bytes, direction);
	wth->phdr.presence_flags = WTAP_HAS_TS;
	wth->phdr.ts.secs	= state->timestamp;
	wth->phdr.ts.nsecs	= state->tenths * 100000000;

	return TRUE;
}
示例#8
0
/* Parses a packet. */
static gboolean
iseries_parse_packet (wtap * wth, FILE_T fh, wtap_rec *rec,
                      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;
    }

  rec->rec_type = REC_TYPE_PACKET;
  rec->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)
    {
      rec->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;
      rec->ts.secs = mktime (&tm);
      rec->ts.nsecs = csec * csec_multiplier(csec);
    }

  rec->rec_header.packet_header.len                       = pkt_len;
  rec->rec_header.packet_header.pkt_encap                 = WTAP_ENCAP_ETHERNET;
  rec->rec_header.packet_header.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.
   */
  rec->rec_header.packet_header.caplen = ((guint32) ascii_offset)/2;

  /* Make sure we have enough room for the packet. */
  ws_buffer_assure_space (buf, rec->rec_header.packet_header.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;
}
示例#9
0
static gboolean
parse_dbs_etherwatch_packet(wtap_rec *rec, FILE_T fh, Buffer* buf,
    int *err, gchar **err_info)
{
    guint8 *pd;
    char    line[DBS_ETHERWATCH_LINE_LENGTH];
    int num_items_scanned;
    int eth_hdr_len, pkt_len, csec;
    int length_pos, length_from, length;
    struct tm tm;
    char mon[4] = "xxx";
    gchar *p;
    static const gchar months[] = "JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC";
    int count, line_count;

    /* Make sure we have enough room for a regular Ethernet packet */
    ws_buffer_assure_space(buf, DBS_ETHERWATCH_MAX_ETHERNET_PACKET_LEN);
    pd = ws_buffer_start_ptr(buf);

    eth_hdr_len = 0;
    memset(&tm, 0, sizeof(tm));
    /* Our file pointer should be on the first line containing the
     * summary information for a packet. Read in that line and
     * extract the useful information
     */
    if (file_gets(line, DBS_ETHERWATCH_LINE_LENGTH, fh) == NULL) {
        *err = file_error(fh, err_info);
        if (*err == 0) {
            *err = WTAP_ERR_SHORT_READ;
        }
        return FALSE;
    }

    /* Get the destination address */
    p = strstr(line, DEST_MAC_PREFIX);
    if(!p) {
        *err = WTAP_ERR_BAD_FILE;
        *err_info = g_strdup("dbs_etherwatch: destination address not found");
        return FALSE;
    }
    p += strlen(DEST_MAC_PREFIX);
    if(parse_hex_dump(p, &pd[eth_hdr_len], HEX_HDR_SPR, HEX_HDR_END)
                != MAC_ADDR_LENGTH) {
        *err = WTAP_ERR_BAD_FILE;
        *err_info = g_strdup("dbs_etherwatch: destination address not valid");
        return FALSE;
    }
    eth_hdr_len += MAC_ADDR_LENGTH;

    /* Get the source address */
    /*
     * Since the first part of the line is already skipped in order to find
     * the start of the record we cannot index, just look for the first
     * 'HEX' character
     */
    p = line;
    while(!g_ascii_isxdigit(*p)) {
        p++;
    }
    if(parse_hex_dump(p, &pd[eth_hdr_len], HEX_HDR_SPR,
        HEX_HDR_END) != MAC_ADDR_LENGTH) {
        *err = WTAP_ERR_BAD_FILE;
        *err_info = g_strdup("dbs_etherwatch: source address not valid");
        return FALSE;
    }
    eth_hdr_len += MAC_ADDR_LENGTH;

    /* Read the next line of the record header */
    if (file_gets(line, DBS_ETHERWATCH_LINE_LENGTH, fh) == NULL) {
        *err = file_error(fh, err_info);
        if (*err == 0) {
            *err = WTAP_ERR_SHORT_READ;
        }
        return FALSE;
    }

    /* Check the lines is as least as long as the length position */
    if(strlen(line) < LENGTH_POS) {
        *err = WTAP_ERR_BAD_FILE;
        *err_info = g_strdup("dbs_etherwatch: line too short");
        return FALSE;
    }

    num_items_scanned = sscanf(line + LENGTH_POS,
                "%9d byte buffer at %2d-%3s-%4d %2d:%2d:%2d.%9d",
                &pkt_len,
                &tm.tm_mday, mon,
                &tm.tm_year, &tm.tm_hour, &tm.tm_min,
                &tm.tm_sec, &csec);

    if (num_items_scanned != 8) {
        *err = WTAP_ERR_BAD_FILE;
        *err_info = g_strdup("dbs_etherwatch: header line not valid");
        return FALSE;
    }

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

    /* Determine whether it is Ethernet II or IEEE 802 */
    if(strncmp(&line[ETH_II_CHECK_POS], ETH_II_CHECK_STR,
        strlen(ETH_II_CHECK_STR)) == 0) {
        /* Ethernet II */
        /* Get the Protocol */
        if(parse_hex_dump(&line[PROTOCOL_POS], &pd[eth_hdr_len], HEX_HDR_SPR,
                    HEX_HDR_END) != PROTOCOL_LENGTH) {
            *err = WTAP_ERR_BAD_FILE;
            *err_info = g_strdup("dbs_etherwatch: Ethernet II protocol value not valid");
            return FALSE;
        }
        eth_hdr_len += PROTOCOL_LENGTH;
    } else {
        /* IEEE 802 */
        /* Remember where to put the length in the header */
        length_pos = eth_hdr_len;
        /* Leave room in the header for the length */
        eth_hdr_len += IEEE802_LEN_LEN;
        /* Remember how much of the header should not be added to the length */
        length_from = eth_hdr_len;
        /* Get the DSAP + SSAP */
        if(parse_hex_dump(&line[SAP_POS], &pd[eth_hdr_len], HEX_HDR_SPR,
                    HEX_HDR_END) != SAP_LENGTH) {
            *err = WTAP_ERR_BAD_FILE;
            *err_info = g_strdup("dbs_etherwatch: 802.2 DSAP+SSAP value not valid");
            return FALSE;
        }
        eth_hdr_len += SAP_LENGTH;
        /* Get the (first part of the) control field */
        if(parse_hex_dump(&line[CTL_POS], &pd[eth_hdr_len], HEX_HDR_SPR,
                    HEX_HDR_END) != CTL_UNNUMB_LENGTH) {
            *err = WTAP_ERR_BAD_FILE;
            *err_info = g_strdup("dbs_etherwatch: 802.2 control field first part not valid");
            return FALSE;
        }
        /* Determine whether the control is numbered, and thus longer */
        if((pd[eth_hdr_len] & CTL_UNNUMB_MASK) != CTL_UNNUMB_VALUE) {
            /* Get the rest of the control field, the first octet in the PID */
            if(parse_hex_dump(&line[PID_POS],
                        &pd[eth_hdr_len + CTL_UNNUMB_LENGTH], HEX_HDR_END,
                        HEX_HDR_SPR) != CTL_NUMB_LENGTH - CTL_UNNUMB_LENGTH) {
                *err = WTAP_ERR_BAD_FILE;
                *err_info = g_strdup("dbs_etherwatch: 802.2 control field second part value not valid");
                return FALSE;
            }
            eth_hdr_len += CTL_NUMB_LENGTH;
        } else {
            eth_hdr_len += CTL_UNNUMB_LENGTH;
        }
        /* Determine whether it is SNAP */
        if(strncmp(&line[SNAP_CHECK_POS], SNAP_CHECK_STR,
                strlen(SNAP_CHECK_STR)) == 0) {
            /* Get the PID */
            if(parse_hex_dump(&line[PID_POS], &pd[eth_hdr_len], HEX_HDR_SPR,
                        HEX_PID_END) != PID_LENGTH) {
                *err = WTAP_ERR_BAD_FILE;
                *err_info = g_strdup("dbs_etherwatch: 802.2 PID value not valid");
                return FALSE;
            }
            eth_hdr_len += PID_LENGTH;
        }
        /* Write the length in the header */
        length = eth_hdr_len - length_from + pkt_len;
        pd[length_pos] = (length) >> 8;
        pd[length_pos+1] = (length) & 0xFF;
    }

    rec->rec_type = REC_TYPE_PACKET;
    rec->presence_flags = WTAP_HAS_TS|WTAP_HAS_CAP_LEN;

    p = strstr(months, mon);
    if (p)
        tm.tm_mon = (int)(p - months) / 3;
    tm.tm_year -= 1900;

    tm.tm_isdst = -1;
    rec->ts.secs = mktime(&tm);
    rec->ts.nsecs = csec * 10000000;
    rec->rec_header.packet_header.caplen = eth_hdr_len + pkt_len;
    rec->rec_header.packet_header.len = eth_hdr_len + pkt_len;

    if (rec->rec_header.packet_header.caplen > WTAP_MAX_PACKET_SIZE_STANDARD) {
        /*
         * Probably a corrupt capture file; return an error,
         * so that our caller doesn't blow up trying to allocate
         * space for an immensely-large packet.
         */
        *err = WTAP_ERR_BAD_FILE;
        *err_info = g_strdup_printf("dbs_etherwatch: File has %u-byte packet, bigger than maximum of %u",
                                    rec->rec_header.packet_header.caplen, WTAP_MAX_PACKET_SIZE_STANDARD);
        return FALSE;
    }

    /* Make sure we have enough room, even for an oversized Ethernet packet */
    ws_buffer_assure_space(buf, rec->rec_header.packet_header.caplen);
    pd = ws_buffer_start_ptr(buf);

    /*
     * We don't have an FCS in this frame.
     */
    rec->rec_header.packet_header.pseudo_header.eth.fcs_len = 0;

    /* Parse the hex dump */
    count = 0;
    while (count < pkt_len) {
        if (file_gets(line, DBS_ETHERWATCH_LINE_LENGTH, fh) == NULL) {
            *err = file_error(fh, err_info);
            if (*err == 0) {
                *err = WTAP_ERR_SHORT_READ;
            }
            return FALSE;
        }
        if (!(line_count = parse_single_hex_dump_line(line,
                &pd[eth_hdr_len + count], count))) {
            *err = WTAP_ERR_BAD_FILE;
            *err_info = g_strdup("dbs_etherwatch: packet data value not valid");
            return FALSE;
        }
        count += line_count;
        if (count > pkt_len) {
            *err = WTAP_ERR_BAD_FILE;
            *err_info = g_strdup("dbs_etherwatch: packet data value has too many bytes");
            return FALSE;
        }
    }
    return TRUE;
}
示例#10
0
/* Converts ASCII hex dump to binary data, and fills in some struct
   wtap_pkthdr fields.  Returns TRUE on success and FALSE on any error. */
static gboolean
parse_netscreen_hex_dump(FILE_T fh, int pkt_len, const char *cap_int,
    const char *cap_dst, struct wtap_pkthdr *phdr, Buffer* buf,
    int *err, gchar **err_info)
{
	guint8	*pd;
	gchar	line[NETSCREEN_LINE_LENGTH];
	gchar	*p;
	int	n, i = 0, offset = 0;
	gchar	dststr[13];

	/* Make sure we have enough room for the packet */
	ws_buffer_assure_space(buf, NETSCREEN_MAX_PACKET_LEN);
	pd = ws_buffer_start_ptr(buf);

	while(1) {

		/* The last packet is not delimited by an empty line, but by EOF
		 * So accept EOF as a valid delimiter too
		 */
		if (file_gets(line, NETSCREEN_LINE_LENGTH, fh) == NULL) {
			break;
		}

		/*
		 * Skip blanks.
		 * The number of blanks is not fixed - for wireless
		 * interfaces, there may be 14 extra spaces before
		 * the hex data.
		 */
		for (p = &line[0]; g_ascii_isspace(*p); p++)
			;
		/* packets are delimited with empty lines */
		if (*p == '\0') {
			break;
		}

		n = parse_single_hex_dump_line(p, pd, offset);

		/* the smallest packet has a length of 6 bytes, if
		 * the first hex-data is less then check whether
		 * it is a info-line and act accordingly
		 */
		if (offset == 0 && n < 6) {
			if (info_line(line)) {
				if (++i <= NETSCREEN_MAX_INFOLINES) {
					continue;
				}
			} else {
				*err = WTAP_ERR_BAD_FILE;
				*err_info = g_strdup("netscreen: cannot parse hex-data");
				return FALSE;
			}
		}

		/* If there is no more data and the line was not empty,
		 * then there must be an error in the file
		 */
		if(n == -1) {
			*err = WTAP_ERR_BAD_FILE;
			*err_info = g_strdup("netscreen: cannot parse hex-data");
			return FALSE;
		}

		/* Adjust the offset to the data that was just added to the buffer */
		offset += n;

		/* If there was more hex-data than was announced in the len=x
		 * header, then then there must be an error in the file
		 */
		if(offset > pkt_len) {
			*err = WTAP_ERR_BAD_FILE;
			*err_info = g_strdup("netscreen: too much hex-data");
			return FALSE;
		}
	}

	/*
	 * Determine the encapsulation type, based on the
	 * first 4 characters of the interface name
	 *
	 * XXX	convert this to a 'case' structure when adding more
	 *	(non-ethernet) interfacetypes
	 */
	if (strncmp(cap_int, "adsl", 4) == 0) {
		/* The ADSL interface can be bridged with or without
		 * PPP encapsulation. Check whether the first six bytes
		 * of the hex data are the same as the destination mac
		 * address in the header. If they are, assume ethernet
		 * LinkLayer or else PPP
		 */
		g_snprintf(dststr, 13, "%02x%02x%02x%02x%02x%02x",
		   pd[0], pd[1], pd[2], pd[3], pd[4], pd[5]);
		if (strncmp(dststr, cap_dst, 12) == 0)
			phdr->pkt_encap = WTAP_ENCAP_ETHERNET;
		else
			phdr->pkt_encap = WTAP_ENCAP_PPP;
		}
	else if (strncmp(cap_int, "seri", 4) == 0)
		phdr->pkt_encap = WTAP_ENCAP_PPP;
	else
		phdr->pkt_encap = WTAP_ENCAP_ETHERNET;

	phdr->caplen = offset;

	return TRUE;
}
示例#11
0
/* Parses a record. */
static gboolean
read_eyesdn_rec(FILE_T fh, wtap_rec *rec, Buffer *buf, int *err,
    gchar **err_info)
{
	union wtap_pseudo_header *pseudo_header = &rec->rec_header.packet_header.pseudo_header;
	guint8		hdr[EYESDN_HDR_LENGTH];
	time_t		secs;
	int		usecs;
	int		pkt_len;
	guint8		channel, direction;
	guint8		*pd;

	/* Our file pointer should be at the summary information header
	 * for a packet. Read in that header and extract the useful
	 * information.
	 */
	if (!esc_read(fh, hdr, EYESDN_HDR_LENGTH, err, err_info))
		return FALSE;

	/* extract information from header */
	usecs = pntoh24(&hdr[0]);
#ifdef TV64BITS
	secs = hdr[3];
#else
	secs = 0;
#endif
	secs = (secs << 8) | hdr[4];
	secs = (secs << 8) | hdr[5];
	secs = (secs << 8) | hdr[6];
	secs = (secs << 8) | hdr[7];

	channel = hdr[8];
	direction = hdr[9];
	pkt_len = pntoh16(&hdr[10]);

	switch(direction >> 1) {

	default:
	case EYESDN_ENCAP_ISDN: /* ISDN */
		pseudo_header->isdn.uton = direction & 1;
		pseudo_header->isdn.channel = channel;
		if(channel) { /* bearer channels */
			rec->rec_header.packet_header.pkt_encap = WTAP_ENCAP_ISDN; /* recognises PPP */
			pseudo_header->isdn.uton=!pseudo_header->isdn.uton; /* bug */
		} else { /* D channel */
			rec->rec_header.packet_header.pkt_encap = WTAP_ENCAP_ISDN;
		}
		break;

	case EYESDN_ENCAP_MSG: /* Layer 1 message */
		rec->rec_header.packet_header.pkt_encap = WTAP_ENCAP_LAYER1_EVENT;
		pseudo_header->l1event.uton = (direction & 1);
		break;

	case EYESDN_ENCAP_LAPB: /* X.25 via LAPB */
		rec->rec_header.packet_header.pkt_encap = WTAP_ENCAP_LAPB;
		pseudo_header->dte_dce.flags = (direction & 1) ? 0 : 0x80;
		break;

	case EYESDN_ENCAP_ATM: { /* ATM cells */
#define CELL_LEN 53
		unsigned char cell[CELL_LEN];
		gint64 cur_off;

		if(pkt_len != CELL_LEN) {
			*err = WTAP_ERR_BAD_FILE;
			*err_info = g_strdup_printf(
			    "eyesdn: ATM cell has a length != 53 (%u)",
			    pkt_len);
			return FALSE;
		}

		cur_off = file_tell(fh);
		if (!esc_read(fh, cell, CELL_LEN, err, err_info))
			return FALSE;
		if (file_seek(fh, cur_off, SEEK_SET, err) == -1)
			return FALSE;
		rec->rec_header.packet_header.pkt_encap = WTAP_ENCAP_ATM_PDUS_UNTRUNCATED;
		pseudo_header->atm.flags=ATM_RAW_CELL;
		pseudo_header->atm.aal=AAL_UNKNOWN;
		pseudo_header->atm.type=TRAF_UMTS_FP;
		pseudo_header->atm.subtype=TRAF_ST_UNKNOWN;
		pseudo_header->atm.vpi=((cell[0]&0xf)<<4) + (cell[0]&0xf);
		pseudo_header->atm.vci=((cell[0]&0xf)<<4) + cell[0]; /* from cell */
		pseudo_header->atm.channel=direction & 1;
		}
		break;

	case EYESDN_ENCAP_MTP2: /* SS7 frames */
		pseudo_header->mtp2.sent = direction & 1;
		pseudo_header->mtp2.annex_a_used = MTP2_ANNEX_A_USED_UNKNOWN;
		pseudo_header->mtp2.link_number = channel;
		rec->rec_header.packet_header.pkt_encap = WTAP_ENCAP_MTP2_WITH_PHDR;
		break;

	case EYESDN_ENCAP_DPNSS: /* DPNSS */
		pseudo_header->isdn.uton = direction & 1;
		pseudo_header->isdn.channel = channel;
		rec->rec_header.packet_header.pkt_encap = WTAP_ENCAP_DPNSS;
		break;

	case EYESDN_ENCAP_DASS2: /* DASS2 frames */
		pseudo_header->isdn.uton = direction & 1;
		pseudo_header->isdn.channel = channel;
		rec->rec_header.packet_header.pkt_encap = WTAP_ENCAP_DPNSS;
		break;

	case EYESDN_ENCAP_BACNET: /* BACNET async over HDLC frames */
	        pseudo_header->isdn.uton = direction & 1;
		pseudo_header->isdn.channel = channel;
		rec->rec_header.packet_header.pkt_encap = WTAP_ENCAP_BACNET_MS_TP_WITH_PHDR;
		break;

	case EYESDN_ENCAP_V5_EF: /* V5EF */
		pseudo_header->isdn.uton = direction & 1;
		pseudo_header->isdn.channel = channel;
		rec->rec_header.packet_header.pkt_encap = WTAP_ENCAP_V5_EF;
		break;
	}

	if(pkt_len > WTAP_MAX_PACKET_SIZE_STANDARD) {
		*err = WTAP_ERR_BAD_FILE;
		*err_info = g_strdup_printf("eyesdn: File has %u-byte packet, bigger than maximum of %u",
		    pkt_len, WTAP_MAX_PACKET_SIZE_STANDARD);
		return FALSE;
	}

	rec->rec_type = REC_TYPE_PACKET;
	rec->presence_flags = WTAP_HAS_TS;
	rec->ts.secs = secs;
	rec->ts.nsecs = usecs * 1000;
	rec->rec_header.packet_header.caplen = pkt_len;
	rec->rec_header.packet_header.len = pkt_len;

	/* Make sure we have enough room for the packet */
	ws_buffer_assure_space(buf, pkt_len);

	pd = ws_buffer_start_ptr(buf);
	if (!esc_read(fh, pd, pkt_len, err, err_info))
		return FALSE;
	return TRUE;
}
示例#12
0
文件: vms.c 项目: wireshark/wireshark
/* Parses a packet record. */
static gboolean
parse_vms_packet(FILE_T fh, wtap_rec *rec, Buffer *buf, int *err, gchar **err_info)
{
    char    line[VMS_LINE_LENGTH + 1];
    int     num_items_scanned;
    guint32 pkt_len = 0;
    int     pktnum;
    int     csec = 101;
    struct tm tm;
    char mon[4] = {'J', 'A', 'N', 0};
    gchar  *p;
    const gchar *endp;
    static const gchar months[] = "JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC";
    guint32 i;
    int     offset = 0;
    guint8 *pd;

    tm.tm_year = 1970;
    tm.tm_mon = 0;
    tm.tm_mday = 1;
    tm.tm_hour = 1;
    tm.tm_min = 1;
    tm.tm_sec = 1;

    /* Skip lines until one starts with a hex number */
    do {
        if (file_gets(line, VMS_LINE_LENGTH, fh) == NULL) {
            *err = file_error(fh, err_info);
            if ((*err == 0) && (csec != 101)) {
                *err = WTAP_ERR_SHORT_READ;
            }
            return FALSE;
        }
        line[VMS_LINE_LENGTH] = '\0';

        if ((csec == 101) && (p = strstr(line, "packet ")) != NULL
            && (! strstr(line, "could not save "))) {
            /* Find text in line starting with "packet ". */

            /* First look for the Format 1 type sequencing */
            num_items_scanned = sscanf(p,
                                       "packet %9d at %2d-%3s-%4d %2d:%2d:%2d.%9d",
                                       &pktnum, &tm.tm_mday, mon,
                                       &tm.tm_year, &tm.tm_hour,
                                       &tm.tm_min, &tm.tm_sec, &csec);
            /* Next look for the Format 2 type sequencing */
            if (num_items_scanned != 8) {
              num_items_scanned = sscanf(p,
                                         "packet seq # = %9d at %2d-%3s-%4d %2d:%2d:%2d.%9d",
                                         &pktnum, &tm.tm_mday, mon,
                                         &tm.tm_year, &tm.tm_hour,
                                         &tm.tm_min, &tm.tm_sec, &csec);
            }
            /* if unknown format then exit with error        */
            /* We will need to add code to handle new format */
            if (num_items_scanned != 8) {
                *err = WTAP_ERR_BAD_FILE;
                *err_info = g_strdup("vms: header line not valid");
                return FALSE;
            }
        }
        if ( (! pkt_len) && (p = strstr(line, "Length"))) {
            p += sizeof("Length ");
            while (*p && ! g_ascii_isdigit(*p))
                p++;

            if ( !*p ) {
                *err = WTAP_ERR_BAD_FILE;
                *err_info = g_strdup("vms: Length field not valid");
                return FALSE;
            }

            if (!ws_strtou32(p, &endp, &pkt_len) || (*endp != '\0' && !g_ascii_isspace(*endp))) {
                *err = WTAP_ERR_BAD_FILE;
                *err_info = g_strdup_printf("vms: Length field '%s' not valid", p);
                return FALSE;
            }
            break;
        }
    } while (! isdumpline(line));
    if (pkt_len > WTAP_MAX_PACKET_SIZE_STANDARD) {
        /*
         * Probably a corrupt capture file; return an error,
         * so that our caller doesn't blow up trying to allocate
         * space for an immensely-large packet.
         */
        *err = WTAP_ERR_BAD_FILE;
        *err_info = g_strdup_printf("vms: File has %u-byte packet, bigger than maximum of %u",
                                    pkt_len, WTAP_MAX_PACKET_SIZE_STANDARD);
        return FALSE;
    }

    p = strstr(months, mon);
    if (p)
        tm.tm_mon = (int) (p - months) / 3;
    tm.tm_year -= 1900;
    tm.tm_isdst = -1;

    rec->rec_type = REC_TYPE_PACKET;
    rec->presence_flags = WTAP_HAS_TS;
    rec->ts.secs = mktime(&tm);
    rec->ts.nsecs = csec * 10000000;
    rec->rec_header.packet_header.caplen = pkt_len;
    rec->rec_header.packet_header.len = pkt_len;

    /* Make sure we have enough room for the packet */
    ws_buffer_assure_space(buf, pkt_len);
    pd = ws_buffer_start_ptr(buf);

    /* Convert the ASCII hex dump to binary data */
    for (i = 0; i < pkt_len; i += 16) {
        if (file_gets(line, VMS_LINE_LENGTH, fh) == NULL) {
            *err = file_error(fh, err_info);
            if (*err == 0) {
                *err = WTAP_ERR_SHORT_READ;
            }
            return FALSE;
        }
        line[VMS_LINE_LENGTH] = '\0';
        if (i == 0) {
            while (! isdumpline(line)) { /* advance to start of hex data */
                if (file_gets(line, VMS_LINE_LENGTH, fh) == NULL) {
                    *err = file_error(fh, err_info);
                    if (*err == 0) {
                        *err = WTAP_ERR_SHORT_READ;
                    }
                    return FALSE;
                }
                line[VMS_LINE_LENGTH] = '\0';
            }
            while (line[offset] && !g_ascii_isxdigit(line[offset]))
                offset++;
        }
        if (!parse_single_hex_dump_line(line, pd, i,
                                        offset, pkt_len - i)) {
            *err = WTAP_ERR_BAD_FILE;
            *err_info = g_strdup("vms: hex dump not valid");
            return FALSE;
        }
    }
    /* Avoid TCPIPTRACE-W-BUFFERSFUL, TCPIPtrace could not save n packets.
     * errors.
     *
     * XXX - when we support packet drop report information in the
     * Wiretap API, we should parse those lines and return "n" as
     * a packet drop count. */
    if (!file_gets(line, VMS_LINE_LENGTH, fh)) {
        *err = file_error(fh, err_info);
        if (*err == 0) {
            /* There is no next line, so there's no "TCPIPtrace could not
             * save n packets" line; not an error. */
            return TRUE;
        }
        return FALSE;
    }
    return TRUE;
}
示例#13
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;
}
示例#14
0
文件: cosine.c 项目: DHODoS/wireshark
/* Parses a packet record header. There are two possible formats:
    1) output to a control blade with date and time
        2002-5-10,20:1:31.4:  l2-tx (FR:3/7/1:1), Length:18, Pro:0, Off:0, Pri:0, RM:0, Err:0 [0x4000, 0x0]
    2) output to PE without date and time
        l2-tx (FR:3/7/1:1), Length:18, Pro:0, Off:0, Pri:0, RM:0, Err:0 [0x4000, 0x0] */
static gboolean
parse_cosine_packet(FILE_T fh, struct wtap_pkthdr *phdr, Buffer *buf,
    char *line, int *err, gchar **err_info)
{
	union wtap_pseudo_header *pseudo_header = &phdr->pseudo_header;
	int	num_items_scanned;
	int	yy, mm, dd, hr, min, sec, csec, pkt_len;
	int	pro, off, pri, rm, error;
	guint	code1, code2;
	char	if_name[COSINE_MAX_IF_NAME_LEN] = "", direction[6] = "";
	struct	tm tm;
	guint8 *pd;
	int	i, hex_lines, n, caplen = 0;

	if (sscanf(line, "%4d-%2d-%2d,%2d:%2d:%2d.%9d:",
		   &yy, &mm, &dd, &hr, &min, &sec, &csec) == 7) {
		/* appears to be output to a control blade */
		num_items_scanned = sscanf(line,
		   "%4d-%2d-%2d,%2d:%2d:%2d.%9d: %5s (%127[A-Za-z0-9/:]), Length:%9d, Pro:%9d, Off:%9d, Pri:%9d, RM:%9d, Err:%9d [%8x, %8x]",
			&yy, &mm, &dd, &hr, &min, &sec, &csec,
				   direction, if_name, &pkt_len,
				   &pro, &off, &pri, &rm, &error,
				   &code1, &code2);

		if (num_items_scanned != 17) {
			*err = WTAP_ERR_BAD_FILE;
			*err_info = g_strdup("cosine: purported control blade line doesn't have code values");
			return FALSE;
		}
	} else {
		/* appears to be output to PE */
		num_items_scanned = sscanf(line,
		   "%5s (%127[A-Za-z0-9/:]), Length:%9d, Pro:%9d, Off:%9d, Pri:%9d, RM:%9d, Err:%9d [%8x, %8x]",
				   direction, if_name, &pkt_len,
				   &pro, &off, &pri, &rm, &error,
				   &code1, &code2);

		if (num_items_scanned != 10) {
			*err = WTAP_ERR_BAD_FILE;
			*err_info = g_strdup("cosine: header line is neither control blade nor PE output");
			return FALSE;
		}
		yy = mm = dd = hr = min = sec = csec = 0;
	}
	if (pkt_len < 0) {
		*err = WTAP_ERR_BAD_FILE;
		*err_info = g_strdup("cosine: packet header has a negative packet length");
		return FALSE;
	}
	if (pkt_len > 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("cosine: File has %u-byte packet, bigger than maximum of %u",
		    pkt_len, WTAP_MAX_PACKET_SIZE);
		return FALSE;
	}

	phdr->rec_type = REC_TYPE_PACKET;
	phdr->presence_flags = WTAP_HAS_TS|WTAP_HAS_CAP_LEN;
	tm.tm_year = yy - 1900;
	tm.tm_mon = mm - 1;
	tm.tm_mday = dd;
	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 * 10000000;
	phdr->len = pkt_len;

	/* XXX need to handle other encapsulations like Cisco HDLC,
	   Frame Relay and ATM */
	if (strncmp(if_name, "TEST:", 5) == 0) {
		pseudo_header->cosine.encap = COSINE_ENCAP_TEST;
	} else if (strncmp(if_name, "PPoATM:", 7) == 0) {
		pseudo_header->cosine.encap = COSINE_ENCAP_PPoATM;
	} else if (strncmp(if_name, "PPoFR:", 6) == 0) {
		pseudo_header->cosine.encap = COSINE_ENCAP_PPoFR;
	} else if (strncmp(if_name, "ATM:", 4) == 0) {
		pseudo_header->cosine.encap = COSINE_ENCAP_ATM;
	} else if (strncmp(if_name, "FR:", 3) == 0) {
		pseudo_header->cosine.encap = COSINE_ENCAP_FR;
	} else if (strncmp(if_name, "HDLC:", 5) == 0) {
		pseudo_header->cosine.encap = COSINE_ENCAP_HDLC;
	} else if (strncmp(if_name, "PPP:", 4) == 0) {
		pseudo_header->cosine.encap = COSINE_ENCAP_PPP;
	} else if (strncmp(if_name, "ETH:", 4) == 0) {
		pseudo_header->cosine.encap = COSINE_ENCAP_ETH;
	} else {
		pseudo_header->cosine.encap = COSINE_ENCAP_UNKNOWN;
	}
	if (strncmp(direction, "l2-tx", 5) == 0) {
		pseudo_header->cosine.direction = COSINE_DIR_TX;
	} else if (strncmp(direction, "l2-rx", 5) == 0) {
		pseudo_header->cosine.direction = COSINE_DIR_RX;
	}
	g_strlcpy(pseudo_header->cosine.if_name, if_name,
		COSINE_MAX_IF_NAME_LEN);
	pseudo_header->cosine.pro = pro;
	pseudo_header->cosine.off = off;
	pseudo_header->cosine.pri = pri;
	pseudo_header->cosine.rm = rm;
	pseudo_header->cosine.err = error;

	/* Make sure we have enough room for the packet */
	ws_buffer_assure_space(buf, pkt_len);
	pd = ws_buffer_start_ptr(buf);

	/* Calculate the number of hex dump lines, each
	 * containing 16 bytes of data */
	hex_lines = pkt_len / 16 + ((pkt_len % 16) ? 1 : 0);

	for (i = 0; i < hex_lines; i++) {
		if (file_gets(line, COSINE_LINE_LENGTH, fh) == NULL) {
			*err = file_error(fh, err_info);
			if (*err == 0) {
				*err = WTAP_ERR_SHORT_READ;
			}
			return FALSE;
		}
		if (empty_line(line)) {
			break;
		}
		if ((n = parse_single_hex_dump_line(line, pd, i*16)) == -1) {
			*err = WTAP_ERR_BAD_FILE;
			*err_info = g_strdup("cosine: hex dump line doesn't have 16 numbers");
			return FALSE;
		}
		caplen += n;
	}
	phdr->caplen = caplen;
	return TRUE;
}
示例#15
0
/* Read a header line, scan it, and fill in a struct wtap_pkthdr.
 * Then convert packet data from ASCII hex string to binary in place,
 * sanity-check its length against what we assume is the packet length field,
 * and copy it into a Buffer. */
static gboolean
daintree_sna_read_packet(FILE_T fh, struct wtap_pkthdr *phdr, Buffer *buf,
    int *err, gchar **err_info)
{
	guint64 seconds;
	int useconds;
	char readLine[DAINTREE_MAX_LINE_SIZE];
	char readData[READDATA_BUF_SIZE];
	guchar *str = (guchar *)readData;
	guint bytes;
	guint8 *p;

	/* we've only seen file header lines starting with '#', but
	 * if others appear in the file, they are tossed */
	do {
		if (file_gets(readLine, DAINTREE_MAX_LINE_SIZE, fh) == NULL) {
			*err = file_error(fh, err_info);
			return FALSE; /* all done */
		}
	} while (readLine[0] == COMMENT_LINE);

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

	if (sscanf(readLine, "%*s %18" G_GINT64_MODIFIER "u.%9d %9u %" READDATA_MAX_FIELD_SIZE "s",
	    &seconds, &useconds, &phdr->len, readData) != 4) {
		*err = WTAP_ERR_BAD_FILE;
		*err_info = g_strdup("daintree_sna: invalid read record");
		return FALSE;
	}

	/* Daintree doesn't store the FCS, but pads end of packet with 0xffff, which we toss */
	if (phdr->len <= FCS_LENGTH) {
		*err = WTAP_ERR_BAD_FILE;
		*err_info = g_strdup_printf("daintree_sna: packet length <= %u bytes, no frame data present",
		    FCS_LENGTH);
		return FALSE;
	}
	phdr->len -= FCS_LENGTH;

	phdr->ts.secs = (time_t) seconds;
	phdr->ts.nsecs = useconds * 1000; /* convert mS to nS */

	/*
	 * READDATA_BUF_SIZE is < WTAP_MAX_PACKET_SIZE, and is the maximum
	 * number of bytes of packet data we can generate, so we don't
	 * need to check the packet length.
	 */
	p = str; /* overlay source buffer */
	bytes = 0;
	/* convert hex string to guint8 */
	while(*str) {
		/* most significant nibble */
		if (!g_ascii_isxdigit(*str)) {
			*err = WTAP_ERR_BAD_FILE;
			*err_info = g_strdup("daintree_sna: non-hex digit in hex data");
			return FALSE;
		}
		if(g_ascii_isdigit(*str)) {
			*p = (*str - '0') << 4;
		} else {
			*p = ((g_ascii_tolower(*str) - 'a') + 10) << 4;
		}
		str++;

		/* least significant nibble */
		if (!g_ascii_isxdigit(*str)) {
			*err = WTAP_ERR_BAD_FILE;
			*err_info = g_strdup("daintree_sna: non-hex digit in hex data");
			return FALSE;
		}
		if(g_ascii_isdigit(*str)) {
			*p += *str - '0';
		} else {
			*p += (g_ascii_tolower(*str) - 'a') + 10;
		}
		str++;

		/* next byte in buffer */
		p++;
		bytes++;
	}

	/* Daintree doesn't store the FCS, but pads end of packet with 0xffff, which we toss */
	if (bytes <= FCS_LENGTH) {
		*err = WTAP_ERR_BAD_FILE;
		*err_info = g_strdup_printf("daintree_sna: Only %u bytes of packet data",
		    bytes);
		return FALSE;
	}
	bytes -= FCS_LENGTH;
	if (bytes > phdr->len) {
		*err = WTAP_ERR_BAD_FILE;
		*err_info = g_strdup_printf("daintree_sna: capture length (%u) > packet length (%u)",
		    bytes, phdr->len);
		return FALSE;
	}

	phdr->caplen = bytes;

	ws_buffer_assure_space(buf, bytes);
	memcpy(ws_buffer_start_ptr(buf), readData, bytes);
	return TRUE;
}
示例#16
0
static gboolean dct3trace_get_packet(FILE_T fh, struct wtap_pkthdr *phdr,
	Buffer *buf, int *err, gchar **err_info)
{
	char line[1024];
	guint8 databuf[MAX_PACKET_LEN], *bufp;
	gboolean have_data = FALSE;
	int len = 0;

	bufp = &databuf[0];
	while (file_gets(line, sizeof(line), fh) != NULL)
	{
		if( memcmp(dct3trace_magic_end, line, strlen(dct3trace_magic_end)) == 0 )
		{
			/* Return on end of file </dump> */
			*err = 0;
			return FALSE;
		}
		else if( memcmp(dct3trace_magic_record_end, line, strlen(dct3trace_magic_record_end)) == 0 )
		{
			/* Return on end of record </l1> */
			if( have_data )
			{
				/* We've got a full packet! */
				phdr->rec_type = REC_TYPE_PACKET;
				phdr->presence_flags = 0; /* no time stamp, no separate "on the wire" length */
				phdr->ts.secs = 0;
				phdr->ts.nsecs = 0;
				phdr->caplen = len;
				phdr->len = len;

				*err = 0;

				/* Make sure we have enough room for the packet */
				ws_buffer_assure_space(buf, phdr->caplen);
				memcpy( ws_buffer_start_ptr(buf), databuf, phdr->caplen );

				return TRUE;
			}
			else
			{
				/* If not got any data return error */
				*err = WTAP_ERR_BAD_FILE;
				*err_info = g_strdup("dct3trace: record without data");
				return FALSE;
			}
		}
		else if( memcmp(dct3trace_magic_record_start, line, strlen(dct3trace_magic_record_start)) == 0 )
		{
			/* Parse L1 header <l1 ...>*/
			int channel, tmp;
			char *ptr;

			phdr->pseudo_header.gsm_um.uplink = !strstr(line, "direction=\"down\"");
			if (!xml_get_int(&channel, line, "logicalchannel", err, err_info))
				return FALSE;

			/* Parse downlink only fields */
			if( !phdr->pseudo_header.gsm_um.uplink )
			{
				if (!xml_get_int(&tmp, line, "physicalchannel", err, err_info))
					return FALSE;
				phdr->pseudo_header.gsm_um.arfcn = tmp;
				if (!xml_get_int(&tmp, line, "sequence", err, err_info))
					return FALSE;
				phdr->pseudo_header.gsm_um.tdma_frame = tmp;
				if (!xml_get_int(&tmp, line, "bsic", err, err_info))
					return FALSE;
				phdr->pseudo_header.gsm_um.bsic = tmp;
				if (!xml_get_int(&tmp, line, "error", err, err_info))
					return FALSE;
				phdr->pseudo_header.gsm_um.error = tmp;
				if (!xml_get_int(&tmp, line, "timeshift", err, err_info))
					return FALSE;
				phdr->pseudo_header.gsm_um.timeshift = tmp;
			}

			switch( channel )
			{
				case 128: phdr->pseudo_header.gsm_um.channel = GSM_UM_CHANNEL_SDCCH; break;
				case 112: phdr->pseudo_header.gsm_um.channel = GSM_UM_CHANNEL_SACCH; break;
				case 176: phdr->pseudo_header.gsm_um.channel = GSM_UM_CHANNEL_FACCH; break;
				case 96: phdr->pseudo_header.gsm_um.channel = GSM_UM_CHANNEL_CCCH; break;
				case 80: phdr->pseudo_header.gsm_um.channel = GSM_UM_CHANNEL_BCCH; break;
				default: phdr->pseudo_header.gsm_um.channel = GSM_UM_CHANNEL_UNKNOWN; break;
			}

			/* Read data (if have it) into databuf */
			ptr = strstr(line, "data=\"");
			if( ptr )
			{
				have_data = TRUE; /* If has data... */
				len = hex2bin(bufp, &databuf[MAX_PACKET_LEN], ptr+6);
				if (len == -1)
				{
					*err = WTAP_ERR_BAD_FILE;
					*err_info = g_strdup_printf("dct3trace: record length %d too long", phdr->caplen);
					return FALSE;
				}
			}
		}
		else if( !have_data && memcmp(dct3trace_magic_l2_start, line, strlen(dct3trace_magic_l2_start)) == 0 )
		{
			/* For uplink packets we might not get the raw L1, so have to recreate it from the L2 */
			/* Parse L2 header if didn't get data from L1 <l2 ...> */
			int data_len;
			char *ptr = strstr(line, "data=\"");

			if( !ptr )
			{
				continue;
			}

			have_data = TRUE;

			/*
			 * We know we have no data already, so we know
			 * we have enough room for the header.
			 */
			if( phdr->pseudo_header.gsm_um.channel == GSM_UM_CHANNEL_SACCH || phdr->pseudo_header.gsm_um.channel == GSM_UM_CHANNEL_FACCH || phdr->pseudo_header.gsm_um.channel == GSM_UM_CHANNEL_SDCCH )
			{
				/* Add LAPDm B header */
				memset(bufp, 0x1, 2);
				len = 3;
			}
			else
			{
				/* Add LAPDm Bbis header */
				len = 1;
			}
			bufp += len;

			data_len = hex2bin(bufp, &databuf[MAX_PACKET_LEN], ptr+6);
			if (data_len == -1)
			{
				*err = WTAP_ERR_BAD_FILE;
				*err_info = g_strdup_printf("dct3trace: record length %d too long", phdr->caplen);
				return FALSE;
			}
			len += data_len;

			/* Add LAPDm length byte */
			*(bufp - 1) = data_len << 2 | 0x1;
		}
	}

	*err = file_error(fh, err_info);
	if (*err == 0)
	{
		*err = WTAP_ERR_SHORT_READ;
	}
	return FALSE;
}
示例#17
0
/* Parse the capture file.
   Returns TRUE if we got a packet, FALSE otherwise. */
static gboolean
parse_ascend(ascend_t *ascend, FILE_T fh, struct wtap_pkthdr *phdr, Buffer *buf,
             guint length, int *err, gchar **err_info)
{
  ascend_state_t parser_state;
  int retval;

  ws_buffer_assure_space(buf, length);
  retval = run_ascend_parser(fh, phdr, ws_buffer_start_ptr(buf), &parser_state,
                             err, err_info);

  /* did we see any data (hex bytes)? if so, tip off ascend_seek()
     as to where to look for the next packet, if any. If we didn't,
     maybe this record was broken. Advance so we don't get into
     an infinite loop reading a broken trace. */
  if (parser_state.first_hexbyte) {
    ascend->next_packet_seek_start = parser_state.first_hexbyte;
  } else {
    /* Sometimes, a header will be printed but the data will be omitted, or
       worse -- two headers will be printed, followed by the data for each.
       Because of this, we need to be fairly tolerant of what we accept
       here.  If we didn't find any hex bytes, skip over what we've read so
       far so we can try reading a new packet. */
    ascend->next_packet_seek_start = file_tell(fh);
    retval = 0;
  }

  /* if we got at least some data, return success even if the parser
     reported an error. This is because the debug header gives the number
     of bytes on the wire, not actually how many bytes are in the trace.
     We won't know where the data ends until we run into the next packet. */
  if (parser_state.caplen) {
    if (! ascend->adjusted) {
      ascend->adjusted = TRUE;
      if (parser_state.saw_timestamp) {
        /*
         * Capture file contained a date and time.
         * We do this only if this is the very first packet we've seen -
         * i.e., if "ascend->adjusted" is false - because
         * if we get a date and time after the first packet, we can't
         * go back and adjust the time stamps of the packets we've already
         * processed, and basing the time stamps of this and following
         * packets on the time stamp from the file text rather than the
         * ctime of the capture file means times before this and after
         * this can't be compared.
         */
        ascend->inittime = parser_state.timestamp;
      }
      if (ascend->inittime > parser_state.secs)
        ascend->inittime -= parser_state.secs;
    }
    phdr->presence_flags = WTAP_HAS_TS|WTAP_HAS_CAP_LEN;
    phdr->ts.secs = parser_state.secs + ascend->inittime;
    phdr->ts.nsecs = parser_state.usecs * 1000;
    phdr->caplen = parser_state.caplen;
    phdr->len = parser_state.wirelen;

    /*
     * For these types, the encapsulation we use is not WTAP_ENCAP_ASCEND,
     * so set the pseudo-headers appropriately for the type (WTAP_ENCAP_ISDN
     * or WTAP_ENCAP_ETHERNET).
     */
    switch(phdr->pseudo_header.ascend.type) {
      case ASCEND_PFX_ISDN_X:
        phdr->pseudo_header.isdn.uton = TRUE;
        phdr->pseudo_header.isdn.channel = 0;
        break;

      case ASCEND_PFX_ISDN_R:
        phdr->pseudo_header.isdn.uton = FALSE;
        phdr->pseudo_header.isdn.channel = 0;
        break;

      case ASCEND_PFX_ETHER:
        phdr->pseudo_header.eth.fcs_len = 0;
        break;
    }
    return TRUE;
  }

  /* Didn't see any data. Still, perhaps the parser was happy.  */
  if (retval) {
    if (*err == 0) {
      /* Parser failed, but didn't report an I/O error, so a parse error.
         Return WTAP_ERR_BAD_FILE, with the parse error as the error string. */
      *err = WTAP_ERR_BAD_FILE;
      *err_info = g_strdup((parser_state.ascend_parse_error != NULL) ? parser_state.ascend_parse_error : "parse error");
    }
  } else {
    if (*err == 0) {
      /* Parser succeeded, but got no data, and didn't report an I/O error.
         Return WTAP_ERR_BAD_FILE, with a "got no data" error string. */
      *err = WTAP_ERR_BAD_FILE;
      *err_info = g_strdup("no data returned by parse");
    }
  }
  return FALSE;
}
示例#18
0
static gboolean
process_packet_data(wtap_rec *rec, Buffer *target, guint8 *buffer,
                    guint record_len, k12_t *k12, int *err, gchar **err_info)
{
    guint32 type;
    guint   buffer_offset;
    guint64 ts;
    guint32 length;
    guint32 extra_len;
    guint32 src_id;
    k12_src_desc_t* src_desc;

    type = pntoh32(buffer + K12_RECORD_TYPE);
    buffer_offset = (type == K12_REC_D0020) ? K12_PACKET_FRAME_D0020 : K12_PACKET_FRAME;
    if (buffer_offset > record_len) {
        *err = WTAP_ERR_BAD_FILE;
        *err_info = g_strdup_printf("k12: Frame data offset %u > record length %u",
                                    buffer_offset, record_len);
        return FALSE;
    }

    length = pntoh32(buffer + K12_RECORD_FRAME_LEN) & 0x00001FFF;
    if (length > record_len - buffer_offset) {
        *err = WTAP_ERR_BAD_FILE;
        *err_info = g_strdup_printf("k12: Frame length %u > record frame data %u",
                                    length, record_len - buffer_offset);
        return FALSE;
    }

    rec->rec_type = REC_TYPE_PACKET;
    rec->presence_flags = WTAP_HAS_TS;

    ts = pntoh64(buffer + K12_PACKET_TIMESTAMP);

    rec->ts.secs = (guint32) ((ts / 2000000) + 631152000);
    rec->ts.nsecs = (guint32) ( (ts % 2000000) * 500 );

    rec->rec_header.packet_header.len = rec->rec_header.packet_header.caplen = length;

    ws_buffer_assure_space(target, length);
    memcpy(ws_buffer_start_ptr(target), buffer + buffer_offset, length);

    /* extra information need by some protocols */
    extra_len = record_len - buffer_offset - length;
    ws_buffer_assure_space(&(k12->extra_info), extra_len);
    memcpy(ws_buffer_start_ptr(&(k12->extra_info)),
           buffer + buffer_offset + length, extra_len);
    rec->rec_header.packet_header.pseudo_header.k12.extra_info = (guint8*)ws_buffer_start_ptr(&(k12->extra_info));
    rec->rec_header.packet_header.pseudo_header.k12.extra_length = extra_len;

    src_id = pntoh32(buffer + K12_RECORD_SRC_ID);
    K12_DBG(5,("process_packet_data: src_id=%.8x",src_id));
    rec->rec_header.packet_header.pseudo_header.k12.input = src_id;

    if ( ! (src_desc = (k12_src_desc_t*)g_hash_table_lookup(k12->src_by_id,GUINT_TO_POINTER(src_id))) ) {
        /*
         * Some records from K15 files have a port ID of an undeclared
         * interface which happens to be the only one with the first byte changed.
         * It is still unknown how to recognize when this happens.
         * If the lookup of the interface record fails we'll mask it
         * and retry.
         */
        src_desc = (k12_src_desc_t*)g_hash_table_lookup(k12->src_by_id,GUINT_TO_POINTER(src_id&K12_RECORD_SRC_ID_MASK));
    }

    if (src_desc) {
        K12_DBG(5,("process_packet_data: input_name='%s' stack_file='%s' type=%x",src_desc->input_name,src_desc->stack_file,src_desc->input_type));
        rec->rec_header.packet_header.pseudo_header.k12.input_name = src_desc->input_name;
        rec->rec_header.packet_header.pseudo_header.k12.stack_file = src_desc->stack_file;
        rec->rec_header.packet_header.pseudo_header.k12.input_type = src_desc->input_type;

        switch(src_desc->input_type) {
            case K12_PORT_ATMPVC:
                if (buffer_offset + length + K12_PACKET_OFFSET_CID < record_len) {
                    rec->rec_header.packet_header.pseudo_header.k12.input_info.atm.vp =  pntoh16(buffer + buffer_offset + length + K12_PACKET_OFFSET_VP);
                    rec->rec_header.packet_header.pseudo_header.k12.input_info.atm.vc =  pntoh16(buffer + buffer_offset + length + K12_PACKET_OFFSET_VC);
                    rec->rec_header.packet_header.pseudo_header.k12.input_info.atm.cid =  *((unsigned char*)(buffer + buffer_offset + length + K12_PACKET_OFFSET_CID));
                    break;
                }
                /* Fall through */
            default:
                memcpy(&(rec->rec_header.packet_header.pseudo_header.k12.input_info),&(src_desc->input_info),sizeof(src_desc->input_info));
                break;
        }
    } else {
        K12_DBG(5,("process_packet_data: NO SRC_RECORD FOUND"));

        memset(&(rec->rec_header.packet_header.pseudo_header.k12),0,sizeof(rec->rec_header.packet_header.pseudo_header.k12));
        rec->rec_header.packet_header.pseudo_header.k12.input_name = "unknown port";
        rec->rec_header.packet_header.pseudo_header.k12.stack_file = "unknown stack file";
    }

    rec->rec_header.packet_header.pseudo_header.k12.input = src_id;
    rec->rec_header.packet_header.pseudo_header.k12.stuff = k12;
    return TRUE;
}
示例#19
0
static gboolean
nettl_read_rec(wtap *wth, FILE_T fh, wtap_rec *rec, Buffer *buf,
                int *err, gchar **err_info)
{
    union wtap_pseudo_header *pseudo_header = &rec->rec_header.packet_header.pseudo_header;
    nettl_t *nettl = (nettl_t *)wth->priv;
    gboolean fddihack = FALSE;
    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;

    if (!wtap_read_bytes_or_eof(fh, &rec_hdr.hdr_len, sizeof rec_hdr.hdr_len,
                                err, err_info))
        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;
    }
    if (!wtap_read_bytes(fh, &rec_hdr.subsys, NETTL_REC_HDR_LEN - 2,
                         err, err_info))
        return FALSE;
    subsys = g_ntohs(rec_hdr.subsys);
    hdr_len -= NETTL_REC_HDR_LEN;
    /* Skip the rest of the header. */
    if (!wtap_read_bytes(fh, NULL, hdr_len, err, err_info))
        return FALSE;

    if ( (pntoh32(&rec_hdr.kind) & NETTL_HDR_PDU_MASK) == 0 ) {
        /* not actually a data packet (PDU) trace record */
        rec->rec_header.packet_header.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)) {
                rec->rec_header.packet_header.pkt_encap = WTAP_ENCAP_NETTL_RAW_IP;
            } else if (subsys == NETTL_SUBSYS_NS_LS_ICMP) {
                rec->rec_header.packet_header.pkt_encap = WTAP_ENCAP_NETTL_RAW_ICMP;
            } else if (subsys == NETTL_SUBSYS_NS_LS_ICMPV6) {
                rec->rec_header.packet_header.pkt_encap = WTAP_ENCAP_NETTL_RAW_ICMPV6;
            } else if (subsys == NETTL_SUBSYS_NS_LS_TELNET) {
                rec->rec_header.packet_header.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) ) {
                rec->rec_header.packet_header.pkt_encap = WTAP_ENCAP_NETTL_FDDI;
            } else if( (subsys == NETTL_SUBSYS_PCI_TR)
                    || (subsys == NETTL_SUBSYS_TOKEN) ) {
                rec->rec_header.packet_header.pkt_encap = WTAP_ENCAP_NETTL_TOKEN_RING;
            } else {
                rec->rec_header.packet_header.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 */
                    if (!wtap_read_bytes(fh, dummyc, 9, err, err_info))
                        return FALSE;
                    /* padding is usually either a total 11 or 16 bytes??? */
                    padlen = (int)dummyc[8];
                    if (!wtap_read_bytes(fh, NULL, padlen, err, err_info))
                        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 (!wtap_read_bytes(fh, NULL, 3, err, err_info))
                    return FALSE;
                padlen = 3;
            } else if (subsys == NETTL_SUBSYS_NS_LS_LOOPBACK) {
                /* LOOPBACK has an extra 26 bytes of padding */
                if (!wtap_read_bytes(fh, NULL, 26, err, err_info))
                    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 (!wtap_read_bytes(fh, NULL, 8, err, err_info))
                    return FALSE;
                padlen = 8;
            } else {
                padlen = 0;
            }
            break;

        case NETTL_SUBSYS_NS_LS_DRIVER :
            /* XXX we don't know how to identify this as ethernet frames, so
               we assume everything is. We will crash and burn for anything else */
            /* for encapsulated 100baseT we do this */
            rec->rec_header.packet_header.pkt_encap = WTAP_ENCAP_NETTL_ETHERNET;
            if (!wtap_read_bytes(fh, &drv_eth_hdr, NS_LS_DRV_ETH_HDR_LEN,
                                      err, err_info))
                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 (!wtap_read_bytes(fh, NULL, 2, err, err_info))
                    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?
             */
            rec->rec_header.packet_header.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 (!wtap_read_bytes(fh, NULL, padlen, err, err_info))
                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;
            rec->rec_header.packet_header.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;
    }
    rec->rec_type = REC_TYPE_PACKET;
    rec->presence_flags = WTAP_HAS_TS|WTAP_HAS_CAP_LEN;
    rec->rec_header.packet_header.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;
    rec->rec_header.packet_header.caplen = datalen;
    rec->ts.secs = pntoh32(&rec_hdr.sec);
    rec->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 (rec->rec_header.packet_header.caplen > 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("nettl: File has %u-byte packet, bigger than maximum of %u",
            rec->rec_header.packet_header.caplen, WTAP_MAX_PACKET_SIZE_STANDARD);
        return FALSE;
    }

    /*
     * Read the packet data.
     */
    ws_buffer_assure_space(buf, datalen);
    pd = ws_buffer_start_ptr(buf);
    if (fddihack) {
        /* read in FC, dest, src, DSAP and SSAP */
        bytes_to_read = 15;
        if (bytes_to_read > datalen)
            bytes_to_read = datalen;
        if (!wtap_read_bytes(fh, pd, bytes_to_read, err, err_info))
            return FALSE;
        datalen -= bytes_to_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;
            if (!wtap_read_bytes(fh, NULL, bytes_to_read, err, err_info))
                return FALSE;
            datalen -= bytes_to_read;
            if (datalen == 0) {
                /* There's nothing past the FC, dest, src, DSAP, SSAP, and 3 bytes to eat */
                return TRUE;
            }
        }
        if (!wtap_read_bytes(fh, pd + 15, datalen, err, err_info))
            return FALSE;
    } else {
        if (!wtap_read_bytes(fh, pd, datalen, err, err_info))
            return FALSE;
    }

    return TRUE;
}