1*8f3e7eeaSChristopher Kilgour /* -*- c -*- */ 2*8f3e7eeaSChristopher Kilgour /* 3*8f3e7eeaSChristopher Kilgour * Copyright 2014 Christopher D. Kilgour techie AT whiterocker.com 4*8f3e7eeaSChristopher Kilgour * 5*8f3e7eeaSChristopher Kilgour * This file is part of libbtbb 6*8f3e7eeaSChristopher Kilgour * 7*8f3e7eeaSChristopher Kilgour * This program is free software; you can redistribute it and/or modify 8*8f3e7eeaSChristopher Kilgour * it under the terms of the GNU General Public License as published by 9*8f3e7eeaSChristopher Kilgour * the Free Software Foundation; either version 2, or (at your option) 10*8f3e7eeaSChristopher Kilgour * any later version. 11*8f3e7eeaSChristopher Kilgour * 12*8f3e7eeaSChristopher Kilgour * This program is distributed in the hope that it will be useful, 13*8f3e7eeaSChristopher Kilgour * but WITHOUT ANY WARRANTY; without even the implied warranty of 14*8f3e7eeaSChristopher Kilgour * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15*8f3e7eeaSChristopher Kilgour * GNU General Public License for more details. 16*8f3e7eeaSChristopher Kilgour * 17*8f3e7eeaSChristopher Kilgour * You should have received a copy of the GNU General Public License 18*8f3e7eeaSChristopher Kilgour * along with libbtbb; see the file COPYING. If not, write to 19*8f3e7eeaSChristopher Kilgour * the Free Software Foundation, Inc., 51 Franklin Street, 20*8f3e7eeaSChristopher Kilgour * Boston, MA 02110-1301, USA. 21*8f3e7eeaSChristopher Kilgour */ 22*8f3e7eeaSChristopher Kilgour 23*8f3e7eeaSChristopher Kilgour #include "pcapng.h" 24*8f3e7eeaSChristopher Kilgour 25*8f3e7eeaSChristopher Kilgour #include <errno.h> 26*8f3e7eeaSChristopher Kilgour #include <fcntl.h> 27*8f3e7eeaSChristopher Kilgour #include <string.h> 28*8f3e7eeaSChristopher Kilgour #include <sys/mman.h> 29*8f3e7eeaSChristopher Kilgour #include <sys/stat.h> 30*8f3e7eeaSChristopher Kilgour #include <sys/types.h> 31*8f3e7eeaSChristopher Kilgour #include <unistd.h> 32*8f3e7eeaSChristopher Kilgour 33*8f3e7eeaSChristopher Kilgour static option_header padopt = { 34*8f3e7eeaSChristopher Kilgour .option_code = 0xffff, 35*8f3e7eeaSChristopher Kilgour }; 36*8f3e7eeaSChristopher Kilgour 37*8f3e7eeaSChristopher Kilgour PCAPNG_RESULT pcapng_create( PCAPNG_HANDLE * handle, 38*8f3e7eeaSChristopher Kilgour const char * filename, 39*8f3e7eeaSChristopher Kilgour const option_header * section_options, 40*8f3e7eeaSChristopher Kilgour const size_t section_options_space, 41*8f3e7eeaSChristopher Kilgour const uint16_t link_type, 42*8f3e7eeaSChristopher Kilgour const uint32_t snaplen, 43*8f3e7eeaSChristopher Kilgour const option_header * interface_options, 44*8f3e7eeaSChristopher Kilgour const size_t interface_options_space ) 45*8f3e7eeaSChristopher Kilgour { 46*8f3e7eeaSChristopher Kilgour PCAPNG_RESULT retval = PCAPNG_OK; 47*8f3e7eeaSChristopher Kilgour int PGSZ = getpagesize( ); 48*8f3e7eeaSChristopher Kilgour size_t zeroes = 0, result = -1; 49*8f3e7eeaSChristopher Kilgour 50*8f3e7eeaSChristopher Kilgour handle->section_header = NULL; 51*8f3e7eeaSChristopher Kilgour handle->interface_description = NULL; 52*8f3e7eeaSChristopher Kilgour handle->section_header_size = handle->next_section_option_offset = 53*8f3e7eeaSChristopher Kilgour handle->interface_description_size = 54*8f3e7eeaSChristopher Kilgour handle->next_interface_option_offset = 0; 55*8f3e7eeaSChristopher Kilgour 56*8f3e7eeaSChristopher Kilgour handle->fd = open( filename, O_RDWR|O_CREAT|O_EXCL, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP ); 57*8f3e7eeaSChristopher Kilgour if (handle->fd == -1) { 58*8f3e7eeaSChristopher Kilgour switch( errno ) { 59*8f3e7eeaSChristopher Kilgour case EEXIST: 60*8f3e7eeaSChristopher Kilgour retval = PCAPNG_FILE_EXISTS; 61*8f3e7eeaSChristopher Kilgour break; 62*8f3e7eeaSChristopher Kilgour case EMFILE: 63*8f3e7eeaSChristopher Kilgour case ENFILE: 64*8f3e7eeaSChristopher Kilgour retval = PCAPNG_TOO_MANY_FILES_OPEN; 65*8f3e7eeaSChristopher Kilgour break; 66*8f3e7eeaSChristopher Kilgour case ENOMEM: 67*8f3e7eeaSChristopher Kilgour case ENOSPC: 68*8f3e7eeaSChristopher Kilgour retval = PCAPNG_NO_MEMORY; 69*8f3e7eeaSChristopher Kilgour break; 70*8f3e7eeaSChristopher Kilgour default: 71*8f3e7eeaSChristopher Kilgour retval = PCAPNG_FILE_NOT_ALLOWED; 72*8f3e7eeaSChristopher Kilgour } 73*8f3e7eeaSChristopher Kilgour } 74*8f3e7eeaSChristopher Kilgour 75*8f3e7eeaSChristopher Kilgour if (retval == PCAPNG_OK) { 76*8f3e7eeaSChristopher Kilgour /* section header */ 77*8f3e7eeaSChristopher Kilgour const section_header_block shb = { 78*8f3e7eeaSChristopher Kilgour .block_type = BLOCK_TYPE_SECTION_HEADER, 79*8f3e7eeaSChristopher Kilgour .block_total_length = 28, 80*8f3e7eeaSChristopher Kilgour .byte_order_magic = SECTION_HEADER_BYTE_ORDER_MAGIC, 81*8f3e7eeaSChristopher Kilgour .major_version = 1, 82*8f3e7eeaSChristopher Kilgour .minor_version = 0, 83*8f3e7eeaSChristopher Kilgour .section_length = (uint64_t) -1, 84*8f3e7eeaSChristopher Kilgour }; 85*8f3e7eeaSChristopher Kilgour handle->section_header_size = sizeof( shb ); 86*8f3e7eeaSChristopher Kilgour result = write( handle->fd, &shb, sizeof( shb ) ); 87*8f3e7eeaSChristopher Kilgour /* write initial section options */ 88*8f3e7eeaSChristopher Kilgour while ((result != -1) && 89*8f3e7eeaSChristopher Kilgour section_options && 90*8f3e7eeaSChristopher Kilgour section_options->option_code && 91*8f3e7eeaSChristopher Kilgour section_options->option_length) { 92*8f3e7eeaSChristopher Kilgour size_t paddedsz = 4*((section_options->option_length+3)/4); 93*8f3e7eeaSChristopher Kilgour zeroes = paddedsz - section_options->option_length; 94*8f3e7eeaSChristopher Kilgour result = write( handle->fd, section_options, 4+section_options->option_length ); 95*8f3e7eeaSChristopher Kilgour while ((zeroes > 0) && (result != -1)) { 96*8f3e7eeaSChristopher Kilgour result = write( handle->fd, "\0", 1 ); 97*8f3e7eeaSChristopher Kilgour zeroes--; 98*8f3e7eeaSChristopher Kilgour } 99*8f3e7eeaSChristopher Kilgour section_options = (const option_header *) &((uint8_t *)section_options)[4+paddedsz]; 100*8f3e7eeaSChristopher Kilgour handle->section_header_size += (4+paddedsz); 101*8f3e7eeaSChristopher Kilgour } 102*8f3e7eeaSChristopher Kilgour handle->next_section_option_offset = handle->section_header_size; 103*8f3e7eeaSChristopher Kilgour } 104*8f3e7eeaSChristopher Kilgour 105*8f3e7eeaSChristopher Kilgour if (result == -1) { 106*8f3e7eeaSChristopher Kilgour retval = PCAPNG_FILE_WRITE_ERROR; 107*8f3e7eeaSChristopher Kilgour } 108*8f3e7eeaSChristopher Kilgour else { 109*8f3e7eeaSChristopher Kilgour /* determine the size of section header with desired space */ 110*8f3e7eeaSChristopher Kilgour zeroes = (size_t) PGSZ*((handle->section_header_size + 4 + 111*8f3e7eeaSChristopher Kilgour section_options_space + PGSZ - 1)/PGSZ) - 112*8f3e7eeaSChristopher Kilgour handle->section_header_size; 113*8f3e7eeaSChristopher Kilgour handle->section_header_size += zeroes; 114*8f3e7eeaSChristopher Kilgour while ((zeroes > 0) && (result != -1)) { 115*8f3e7eeaSChristopher Kilgour result = write( handle->fd, "\0", 1 ); 116*8f3e7eeaSChristopher Kilgour zeroes--; 117*8f3e7eeaSChristopher Kilgour } 118*8f3e7eeaSChristopher Kilgour 119*8f3e7eeaSChristopher Kilgour /* mmap the section header */ 120*8f3e7eeaSChristopher Kilgour handle->section_header = mmap( NULL, handle->section_header_size, 121*8f3e7eeaSChristopher Kilgour PROT_READ|PROT_WRITE, 122*8f3e7eeaSChristopher Kilgour MAP_SHARED, 123*8f3e7eeaSChristopher Kilgour handle->fd, 0 ); 124*8f3e7eeaSChristopher Kilgour } 125*8f3e7eeaSChristopher Kilgour 126*8f3e7eeaSChristopher Kilgour if (retval == PCAPNG_OK) { 127*8f3e7eeaSChristopher Kilgour if (result == -1) { 128*8f3e7eeaSChristopher Kilgour retval = PCAPNG_FILE_WRITE_ERROR; 129*8f3e7eeaSChristopher Kilgour } 130*8f3e7eeaSChristopher Kilgour else if (handle->section_header == MAP_FAILED) { 131*8f3e7eeaSChristopher Kilgour retval = PCAPNG_MMAP_FAILED; 132*8f3e7eeaSChristopher Kilgour } 133*8f3e7eeaSChristopher Kilgour else { 134*8f3e7eeaSChristopher Kilgour /* write the interface header */ 135*8f3e7eeaSChristopher Kilgour const interface_description_block idb = { 136*8f3e7eeaSChristopher Kilgour .block_type = BLOCK_TYPE_INTERFACE, 137*8f3e7eeaSChristopher Kilgour .block_total_length = 0, 138*8f3e7eeaSChristopher Kilgour .link_type = link_type, 139*8f3e7eeaSChristopher Kilgour .snaplen = snaplen 140*8f3e7eeaSChristopher Kilgour }; 141*8f3e7eeaSChristopher Kilgour handle->interface_description_size = sizeof( idb ); 142*8f3e7eeaSChristopher Kilgour result = write( handle->fd, &idb, sizeof( idb ) ); 143*8f3e7eeaSChristopher Kilgour 144*8f3e7eeaSChristopher Kilgour /* write interface options */ 145*8f3e7eeaSChristopher Kilgour while ((result != -1) && 146*8f3e7eeaSChristopher Kilgour interface_options && 147*8f3e7eeaSChristopher Kilgour interface_options->option_code && 148*8f3e7eeaSChristopher Kilgour interface_options->option_length) { 149*8f3e7eeaSChristopher Kilgour size_t paddedsz = 4*((interface_options->option_length+3)/4); 150*8f3e7eeaSChristopher Kilgour zeroes = paddedsz - interface_options->option_length; 151*8f3e7eeaSChristopher Kilgour result = write( handle->fd, interface_options, 4+interface_options->option_length ); 152*8f3e7eeaSChristopher Kilgour while ((zeroes > 0) && (result != -1)) { 153*8f3e7eeaSChristopher Kilgour result = write( handle->fd, "\0", 1 ); 154*8f3e7eeaSChristopher Kilgour zeroes--; 155*8f3e7eeaSChristopher Kilgour } 156*8f3e7eeaSChristopher Kilgour interface_options = (const option_header *) &((uint8_t *)interface_options)[4+paddedsz]; 157*8f3e7eeaSChristopher Kilgour handle->interface_description_size += (4+paddedsz); 158*8f3e7eeaSChristopher Kilgour } 159*8f3e7eeaSChristopher Kilgour handle->next_interface_option_offset = handle->interface_description_size; 160*8f3e7eeaSChristopher Kilgour } 161*8f3e7eeaSChristopher Kilgour } 162*8f3e7eeaSChristopher Kilgour 163*8f3e7eeaSChristopher Kilgour if (retval == PCAPNG_OK) { 164*8f3e7eeaSChristopher Kilgour if (result == -1) { 165*8f3e7eeaSChristopher Kilgour retval = PCAPNG_FILE_WRITE_ERROR; 166*8f3e7eeaSChristopher Kilgour } 167*8f3e7eeaSChristopher Kilgour else { 168*8f3e7eeaSChristopher Kilgour /* determine the size of interface description with desired space */ 169*8f3e7eeaSChristopher Kilgour zeroes = (size_t) PGSZ*((handle->interface_description_size + 4 + 170*8f3e7eeaSChristopher Kilgour interface_options_space + PGSZ - 1)/PGSZ) - 171*8f3e7eeaSChristopher Kilgour handle->interface_description_size; 172*8f3e7eeaSChristopher Kilgour handle->interface_description_size += zeroes; 173*8f3e7eeaSChristopher Kilgour while ((zeroes > 0) && (result != -1)) { 174*8f3e7eeaSChristopher Kilgour result = write( handle->fd, "\0", 1 ); 175*8f3e7eeaSChristopher Kilgour zeroes--; 176*8f3e7eeaSChristopher Kilgour } 177*8f3e7eeaSChristopher Kilgour 178*8f3e7eeaSChristopher Kilgour /* mmap the interface description */ 179*8f3e7eeaSChristopher Kilgour handle->interface_description = mmap( NULL, handle->interface_description_size, 180*8f3e7eeaSChristopher Kilgour PROT_READ|PROT_WRITE, 181*8f3e7eeaSChristopher Kilgour MAP_SHARED, 182*8f3e7eeaSChristopher Kilgour handle->fd, 183*8f3e7eeaSChristopher Kilgour handle->section_header_size ); 184*8f3e7eeaSChristopher Kilgour } 185*8f3e7eeaSChristopher Kilgour } 186*8f3e7eeaSChristopher Kilgour 187*8f3e7eeaSChristopher Kilgour if (retval == PCAPNG_OK) { 188*8f3e7eeaSChristopher Kilgour if (result == -1) { 189*8f3e7eeaSChristopher Kilgour retval = PCAPNG_FILE_WRITE_ERROR; 190*8f3e7eeaSChristopher Kilgour } 191*8f3e7eeaSChristopher Kilgour else if (handle->interface_description == MAP_FAILED) { 192*8f3e7eeaSChristopher Kilgour retval = PCAPNG_MMAP_FAILED; 193*8f3e7eeaSChristopher Kilgour } 194*8f3e7eeaSChristopher Kilgour else { 195*8f3e7eeaSChristopher Kilgour uint8_t * dest = &((uint8_t *)handle->section_header)[handle->next_section_option_offset]; 196*8f3e7eeaSChristopher Kilgour padopt.option_length = handle->section_header_size - 197*8f3e7eeaSChristopher Kilgour handle->next_section_option_offset - 12; 198*8f3e7eeaSChristopher Kilgour 199*8f3e7eeaSChristopher Kilgour /* Add padding options, update the header sizes. */ 200*8f3e7eeaSChristopher Kilgour (void) memcpy( dest, &padopt, sizeof( padopt ) ); 201*8f3e7eeaSChristopher Kilgour handle->section_header->block_total_length = 202*8f3e7eeaSChristopher Kilgour (uint32_t) handle->section_header_size; 203*8f3e7eeaSChristopher Kilgour ((uint32_t*)handle->section_header)[handle->section_header_size/4-1] = 204*8f3e7eeaSChristopher Kilgour (uint32_t) handle->section_header_size; 205*8f3e7eeaSChristopher Kilgour 206*8f3e7eeaSChristopher Kilgour padopt.option_length = handle->interface_description_size - 207*8f3e7eeaSChristopher Kilgour handle->next_interface_option_offset - 12; 208*8f3e7eeaSChristopher Kilgour dest = &((uint8_t *)handle->interface_description)[handle->next_interface_option_offset]; 209*8f3e7eeaSChristopher Kilgour (void) memcpy( dest, &padopt, sizeof( padopt ) ); 210*8f3e7eeaSChristopher Kilgour handle->interface_description->block_total_length = 211*8f3e7eeaSChristopher Kilgour (uint32_t) handle->interface_description_size; 212*8f3e7eeaSChristopher Kilgour ((uint32_t*)handle->interface_description)[handle->interface_description_size/4-1] = 213*8f3e7eeaSChristopher Kilgour (uint32_t) handle->interface_description_size; 214*8f3e7eeaSChristopher Kilgour 215*8f3e7eeaSChristopher Kilgour handle->section_header->section_length = (uint64_t) handle->interface_description_size; 216*8f3e7eeaSChristopher Kilgour } 217*8f3e7eeaSChristopher Kilgour } 218*8f3e7eeaSChristopher Kilgour 219*8f3e7eeaSChristopher Kilgour if (retval != PCAPNG_OK) { 220*8f3e7eeaSChristopher Kilgour (void) pcapng_close( handle ); 221*8f3e7eeaSChristopher Kilgour } 222*8f3e7eeaSChristopher Kilgour 223*8f3e7eeaSChristopher Kilgour return retval; 224*8f3e7eeaSChristopher Kilgour } 225*8f3e7eeaSChristopher Kilgour 226*8f3e7eeaSChristopher Kilgour PCAPNG_RESULT pcapng_append_section_option( PCAPNG_HANDLE * handle, 227*8f3e7eeaSChristopher Kilgour const option_header * section_option ) 228*8f3e7eeaSChristopher Kilgour { 229*8f3e7eeaSChristopher Kilgour PCAPNG_RESULT retval = PCAPNG_OK; 230*8f3e7eeaSChristopher Kilgour if (handle && (handle->fd != -1)) { 231*8f3e7eeaSChristopher Kilgour if (handle->section_header && 232*8f3e7eeaSChristopher Kilgour (handle->section_header != MAP_FAILED) && 233*8f3e7eeaSChristopher Kilgour handle->next_section_option_offset && 234*8f3e7eeaSChristopher Kilgour section_option) { 235*8f3e7eeaSChristopher Kilgour size_t copysz = 4+section_option->option_length; 236*8f3e7eeaSChristopher Kilgour uint8_t * dest = &((uint8_t *)handle->section_header)[handle->next_section_option_offset]; 237*8f3e7eeaSChristopher Kilgour (void) memcpy( dest, section_option, copysz ); 238*8f3e7eeaSChristopher Kilgour handle->next_section_option_offset += 4*((copysz+3)/4); 239*8f3e7eeaSChristopher Kilgour 240*8f3e7eeaSChristopher Kilgour /* update padding option */ 241*8f3e7eeaSChristopher Kilgour dest = &((uint8_t *)handle->section_header)[handle->next_section_option_offset]; 242*8f3e7eeaSChristopher Kilgour padopt.option_length = handle->section_header_size - 243*8f3e7eeaSChristopher Kilgour handle->next_section_option_offset - 12; 244*8f3e7eeaSChristopher Kilgour (void) memcpy( dest, &padopt, sizeof( padopt ) ); 245*8f3e7eeaSChristopher Kilgour } 246*8f3e7eeaSChristopher Kilgour else { 247*8f3e7eeaSChristopher Kilgour retval = PCAPNG_NO_MEMORY; 248*8f3e7eeaSChristopher Kilgour } 249*8f3e7eeaSChristopher Kilgour } 250*8f3e7eeaSChristopher Kilgour else { 251*8f3e7eeaSChristopher Kilgour retval = PCAPNG_INVALID_HANDLE; 252*8f3e7eeaSChristopher Kilgour } 253*8f3e7eeaSChristopher Kilgour return retval; 254*8f3e7eeaSChristopher Kilgour } 255*8f3e7eeaSChristopher Kilgour 256*8f3e7eeaSChristopher Kilgour PCAPNG_RESULT pcapng_append_interface_option( PCAPNG_HANDLE * handle, 257*8f3e7eeaSChristopher Kilgour const option_header * interface_option ) 258*8f3e7eeaSChristopher Kilgour { 259*8f3e7eeaSChristopher Kilgour PCAPNG_RESULT retval = PCAPNG_OK; 260*8f3e7eeaSChristopher Kilgour if (handle && (handle->fd != -1)) { 261*8f3e7eeaSChristopher Kilgour if (handle->interface_description && 262*8f3e7eeaSChristopher Kilgour (handle->interface_description != MAP_FAILED) && 263*8f3e7eeaSChristopher Kilgour handle->next_interface_option_offset && 264*8f3e7eeaSChristopher Kilgour interface_option) { 265*8f3e7eeaSChristopher Kilgour size_t copysz = 4+interface_option->option_length; 266*8f3e7eeaSChristopher Kilgour uint8_t * dest = &((uint8_t *)handle->interface_description)[handle->next_interface_option_offset]; 267*8f3e7eeaSChristopher Kilgour (void) memcpy( dest, interface_option, copysz ); 268*8f3e7eeaSChristopher Kilgour handle->next_interface_option_offset += 4*((copysz+3)/4); 269*8f3e7eeaSChristopher Kilgour 270*8f3e7eeaSChristopher Kilgour /* update padding option */ 271*8f3e7eeaSChristopher Kilgour dest = &((uint8_t *)handle->interface_description)[handle->next_interface_option_offset]; 272*8f3e7eeaSChristopher Kilgour padopt.option_length = handle->interface_description_size - 273*8f3e7eeaSChristopher Kilgour handle->next_interface_option_offset - 12; 274*8f3e7eeaSChristopher Kilgour (void) memcpy( dest, &padopt, sizeof( padopt ) ); 275*8f3e7eeaSChristopher Kilgour } 276*8f3e7eeaSChristopher Kilgour else { 277*8f3e7eeaSChristopher Kilgour retval = PCAPNG_NO_MEMORY; 278*8f3e7eeaSChristopher Kilgour } 279*8f3e7eeaSChristopher Kilgour } 280*8f3e7eeaSChristopher Kilgour else { 281*8f3e7eeaSChristopher Kilgour retval = PCAPNG_INVALID_HANDLE; 282*8f3e7eeaSChristopher Kilgour } 283*8f3e7eeaSChristopher Kilgour return retval; 284*8f3e7eeaSChristopher Kilgour } 285*8f3e7eeaSChristopher Kilgour 286*8f3e7eeaSChristopher Kilgour PCAPNG_RESULT pcapng_append_packet( PCAPNG_HANDLE * handle, 287*8f3e7eeaSChristopher Kilgour const enhanced_packet_block * packet ) 288*8f3e7eeaSChristopher Kilgour { 289*8f3e7eeaSChristopher Kilgour PCAPNG_RESULT retval = PCAPNG_OK; 290*8f3e7eeaSChristopher Kilgour if (handle && (handle->fd != -1)) { 291*8f3e7eeaSChristopher Kilgour size_t writesz = packet->block_total_length; 292*8f3e7eeaSChristopher Kilgour ssize_t result = write( handle->fd, packet, writesz ); 293*8f3e7eeaSChristopher Kilgour if (result == -1) { 294*8f3e7eeaSChristopher Kilgour result = PCAPNG_FILE_WRITE_ERROR; 295*8f3e7eeaSChristopher Kilgour } 296*8f3e7eeaSChristopher Kilgour else { 297*8f3e7eeaSChristopher Kilgour handle->section_header->section_length += writesz; 298*8f3e7eeaSChristopher Kilgour } 299*8f3e7eeaSChristopher Kilgour } 300*8f3e7eeaSChristopher Kilgour else { 301*8f3e7eeaSChristopher Kilgour retval = PCAPNG_INVALID_HANDLE; 302*8f3e7eeaSChristopher Kilgour } 303*8f3e7eeaSChristopher Kilgour return retval; 304*8f3e7eeaSChristopher Kilgour } 305*8f3e7eeaSChristopher Kilgour 306*8f3e7eeaSChristopher Kilgour PCAPNG_RESULT pcapng_close( PCAPNG_HANDLE * handle ) 307*8f3e7eeaSChristopher Kilgour { 308*8f3e7eeaSChristopher Kilgour if (handle->interface_description && 309*8f3e7eeaSChristopher Kilgour (handle->interface_description != MAP_FAILED)) { 310*8f3e7eeaSChristopher Kilgour (void) munmap( handle->interface_description, 311*8f3e7eeaSChristopher Kilgour handle->interface_description_size ); 312*8f3e7eeaSChristopher Kilgour } 313*8f3e7eeaSChristopher Kilgour if (handle->section_header && 314*8f3e7eeaSChristopher Kilgour (handle->section_header != MAP_FAILED)) { 315*8f3e7eeaSChristopher Kilgour (void) munmap( handle->section_header, 316*8f3e7eeaSChristopher Kilgour handle->section_header_size ); 317*8f3e7eeaSChristopher Kilgour } 318*8f3e7eeaSChristopher Kilgour if (handle->fd != -1) { 319*8f3e7eeaSChristopher Kilgour (void) close( handle->fd ); 320*8f3e7eeaSChristopher Kilgour } 321*8f3e7eeaSChristopher Kilgour return PCAPNG_OK; 322*8f3e7eeaSChristopher Kilgour } 323