I have the following code
int ParseData(unsigned char *packet, int len)
{
struct ethhdr *ethernet_header;
struct iphdr *ip_header;
struct tcphdr *tcp_header;
unsigned char *data;
int data_len;
/* Check if any data is there */
if(len > (sizeof(struct ethhdr) + sizeof(struct iphdr) + sizeof(struct tcphdr)))
{
ip_header = (struct iphdr*)(packet + sizeof(struct ethhdr));
data = (packet + sizeof(struct ethhdr) + ip_header->ihl*4 + sizeof(struct tcphdr));
data_len = ntohs(ip_header->tot_len) - ip_header->ihl*4 - sizeof(struct tcphdr);
if(data_len)
{
printf("Data Len : %d\n", data_len);
PrintData("Data : ", data, data_len);
printf("\n\n");
return 1;
}
else
{
printf("No Data in packet\n");
return 0;
}
}
}
I am trying to print in ASCII the payload and with a simple function like this
PrintData(char *mesg, unsigned char *p, int len)
{
printf(mesg);
while(len--)
{
if(isprint(*p))
printf("%c", *p);
else
printf(".");
p++;
}
}
The code looks good, no compile problems/warning. The problem is that the first payload
character is not being print at position 0, but 12 bytes later.
I thought that all the "len" bytes are the exact data I have to print.
My data point at
data = (packet + sizeof(struct ethhdr) + ip_header->ihl*4 + sizeof(struct tcphdr));
however data[0] is not printable. What is the problem? Do I miss something? Do I have to check for the TCP options part maybe?
Thanks
That's right, adding the sizeof(struct tcphdr) is only going to get you past the header, not the options. To get to the actual data, you should use the 'offset' field from the TCP header. The offset is calculated from the start of the TCP header and is in 4-byte units, e.g. if the offset is 8 then the header + options length is 32.
Related
I am validating DPDK receive functionality & for this I'm shooting a pcap externally &
added code in l2fwd to dump received packets to pcap, the l2fwd dumped pcap have all the packets from shooter but some of them are not in sequence.
Shooter is already validated.
DPDK version in use-21.11
link of the pcap used : https://wiki.wireshark.org/uploads/__moin_import__/attachments/SampleCaptures/tcp-ecn-sample.pcap
Out of order packets are random. For the first run I saw no jumbled packets but was able to replicate the issue on second run with the 2nd,3rd,4th packets jumbled having order 3,4,2.
Below is snipped from l2fwd example & our modifications as //TESTCODE..
/* Read packet from RX queues. 8< */
for (i = 0; i < qconf->n_rx_port; i++) {
portid = qconf->rx_port_list[i];
nb_rx = rte_eth_rx_burst(portid, 0,
pkts_burst, MAX_PKT_BURST);
port_statistics[portid].rx += nb_rx;
for (j = 0; j < nb_rx; j++) {
m = pkts_burst[j];
// TESTCODE_STARTS
uint8_t* pkt = rte_pktmbuf_mtod(m, uint8_t*);
dump_to_pcap(pkt, rte_pktmbuf_pkt_len(m));
// TESTCODE_ENDS
rte_prefetch0(rte_pktmbuf_mtod(m, void *));
l2fwd_simple_forward(m, portid);
}
}
/* >8 End of read packet from RX queues. */
Below is code for dump_to_pcap
static int
dump_to_pcap(uint8_t* pkt, int pkt_len)
{
static FILE* fp = NULL;
static int init_file = 0;
if (0 == init_file) {
printf("Creating pcap\n");
char pcap_filename[256] = { 0 };
char Two_pcap_filename[256] = { 0 };
currentDateTime(pcap_filename);
sprintf(Two_pcap_filename,".\\Rx_%d_%s.pcap", 0, pcap_filename);
printf("FileSName to Create: %s\n", Two_pcap_filename);
fp = fopen(Two_pcap_filename, "wb");
if (NULL == fp) {
printf("Unable to open file\n");
fp = NULL;
}
else {
printf("File create success..\n");
init_file = 1;
typedef struct pcap_file_header1 {
unsigned int magic; // a 32-bit "magic number"
unsigned short version_major; //a 16-bit major version number
unsigned short version_minor; //a 16-bit minor version number
unsigned int thiszone; //a 32-bit "time zone offset" field that's actually not used, so ou can (and probably should) just make it 0
unsigned int sigfigs; //a 32-bit "time stamp accuracy" field that's not actually used,so you can (and probably should) just make it 0;
unsigned int snaplen; //a 32-bit "snapshot length" field
unsigned int linktype; //a 32-bit "link layer type" field
}dumpFileHdr;
dumpFileHdr file_hdr;
file_hdr.magic = 2712847316; //0xa1b2c3d4;
file_hdr.version_major = 2;
file_hdr.version_minor = 4;
file_hdr.thiszone = 0;
file_hdr.sigfigs = 0;
file_hdr.snaplen = 65535;
file_hdr.linktype = 1;
fwrite((void*)(&file_hdr), sizeof(dumpFileHdr), 1, fp);
//printf("Pcap Header written\n");
}
}
typedef struct pcap_pkthdr1 {
unsigned int ts_sec; /* time stamp */
unsigned int ts_usec;
unsigned int caplen; /* length of portion present */
unsigned int len; /* length this packet (off wire) */
}dumpPktHdr;
dumpPktHdr pkt_hdr;
static int ts_sec = 1;
pkt_hdr.ts_sec = ts_sec++;
pkt_hdr.ts_usec = 0;
pkt_hdr.caplen = pkt_hdr.len = pkt_len;
if (NULL != fp) {
fwrite((void*)(&pkt_hdr), sizeof(dumpPktHdr), 1, fp);
fwrite((void*)(pkt), pkt_len, 1, fp);
fflush(fp);
}
return 0;
}
How could I guarantee the integrity of the code of an iOS app? I've been taking a look to Apple's Security Overview document, would code signing be enough? Is there any other recommended mechanism to guarantee the code integrity?
Thanks in advance
I had a same problem. This is easy on OS X but somewhat difficult in iOS because iOS doesn't have API like SecStaticCodeCheckValidity.
There are two sections in mach-o binary that you can use to ensure integrity of the app.
LC_ENCRYPTION_INFO
LC_CODE_SIGNATURE
1. LC_ENCRYPTION_INFO
First, LC_ENCRYPTION_INFO stores informations about 'app store encryption'. Once an app is uploaded to app store, app is encrypted before it is released to users.
binary before uploading to appstore or decrypted
otool -l [binary] | grep LC_ENCRYPTION_INFO -A5
cmd LC_ENCRYPTION_INFO
cmdsize 20
cryptoff 16384
cryptsize 5783552
cryptid 0
--
cmd LC_ENCRYPTION_INFO_64
cmdsize 24
cryptoff 16384
cryptsize 6635520
cryptid 0
pad 0
binary after uploading to appstore (encrypted)
otool -l [binary] | grep LC_ENCRYPTION_INFO -A5
cmd LC_ENCRYPTION_INFO
cmdsize 20
cryptoff 16384
cryptsize 5783552
cryptid 1
--
cmd LC_ENCRYPTION_INFO_64
cmdsize 24
cryptoff 16384
cryptsize 6635520
cryptid 1
pad 0
As you can see, 'cryptid' is set to 1 when app is uploaded. So checking 'cryptid' bit will tell us if the binary is encrypted or not.
You may think that this can be bypassed easily by just setting the bit to 1, but then OS will try to decrypt the binary which will make the codes to unrecognizable bytes.
bool isBinaryEncrypted()
{
// checking current binary's LC_ENCRYPTION_INFO
const void *binaryBase;
struct load_command *machoCmd;
const struct mach_header *machoHeader;
NSString *path = [[NSBundle mainBundle] executablePath];
NSData *filedata = [NSData dataWithContentsOfFile:path];
binaryBase = (char *)[filedata bytes];
machoHeader = (const struct mach_header *) binaryBase;
if(machoHeader->magic == FAT_CIGAM)
{
unsigned int offset = 0;
struct fat_arch *fatArch = (struct fat_arch *)((struct fat_header *)machoHeader + 1);
struct fat_header *fatHeader = (struct fat_header *)machoHeader;
for(uint32_t i = 0; i < ntohl(fatHeader->nfat_arch); i++)
{
if(sizeof(int *) == 4 && !(ntohl(fatArch->cputype) & CPU_ARCH_ABI64)) // check 32bit section for 32bit architecture
{
offset = ntohl(fatArch->offset);
break;
}
else if(sizeof(int *) == 8 && (ntohl(fatArch->cputype) & CPU_ARCH_ABI64)) // and 64bit section for 64bit architecture
{
offset = ntohl(fatArch->offset);
break;
}
fatArch = (struct fat_arch *)((uint8_t *)fatArch + sizeof(struct fat_arch));
}
machoHeader = (const struct mach_header *)((uint8_t *)machoHeader + offset);
}
if(machoHeader->magic == MH_MAGIC) // 32bit
{
machoCmd = (struct load_command *)((struct mach_header *)machoHeader + 1);
}
else if(machoHeader->magic == MH_MAGIC_64) // 64bit
{
machoCmd = (struct load_command *)((struct mach_header_64 *)machoHeader + 1);
}
for(uint32_t i=0; i < machoHeader->ncmds && machoCmd != NULL; i++){
if(machoCmd->cmd == LC_ENCRYPTION_INFO)
{
struct encryption_info_command *cryptCmd = (struct encryption_info_command *) machoCmd;
return cryptCmd->cryptid;
}
if(machoCmd->cmd == LC_ENCRYPTION_INFO_64)
{
struct encryption_info_command_64 *cryptCmd = (struct encryption_info_command_64 *) machoCmd;
return cryptCmd->cryptid;
}
machoCmd = (struct load_command *)((uint8_t *)machoCmd + machoCmd->cmdsize);
}
return FALSE; // couldn't find cryptcmd
}
2. LC_CODE_SIGNATURE
LC_CODE_SIGNATURE is the section that /usr/bin/codesign actually refers when checking validity of the binary. But parsing the section is a little bit more difficult than parsing LC_ENCRYPTION_INFO, because it's undocumented and there are no types like signature_info_command.
LC_CODE_SIGNATURE contains hashes of all of the binary except the section itself, and hashes are adjusted whenever it's re-signed.
I ported the codes of /usr/bin/codesign to parse this section. check here and SecStaticCode::validateExecutable defined in here
CodeSigning.h
#ifndef CodeSigning_h
#define CodeSigning_h
#include <stdio.h>
// codes from https://opensource.apple.com/source/Security/Security-55179.1/libsecurity_codesigning/lib/cscdefs.h
enum {
CSMAGIC_REQUIREMENT = 0xfade0c00, /* single Requirement blob */
CSMAGIC_REQUIREMENTS = 0xfade0c01, /* Requirements vector (internal requirements) */
CSMAGIC_CODEDIRECTORY = 0xfade0c02, /* CodeDirectory blob */
CSMAGIC_EMBEDDED_SIGNATURE = 0xfade0cc0, /* embedded form of signature data */
CSMAGIC_DETACHED_SIGNATURE = 0xfade0cc1, /* multi-arch collection of embedded signatures */
CSSLOT_CODEDIRECTORY = 0, /* slot index for CodeDirectory */
};
/*
* Structure of an embedded-signature SuperBlob
*/
typedef struct __BlobIndex {
uint32_t type; /* type of entry */
uint32_t offset; /* offset of entry */
} CS_BlobIndex;
typedef struct __SuperBlob {
uint32_t magic; /* magic number */
uint32_t length; /* total length of SuperBlob */
uint32_t count; /* number of index entries following */
CS_BlobIndex index[]; /* (count) entries */
/* followed by Blobs in no particular order as indicated by offsets in index */
} CS_SuperBlob;
/*
* C form of a CodeDirectory.
*/
typedef struct __CodeDirectory {
uint32_t magic; /* magic number (CSMAGIC_CODEDIRECTORY) */
uint32_t length; /* total length of CodeDirectory blob */
uint32_t version; /* compatibility version */
uint32_t flags; /* setup and mode flags */
uint32_t hashOffset; /* offset of hash slot element at index zero */
uint32_t identOffset; /* offset of identifier string */
uint32_t nSpecialSlots; /* number of special hash slots */
uint32_t nCodeSlots; /* number of ordinary (code) hash slots */
uint32_t codeLimit; /* limit to main image signature range */
uint8_t hashSize; /* size of each hash in bytes */
uint8_t hashType; /* type of hash (cdHashType* constants) */
uint8_t spare1; /* unused (must be zero) */
uint8_t pageSize; /* log2(page size in bytes); 0 => infinite */
uint32_t spare2; /* unused (must be zero) */
/* followed by dynamic content as located by offset fields above */
} CS_CodeDirectory;
static inline const CS_CodeDirectory *findCodeDirectory(const CS_SuperBlob *embedded)
{
if (embedded && ntohl(embedded->magic) == CSMAGIC_EMBEDDED_SIGNATURE) {
const CS_BlobIndex *limit = &embedded->index[ntohl(embedded->count)];
const CS_BlobIndex *p;
for (p = embedded->index; p < limit; ++p)
if (ntohl(p->type) == CSSLOT_CODEDIRECTORY) {
const unsigned char *base = (const unsigned char *)embedded;
const CS_CodeDirectory *cd = (const CS_CodeDirectory *)(base + ntohl(p->offset));
if (ntohl(cd->magic) == CSMAGIC_CODEDIRECTORY){
return cd;
}
else{
break;
}
}
}
// not found
return NULL;
}
//
unsigned char validateSlot(const void *data, size_t length, size_t slot, const CS_CodeDirectory *codeDirectory);
#endif /* CodeSigning_h */
CodeSigning.c
#include "CodeSigning.h"
#include <stdio.h>
#include <string.h>
#import <CommonCrypto/CommonDigest.h>
unsigned char validateSlot(const void *data, size_t length, size_t slot, const CS_CodeDirectory *codeDirectory)
{
uint8_t digest[CC_SHA1_DIGEST_LENGTH + 1] = {0, };
CC_SHA1(data, (CC_LONG)length, digest);
return (memcmp(digest, (void *)((char *)codeDirectory + ntohl(codeDirectory->hashOffset) + 20*slot), 20) == 0);
}
parsing the section
void checkCodeSignature(void *binaryContent){
struct load_command *machoCmd;
const struct mach_header *machoHeader;
machoHeader = (const struct mach_header *) binaryContent;
if(machoHeader->magic == FAT_CIGAM){
unsigned int offset = 0;
struct fat_arch *fatArch = (struct fat_arch *)((struct fat_header *)machoHeader + 1);
struct fat_header *fatHeader = (struct fat_header *)machoHeader;
for(uint32_t i = 0; i < ntohl(fatHeader->nfat_arch); i++)
{
if(sizeof(int *) == 4 && !(ntohl(fatArch->cputype) & CPU_ARCH_ABI64)) // check 32bit section for 32bit architecture
{
offset = ntohl(fatArch->offset);
break;
}
else if(sizeof(int *) == 8 && (ntohl(fatArch->cputype) & CPU_ARCH_ABI64)) // and 64bit section for 64bit architecture
{
offset = ntohl(fatArch->offset);
break;
}
fatArch = (struct fat_arch *)((uint8_t *)fatArch + sizeof(struct fat_arch));
}
machoHeader = (const struct mach_header *)((uint8_t *)machoHeader + offset);
}
if(machoHeader->magic == MH_MAGIC) // 32bit
{
machoCmd = (struct load_command *)((struct mach_header *)machoHeader + 1);
}
else if(machoHeader->magic == MH_MAGIC_64) // 64bit
{
machoCmd = (struct load_command *)((struct mach_header_64 *)machoHeader + 1);
}
for(uint32_t i=0; i < machoHeader->ncmds && machoCmd != NULL; i++){
if(machoCmd->cmd == LC_CODE_SIGNATURE)
{
struct linkedit_data_command *codeSigCmd = (struct linkedit_data_command *) machoCmd;
const CS_SuperBlob *codeEmbedded = (const CS_SuperBlob *)&((char *)machoHeader)[codeSigCmd->dataoff];
void *binaryBase = (void *)machoHeader;
const CS_BlobIndex curIndex = codeEmbedded->index[0];
const CS_CodeDirectory *codeDirectory = (const CS_CodeDirectory *)((char *)codeEmbedded + ntohl(curIndex.offset));
size_t pageSize = codeDirectory->pageSize ? (1 << codeDirectory->pageSize) : 0;
size_t remaining = ntohl(codeDirectory->codeLimit);
size_t processed = 0;
for(size_t slot = 0; slot < ntohl(codeDirectory->nCodeSlots); ++slot){
size_t size = MIN(remaining, pageSize);
if(!validateSlot(binaryBase+processed, size, slot, codeDirectory)){
return;
}
processed += size;
remaining -= size;
}
printf("[*] Code is valid!");
}
}
machoCmd = (struct load_command *)((uint8_t *)machoCmd + machoCmd->cmdsize);
}
I wrote a dissector,
I found one packet which contains couple of different/indifferent messages inside it,
Can someone point on the problem ?
Is this even a problem ?
I reassemble TCP packets...
This is the function of dissection:
(FRAME_HEADER_LEN = 8)
static void
dissect_PROTOC(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
//Reassembling TCP fragments
tcp_dissect_pdus(tvb, pinfo, tree, TRUE, FRAME_HEADER_LEN,
get_PROTOC_message_len, dissect_PROTOC_message);
}
static guint get_PROTOC_message_len(packet_info *pinfo, tvbuff_t *tvb, int offset)
{
/* the packet's size is "length" + 4bytes of TYPESIZE + 4bytes of LENGTHSIZE + 256bytes of CONTEXTIDSIZE */
return (guint)(tvb_get_ntohl(tvb, offset + 4) + CONTEXT_ID_SIZE + TYPE_SIZE + LENGTH_SIZE); /* e.g. length is at offset 4 */
}
static void dissect_PROTOC_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
/* my dissecting code */
guint32 packet_type = tvb_get_ntohl(tvb, 0);
col_set_str(pinfo->cinfo, COL_PROTOCOL, "PROTOC");
/* Clear out stuff in the info column */
col_clear(pinfo->cinfo,COL_INFO);
col_add_fstr(pinfo->cinfo, COL_INFO, "%d > %d [%s]",pinfo->srcport, pinfo->destport,
val_to_str(packet_type, packettypenames, "Unknown (0x%02x)"));
if (tree) { /* we are being asked for details */
proto_item *ti = NULL;
proto_tree *PROTOC_tree = NULL;
proto_item *PROTOC_data = NULL;
proto_tree *PROTOC_data_tree = NULL;
guint32 type = 0;
guint32 length = 0;
gint offset = 0;
ti = proto_tree_add_item(tree, proto_PROTOC, tvb, 0, -1, ENC_NA);
proto_item_append_text(ti, ", Type: %s",
val_to_str(packet_type, packettypenames, "Unknown (0x%02x)"));
PROTOC_tree = proto_item_add_subtree(ti, ett_PROTOC);
//getting type
type = tvb_get_ntohl(tvb, offset);
proto_tree_add_item(PROTOC_tree, hf_PROTOC_pdu_type, tvb, 0, TYPE_SIZE, ENC_BIG_ENDIAN);
offset += TYPE_SIZE;
//getting length for the data length
length = tvb_get_ntohl(tvb, offset);
proto_tree_add_item(PROTOC_tree, hf_PROTOC_len, tvb, offset, LENGTH_SIZE, ENC_BIG_ENDIAN);
offset += LENGTH_SIZE;
proto_tree_add_item(PROTOC_tree, hf_PROTOC_contextid, tvb, offset, CONTEXT_ID_SIZE, ENC_BIG_ENDIAN);
offset += CONTEXT_ID_SIZE;
PROTOC_data = proto_tree_add_item(PROTOC_tree, hf_PROTOC_data, tvb, offset, length, FALSE);
PROTOC_data_tree = proto_item_add_subtree(PROTOC_data, ett_PROTOC_data);
offset += length;
}
}
I found one packet which contains couple of different/indifferent messages inside it,
...
I reassemble TCP packets...
That's pretty common for protocols running over TCP; there is no guarantee that TCP segment boundaries will correspond to packet boundaries in protocols running on top of TCP. A TCP segment can contain parts of, or all of, more than one higher-level protocol packet, and a higher-level protocol packet can be composed of data from more than one TCP segment.
I'm wrote a wireshark dissector named PLUGIN.
Now when I'm testing it, for some reason a packet of type X can be seen on the wireshark as PLUGIN (like it should), and some other packets afterwards, of the same type X cannot be seen as PLUGIN.
The other packets can be found in the .pcap as [TCP segment of a reassembled PDU]
The question is: why doesn't WireShark dissect other packets of type X like the first packet of type X and shows it to me as PLUGIN ?
Why does the dissection works only for the first time?
I use functions for assembling fragments of chopped packets:
tcp_dissect_pdus()
get_PLUGIN_message_len()
as written in "9.4.2. How to reassemble split TCP Packets"
in "http://www.wireshark.org/docs/wsdg_html_chunked/ChDissectReassemble.html#TcpDissectPdus"
This is the function of dissection:
(FRAME_HEADER_LEN = 8)
static void
dissect_PROTOC(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
//Reassembling TCP fragments
tcp_dissect_pdus(tvb, pinfo, tree, TRUE, FRAME_HEADER_LEN,
get_PROTOC_message_len, dissect_PROTOC_message);
}
static guint get_PROTOC_message_len(packet_info *pinfo, tvbuff_t *tvb, int offset)
{
/* the packet's size is "length" + 4bytes of TYPESIZE + 4bytes of LENGTHSIZE + 256bytes of CONTEXTIDSIZE */
return (guint)(tvb_get_ntohl(tvb, offset + 4) + CONTEXT_ID_SIZE + TYPE_SIZE + LENGTH_SIZE); /* e.g. length is at offset 4 */
}
static void dissect_PROTOC_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
/* my dissecting code */
guint32 packet_type = tvb_get_ntohl(tvb, 0);
col_set_str(pinfo->cinfo, COL_PROTOCOL, "PROTOC");
/* Clear out stuff in the info column */
col_clear(pinfo->cinfo,COL_INFO);
col_add_fstr(pinfo->cinfo, COL_INFO, "%d > %d [%s]",pinfo->srcport, pinfo->destport,
val_to_str(packet_type, packettypenames, "Unknown (0x%02x)"));
if (tree) { /* we are being asked for details */
proto_item *ti = NULL;
proto_tree *PROTOC_tree = NULL;
proto_item *PROTOC_data = NULL;
proto_tree *PROTOC_data_tree = NULL;
guint32 type = 0;
guint32 length = 0;
gint offset = 0;
ti = proto_tree_add_item(tree, proto_PROTOC, tvb, 0, -1, ENC_NA);
proto_item_append_text(ti, ", Type: %s",
val_to_str(packet_type, packettypenames, "Unknown (0x%02x)"));
PROTOC_tree = proto_item_add_subtree(ti, ett_PROTOC);
//getting type
type = tvb_get_ntohl(tvb, offset);
proto_tree_add_item(PROTOC_tree, hf_PROTOC_pdu_type, tvb, 0, TYPE_SIZE, ENC_BIG_ENDIAN);
offset += TYPE_SIZE;
//getting length for the data length
length = tvb_get_ntohl(tvb, offset);
proto_tree_add_item(PROTOC_tree, hf_PROTOC_len, tvb, offset, LENGTH_SIZE, ENC_BIG_ENDIAN);
offset += LENGTH_SIZE;
proto_tree_add_item(PROTOC_tree, hf_PROTOC_contextid, tvb, offset, CONTEXT_ID_SIZE, ENC_BIG_ENDIAN);
offset += CONTEXT_ID_SIZE;
PROTOC_data = proto_tree_add_item(PROTOC_tree, hf_PROTOC_data, tvb, offset, length, FALSE);
PROTOC_data_tree = proto_item_add_subtree(PROTOC_data, ett_PROTOC_data);
offset += length;
}
}
more information:
I opened the file.pcap on some hex editor and I can see my packets that the wireshark doesn't dissect...
Inside wireshark I can find a packet that wireshark doesn't dissect, with the info of: "[TCP segment of a reassembled PDU]", but it doesn't say to which reassemble packet it belong, and I can't find it anywhere...
I would speculate that your calculated length does not match the reality. If wireshark does not think it has all the frames it needs to complete the PDU, then I guess it might not call dissect_PROTOC_message()
You could try to print your calculated lengths and then verify that the pcap file contains that many frames:
static guint get_PROTOC_message_len(packet_info *pinfo, tvbuff_t *tvb, int offset)
{
/* the packet's size is "length" + 4bytes of TYPESIZE + 4bytes of LENGTHSIZE + 256bytes of CONTEXTIDSIZE */
guint len = (guint)(tvb_get_ntohl(tvb, offset + 4) + CONTEXT_ID_SIZE + TYPE_SIZE + LENGTH_SIZE); /* e.g. length is at offset 4 */
g_warning("frame=%d PDU len=%d", pinfo->fd->num, len);
return len;
}
I wrote module for a device, and I'm having problems in my read function:
ssize_t my_sys_read(struct file *f, char __user *buffer, size_t s, loff_t *off){
char * myBuffer = "ossec buffer";
size_t read_bytes;
if (s > ( sizeof(char) * 13 ) ) s = ( sizeof(char) * 13 );
if (!access_ok(%VERIFY_WRITE, (void *) buffer, s)) return -EFAULT;
read_bytes = copy_to_user((void *) buffer, (void *) myBuffer, s);
printk(KERN_INFO "myBuffer %s", myBuffer);
printk(KERN_INFO "buffer %s", buffer);
read_bytes = s - ( sizeof(char) * 13 );
return read_bytes;
}
I really don't know why but the copy it's not working, and the printed buffer has no sense for me.
[10038.885838] buffer \xffffff81\xffffffc3\xffffffcb\x1a
I guess the problem is in the copy because the program which use the device is simple.
int main(void)
{
int fd = open(device_name, O_RDONLY);
if(fd < 0)
{
printf("Error: Impossible to open device, action not permited.\n");
return 0;
}
char * buff;
int read_bytes;
read_bytes = read(fd, buff, (13 * sizeof(char) ) );
printf(" %s\n", buff);
}
Thanks!
char * buff;
int read_bytes;
read_bytes = read(fd, buff, (13 * sizeof(char) ) );
You are using the pointer buff without allocating memory for it, it is then a dangling pointer with a random value. You need to do
char *buff = new char(); or
char buff;
int read_bytes;
read_bytes = read(fd, &buff, (13 * sizeof(char)) );