Cannot run a large structure filled with arrays win C - c

I'm building a SAE J1939 library for embedded systems such as Arduino, STM32, AVR etc.
But I have an issue I don't understand. First when I compile. No error!
But when I run, I get this assembler error. It's all about the J1939 struct.
Why does this happen? Is the heap to small?
Can't find a source file at
"C:\mingw810\i686-810-posix-dwarf-rt_v6-rev0\build\gcc-8.1.0\i686-w64-mingw32\libgcc/../../../../../src/gcc-8.1.0/libgcc/config/i386/cygwin.S"
Locate the file or edit the source lookup path to include its
location.
Run this code below to reproduce the error:
#include <stdio.h>
#include <stdlib.h>
#include "stdint.h"
/* PGN: 0x00E800 - Storing the Acknowledgement from the reading process */
struct Acknowledgement {
uint8_t control_byte; /* This indicates the status of the requested information about PGN: */
uint8_t group_function_value; /* The function code that specify cause of the control byte e.g time out or aborted */
uint8_t address; /* Address from the ECU where the acknowledgement is comming from */
uint32_t PGN_of_requested_info; /* Information request about the PGN */
};
/* PGN: 0x00EC00 - Storing the Transport Protocol Connection Management from the reading process */
struct TP_CM {
uint8_t control_byte; /* What type of message are we going to send */
uint16_t total_message_size; /* Total bytes our complete message includes */
uint8_t number_of_packages; /* How many times we are going to send packages via TP_DT */
uint32_t PGN_of_the_packeted_message; /* Our message is going to activate a PGN */
};
/* PGN: 0x00EB00 - Storing the Transport Protocol Data Transfer from the reading process */
struct TP_DT {
uint8_t sequence_number; /* When this sequence number is the same as number_of_packages from TP_CM, then we have our complete message */
uint8_t data[7][256]; /* Package data of 2D array where first index is data0 -> data6 and second index is sequence of the data */
};
/* PGN: 0x00EE00 - Storing the Address claimed from the reading process */
struct Name {
uint32_t identity_number; /* Specify the ECU serial ID - 0 to 2097151 */
uint16_t manufacturer_code; /* Specify the ECU manufacturer code - 0 to 2047 */
uint8_t function_instance; /* Specify the ECU function number - 0 to 31 */
uint8_t ECU_instance; /* Specify the ECU number - 0 to 7 */
uint8_t function; /* Specify the ECU function - 0 to 255 */
uint8_t vehicle_system; /* Specify the type of vehicle where ECU is located - 0 to 127 */
uint8_t arbitrary_address_capable; /* Specify if the ECU have right to change address if addresses conflicts - 0 to 1 */
uint8_t industry_group; /* Specify the group where this ECU is located - 0 to 7 */
uint8_t vehicle_system_instance; /* Specify the vehicle system number - 0 to 15 */
};
/* PGN: 0x00FECA - Storing the DM1 Active diagnostic trouble codes from the reading process */
struct DM1 {
/* These are SAE lamps can have 1 = ON and 0 = OFF */
uint8_t SAE_lamp_status_malfunction_indicator;
uint8_t SAE_lamp_status_red_stop;
uint8_t SAE_lamp_status_amber_warning;
uint8_t SAE_lamp_status_protect_lamp;
uint8_t SAE_flash_lamp_malfunction_indicator;
uint8_t SAE_flash_lamp_red_stop;
uint8_t SAE_flash_lamp_amber_warning;
uint8_t SAE_flash_lamp_protect_lamp;
/* Fault location, problem and codes */
uint32_t SPN; /* Location where the fault exist */
uint8_t FMI; /* Type of problem */
uint8_t SPN_conversion_method; /* If SPN_conversion_method = 1 that means Diagnostics Trouble Code are aligned using a newer conversion method. If SPN_conversion_method = 0 means one of the three Diagnostics Trouble Code conversion methods is used and ECU manufacture shall know which of the three methods is used */
uint8_t occurence_count; /* This tells how many times failure has occurred. Every time fault goes from inactive to active, the occurence_count is incremented by 1. If fault becomes active for more than 126 times the occurence_count remains 126 */
};
/* PGN: 0x00D800 - Storing the DM15 response from the reading process */
struct DM15 {
uint16_t number_of_allowed_bytes; /* How many bytes we are allowed to write or read to */
uint8_t status; /* Status of the response */
uint32_t EDC_parameter; /* Status code */
uint8_t EDCP_extention; /* Describe how we should interpret the EDC parameter as a status code or error code */
uint16_t seed; /* Response of the key if we need more key or no key at all */
};
/* PGN: 0x00D700 - Storing the DM16 binary data transfer from the reading process */
struct DM16 {
uint8_t number_of_occurences; /* How many bytes we have sent */
uint8_t raw_binary_data[256]; /* Here we store the bytes */
};
/* Storing the error codes from the reading process */
struct DM {
uint8_t errors_dm1_active; /* How many errors of DM1 we have right now */
uint8_t errors_dm2_active; /* How many errors of DM2 is active */
struct DM1 dm1[256]; /* dm1 can contains multiple error messages */
struct DM1 dm2[256]; /* dm2 contains previously active errors from dm1 */
struct DM15 dm15; /* dm15 is the memory access response from DM14 memory request */
struct DM16 dm16; /* dm16 is the binary data transfer after DM15 memory response (if it was proceeded) */
/* Add more DM here */
};
/* PGN: 0x00FEDA - Storing the software identification from the reading process */
struct Software_identification {
uint8_t length_of_each_identification; /* The length of each identification - Not part of J1939 standard */
uint8_t number_of_fields; /* How many numbers contains in the identifications array */
uint8_t identifications[256]; /* This can be for example ASCII */
};
/* PGN: 0x00FDC5 - Storing the ECU identification from the reading process */
struct ECU_identification {
uint8_t length_of_each_field; /* The real length of the fields - Not part of J1939 standard */
uint8_t ecu_part_number[256]; /* ASCII field */
uint8_t ecu_serial_number[256]; /* ASCII field */
uint8_t ecu_location[256]; /* ASCII field */
uint8_t ecu_type[256]; /* ASCII field */
uint8_t ecu_manufacturer[256]; /* ASCII field */
uint8_t ecu_hardware_version[256]; /* ASCII field */
};
/* PGN: 0x00FEEB - Storing the component identification from the reading process */
struct Component_identification {
uint8_t length_of_each_field; /* The real length of the fields - Not part of J1939 standard */
uint8_t component_product_date[256]; /* ASCII field */
uint8_t component_model_name[256]; /* ASCII field */
uint8_t component_serial_number[256]; /* ASCII field */
uint8_t component_unit_name[256]; /* ASCII field */
};
/* PGN: 0x00FE30 (65072) to 0x00FE3F (65087) */
struct Auxiliary_valve_command {
uint8_t standard_flow; /* Command flow */
uint8_t fail_safe_mode; /* If the user want the valve to go to neutral */
uint8_t valve_state; /* Retract, Extend, Neutral, Init, Error etc */
};
/* PGN: 0x00FE10 (65040) to 0x00FE1F (65055) */
struct Auxiliary_valve_estimated_flow {
uint8_t extend_estimated_flow_standard; /* A measurement */
uint8_t retract_estimated_flow_standard; /* A measurement */
uint8_t valve_state; /* Retract, Extend, Neutral, Init, Error etc */
uint8_t fail_safe_mode; /* The mode if we are going to use fail safe mode or not */
uint8_t limit; /* Enter a limit code */
};
/* PGN: 0x00C400 (50176) */
struct General_purpose_valve_command {
uint8_t standard_flow; /* Command flow */
uint8_t fail_safe_mode; /* If the user want the valve to go to neutral */
uint8_t valve_state; /* Retract, Extend, Neutral, Init, Error etc */
uint16_t extended_flow; /* Another command flow */
};
/* PGN: 0x00C600 (50688) */
struct General_purpose_valve_estimated_flow {
uint8_t extend_estimated_flow_standard; /* A measurement */
uint8_t retract_estimated_flow_standard; /* A measurement */
uint8_t valve_state; /* Retract, Extend, Neutral, Init, Error etc */
uint8_t fail_safe_mode; /* The mode if we are going to use fail safe mode or not */
uint8_t limit; /* Enter a limit code */
uint16_t extend_estimated_flow_extended; /* A measurement */
uint16_t retract_estimated_flow_extended; /* A measurement */
};
struct Auxiliary_valve_measured_position {
uint16_t measured_position_procent; /* Procent position */
uint8_t valve_state; /* Retract, Extend, Neutral, Init, Error etc */
uint16_t measured_position_micrometer; /* Micrometer position */
};
typedef struct {
/* For information about other ECU */
uint8_t number_of_ECU;
uint8_t number_of_cannot_claim_address;
uint8_t ECU_address[256];
struct Acknowledgement acknowledgement[256];
struct TP_CM tp_cm[256];
struct TP_DT tp_dt[256];
struct Name name[256];
struct DM dm[256];
struct Software_identification software_identification[256];
struct ECU_identification ecu_identification[256];
struct Component_identification component_identification[256];
struct Auxiliary_valve_estimated_flow auxiliary_valve_estimated_flow[256][16];
struct General_purpose_valve_estimated_flow general_purpose_valve_estimated_flow[256];
struct Auxiliary_valve_measured_position auxiliary_valve_measured_position[256][16];
/* For information about this ECU */
struct Name this_name;
uint8_t this_ECU_address;
struct DM this_dm;
struct Software_identification this_software_identification;
struct ECU_identification this_ecu_identification;
struct Component_identification this_component_identification;
struct Auxiliary_valve_command this_auxiliary_valve_command[16];
struct General_purpose_valve_command this_general_purpose_valve_command;
} J1939;
int main(void) {
J1939 j1939;
puts("!!!Hello World!!!"); /* prints !!!Hello World!!! */
return EXIT_SUCCESS;
}

This information is not a compilation error. You execute a debugger and try to debug a part of program without located sources. This could happen if your program stops in a compiled library. Then we can use a assembler instruction only. As mentioned above try to set breakpoint into your main() funcion.

Related

Getting kernel image size in uboot

I'm attempting to create custom functionality for kernel authenticity validation on my uboot on an armv8 based platform. The method in which context I'm working in is boot_jump_linux, seen in uboot source here, around line #50.
The parameter (bootm_headers_t *images) includes the information on where the kernel is loaded in memory. With that I've been able to iterate over the specific memory area and otherwise I have everything I need, but I'm missing the information on the length of kernel data. The struct under *images references multiple relevant data structures found here:
typedef struct image_header {
uint32_t ih_magic; /* Image Header Magic Number */
uint32_t ih_hcrc; /* Image Header CRC Checksum */
uint32_t ih_time; /* Image Creation Timestamp */
uint32_t ih_size; /* Image Data Size */
uint32_t ih_load; /* Data Load Address */
uint32_t ih_ep; /* Entry Point Address */
uint32_t ih_dcrc; /* Image Data CRC Checksum */
uint8_t ih_os; /* Operating System */
uint8_t ih_arch; /* CPU architecture */
uint8_t ih_type; /* Image Type */
uint8_t ih_comp; /* Compression Type */
uint8_t ih_name[IH_NMLEN]; /* Image Name */
} image_header_t;
typedef struct image_info {
ulong start, end; /* start/end of blob */
ulong image_start, image_len; /* start of image within blob, len of image */
ulong load; /* load addr for the image */
uint8_t comp, type, os; /* compression, type of image, os type */
uint8_t arch; /* CPU architecture */
} image_info_t;
All values in the above image_header have a similar constant value, including timestamp, so that leads me to believe that they haven't been initialized. Additionally the image_info struct contains values of 0 all length related fields.
Is there some other way of determining the kernel size, or should I just fall back on to a predetermined default value?

Get USB Host Controller parameters in Linux programmatically

I need to get some parameters related to USB Host Controllers in Linux. I made a lot of searches in the internet and the only way that I found is using pciutils lib. Each PCI device is in the structure pci_dev in pci.h:
struct pci_dev {
struct pci_dev *next; /* Next device in the chain */
u16 domain_16; /* 16-bit version of the PCI domain for backward compatibility */
/* 0xffff if the real domain doesn't fit in 16 bits */
u8 bus, dev, func; /* Bus inside domain, device and function */
/* These fields are set by pci_fill_info() */
int known_fields; /* Set of info fields already known */
u16 vendor_id, device_id; /* Identity of the device */
u16 device_class; /* PCI device class */
int irq; /* IRQ number */
pciaddr_t base_addr[6]; /* Base addresses including flags in lower bits */
pciaddr_t size[6]; /* Region sizes */
pciaddr_t rom_base_addr; /* Expansion ROM base address */
pciaddr_t rom_size; /* Expansion ROM size */
struct pci_cap *first_cap; /* List of capabilities */
char *phy_slot; /* Physical slot */
char *module_alias; /* Linux kernel module alias */
char *label; /* Device name as exported by BIOS */
int numa_node; /* NUMA node */
pciaddr_t flags[6]; /* PCI_IORESOURCE_* flags for regions */
pciaddr_t rom_flags; /* PCI_IORESOURCE_* flags for expansion ROM */
int domain; /* PCI domain (host bridge) */
/* Fields used internally */
struct pci_access *access;
struct pci_methods *methods;
u8 *cache; /* Cached config registers */
int cache_len;
int hdrtype; /* Cached low 7 bits of header type, -1 if unknown */
void *aux; /* Auxiliary data */
struct pci_property *properties; /* A linked list of extra properties */
struct pci_cap *last_cap; /* Last capability in the list */
};
I found also that I can parse pci devices as following:
struct pci_access *pacc1;
struct pci_dev *dev1;
unsigned int c1;
char namebuf1[1024], *name1;
pacc1 = pci_alloc(); /* Get the pci_access structure */
/* Set all options you want -- here we stick with the defaults */
pci_init(pacc1); /* Initialize the PCI library */
pci_scan_bus(pacc1); /* We want to get the list of devices */
for (dev1=pacc1->devices; dev1; dev1=dev1->next) /* Iterate over all devices */
{
pci_fill_info(dev1, PCI_FILL_IDENT | PCI_FILL_BASES | PCI_FILL_CLASS); /* Fill in header info we need */
c1 = pci_read_byte(dev1, PCI_INTERRUPT_PIN); /* Read config register directly */
printf("%04x:%02x:%02x.%d vendor=%04x device=%04x class=%04x irq=%d (pin %d) base0=%lx",
dev1->domain, dev1->bus, dev1->dev, dev1->func, dev1->vendor_id, dev1->device_id,
dev1->device_class, dev1->irq, c1, (long) dev1->base_addr[0]);
/* Look up and print the full name of the device */
name1 = pci_lookup_name(pacc, namebuf1, sizeof(namebuf1), PCI_LOOKUP_DEVICE, dev1->vendor_id, dev1->device_id);
printf(" ***************** %d: (%s)\n", dev1->dev, name1);
}
pci_cleanup(pacc1); /* Close everything */
Is there a way to check in the loop if the corresponding pci device corresponds to an USB Host Controller? Or is there a simpler way to get USB Host Controller infos?

Nordic SDK printing to serial

I have an Arduino device that runs on the Nordic SDK (it's a Red Bear Lab BLE nano). I want to be able to do a serial print into GTKTerm to be able to debug what is going on in my code. To do this I have the following code:
/*
* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved.
*
* The information contained herein is confidential property of Nordic Semiconductor. The use,
* copying, transfer or disclosure of such information is prohibited except by express written
* agreement with Nordic Semiconductor.
*
*/
/**
* #brief BLE Heart Rate Collector application main file.
*
* This file contains the source code for a sample heart rate collector.
*/
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include "nordic_common.h"
#include "nrf_sdm.h"
#include "ble.h"
#include "ble_hci.h"
#include "ble_db_discovery.h"
#include "softdevice_handler.h"
#include "app_util.h"
#include "app_error.h"
#include "boards.h"
#include "nrf_gpio.h"
#include "pstorage.h"
#include "device_manager.h"
#include "app_trace.h"
#include "ble_hrs_c.h"
#include "ble_bas_c.h"
#include "app_util.h"
#include "app_timer.h"
#include "bsp.h"
#include "bsp_btn_ble.h"
#define UART_TX_BUF_SIZE 256 /**< UART TX buffer size. */
#define UART_RX_BUF_SIZE 1 /**< UART RX buffer size. */
#define STRING_BUFFER_LEN 50
#define BOND_DELETE_ALL_BUTTON_ID 0 /**< Button used for deleting all bonded centrals during startup. */
#define APP_TIMER_PRESCALER 0 /**< Value of the RTC1 PRESCALER register. */
#define APP_TIMER_MAX_TIMERS (2+BSP_APP_TIMERS_NUMBER) /**< Maximum number of simultaneously created timers. */
#define APP_TIMER_OP_QUEUE_SIZE 2 /**< Size of timer operation queues. */
#define APPL_LOG app_trace_log /**< Debug logger macro that will be used in this file to do logging of debug information over UART. */
#define SEC_PARAM_BOND 1 /**< Perform bonding. */
#define SEC_PARAM_MITM 1 /**< Man In The Middle protection not required. */
#define SEC_PARAM_IO_CAPABILITIES BLE_GAP_IO_CAPS_NONE /**< No I/O capabilities. */
#define SEC_PARAM_OOB 0 /**< Out Of Band data not available. */
#define SEC_PARAM_MIN_KEY_SIZE 7 /**< Minimum encryption key size. */
#define SEC_PARAM_MAX_KEY_SIZE 16 /**< Maximum encryption key size. */
#define SCAN_INTERVAL 0x00A0 /**< Determines scan interval in units of 0.625 millisecond. */
#define SCAN_WINDOW 0x0050 /**< Determines scan window in units of 0.625 millisecond. */
#define MIN_CONNECTION_INTERVAL MSEC_TO_UNITS(7.5, UNIT_1_25_MS) /**< Determines minimum connection interval in millisecond. */
#define MAX_CONNECTION_INTERVAL MSEC_TO_UNITS(30, UNIT_1_25_MS) /**< Determines maximum connection interval in millisecond. */
#define SLAVE_LATENCY 0 /**< Determines slave latency in counts of connection events. */
#define SUPERVISION_TIMEOUT MSEC_TO_UNITS(4000, UNIT_10_MS) /**< Determines supervision time-out in units of 10 millisecond. */
#define TARGET_UUID 0x180D /**< Target device name that application is looking for. */
#define MAX_PEER_COUNT DEVICE_MANAGER_MAX_CONNECTIONS /**< Maximum number of peer's application intends to manage. */
#define UUID16_SIZE 2 /**< Size of 16 bit UUID */
/**#breif Macro to unpack 16bit unsigned UUID from octet stream. */
#define UUID16_EXTRACT(DST, SRC) \
do \
{ \
(*(DST)) = (SRC)[1]; \
(*(DST)) <<= 8; \
(*(DST)) |= (SRC)[0]; \
} while (0)
/**#brief Variable length data encapsulation in terms of length and pointer to data */
typedef struct
{
uint8_t * p_data; /**< Pointer to data. */
uint16_t data_len; /**< Length of data. */
}data_t;
typedef enum
{
BLE_NO_SCAN, /**< No advertising running. */
BLE_WHITELIST_SCAN, /**< Advertising with whitelist. */
BLE_FAST_SCAN, /**< Fast advertising running. */
} ble_scan_mode_t;
static ble_db_discovery_t m_ble_db_discovery; /**< Structure used to identify the DB Discovery module. */
static ble_hrs_c_t m_ble_hrs_c; /**< Structure used to identify the heart rate client module. */
static ble_bas_c_t m_ble_bas_c; /**< Structure used to identify the Battery Service client module. */
static ble_gap_scan_params_t m_scan_param; /**< Scan parameters requested for scanning and connection. */
static dm_application_instance_t m_dm_app_id; /**< Application identifier. */
static dm_handle_t m_dm_device_handle; /**< Device Identifier identifier. */
static uint8_t m_peer_count = 0; /**< Number of peer's connected. */
static ble_scan_mode_t m_scan_mode = BLE_FAST_SCAN; /**< Scan mode used by application. */
static uint16_t m_conn_handle; /**< Current connection handle. */
static volatile bool m_whitelist_temporarily_disabled = false; /**< True if whitelist has been temporarily disabled. */
static bool m_memory_access_in_progress = false; /**< Flag to keep track of ongoing operations on persistent memory. */
/**
* #brief Connection parameters requested for connection.
*/
static const ble_gap_conn_params_t m_connection_param =
{
(uint16_t)MIN_CONNECTION_INTERVAL, // Minimum connection
(uint16_t)MAX_CONNECTION_INTERVAL, // Maximum connection
0, // Slave latency
(uint16_t)SUPERVISION_TIMEOUT // Supervision time-out
};
static void scan_start(void);
#define APPL_LOG app_trace_log /**< Debug logger macro that will be used in this file to do logging of debug information over UART. */
/**#brief Function for initializing the UART.
*/
static void uart_init(void)
{
uint32_t err_code;
const app_uart_comm_params_t comm_params =
{
RX_PIN_NUMBER,
TX_PIN_NUMBER,
RTS_PIN_NUMBER,
CTS_PIN_NUMBER,
APP_UART_FLOW_CONTROL_ENABLED,
false,
UART_BAUDRATE_BAUDRATE_Baud38400
};
APP_UART_FIFO_INIT(&comm_params,
UART_RX_BUF_SIZE,
UART_TX_BUF_SIZE,
uart_error_handle,
APP_IRQ_PRIORITY_LOW,
err_code);
APP_ERROR_CHECK(err_code);
app_trace_init();
}
/** #brief Function for the Power manager.
*/
static void power_manage(void)
{
uint32_t err_code = sd_app_evt_wait();
APP_ERROR_CHECK(err_code);
}
int main(void)
{
bool erase_bonds;
// Initialize.
uart_init();
printf("Heart rate collector example (this is a custom log)\r\n");
for (;; )
{
power_manage();
}
}
The problem I am having is that only sometimes I will see an output in GTKterm. I am unable to find a pattern for when it works and when it doesn't. How would I go about debugging this?
How would I go about debugging this?
Some suggestions for starters:
Ensure that your terminal software is asserting the DTR signal. That was the solution found here.
Temporarily remove the call to power_manage() to ensure that is not part of the problem.
Change APP_UART_FLOW_CONTROL_ENABLED for APP_UART_FLOW_CONTROL_DISABLED to determine whether it is a flow control issue. You will not need flow control for output to a PC in any case. It may be needed if you are inputting to the device (especially with a buffer length of 1) or if you are sending to data to a slow device with limited buffering.
Verify ERR_CODE after calling APP_UART_FIFO_INIT to ensure no problems occurred at that stage. Possible error codes are defined here.

error: dereferencing pointer to incomplete type when accessing struct

I am not sure why this is happening. I am doing an assignment and the code somehow does not compile.
This is the header file
#include <stdint.h>
typedef struct
{
uint8_t jump_code[3]; /* Ignore this */
char oemname[8]; /* Might as well ignore this one too */
uint8_t ssize[2]; /* Sector size in bytes */
uint8_t csize; /* Cluster size in sectors */
uint8_t reserved[2]; /* Number of reserved sectors for boot sectors */
uint8_t numfat; /* Number of FATs */
uint8_t numroot[2]; /* Number of Root directory entries */
uint8_t sectors16[2]; /* number of sectors in the file system */
uint8_t media[1]; /* Media descriptor type */
uint8_t sectperfat16[2];/* Number of sectors per FAT */
uint8_t sectpertrack[2];/* Number of sectors per track */
uint8_t heads[2]; /* Number of heads */
uint8_t prevsect[2]; /* Number of sectors before FS partition */
uint8_t ignore[482]; /* Ignore these */
} boot_sect_t;
This is the part that gives the error:
struct boot_sect_t* boot = malloc(sizeof(boot_sect_t));
boot->ssize[0] = buffer[11]; //error here
boot->ssize[1] = buffer[12]; //error here
The error is:
error: dereferencing pointer to incomplete type when accessing struct
you need to change
struct boot_sect_t* boot = malloc(sizeof(boot_sect_t));
to
boot_sect_t* boot = malloc(sizeof(boot_sect_t));
boot_sect_t is already a typedef. no need to write struct boot_sect_t.

issue with C pwrite(); extra bytes got written to file

I am having a weird issue when i do a pwrite a struct to a file. It adds a single byte with next to a char entry in the struct. When i tried to write the char alone to a file it correctly wrote a single byte. Could some one tell me why the single byte got added??
int main(){
typedef struct pcap_hdr_s {
guint32 magic_number; /* magic number */
guint16 version_major; /* major version number */
guint16 version_minor; /* minor version number */
gint32 thiszone; /* GMT to local correction */
guint32 sigfigs; /* accuracy of timestamps */
guint32 snaplen; /* max length of captured packets, in octets */
guint32 network; /* data link type */
guint32 ts_sec; /* timestamp seconds */
guint32 ts_usec; /* timestamp microseconds */
guint32 incl_len; /* number of octets of packet saved in file */
guint32 orig_len; /* actual length of packet */
guint16 fcf;
char seqno;
guint16 dpan;
guint16 daddr;
guint16 saddr;
gint16 payload_data;
} pcaprec_hdr_t;
pcaprec_hdr_t packet_header;
packet_header.magic_number = PCAP_MAGIC;
packet_header.version_major = 2;
packet_header.version_minor = 4;
packet_header.thiszone = 0;
packet_header.sigfigs = 0;
packet_header.snaplen = 65535;
packet_header.network = 195;
struct timeval tv;
gettimeofday(&tv, NULL);
packet_header.ts_sec = tv.tv_sec;
packet_header.ts_usec = tv.tv_usec;
packet_header.incl_len = 11;
packet_header.orig_len = 13;
packet_header.seqno = 255;
packet_header.dpan = 65535;
packet_header.daddr = 65535;
packet_header.saddr = 65535;
packet_header.payload_data = 8;
int fd = open("sample.cap", O_CREAT | O_WRONLY);
printf("Bytes written: %d \n",pwrite(fd, &packet_header, sizeof(packet_header),0));
}
The struct has a char var "seq" and next to the seq no value a single byte of random value gets added in the file.
Your structure contains a char data member and you probably have word-alignment on. See if you can find a "pack" option in the compiler.
You can probably use a #pragma pack(1) or similar pragma (pragma's are implementation specific) to change the alignment for a particular set of classes.
Be careful though, the compiler word-aligns for performance reasons. The memory bus typically works on word boundaries, so you could end up requiring two fetchs for each word that straddles the word boundary thereby slowing memory access down a bit.
You might want to stream the structure members out individually if you're concerned about the added bytes in the file.

Resources