xref: /libbtbb/lib/src/pcapng.c (revision 3e500799e4da0e5c7f5b8c521c7a336da272f91b)
18f3e7eeaSChristopher Kilgour /* -*- c -*- */
28f3e7eeaSChristopher Kilgour /*
38f3e7eeaSChristopher Kilgour  * Copyright 2014 Christopher D. Kilgour techie AT whiterocker.com
48f3e7eeaSChristopher Kilgour  *
58f3e7eeaSChristopher Kilgour  * This file is part of libbtbb
68f3e7eeaSChristopher Kilgour  *
78f3e7eeaSChristopher Kilgour  * This program is free software; you can redistribute it and/or modify
88f3e7eeaSChristopher Kilgour  * it under the terms of the GNU General Public License as published by
98f3e7eeaSChristopher Kilgour  * the Free Software Foundation; either version 2, or (at your option)
108f3e7eeaSChristopher Kilgour  * any later version.
118f3e7eeaSChristopher Kilgour  *
128f3e7eeaSChristopher Kilgour  * This program is distributed in the hope that it will be useful,
138f3e7eeaSChristopher Kilgour  * but WITHOUT ANY WARRANTY; without even the implied warranty of
148f3e7eeaSChristopher Kilgour  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
158f3e7eeaSChristopher Kilgour  * GNU General Public License for more details.
168f3e7eeaSChristopher Kilgour  *
178f3e7eeaSChristopher Kilgour  * You should have received a copy of the GNU General Public License
188f3e7eeaSChristopher Kilgour  * along with libbtbb; see the file COPYING.  If not, write to
198f3e7eeaSChristopher Kilgour  * the Free Software Foundation, Inc., 51 Franklin Street,
208f3e7eeaSChristopher Kilgour  * Boston, MA 02110-1301, USA.
218f3e7eeaSChristopher Kilgour  */
228f3e7eeaSChristopher Kilgour 
238f3e7eeaSChristopher Kilgour #include "pcapng.h"
248f3e7eeaSChristopher Kilgour 
258f3e7eeaSChristopher Kilgour #include <errno.h>
268f3e7eeaSChristopher Kilgour #include <fcntl.h>
278f3e7eeaSChristopher Kilgour #include <string.h>
288f3e7eeaSChristopher Kilgour #include <sys/mman.h>
298f3e7eeaSChristopher Kilgour #include <sys/stat.h>
308f3e7eeaSChristopher Kilgour #include <sys/types.h>
318f3e7eeaSChristopher Kilgour #include <unistd.h>
328f3e7eeaSChristopher Kilgour 
338f3e7eeaSChristopher Kilgour static option_header padopt = {
348f3e7eeaSChristopher Kilgour 	.option_code = 0xffff,
358f3e7eeaSChristopher Kilgour };
368f3e7eeaSChristopher Kilgour 
pcapng_create(PCAPNG_HANDLE * handle,const char * filename,const option_header * section_options,const size_t section_options_space,const uint16_t link_type,const uint32_t snaplen,const option_header * interface_options,const size_t interface_options_space)378f3e7eeaSChristopher Kilgour PCAPNG_RESULT pcapng_create( PCAPNG_HANDLE * handle,
388f3e7eeaSChristopher Kilgour 			     const char * filename,
398f3e7eeaSChristopher Kilgour 			     const option_header * section_options,
408f3e7eeaSChristopher Kilgour 			     const size_t section_options_space,
418f3e7eeaSChristopher Kilgour 			     const uint16_t link_type,
428f3e7eeaSChristopher Kilgour 			     const uint32_t snaplen,
438f3e7eeaSChristopher Kilgour 			     const option_header * interface_options,
448f3e7eeaSChristopher Kilgour 			     const size_t interface_options_space )
458f3e7eeaSChristopher Kilgour {
468f3e7eeaSChristopher Kilgour 	PCAPNG_RESULT retval = PCAPNG_OK;
478f3e7eeaSChristopher Kilgour 	int PGSZ = getpagesize( );
48*3e500799SMike Ryan 	size_t zeroes = 0;
49*3e500799SMike Ryan 	ssize_t result = -1;
508f3e7eeaSChristopher Kilgour 
518f3e7eeaSChristopher Kilgour 	handle->section_header = NULL;
528f3e7eeaSChristopher Kilgour 	handle->interface_description = NULL;
538f3e7eeaSChristopher Kilgour 	handle->section_header_size = handle->next_section_option_offset =
548f3e7eeaSChristopher Kilgour 		handle->interface_description_size =
558f3e7eeaSChristopher Kilgour 		handle->next_interface_option_offset = 0;
568f3e7eeaSChristopher Kilgour 
578f3e7eeaSChristopher Kilgour 	handle->fd = open( filename, O_RDWR|O_CREAT|O_EXCL, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP );
588f3e7eeaSChristopher Kilgour 	if (handle->fd == -1) {
598f3e7eeaSChristopher Kilgour 		switch( errno ) {
608f3e7eeaSChristopher Kilgour 		case EEXIST:
618f3e7eeaSChristopher Kilgour 			retval = PCAPNG_FILE_EXISTS;
628f3e7eeaSChristopher Kilgour 			break;
638f3e7eeaSChristopher Kilgour 		case EMFILE:
648f3e7eeaSChristopher Kilgour 		case ENFILE:
658f3e7eeaSChristopher Kilgour 			retval = PCAPNG_TOO_MANY_FILES_OPEN;
668f3e7eeaSChristopher Kilgour 			break;
678f3e7eeaSChristopher Kilgour 		case ENOMEM:
688f3e7eeaSChristopher Kilgour 		case ENOSPC:
698f3e7eeaSChristopher Kilgour 			retval = PCAPNG_NO_MEMORY;
708f3e7eeaSChristopher Kilgour 			break;
718f3e7eeaSChristopher Kilgour 		default:
728f3e7eeaSChristopher Kilgour 			retval = PCAPNG_FILE_NOT_ALLOWED;
738f3e7eeaSChristopher Kilgour 		}
748f3e7eeaSChristopher Kilgour 	}
758f3e7eeaSChristopher Kilgour 
768f3e7eeaSChristopher Kilgour 	if (retval == PCAPNG_OK) {
778f3e7eeaSChristopher Kilgour 		/* section header */
788f3e7eeaSChristopher Kilgour 		const section_header_block shb = {
798f3e7eeaSChristopher Kilgour 			.block_type = BLOCK_TYPE_SECTION_HEADER,
808f3e7eeaSChristopher Kilgour 			.block_total_length = 28,
818f3e7eeaSChristopher Kilgour 			.byte_order_magic = SECTION_HEADER_BYTE_ORDER_MAGIC,
828f3e7eeaSChristopher Kilgour 			.major_version = 1,
838f3e7eeaSChristopher Kilgour 			.minor_version = 0,
848f3e7eeaSChristopher Kilgour 			.section_length = (uint64_t) -1,
858f3e7eeaSChristopher Kilgour 		};
868f3e7eeaSChristopher Kilgour 		handle->section_header_size = sizeof( shb );
878f3e7eeaSChristopher Kilgour 		result = write( handle->fd, &shb, sizeof( shb ) );
888f3e7eeaSChristopher Kilgour 		/* write initial section options */
898f3e7eeaSChristopher Kilgour 		while ((result != -1) &&
908f3e7eeaSChristopher Kilgour 		       section_options &&
918f3e7eeaSChristopher Kilgour 		       section_options->option_code &&
928f3e7eeaSChristopher Kilgour 		       section_options->option_length) {
938f3e7eeaSChristopher Kilgour 			size_t paddedsz = 4*((section_options->option_length+3)/4);
948f3e7eeaSChristopher Kilgour 			zeroes = paddedsz - section_options->option_length;
958f3e7eeaSChristopher Kilgour 			result = write( handle->fd, section_options, 4+section_options->option_length );
968f3e7eeaSChristopher Kilgour 			while ((zeroes > 0) && (result != -1)) {
978f3e7eeaSChristopher Kilgour 				result = write( handle->fd, "\0", 1 );
988f3e7eeaSChristopher Kilgour 				zeroes--;
998f3e7eeaSChristopher Kilgour 			}
1008f3e7eeaSChristopher Kilgour 			section_options = (const option_header *) &((uint8_t *)section_options)[4+paddedsz];
1018f3e7eeaSChristopher Kilgour 			handle->section_header_size += (4+paddedsz);
1028f3e7eeaSChristopher Kilgour 		}
1038f3e7eeaSChristopher Kilgour 		handle->next_section_option_offset = handle->section_header_size;
1048f3e7eeaSChristopher Kilgour 	}
1058f3e7eeaSChristopher Kilgour 
1068f3e7eeaSChristopher Kilgour 	if (result == -1) {
1078f3e7eeaSChristopher Kilgour 		retval = PCAPNG_FILE_WRITE_ERROR;
1088f3e7eeaSChristopher Kilgour 	}
1098f3e7eeaSChristopher Kilgour 	else {
1108f3e7eeaSChristopher Kilgour 		/* determine the size of section header with desired space */
1118f3e7eeaSChristopher Kilgour 		zeroes = (size_t) PGSZ*((handle->section_header_size + 4 +
1128f3e7eeaSChristopher Kilgour 					 section_options_space + PGSZ - 1)/PGSZ) -
1138f3e7eeaSChristopher Kilgour 			handle->section_header_size;
1148f3e7eeaSChristopher Kilgour 		handle->section_header_size += zeroes;
1158f3e7eeaSChristopher Kilgour 		while ((zeroes > 0) && (result != -1)) {
1168f3e7eeaSChristopher Kilgour 			result = write( handle->fd, "\0", 1 );
1178f3e7eeaSChristopher Kilgour 			zeroes--;
1188f3e7eeaSChristopher Kilgour 		}
1198f3e7eeaSChristopher Kilgour 
1208f3e7eeaSChristopher Kilgour 		/* mmap the section header */
1218f3e7eeaSChristopher Kilgour 		handle->section_header = mmap( NULL, handle->section_header_size,
1228f3e7eeaSChristopher Kilgour 					       PROT_READ|PROT_WRITE,
1238f3e7eeaSChristopher Kilgour 					       MAP_SHARED,
1248f3e7eeaSChristopher Kilgour 					       handle->fd, 0 );
1258f3e7eeaSChristopher Kilgour 	}
1268f3e7eeaSChristopher Kilgour 
1278f3e7eeaSChristopher Kilgour 	if (retval == PCAPNG_OK) {
1288f3e7eeaSChristopher Kilgour 		if (result == -1) {
1298f3e7eeaSChristopher Kilgour 			retval = PCAPNG_FILE_WRITE_ERROR;
1308f3e7eeaSChristopher Kilgour 		}
1318f3e7eeaSChristopher Kilgour 		else if (handle->section_header == MAP_FAILED) {
1328f3e7eeaSChristopher Kilgour 			retval = PCAPNG_MMAP_FAILED;
1338f3e7eeaSChristopher Kilgour 		}
1348f3e7eeaSChristopher Kilgour 		else {
1358f3e7eeaSChristopher Kilgour 			/* write the interface header */
1368f3e7eeaSChristopher Kilgour 			const interface_description_block idb = {
1378f3e7eeaSChristopher Kilgour 				.block_type = BLOCK_TYPE_INTERFACE,
1388f3e7eeaSChristopher Kilgour 				.block_total_length = 0,
1398f3e7eeaSChristopher Kilgour 				.link_type = link_type,
1408f3e7eeaSChristopher Kilgour 				.snaplen = snaplen
1418f3e7eeaSChristopher Kilgour 			};
1428f3e7eeaSChristopher Kilgour 			handle->interface_description_size = sizeof( idb );
1438f3e7eeaSChristopher Kilgour 			result = write( handle->fd, &idb, sizeof( idb ) );
1448f3e7eeaSChristopher Kilgour 
1458f3e7eeaSChristopher Kilgour 			/* write interface options */
1468f3e7eeaSChristopher Kilgour 			while ((result != -1) &&
1478f3e7eeaSChristopher Kilgour 			       interface_options &&
1488f3e7eeaSChristopher Kilgour 			       interface_options->option_code &&
1498f3e7eeaSChristopher Kilgour 			       interface_options->option_length) {
1508f3e7eeaSChristopher Kilgour 				size_t paddedsz = 4*((interface_options->option_length+3)/4);
1518f3e7eeaSChristopher Kilgour 				zeroes = paddedsz - interface_options->option_length;
1528f3e7eeaSChristopher Kilgour 				result = write( handle->fd, interface_options, 4+interface_options->option_length );
1538f3e7eeaSChristopher Kilgour 				while ((zeroes > 0) && (result != -1)) {
1548f3e7eeaSChristopher Kilgour 					result = write( handle->fd, "\0", 1 );
1558f3e7eeaSChristopher Kilgour 					zeroes--;
1568f3e7eeaSChristopher Kilgour 				}
1578f3e7eeaSChristopher Kilgour 				interface_options = (const option_header *) &((uint8_t *)interface_options)[4+paddedsz];
1588f3e7eeaSChristopher Kilgour 				handle->interface_description_size += (4+paddedsz);
1598f3e7eeaSChristopher Kilgour 			}
1608f3e7eeaSChristopher Kilgour 			handle->next_interface_option_offset = handle->interface_description_size;
1618f3e7eeaSChristopher Kilgour 		}
1628f3e7eeaSChristopher Kilgour 	}
1638f3e7eeaSChristopher Kilgour 
1648f3e7eeaSChristopher Kilgour 	if (retval == PCAPNG_OK) {
1658f3e7eeaSChristopher Kilgour 		if (result == -1) {
1668f3e7eeaSChristopher Kilgour 			retval = PCAPNG_FILE_WRITE_ERROR;
1678f3e7eeaSChristopher Kilgour 		}
1688f3e7eeaSChristopher Kilgour 		else {
1698f3e7eeaSChristopher Kilgour 			/* determine the size of interface description with desired space */
1708f3e7eeaSChristopher Kilgour 			zeroes = (size_t) PGSZ*((handle->interface_description_size + 4 +
1718f3e7eeaSChristopher Kilgour 						 interface_options_space + PGSZ - 1)/PGSZ) -
1728f3e7eeaSChristopher Kilgour 				handle->interface_description_size;
1738f3e7eeaSChristopher Kilgour 			handle->interface_description_size += zeroes;
1748f3e7eeaSChristopher Kilgour 			while ((zeroes > 0) && (result != -1)) {
1758f3e7eeaSChristopher Kilgour 				result = write( handle->fd, "\0", 1 );
1768f3e7eeaSChristopher Kilgour 				zeroes--;
1778f3e7eeaSChristopher Kilgour 			}
1788f3e7eeaSChristopher Kilgour 
1798f3e7eeaSChristopher Kilgour 			/* mmap the interface description */
1808f3e7eeaSChristopher Kilgour 			handle->interface_description = mmap( NULL, handle->interface_description_size,
1818f3e7eeaSChristopher Kilgour 							      PROT_READ|PROT_WRITE,
1828f3e7eeaSChristopher Kilgour 							      MAP_SHARED,
1838f3e7eeaSChristopher Kilgour 							      handle->fd,
1848f3e7eeaSChristopher Kilgour 							      handle->section_header_size );
1858f3e7eeaSChristopher Kilgour 		}
1868f3e7eeaSChristopher Kilgour 	}
1878f3e7eeaSChristopher Kilgour 
1888f3e7eeaSChristopher Kilgour 	if (retval == PCAPNG_OK) {
1898f3e7eeaSChristopher Kilgour 		if (result == -1) {
1908f3e7eeaSChristopher Kilgour 			retval = PCAPNG_FILE_WRITE_ERROR;
1918f3e7eeaSChristopher Kilgour 		}
1928f3e7eeaSChristopher Kilgour 		else if (handle->interface_description == MAP_FAILED) {
1938f3e7eeaSChristopher Kilgour 			retval = PCAPNG_MMAP_FAILED;
1948f3e7eeaSChristopher Kilgour 		}
1958f3e7eeaSChristopher Kilgour 		else {
1968f3e7eeaSChristopher Kilgour 			uint8_t * dest = &((uint8_t *)handle->section_header)[handle->next_section_option_offset];
1978f3e7eeaSChristopher Kilgour 			padopt.option_length = handle->section_header_size -
1988f3e7eeaSChristopher Kilgour 				handle->next_section_option_offset - 12;
1998f3e7eeaSChristopher Kilgour 
2008f3e7eeaSChristopher Kilgour 			/* Add padding options, update the header sizes. */
2018f3e7eeaSChristopher Kilgour 			(void) memcpy( dest, &padopt, sizeof( padopt ) );
2028f3e7eeaSChristopher Kilgour 			handle->section_header->block_total_length =
2038f3e7eeaSChristopher Kilgour 				(uint32_t) handle->section_header_size;
2048f3e7eeaSChristopher Kilgour 			((uint32_t*)handle->section_header)[handle->section_header_size/4-1] =
2058f3e7eeaSChristopher Kilgour 				(uint32_t) handle->section_header_size;
2068f3e7eeaSChristopher Kilgour 
2078f3e7eeaSChristopher Kilgour 			padopt.option_length = handle->interface_description_size -
2088f3e7eeaSChristopher Kilgour 				handle->next_interface_option_offset - 12;
2098f3e7eeaSChristopher Kilgour 			dest = &((uint8_t *)handle->interface_description)[handle->next_interface_option_offset];
2108f3e7eeaSChristopher Kilgour 			(void) memcpy( dest, &padopt, sizeof( padopt ) );
2118f3e7eeaSChristopher Kilgour 			handle->interface_description->block_total_length =
2128f3e7eeaSChristopher Kilgour 				(uint32_t) handle->interface_description_size;
2138f3e7eeaSChristopher Kilgour 			((uint32_t*)handle->interface_description)[handle->interface_description_size/4-1] =
2148f3e7eeaSChristopher Kilgour 				(uint32_t) handle->interface_description_size;
2158f3e7eeaSChristopher Kilgour 
2168f3e7eeaSChristopher Kilgour 			handle->section_header->section_length = (uint64_t) handle->interface_description_size;
2178f3e7eeaSChristopher Kilgour 		}
2188f3e7eeaSChristopher Kilgour 	}
2198f3e7eeaSChristopher Kilgour 
2208f3e7eeaSChristopher Kilgour 	if (retval != PCAPNG_OK) {
2218f3e7eeaSChristopher Kilgour 		(void) pcapng_close( handle );
2228f3e7eeaSChristopher Kilgour 	}
2238f3e7eeaSChristopher Kilgour 
2248f3e7eeaSChristopher Kilgour 	return retval;
2258f3e7eeaSChristopher Kilgour }
2268f3e7eeaSChristopher Kilgour 
pcapng_append_section_option(PCAPNG_HANDLE * handle,const option_header * section_option)2278f3e7eeaSChristopher Kilgour PCAPNG_RESULT pcapng_append_section_option( PCAPNG_HANDLE * handle,
2288f3e7eeaSChristopher Kilgour 					    const option_header * section_option )
2298f3e7eeaSChristopher Kilgour {
2308f3e7eeaSChristopher Kilgour 	PCAPNG_RESULT retval = PCAPNG_OK;
2318f3e7eeaSChristopher Kilgour 	if (handle && (handle->fd != -1)) {
2328f3e7eeaSChristopher Kilgour 		if (handle->section_header &&
2338f3e7eeaSChristopher Kilgour 		    (handle->section_header != MAP_FAILED) &&
2348f3e7eeaSChristopher Kilgour 		    handle->next_section_option_offset &&
2358f3e7eeaSChristopher Kilgour 		    section_option) {
2368f3e7eeaSChristopher Kilgour 			size_t copysz = 4+section_option->option_length;
2378f3e7eeaSChristopher Kilgour 			uint8_t * dest = &((uint8_t *)handle->section_header)[handle->next_section_option_offset];
2388f3e7eeaSChristopher Kilgour 			(void) memcpy( dest, section_option, copysz );
2398f3e7eeaSChristopher Kilgour 			handle->next_section_option_offset += 4*((copysz+3)/4);
2408f3e7eeaSChristopher Kilgour 
2418f3e7eeaSChristopher Kilgour 			/* update padding option */
2428f3e7eeaSChristopher Kilgour 			dest = &((uint8_t *)handle->section_header)[handle->next_section_option_offset];
2438f3e7eeaSChristopher Kilgour 			padopt.option_length = handle->section_header_size -
2448f3e7eeaSChristopher Kilgour 				handle->next_section_option_offset - 12;
2458f3e7eeaSChristopher Kilgour 			(void) memcpy( dest, &padopt, sizeof( padopt ) );
2468f3e7eeaSChristopher Kilgour 		}
2478f3e7eeaSChristopher Kilgour 		else {
2488f3e7eeaSChristopher Kilgour 			retval = PCAPNG_NO_MEMORY;
2498f3e7eeaSChristopher Kilgour 		}
2508f3e7eeaSChristopher Kilgour 	}
2518f3e7eeaSChristopher Kilgour 	else {
2528f3e7eeaSChristopher Kilgour 		retval = PCAPNG_INVALID_HANDLE;
2538f3e7eeaSChristopher Kilgour 	}
2548f3e7eeaSChristopher Kilgour 	return retval;
2558f3e7eeaSChristopher Kilgour }
2568f3e7eeaSChristopher Kilgour 
pcapng_append_interface_option(PCAPNG_HANDLE * handle,const option_header * interface_option)2578f3e7eeaSChristopher Kilgour PCAPNG_RESULT pcapng_append_interface_option( PCAPNG_HANDLE * handle,
2588f3e7eeaSChristopher Kilgour 					      const option_header * interface_option )
2598f3e7eeaSChristopher Kilgour {
2608f3e7eeaSChristopher Kilgour 	PCAPNG_RESULT retval = PCAPNG_OK;
2618f3e7eeaSChristopher Kilgour 	if (handle && (handle->fd != -1)) {
2628f3e7eeaSChristopher Kilgour 		if (handle->interface_description &&
2638f3e7eeaSChristopher Kilgour 		    (handle->interface_description != MAP_FAILED) &&
2648f3e7eeaSChristopher Kilgour 		    handle->next_interface_option_offset &&
2658f3e7eeaSChristopher Kilgour 		    interface_option) {
2668f3e7eeaSChristopher Kilgour 			size_t copysz = 4+interface_option->option_length;
2678f3e7eeaSChristopher Kilgour 			uint8_t * dest = &((uint8_t *)handle->interface_description)[handle->next_interface_option_offset];
2688f3e7eeaSChristopher Kilgour 			(void) memcpy( dest, interface_option, copysz );
2698f3e7eeaSChristopher Kilgour 			handle->next_interface_option_offset += 4*((copysz+3)/4);
2708f3e7eeaSChristopher Kilgour 
2718f3e7eeaSChristopher Kilgour 			/* update padding option */
2728f3e7eeaSChristopher Kilgour 			dest = &((uint8_t *)handle->interface_description)[handle->next_interface_option_offset];
2738f3e7eeaSChristopher Kilgour 			padopt.option_length = handle->interface_description_size -
2748f3e7eeaSChristopher Kilgour 				handle->next_interface_option_offset - 12;
2758f3e7eeaSChristopher Kilgour 			(void) memcpy( dest, &padopt, sizeof( padopt ) );
2768f3e7eeaSChristopher Kilgour 		}
2778f3e7eeaSChristopher Kilgour 		else {
2788f3e7eeaSChristopher Kilgour 			retval = PCAPNG_NO_MEMORY;
2798f3e7eeaSChristopher Kilgour 		}
2808f3e7eeaSChristopher Kilgour 	}
2818f3e7eeaSChristopher Kilgour 	else {
2828f3e7eeaSChristopher Kilgour 		retval = PCAPNG_INVALID_HANDLE;
2838f3e7eeaSChristopher Kilgour 	}
2848f3e7eeaSChristopher Kilgour 	return retval;
2858f3e7eeaSChristopher Kilgour }
2868f3e7eeaSChristopher Kilgour 
pcapng_append_packet(PCAPNG_HANDLE * handle,const enhanced_packet_block * packet)2878f3e7eeaSChristopher Kilgour PCAPNG_RESULT pcapng_append_packet( PCAPNG_HANDLE * handle,
2888f3e7eeaSChristopher Kilgour 				    const enhanced_packet_block * packet )
2898f3e7eeaSChristopher Kilgour {
2908f3e7eeaSChristopher Kilgour 	PCAPNG_RESULT retval = PCAPNG_OK;
2918f3e7eeaSChristopher Kilgour 	if (handle && (handle->fd != -1)) {
2928f3e7eeaSChristopher Kilgour 		size_t writesz = packet->block_total_length;
2938f3e7eeaSChristopher Kilgour 		ssize_t result = write( handle->fd, packet, writesz );
2948f3e7eeaSChristopher Kilgour 		if (result == -1) {
2958f3e7eeaSChristopher Kilgour 			result = PCAPNG_FILE_WRITE_ERROR;
2968f3e7eeaSChristopher Kilgour 		}
2978f3e7eeaSChristopher Kilgour 		else {
2988f3e7eeaSChristopher Kilgour 			handle->section_header->section_length += writesz;
2998f3e7eeaSChristopher Kilgour 		}
3008f3e7eeaSChristopher Kilgour 	}
3018f3e7eeaSChristopher Kilgour 	else {
3028f3e7eeaSChristopher Kilgour 		retval = PCAPNG_INVALID_HANDLE;
3038f3e7eeaSChristopher Kilgour 	}
3048f3e7eeaSChristopher Kilgour 	return retval;
3058f3e7eeaSChristopher Kilgour }
3068f3e7eeaSChristopher Kilgour 
pcapng_close(PCAPNG_HANDLE * handle)3078f3e7eeaSChristopher Kilgour PCAPNG_RESULT pcapng_close( PCAPNG_HANDLE * handle )
3088f3e7eeaSChristopher Kilgour {
3098f3e7eeaSChristopher Kilgour 	if (handle->interface_description &&
3108f3e7eeaSChristopher Kilgour 	    (handle->interface_description != MAP_FAILED)) {
3118f3e7eeaSChristopher Kilgour 		(void) munmap( handle->interface_description,
3128f3e7eeaSChristopher Kilgour 			       handle->interface_description_size );
3138f3e7eeaSChristopher Kilgour 	}
3148f3e7eeaSChristopher Kilgour 	if (handle->section_header &&
3158f3e7eeaSChristopher Kilgour 	    (handle->section_header != MAP_FAILED)) {
3168f3e7eeaSChristopher Kilgour 		(void) munmap( handle->section_header,
3178f3e7eeaSChristopher Kilgour 			       handle->section_header_size );
3188f3e7eeaSChristopher Kilgour 	}
3198f3e7eeaSChristopher Kilgour 	if (handle->fd != -1) {
3208f3e7eeaSChristopher Kilgour 		(void) close( handle->fd );
3218f3e7eeaSChristopher Kilgour 	}
3228f3e7eeaSChristopher Kilgour 	return PCAPNG_OK;
3238f3e7eeaSChristopher Kilgour }
324