예제 #1
0
파일: k12.c 프로젝트: bearxiong99/wireshark
static void
process_packet_data(struct wtap_pkthdr *phdr, Buffer *target, guint8 *buffer,
                    gint len, k12_t *k12)
{
    guint32 type;
    guint   buffer_offset;
    guint64 ts;
    guint32 length;
    guint32 extra_len;
    guint32 src_id;
    k12_src_desc_t* src_desc;

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

    ts = pntoh64(buffer + K12_PACKET_TIMESTAMP);

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

    length = pntoh32(buffer + K12_RECORD_FRAME_LEN) & 0x00001FFF;
    phdr->len = phdr->caplen = length;

    type = pntoh32(buffer + K12_RECORD_TYPE);
    buffer_offset = (type == K12_REC_D0020) ? K12_PACKET_FRAME_D0020 : K12_PACKET_FRAME;

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

    /* extra information need by some protocols */
    extra_len = 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);
    phdr->pseudo_header.k12.extra_info = (guint8*)ws_buffer_start_ptr(&(k12->extra_info));
    phdr->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));
    phdr->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));
        phdr->pseudo_header.k12.input_name = src_desc->input_name;
        phdr->pseudo_header.k12.stack_file = src_desc->stack_file;
        phdr->pseudo_header.k12.input_type = src_desc->input_type;

        switch(src_desc->input_type) {
            case K12_PORT_ATMPVC:
                if ((long)(buffer_offset + length + K12_PACKET_OFFSET_CID) < len) {
                    phdr->pseudo_header.k12.input_info.atm.vp =  pntoh16(buffer + buffer_offset + length + K12_PACKET_OFFSET_VP);
                    phdr->pseudo_header.k12.input_info.atm.vc =  pntoh16(buffer + buffer_offset + length + K12_PACKET_OFFSET_VC);
                    phdr->pseudo_header.k12.input_info.atm.cid =  *((unsigned char*)(buffer + buffer_offset + length + K12_PACKET_OFFSET_CID));
                    break;
                }
                /* Fall through */
            default:
                memcpy(&(phdr->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(&(phdr->pseudo_header.k12),0,sizeof(phdr->pseudo_header.k12));
        phdr->pseudo_header.k12.input_name = "unknown port";
        phdr->pseudo_header.k12.stack_file = "unknown stack file";
    }

    phdr->pseudo_header.k12.input = src_id;
    phdr->pseudo_header.k12.stuff = k12;
}
예제 #2
0
파일: k12.c 프로젝트: ljakab/wireshark
wtap_open_return_val k12_open(wtap *wth, int *err, gchar **err_info) {
    k12_src_desc_t* rec;
    guint8 header_buffer[K12_FILE_HDR_LEN];
    guint8* read_buffer;
    guint32 type;
    long offset;
    long len;
    guint port_type;
    guint32 rec_len;
    guint32 hwpart_len;
    guint32 name_len;
    guint32 stack_len;
    guint i;
    k12_t* file_data;

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

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

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

    offset = K12_FILE_HDR_LEN;

    file_data = new_k12_file_data();

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

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

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

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

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

        read_buffer = file_data->seq_read_buff;

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

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

        switch (type) {

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

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

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

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

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

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

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

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

            ascii_strdown_inplace (rec->stack_file);

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

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

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

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

    return WTAP_OPEN_MINE;
}
예제 #3
0
파일: k12.c 프로젝트: bearxiong99/wireshark
/*
 * get_record: Get the next record into a buffer
 *   Every 8192 bytes 16 bytes are inserted in the file,
 *   even in the middle of a record.
 *   This reads the next record without the eventual 16 bytes.
 *   returns the length of the record + the stuffing (if any)
 *
 *   Returns number of bytes read on success, 0 on EOF, -1 on error;
 *   if -1 is returned, *err is set to the error indication and, for
 *   errors where that's appropriate, *err_info is set to an additional
 *   error string.
 *
 * XXX: works at most with 8191 bytes per record
 */
static gint get_record(k12_t *file_data, FILE_T fh, gint64 file_offset,
                       gboolean is_random, int *err, gchar **err_info) {
    guint8 *buffer = is_random ? file_data->rand_read_buff : file_data->seq_read_buff;
    guint buffer_len = is_random ? file_data->rand_read_buff_len : file_data->seq_read_buff_len;
    guint total_read = 0;
    guint left;
    guint8* writep;
#ifdef DEBUG_K12
    guint actual_len;
#endif

    /*
     * Where the next unknown 16 bytes are stuffed to the file.
     * Following the file header, they appear every 8192 bytes,
     * starting right after the file header, so if the file offset
     * relative to the file header is a multiple of 8192, the
     * 16-byte blob is there.
     */
    guint junky_offset = 8192 - (gint) ( (file_offset - K12_FILE_HDR_LEN) % 8192 );

    K12_DBG(6,("get_record: ENTER: junky_offset=%" G_GINT64_MODIFIER "d, file_offset=%" G_GINT64_MODIFIER "d",junky_offset,file_offset));

    /* no buffer is given, lets create it */
    if (buffer == NULL) {
        buffer = (guint8*)g_malloc(8192);
        buffer_len = 8192;
        if (is_random) {
            file_data->rand_read_buff = buffer;
            file_data->rand_read_buff_len = buffer_len;
        } else {
            file_data->seq_read_buff = buffer;
            file_data->seq_read_buff_len = buffer_len;
        }
    }

    if ( junky_offset == 8192 ) {
        /*
         * We're at the beginning of one of the 16-byte blobs,
         * so we first need to skip the blob.
         *
         * XXX - what if the blob is in the middle of the record
         * length?  If the record length is always a multiple of
         * 4 bytes, that won't happen.
         */
        if ( ! file_skip( fh, K12_FILE_BLOB_LEN, err ) )
            return -1;
        total_read += K12_FILE_BLOB_LEN;
    }

    /*
     * Read the record length.
     */
    if ( !wtap_read_bytes( fh, buffer, 4, err, err_info ) )
        return -1;
    total_read += 4;

    left = pntoh32(buffer + K12_RECORD_LEN);
#ifdef DEBUG_K12
    actual_len = left;
#endif
    junky_offset -= 4;

    K12_DBG(5,("get_record: GET length=%u",left));

    /*
     * Record length must be at least large enough for the length
     * and type, hence 8 bytes.
     *
     * XXX - is WTAP_MAX_PACKET_SIZE the right check for a maximum
     * record size?  Should we report this error differently?
     */
    if (left < 8) {
        *err = WTAP_ERR_BAD_FILE;
        *err_info = g_strdup_printf("k12: Record length %u is less than 8 bytes long",left);
        return -1;
    }
    if (left > WTAP_MAX_PACKET_SIZE) {
        *err = WTAP_ERR_BAD_FILE;
        *err_info = g_strdup_printf("k12: Record length %u is greater than the maximum %u",left,WTAP_MAX_PACKET_SIZE);
        return -1;
    }

    /*
     * XXX - calculate the lowest power of 2 >= left, rather than just
     * looping.
     */
    while (left > buffer_len) {
        buffer = (guint8*)g_realloc(buffer,buffer_len*=2);
        if (is_random) {
            file_data->rand_read_buff = buffer;
            file_data->rand_read_buff_len = buffer_len;
        } else {
            file_data->seq_read_buff = buffer;
            file_data->seq_read_buff_len = buffer_len;
        }
    }

    writep = buffer + 4;
    left -= 4;

    /* Read the rest of the record. */
    do {
        K12_DBG(6,("get_record: looping left=%d junky_offset=%" G_GINT64_MODIFIER "d",left,junky_offset));

        if (junky_offset > left) {
            /*
             * The next 16-byte blob is past the end of this record.
             * Just read the rest of the record.
             */
            if ( !wtap_read_bytes( fh, writep, left, err, err_info ) )
                return -1;
            total_read += left;
            break;
        } else {
            /*
             * The next 16-byte blob is part of this record.
             * Read up to the blob.
             */
            if ( !wtap_read_bytes( fh, writep, junky_offset, err, err_info ) )
                return -1;

            total_read += junky_offset;
            writep += junky_offset;

            /*
             * Skip the blob.
             */
            if ( !file_skip( fh, K12_FILE_BLOB_LEN, err ) )
                return -1;
            total_read += K12_FILE_BLOB_LEN;

            left -= junky_offset;
            junky_offset = 8192;
        }

    } while(left);

    K12_HEX_ASCII_DUMP(5,file_offset, "GOT record", buffer, actual_len);
    return total_read;
}
예제 #4
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;
}
예제 #5
0
파일: k12.c 프로젝트: ljakab/wireshark
static gboolean k12_read(wtap *wth, int *err, gchar **err_info, gint64 *data_offset) {
    k12_t *k12 = (k12_t *)wth->priv;
    k12_src_desc_t* src_desc;
    guint8* buffer;
    gint64 offset;
    gint len;
    guint32 type;
    guint32 src_id;

    offset = file_tell(wth->fh);

    /* ignore the record if it isn't a packet */
    do {
        if ( k12->num_of_records == 0 ) {
            /* No more records */
            *err = 0;
            return FALSE;
        }

        K12_DBG(5,("k12_read: offset=%i",offset));

        *data_offset = offset;

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

        if (len < 0) {
            /* read error */
            return FALSE;
        } else if (len == 0) {
            /* EOF */
            *err = WTAP_ERR_SHORT_READ;
            return FALSE;
        } else if (len < K12_RECORD_SRC_ID + 4) {
            /* Record not large enough to contain a src ID */
            *err = WTAP_ERR_BAD_FILE;
            *err_info = g_strdup_printf("k12: Data record length %d too short", len);
            return FALSE;
        }
        k12->num_of_records--;

        buffer = k12->seq_read_buff;

        type = pntoh32(buffer + K12_RECORD_TYPE);
        src_id = pntoh32(buffer + K12_RECORD_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));
        }

        K12_DBG(5,("k12_read: record type=%x src_id=%x",type,src_id));

        offset += len;

    } while ( ((type & K12_MASK_PACKET) != K12_REC_PACKET && (type & K12_MASK_PACKET) != K12_REC_D0020) || !src_id || !src_desc );

    return process_packet_data(&wth->rec, wth->rec_data, buffer, (guint)len, k12, err, err_info);
}
예제 #6
0
static gboolean peekclassic_read_packet_v56(wtap *wth, FILE_T fh,
        struct wtap_pkthdr *phdr, Buffer *buf, int *err, gchar **err_info)
{
    peekclassic_t *peekclassic = (peekclassic_t *)wth->priv;
    guint8 ep_pkt[PEEKCLASSIC_V56_PKT_SIZE];
    guint16 length;
    guint16 sliceLength;
#if 0
    guint8  flags;
    guint8  status;
#endif
    guint32 timestamp;
#if 0
    guint16 destNum;
    guint16 srcNum;
#endif
    guint16 protoNum;
#if 0
    char    protoStr[8];
#endif
    unsigned int i;

    if (!wtap_read_bytes_or_eof(fh, ep_pkt, sizeof(ep_pkt), err, err_info))
        return FALSE;

    /* Extract the fields from the packet */
    length = pntoh16(&ep_pkt[PEEKCLASSIC_V56_LENGTH_OFFSET]);
    sliceLength = pntoh16(&ep_pkt[PEEKCLASSIC_V56_SLICE_LENGTH_OFFSET]);
#if 0
    flags = ep_pkt[PEEKCLASSIC_V56_FLAGS_OFFSET];
    status = ep_pkt[PEEKCLASSIC_V56_STATUS_OFFSET];
#endif
    timestamp = pntoh32(&ep_pkt[PEEKCLASSIC_V56_TIMESTAMP_OFFSET]);
#if 0
    destNum = pntoh16(&ep_pkt[PEEKCLASSIC_V56_DESTNUM_OFFSET]);
    srcNum = pntoh16(&ep_pkt[PEEKCLASSIC_V56_SRCNUM_OFFSET]);
#endif
    protoNum = pntoh16(&ep_pkt[PEEKCLASSIC_V56_PROTONUM_OFFSET]);
#if 0
    memcpy(protoStr, &ep_pkt[PEEKCLASSIC_V56_PROTOSTR_OFFSET],
           sizeof protoStr);
#endif

    /*
     * XXX - is the captured packet data padded to a multiple
     * of 2 bytes?
     */

    /* force sliceLength to be the actual length of the packet */
    if (0 == sliceLength) {
        sliceLength = length;
    }

    /* fill in packet header values */
    phdr->rec_type = REC_TYPE_PACKET;
    phdr->presence_flags = WTAP_HAS_TS|WTAP_HAS_CAP_LEN;
    /* timestamp is in milliseconds since reference_time */
    phdr->ts.secs  = peekclassic->reference_time + (timestamp / 1000);
    phdr->ts.nsecs = 1000 * (timestamp % 1000) * 1000;
    phdr->len      = length;
    phdr->caplen   = sliceLength;

    phdr->pkt_encap = WTAP_ENCAP_UNKNOWN;
    for (i=0; i<NUM_PEEKCLASSIC_ENCAPS; i++) {
        if (peekclassic_encap[i].protoNum == protoNum) {
            phdr->pkt_encap = peekclassic_encap[i].encap;
        }
    }

    switch (phdr->pkt_encap) {

    case WTAP_ENCAP_ETHERNET:
        /* We assume there's no FCS in this frame. */
        phdr->pseudo_header.eth.fcs_len = 0;
        break;
    }

    /* read the packet data */
    return wtap_read_packet_bytes(fh, buf, sliceLength, err, err_info);
}
예제 #7
0
/* Tests a tvbuff against the expected pattern/length.
 * Returns TRUE if all tests succeeed, FALSE if any test fails */
gboolean
test(tvbuff_t *tvb, const gchar* name,
     guint8* expected_data, guint expected_length, guint expected_reported_length)
{
	guint			length;
	guint			reported_length;
	guint8			*ptr;
	volatile gboolean	ex_thrown;
	volatile guint32	val32;
	guint32			expected32;
	guint			incr, i;

	length = tvb_length(tvb);

	if (length != expected_length) {
		printf("01: Failed TVB=%s Length of tvb=%u while expected length=%u\n",
				name, length, expected_length);
		failed = TRUE;
		return FALSE;
	}

	reported_length = tvb_reported_length(tvb);

	if (reported_length != expected_reported_length) {
		printf("01: Failed TVB=%s Reported length of tvb=%u while expected reported length=%u\n",
				name, reported_length, expected_reported_length);
		failed = TRUE;
		return FALSE;
	}

	/* Test boundary case. A BoundsError exception should be thrown. */
	ex_thrown = FALSE;
	TRY {
		tvb_get_ptr(tvb, 0, length + 1);
	}
	CATCH(BoundsError) {
		ex_thrown = TRUE;
	}
	CATCH(FragmentBoundsError) {
		printf("02: Caught wrong exception: FragmentBoundsError\n");
	}
	CATCH(ReportedBoundsError) {
		printf("02: Caught wrong exception: ReportedBoundsError\n");
	}
	CATCH_ALL {
		printf("02: Caught wrong exception: %lu, exc->except_id.except_code\n");
	}
	ENDTRY;

	if (!ex_thrown) {
		printf("02: Failed TVB=%s No BoundsError when retrieving %u bytes\n",
				name, length + 1);
		failed = TRUE;
		return FALSE;
	}

	/* Test boundary case with reported_length+1. A ReportedBoundsError
	   exception should be thrown. */
	ex_thrown = FALSE;
	TRY {
		tvb_get_ptr(tvb, 0, reported_length + 1);
	}
	CATCH(BoundsError) {
		printf("03: Caught wrong exception: BoundsError\n");
	}
	CATCH(FragmentBoundsError) {
		printf("03: Caught wrong exception: FragmentBoundsError\n");
	}
	CATCH(ReportedBoundsError) {
		ex_thrown = TRUE;
	}
	CATCH_ALL {
		printf("02: Caught wrong exception: %lu, exc->except_id.except_code\n");
	}
	ENDTRY;

	if (!ex_thrown) {
		printf("03: Failed TVB=%s No ReportedBoundsError when retrieving %u bytes\n",
				name, reported_length + 1);
		failed = TRUE;
		return FALSE;
	}

	/* Test boundary case. A BoundsError exception should be thrown. */
	ex_thrown = FALSE;
	TRY {
		tvb_get_ptr(tvb, -1, 2);
	}
	CATCH(BoundsError) {
		ex_thrown = TRUE;
	}
	CATCH(FragmentBoundsError) {
		printf("04: Caught wrong exception: FragmentBoundsError\n");
	}
	CATCH(ReportedBoundsError) {
		printf("04: Caught wrong exception: ReportedBoundsError\n");
	}
	CATCH_ALL {
		printf("02: Caught wrong exception: %lu, exc->except_id.except_code\n");
	}
	ENDTRY;

	if (!ex_thrown) {
		printf("04: Failed TVB=%s No BoundsError when retrieving 2 bytes from"
				" offset -1\n", name);
		failed = TRUE;
		return FALSE;
	}

	/* Test boundary case. A BoundsError exception should not be thrown. */
	ex_thrown = FALSE;
	TRY {
		tvb_get_ptr(tvb, 0, 1);
	}
	CATCH(BoundsError) {
		ex_thrown = TRUE;
	}
	CATCH(FragmentBoundsError) {
		printf("05: Caught wrong exception: FragmentBoundsError\n");
	}
	CATCH(ReportedBoundsError) {
		printf("05: Caught wrong exception: ReportedBoundsError\n");
	}
	CATCH_ALL {
		printf("02: Caught wrong exception: %lu, exc->except_id.except_code\n");
	}
	ENDTRY;

	if (ex_thrown) {
		printf("05: Failed TVB=%s BoundsError when retrieving 1 bytes from"
				" offset 0\n", name);
		failed = TRUE;
		return FALSE;
	}

	/* Test boundary case. A BoundsError exception should not be thrown. */
	ex_thrown = FALSE;
	TRY {
		tvb_get_ptr(tvb, -1, 1);
	}
	CATCH(BoundsError) {
		ex_thrown = TRUE;
	}
	CATCH(FragmentBoundsError) {
		printf("06: Caught wrong exception: FragmentBoundsError\n");
	}
	CATCH(ReportedBoundsError) {
		printf("06: Caught wrong exception: ReportedBoundsError\n");
	}
	CATCH_ALL {
		printf("02: Caught wrong exception: %lu, exc->except_id.except_code\n");
	}
	ENDTRY;

	if (ex_thrown) {
		printf("06: Failed TVB=%s BoundsError when retrieving 1 bytes from"
				" offset -1\n", name);
		failed = TRUE;
		return FALSE;
	}


	/* Check data at boundary. An exception should not be thrown. */
	if (length >= 4) {
		ex_thrown = FALSE;
		TRY {
			val32 = tvb_get_ntohl(tvb, 0);
		}
		CATCH_ALL {
			ex_thrown = TRUE;
		}
		ENDTRY;

		if (ex_thrown) {
			printf("07: Failed TVB=%s Exception when retrieving "
					"guint32 from offset 0\n", name);
			failed = TRUE;
			return FALSE;
		}

		expected32 = pntoh32(expected_data);
		if (val32 != expected32) {
			printf("08: Failed TVB=%s  guint32 @ 0 %u != expected %u\n",
					name, val32, expected32);
			failed = TRUE;
			return FALSE;
		}
	}
예제 #8
0
static gboolean
nettl_read_rec(wtap *wth, FILE_T fh, struct wtap_pkthdr *phdr, Buffer *buf,
		int *err, gchar **err_info)
{
    union wtap_pseudo_header *pseudo_header = &phdr->pseudo_header;
    nettl_t *nettl = (nettl_t *)wth->priv;
    gboolean fddihack = FALSE;
    int bytes_read;
    struct nettlrec_hdr rec_hdr;
    guint16 hdr_len;
    struct nettlrec_ns_ls_drv_eth_hdr drv_eth_hdr;
    guint32 length, caplen;
    int subsys;
    guint padlen;
    int datalen;
    guint8 dummyc[16];
    int bytes_to_read;
    guint8 *pd;
    guint8 dummy[3];

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

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

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

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

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

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

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

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

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

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

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

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

    if (bytes_read != datalen) {
	*err = file_error(fh, err_info);
	if (*err == 0)
	    *err = WTAP_ERR_SHORT_READ;
	return FALSE;
    }
    return TRUE;
}
예제 #9
0
/* XXX - return -1 on I/O error and actually do something with 'err'. */
int csids_open(wtap *wth, int *err, gchar **err_info)
{
  /* There is no file header. There is only a header for each packet
   * so we read a packet header and compare the caplen with iplen. They
   * should always be equal except with the weird byteswap version.
   *
   * THIS IS BROKEN-- anytime the caplen is 0x0101 or 0x0202 up to 0x0505
   * this will byteswap it. I need to fix this. XXX --mlh
   */

  int tmp,iplen,bytesRead;

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

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

  if ( iplen == 0 )
    return 0;

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

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

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

  return 1;
}
예제 #10
0
static gboolean
iptrace_read_rec_1_0(FILE_T fh, struct wtap_pkthdr *phdr, Buffer *buf,
    int *err, gchar **err_info)
{
	guint8			header[IPTRACE_1_0_PHDR_SIZE];
	int			ret;
	iptrace_1_0_phdr	pkt_hdr;
	guint32			packet_size;

	ret = iptrace_read_rec_header(fh, header, IPTRACE_1_0_PHDR_SIZE,
	    err, err_info);
	if (ret <= 0) {
		/* Read error or EOF */
		return FALSE;
	}

	/*
	 * Byte 28 of the frame header appears to be a BSD-style IFT_xxx
	 * value giving the type of the interface.  Check out the
	 * <net/if_types.h> header file.
	 */
	pkt_hdr.if_type = header[28];
	phdr->pkt_encap = wtap_encap_ift(pkt_hdr.if_type);
	if (phdr->pkt_encap == WTAP_ENCAP_UNKNOWN) {
		*err = WTAP_ERR_UNSUPPORTED_ENCAP;
		*err_info = g_strdup_printf("iptrace: interface type IFT=0x%02x unknown or unsupported",
		    pkt_hdr.if_type);
		return FALSE;
	}

	/* Read the packet metadata */
	packet_size = pntoh32(&header[0]);
	if (packet_size < IPTRACE_1_0_PDATA_SIZE) {
		/*
		 * Uh-oh, the record isn't big enough to even have a
		 * packet meta-data header.
		 */
		*err = WTAP_ERR_BAD_FILE;
		*err_info = g_strdup_printf("iptrace: file has a %u-byte record, too small to have even a packet meta-data header",
		    packet_size);
		return FALSE;
	}
	packet_size -= IPTRACE_1_0_PDATA_SIZE;

	/*
	 * AIX appears to put 3 bytes of padding in front of FDDI
	 * frames; strip that crap off.
	 */
	if (phdr->pkt_encap == WTAP_ENCAP_FDDI_BITSWAPPED) {
		/*
		 * The packet size is really a record size and includes
		 * the padding.
		 */
		if (packet_size < 3) {
			/*
			 * Uh-oh, the record isn't big enough to even have
			 * the padding.
			 */
			*err = WTAP_ERR_BAD_FILE;
			*err_info = g_strdup_printf("iptrace: file has a %u-byte record, too small to have even a packet meta-data header",
			    packet_size + IPTRACE_1_0_PDATA_SIZE);
			return FALSE;
		}
		packet_size -= 3;

		/*
		 * Skip the padding.
		 */
		if (!file_skip(fh, 3, err))
			return FALSE;
	}
	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("iptrace: File has %u-byte packet, bigger than maximum of %u",
		    packet_size, WTAP_MAX_PACKET_SIZE);
		return FALSE;
	}

	phdr->presence_flags = WTAP_HAS_TS;
	phdr->len = packet_size;
	phdr->caplen = packet_size;
	phdr->ts.secs = pntoh32(&header[4]);
	phdr->ts.nsecs = 0;

	/* Fill in the pseudo-header. */
	fill_in_pseudo_header(phdr->pkt_encap, &phdr->pseudo_header, header);

	/* Get the packet data */
	return iptrace_read_rec_data(fh, buf, phdr, err, err_info);
}
예제 #11
0
static gboolean
iptrace_read_rec_2_0(FILE_T fh, struct wtap_pkthdr *phdr, Buffer *buf,
    int *err, gchar **err_info)
{
	guint8			header[IPTRACE_2_0_PHDR_SIZE];
	int			ret;
	iptrace_2_0_phdr	pkt_hdr;
	guint32			packet_size;

	ret = iptrace_read_rec_header(fh, header, IPTRACE_2_0_PHDR_SIZE,
	    err, err_info);
	if (ret <= 0) {
		/* Read error or EOF */
		return FALSE;
	}

	/*
	 * Byte 28 of the frame header appears to be a BSD-style IFT_xxx
	 * value giving the type of the interface.  Check out the
	 * <net/if_types.h> header file.
	 */
	pkt_hdr.if_type = header[28];
	phdr->pkt_encap = wtap_encap_ift(pkt_hdr.if_type);
#if 0
	/*
	 * We used to error out if the interface type in iptrace was
	 * unknown/unhandled, but an iptrace may contain packets
	 * from a variety of interfaces, some known, and others
	 * unknown.
	 *
	 * It is better to display the data even for unknown interface
	 * types, isntead of erroring out. In the future, it would be
	 * nice to be able to flag which frames are shown as data
	 * because their interface type is unknown, and also present
	 * the interface type number to the user so that it can be
	 * reported easily back to the Wireshark developer.
	 *
	 * XXX - what types are there that are used in files but
	 * that we don't handle?
	 */
	if (phdr->pkt_encap == WTAP_ENCAP_UNKNOWN) {
		*err = WTAP_ERR_UNSUPPORTED_ENCAP;
		*err_info = g_strdup_printf("iptrace: interface type IFT=0x%02x unknown or unsupported",
		    pkt_hdr.if_type);
		return FALSE;
	}
#endif

	/* Read the packet metadata */
	packet_size = pntoh32(&header[0]);
	if (packet_size < IPTRACE_2_0_PDATA_SIZE) {
		/*
		 * Uh-oh, the record isn't big enough to even have a
		 * packet meta-data header.
		 */
		*err = WTAP_ERR_BAD_FILE;
		*err_info = g_strdup_printf("iptrace: file has a %u-byte record, too small to have even a packet meta-data header",
		    packet_size);
		return FALSE;
	}
	packet_size -= IPTRACE_2_0_PDATA_SIZE;

	/*
	 * AIX appears to put 3 bytes of padding in front of FDDI
	 * frames; strip that crap off.
	 */
	if (phdr->pkt_encap == WTAP_ENCAP_FDDI_BITSWAPPED) {
		/*
		 * The packet size is really a record size and includes
		 * the padding.
		 */
		if (packet_size < 3) {
			/*
			 * Uh-oh, the record isn't big enough to even have
			 * the padding.
			 */
			*err = WTAP_ERR_BAD_FILE;
			*err_info = g_strdup_printf("iptrace: file has a %u-byte record, too small to have even a packet meta-data header",
			    packet_size + IPTRACE_2_0_PDATA_SIZE);
			return FALSE;
		}
		packet_size -= 3;

		/*
		 * Skip the padding.
		 */
		if (!file_skip(fh, 3, err))
			return FALSE;
	}
	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("iptrace: File has %u-byte packet, bigger than maximum of %u",
		    packet_size, WTAP_MAX_PACKET_SIZE);
		return FALSE;
	}

	phdr->presence_flags = WTAP_HAS_TS;
	phdr->len = packet_size;
	phdr->caplen = packet_size;
	phdr->ts.secs = pntoh32(&header[32]);
	phdr->ts.nsecs = pntoh32(&header[36]);

	/* Fill in the pseudo_header. */
	fill_in_pseudo_header(phdr->pkt_encap, &phdr->pseudo_header, header);

	/* Get the packet data */
	return iptrace_read_rec_data(fh, buf, phdr, err, err_info);
}
예제 #12
0
static gboolean stanag4607_read_file(wtap *wth, FILE_T fh, struct wtap_pkthdr *phdr,
                                     Buffer *buf, int *err, gchar **err_info)
{
    stanag4607_t *stanag4607 = (stanag4607_t *)wth->priv;
    guint32 millisecs, secs, nsecs;
    gint64 offset = 0;
    guint8 stanag_pkt_hdr[37];
    int bytes_read;
    guint32 packet_size;

    *err = 0;

    /* Combined packet header and segment header */
    bytes_read = file_read(stanag_pkt_hdr, sizeof stanag_pkt_hdr, fh);
    if (bytes_read != sizeof stanag_pkt_hdr)
        goto fail;
    offset += bytes_read;

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

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

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

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

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

        bytes_read = file_read(&mseg, sizeof mseg, fh);
        if (bytes_read != sizeof mseg)
            goto fail;
        offset += bytes_read;

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

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

    return wtap_read_packet_bytes(fh, buf, packet_size, err, err_info);

fail:
    *err = file_error(wth->fh, err_info);
    return FALSE;
}
예제 #13
0
/* Returns TRUE if packet data copied, FALSE if error occurred or EOF (no more records). */
static gboolean
collate(pppdump_t* state, FILE_T fh, int *err, gchar **err_info, guint8 *pd,
		int *num_bytes, direction_enum *direction, pkt_id *pid,
		gint64 num_bytes_to_skip)
{
	int		id;
	pkt_t		*pkt = NULL;
	int		byte0, byte1;
	int		n, num_written = 0;
	gint64		start_offset;
	guint32		time_long;
	guint8		time_short;

	/*
	 * Process any data left over in the current record when doing
	 * sequential processing.
	 */
	if (state->num_bytes > 0) {
		g_assert(num_bytes_to_skip == 0);
		pkt = state->pkt;
		num_written = process_data(state, fh, pkt, state->num_bytes,
		    pd, err, err_info, pid);

		if (num_written < 0) {
			return FALSE;
		}
		else if (num_written > 0) {
			*num_bytes = num_written;
			*direction = pkt->dir;
			return TRUE;
		}
		/* if 0 bytes written, keep processing */
	} else {
		/*
		 * We didn't have any data left over, so the packet will
		 * start at the beginning of a record.
		 */
		if (pid)
			pid->num_bytes_to_skip = 0;
	}

	/*
	 * That didn't get all the data for this packet, so process
	 * subsequent records.
	 */
	start_offset = state->offset;
	while ((id = file_getc(fh)) != EOF) {
		state->offset++;
		switch (id) {
			case PPPD_SENT_DATA:
			case PPPD_RECV_DATA:
				pkt = id == PPPD_SENT_DATA ? &state->spkt : &state->rpkt;

				/*
				 * Save the offset of the beginning of
				 * the current record.
				 */
				pkt->cd_offset = state->offset - 1;

				/*
				 * Get the length of the record.
				 */
				byte0 = file_getc(fh);
				if (byte0 == EOF)
					goto done;
				state->offset++;
				byte1 = file_getc(fh);
				if (byte1 == EOF)
					goto done;
				state->offset++;
				n = (byte0 << 8) | byte1;

				if (pkt->id_offset == 0) {
					/*
					 * We don't have the initial data
					 * offset for this packet, which
					 * means this is the first
					 * data record for that packet.
					 * Save the offset of the
					 * beginning of that record and
					 * the offset of the first data
					 * byte in the packet, which is
					 * the first data byte in the
					 * record.
					 */
					pkt->id_offset = pkt->cd_offset;
					pkt->sd_offset = state->offset;
				}

				if (n == 0)
					continue;

				g_assert(num_bytes_to_skip < n);
				while (num_bytes_to_skip) {
					if (file_getc(fh) == EOF)
						goto done;
					state->offset++;
					num_bytes_to_skip--;
					n--;
				}
				num_written = process_data(state, fh, pkt, n,
				    pd, err, err_info, pid);

				if (num_written < 0) {
					return FALSE;
				}
				else if (num_written > 0) {
					*num_bytes = num_written;
					*direction = pkt->dir;
					return TRUE;
				}
				/* if 0 bytes written, keep looping */
				break;

			case PPPD_SEND_DELIM:
			case PPPD_RECV_DELIM:
				/* What can we do? */
				break;

			case PPPD_RESET_TIME:
				wtap_file_read_unknown_bytes(&time_long, sizeof(guint32), fh, err, err_info);
				state->offset += sizeof(guint32);
				state->timestamp = pntoh32(&time_long);
				state->tenths = 0;
				break;

			case PPPD_TIME_STEP_LONG:
				wtap_file_read_unknown_bytes(&time_long, sizeof(guint32), fh, err, err_info);
				state->offset += sizeof(guint32);
				state->tenths += pntoh32(&time_long);

				if (state->tenths >= 10) {
					state->timestamp += state->tenths / 10;
					state->tenths = state->tenths % 10;
				}

				break;

			case PPPD_TIME_STEP_SHORT:
				wtap_file_read_unknown_bytes(&time_short, sizeof(guint8), fh, err, err_info);
				state->offset += sizeof(guint8);
				state->tenths += time_short;

				if (state->tenths >= 10) {
					state->timestamp += state->tenths / 10;
					state->tenths = state->tenths % 10;
				}

				break;

			default:
				/* XXX - bad file */
				*err = WTAP_ERR_BAD_FILE;
				*err_info = g_strdup_printf("pppdump: bad ID byte 0x%02x", id);
				return FALSE;
		}

	}

done:
	*err = file_error(fh, err_info);
	if (*err == 0) {
		if (state->offset != start_offset) {
			/*
			 * We read at least one byte, so we were working
			 * on a record; an EOF means that record was
			 * cut short.
			 */
			*err = WTAP_ERR_SHORT_READ;
		}
	}
	return FALSE;
}
예제 #14
0
int
pppdump_open(wtap *wth, int *err, gchar **err_info)
{
	guint8		buffer[6];	/* Looking for: 0x07 t3 t2 t1 t0 ID */
	int		bytes_read;
	pppdump_t	*state;

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

	bytes_read = file_read(buffer, sizeof(buffer), wth->fh);
	if (bytes_read != (int) sizeof(buffer)) {
		*err = file_error(wth->fh, err_info);
		if (*err != 0 && *err != WTAP_ERR_SHORT_READ)
			return -1;
		return 0;
	}

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

		goto my_file_type;
	}
	else {
		return 0;
	}

  my_file_type:

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

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

	init_state(state);

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

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

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

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

	return 1;
}
예제 #15
0
파일: k12.c 프로젝트: hekmati/spyshark
int k12_open(wtap *wth, int *err, gchar **err_info) {
    k12_src_desc_t* rec;
    guint8 header_buffer[0x200];
    guint8* read_buffer;
    guint32 type;
    long offset;
    long len;
    guint port_type;
    guint32 rec_len;
    guint32 hwpart_len;
    guint32 name_len;
    guint32 stack_len;
    guint i;
    k12_t* file_data;

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

    if ( file_read(header_buffer,0x200,wth->fh) != 0x200 ) {
        K12_DBG(1,("k12_open: FILE HEADER TOO SHORT OR READ ERROR"));
        *err = file_error(wth->fh, err_info);
        if (*err != 0 && *err != WTAP_ERR_SHORT_READ) {
            return -1;
        }
        return 0;
    } else {
        if ( memcmp(header_buffer,k12_file_magic,8) != 0 ) {
            K12_DBG(1,("k12_open: BAD MAGIC"));
            return 0;
        }
    }

    offset = 0x200;

    file_data = new_k12_file_data();

    file_data->file_len = pntoh32( header_buffer + 0x8);
    file_data->num_of_records = pntoh32( header_buffer + 0xC );

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

    do {

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

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

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

        read_buffer = file_data->seq_read_buff;

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

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

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

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

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

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

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

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

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

            ascii_strdown_inplace (rec->stack_file);

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

            offset += len;
            continue;
        } else if (type == K12_REC_STK_FILE) {
            K12_DBG(1,("k12_open: K12_REC_STK_FILE"));
            K12_DBG(1,("Field 1: 0x%08x",pntoh32( read_buffer + 0x08 )));
            K12_DBG(1,("Field 2: 0x%08x",pntoh32( read_buffer + 0x0c )));
            K12_ASCII_DUMP(1, read_buffer, rec_len, 0x10);

            offset += len;
            continue;
        } else {
            K12_DBG(1,("k12_open: RECORD TYPE 0x%08x",type));
            offset += len;
            continue;
        }
    } while(1);

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

    return 1;
}
예제 #16
0
파일: k12.c 프로젝트: hekmati/spyshark
/*
 * get_record: Get the next record into a buffer
 *   Every about 0x2000 bytes 0x10 bytes are inserted in the file,
 *   even in the middle of a record.
 *   This reads the next record without the eventual 0x10 bytes.
 *   returns the length of the record + the stuffing (if any)
 *
 *   Returns number of bytes read on success, 0 on EOF, -1 on error;
 *   if -1 is returned, *err is set to the error indication and, for
 *   errors where that's appropriate, *err_info is set to an additional
 *   error string.
 *
 * XXX: works at most with 0x1FFF bytes per record
 */
static gint get_record(k12_t *file_data, FILE_T fh, gint64 file_offset,
                       gboolean is_random, int *err, gchar **err_info) {
    guint8 *buffer = is_random ? file_data->rand_read_buff : file_data->seq_read_buff;
    guint buffer_len = is_random ? file_data->rand_read_buff_len : file_data->seq_read_buff_len;
    guint bytes_read;
    guint last_read;
    guint left;
    guint8 junk[0x14];
    guint8* writep;
#ifdef DEBUG_K12
    guint actual_len;
#endif

    /* where the next unknown 0x10 bytes are stuffed to the file */
    guint junky_offset = 0x2000 - (gint) ( (file_offset - 0x200) % 0x2000 );

    K12_DBG(6,("get_record: ENTER: junky_offset=%" G_GINT64_MODIFIER "d, file_offset=%" G_GINT64_MODIFIER "d",junky_offset,file_offset));

    /* no buffer is given, lets create it */
    if (buffer == NULL) {
        buffer = (guint8*)g_malloc(0x2000);
        buffer_len = 0x2000;
        if (is_random) {
            file_data->rand_read_buff = buffer;
            file_data->rand_read_buff_len = buffer_len;
        } else {
            file_data->seq_read_buff = buffer;
            file_data->seq_read_buff_len = buffer_len;
        }
    }

    /* Get the record length. */
    if ( junky_offset == 0x2000 ) {
        /* the length of the record is 0x10 bytes ahead from we are reading */
        bytes_read = file_read(junk,0x14,fh);

        if (bytes_read == 2 && junk[0] == 0xff && junk[1] == 0xff) {
            K12_DBG(1,("get_record: EOF"));
            return 0;
        } else if ( bytes_read < 0x14 ) {
            K12_DBG(1,("get_record: SHORT READ OR ERROR"));
            *err = file_error(fh, err_info);
            if (*err == 0) {
                *err = WTAP_ERR_SHORT_READ;
            }
            return -1;
        }

        memcpy(buffer,&(junk[0x10]),4);
    } else {
        /* the length of the record is right where we are reading */
        bytes_read = file_read(buffer, 0x4, fh);

        if (bytes_read == 2 && buffer[0] == 0xff && buffer[1] == 0xff) {
            K12_DBG(1,("get_record: EOF"));
            return 0;
        } else if (bytes_read == 4 && buffer[0] == 0xff && buffer[1] == 0xff
                   && buffer[2] == 0x00 && buffer[3] == 0x00) {
            /*
             * In at least one k18 RF5 file, there appears to be a "record"
             * with a length value of 0xffff0000, followed by a bunch of
             * data that doesn't appear to be records, including a long
             * list of numbers.
             *
             * We treat a length value of 0xffff0000 as an end-of-file
             * indication.
             *
             * XXX - is this a length indication, or will it appear
             * at the beginning of an 8KB block, so that we should
             * check for it above?
             */
            K12_DBG(1,("get_record: EOF"));
            return 0;
        } else if ( bytes_read != 0x4 ) {
            K12_DBG(1,("get_record: SHORT READ OR ERROR"));
            *err = file_error(fh, err_info);
            if (*err == 0) {
                *err = WTAP_ERR_SHORT_READ;
            }
            return -1;
        }
    }

    left = pntoh32(buffer + K12_RECORD_LEN);
#ifdef DEBUG_K12
    actual_len = left;
#endif
    junky_offset -= 0x4;

    K12_DBG(5,("get_record: GET length=%u",left));

    /*
     * Record length must be at least large enough for the length,
     * hence 4 bytes.
     *
     * XXX - Is WTAP_MAX_PACKET_SIZE the right check for a maximum
     * record size?  Should we report this error differently?
     */
    if (left < 4 || left > WTAP_MAX_PACKET_SIZE) {
        K12_DBG(1,("get_record: Invalid GET length=%u",left));
        *err = WTAP_ERR_BAD_FILE;
        *err_info = g_strdup_printf("get_record: Invalid GET length=%u",left);
        return -1;
    }

    /*
     * XXX - calculate the lowest power of 2 >= left, rather than just
     * looping.
     */
    while (left > buffer_len) {
        buffer = (guint8*)g_realloc(buffer,buffer_len*=2);
        if (is_random) {
            file_data->rand_read_buff = buffer;
            file_data->rand_read_buff_len = buffer_len;
        } else {
            file_data->seq_read_buff = buffer;
            file_data->seq_read_buff_len = buffer_len;
        }
    }

    writep = buffer + 4;
    left -= 4;

    /* Read the rest of the record. */
    do {
        K12_DBG(6,("get_record: looping left=%d junky_offset=%" G_GINT64_MODIFIER "d",left,junky_offset));

        if (junky_offset > left) {
            bytes_read += last_read = file_read(writep, left, fh);

            if ( last_read != left ) {
                K12_DBG(1,("get_record: SHORT READ OR ERROR"));
                *err = file_error(fh, err_info);
                if (*err == 0) {
                    *err = WTAP_ERR_SHORT_READ;
                }
                return -1;
            } else {
                K12_HEX_ASCII_DUMP(5,file_offset, "GOT record", buffer, actual_len);
                return bytes_read;
            }
        } else {
            bytes_read += last_read = file_read(writep, junky_offset, fh);

            if ( last_read != junky_offset ) {
                K12_DBG(1,("get_record: SHORT READ OR ERROR, read=%d expected=%d",last_read, junky_offset));
                *err = file_error(fh, err_info);
                if (*err == 0) {
                    *err = WTAP_ERR_SHORT_READ;
                }
                return -1;
            }

            writep += last_read;

            bytes_read += last_read = file_read(junk, 0x10, fh);

            if ( last_read != 0x10 ) {
                K12_DBG(1,("get_record: SHORT READ OR ERROR"));
                *err = file_error(fh, err_info);
                if (*err == 0) {
                    *err = WTAP_ERR_SHORT_READ;
                }
                return -1;
            }

            left -= junky_offset;
            junky_offset = 0x2000;
        }

    } while(left);

    K12_HEX_ASCII_DUMP(5,file_offset, "GOT record", buffer, actual_len);
    return bytes_read;
}