/* ** Copyright (C) 2005-2006 by Carnegie Mellon University. ** ** @OPENSOURCE_HEADER_START@ ** ** Use of the SILK system and related source code is subject to the terms ** of the following licenses: ** ** GNU Public License (GPL) Rights pursuant to Version 2, June 1991 ** Government Purpose License Rights (GPLR) pursuant to DFARS 252.225-7013 ** ** NO WARRANTY ** ** ANY INFORMATION, MATERIALS, SERVICES, INTELLECTUAL PROPERTY OR OTHER ** PROPERTY OR RIGHTS GRANTED OR PROVIDED BY CARNEGIE MELLON UNIVERSITY ** PURSUANT TO THIS LICENSE (HEREINAFTER THE "DELIVERABLES") ARE ON AN ** "AS-IS" BASIS. CARNEGIE MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY ** KIND, EITHER EXPRESS OR IMPLIED AS TO ANY MATTER INCLUDING, BUT NOT ** LIMITED TO, WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE, ** MERCHANTABILITY, INFORMATIONAL CONTENT, NONINFRINGEMENT, OR ERROR-FREE ** OPERATION. CARNEGIE MELLON UNIVERSITY SHALL NOT BE LIABLE FOR INDIRECT, ** SPECIAL OR CONSEQUENTIAL DAMAGES, SUCH AS LOSS OF PROFITS OR INABILITY ** TO USE SAID INTELLECTUAL PROPERTY, UNDER THIS LICENSE, REGARDLESS OF ** WHETHER SUCH PARTY WAS AWARE OF THE POSSIBILITY OF SUCH DAMAGES. ** LICENSEE AGREES THAT IT WILL NOT MAKE ANY WARRANTY ON BEHALF OF ** CARNEGIE MELLON UNIVERSITY, EXPRESS OR IMPLIED, TO ANY PERSON ** CONCERNING THE APPLICATION OF OR THE RESULTS TO BE OBTAINED WITH THE ** DELIVERABLES UNDER THIS LICENSE. ** ** Licensee hereby agrees to defend, indemnify, and hold harmless Carnegie ** Mellon University, its trustees, officers, employees, and agents from ** all claims or demands made against them (and any related losses, ** expenses, or attorney's fees) arising out of, or relating to Licensee's ** and/or its sub licensees' negligent use or willful misuse of or ** negligent conduct or willful misconduct regarding the Software, ** facilities, or other rights or assistance granted by Carnegie Mellon ** University under this License, including, but not limited to, any ** claims of product liability, personal injury, death, damage to ** property, or violation of any laws or regulations. ** ** Carnegie Mellon University Software Engineering Institute authored ** documents are sponsored by the U.S. Department of Defense under ** Contract F19628-00-C-0003. Carnegie Mellon University retains ** copyrights in all material produced under this contract. The U.S. ** Government retains a non-exclusive, royalty-free license to publish or ** reproduce these documents, or allow others to do so, for U.S. ** Government purposes only pursuant to the copyright license under the ** contract clause at 252.227.7013. ** ** @OPENSOURCE_HEADER_END@ */ /* ** Code to handle the header on packed data files. ** */ #include "silk.h" RCSIDENT("$SiLK: rwpackedfileheader.c 5956 2006-12-14 21:37:05Z mthomas $"); #include "librw_priv.h" /* * _packedfileheaderReadV0(rwIOS) * * Assumes the cursor is at the end of the genericHeader and reads * the remainder of a FileHeaderV0. This involves reading the start * time (byte swapping it if necessary, and reading any header * padding in V2 or greater files. This function leaves the cursor * at the start of the data. Will realloc() the header contained in * the rwIOS. * * Returns 0 if successful; 1 on error. */ int _packedfileheaderReadV0(rwIOStruct *rwIOS) { rwFileHeaderV0 *file_hdr = NULL; int rv = LIBRW_OK; /* Grow the header to store the start time */ rv = _packedfileheaderCreateV0(rwIOS); if (rv) { goto END; } file_hdr = (rwFileHeaderV0*)rwGetHeader(rwIOS); if (RWIO_READ(rwIOS, &file_hdr->fileSTime,sizeof(file_hdr->fileSTime))) { rv = LIBRW_ERR_READ; goto END; } /* Read header padding, if any */ rv = _ioHandleHeaderPadding(rwIOS); if (rv) { goto END; } if (rwIOS->swapFlag) { file_hdr->fileSTime = BSWAP32(file_hdr->fileSTime); } END: return rv; } /* * status = _packedfileheaderCreateV0(&rwIOS) * * DO NOT CALL DIRECTLY. FOR INTERNAL USE BY rwOpen*Write() * * Complete the setup of the file described by *rwIOS: Grow the * header to hold an rwFileHeaderV0* and copy the startTime into * the header structure. Returns LIBRW_OK on success and non-zero on * failure: memory-allocation. * */ int _packedfileheaderCreateV0(rwIOStruct *rwIOS) { int rv = LIBRW_OK; size_t old_len; void *old_hdr; assert(rwIOS); assert(rwIOS->hdr); /* store old length and set new length */ old_len = rwIOS->hdrLen; rwIOS->hdrLen = sizeof(rwFileHeaderV0); /* return if old length and new length are the same */ if (old_len == rwIOS->hdrLen) { /* Assume this function was previously called. Do not clear * the time value. */ goto END; } /* the old header should be a genericHeader */ assert(old_len == sizeof(genericHeader)); /* store the current header, then grow it to hold the start time */ old_hdr = rwIOS->hdr; rwIOS->hdr = realloc(rwIOS->hdr, rwIOS->hdrLen); if (NULL == rwIOS->hdr) { rwIOS->hdr = old_hdr; rwIOS->hdrLen = old_len; rv = LIBRW_ERR_ALLOC; goto END; } /* clear newly allocated section */ assert(rwIOS->hdrLen > old_len); memset((((uint8_t*)rwIOS->hdr) + old_len), 0, (rwIOS->hdrLen - old_len)); END: return rv; } /* * status = _packedfileheaderSetSTime(rwIOS, start_time, round_to_hour); * * Sets the start time on the 'rwIOS' to the given 'start_time', * rounding the time down to the hour (floor) if 'round_to_hour' is * non-zero. Will expand the header on 'rwIOS' to a rwFileHeaderV0 * if required. Return LIBRW_OK on succcess, or non-zero on * failure: allocation. */ int _packedfileheaderSetSTime( rwIOStruct *rwIOS, uint32_t start_time, int round_to_hour) { int rv; /* grow the header */ rv = _packedfileheaderCreateV0(rwIOS); if (rv) { goto END; } if (round_to_hour) { start_time = start_time - (start_time % 3600); } /* set the start time */ ((rwFileHeaderV0*)rwIOS->hdr)->fileSTime = start_time; END: return rv; } /* * status = _packedfileheaderWriteV0(rwIOS, &rwrec) * * DO NOT CALL DIRECTLY. FOR INTERNAL USE BY rwOpen*Write() * * Write the entire header for the rwIOS, a rwFileHeaderV0*, to the * underlying file or stream--with the start time in the appropriate * byte order--and pad the header to an even multiple of the record * size if required. Returns 0 on success and non-zero on failure. * Use 'rwrec', if provided, to set the start time of the file if * the start-time had not been previously set. * */ int _packedfileheaderWriteV0( rwIOStruct *rwIOS, const rwGenericRec_V3 *rwRP) { int rv; uint32_t startTime; assert(rwIOS); /* If the file's start time was never set, set it. */ if (rwGetFileSTime(rwIOS) == 0) { /* If we were given an rwrec, Set the time based on the * record's time; otherwise set it based on the current * time. */ if (rwRP != NULL) { startTime = rwRP->sTime; } else { startTime = time(NULL); } rv = _packedfileheaderSetSTime(rwIOS, startTime, 1); if (rv) { goto END; } } /* write the genericHeader part of the header */ if (RWIO_WRITE(rwIOS, rwIOS->hdr, sizeof(genericHeader))) { rwIOS->errnum = errno; rv = LIBRW_ERR_WRITE; goto END; } /* write the start time, byte swapping it first if required */ if (rwIOS->swapFlag) { startTime = BSWAP32(((rwFileHeaderV0*)rwIOS->hdr)->fileSTime); } else { startTime = ((rwFileHeaderV0*)rwIOS->hdr)->fileSTime; } if (RWIO_WRITE(rwIOS, &startTime, sizeof(uint32_t))) { rwIOS->errnum = errno; rv = LIBRW_ERR_WRITE; goto END; } /* Write the header padding, if any */ rv = _ioHandleHeaderPadding(rwIOS); END: return rv; } #if 0 /* ********************************************************************* */ /* ** RWFILEHEADER VERSION 1 ** ** genericHeader gHdr; // 0- 7 Generic Header ** // uint8_t magic1; // Magic number for RW files ** // uint8_t magic2; // ** // uint8_t magic3; // ** // uint8_t magic4; // ** // uint8_t isBigEndian; // Byte order (1=big, 0=little) ** // uint8_t fileType; // File type ** // uint8_t fileVersion; // Version of the file type ** // uint8_t compressType;// Compression type ** ** uint32_t hdrLen; // 8-11 Total on-disk header length ** ** uint16_t recLen; // 12-13 Bytes per record ** uint16_t flowType; // 14-15 Class/Type of data in this file ** ** uint32_t fileSTime; // 16-19 Epoch start time for this file ** ** uint16_t sID; // 20-21 Sensor ID (integer) ** ** uint8_t* padding; // 22-var Padding ** ** ** Minimum 22 bytes on disk. */ #define N_TO_H_32(d) *((uint32_t*)(d)) = ntohl(*(uint32_t*)(d)) #define N_TO_H_16(d) *((uint16_t*)(d)) = ntohs(*(uint16_t*)(d)) static void packedFileHeaderNetToNative(uint8_t *dataPtr) { N_TO_H_32(dataPtr + 8); N_TO_H_16(dataPtr + 12); N_TO_H_16(dataPtr + 14); N_TO_H_32(dataPtr + 16); N_TO_H_16(dataPtr + 20); } /* * status = _librwReadPackedFileHeaderV1(rwIOS); * * Assumes the cursor is at the end of the genericHeader and reads * the remainder of an rwFileHeaderV1. This involves reading the * record length, the header length, the start time, the flowtype, * the length of the sensor name, the sensor name, and any header * padding to make the header a multiple of the record size. This * function leaves the cursor at the start of the data. Will * realloc() the header contained in the rwIOS. * * Returns 0 if successful; 1 on error. */ int _readPackedFileHeaderV1(rwIOStruct *rwIOS) { rwPackedFileHeaderV1_t *hdr; uint8_t buffer[256]; uint16_t header_len; size_t bytes_read; /* so far, we've read the generic header */ bytes_read = sizeof(genericHeader); /* grow the header field in rwIOS to store a rwPackedFileHeaderV1_t */ rwIOS->hdr = realloc(rwIOS->hdr, (sizeof(rwPackedFileHeaderV1_t))); if (NULL == (rwIOS->hdr)) { skAppPrintErr("Out of memory!"); return 1; } hdr = (rwPackedFileHeaderV1_t*)rwIOS->hdr; /* Read the fixed-width header data */ if (RWIO_READ(rwIOS, &buffer[8], MAGIC_NUMBER_9)) { } bytes_read += MAGIC_NUMBER_9; /* Put into host byte order */ packedFileHeaderNetToNative(buffer); /* Unpack it */ memcpy(&rwIOS->hdrLen, &buffer[ 8], 4); memcpy(&rwIOS->recLen, &buffer[12], 2); memcpy(&flow_type, &buffer[14], 2); memcpy(&hdr->fileSTime, &buffer[16], 4); memcpy(&rwIOS->sID, &buffer[20], 2); if (flow_type > 0xFF) { skAppPrintErr("flow type is too large"); } else { rwIOS->flowType = flow_type & 0xFF; } /* Read and ignore the rest of the header */ while (bytes_read < rwIOS->hdrLen) { size_t to_read = rwIOS->hdrLen - bytes_read; if (to_read > sizeof(buffer)) { to_read = sizeof(buffer); } if (RWIO_READ(rwIOS, &buffer, to_read)) { skAppPrintErr("Could not read rest of header on %s", rwIOS->fPath); return 1; } bytes_read -= to_read; } return 0; } /* _readPackedFileHeaderV1 */ int _writePackedFileHeaderV0(rwIOStruct *rwIOS) { uint8_t buffer[256]; uint16_t tmp16; size_t bytes_written; size_t offset = 0; assert(8 == sizeof(genericHeader)); memset(&buffer, 0, sizeof(buffer)); header_len = 22; if (header_len % rwIOS->recLen != 0) { header_len += (rwIOS->recLen - (header_len % rwIOS->recLen)); } rwIOS->hdrLen = header_len; memcpy(&buffer[ 0], &rwIOS->hdr, 8); memcpy(&buffer[ 8], &rwIOS->hdrLen, 4); memcpy(&buffer[12], &rwIOS->recLen, 2); memcpy(&buffer[14], &flow_type, 2); memcpy(&buffer[16], &hdr->fileSTime, 4); memcpy(&buffer[20], &rwIOS->sID, 2); /* Put into network byte order */ packedFileHeaderNetToNative(buffer); /* so far, we've read the generic header */ bytes_read = sizeof(genericHeader); /* grow the header field in rwIOS to store a rwPackedFileHeaderV1_t */ rwIOS->hdr = realloc(rwIOS->hdr, (sizeof(rwPackedFileHeaderV1_t))); if (NULL == (rwIOS->hdr)) { skAppPrintErr("Out of memory!"); return 1; } hdr = (rwPackedFileHeaderV1_t*)rwIOS->hdr; /* Read the fixed-width header data */ if (RWIO_READ(rwIOS, &buffer, MAGIC_NUMBER_9)) { } bytes_read += MAGIC_NUMBER_9; /* Unpack it */ memcpy(&rwIOS->recLen, &buffer[0], 2); memcpy(&header_len, &buffer[2], 2); memcpy(&hdr->sTime, &buffer[4], 4); hdr->flow_type = &buffer[8]; sensor_len = &buffer[9]; /* Byte swap */ rwIOS->recLen = ntohs(rwIOS->recLen); header_len = ntohs(header_len); hdr->sTime = ntohl(hdr->sTime); /* Compute true header length */ rwIOS->hdrLen = header_len * rwIOS->recLen; if (sensor_len > sizeof(buffer)) { skAppPrintErr("buffer too small to hold %d bytes of sensor name", sensor_len); hdr->sID = SENSOR_INVALID_SID; } else { if (RWIO_READ(rwIOS, &buffer, sensor_len)) { } bytes_read += sensor_len; hdr->sID = sksiteSensorLookup(buffer); } /* Read and ignore the rest of the header */ while (bytes_read < rwIOS->hdrLen) { size_t to_read = rwIOS->hdrLen - bytes_read; if (to_read > sizeof(buffer)) { to_read = sizeof(buffer); } if (RWIO_READ(rwIOS, &buffer, to_read)) { skAppPrintErr("Could not read rest of header on %s", rwIOS->fPath); return 1; } bytes_read -= to_read; } return 0; } /* librwReadFileHeaderV0 */ #endif /* 0 */ /* ** Local variables: ** mode:c ** indent-tabs-mode:nil ** c-basic-offset:4 ** End: */