diff --git a/examples/pcapread.c b/examples/pcapread.c index bd7721a..09ecf95 100644 --- a/examples/pcapread.c +++ b/examples/pcapread.c @@ -23,9 +23,11 @@ static void usage(int argc, char **argv, const char *message, ...) { exit(1); } -static ssize_t handle_block(int fd, uint32_t type, size_t len, int *error) { +static ssize_t handle_block(hexagram_pcapng_stream *stream, + uint32_t type, + size_t len) { hexagram_pcapng_packet header; - uint8_t packet[65535]; + uint8_t body[65535]; ssize_t readlen, remaining = len; @@ -38,7 +40,7 @@ static ssize_t handle_block(int fd, uint32_t type, size_t len, int *error) { printf("Read block type %08"PRIx32" len %zu\n", type, len); - if (lseek(fd, len, SEEK_CUR) < 0) { + if (lseek(stream->fd, len, SEEK_CUR) < 0) { perror("lseek()"); goto error_io; @@ -51,7 +53,7 @@ static ssize_t handle_block(int fd, uint32_t type, size_t len, int *error) { * Otherwise, read the packet block header so that we may determine the * size of the payload to continue to read. */ - if ((readlen = read(fd, &header, sizeof(header))) < 0) { + if ((readlen = read(stream->fd, &header, sizeof(header))) < 0) { perror("read()"); goto error_io; @@ -60,9 +62,9 @@ static ssize_t handle_block(int fd, uint32_t type, size_t len, int *error) { } /* - * Read the packet data into our scratchpad. + * Read the packet body into our scratchpad. */ - if ((readlen = read(fd, &packet, header.caplen)) < 0) { + if ((readlen = read(stream->fd, &body, header.caplen)) < 0) { perror("read()"); goto error_io; @@ -77,24 +79,25 @@ static ssize_t handle_block(int fd, uint32_t type, size_t len, int *error) { * The remaining data here should be pcapng option values, and since we do * not presently require them, we can safely seek past them. */ - if (lseek(fd, remaining, SEEK_CUR) < 0) { + if (lseek(stream->fd, remaining, SEEK_CUR) < 0) { perror("lseek()"); goto error_io; } - *error = HEXAGRAM_PCAPNG_ERROR_OK; + stream->error = HEXAGRAM_PCAPNG_ERROR_OK; return 0; error_io: - *error = HEXAGRAM_PCAPNG_ERROR_IO; + stream->error = HEXAGRAM_PCAPNG_ERROR_IO; return -1; } int main(int argc, char **argv) { - int fd, error; + int fd; + hexagram_pcapng_stream *stream; if (argc == 1) { fd = fileno(stdin); @@ -106,21 +109,31 @@ int main(int argc, char **argv) { } } else { usage(argc, argv, NULL); + exit(1); } - if (hexagram_pcapng_stream_read(fd, handle_block, &error) < 0) { + if ((stream = hexagram_pcapng_stream_open_fd(fd)) < 0) { + goto error_pcapng_stream_open_fd; + } + + if (hexagram_pcapng_stream_read(stream, handle_block) < 0) { perror("hexagram_pcapng_stream_read()"); - goto error_io; + goto error_pcapng_stream_read; } + hexagram_pcapng_stream_destroy(stream); + if (argc == 2) { close(fd); } return 0; -error_io: +error_pcapng_stream_read: + hexagram_pcapng_stream_destroy(stream); + +error_pcapng_stream_open_fd: if (argc == 2) { close(fd); } diff --git a/include/hexagram/pcapng.h b/include/hexagram/pcapng.h index df6fbe8..ff319b4 100644 --- a/include/hexagram/pcapng.h +++ b/include/hexagram/pcapng.h @@ -11,6 +11,28 @@ #include #include #include -#include + +typedef struct _hexagram_pcapng_stream { + int fd, + error; + + uint8_t if_tsresol; +} hexagram_pcapng_stream; + +typedef ssize_t (hexagram_pcapng_block_handler)(hexagram_pcapng_stream *, + uint32_t type, + size_t length); + +typedef ssize_t (hexagram_pcapng_option_handler)(hexagram_pcapng_stream *, + hexagram_pcapng_block_header *, + uint16_t code, + uint16_t length); + +hexagram_pcapng_stream *hexagram_pcapng_stream_open_fd(int fd); + +void hexagram_pcapng_stream_destroy(hexagram_pcapng_stream *stream); + +ssize_t hexagram_pcapng_stream_read(hexagram_pcapng_stream *stream, + hexagram_pcapng_block_handler *handler); #endif /* _HEXAGRAM_PCAPNG_H */ diff --git a/include/hexagram/pcapng/block.h b/include/hexagram/pcapng/block.h index bbfe44a..0c6c68d 100644 --- a/include/hexagram/pcapng/block.h +++ b/include/hexagram/pcapng/block.h @@ -20,9 +20,4 @@ typedef struct _hexagram_pcapng_block_footer { uint32_t length; } hexagram_pcapng_block_footer; -typedef ssize_t (hexagram_pcapng_block_handler)(int fd, - uint32_t type, - size_t length, - int *error); - #endif /* _HEXAGRAM_PCAPNG_BLOCK_H */ diff --git a/include/hexagram/pcapng/option.h b/include/hexagram/pcapng/option.h index fe302de..07ef203 100644 --- a/include/hexagram/pcapng/option.h +++ b/include/hexagram/pcapng/option.h @@ -16,14 +16,4 @@ typedef struct _hexagram_pcapng_option { length; } hexagram_pcapng_option; -typedef ssize_t (hexagram_pcapng_option_handler)(int fd, - uint16_t code, - uint16_t length, - int *error); - -ssize_t hexagram_pcapng_option_read(int fd, - hexagram_pcapng_option_handler *handler, - size_t len, - int *error); - #endif /* _HEXAGRAM_PCAPNG_OPTION_H */ diff --git a/include/hexagram/pcapng/stream.h b/include/hexagram/pcapng/stream.h deleted file mode 100644 index 38d9ec4..0000000 --- a/include/hexagram/pcapng/stream.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef _HEXAGRAM_PCAPNG_STREAM_H -#define _HEXAGRAM_PCAPNG_STREAM_H - -/* - * pcapng stream reading facilities - */ -typedef struct _hexagram_pcapng_stream hexagram_pcapng_stream; - -ssize_t hexagram_pcapng_stream_read(int fd, - hexagram_pcapng_block_handler *handler, - int *error); - -#endif /* _HEXAGRAM_PCAPNG_STREAM_H */ diff --git a/src/pcapng.c b/src/pcapng.c index 4abe82b..1c0222d 100644 --- a/src/pcapng.c +++ b/src/pcapng.c @@ -1,5 +1,6 @@ #include #include +#include #include #include #include @@ -7,50 +8,69 @@ #include -struct _hexagram_pcapng_stream { - int fd; - uint32_t if_count; - hexagram_pcapng_section *section; - hexagram_pcapng_if *ifs; - hexagram_pcapng_if_stats *stats; -}; +static ssize_t handle_option(hexagram_pcapng_stream *stream, + hexagram_pcapng_block_header *header, + uint16_t code, + uint16_t len) { + ssize_t readlen; + uint8_t data[65535]; -ssize_t hexagram_pcapng_option_read(int fd, - hexagram_pcapng_option_handler *handler, - size_t len, - int *error) { - hexagram_pcapng_option header; + if ((readlen = read(stream->fd, data, (size_t)len)) < 0) { + goto error_io; + } + + if (header->type == HEXAGRAM_PCAPNG_BLOCK_IF) { + if (code == HEXAGRAM_PCAPNG_OPTION_IF_TSRESOL) { + stream->if_tsresol = data[0]; + } + } + + stream->error = HEXAGRAM_PCAPNG_ERROR_OK; + + return readlen; + +error_io: + stream->error = HEXAGRAM_PCAPNG_ERROR_IO; + + return -1; +} + +static ssize_t read_options(hexagram_pcapng_stream *stream, + hexagram_pcapng_block_header *header, + hexagram_pcapng_option_handler *handler, + size_t len) { + hexagram_pcapng_option option; ssize_t total = 0; while (total < len) { ssize_t readlen; - if ((readlen = read(fd, &header, sizeof(header))) < 0) { - *error = HEXAGRAM_PCAPNG_ERROR_IO; + if ((readlen = read(stream->fd, &option, sizeof(option))) < 0) { + stream->error = HEXAGRAM_PCAPNG_ERROR_IO; goto error_io; } else { total += readlen; } - if ((readlen = handler(fd, header.code, header.length, error)) < 0) { + if ((readlen = handler(stream, header, option.code, option.length)) < 0) { goto error_io; - } else if (readlen < header.length) { - *error = HEXAGRAM_PCAPNG_ERROR_TRUNCATED; + } else if (readlen < option.length) { + stream->error = HEXAGRAM_PCAPNG_ERROR_TRUNCATED; goto error_io; } else { total += readlen; } - if ((readlen = lseek(fd, header.length % sizeof(uint32_t), SEEK_CUR)) < 0) { + if ((readlen = lseek(stream->fd, option.length % sizeof(uint32_t), SEEK_CUR)) < 0) { goto error_io; } else { total += readlen; } } - *error = HEXAGRAM_PCAPNG_ERROR_OK; + stream->error = HEXAGRAM_PCAPNG_ERROR_OK; return total; @@ -65,7 +85,9 @@ hexagram_pcapng_stream *hexagram_pcapng_stream_open_fd(int fd) { goto error_malloc_stream; } - stream->if_count = 0; + stream->fd = fd; + stream->error = HEXAGRAM_PCAPNG_ERROR_OK; + stream->if_tsresol = 0; return stream; @@ -73,9 +95,14 @@ error_malloc_stream: return NULL; } -ssize_t hexagram_pcapng_stream_read(int fd, - hexagram_pcapng_block_handler *handler, - int *error) { +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) { hexagram_pcapng_block_header header; hexagram_pcapng_block_footer footer; ssize_t total = 0; @@ -84,14 +111,14 @@ ssize_t hexagram_pcapng_stream_read(int fd, size_t expected; ssize_t readlen; - if ((readlen = read(fd, &header, sizeof(header))) < 0) { - *error = HEXAGRAM_PCAPNG_ERROR_IO; + if ((readlen = read(stream->fd, &header, sizeof(header))) < 0) { + stream->error = HEXAGRAM_PCAPNG_ERROR_IO; goto error_io; } else if (readlen == 0) { goto done; } else if (readlen < sizeof(header)) { - *error = HEXAGRAM_PCAPNG_ERROR_TRUNCATED; + stream->error = HEXAGRAM_PCAPNG_ERROR_TRUNCATED; goto error_io; } else { @@ -100,24 +127,24 @@ ssize_t hexagram_pcapng_stream_read(int fd, expected = header.length - sizeof(header) - sizeof(footer); - if ((readlen = handler(fd, header.type, expected, error)) < 0) { + if ((readlen = handler(stream, header.type, expected)) < 0) { goto error_io; } else { total += readlen; } - if ((readlen = read(fd, &footer, sizeof(footer))) < 0) { - *error = HEXAGRAM_PCAPNG_ERROR_IO; + if ((readlen = read(stream->fd, &footer, sizeof(footer))) < 0) { + stream->error = HEXAGRAM_PCAPNG_ERROR_IO; goto error_io; } else if (readlen == 0) { goto done; } else if (readlen < sizeof(footer)) { - *error = HEXAGRAM_PCAPNG_ERROR_TRUNCATED; + stream->error = HEXAGRAM_PCAPNG_ERROR_TRUNCATED; goto error_io; } else if (footer.length != header.length) { - *error = HEXAGRAM_PCAPNG_ERROR_FORMAT; + stream->error = HEXAGRAM_PCAPNG_ERROR_FORMAT; goto error_io; } else { @@ -126,7 +153,7 @@ ssize_t hexagram_pcapng_stream_read(int fd, } done: - *error = HEXAGRAM_PCAPNG_ERROR_OK; + stream->error = HEXAGRAM_PCAPNG_ERROR_OK; return total;