Exemplo n.º 1
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;
}
Exemplo n.º 2
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);
}
Exemplo n.º 3
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;
}
Exemplo n.º 4
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;
}
Exemplo n.º 5
0
/* Classic wtap seek_read function, called by wtap core.  This must return TRUE on
 * success, FALSE on error.
 */
static gboolean
wslua_filehandler_seek_read(wtap *wth, gint64 seek_off,
                            struct wtap_pkthdr *phdr, Buffer *buf,
                            int *err, gchar **err_info)
{
    FileHandler fh = (FileHandler)(wth->wslua_data);
    int retval = -1;
    lua_State* L = NULL;
    File *fp = NULL;
    CaptureInfo *fc = NULL;
    FrameInfo *fi = NULL;

    INIT_FILEHANDLER_ROUTINE(seek_read,FALSE);

    /* Reset errno */
    if (err) {
        *err = errno = 0;
    }
    phdr->opt_comment = NULL;

    fp = push_File(L, wth->random_fh);
    fc = push_CaptureInfo(L, wth, FALSE);
    fi = push_FrameInfo(L, phdr, buf);
    lua_pushnumber(L, (lua_Number)seek_off);

    switch ( lua_pcall(L,4,1,1) ) {
    case 0:
        if (lua_isstring(L,-1)) {
            size_t len = 0;
            const gchar* fd = lua_tolstring(L, -1, &len);
            if (len < WTAP_MAX_PACKET_SIZE)
                memcpy(ws_buffer_start_ptr(buf), fd, len);
            retval = 1;
            break;
        }
        retval = wslua_optboolint(L,-1,0);
        break;
        CASE_ERROR_ERRINFO("seek_read")
    }

    END_FILEHANDLER_ROUTINE();

    (*fp)->expired = TRUE;
    (*fc)->expired = TRUE;
    (*fi)->expired = TRUE;
    lua_settop(L,0);

    return (retval == 1);
}
Exemplo n.º 6
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;
}
Exemplo n.º 7
0
static gboolean
iptrace_read_rec_data(FILE_T fh, Buffer *buf, struct wtap_pkthdr *phdr,
    int *err, gchar **err_info)
{
	if (!wtap_read_packet_bytes(fh, buf, phdr->caplen, err, err_info))
		return FALSE;

	if (phdr->pkt_encap == WTAP_ENCAP_ATM_PDUS) {
		/*
		 * Attempt to guess from the packet data, the VPI,
		 * and the VCI information about the type of traffic.
		 */
		atm_guess_traffic_type(phdr, ws_buffer_start_ptr(buf));
	}

	return TRUE;
}
Exemplo n.º 8
0
static void
frame_cache(struct tvb_frame *frame_tvb)
{
	struct wtap_pkthdr phdr; /* Packet header */

	memset(&phdr, 0, sizeof(struct wtap_pkthdr));

	if (frame_tvb->buf == NULL) {
		frame_tvb->buf = (struct Buffer *) g_malloc(sizeof(struct Buffer));

		/* XXX, register frame_tvb to some list which frees from time to time not used buffers :] */
		ws_buffer_init(frame_tvb->buf, frame_tvb->tvb.length + frame_tvb->offset);

		if (!frame_read(frame_tvb, &phdr, frame_tvb->buf))
			{ /* TODO: THROW(???); */ }
	}

	frame_tvb->tvb.real_data = ws_buffer_start_ptr(frame_tvb->buf) + frame_tvb->offset;
}
Exemplo n.º 9
0
static void
frame_write(FrameRecord_t *frame, wtap *wth, wtap_dumper *pdh,
            struct wtap_pkthdr *phdr, Buffer *buf, const char *infile)
{
    int    err;
    gchar  *err_info;

    DEBUG_PRINT("\nDumping frame (offset=%" G_GINT64_MODIFIER "u)\n",
                frame->offset);


    /* Re-read the frame from the stored location */
    if (!wtap_seek_read(wth, frame->offset, phdr, buf, &err, &err_info)) {
        if (err != 0) {
            /* Print a message noting that the read failed somewhere along the line. */
            fprintf(stderr,
                    "reordercap: An error occurred while re-reading \"%s\": %s.\n",
                    infile, wtap_strerror(err));
            if (err_info != NULL) {
                fprintf(stderr, "(%s)\n", err_info);
                g_free(err_info);
            }
            exit(1);
        }
    }

    /* Copy, and set length and timestamp from item. */
    /* TODO: remove when wtap_seek_read() fills in phdr,
       including time stamps, for all file types  */
    phdr->ts = frame->frame_time;

    /* Dump frame to outfile */
    if (!wtap_dump(pdh, phdr, ws_buffer_start_ptr(buf), &err, &err_info)) {
        fprintf(stderr, "reordercap: Error (%s) writing frame to outfile\n",
                wtap_strerror(err));
        if (err_info != NULL) {
            fprintf(stderr, "(%s)\n", err_info);
            g_free(err_info);
        }
        exit(1);
    }
}
Exemplo n.º 10
0
void FrameInformation::loadFrameTree()
{
    if ( ! fi_ || ! cap_file_ || !cap_file_->capFile())
        return;

    if (!cf_read_record(cap_file_->capFile(), fi_))
        return;

    struct wtap_pkthdr phdr_ = cap_file_->capFile()->phdr;
    packet_data_ = (guint8 *) g_memdup(ws_buffer_start_ptr(&(cap_file_->capFile()->buf)), fi_->cap_len);

    /* proto tree, visible. We need a proto tree if there's custom columns */
    epan_dissect_init(&edt_, cap_file_->capFile()->epan, TRUE, TRUE);
    col_custom_prime_edt(&edt_, &(cap_file_->capFile()->cinfo));

    epan_dissect_run(&edt_, cap_file_->capFile()->cd_t, &phdr_,
                     frame_tvbuff_new(&cap_file_->capFile()->provider, fi_, packet_data_),
                     fi_, &(cap_file_->capFile()->cinfo));
    epan_dissect_fill_in_columns(&edt_, TRUE, TRUE);
}
Exemplo n.º 11
0
static gboolean
csids_read_packet(FILE_T fh, csids_t *csids, wtap_rec *rec,
                  Buffer *buf, int *err, gchar **err_info)
{
  struct csids_header hdr;
  guint8 *pd;

  if( !wtap_read_bytes_or_eof( fh, &hdr, sizeof( struct csids_header), err, err_info ) )
    return FALSE;
  hdr.seconds = pntoh32(&hdr.seconds);
  hdr.caplen = pntoh16(&hdr.caplen);
  /*
   * The maximum value of hdr.caplen is 65535, which is less than
   * WTAP_MAX_PACKET_SIZE_STANDARD will ever be, so we don't need to check
   * it.
   */

  rec->rec_type = REC_TYPE_PACKET;
  rec->presence_flags = WTAP_HAS_TS;
  rec->rec_header.packet_header.len = hdr.caplen;
  rec->rec_header.packet_header.caplen = hdr.caplen;
  rec->ts.secs = hdr.seconds;
  rec->ts.nsecs = 0;

  if( !wtap_read_packet_bytes( fh, buf, rec->rec_header.packet_header.caplen, err, err_info ) )
    return FALSE;

  pd = ws_buffer_start_ptr( buf );
  if( csids->byteswapped ) {
    if( rec->rec_header.packet_header.caplen >= 2 ) {
      PBSWAP16(pd);   /* the ip len */
      if( rec->rec_header.packet_header.caplen >= 4 ) {
        PBSWAP16(pd+2); /* ip id */
        if( rec->rec_header.packet_header.caplen >= 6 )
          PBSWAP16(pd+4); /* ip flags and fragoff */
      }
    }
  }

  return TRUE;
}
Exemplo n.º 12
0
static void
frame_write(FrameRecord_t *frame, wtap *wth, wtap_dumper *pdh,
            wtap_rec *rec, Buffer *buf, const char *infile,
            const char *outfile)
{
    int    err;
    gchar  *err_info;

    DEBUG_PRINT("\nDumping frame (offset=%" G_GINT64_MODIFIER "u)\n",
                frame->offset);


    /* Re-read the frame from the stored location */
    if (!wtap_seek_read(wth, frame->offset, rec, buf, &err, &err_info)) {
        if (err != 0) {
            /* Print a message noting that the read failed somewhere along the line. */
            fprintf(stderr,
                    "reordercap: An error occurred while re-reading \"%s\".\n",
                    infile);
            cfile_read_failure_message("reordercap", infile, err, err_info);
            exit(1);
        }
    }

    /* Copy, and set length and timestamp from item. */
    /* TODO: remove when wtap_seek_read() fills in rec,
       including time stamps, for all file types  */
    rec->ts = frame->frame_time;

    /* Dump frame to outfile */
    if (!wtap_dump(pdh, rec, ws_buffer_start_ptr(buf), &err, &err_info)) {
        cfile_write_failure_message("reordercap", infile, outfile, err,
                                    err_info, frame->num,
                                    wtap_file_type_subtype(wth));
        exit(1);
    }
}
Exemplo n.º 13
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;
}
Exemplo n.º 14
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;
}
Exemplo n.º 15
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;
}
Exemplo n.º 16
0
PacketDialog::PacketDialog(QWidget &parent, CaptureFile &cf, frame_data *fdata) :
    WiresharkDialog(parent, cf),
    ui(new Ui::PacketDialog),
    phdr_(wtap_pkthdr()),
    packet_data_(NULL)
{
    ui->setupUi(this);
    loadGeometry(parent.width() * 4 / 5, parent.height() * 4 / 5);
    ui->hintLabel->setSmallText();

    setWindowSubtitle(tr("Packet %1").arg(fdata->num));

    if (!cf_read_record(cap_file_.capFile(), fdata)) {
        reject();
        return;
    }

    phdr_ = cap_file_.capFile()->phdr;
    packet_data_ = (guint8 *) g_memdup(ws_buffer_start_ptr(&(cap_file_.capFile()->buf)), fdata->cap_len);

    /* proto tree, visible. We need a proto tree if there's custom columns */
    epan_dissect_init(&edt_, cap_file_.capFile()->epan, TRUE, TRUE);
    col_custom_prime_edt(&edt_, &(cap_file_.capFile()->cinfo));

    epan_dissect_run(&edt_, cap_file_.capFile()->cd_t, &phdr_,
                     frame_tvbuff_new(&cap_file_.capFile()->provider, fdata, packet_data_),
                     fdata, &(cap_file_.capFile()->cinfo));
    epan_dissect_fill_in_columns(&edt_, TRUE, TRUE);

    proto_tree_ = new ProtoTree(ui->packetSplitter);
    proto_tree_->setRootNode(edt_.tree);

    byte_view_tab_ = new ByteViewTab(ui->packetSplitter);
    byte_view_tab_->setCaptureFile(cap_file_.capFile());
    byte_view_tab_->selectedFrameChanged(0);

    ui->packetSplitter->setStretchFactor(1, 0);

    QStringList col_parts;
    for (int i = 0; i < cap_file_.capFile()->cinfo.num_cols; ++i) {
        // ElidedLabel doesn't support rich text / HTML
        col_parts << QString("%1: %2")
                     .arg(get_column_title(i))
                     .arg(cap_file_.capFile()->cinfo.columns[i].col_data);
    }
    col_info_ = col_parts.join(" " UTF8_MIDDLE_DOT " ");

    ui->hintLabel->setText(col_info_);

    connect(wsApp, SIGNAL(zoomMonospaceFont(QFont)),
            proto_tree_, SLOT(setMonospaceFont(QFont)));

    connect(byte_view_tab_, SIGNAL(fieldSelected(FieldInformation *)),
            proto_tree_, SLOT(selectedFieldChanged(FieldInformation *)));
    connect(proto_tree_, SIGNAL(fieldSelected(FieldInformation *)),
            byte_view_tab_, SLOT(selectedFieldChanged(FieldInformation *)));

    connect(byte_view_tab_, SIGNAL(fieldHighlight(FieldInformation *)),
            this, SLOT(setHintText(FieldInformation *)));

}
Exemplo n.º 17
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;
}
Exemplo n.º 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;
}
Exemplo n.º 19
0
PacketDialog::PacketDialog(QWidget &parent, CaptureFile &cf, frame_data *fdata) :
    WiresharkDialog(parent, cf),
    ui(new Ui::PacketDialog),
    packet_data_(NULL)
{
    ui->setupUi(this);
    ui->hintLabel->setSmallText();

    // XXX Use recent settings instead
    resize(parent.width() * 4 / 5, parent.height() * 4 / 5);

    setWindowSubtitle(tr("Packet %1").arg(fdata->num));

    phdr_ = cap_file_.capFile()->phdr;
    packet_data_ = (guint8 *) g_memdup(ws_buffer_start_ptr(&(cap_file_.capFile()->buf)), fdata->cap_len);

    if (!cf_read_record(cap_file_.capFile(), fdata)) reject();
    /* proto tree, visible. We need a proto tree if there's custom columns */
    epan_dissect_init(&edt_, cap_file_.capFile()->epan, TRUE, TRUE);
    col_custom_prime_edt(&edt_, &(cap_file_.capFile()->cinfo));

    epan_dissect_run(&edt_, cap_file_.capFile()->cd_t, &phdr_,
                     frame_tvbuff_new(fdata, packet_data_),
                     fdata, &(cap_file_.capFile()->cinfo));
    epan_dissect_fill_in_columns(&edt_, TRUE, TRUE);

    proto_tree_ = new ProtoTree(ui->packetSplitter);
    proto_tree_->fillProtocolTree(edt_.tree);
    proto_tree_->expandAll();

    byte_view_tab_ = new ByteViewTab(ui->packetSplitter);
    byte_view_tab_->setCaptureFile(cap_file_.capFile());
    byte_view_tab_->clear();

    GSList *src_le;
    for (src_le = edt_.pi.data_src; src_le != NULL; src_le = src_le->next) {
        struct data_source *source;
        char* source_name;
        source = (struct data_source *)src_le->data;
        source_name = get_data_source_name(source);
        byte_view_tab_->addTab(source_name, get_data_source_tvb(source), edt_.tree, proto_tree_,
                               cap_file_.capFile()->current_frame->flags.encoding);
        wmem_free(NULL, source_name);
    }
    byte_view_tab_->setCurrentIndex(0);

    ui->packetSplitter->setStretchFactor(0, 5);
    ui->packetSplitter->setStretchFactor(1, 1);

    QStringList col_parts;
    for (int i = 0; i < cap_file_.capFile()->cinfo.num_cols; ++i) {
        // ElidedLabel doesn't support rich text / HTML
        col_parts << QString("%1: %2")
                     .arg(get_column_title(i))
                     .arg(cap_file_.capFile()->cinfo.col_data[i]);
    }
    col_info_ = col_parts.join(" " UTF8_MIDDLE_DOT " ");
    setHintText();

    connect(this, SIGNAL(monospaceFontChanged(QFont)),
            proto_tree_, SLOT(setMonospaceFont(QFont)));
    connect(this, SIGNAL(monospaceFontChanged(QFont)),
            byte_view_tab_, SLOT(setMonospaceFont(QFont)));

    connect(proto_tree_, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)),
            byte_view_tab_, SLOT(protoTreeItemChanged(QTreeWidgetItem*)));
    connect(byte_view_tab_, SIGNAL(byteFieldHovered(QString&)),
            this, SLOT(setHintText(QString&)));
}
Exemplo n.º 20
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;
}
Exemplo n.º 21
0
/* 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;
}
Exemplo n.º 22
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;
}
Exemplo n.º 23
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;
}
Exemplo n.º 24
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;
}
Exemplo n.º 25
0
static gboolean
libpcap_read_packet(wtap *wth, FILE_T fh, struct wtap_pkthdr *phdr,
    Buffer *buf, int *err, gchar **err_info)
{
	struct pcaprec_ss990915_hdr hdr;
	guint packet_size;
	guint orig_size;
	int phdr_len;
	libpcap_t *libpcap;

	if (!libpcap_read_header(wth, fh, err, err_info, &hdr))
		return FALSE;

	if (hdr.hdr.incl_len > WTAP_MAX_PACKET_SIZE) {
		/*
		 * 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;
		if (err_info != NULL) {
			*err_info = g_strdup_printf("pcap: File has %u-byte packet, bigger than maximum of %u",
			    hdr.hdr.incl_len, WTAP_MAX_PACKET_SIZE);
		}
		return FALSE;
	}

	packet_size = hdr.hdr.incl_len;
	orig_size = hdr.hdr.orig_len;

	/*
	 * AIX appears to put 3 bytes of padding in front of FDDI
	 * frames; strip that crap off.
	 */
	if (wth->file_type_subtype == WTAP_FILE_TYPE_SUBTYPE_PCAP_AIX &&
	    (wth->file_encap == WTAP_ENCAP_FDDI ||
	     wth->file_encap == WTAP_ENCAP_FDDI_BITSWAPPED)) {
		/*
		 * The packet size is really a record size and includes
		 * the padding.
		 */
		packet_size -= 3;
		orig_size -= 3;

		/*
		 * Skip the padding.
		 */
		if (!file_skip(fh, 3, err))
			return FALSE;
	}

	phdr_len = pcap_process_pseudo_header(fh, wth->file_type_subtype,
	    wth->file_encap, packet_size, TRUE, phdr, err, err_info);
	if (phdr_len < 0)
		return FALSE;	/* error */

	/*
	 * Don't count any pseudo-header as part of the packet.
	 */
	orig_size -= phdr_len;
	packet_size -= phdr_len;

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

	/* Update the timestamp, if not already done */
	if (wth->file_encap != WTAP_ENCAP_ERF) {
		phdr->ts.secs = hdr.hdr.ts_sec;
		if (wth->file_tsprec == WTAP_TSPREC_NSEC)
			phdr->ts.nsecs = hdr.hdr.ts_usec;
		else
			phdr->ts.nsecs = hdr.hdr.ts_usec * 1000;
	} else {
		/* Set interface ID for ERF format */
		phdr->presence_flags |= WTAP_HAS_INTERFACE_ID;
		phdr->interface_id = phdr->pseudo_header.erf.phdr.flags & 0x03;
	}
	phdr->caplen = packet_size;
	phdr->len = orig_size;

	/*
	 * Read the packet data.
	 */
	if (!wtap_read_packet_bytes(fh, buf, packet_size, err, err_info))
		return FALSE;	/* failed */

	libpcap = (libpcap_t *)wth->priv;
	pcap_read_post_process(wth->file_type_subtype, wth->file_encap,
	    phdr, ws_buffer_start_ptr(buf), libpcap->byte_swapped, -1);
	return TRUE;
}
Exemplo n.º 26
0
/* 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;
}
Exemplo n.º 27
0
static int
snoop_read_packet(wtap *wth, FILE_T fh, struct wtap_pkthdr *phdr,
    Buffer *buf, int *err, gchar **err_info)
{
	struct snooprec_hdr hdr;
	guint32 rec_size;
	guint32	packet_size;
	guint32 orig_size;
	int header_size;

	/* Read record header. */
	if (!wtap_read_bytes_or_eof(fh, &hdr, sizeof hdr, err, err_info))
		return -1;

	rec_size = g_ntohl(hdr.rec_len);
	orig_size = g_ntohl(hdr.orig_len);
	packet_size = g_ntohl(hdr.incl_len);
	if (orig_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("snoop: File has %u-byte original length, bigger than maximum of %u",
		    orig_size, WTAP_MAX_PACKET_SIZE);
		return -1;
	}
	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("snoop: File has %u-byte packet, bigger than maximum of %u",
		    packet_size, WTAP_MAX_PACKET_SIZE);
		return -1;
	}
	if (packet_size > rec_size) {
		/*
		 * Probably a corrupt capture file.
		 */
		*err = WTAP_ERR_BAD_FILE;
		*err_info = g_strdup_printf("snoop: File has %u-byte packet, bigger than record size %u",
		    packet_size, rec_size);
		return -1;
	}

	switch (wth->file_encap) {

	case WTAP_ENCAP_ATM_PDUS:
		/*
		 * This is an ATM packet, so the first four bytes are
		 * the direction of the packet (transmit/receive), the
		 * VPI, and the VCI; read them and generate the
		 * pseudo-header from them.
		 */
		if (packet_size < sizeof (struct snoop_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("snoop: atmsnoop file has a %u-byte packet, too small to have even an ATM pseudo-header",
			    packet_size);
			return -1;
		}
		if (!snoop_read_atm_pseudoheader(fh, &phdr->pseudo_header,
		    err, err_info))
			return -1;	/* Read error */

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

	case WTAP_ENCAP_ETHERNET:
		/*
		 * If this is a snoop file, we assume there's no FCS in
		 * this frame; if this is a Shomit file, we assume there
		 * is.  (XXX - or should we treat it a "maybe"?)
		 */
		if (wth->file_type_subtype == WTAP_FILE_TYPE_SUBTYPE_SHOMITI)
			phdr->pseudo_header.eth.fcs_len = 4;
		else
			phdr->pseudo_header.eth.fcs_len = 0;
		break;

	case WTAP_ENCAP_IEEE_802_11_WITH_RADIO:
		if (packet_size < sizeof (shomiti_wireless_header)) {
			/*
			 * Uh-oh, the packet isn't big enough to even
			 * have a pseudo-header.
			 */
			*err = WTAP_ERR_BAD_FILE;
			*err_info = g_strdup_printf("snoop: Shomiti wireless file has a %u-byte packet, too small to have even a wireless pseudo-header",
			    packet_size);
			return -1;
		}
		if (!snoop_read_shomiti_wireless_pseudoheader(fh,
		    &phdr->pseudo_header, err, err_info, &header_size))
			return -1;	/* Read error */

		/*
		 * Don't count the pseudo-header as part of the packet.
		 */
		rec_size -= header_size;
		orig_size -= header_size;
		packet_size -= header_size;
		break;
	}

	phdr->rec_type = REC_TYPE_PACKET;
	phdr->presence_flags = WTAP_HAS_TS|WTAP_HAS_CAP_LEN;
	phdr->ts.secs = g_ntohl(hdr.ts_sec);
	phdr->ts.nsecs = g_ntohl(hdr.ts_usec) * 1000;
	phdr->caplen = packet_size;
	phdr->len = orig_size;

	if (rec_size < (sizeof hdr + packet_size)) {
		/*
		 * What, *negative* padding?  Bogus.
		 */
		*err = WTAP_ERR_BAD_FILE;
		*err_info = g_strdup_printf("snoop: File has %u-byte record with packet size of %u",
		    rec_size, packet_size);
		return -1;
	}

	/*
	 * Read the packet data.
	 */
	if (!wtap_read_packet_bytes(fh, buf, packet_size, err, err_info))
		return -1;	/* failed */

	/*
	 * If this is ATM LANE traffic, try to guess what type of LANE
	 * traffic it is based on the packet contents.
	 */
	if (wth->file_encap == WTAP_ENCAP_ATM_PDUS &&
	    phdr->pseudo_header.atm.type == TRAF_LANE) {
		atm_guess_lane_type(phdr, ws_buffer_start_ptr(buf));
	}

	return rec_size - ((guint)sizeof hdr + packet_size);
}
Exemplo n.º 28
0
static gboolean
visual_read_packet(wtap *wth, FILE_T fh, struct wtap_pkthdr *phdr,
        Buffer *buf, int *err, gchar **err_info)
{
    struct visual_read_info *visual = (struct visual_read_info *)wth->priv;
    struct visual_pkt_hdr vpkt_hdr;
    int bytes_read;
    guint32 packet_size;
    struct visual_atm_hdr vatm_hdr;
    double  t;
    time_t  secs;
    guint32 usecs;
    guint32 packet_status;
    guint8 *pd;

    /* Read the packet header. */
    errno = WTAP_ERR_CANT_READ;
    bytes_read = file_read(&vpkt_hdr, (unsigned int)sizeof vpkt_hdr, fh);
    if (bytes_read < 0 || (size_t)bytes_read != sizeof vpkt_hdr)
    {
        *err = file_error(fh, err_info);
        if (*err == 0 && bytes_read != 0)
        {
            *err = WTAP_ERR_SHORT_READ;
        }
        return FALSE;
    }

    /* Get the included length of data. This includes extra headers + payload */
    packet_size = pletoh16(&vpkt_hdr.incl_len);

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

    /* Set the packet time and length. */
    t = visual->start_time;
    t += ((double)pletoh32(&vpkt_hdr.ts_delta))*1000;
    secs = (time_t)(t/1000000);
    usecs = (guint32)(t - secs*1000000);
    phdr->ts.secs = secs;
    phdr->ts.nsecs = usecs * 1000;

    phdr->len = pletoh16(&vpkt_hdr.orig_len);

    packet_status = pletoh32(&vpkt_hdr.status);

    /* Do encapsulation-specific processing.

       Most Visual capture types include the FCS in the original length
       value, but don't include the FCS as part of the payload or captured
       length.  This is different from the model used in most other capture
       file formats, including pcap and pcap-ng in cases where the FCS isn't
       captured (which are the typical cases), and causes the RTP audio
       payload save to fail since then captured len != orig len.

       We adjust the original length to remove the FCS bytes we counted based
       on the file encapsualtion type.  The only downside to this fix is
       throughput calculations will be slightly lower as it won't include
       the FCS bytes.  However, as noted, that problem also exists with
       other capture formats.

       We also set status flags.  The only status currently supported for
       all encapsulations is direction.  This either goes in the p2p or the
       X.25 pseudo header.  It would probably be better to move this up
       into the phdr. */
    switch (wth->file_encap)
    {
    case WTAP_ENCAP_ETHERNET:
        /* Ethernet has a 4-byte FCS. */
        if (phdr->len < 4)
        {
            *err = WTAP_ERR_BAD_FILE;
            *err_info = g_strdup_printf("visual: Ethernet packet has %u-byte original packet, less than the FCS length",
                        phdr->len);
            return FALSE;
        }
        phdr->len -= 4;

        /* XXX - the above implies that there's never an FCS; should this
           set the FCS length to 0? */
        phdr->pseudo_header.eth.fcs_len = -1;
        break;

    case WTAP_ENCAP_CHDLC_WITH_PHDR:
        /* This has a 2-byte FCS. */
        if (phdr->len < 2)
        {
            *err = WTAP_ERR_BAD_FILE;
            *err_info = g_strdup_printf("visual: Cisco HDLC packet has %u-byte original packet, less than the FCS length",
                        phdr->len);
            return FALSE;
        }
        phdr->len -= 2;

        phdr->pseudo_header.p2p.sent = (packet_status & PS_SENT) ? TRUE : FALSE;
        break;

    case WTAP_ENCAP_PPP_WITH_PHDR:
        /* No FCS.
           XXX - true?  Note that PPP can negotiate no FCS, a 2-byte FCS,
           or a 4-byte FCS. */
        phdr->pseudo_header.p2p.sent = (packet_status & PS_SENT) ? TRUE : FALSE;
        break;

    case WTAP_ENCAP_FRELAY_WITH_PHDR:
        /* This has a 2-byte FCS. */
        if (phdr->len < 2)
        {
            *err = WTAP_ERR_BAD_FILE;
            *err_info = g_strdup_printf("visual: Frame Relay packet has %u-byte original packet, less than the FCS length",
                        phdr->len);
            return FALSE;
        }
        phdr->len -= 2;

        phdr->pseudo_header.x25.flags =
            (packet_status & PS_SENT) ? 0x00 : FROM_DCE;
        break;

    case WTAP_ENCAP_LAPB:
        /* This has a 2-byte FCS. */
        if (phdr->len < 2)
        {
            *err = WTAP_ERR_BAD_FILE;
            *err_info = g_strdup_printf("visual: Frame Relay packet has %u-byte original packet, less than the FCS length",
                        phdr->len);
            return FALSE;
        }
        phdr->len -= 2;

        phdr->pseudo_header.x25.flags =
            (packet_status & PS_SENT) ? 0x00 : FROM_DCE;
        break;

    case WTAP_ENCAP_ATM_PDUS:
        /* ATM original length doesn't include any FCS. Do nothing to
           the packet length.

           ATM packets have an additional packet header; read and
           process it. */
        errno = WTAP_ERR_CANT_READ;
        bytes_read = file_read(&vatm_hdr, (unsigned int)sizeof vatm_hdr, fh);
        if (bytes_read < 0 || (size_t)bytes_read != sizeof vatm_hdr)
        {
            *err = file_error(fh, err_info);
            if (*err == 0)
            {
                *err = WTAP_ERR_SHORT_READ;
            }
            return FALSE;
        }

        /* Remove ATM header from length of included bytes in capture, as
           this header was appended by the processor doing the packet
           reassembly, and was not transmitted across the wire */
        packet_size -= (guint32)sizeof vatm_hdr;

        /* Set defaults */
        phdr->pseudo_header.atm.type = TRAF_UNKNOWN;
        phdr->pseudo_header.atm.subtype = TRAF_ST_UNKNOWN;
        phdr->pseudo_header.atm.aal5t_len = 0;

        /* Next two items not supported. Defaulting to zero */
        phdr->pseudo_header.atm.aal5t_u2u = 0;
        phdr->pseudo_header.atm.aal5t_chksum = 0;

        /* Flags appear only to convey that packet is a raw cell. Set to 0 */
        phdr->pseudo_header.atm.flags = 0;

        /* Not supported. Defaulting to zero */
        phdr->pseudo_header.atm.aal2_cid = 0;

        switch(vatm_hdr.category & VN_CAT_TYPE_MASK )
        {
        case VN_AAL1:
            phdr->pseudo_header.atm.aal = AAL_1;
            break;

        case VN_AAL2:
            phdr->pseudo_header.atm.aal = AAL_2;
            break;

        case VN_AAL34:
            phdr->pseudo_header.atm.aal = AAL_3_4;
            break;

        case VN_AAL5:
            phdr->pseudo_header.atm.aal = AAL_5;
            phdr->pseudo_header.atm.type = TRAF_LLCMX;
            phdr->pseudo_header.atm.aal5t_len = pntoh32(&vatm_hdr.data_length);
            break;

        case VN_OAM:
        /* Marking next 3 as OAM versus unknown */
        case VN_O191:
        case VN_IDLE:
        case VN_RM:
            phdr->pseudo_header.atm.aal = AAL_OAMCELL;
            break;

        case VN_UNKNOWN:
        default:
            phdr->pseudo_header.atm.aal = AAL_UNKNOWN;
            break;
        }
        phdr->pseudo_header.atm.vpi = pntoh16(&vatm_hdr.vpi) & 0x0FFF;
        phdr->pseudo_header.atm.vci = pntoh16(&vatm_hdr.vci);
        phdr->pseudo_header.atm.cells = pntoh16(&vatm_hdr.cell_count);

        /* Using bit value of 1 (DCE -> DTE) to indicate From Network */
        phdr->pseudo_header.atm.channel = vatm_hdr.info & FROM_NETWORK;
        break;

    /* Not sure about token ring. Just leaving alone for now. */
    case WTAP_ENCAP_TOKEN_RING:
    default:
        break;
    }

    phdr->caplen = packet_size;

    /* Check for too-large packet. */
    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("visual: File has %u-byte packet, bigger than maximum of %u",
            packet_size, WTAP_MAX_PACKET_SIZE);
        return FALSE;
    }

    /* Read the packet data */
    if (!wtap_read_packet_bytes(fh, buf, packet_size, err, err_info))
        return FALSE;

    if (wth->file_encap == WTAP_ENCAP_CHDLC_WITH_PHDR)
    {
        /* Fill in the encapsulation.  Visual files have a media type in the
           file header and an encapsulation type in each packet header.  Files
           with a media type of HDLC can be either Cisco EtherType or PPP.

           The encapsulation hint values we've seen are:

             2 - seen in an Ethernet capture
             13 - seen in a PPP capture; possibly also seen in Cisco HDLC
                  captures
             14 - seen in a PPP capture; probably seen only for PPP.

           According to bug 2005, the collection probe can be configured
           for PPP, in which case the encapsulation hint is 14, or can
           be configured for auto-detect, in which case the encapsulation
           hint is 13, and the encapsulation must be guessed from the
           packet contents.  Auto-detect is the default. */
        pd = ws_buffer_start_ptr(buf);

        /* If PPP is specified in the encap hint, then use that */
        if (vpkt_hdr.encap_hint == 14)
        {
            /* But first we need to examine the first three octets to
               try to determine the proper encapsulation, see RFC 2364. */
            if (packet_size >= 3 &&
                (0xfe == pd[0]) && (0xfe == pd[1]) && (0x03 == pd[2]))
            {
                /* It is actually LLC encapsulated PPP */
                phdr->pkt_encap = WTAP_ENCAP_ATM_RFC1483;
            }
            else
            {
                /* It is actually PPP */
                phdr->pkt_encap = WTAP_ENCAP_PPP_WITH_PHDR;
            }
        }
        else
        {
            /* Otherwise, we need to examine the first two octets to
               try to determine the encapsulation. */
            if (packet_size >= 2 && (0xff == pd[0]) && (0x03 == pd[1]))
            {
                /* It is actually PPP */
                phdr->pkt_encap = WTAP_ENCAP_PPP_WITH_PHDR;
            }
        }
    }

    return TRUE;
}
Exemplo n.º 29
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;
}
Exemplo n.º 30
0
guint8 *
wtap_buf_ptr(wtap *wth)
{
	return ws_buffer_start_ptr(wth->frame_buffer);
}