hexagram/examples/pcapread.c
2019-01-23 21:42:16 -06:00

130 lines
2.7 KiB
C

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <inttypes.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <hexagram/pcapng.h>
static void usage(int argc, char **argv, const char *message, ...) {
if (message) {
va_list args;
va_start(args, message);
vfprintf(stderr, message, args);
va_end(args);
}
fprintf(stderr, "usage: %s [file.pcapng]\n", argv[0]);
exit(1);
}
static ssize_t handle_block(int fd, uint32_t type, size_t len, int *error) {
hexagram_pcapng_packet header;
uint8_t packet[65535];
ssize_t readlen,
remaining = len;
/*
* If we've received anything other than a packet block, then seek past
* that data and move on.
*/
if (type != HEXAGRAM_PCAPNG_BLOCK_PACKET) {
printf("Read block type %08"PRIx32" len %zu\n",
type, len);
if (lseek(fd, len, SEEK_CUR) < 0) {
perror("lseek()");
goto error_io;
}
return 0;
}
/*
* 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) {
perror("read()");
goto error_io;
} else {
remaining -= readlen;
}
/*
* Read the packet data into our scratchpad.
*/
if ((readlen = read(fd, &packet, header.caplen)) < 0) {
perror("read()");
goto error_io;
} else {
remaining -= readlen;
}
printf("Read packet %"PRIu32" bytes time hi %"PRIu32" lo %"PRIu32"\n",
header.caplen, header.timestamp[0], header.timestamp[1]);
/*
* 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) {
perror("lseek()");
goto error_io;
}
*error = HEXAGRAM_PCAPNG_ERROR_OK;
return 0;
error_io:
*error = HEXAGRAM_PCAPNG_ERROR_IO;
return -1;
}
int main(int argc, char **argv) {
int fd, error;
if (argc == 1) {
fd = fileno(stdin);
} else if (argc == 2) {
if ((fd = open(argv[1], O_RDONLY)) < 0) {
perror("open()");
goto error_open;
}
} else {
usage(argc, argv, NULL);
}
if (hexagram_pcapng_stream_read(fd, handle_block, &error) < 0) {
perror("hexagram_pcapng_stream_read()");
goto error_io;
}
if (argc == 2) {
close(fd);
}
return 0;
error_io:
if (argc == 2) {
close(fd);
}
error_open:
return 1;
}