how can I print the bits of inode bitmap which is fetched as an unsigned char? this is my code which is used to fetch bitmap.what i want to do is to print the bitmap in binary format.
#include <cstdlib>
#include <ext2fs/ext2fs.h>
#include <linux/fs.h>
#include <iostream>
#include <stdio.h>
#include <fstream>
#include <fcntl.h>
using namespace std;
int main() {
int fd, block_size;
char boot[1024];
struct ext2_super_block super_block;
fd = open("/dev/sda6", O_RDONLY);
printf("Error: %s\n", strerror(errno));
/* Reads the boot section and the superblock */
read(fd, boot, 1024);
read(fd, &super_block, sizeof (struct ext2_super_block));
if (super_block.s_magic != EXT2_SUPER_MAGIC) {
fprintf(stderr, "Not an Ext2 filesystem!\n");
getchar();
exit(1);
}
/* Prints the Magic Number */
// printf("%x\n", super_block.s_magic);
printf("%x\n", super_block.s_log_block_size);
block_size = 4096 << super_block.s_log_block_size;
/* calculate number of block groups on the disk */
unsigned int group_count =
1 + (super_block.s_blocks_count - 1) / super_block.s_blocks_per_group;
/* calculate size of the group descriptor list in bytes */
unsigned int descr_list_size =
group_count * sizeof (struct ext2_group_desc);
struct ext2_group_desc group_descr;
/* position head above the group descriptor block */
lseek(fd, 1024 + block_size, SEEK_SET);
read(fd, &group_descr, sizeof (group_descr));
/* location of the super-block in the first group */
#define BASE_OFFSET 1024
#define BLOCK_OFFSET(block) (BASE_OFFSET + (block-1)*block_size)
struct ext2_super_block super;
struct ext2_group_desc group;
unsigned char *bitmap, bits[8];
/* the super block */
/* the group descritopr */
/* ... [read superblock and group descriptor] ... */
bitmap = (unsigned char*) malloc(block_size);
/* allocate memory for the bitmap */
lseek(fd, BLOCK_OFFSET(group.bg_block_bitmap), SEEK_SET);
read(fd, bitmap, block_size);
/* read bitmap from disk */
unsigned char* bla = (unsigned char*) bitmap;
printf("bitmap: ");
for (int i = 0; i < block_size; i++) {
printf("%x", &bitmap[i]);
}
free(bitmap);
printf("%x\n", block_size);
close(fd);
return 0;
}
i'm a little doubtfull about this code.how can I be sure about the result.I'm running it on ubuntu 12.4 ex4 file system.
EDIT : I've made a raw disk image and tried to read it but get the error that it's not a EXtended2 file system?
this is the address which i used :
fd = open("/dev/zero", O_RDONLY);
Related
i try to write to the Linux framebuffer with c++, my problem is, that my program cant write to the whole screen, because the screensize i get is wrong. Although this code worked on an older VM, but i lost it.
#include <fcntl.h>
#include <unistd.h>
#include <linux/fb.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <cerrno>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
int main() {
fb_var_screeninfo vinfo;
fb_fix_screeninfo finfo;
size_t screensize = 0;
long int location = 0;
/* Open the file for reading and writing */
int fbfd = open("/dev/fb0", O_RDWR);
if(fbfd == -1) {
perror("Error: cannot open framebuffer device");
exit(1);
}
printf("The framebuffer device was opened successfully.\n");
/* Get fixed screen information */
if(ioctl(fbfd, FBIOGET_FSCREENINFO, &finfo) == -1) {
perror("Error reading fixed information");
exit(2);
}
/* Get variable screen information */
if(ioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo) == -1) {
perror("Error reading variable information");
exit(3);
}
/* Figure out the size of the screen in bytes */
screensize = vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8;
printf("Screen size is %ld\n", screensize);
printf("Vinfo.bpp = %d\n", vinfo.bits_per_pixel);
/* Map the device to memory */
auto fbp = static_cast<unsigned char*>(
mmap(0, screensize, PROT_READ | PROT_WRITE, MAP_SHARED, fbfd, 0));
if(fbp == MAP_FAILED) {
perror("Error: failed to map framebuffer device to memory");
exit(4);
}
printf("The framebuffer device was mapped to memory successfully.\n");
unsigned x = 0;
unsigned y = 0; /* Where we are going to put the pixel */
/* Figure out where in memory to put the pixel */
location = (x + vinfo.xoffset) * (vinfo.bits_per_pixel / 8) +
(y + vinfo.yoffset) * finfo.line_length;
for(uint32_t i = 0; i < vinfo.yres; i++) {
for(uint32_t count = 1; count < vinfo.xres; count++) {
fbp[location++] = 255; /* Some blue */
fbp[location++] = 0; /* A little green */
fbp[location++] = 0; /* A lot of red */
fbp[location++] = 0; /* No transparency */
}
}
munmap(fbp, screensize);
close(fbfd);
return 0;
}
I tried increasing the screensize by multiplying it by 2 and it wrote to the full screen, but then my coordinates are wrong.
I have a problem with a program in C. I need the absolute memory address of the local variables to the function main. I am debugging with the gdb.
How to know if there is an overflow in the variables.
Thank you
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <ctype.h>
typedef int16_t int16;
#include "mulaw.h"
void decodeFile(FILE * fIn, FILE * fOut, uint32_t samples) {
uint32_t i;
uint8_t * inSamples = malloc(samples * sizeof(uint8_t));
int16_t * outSamples = malloc(samples * sizeof(int16_t));
fread(inSamples, sizeof(uint8_t), samples, fIn);
for (i = 0; i < samples; i++) {
outSamples[i] = 4 * muLaw[inSamples[i]];
}
fwrite(outSamples, sizeof(int16_t), samples, fOut);
free(inSamples);
free(outSamples);
}
#define MAX_FILE_SIZE 256
int main(int argc, char **argv)
{
char inputFile[MAX_FILE_SIZE];
char outputFile[MAX_FILE_SIZE];
FILE * fIn = NULL, * fOut = NULL;
struct header_t {
char ChunkID[4];
int32_t ChunkSize;
char Format[4];
} header;
char SubchunkID[4];
uint32_t SubchunkSize;
struct subheader_t {
int16_t AudioFormat;
int16_t NumChannels;
int32_t SampleRate;
int32_t ByteRate;
int16_t BlockAlign;
int16_t BitsPerSample;
int16_t ExtraParamSize;
int16_t Padding;
} subheader;
/* Usage */
if (argc != 3) {
puts("Usage is: mulaw INFILE OUTFILE\n");
exit(EXIT_FAILURE);
}
/* Careful here!!!!! */
strncpy(inputFile, argv[1], MAX_FILE_SIZE);
strncpy(outputFile, argv[2], MAX_FILE_SIZE);
/* Open input file */
fIn = fopen (inputFile, "rb");
/* Read main header */
fread(&header, sizeof(struct header_t), 1, fIn);
if (memcmp(header.ChunkID, "RIFF", 4) != 0
|| memcmp(header.Format, "WAVE", 4) != 0) {
fprintf(stderr, "Unknown input format\n");
exit(EXIT_FAILURE);
}
/* Read sub header */
while (fread(SubchunkID, sizeof(SubchunkID), 1, fIn)) {
fread(&SubchunkSize, sizeof(SubchunkSize), 1, fIn);
printf("Reading chunk of type %c%c%c%c (%d bytes)\n",
isprint(SubchunkID[0]) ? SubchunkID[0] : '?',
isprint(SubchunkID[1]) ? SubchunkID[1] : '?',
isprint(SubchunkID[2]) ? SubchunkID[2] : '?',
isprint(SubchunkID[3]) ? SubchunkID[3] : '?',
(int) SubchunkSize);
if (memcmp(SubchunkID, "fmt ", 4) == 0) {
/* read a fmt_ header */
fread(&subheader, SubchunkSize, 1, fIn);
/* we are going to adjust this header now to change the audio format */
if (subheader.AudioFormat != 7) {
fprintf(stderr, "Only mu-law audio input is supported\n");
exit(EXIT_FAILURE);
}
/* adjust audio format and bit depth */
subheader.AudioFormat = 1;
subheader.BitsPerSample = 16;
/* fix derivative fields */
subheader.ByteRate = subheader.SampleRate * subheader.NumChannels * subheader.BitsPerSample / 8;
subheader.BlockAlign = subheader.NumChannels * subheader.BitsPerSample / 8;
/* we don't write ExtraParamSize, because for AudioFormat == 1 it is not needed */
SubchunkSize -= 2;
/* Open file and write the header for our updated fmt_ chunk */
fOut = fopen (outputFile, "wb");
fwrite(&header, sizeof(struct header_t), 1, fOut); /* Main header */
fwrite(SubchunkID, sizeof(SubchunkID), 1, fOut); /* Subheader */
fwrite(&SubchunkSize, sizeof(SubchunkSize), 1, fOut);
fwrite(&subheader, SubchunkSize, 1, fOut);
} else if (memcmp(SubchunkID, "data", 4) == 0) {
/* here is our mu-law data */
/* write the header for our new chunk (it is twice as large) */
int32_t tSubchunkSize = SubchunkSize * 2;
fwrite(SubchunkID, sizeof(SubchunkID), 1, fOut);
fwrite(&tSubchunkSize, sizeof(SubchunkSize), 1, fOut);
/* process the data */
(fIn, fOut, SubchunkSize);
} else {
/* unknown chunk, skipping */
fseek(fIn, SubchunkSize, SEEK_CUR);
}
}
/* Cleanup and exit */
fclose(fIn);
fclose(fOut);
exit(EXIT_SUCCESS);
}
}
Just run gdb yourexe
Then in gdb:
break main
run
p &inputFile
That will give you the address of inputFile: ex $2 = (char (*)[256]) 0x62fd60
To get the size of a variable you can use p sizeof(variable) or p sizeof(type_of_the_variable>)
That said, not sure if it will help you to track down your problem.
I am trying to split a struct that is size 1536 into three equal size chunks of 512 bytes so that it can be saved to a virtual disk. The buffer size of the virtual disk is limited to 512 bytes. There is an issue when offsetting the pointer but I can't figure out why.
Here is the SSCCE:
#include <iostream>
#include <string.h>
#include <stdlib.h>
#include <bitset>
#define SECTOR_SIZE 512
#define NUM_SECTORS 10000
typedef struct sector {
char data[SECTOR_SIZE];
} Sector;
static Sector* disk;
struct dataBitmap {
/* sizeof myBits = 1228 bytes */
std::bitset<9795> myBits;
/* 308 bytes not accounted for */
char emptyData[308];
/* dataBitmap will now perfectly overlay 3 sectors of disk */
} dataMap;
void Disk_Write(int sector, char* buffer) {
// quick error checks
if((sector < 0) || (sector >= NUM_SECTORS) || (buffer == NULL)) {
std::cout << "Error!";
}
// copy the memory for the user
if((memcpy((void*)(disk + sector), (void*)buffer, sizeof(Sector))) == NULL) {
std::cout << "Error!";;
}
}
void Update_Bitmaps() {
char * bytes = (char*) malloc(512);
std::cout << "size of dataMap: " << sizeof(dataMap) << '\n';
const void* a = &dataMap;
const void* b = (const void*)((char*)a + 512);
/* data bitmap is 3 times the size of regular sector */
memcpy(&bytes, b, 512);
//Disk_Write(2, (char *) bytes); /* offset for data bitmap is 2 */
memcpy(&bytes, (char *) &dataMap + 512, 512);
Disk_Write(2, (char *) bytes);
//memcpy(&bytes, (char *) &dataMap.myBits + 1024, 512);
//Disk_Write(2, (char *) bytes);
free(bytes);
}
int main()
{
Update_Bitmaps();
return 0;
}
Here is the output of the program:
size of dataMap: 1536
0 [main] BitSet 8276 cygwin_exception::open_stackdumpfile:
Dumping stack trace to BitSet.exe.stackdump
Process returned 35584 (0x8B00) execution time : 0.464 s
I realize this is C-style code but I don't know how else to copy bytes in this manner. Any help is appreciated.
You haven't allocated memory for disk.
int main()
{
disk = malloc(sizeof(*disk)*NUM_SECTORS); // Allocate memory for disk
Update_Bitmaps();
free(disk); // Free the allocated memory.
return 0;
}
Also, the following lines are not correct.
memcpy(&bytes, b, 512);
//Disk_Write(2, (char *) bytes); /* offset for data bitmap is 2 */
memcpy(&bytes, (char *) &dataMap + 512, 512);
They need to be
memcpy(bytes, b, 512);
// ^^ just bytes, not &bytes.
//Disk_Write(2, (char *) bytes); /* offset for data bitmap is 2 */
memcpy(bytes, (char *) &dataMap + 512, 512);
// ^^ just bytes, not &bytes.
I've been studying hashing in C/C++ and tried to replicate the md5sum command in Linux. After analysing the source code, it seems that md5sum relies on the md5 library's md5_stream. I've approximated the md5_stream function from the md5.h library into the code below, and it runs in ~13-14 seconds. I've tried to call the md5_stream function directly and got ~13-14 seconds. The md5sum runs in 4 seconds. What have the GNU people done to get the speed out of the code?
The md5.h/md5.c code is available in the CoreUtils source code.
#include <QtCore/QCoreApplication>
#include <QtCore/QDebug>
#include <iostream>
#include <iomanip>
#include <fstream>
#include "md5.h"
#define BLOCKSIZE 32784
int main()
{
FILE *fpinput, *fpoutput;
if ((fpinput = fopen("/dev/sdb", "rb")) == 0) {
throw std::runtime_error("input file doesn't exist");
}
struct md5_ctx ctx;
size_t sum;
char *buffer = (char*)malloc (BLOCKSIZE + 72);
unsigned char *resblock = (unsigned char*)malloc (16);
if (!buffer)
return 1;
md5_init_ctx (&ctx);
size_t n;
sum = 0;
while (!ferror(fpinput) && !feof(fpinput)) {
n = fread (buffer + sum, 1, BLOCKSIZE - sum, fpinput);
if (n == 0){
break;
}
sum += n;
if (sum == BLOCKSIZE) {
md5_process_block (buffer, BLOCKSIZE, &ctx);
sum = 0;
}
}
if (n == 0 && ferror (fpinput)) {
free (buffer);
return 1;
}
/* Process any remaining bytes. */
if (sum > 0){
md5_process_bytes (buffer, sum, &ctx);
}
/* Construct result in desired memory. */
md5_finish_ctx (&ctx, resblock);
free (buffer);
for (int x = 0; x < 16; ++x){
std::cout << std::setfill('0') << std::setw(2) << std::hex << static_cast<uint16_t>(resblock[x]);
std::cout << " ";
}
std::cout << std::endl;
free(resblock);
return 0;
}
EDIT: Was a default mkspec problem in Fedora 19 64-bit.
fread() is convenient, but don't use fread() if you care about performance. fread() will copy from the OS to a libc buffer, then to your buffer. This extra copying cost CPU cycles and cache.
For better performance use open() then read() to avoid the extra copy. Make sure your read() calls are multiples of the block size, but lower than your CPU cache size.
For best performance use mmap() map the disk directly to RAM.
If you try something like the below code, it should go faster.
// compile gcc mmap_md5.c -lgcrypt
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <gcrypt.h>
#include <linux/fs.h> // ioctl
#define handle_error(msg) \
do { perror(msg); exit(EXIT_FAILURE); } while (0)
int main(int argc, char *argv[])
{
char *addr;
int fd;
struct stat sb;
off_t offset, pa_offset;
size_t length;
ssize_t s;
unsigned char digest[16];
char digest_ascii[32+1] = {0,};
int digest_length = gcry_md_get_algo_dlen (GCRY_MD_MD5);
int i;
if (argc < 3 || argc > 4) {
fprintf(stderr, "%s file offset [length]\n", argv[0]);
exit(EXIT_FAILURE);
}
fd = open(argv[1], O_RDONLY);
if (fd == -1)
handle_error("open");
if (fstat(fd, &sb) == -1) /* To obtain file size */
handle_error("fstat");
offset = atoi(argv[2]);
pa_offset = offset & ~(sysconf(_SC_PAGE_SIZE) - 1);
if (sb.st_mode | S_IFBLK ) {
// block device. use ioctl to find length
ioctl(fd, BLKGETSIZE64, &length);
} else {
/* offset for mmap() must be page aligned */
if (offset >= sb.st_size) {
fprintf(stderr, "offset is past end of file size=%zd, offset=%d\n", sb.st_size, (int) offset);
exit(EXIT_FAILURE);
}
if (argc == 4) {
length = atoi(argv[3]);
if (offset + length > sb.st_size)
length = sb.st_size - offset;
/* Canaqt display bytes past end of file */
} else { /* No length arg ==> display to end of file */
length = sb.st_size - offset;
}
}
printf("length= %zd\n", length);
addr = mmap(NULL, length + offset - pa_offset, PROT_READ,
MAP_PRIVATE, fd, pa_offset);
if (addr == MAP_FAILED)
handle_error("mmap");
gcry_md_hash_buffer(GCRY_MD_MD5, digest, addr + offset - pa_offset, length);
for (i=0; i < digest_length; i++) {
sprintf(digest_ascii+(i*2), "%02x", digest[i]);
}
printf("hash=%s\n", digest_ascii);
exit(EXIT_SUCCESS);
}
It turned out to be an error in the Qt mkspecs regarding an optimization flag not being set properly.
I have the following code:
#ifndef RAWSOCKET_H
#define RAWSOCKET_H
#include <stdio.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <unistd.h>
#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <poll.h>
#include <arpa/inet.h>
#include <netinet/if_ether.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <linux/if.h>
#include <linux/if_packet.h>
#include "IPPacket.h"
#define CONF_RING_FRAMES 128
/// Initialize a packet socket ring buffer
// #param ringtype is one of PACKET_RX_RING or PACKET_TX_RING
static inline char *
init_packetsock_ring(int fd, int ringtype)
{
tpacket_req tp;
char *ring;
// tell kernel to export data through mmap()ped ring
tp.tp_block_size = 1024 * 8;
tp.tp_block_nr = 1024;
tp.tp_frame_size = 1024 * 8;
tp.tp_frame_nr = 1024;
setsockopt(fd, SOL_PACKET, ringtype, (void*) &tp, sizeof(tp));
int val = TPACKET_V1;
setsockopt(fd, SOL_PACKET, PACKET_VERSION, &val, sizeof(val));
// open ring
ring = (char*)mmap(0, tp.tp_block_size * tp.tp_block_nr,
PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (!ring)
return NULL;
return ring;
}
/// transmit a packet using packet ring
// NOTE: for high rate processing try to batch system calls,
// by writing multiple packets to the ring before calling send()
//
// #param pkt is a packet from the network layer up (e.g., IP)
// #return 0 on success, -1 on failure
static inline int
process_tx(int fd, char *ring, const char *pkt, int pktlen, sockaddr_ll *txring_daddr)
{
static int ring_offset = 0;
struct tpacket_hdr *header;
struct pollfd pollset;
char *off;
int ret;
// fetch a frame
// like in the PACKET_RX_RING case, we define frames to be a page long,
// including their header. This explains the use of getpagesize().
header = (tpacket_hdr*)(void *) ring + (ring_offset * 1024);
while (header->tp_status != TP_STATUS_AVAILABLE) {
// if none available: wait on more data
pollset.fd = fd;
pollset.events = POLLOUT;
pollset.revents = 0;
ret = poll(&pollset, 1, 1000 /* don't hang */);
if (ret < 0) {
if (errno != EINTR) {
perror("poll");
return -1;
}
return 0;
}
ring_offset++;
if(ring_offset >= 1024 * 8) ring_offset = 0;
header = (tpacket_hdr*)(void *) ring + (ring_offset * 1024);
}
// fill data
off = (char*)(((char*) header) + (TPACKET_HDRLEN - sizeof(struct sockaddr_ll)));
memcpy(off, pkt, pktlen);
// fill header
header->tp_len = pktlen;
header->tp_status = TP_STATUS_SEND_REQUEST;
// increase consumer ring pointer
/*ring_offset++;
if(ring_offset >= 1024 * 8) ring_offset = 0;*/
// notify kernel
if (sendto(fd, NULL, 0, 0, (sockaddr*)txring_daddr, sizeof(sockaddr_ll)) < 0) {
perror("sendto");
return -1;
}
return 0;
}
class RawSocket
{
public:
inline RawSocket() { }
inline void initialize() {
sockfd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_IP));
ring = init_packetsock_ring(sockfd, PACKET_TX_RING);
ifreq ifr;
memset (&ifr, 0, sizeof (ifr));
strncpy((char *) ifr.ifr_name, "eth0", IFNAMSIZ);
ioctl(sockfd, SIOCGIFINDEX, &ifr);
int index = ifr.ifr_ifindex;
ioctl(sockfd, SIOCGIFHWADDR, &ifr);
sll = new sockaddr_ll();
sll->sll_family = AF_PACKET;
sll->sll_ifindex = index;
sll->sll_protocol = htons(ETH_P_IP);
sll->sll_halen = htons(6);
memcpy(IPPacket::our_mac, ifr.ifr_hwaddr.sa_data, ETH_ALEN);
memcpy(sll->sll_addr, ifr.ifr_hwaddr.sa_data, ETH_ALEN);
/*struct packet_mreq mr;
memset (&mr, 0, sizeof (mr));
mr.mr_ifindex = ifr.ifr_ifindex;
mr.mr_type = PACKET_MR_PROMISC;
setsockopt(sockfd, SOL_PACKET,PACKET_ADD_MEMBERSHIP, &mr, sizeof (mr));*/
//setsockopt(sockfd, IPPROTO_IP, IP_HDRINCL, &optval, sizeof(int));
}
inline ~RawSocket() {
close(sockfd);
}
inline void send(const IPPacket* ip) const {
process_tx(sockfd, ring, ip->packet_ptr, ip->tot_len, sll);
printf("TX\n");
}
protected:
char *ring;
int sockfd;
sockaddr_ll *sll;
};
#endif // RAWSOCKET_H
ip->packet_ptr being a pointer to a packet containing ethhdr and iphdr and so on.
The packets are being correcly sent via "normal" PF_PACKET sockets.
Now I tried using the TX Ring feature. However, only the first packet ever gets sent (and it gets sent 100% correctly).
Nothing else seems to happen on the network layer (tcpdump -vvv -e shows no network traffic at all occuring!)
However, the sendto() calls get processed correctly.
I didnt test this functionality myself, but I think you have an error in configuring the struct tpacket_req fields. the _nr fields are quite large. See this example code (linked to from the wiki ):
/* Setup the fd for mmap() ring buffer */
req.tp_block_size=4096;
req.tp_frame_size=1024;
req.tp_block_nr=64;
req.tp_frame_nr=4*64;
if ( (setsockopt(fd,
SOL_PACKET,
PACKET_RX_RING,
(char *)&req,
sizeof(req))) != 0 ) {
perror("setsockopt()");
close(fd);
return 1;
};
/* mmap() the sucker */
map=mmap(NULL,
req.tp_block_size * req.tp_block_nr,
PROT_READ|PROT_WRITE|PROT_EXEC, MAP_SHARED, fd, 0);
(I know this is a bit late but the documentation for this is still poor and examples are few, so hopefully this will help someone):
As per my comments above, this is the working code for me now (with no error checking, just a crude proof of concept):
struct tpacket2_hdr *hdr;
for (uint16_t i = 0; i < tpacket_req.tp_frame_nr; i += 1) {
hdr = (void*)(mmapped_buffer + (tpacket_req.tp_frame_size * i));
uint8_t *data = (uint8_t*)(hdr + TPACKET_ALIGN(TPACKET2_HDRLEN));
memcpy(data, tx_buffer, frame_size);
hdr->tp_len = frame_size;
hdr->tp_status = TP_STATUS_SEND_REQUEST;
}
int32_t send_ret = sendto(sock_fd, NULL, 0, 0, NULL, 0);