예제 #1
0
파일: vms.c 프로젝트: wireshark/wireshark
/* Parses a packet record. */
static gboolean
parse_vms_packet(FILE_T fh, wtap_rec *rec, Buffer *buf, int *err, gchar **err_info)
{
    char    line[VMS_LINE_LENGTH + 1];
    int     num_items_scanned;
    guint32 pkt_len = 0;
    int     pktnum;
    int     csec = 101;
    struct tm tm;
    char mon[4] = {'J', 'A', 'N', 0};
    gchar  *p;
    const gchar *endp;
    static const gchar months[] = "JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC";
    guint32 i;
    int     offset = 0;
    guint8 *pd;

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

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

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

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

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

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

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

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

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

    /* Convert the ASCII hex dump to binary data */
    for (i = 0; i < pkt_len; i += 16) {
        if (file_gets(line, VMS_LINE_LENGTH, fh) == NULL) {
            *err = file_error(fh, err_info);
            if (*err == 0) {
                *err = WTAP_ERR_SHORT_READ;
            }
            return FALSE;
        }
        line[VMS_LINE_LENGTH] = '\0';
        if (i == 0) {
            while (! isdumpline(line)) { /* advance to start of hex data */
                if (file_gets(line, VMS_LINE_LENGTH, fh) == NULL) {
                    *err = file_error(fh, err_info);
                    if (*err == 0) {
                        *err = WTAP_ERR_SHORT_READ;
                    }
                    return FALSE;
                }
                line[VMS_LINE_LENGTH] = '\0';
            }
            while (line[offset] && !g_ascii_isxdigit(line[offset]))
                offset++;
        }
        if (!parse_single_hex_dump_line(line, pd, i,
                                        offset, pkt_len - i)) {
            *err = WTAP_ERR_BAD_FILE;
            *err_info = g_strdup("vms: hex dump not valid");
            return FALSE;
        }
    }
    /* Avoid TCPIPTRACE-W-BUFFERSFUL, TCPIPtrace could not save n packets.
     * errors.
     *
     * XXX - when we support packet drop report information in the
     * Wiretap API, we should parse those lines and return "n" as
     * a packet drop count. */
    if (!file_gets(line, VMS_LINE_LENGTH, fh)) {
        *err = file_error(fh, err_info);
        if (*err == 0) {
            /* There is no next line, so there's no "TCPIPtrace could not
             * save n packets" line; not an error. */
            return TRUE;
        }
        return FALSE;
    }
    return TRUE;
}
예제 #2
0
/* Parses a packet record. */
static gboolean
parse_vms_packet(FILE_T fh, struct wtap_pkthdr *phdr, Buffer *buf, int *err, gchar **err_info)
{
    char   line[VMS_LINE_LENGTH + 1];
    int    num_items_scanned;
    int	   pkt_len = 0;
    int	   pktnum;
    int	   csec = 101;
    struct tm tm;
    char mon[4] = {'J', 'A', 'N', 0};
    gchar *p;
    static const gchar months[] = "JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC";
    int    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_printf("vms: header line not valid");
		return FALSE;
	    }
	}
        if ( (! pkt_len) && (p = strstr(line, "Length"))) {
            p += sizeof("Length ");
            while (*p && ! isdigit((guchar)*p))
                p++;

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

            pkt_len = atoi(p);
	    break;
        }
    } while (! isdumpline(line));

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

    phdr->presence_flags = WTAP_HAS_TS;
    phdr->ts.secs = mktime(&tm);
    phdr->ts.nsecs = csec * 10000000;
    phdr->caplen = pkt_len;
    phdr->len = pkt_len;

    /* Make sure we have enough room for the packet */
    buffer_assure_space(buf, pkt_len);
    pd = 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] && !isxdigit((guchar)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_printf("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;
}