diff --git a/examples/pcapread.c b/examples/pcapread.c index d3f1fd5..2990f42 100644 --- a/examples/pcapread.c +++ b/examples/pcapread.c @@ -23,7 +23,7 @@ static void usage(int argc, char **argv, const char *message, ...) { exit(1); } -static int handle_block(int fd, uint32_t type, size_t len) { +static int handle_block(int fd, uint32_t type, size_t len, int *error) { hexagram_pcapng_packet header; uint8_t packet[65535]; @@ -83,9 +83,13 @@ static int handle_block(int fd, uint32_t type, size_t len) { goto error_io; } + *error = HEXAGRAM_PCAPNG_ERROR_OK; + return 0; error_io: + *error = HEXAGRAM_PCAPNG_ERROR_IO; + return -1; } diff --git a/include/hexagram/pcapng.h b/include/hexagram/pcapng.h index 037a1c9..df6fbe8 100644 --- a/include/hexagram/pcapng.h +++ b/include/hexagram/pcapng.h @@ -11,20 +11,6 @@ #include #include #include - -/* - * pcapng stream reading facilities - */ -typedef struct _hexagram_pcapng_stream hexagram_pcapng_stream; - -typedef int (hexagram_pcapng_block_handler)(int fd, - uint32_t type, - size_t length); - -ssize_t hexagram_pcapng_stream_read(int fd, - hexagram_pcapng_block_handler *handler, - int *error); - - +#include #endif /* _HEXAGRAM_PCAPNG_H */ diff --git a/include/hexagram/pcapng/block.h b/include/hexagram/pcapng/block.h index 0c6c68d..bbfe44a 100644 --- a/include/hexagram/pcapng/block.h +++ b/include/hexagram/pcapng/block.h @@ -20,4 +20,9 @@ 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/error.h b/include/hexagram/pcapng/error.h index 1f6109d..b725698 100644 --- a/include/hexagram/pcapng/error.h +++ b/include/hexagram/pcapng/error.h @@ -8,8 +8,7 @@ typedef enum { HEXAGRAM_PCAPNG_ERROR_OK = 0, HEXAGRAM_PCAPNG_ERROR_IO = 1, HEXAGRAM_PCAPNG_ERROR_TRUNCATED = 2, - HEXAGRAM_PCAPNG_ERROR_FORMAT = 3, - HEXAGRAM_PCAPNG_ERROR_HANDLER = 4 + HEXAGRAM_PCAPNG_ERROR_FORMAT = 3 } hexagram_pcapng_error; #endif /* _HEXAGRAM_PCAPNG_ERROR_H */ diff --git a/include/hexagram/pcapng/option.h b/include/hexagram/pcapng/option.h index 07ef203..43acd14 100644 --- a/include/hexagram/pcapng/option.h +++ b/include/hexagram/pcapng/option.h @@ -16,4 +16,13 @@ typedef struct _hexagram_pcapng_option { length; } hexagram_pcapng_option; +typedef ssize_t (hexagram_pcapng_option_handler)(int fd, + uint16_t code, + uint16_t length); + +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 new file mode 100644 index 0000000..38d9ec4 --- /dev/null +++ b/include/hexagram/pcapng/stream.h @@ -0,0 +1,13 @@ +#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 910ef85..92cef51 100644 --- a/src/pcapng.c +++ b/src/pcapng.c @@ -15,6 +15,47 @@ struct _hexagram_pcapng_stream { hexagram_pcapng_if_stats *stats; }; +ssize_t hexagram_pcapng_option_read(int fd, + hexagram_pcapng_option_handler *handler, + size_t len, + int *error) { + hexagram_pcapng_option header; + ssize_t total = 0; + + while (total < len) { + size_t expected; + ssize_t readlen; + + if ((readlen = read(fd, &header, sizeof(header))) < 0) { + *error = HEXAGRAM_PCAPNG_ERROR_IO; + + goto error_io; + } else { + total += readlen; + } + + expected = header.length + (header.length % sizeof(uint32_t)); + + if ((readlen = handler(fd, header.code, expected, error)) < 0) { + goto error_io; + } else if (readlen < expected) { + *error = HEXAGRAM_PCAPNG_ERROR_TRUNCATED; + + goto error_io; + } else { + total += readlen; + } + } + +done: + *error = HEXAGRAM_PCAPNG_ERROR_OK; + + return total; + +error_io: + return -1; +} + hexagram_pcapng_stream *hexagram_pcapng_stream_open_fd(int fd) { hexagram_pcapng_stream *stream; @@ -56,9 +97,7 @@ ssize_t hexagram_pcapng_stream_read(fd, handler, error) total += readlen; - if (handler(fd, header.type, header.length - sizeof(header) - sizeof(footer)) < 0) { - *error = HEXAGRAM_PCAPNG_ERROR_HANDLER; - + if (handler(fd, header.type, header.length - sizeof(header) - sizeof(footer), error) < 0) { goto error_io; }