From Anders: Add support for options in the SHB.
From me: Some whitespace changes. svn path=/trunk/; revision=41026
This commit is contained in:
parent
7e51e80fe0
commit
68204c94a4
32
dumpcap.c
32
dumpcap.c
|
@ -2559,9 +2559,23 @@ capture_loop_init_output(capture_options *capture_opts, loop_data *ld, char *err
|
|||
if (ld->pdh) {
|
||||
if (capture_opts->use_pcapng) {
|
||||
char appname[100];
|
||||
GString *runtime_info_str;
|
||||
|
||||
runtime_info_str = g_string_new("");
|
||||
get_runtime_version_info(runtime_info_str, NULL);
|
||||
|
||||
g_snprintf(appname, sizeof(appname), "Dumpcap " VERSION "%s", wireshark_svnversion);
|
||||
successful = libpcap_write_session_header_block(ld->pdh, appname, &ld->bytes_written, &err);
|
||||
successful = libpcap_write_session_header_block(ld->pdh,
|
||||
NULL, /* Comment*/
|
||||
NULL, /* HW*/
|
||||
runtime_info_str->str, /* OS*/
|
||||
appname,
|
||||
-1, /* section_length */
|
||||
&ld->bytes_written,
|
||||
&err);
|
||||
|
||||
g_string_free(runtime_info_str, TRUE);
|
||||
|
||||
for (i = 0; successful && (i < capture_opts->ifaces->len); i++) {
|
||||
interface_opts = g_array_index(capture_opts->ifaces, interface_options, i);
|
||||
pcap_opts = g_array_index(ld->pcaps, pcap_options *, i);
|
||||
|
@ -2994,9 +3008,23 @@ do_file_switch_or_stop(capture_options *capture_opts,
|
|||
global_ld.bytes_written = 0;
|
||||
if (capture_opts->use_pcapng) {
|
||||
char appname[100];
|
||||
GString *runtime_info_str;
|
||||
|
||||
runtime_info_str = g_string_new("");
|
||||
get_runtime_version_info(runtime_info_str, NULL);
|
||||
|
||||
g_snprintf(appname, sizeof(appname), "Dumpcap " VERSION "%s", wireshark_svnversion);
|
||||
successful = libpcap_write_session_header_block(global_ld.pdh, appname, &(global_ld.bytes_written), &global_ld.err);
|
||||
successful = libpcap_write_session_header_block(global_ld.pdh,
|
||||
NULL, /* Comment */
|
||||
NULL, /* HW */
|
||||
runtime_info_str->str, /* OS */
|
||||
appname,
|
||||
-1, /* section_length */
|
||||
&(global_ld.bytes_written),
|
||||
&global_ld.err);
|
||||
|
||||
g_string_free(runtime_info_str, TRUE);
|
||||
|
||||
for (i = 0; successful && (i < capture_opts->ifaces->len); i++) {
|
||||
interface_opts = g_array_index(capture_opts->ifaces, interface_options, i);
|
||||
pcap_opts = g_array_index(global_ld.pcaps, pcap_options *, i);
|
||||
|
|
71
pcapio.c
71
pcapio.c
|
@ -160,7 +160,7 @@ struct option {
|
|||
#define OPT_ENDOFOPT 0
|
||||
#define OPT_COMMENT 1 /* currently not used */
|
||||
#define SHB_HARDWARE 2 /* currently not used */
|
||||
#define SHB_OS 3 /* currently not used */
|
||||
#define SHB_OS 3
|
||||
#define SHB_USERAPPL 4
|
||||
#define IDB_NAME 2
|
||||
#define IDB_FILTER 11
|
||||
|
@ -268,7 +268,11 @@ libpcap_write_packet(FILE *fp, const struct pcap_pkthdr *phdr, const u_char *pd,
|
|||
|
||||
gboolean
|
||||
libpcap_write_session_header_block(FILE *fp,
|
||||
const char *comment,
|
||||
const char *hw,
|
||||
const char *os,
|
||||
const char *appname,
|
||||
guint64 section_length,
|
||||
long *bytes_written,
|
||||
int *err)
|
||||
{
|
||||
|
@ -276,12 +280,34 @@ libpcap_write_session_header_block(FILE *fp,
|
|||
struct option option;
|
||||
guint32 block_total_length;
|
||||
const guint32 padding = 0;
|
||||
gboolean have_options = FALSE;
|
||||
|
||||
/* Size of base header */
|
||||
block_total_length = sizeof(struct shb) +
|
||||
sizeof(guint32);
|
||||
if ((strlen(appname) > 0) && (strlen(appname) < G_MAXUINT16)) {
|
||||
block_total_length += 2 * sizeof(struct option) +
|
||||
if ((comment)&&(strlen(comment) > 0) && (strlen(comment) < G_MAXUINT16)) {
|
||||
block_total_length += sizeof(struct option) +
|
||||
(guint16)(ADD_PADDING(strlen(comment) + 1));
|
||||
have_options = TRUE;
|
||||
}
|
||||
if ((hw)&&(strlen(hw) > 0) && (strlen(hw) < G_MAXUINT16)) {
|
||||
block_total_length += sizeof(struct option) +
|
||||
(guint16)(ADD_PADDING(strlen(hw) + 1));
|
||||
have_options = TRUE;
|
||||
}
|
||||
if ((os)&&(strlen(os) > 0) && (strlen(os) < G_MAXUINT16)) {
|
||||
block_total_length += sizeof(struct option) +
|
||||
(guint16)(ADD_PADDING(strlen(os) + 1));
|
||||
have_options = TRUE;
|
||||
}
|
||||
if ((appname)&&(strlen(appname) > 0) && (strlen(appname) < G_MAXUINT16)) {
|
||||
block_total_length += sizeof(struct option) +
|
||||
(guint16)(ADD_PADDING(strlen(appname) + 1));
|
||||
have_options = TRUE;
|
||||
}
|
||||
/* If we have options add size of end-of-options */
|
||||
if(have_options){
|
||||
block_total_length += sizeof(struct option);
|
||||
}
|
||||
/* write shb header */
|
||||
shb.block_type = SECTION_HEADER_BLOCK_TYPE;
|
||||
|
@ -289,10 +315,40 @@ libpcap_write_session_header_block(FILE *fp,
|
|||
shb.byte_order_magic = PCAPNG_MAGIC;
|
||||
shb.major_version = PCAPNG_MAJOR_VERSION;
|
||||
shb.minor_version = PCAPNG_MINOR_VERSION;
|
||||
shb.section_length = -1;
|
||||
shb.section_length = section_length;
|
||||
WRITE_DATA(fp, &shb, sizeof(struct shb), *bytes_written, err);
|
||||
|
||||
if ((strlen(appname) > 0) && (strlen(appname) < G_MAXUINT16)) {
|
||||
if ((comment)&&(strlen(comment) > 0) && (strlen(comment) < G_MAXUINT16)) {
|
||||
/* write opt_comment options */
|
||||
option.type = OPT_COMMENT;
|
||||
option.value_length = (guint16)(strlen(comment) + 1);
|
||||
WRITE_DATA(fp, &option, sizeof(struct option), *bytes_written, err);
|
||||
WRITE_DATA(fp, comment, strlen(comment) + 1, *bytes_written, err);
|
||||
if ((strlen(comment) + 1) % 4) {
|
||||
WRITE_DATA(fp, &padding, 4 - (strlen(hw) + 1) % 4, *bytes_written, err);
|
||||
}
|
||||
}
|
||||
if ((hw)&&(strlen(hw) > 0) && (strlen(hw) < G_MAXUINT16)) {
|
||||
/* write shb_hardware options */
|
||||
option.type = SHB_HARDWARE;
|
||||
option.value_length = (guint16)(strlen(hw) + 1);
|
||||
WRITE_DATA(fp, &option, sizeof(struct option), *bytes_written, err);
|
||||
WRITE_DATA(fp, hw, strlen(hw) + 1, *bytes_written, err);
|
||||
if ((strlen(hw) + 1) % 4) {
|
||||
WRITE_DATA(fp, &padding, 4 - (strlen(hw) + 1) % 4, *bytes_written, err);
|
||||
}
|
||||
}
|
||||
if ((os)&&(strlen(os) > 0) && (strlen(os) < G_MAXUINT16)) {
|
||||
/* write shb_os options */
|
||||
option.type = SHB_OS;
|
||||
option.value_length = (guint16)(strlen(os) + 1);
|
||||
WRITE_DATA(fp, &option, sizeof(struct option), *bytes_written, err);
|
||||
WRITE_DATA(fp, os, strlen(os) + 1, *bytes_written, err);
|
||||
if ((strlen(os) + 1) % 4) {
|
||||
WRITE_DATA(fp, &padding, 4 - (strlen(os) + 1) % 4, *bytes_written, err);
|
||||
}
|
||||
}
|
||||
if ((appname)&&(strlen(appname) > 0) && (strlen(appname) < G_MAXUINT16)) {
|
||||
/* write shb_userappl options */
|
||||
option.type = SHB_USERAPPL;
|
||||
option.value_length = (guint16)(strlen(appname) + 1);
|
||||
|
@ -301,11 +357,14 @@ libpcap_write_session_header_block(FILE *fp,
|
|||
if ((strlen(appname) + 1) % 4) {
|
||||
WRITE_DATA(fp, &padding, 4 - (strlen(appname) + 1) % 4, *bytes_written, err);
|
||||
}
|
||||
/* write last option */
|
||||
}
|
||||
if(have_options){
|
||||
/* write end of options */
|
||||
option.type = OPT_ENDOFOPT;
|
||||
option.value_length = 0;
|
||||
WRITE_DATA(fp, &option, sizeof(struct option), *bytes_written, err);
|
||||
}
|
||||
|
||||
/* write the trailing block total length */
|
||||
WRITE_DATA(fp, &block_total_length, sizeof(guint32), *bytes_written, err);
|
||||
return TRUE;
|
||||
|
|
25
pcapio.h
25
pcapio.h
|
@ -25,25 +25,40 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/* Returns a FILE * to write to on success, NULL on failure */
|
||||
/** Returns a FILE * to write to on success, NULL on failure */
|
||||
extern FILE *
|
||||
libpcap_fdopen(int fd, int *err);
|
||||
|
||||
/* Write the file header to a dump file.
|
||||
/** Write the file header to a dump file.
|
||||
Returns TRUE on success, FALSE on failure.
|
||||
Sets "*err" to an error code, or 0 for a short write, on failure*/
|
||||
extern gboolean
|
||||
libpcap_write_file_header(FILE *fp, int linktype, int snaplen, long *bytes_written, int *err);
|
||||
|
||||
/* Write a record for a packet to a dump file.
|
||||
/** Write a record for a packet to a dump file.
|
||||
Returns TRUE on success, FALSE on failure. */
|
||||
extern gboolean
|
||||
libpcap_write_packet(FILE *fp, const struct pcap_pkthdr *phdr, const u_char *pd,
|
||||
long *bytes_written, int *err);
|
||||
|
||||
/** Write a section header block (SHB)
|
||||
*
|
||||
*/
|
||||
extern gboolean
|
||||
libpcap_write_session_header_block(FILE *fp,
|
||||
const char *appname,
|
||||
libpcap_write_session_header_block(FILE *fp, /**< File pointer */
|
||||
const char *comment, /**< Comment on the section, Optinon 1 opt_comment
|
||||
* A UTF-8 string containing a comment that is associated to the current block.
|
||||
*/
|
||||
const char *hw, /**< HW, Optinon 2 shb_hardware
|
||||
* An UTF-8 string containing the description of the hardware used to create this section.
|
||||
*/
|
||||
const char *os, /**< Operating system name, Optinon 3 shb_os
|
||||
* An UTF-8 string containing the name of the operating system used to create this section.
|
||||
*/
|
||||
const char *appname, /**< Application name, Optinon 4 shb_userappl
|
||||
* An UTF-8 string containing the name of the application used to create this section.
|
||||
*/
|
||||
guint64 section_length,
|
||||
long *bytes_written,
|
||||
int *err);
|
||||
|
||||
|
|
|
@ -171,7 +171,7 @@ typedef struct pcapng_option_header_s {
|
|||
guint16 option_code;
|
||||
guint16 option_length;
|
||||
/* ... x bytes Option Body ... */
|
||||
/* ... Padding ... */
|
||||
/* ... Padding ... */
|
||||
} pcapng_option_header_t;
|
||||
|
||||
/* Block types */
|
||||
|
@ -399,10 +399,10 @@ pcapng_read_section_header_block(FILE_T fh, gboolean first_block,
|
|||
{
|
||||
int bytes_read;
|
||||
int block_read;
|
||||
int to_read;
|
||||
int to_read, opt_cont_buf_len;
|
||||
pcapng_section_header_block_t shb;
|
||||
pcapng_option_header_t oh;
|
||||
char option_content[100]; /* XXX - size might need to be increased, if we see longer options */
|
||||
char *option_content = NULL; /* Allocate as large as the options block */
|
||||
|
||||
|
||||
/* read block content */
|
||||
|
@ -486,18 +486,23 @@ pcapng_read_section_header_block(FILE_T fh, gboolean first_block,
|
|||
/* Option defaults */
|
||||
wblock->data.section.opt_comment = NULL;
|
||||
wblock->data.section.shb_hardware = NULL;
|
||||
wblock->data.section.shb_os = NULL;
|
||||
wblock->data.section.shb_os = NULL;
|
||||
wblock->data.section.shb_user_appl = NULL;
|
||||
|
||||
/* Options */
|
||||
errno = WTAP_ERR_CANT_READ;
|
||||
to_read = bh->block_total_length
|
||||
- (int)sizeof(pcapng_block_header_t)
|
||||
- (int)sizeof (pcapng_section_header_block_t)
|
||||
- (int)sizeof(bh->block_total_length);
|
||||
to_read = bh->block_total_length -
|
||||
(int)sizeof(pcapng_block_header_t) -
|
||||
(int)sizeof(pcapng_section_header_block_t) -
|
||||
(int)sizeof(bh->block_total_length);
|
||||
/* Allocate enough memory to hold all options */
|
||||
opt_cont_buf_len = to_read;
|
||||
option_content = g_malloc(opt_cont_buf_len);
|
||||
pcapng_debug1("pcapng_read_section_header_block: Options %u bytes", to_read);
|
||||
while(to_read > 0) {
|
||||
/* read option */
|
||||
bytes_read = pcapng_read_option(fh, pn, &oh, option_content, sizeof(option_content), err, err_info);
|
||||
pcapng_debug1("pcapng_read_section_header_block: Options %u bytes remaining", to_read);
|
||||
bytes_read = pcapng_read_option(fh, pn, &oh, option_content, opt_cont_buf_len, err, err_info);
|
||||
if (bytes_read <= 0) {
|
||||
pcapng_debug0("pcapng_read_section_header_block: failed to read option");
|
||||
return bytes_read;
|
||||
|
@ -515,32 +520,32 @@ pcapng_read_section_header_block(FILE_T fh, gboolean first_block,
|
|||
to_read = 0;
|
||||
break;
|
||||
case(1): /* opt_comment */
|
||||
if(oh.option_length > 0 && oh.option_length < sizeof(option_content)) {
|
||||
wblock->data.section.opt_comment = g_strndup(option_content, sizeof(option_content));
|
||||
if(oh.option_length > 0 && oh.option_length < opt_cont_buf_len) {
|
||||
wblock->data.section.opt_comment = g_strndup(option_content, oh.option_length);
|
||||
pcapng_debug1("pcapng_read_section_header_block: opt_comment %s", wblock->data.section.opt_comment);
|
||||
} else {
|
||||
pcapng_debug1("pcapng_read_section_header_block: opt_comment length %u seems strange", oh.option_length);
|
||||
}
|
||||
break;
|
||||
case(2): /* shb_hardware */
|
||||
if(oh.option_length > 0 && oh.option_length < sizeof(option_content)) {
|
||||
wblock->data.section.shb_hardware = g_strndup(option_content, sizeof(option_content));
|
||||
if(oh.option_length > 0 && oh.option_length < opt_cont_buf_len) {
|
||||
wblock->data.section.shb_hardware = g_strndup(option_content, oh.option_length);
|
||||
pcapng_debug1("pcapng_read_section_header_block: shb_hardware %s", wblock->data.section.shb_hardware);
|
||||
} else {
|
||||
pcapng_debug1("pcapng_read_section_header_block: shb_hardware length %u seems strange", oh.option_length);
|
||||
}
|
||||
break;
|
||||
case(3): /* shb_os */
|
||||
if(oh.option_length > 0 && oh.option_length < sizeof(option_content)) {
|
||||
wblock->data.section.shb_os = g_strndup(option_content, sizeof(option_content));
|
||||
if(oh.option_length > 0 && oh.option_length < opt_cont_buf_len) {
|
||||
wblock->data.section.shb_os = g_strndup(option_content, oh.option_length);
|
||||
pcapng_debug1("pcapng_read_section_header_block: shb_os %s", wblock->data.section.shb_os);
|
||||
} else {
|
||||
pcapng_debug1("pcapng_read_section_header_block: shb_os length %u seems strange", oh.option_length);
|
||||
pcapng_debug2("pcapng_read_section_header_block: shb_os length %u seems strange, opt buffsize %u", oh.option_length,to_read);
|
||||
}
|
||||
break;
|
||||
case(4): /* shb_userappl */
|
||||
if(oh.option_length > 0 && oh.option_length < sizeof(option_content)) {
|
||||
wblock->data.section.shb_user_appl = g_strndup(option_content, sizeof(option_content));
|
||||
if(oh.option_length > 0 && oh.option_length < opt_cont_buf_len) {
|
||||
wblock->data.section.shb_user_appl = g_strndup(option_content, oh.option_length);
|
||||
pcapng_debug1("pcapng_read_section_header_block: shb_userappl %s", wblock->data.section.shb_user_appl);
|
||||
} else {
|
||||
pcapng_debug1("pcapng_read_section_header_block: shb_userappl length %u seems strange", oh.option_length);
|
||||
|
@ -551,6 +556,7 @@ pcapng_read_section_header_block(FILE_T fh, gboolean first_block,
|
|||
oh.option_code, oh.option_length);
|
||||
}
|
||||
}
|
||||
g_free(option_content);
|
||||
|
||||
if (pn->interface_data != NULL) {
|
||||
g_array_free(pn->interface_data, TRUE);
|
||||
|
@ -637,10 +643,10 @@ pcapng_read_if_descr_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t *pn,
|
|||
|
||||
/* Options */
|
||||
errno = WTAP_ERR_CANT_READ;
|
||||
to_read = bh->block_total_length
|
||||
- (int)sizeof(pcapng_block_header_t)
|
||||
- (int)sizeof (pcapng_interface_description_block_t)
|
||||
- (int)sizeof(bh->block_total_length);
|
||||
to_read = bh->block_total_length -
|
||||
(int)sizeof(pcapng_block_header_t) -
|
||||
(int)sizeof (pcapng_interface_description_block_t) -
|
||||
(int)sizeof(bh->block_total_length);
|
||||
while (to_read > 0) {
|
||||
/* read option */
|
||||
bytes_read = pcapng_read_option(fh, pn, &oh, option_content, sizeof(option_content), err, err_info);
|
||||
|
@ -926,10 +932,10 @@ pcapng_read_packet_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t *pn, wta
|
|||
* epb_dropcount 4
|
||||
*/
|
||||
errno = WTAP_ERR_CANT_READ;
|
||||
to_read = block_total_length
|
||||
- (int)sizeof(pcapng_block_header_t)
|
||||
- block_read /* fixed and variable part, including padding */
|
||||
- (int)sizeof(bh->block_total_length);
|
||||
to_read = block_total_length -
|
||||
(int)sizeof(pcapng_block_header_t) -
|
||||
block_read - /* fixed and variable part, including padding */
|
||||
(int)sizeof(bh->block_total_length);
|
||||
while(to_read > 0) {
|
||||
/* read option */
|
||||
bytes_read = pcapng_read_option(fh, pn, &oh, option_content, sizeof(option_content), err, err_info);
|
||||
|
@ -1254,10 +1260,10 @@ pcapng_read_interface_statistics_block(FILE_T fh, pcapng_block_header_t *bh, pca
|
|||
|
||||
/* Options */
|
||||
errno = WTAP_ERR_CANT_READ;
|
||||
to_read = bh->block_total_length
|
||||
- sizeof(pcapng_block_header_t)
|
||||
- block_read /* fixed and variable part, including padding */
|
||||
- sizeof(bh->block_total_length);
|
||||
to_read = bh->block_total_length -
|
||||
sizeof(pcapng_block_header_t) -
|
||||
block_read - /* fixed and variable part, including padding */
|
||||
sizeof(bh->block_total_length);
|
||||
while(to_read > 0) {
|
||||
/* read option */
|
||||
bytes_read = pcapng_read_option(fh, pn, &oh, option_content, sizeof(option_content), err, err_info);
|
||||
|
@ -2114,8 +2120,8 @@ static gboolean pcapng_dump(wtap_dumper *wdh,
|
|||
ts = (((guint64)phdr->ts.secs) * 1000000) + (phdr->ts.nsecs / 1000);
|
||||
|
||||
/* Split the 64-bit timestamp into two 32-bit pieces */
|
||||
wblock.data.packet.ts_high = (guint32)(ts >> 32);
|
||||
wblock.data.packet.ts_low = (guint32)ts;
|
||||
wblock.data.packet.ts_high = (guint32)(ts >> 32);
|
||||
wblock.data.packet.ts_low = (guint32)ts;
|
||||
|
||||
wblock.data.packet.cap_len = phdr->caplen;
|
||||
wblock.data.packet.packet_len = phdr->len;
|
||||
|
|
Loading…
Reference in New Issue