2019-01-07 01:00:44 -06:00
|
|
|
#include <stdlib.h>
|
2018-12-16 02:11:53 -06:00
|
|
|
#include <stdint.h>
|
2019-01-24 00:20:55 -06:00
|
|
|
#include <string.h>
|
2018-12-16 02:11:53 -06:00
|
|
|
#include <fcntl.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <sys/types.h>
|
|
|
|
#include <sys/stat.h>
|
|
|
|
|
2018-12-16 02:15:33 -06:00
|
|
|
#include <hexagram/pcapng.h>
|
|
|
|
|
2019-01-24 01:26:44 -06:00
|
|
|
ssize_t hexagram_pcapng_read_options(hexagram_pcapng_stream *stream,
|
|
|
|
hexagram_pcapng_option_handler *handler,
|
|
|
|
uint32_t type,
|
|
|
|
size_t len) {
|
2019-01-24 00:20:55 -06:00
|
|
|
hexagram_pcapng_option option;
|
2019-01-21 08:51:30 -06:00
|
|
|
ssize_t total = 0;
|
|
|
|
|
|
|
|
while (total < len) {
|
|
|
|
ssize_t readlen;
|
|
|
|
|
2019-01-24 00:20:55 -06:00
|
|
|
if ((readlen = read(stream->fd, &option, sizeof(option))) < 0) {
|
|
|
|
stream->error = HEXAGRAM_PCAPNG_ERROR_IO;
|
2019-01-21 08:51:30 -06:00
|
|
|
|
|
|
|
goto error_io;
|
|
|
|
} else {
|
|
|
|
total += readlen;
|
|
|
|
}
|
|
|
|
|
2019-01-24 01:26:44 -06:00
|
|
|
if ((readlen = handler(stream, type, option.code, option.length)) < 0) {
|
2019-01-21 08:51:30 -06:00
|
|
|
goto error_io;
|
2019-01-24 00:20:55 -06:00
|
|
|
} else if (readlen < option.length) {
|
|
|
|
stream->error = HEXAGRAM_PCAPNG_ERROR_TRUNCATED;
|
2019-01-21 08:51:30 -06:00
|
|
|
|
|
|
|
goto error_io;
|
|
|
|
} else {
|
|
|
|
total += readlen;
|
|
|
|
}
|
2019-01-23 21:42:16 -06:00
|
|
|
|
2019-01-24 01:26:44 -06:00
|
|
|
if (option.length % sizeof(uint32_t)) {
|
|
|
|
size_t padding = sizeof(uint32_t) - (option.length % sizeof(uint32_t));
|
|
|
|
|
|
|
|
if ((readlen = lseek(stream->fd, padding, SEEK_CUR)) < 0) {
|
|
|
|
goto error_io;
|
|
|
|
} else {
|
|
|
|
total += padding;
|
|
|
|
}
|
2019-01-23 21:42:16 -06:00
|
|
|
}
|
2019-01-21 08:51:30 -06:00
|
|
|
}
|
|
|
|
|
2019-01-24 00:20:55 -06:00
|
|
|
stream->error = HEXAGRAM_PCAPNG_ERROR_OK;
|
2019-01-21 08:51:30 -06:00
|
|
|
|
|
|
|
return total;
|
|
|
|
|
|
|
|
error_io:
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2019-01-07 01:00:44 -06:00
|
|
|
hexagram_pcapng_stream *hexagram_pcapng_stream_open_fd(int fd) {
|
|
|
|
hexagram_pcapng_stream *stream;
|
|
|
|
|
|
|
|
if ((stream = malloc(sizeof(*stream))) == NULL) {
|
|
|
|
goto error_malloc_stream;
|
|
|
|
}
|
|
|
|
|
2019-01-24 00:20:55 -06:00
|
|
|
stream->fd = fd;
|
|
|
|
stream->error = HEXAGRAM_PCAPNG_ERROR_OK;
|
|
|
|
stream->if_tsresol = 0;
|
2019-01-07 01:00:44 -06:00
|
|
|
|
|
|
|
return stream;
|
|
|
|
|
|
|
|
error_malloc_stream:
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2019-01-24 00:20:55 -06:00
|
|
|
void hexagram_pcapng_stream_destroy(hexagram_pcapng_stream *stream) {
|
|
|
|
memset(stream, '\0', sizeof(*stream));
|
|
|
|
|
|
|
|
free(stream);
|
|
|
|
}
|
|
|
|
|
|
|
|
ssize_t hexagram_pcapng_stream_read(hexagram_pcapng_stream *stream,
|
|
|
|
hexagram_pcapng_block_handler *handler) {
|
2018-12-16 23:42:39 -06:00
|
|
|
hexagram_pcapng_block_header header;
|
|
|
|
hexagram_pcapng_block_footer footer;
|
2018-12-16 02:11:53 -06:00
|
|
|
ssize_t total = 0;
|
|
|
|
|
|
|
|
while (1) {
|
2019-01-23 21:42:16 -06:00
|
|
|
size_t expected;
|
2018-12-16 02:11:53 -06:00
|
|
|
ssize_t readlen;
|
|
|
|
|
2019-01-24 00:20:55 -06:00
|
|
|
if ((readlen = read(stream->fd, &header, sizeof(header))) < 0) {
|
|
|
|
stream->error = HEXAGRAM_PCAPNG_ERROR_IO;
|
2018-12-16 02:11:53 -06:00
|
|
|
|
|
|
|
goto error_io;
|
|
|
|
} else if (readlen == 0) {
|
|
|
|
goto done;
|
|
|
|
} else if (readlen < sizeof(header)) {
|
2019-01-24 00:20:55 -06:00
|
|
|
stream->error = HEXAGRAM_PCAPNG_ERROR_TRUNCATED;
|
2018-12-16 02:11:53 -06:00
|
|
|
|
|
|
|
goto error_io;
|
2019-01-23 21:42:16 -06:00
|
|
|
} else {
|
|
|
|
total += readlen;
|
2018-12-16 02:11:53 -06:00
|
|
|
}
|
|
|
|
|
2019-01-23 21:42:16 -06:00
|
|
|
expected = header.length - sizeof(header) - sizeof(footer);
|
2018-12-16 02:11:53 -06:00
|
|
|
|
2019-01-24 00:20:55 -06:00
|
|
|
if ((readlen = handler(stream, header.type, expected)) < 0) {
|
2018-12-16 02:11:53 -06:00
|
|
|
goto error_io;
|
2019-01-23 21:42:16 -06:00
|
|
|
} else {
|
|
|
|
total += readlen;
|
2018-12-16 02:11:53 -06:00
|
|
|
}
|
|
|
|
|
2019-01-24 00:20:55 -06:00
|
|
|
if ((readlen = read(stream->fd, &footer, sizeof(footer))) < 0) {
|
|
|
|
stream->error = HEXAGRAM_PCAPNG_ERROR_IO;
|
2018-12-16 02:11:53 -06:00
|
|
|
|
|
|
|
goto error_io;
|
|
|
|
} else if (readlen == 0) {
|
|
|
|
goto done;
|
|
|
|
} else if (readlen < sizeof(footer)) {
|
2019-01-24 00:20:55 -06:00
|
|
|
stream->error = HEXAGRAM_PCAPNG_ERROR_TRUNCATED;
|
2018-12-16 02:11:53 -06:00
|
|
|
|
|
|
|
goto error_io;
|
2019-01-23 21:42:16 -06:00
|
|
|
} else if (footer.length != header.length) {
|
2019-01-24 00:20:55 -06:00
|
|
|
stream->error = HEXAGRAM_PCAPNG_ERROR_FORMAT;
|
2018-12-16 03:00:28 -06:00
|
|
|
|
|
|
|
goto error_io;
|
2019-01-23 21:42:16 -06:00
|
|
|
} else {
|
|
|
|
total += readlen;
|
2018-12-16 03:00:28 -06:00
|
|
|
}
|
2018-12-16 02:11:53 -06:00
|
|
|
}
|
|
|
|
|
2019-01-23 21:42:16 -06:00
|
|
|
done:
|
2019-01-24 00:20:55 -06:00
|
|
|
stream->error = HEXAGRAM_PCAPNG_ERROR_OK;
|
2018-12-16 02:11:53 -06:00
|
|
|
|
|
|
|
return total;
|
|
|
|
|
|
|
|
error_io:
|
|
|
|
return -1;
|
|
|
|
}
|