ngofflinereadtest.c [plain text]
#include "pcap-ng.h"
#include <stdio.h>
#include <err.h>
#include <stdlib.h>
#include <string.h>
struct section_info {
struct section_info *next;
struct pcapng_section_header_fields shb;
pcap_t *pcap;
u_int32_t if_count;
struct interface_info *if_list;
};
struct interface_info {
struct interface_info *next;
struct pcapng_interface_description_fields idb;
struct section_info *section_info;
u_int32_t interface_id;
char *if_name;
char *if_desc;
};
struct section_info *section_list = NULL;
struct section_info *current_section = NULL;
int mode_raw = 0;
int mode_block = 0;
#define PAD32(x) (((x) + 3) & ~3)
void hex_and_ascii_print(const char *, const void *, unsigned int , const char *);
struct section_info *
new_section_info(pcap_t *pcap, struct pcapng_section_header_fields *shb)
{
struct section_info *section_info = calloc(1, sizeof(struct section_info));
if (section_info == NULL)
return NULL;
section_info->pcap = pcap;
section_info->shb = *shb;
if (section_list == NULL) {
section_list = section_info;
} else {
section_info->next = section_list;
section_list = section_info;
}
current_section = section_info;
return section_info;
}
void
interface_option_iterator(pcapng_block_t block, struct pcapng_option_info *option_info, void *context)
{
struct interface_info *interface_info = (struct interface_info *)context;
switch (option_info->code) {
case 0:
break;
case 1:
break;
case 2:
interface_info->if_name = malloc(option_info->length + 1);
if (interface_info->if_name == NULL)
break;
snprintf(interface_info->if_name, option_info->length + 1, "%s", option_info->value);
break;
case 3:
interface_info->if_desc = malloc(option_info->length + 1);
if (interface_info->if_desc == NULL)
break;
snprintf(interface_info->if_desc, option_info->length + 1, "%s", option_info->value);
break;
case 4:
break;
case 5:
break;
case 6:
break;
case 7:
break;
case 8:
break;
case 9:
break;
case 10:
break;
case 11:
break;
case 12:
break;
case 13:
break;
case 14:
break;
default:
break;
}
}
struct interface_info *
new_interface_info(struct section_info *section_info, pcapng_block_t block)
{
struct interface_info *interface_info = calloc(1, sizeof(struct interface_info));
if (interface_info == NULL)
return NULL;
interface_info->section_info = section_info;
interface_info->interface_id = section_info->if_count;
section_info->if_count++;
if (section_info->if_list == NULL) {
section_info->if_list = interface_info;
} else {
interface_info->next = section_info->if_list;
section_info->if_list = interface_info;
}
(void) pcnapng_block_iterate_options(block,
interface_option_iterator,
interface_info);
return interface_info;
}
struct interface_info *
find_interface_info_by_id(u_int16_t interface_id)
{
struct interface_info *interface_info;
if (current_section == NULL)
return (NULL);
if (interface_id + 1 > current_section->if_count)
return (NULL);
for (interface_info = current_section->if_list;
interface_info != NULL;
interface_info = interface_info->next) {
if (interface_info->interface_id == interface_id)
return (interface_info);
}
return (NULL);
}
void
block_option_iterator(pcapng_block_t block, struct pcapng_option_info *option_info, void *context)
{
printf(" block_type %u context %p option_code %u value_len %u value_ptr %p\n",
pcap_ng_block_get_type(block), context,
option_info->code, option_info->length,
option_info->value
);
switch (option_info->code) {
case 0:
printf(" opt_endofopt\n");
break;
case 1:
printf(" opt_comment: %-*s\n",
option_info->length, option_info->value);
break;
default:
switch (pcap_ng_block_get_type(block)) {
case PCAPNG_BT_SHB:
switch (option_info->code) {
case 2:
printf(" shb_hardware: %-*s\n",
option_info->length, option_info->value);
break;
case 3:
printf(" shb_os: %-*s\n",
option_info->length, option_info->value);
break;
case 4:
printf(" shb_userappl: %-*s\n",
option_info->length, option_info->value);
break;
default:
printf(" <unkown shb option>\n");
break;
}
break;
case PCAPNG_BT_IDB:
switch (option_info->code) {
case 2:
printf(" if_name: %-*s\n",
option_info->length, option_info->value);
break;
case 3:
printf(" if_desc: %-*s\n",
option_info->length, option_info->value);
break;
case 4:
printf(" if_IPv4addr\n");
break;
case 5:
printf(" if_IPv6addr\n");
break;
case 6:
printf(" if_MACaddr\n");
break;
case 7:
printf(" if_EUIaddr\n");
break;
case 8:
printf(" if_speed\n");
break;
case 9:
printf(" if_tsresol\n");
break;
case 10:
printf(" if_tzone\n");
break;
case 11:
printf(" if_filter %-*s\n",
option_info->length, option_info->value);
break;
case 12:
printf(" if_os %-*s\n",
option_info->length, option_info->value);
break;
case 13:
printf(" if_fcslen\n");
break;
case 14:
printf(" if_tsoffset\n");
break;
default:
printf(" <unkown idb option>\n");
break;
}
break;
case PCAPNG_BT_EPB:
switch (option_info->code) {
case 2:
printf(" epb_flags\n");
break;
case 3:
printf(" epb_hash\n");
break;
case 4:
printf(" epb_dropcount\n");
break;
case PCAPNG_EPB_PIB_INDEX:
printf(" epb_pib\n");
break;
case PCAPNG_EPB_SVC:
printf(" epb_svc\n");
break;
default:
printf(" <unkown epb option>\n");
break;
}
break;
case PCAPNG_BT_SPB:
printf(" <invalid spb option>\n");
break;
case PCAPNG_BT_PB:
switch (option_info->code) {
case 2:
printf(" pack_flags\n");
break;
case 3:
printf(" pack_hash\n");
break;
default:
printf(" <unkown pb option>\n");
break;
}
break;
case PCAPNG_BT_PIB: {
switch (option_info->code) {
case 2:
printf(" proc_name\n");
break;
case 3:
printf(" proc_path\n");
break;
default:
printf(" <unkown pib option>\n");
break;
}
break;
}
case PCAPNG_BT_ISB: {
break;
}
case PCAPNG_BT_NRB: {
break;
}
default:
break;
}
break;
}
if (option_info->value) {
hex_and_ascii_print(" ", option_info->value, option_info->length, "\n");
}
}
void
read_callback(u_char *user, const struct pcap_pkthdr *hdr, const u_char *bytes)
{
pcap_t *pcap = (pcap_t *)user;
struct pcapng_option_info option_info;
u_char *optptr = NULL;
if (mode_raw) {
struct pcapng_block_header *block_header = (struct pcapng_block_header*)bytes;
printf("raw hdr caplen %u len %u\n", hdr->caplen, hdr->len);
printf("#\n# user %p hdr.caplen %u hdr.len %u block_header.blocktype 0x%x block_header.totallength %u\n",
user, hdr->caplen, hdr->len,
block_header->block_type, block_header->total_length);
hex_and_ascii_print("", bytes, block_header->total_length, "\n");
switch (block_header->block_type) {
case PCAPNG_BT_SHB: {
struct pcapng_section_header_fields *shb = (struct pcapng_section_header_fields *)(block_header + 1);
printf("# Section Header Block\n");
printf(" byte_order_magic 0x%x major_version %u minor_version %u section_length %llu\n",
shb->byte_order_magic, shb->major_version, shb->minor_version, shb->section_length);
hex_and_ascii_print("", shb, sizeof(struct pcapng_section_header_fields), "\n");
optptr = (u_char *)(shb + 1);
break;
}
case PCAPNG_BT_IDB: {
struct pcapng_interface_description_fields *idb = (struct pcapng_interface_description_fields *)(block_header + 1);
printf("# Interface Description Block\n");
printf(" linktype %u reserved %u snaplen %u\n",
idb->linktype, idb->reserved, idb->snaplen);
hex_and_ascii_print("", idb, sizeof(struct pcapng_interface_description_fields), "\n");
optptr = (u_char *)(idb + 1);
break;
}
case PCAPNG_BT_EPB: {
struct pcapng_enhanced_packet_fields *epb = (struct pcapng_enhanced_packet_fields *)(block_header + 1);
printf("# Enhanced Packet Block\n");
printf(" interface_id %u timestamp_high %u timestamp_low %u caplen %u len %u\n",
epb->interface_id, epb->timestamp_high, epb->timestamp_low, epb->caplen, epb->len);
hex_and_ascii_print("", epb, sizeof(struct pcapng_enhanced_packet_fields), "\n");
hex_and_ascii_print("", epb + 1, epb->caplen, "\n");
optptr = (u_char *)(epb + 1);
optptr += PAD32(epb->caplen);
break;
}
case PCAPNG_BT_SPB: {
struct pcapng_simple_packet_fields *spb = (struct pcapng_simple_packet_fields *)(block_header + 1);
printf("# Simple Packet Block\n");
printf(" len %u\n",
spb->len);
hex_and_ascii_print("", spb, sizeof(struct pcapng_simple_packet_fields), "\n");
hex_and_ascii_print("", spb + 1, spb->len, "\n");
break;
}
case PCAPNG_BT_PB: {
struct pcapng_packet_fields *pb = (struct pcapng_packet_fields *)(block_header + 1);
printf("# Packet Block\n");
printf(" interface_id %u drops_count %u timestamp_high %u timestamp_low %u caplen %u len %u\n",
pb->interface_id, pb->drops_count, pb->timestamp_high, pb->timestamp_low, pb->caplen, pb->len);
hex_and_ascii_print("", pb, sizeof(struct pcapng_packet_fields), "\n");
hex_and_ascii_print("", pb + 1, pb->caplen, "\n");
break;
}
case PCAPNG_BT_PIB: {
struct pcapng_process_information_fields *pib = (struct pcapng_process_information_fields *)(block_header + 1);
printf("# Process Information Block\n");
printf(" process_id %u\n",
pib->process_id);
hex_and_ascii_print("", pib, sizeof(struct pcapng_process_information_fields), "\n");
break;
}
case PCAPNG_BT_ISB: {
printf("# Interface Statistics Block\n");
break;
}
case PCAPNG_BT_NRB: {
printf("# Name Record Block\n");
break;
}
default:
printf("# Unknown Block\n");
break;
}
if (optptr) {
size_t optlen = block_header->total_length - (optptr - bytes);
hex_and_ascii_print("", optptr, optlen, "\n");
}
}
if (mode_block) {
pcapng_block_t block = pcap_ng_block_alloc_with_raw_block(pcap, (u_char *)bytes);
if (block == NULL) {
printf(" pcap_ng_block_alloc_with_raw_block() failed: %s\n", pcap_geterr(pcap));
return;
}
switch (pcap_ng_block_get_type(block)) {
case PCAPNG_BT_SHB: {
struct pcapng_section_header_fields *shb = pcap_ng_get_section_header_fields(block);
printf("# Section Header Block\n");
printf(" byte_order_magic 0x%x major_version %u minor_version %u section_length %llu\n",
shb->byte_order_magic, shb->major_version, shb->minor_version, shb->section_length);
(void)new_section_info(pcap, shb);
break;
}
case PCAPNG_BT_IDB: {
struct pcapng_interface_description_fields *idb = pcap_ng_get_interface_description_fields(block);
printf("# Interface Description Block\n");
printf(" linktype %u reserved %u snaplen %u\n",
idb->linktype, idb->reserved, idb->snaplen);
if (pcap_ng_block_get_option(block, PCAPNG_IF_NAME, &option_info) == 1)
if (option_info.value)
printf(" interface name: %s\n", option_info.value);
(void)new_interface_info(current_section, block);
break;
}
case PCAPNG_BT_EPB: {
struct pcapng_enhanced_packet_fields *epb = pcap_ng_get_enhanced_packet_fields(block);
printf("# Enhanced Packet Block\n");
printf(" interface_id %u timestamp_high %u timestamp_low %u caplen %u len %u\n",
epb->interface_id, epb->timestamp_high, epb->timestamp_low, epb->caplen, epb->len);
break;
}
case PCAPNG_BT_SPB: {
struct pcapng_simple_packet_fields *spb = pcap_ng_get_simple_packet_fields(block);
printf("# Simple Packet Block\n");
printf(" len %u\n",
spb->len);
break;
}
case PCAPNG_BT_PB: {
struct pcapng_packet_fields *pb = pcap_ng_get_packet_fields(block);
printf("# Packet Block\n");
printf(" interface_id %u drops_count %u timestamp_high %u timestamp_low %u caplen %u len %u\n",
pb->interface_id, pb->drops_count, pb->timestamp_high, pb->timestamp_low, pb->caplen, pb->len);
break;
}
case PCAPNG_BT_PIB: {
struct pcapng_process_information_fields *pib = pcap_ng_get_process_information_fields(block);
printf("# Process Information Block\n");
printf(" process_id %u\n",
pib->process_id);
if (pcap_ng_block_get_option(block, PCAPNG_PIB_NAME, &option_info) == 1)
if (option_info.value)
printf(" process name: %s\n", option_info.value);
break;
}
case PCAPNG_BT_ISB: {
printf("# Interface Statistics Block\n");
break;
}
case PCAPNG_BT_NRB: {
printf("# Name Record Block\n");
break;
}
default:
printf("# Unknown Block\n");
break;
}
pcnapng_block_iterate_options(block, block_option_iterator, NULL);
}
}
#define SWAPLONG(y) \
((((y)&0xff)<<24) | (((y)&0xff00)<<8) | (((y)&0xff0000)>>8) | (((y)>>24)&0xff))
#define SWAPSHORT(y) \
( (((y)&0xff)<<8) | ((u_short)((y)&0xff00)>>8) )
#define SWAPLONGLONG(y) \
(SWAPLONG((unsigned long)(y)) << 32 | SWAPLONG((unsigned long)((y) >> 32)))
int main(int argc, const char * argv[])
{
int i;
char errbuf[PCAP_ERRBUF_SIZE];
#if 0
u_int64_t section_length;
section_length = 0x0004000300020001;
printf("section_length %llx\n", section_length);
u_int32_t lowlong = (u_int32_t)section_length;
printf("lowlong %x\n", lowlong);
u_int32_t hilong = (u_int32_t)(section_length >> 32);
printf("hilong %x\n", hilong);
u_int64_t swapped = SWAPLONGLONG(section_length);
printf("swapped %llx\n", swapped);
int nums[11] = { 0, 1, 2, 3, 4, 5, -1, -2, -3, -4, -5 };
for (i = 0; i < 11; i++) {
printf("PCAPNG_ROUNDUP32(%d): %d\n", nums[i], PCAPNG_ROUNDUP32(nums[i]));
}
#endif
for (i = 1; i < argc; i++) {
if (strcmp(argv[i], "-raw") == 0) {
mode_raw = 1;
continue;
}
if (strcmp(argv[i], "-block") == 0) {
mode_block = 1;
continue;
}
if (mode_block == 0 && mode_raw == 0)
mode_block = 1;
printf("#\n# opening %s\n#\n", argv[i]);
pcap_t *pcap = pcap_ng_open_offline(argv[i], errbuf);
if (pcap == NULL) {
warnx("pcap_ng_open_offline(%s) failed: %s\n",
argv[i], errbuf);
continue;
}
int result = pcap_dispatch(pcap, -1, read_callback, (u_char *)pcap);
if (result < 0) {
warnx("pcap_dispatch failed: %s\n",
pcap_statustostr(result));
} else {
printf("# read %d packets\n", result);
}
pcap_close(pcap);
}
return 0;
}