/* 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; }
/* 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; }