Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[API] add functions to be able to get packet's savefile offset #491

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions pcap-int.h
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,9 @@ struct pcap {
int activated; /* true if the capture is really started */
int oldstyle; /* if we're opening with pcap_open_live() */

long lastpkt_offset; /* last packet offset in save file */
long current_offset; /* current offset in save file */

struct pcap_opt opt;

/*
Expand Down
22 changes: 22 additions & 0 deletions pcap.c
Original file line number Diff line number Diff line change
Expand Up @@ -503,6 +503,28 @@ struct pcap_if_list {
pcap_if_t *beginning;
};

const u_char *
pcap_next_with_file_offset(pcap_t *p, struct pcap_pkthdr *pkt_header,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a version of pcap_next() with additional information, and inherit's pcap_next()s broken-by-design problems. Don't bother with it.

long *file_offset)
{
const u_char *ret = pcap_next(p, pkt_header);

// sf_offset is set to -1 if live capture
*file_offset = (p->rfile != NULL ? p->lastpkt_offset : -1);
return ret;
}

int
pcap_next_ex_with_file_offset(pcap_t *p, struct pcap_pkthdr **pkt_header,
const u_char **pkt_data, long *file_offset)
{
int ret = pcap_next_ex(p, pkt_header, pkt_data);

// sf_offset is set to -1 if live capture
*file_offset = (p->rfile != NULL ? p->lastpkt_offset : -1);
return ret;
}

static struct capture_source_type {
int (*findalldevs_op)(pcap_if_list_t *, char *);
pcap_t *(*create_op)(const char *, char *, int *);
Expand Down
2 changes: 2 additions & 0 deletions pcap/pcap.h
Original file line number Diff line number Diff line change
Expand Up @@ -444,6 +444,8 @@ PCAP_API int pcap_loop(pcap_t *, int, pcap_handler, u_char *);
PCAP_API int pcap_dispatch(pcap_t *, int, pcap_handler, u_char *);
PCAP_API const u_char *pcap_next(pcap_t *, struct pcap_pkthdr *);
PCAP_API int pcap_next_ex(pcap_t *, struct pcap_pkthdr **, const u_char **);
PCAP_API int pcap_next_ex_with_sf_offset(pcap_t *, struct pcap_pkthdr **,
const u_char **, long *);
PCAP_API void pcap_breakloop(pcap_t *);
PCAP_API int pcap_stats(pcap_t *, struct pcap_stat *);
PCAP_API int pcap_setfilter(pcap_t *, struct bpf_program *);
Expand Down
27 changes: 24 additions & 3 deletions pcap_next_ex.3pcap
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@
.\"
.TH PCAP_NEXT_EX 3PCAP "25 July 2018"
.SH NAME
pcap_next_ex, pcap_next \- read the next packet from a pcap_t
pcap_next_ex, pcap_next_ex_with_sf_offset, pcap_next
\- read the next packet from a pcap_t
.SH SYNOPSIS
.nf
.ft B
Expand All @@ -30,7 +31,14 @@ pcap_next_ex, pcap_next \- read the next packet from a pcap_t
int pcap_next_ex(pcap_t *p, struct pcap_pkthdr **pkt_header,
.ti +8
const u_char **pkt_data);
.ft B
int pcap_next_ex_with_sf_offset(pcap_t *p, struct pcap_pkthdr **pkt_header,
.ti +8
const u_char **pkt_data, long *sf_offset);
.BR
.ft B
const u_char *pcap_next(pcap_t *p, struct pcap_pkthdr *h);
.LP
.ft
.fi
.SH DESCRIPTION
Expand All @@ -48,6 +56,7 @@ argument is set to point to the data in the packet. The
and the packet data are not to be freed by the caller, and are not
guaranteed to be valid after the next call to
.BR pcap_next_ex() ,
.BR pcap_next_ex_with_sf_offset() ,
.BR pcap_next() ,
.BR pcap_loop (3PCAP),
or
Expand All @@ -65,6 +74,7 @@ pointer to the data in that packet. The
packet data is not to be freed by the caller, and is not
guaranteed to be valid after the next call to
.BR pcap_next_ex() ,
.BR pcap_next_ex_with_sf_offset() ,
.BR pcap_next() ,
.BR pcap_loop() ,
or
Expand All @@ -76,6 +86,15 @@ structure pointed to by
.I h
is filled in with the appropriate values for the packet.
.PP
.B pcap_next_ex_with_sf_offset()
is the same as
.B pcap_next_ex()
except that it takes an additional
.I sf_offset
pointer argument. The pointed variable will be set to the extracted
packet's ``savefile`` offset. If the packets are being read from a live capture, the
pointed variable will be set to -1.
.PP
The bytes of data from the packet begin with a link-layer header. The
format of the link-layer header is indicated by the return value of the
.BR pcap_datalink (3PCAP)
Expand Down Expand Up @@ -112,8 +131,10 @@ have some other data link type, such as
for Ethernet.
.SH RETURN VALUE
.B pcap_next_ex()
returns 1 if the packet was read without problems, 0 if packets are
being read from a live capture and the packet buffer timeout expired,
and
.B pcap_next_ex_with_sf_offset()
both return 1 if the packet was read without problems, 0
if packets are being read from a live capture and the timeout expired,
.B PCAP_ERROR
if an error occurred while reading the packet, and
.B PCAP_ERROR_BREAK
Expand Down
16 changes: 14 additions & 2 deletions sf-pcap.c
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,6 @@ pcap_check_header(bpf_u_int32 magic, FILE *fp, u_int precision, char *errbuf,
}
p->linktype = linktype_to_dlt(LT_LINKTYPE(hdr.linktype));
p->linktype_ext = LT_LINKTYPE_EXT(hdr.linktype);

p->next_packet_op = pcap_next_packet;

ps = p->priv;
Expand Down Expand Up @@ -417,7 +416,10 @@ pcap_check_header(bpf_u_int32 magic, FILE *fp, u_int precision, char *errbuf,
}

p->cleanup_op = sf_cleanup;

/*
* If savefile, initialize current_offset to pcap file's body
*/
p->current_offset = sizeof(struct pcap_file_header);
return (p);
}

Expand Down Expand Up @@ -716,6 +718,16 @@ pcap_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **data)
if (p->swapped)
swap_pseudo_headers(p->linktype, hdr, *data);

if (p->rfile != NULL) {
/*
* If savefile:
* - we set lastpkt_offset to the offset of the packet we just read
* - we set the current_offset to the end of this packet
*/
p->current_offset += ps->hdrsize;
p->lastpkt_offset = p->current_offset;
p->current_offset += hdr->caplen;
}
return (0);
}

Expand Down
49 changes: 45 additions & 4 deletions sf-pcapng.c
Original file line number Diff line number Diff line change
Expand Up @@ -947,6 +947,12 @@ pcap_ng_check_header(bpf_u_int32 magic, FILE *fp, u_int precision, char *errbuf,
bhdrp->block_type = magic;
bhdrp->total_length = total_length;
shbp->byte_order_magic = byte_order_magic;

/*
* We initialize current_offset to the end of the SHB
*/
p->current_offset = bhdrp->total_length;

if (read_bytes(fp,
(u_char *)p->buffer + (sizeof(magic) + sizeof(total_length) + sizeof(byte_order_magic)),
total_length - (sizeof(magic) + sizeof(total_length) + sizeof(byte_order_magic)),
Expand Down Expand Up @@ -996,6 +1002,12 @@ pcap_ng_check_header(bpf_u_int32 magic, FILE *fp, u_int precision, char *errbuf,
}
if (status == -1)
goto fail; /* error */

/*
* Add to current_offset the length of the section we just read
*/
p->current_offset += cursor.data_remaining + sizeof(struct block_header)
+ sizeof(struct block_trailer);
switch (cursor.block_type) {

case BT_IDB:
Expand Down Expand Up @@ -1070,7 +1082,6 @@ pcap_ng_check_header(bpf_u_int32 magic, FILE *fp, u_int precision, char *errbuf,

p->next_packet_op = pcap_ng_next_packet;
p->cleanup_op = pcap_ng_cleanup;

return (p);

fail:
Expand Down Expand Up @@ -1124,6 +1135,23 @@ pcap_ng_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **data)
return (1); /* EOF */
if (status == -1)
return (-1); /* error */
if (p->rfile != NULL) {
/*
* We set lastpkt_offset to current offset and we add the length of
* the section we just read to the current_offset
*
* When we will read a packet block (from any kind), we will add to
* lastpkt_offset the length of a block header and the length of our
* packet block's header
* This way, the lastpkt_offset variable will be set to the
* packet savefile's offset
* offset in his original savefile.
*/
p->lastpkt_offset = p->current_offset;
p->current_offset += cursor.data_remaining
+ sizeof(struct block_header)
+ sizeof(struct block_trailer);
}
switch (cursor.block_type) {

case BT_EPB:
Expand All @@ -1132,7 +1160,7 @@ pcap_ng_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **data)
* EPB.
*/
epbp = get_from_block_data(&cursor, sizeof(*epbp),
p->errbuf);
p->errbuf);
if (epbp == NULL)
return (-1); /* error */

Expand All @@ -1153,6 +1181,10 @@ pcap_ng_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **data)
t = ((uint64_t)epbp->timestamp_high) << 32 |
epbp->timestamp_low;
}
if (p->rfile != NULL) {
p->lastpkt_offset += sizeof(struct block_header)
+ sizeof(struct enhanced_packet_block);
}
goto found;

case BT_SPB:
Expand All @@ -1161,7 +1193,7 @@ pcap_ng_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **data)
* SPB.
*/
spbp = get_from_block_data(&cursor, sizeof(*spbp),
p->errbuf);
p->errbuf);
if (spbp == NULL)
return (-1); /* error */

Expand Down Expand Up @@ -1189,6 +1221,11 @@ pcap_ng_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **data)
if (hdr->caplen > (bpf_u_int32)p->snapshot)
hdr->caplen = p->snapshot;
t = 0; /* no time stamps */

if (p->rfile != NULL) {
p->lastpkt_offset += sizeof(struct block_header)
+ sizeof(struct simple_packet_block);
}
goto found;

case BT_PB:
Expand All @@ -1197,7 +1234,7 @@ pcap_ng_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **data)
* PB.
*/
pbp = get_from_block_data(&cursor, sizeof(*pbp),
p->errbuf);
p->errbuf);
if (pbp == NULL)
return (-1); /* error */

Expand All @@ -1218,6 +1255,10 @@ pcap_ng_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **data)
t = ((uint64_t)pbp->timestamp_high) << 32 |
pbp->timestamp_low;
}
if (p->rfile != NULL) {
p->lastpkt_offset += sizeof(struct block_header)
+ sizeof(struct packet_block);
}
goto found;

case BT_IDB:
Expand Down