illegal flag specified error in berkeley DB using C - c

Below is my code:
#include <sys/types.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <db.h>
#define DATABASE "access.db"
typedef struct {
char data1[20];
char src[20];
} pearson_record;
I am geting the error:
illegal flag specified to DB->get
DB->get: Invalid argument
Any idea where I am going wrong.
int
main()
{
pearson_record s;
char *papa="1.1.1.1";
char *source="papa";
DB *dbp;
DBT key, data;
int ret, t_ret;
db_recno_t recno;
if ((ret = db_create(&dbp, NULL, 0)) != 0) {
fprintf(stderr, "db_create: %s\n", db_strerror(ret));
exit (1);
}
if ((ret = dbp->open(dbp,
NULL, DATABASE, NULL, DB_BTREE, DB_CREATE, 0664)) != 0) {
dbp->err(dbp, ret, "%s", DATABASE);
goto err;
}
recno = 10;
#define BUFFER_LENGTH (5 * 1024 * 1024)
data.ulen = BUFFER_LENGTH;
data.flags = DB_DBT_USERMEM;
strncpy(s.data1, papa, strlen(papa)+1);
strncpy(s.src, source, strlen(source)+1);
memset(&key, 0, sizeof(key));
memset(&data, 0, sizeof(data));
//memset(&s, 0, sizeof(struct pearson_record));
key.data = &recno;
key.size = sizeof(recno);
data.data = &s;
data.size = sizeof(s);
papa="1.1.1.2";
source="papaa";
strncpy(s.data1, papa, strlen(papa)+1);
strncpy(s.src, source, strlen(source)+1);
if ((ret = dbp->put(dbp, NULL, &key,&data,0)) == 0)
printf("db: %d: key stored.\n", *(int *)key.data);
else
{
dbp->err(dbp, ret, "DB->put");
goto err;
}
recno = 11;
strncpy(s.data1, papa, strlen(papa)+1);
strncpy(s.src, source, strlen(source)+1);
memset(&key, 0, sizeof(key));
memset(&data, 0, sizeof(data));
//memset(&s, 0, sizeof(struct pearson_record));
key.data = &recno;
key.size = sizeof(recno);
data.data = &s;
data.size = sizeof(s);
papa="1.1.1.2";
source="papaa";
strncpy(s.data1, papa, strlen(papa)+1);
strncpy(s.src, source, strlen(source)+1);
if ((ret = dbp->put(dbp, NULL, &key,&data,0)) == 0)
printf("db: %d: key stored.\n", *(int *)key.data);
else
{
dbp->err(dbp, ret, "DB->put");
goto err;
}
pearson_record *ppr;
if ((ret = dbp->get(dbp, NULL, &key, &data, DB_SET_RECNO)) == 0) {
ppr = (pearson_record *) data.data;
printf("db: %d: key retrieved: data was %s,%s. %d\n",
*(int *)key.data, ppr->data1,ppr->src, data.size);
}
else {
dbp->err(dbp, ret, "DB->get");
goto err;
}
if ((ret = dbp->get(dbp, NULL, &key, &data, DB_SET_RECNO)) == 0) {
ppr = (pearson_record *) data.data;
printf("db: %d: key retrieved: data was %s,%s. %d\n",
*(int *)key.data, ppr->data1,ppr->src, data.size);
}
else {
dbp->err(dbp, ret, "DB->get");
goto err;
}
err: if ((t_ret = dbp->close(dbp, 0)) != 0 && ret == 0)
ret = t_ret;
exit(ret);
}

A quick glance at the documentation for DB->get says: "For DB_SET_RECNO to be specified, the underlying database must be of type Btree, and it must have been created with the DB_RECNUM flag."
It doesn't look like you created the database with that flag. I haven't looked through the rest of your code, but that's one obvious place that needs to be fixed.
You can also ask these questions on the online Berkeley DB forum.
Regards,
Dave

Related

Pcap_inject sends too many messages

I am trying to send authenticate messages to an access point, but when I do that it sends 15 authenticate messages to the AP, whereby the AP doesn't respond. I use a Mac OS X and the libpcap library.
Here is my code:
int inject(char *src_mac, char *dst_mac)
{
int i, rc;
char *device, *packet;
char error[PCAP_ERRBUF_SIZE];
pcap_t *handle;
device = pcap_lookupdev(error);
handle = pcap_create(device, error);
check(device != NULL, "Failed to find a device!");
check(handle != NULL, "Failed to create handle!");
rc = pcap_set_rfmon(handle, 1);
check(rc == 0, "Failed to set monitor mode!");
rc = pcap_set_promisc(handle, 1);
check(rc == 0, "Failed to set promiscuous mode!");
rc = pcap_activate(handle);
check(rc == 0, "Failed to activate handle!");
rc = pcap_datalink(handle);
check(rc == DLT_IEEE802_11_RADIO, "Failed to use the correct format!");
packet = radiotap_setup(src_mac, dst_mac,\
dst_mac, 0xb0);
rc = pcap_inject(handle, packet,\
RADIO_LEN + sizeof(ieee80211_hdr));
check(rc != -1, "Failed to send packet!");
pcap_close(handle);
return 1;
error:
pcap_close(handle);
return -1;
}
char *radiotap_setup(char *dst_mac, char *src_mac, char *bssid_mac, int fc)
{
int i, radio_len;
unsigned int shost_mac[6], dhost_mac[6], bhost_mac[6];
static char packet[RADIO_LEN + sizeof(ieee80211_hdr)];
ieee80211_hdr ieeeh;
ieeeh.fc = fc;
ieeeh.dur = 314;
sscanf(src_mac, "%x:%x:%x:%x:%x:%x", &shost_mac[0], &shost_mac[1],\
&shost_mac[2], &shost_mac[3], &shost_mac[4], &shost_mac[5]);
sscanf(dst_mac, "%x:%x:%x:%x:%x:%x", &dhost_mac[0], &dhost_mac[1],\
&dhost_mac[2], &dhost_mac[3], &dhost_mac[4], &dhost_mac[5]);
sscanf(bssid_mac, "%x:%x:%x:%x:%x:%x", &bhost_mac[0], &bhost_mac[1],\
&bhost_mac[2], &bhost_mac[3], &bhost_mac[4], &bhost_mac[5]);
for (i = 0; i != 6; i++) {
ieeeh.src[i] = (unsigned char)shost_mac[i];
ieeeh.dest[i] = (unsigned char)dhost_mac[i];
ieeeh.bssid[i] = (unsigned char)bhost_mac[i];
}
ieeeh.seq = rand();
ieeeh.rc = 1792;
radio_len = RADIO_LEN;
memcpy(&packet[2], &radio_len, 2);
memcpy(packet + RADIO_LEN, &ieeeh,\
sizeof(ieee80211_hdr));
return packet;
}
When I execute the code I get this on Wireshark:
Wireshark output

Berkeley DB store is so slow

I am using Berkeley DB to store the data persistently in my program. I tested it on my SSD, my SSD speed is 1.4Gb/s for writing. My progrma for testing the storing speed of DB is shown below (error checking is omitted).
const char* db_dir="./.db";
const char* db_name = "node_test_0";
void mk_path(char* dest,const char* prefix,const char* db_name){
memcpy(dest,prefix,strlen(prefix));
dest[strlen(prefix)] = '/';
memcpy(dest+strlen(prefix)+1,db_name,strlen(db_name));
dest[strlen(prefix)+strlen(db_name)+1] = '\0';
return;
}
int main() {
DB* b_db;
DB_ENV* dbenv;
int ret;
int flag = 0;
DBT key, data;
char* full_path = NULL;
if((ret = mkdir(db_dir,S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH)) != 0){
if(errno != EEXIST){
}
}
full_path = (char*)malloc(strlen(db_dir) + strlen(db_name) + 2);
mk_path(full_path, db_dir, db_name);
if ((ret = db_env_create(&dbenv, 0)) != 0) {
dbenv->err(dbenv, ret, "Environment Created: %s", db_dir);
}
if ((ret = dbenv->open(dbenv, db_dir, DB_CREATE|DB_INIT_CDB|DB_INIT_MPOOL|DB_THREAD, 0)) != 0) {
}
if((ret = db_create(&b_db,dbenv,flag)) != 0){
}
if((ret = b_db->open(b_db, NULL, db_name, NULL, DB_BTREE, DB_THREAD|DB_CREATE,0)) != 0){
}
struct timeval start_time;
struct timeval end_time;
unsigned long e_usec;
memset(&key, 0, sizeof(key));
memset(&data, 0, sizeof(data));
key.data = "fruit";
key.size = sizeof("fruit");
data.data = "apple";
data.size = sizeof("apple");
gettimeofday(&start_time, NULL);
ret = b_db->put(b_db, NULL, &key, &data, 0);
gettimeofday(&end_time, NULL);
e_usec = ((end_time.tv_sec * 1000000) + end_time.tv_usec) - ((start_time.tv_sec * 1000000) + start_time.tv_usec);
printf("%lu\n", e_usec);
if (ret == 0)
printf("db: %s: key stored.\n", (char *)key.data);
else {
b_db->err(b_db, ret, "DB->put");
}
return 0;
}
The result is about 23 microseconds. It's much slower than I expected. Does anyone have idea on this? What can I do to make my persistent storage as fast as writing to SSD.
BerkeleyDB does a fsync after write's to ensure that the data on disk is saved. You can stub out the fsync(2) vector (just return 0) if you are willing to live with the consequence of possibly catastrophic data loss (which is acceptable for a temporary, non-persistent, data store using BDB)

How to convert ECDSA SIG signature to array of characters in C

I'm a beginner to cryptography (openssl library) and I wanted help on how to send an ECDSA signature through a C socket communication. My plan is:
make socket connection
convert ECDSA SIG object into string
send signature in the form of a string
At the destination, convert the string back to SIG object and verify signing
Here is the code.
static ECDSA_SIG* sig = NULL;
static EC_KEY *eckey = NULL;
int main(int argc, char *argv[])
{
unsigned char* msgDigest = "6df19ccf6b89397c9a9906bfd0848f061352e9b5";
if(ECDSAsign())
printf("signed successfully\n");
else
printf("signing failed\n");
...
}
int ECDSAsign()
{
int ret;
eckey = EC_KEY_new_by_curve_name(NID_secp192k1);
if (eckey == NULL)
{
printf(" error ");
return 0;
}
if (!EC_KEY_generate_key(eckey))
{
printf(" error ");
return 0;
}
unsigned char *buffer, *pp;
int bufLen;
bufLen = ECDSA_size(eckey);
buffer = OPENSSL_malloc(bufLen);
pp = buffer;
unsigned char *dgst = "5df19ccf6b89397c9a9906bfd0848f061352e9ba";
sig = ECDSA_do_sign(dgst, strlen(dgst), eckey);
if (sig == NULL)
{
printf(" Signature NOT generated\n ");
return 0;
}
return 1;
}
How to convert ECDSA SIG signature to array of characters in C
...
The signature is already an array of bytes. That is what is returned from EVP_DigestSignFinal.
In general, you want to use the EVP_* interfaces for signing and verification. Below is from the OpenSSL wiki on EVP Signing and Verifying.
Your job below is to get the ECDSA into the EVP_PKEY*. The function will allocate the signature buffer with OPENSSL_malloc. The caller needs to free it with OPENSSL_free. The buffer is an array of bytes.
int sign_it(const byte* msg, size_t mlen, byte** sig, size_t* slen, EVP_PKEY* pkey)
{
/* Returned to caller */
int result = -1;
if(!msg || !mlen || !sig || !pkey) {
assert(0);
return -1;
}
if(*sig)
OPENSSL_free(*sig);
*sig = NULL;
*slen = 0;
EVP_MD_CTX* ctx = NULL;
do
{
ctx = EVP_MD_CTX_create();
assert(ctx != NULL);
if(ctx == NULL) {
printf("EVP_MD_CTX_create failed, error 0x%lx\n", ERR_get_error());
break; /* failed */
}
const EVP_MD* md = EVP_get_digestbyname("SHA256");
assert(md != NULL);
if(md == NULL) {
printf("EVP_get_digestbyname failed, error 0x%lx\n", ERR_get_error());
break; /* failed */
}
int rc = EVP_DigestInit_ex(ctx, md, NULL);
assert(rc == 1);
if(rc != 1) {
printf("EVP_DigestInit_ex failed, error 0x%lx\n", ERR_get_error());
break; /* failed */
}
rc = EVP_DigestSignInit(ctx, NULL, md, NULL, pkey);
assert(rc == 1);
if(rc != 1) {
printf("EVP_DigestSignInit failed, error 0x%lx\n", ERR_get_error());
break; /* failed */
}
rc = EVP_DigestSignUpdate(ctx, msg, mlen);
assert(rc == 1);
if(rc != 1) {
printf("EVP_DigestSignUpdate failed, error 0x%lx\n", ERR_get_error());
break; /* failed */
}
size_t req = 0;
rc = EVP_DigestSignFinal(ctx, NULL, &req);
assert(rc == 1);
if(rc != 1) {
printf("EVP_DigestSignFinal failed (1), error 0x%lx\n", ERR_get_error());
break; /* failed */
}
assert(req > 0);
if(!(req > 0)) {
printf("EVP_DigestSignFinal failed (2), error 0x%lx\n", ERR_get_error());
break; /* failed */
}
*sig = OPENSSL_malloc(req);
assert(*sig != NULL);
if(*sig == NULL) {
printf("OPENSSL_malloc failed, error 0x%lx\n", ERR_get_error());
break; /* failed */
}
*slen = req;
rc = EVP_DigestSignFinal(ctx, *sig, slen);
assert(rc == 1);
if(rc != 1) {
printf("EVP_DigestSignFinal failed (3), return code %d, error 0x%lx\n", rc, ERR_get_error());
break; /* failed */
}
assert(req == *slen);
if(rc != 1) {
printf("EVP_DigestSignFinal failed, mismatched signature sizes %ld, %ld", req, *slen);
break; /* failed */
}
result = 0;
} while(0);
if(ctx) {
EVP_MD_CTX_destroy(ctx);
ctx = NULL;
}
/* Convert to 0/1 result */
return !!result;
}

Not able to access multiple data inside a database created by Berkeley DB using C

I am trying to develop a database using Berkeley Db in C. I want to have multiple data inside the database and then access them. my code is below:
#include <sys/types.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <db.h>
#define DATABASE "access.db"
typedef struct {
int id;
char data1[20];
char src[20];
} pearson_record;
int
main()
{
pearson_record s;
char *papa="1.1.1.1";
char *source="papa";
DB *dbp;
DBT key, data;
int ret, t_ret;
if ((ret = db_create(&dbp, NULL, 0)) != 0) {
fprintf(stderr, "db_create: %s\n", db_strerror(ret));
exit (1);
}
if ((ret = dbp->open(dbp, NULL, DATABASE, NULL, DB_BTREE, DB_CREATE, 0664)) != 0) {
dbp->err(dbp, ret, "%s", DATABASE);
goto err;
}
s.id = 10;
strncpy(s.data1, papa, strlen(papa)+1);
strncpy(s.src, source, strlen(source)+1);
memset(&key, 0, sizeof(key));
memset(&data, 0, sizeof(data));
//memset(&s, 0, sizeof(struct pearson_record));
key.data = &(s.id);
key.size = sizeof(int);
data.data = &s;
data.size = sizeof(s);
papa="1.1.1.2";
source="papaa";
strncpy(s.data1, papa, strlen(papa)+1);
strncpy(s.src, source, strlen(source)+1);
if ((ret = dbp->put(dbp, NULL, &key,&data,DB_NOOVERWRITE)) == 0)
printf("db: %d: key stored.\n", *(int *)key.data);
else
{
dbp->err(dbp, ret, "DB->put");
goto err;
}
s.id = 11;
strncpy(s.data1, papa, strlen(papa)+1);
strncpy(s.src, source, strlen(source)+1);
memset(&key, 0, sizeof(key));
memset(&data, 0, sizeof(data));
//memset(&s, 0, sizeof(struct pearson_record));
key.data = &(s.id);
key.size = sizeof(int);
data.data = &s;
data.size = sizeof(s);
papa="1.1.1.2";
source="papaa";
strncpy(s.data1, papa, strlen(papa)+1);
strncpy(s.src, source, strlen(source)+1);
if ((ret = dbp->put(dbp, NULL, &key,&data,DB_NOOVERWRITE)) == 0)
printf("db: %d: key stored.\n", *(int *)key.data);
else
{
dbp->err(dbp, ret, "DB->put");
goto err;
}
pearson_record *ppr;
if ((ret = dbp->get(dbp, NULL, &key, &data, DB_MULTIPLE)) == 0) {
ppr = (pearson_record *) data.data;
printf("db: %d: key retrieved: data was %s,%s. %d\n",
*(int *)key.data, ppr->data1,ppr->src, data.size);
} else {
dbp->err(dbp, ret, "DB->get");
goto err;
}
if ((ret = dbp->get(dbp, NULL, &key, &data, DB_MULTIPLE)) == 0) {
ppr = (pearson_record *) data.data;
printf("db: %d: key retrieved: data was %s,%s. %d\n",
*(int *)key.data, ppr->data1,ppr->src, data.size);
} else {
dbp->err(dbp, ret, "DB->get");
goto err;
}
err:
if ((t_ret = dbp->close(dbp, 0)) != 0 && ret == 0)
ret = t_ret;
exit(ret);
}
Right now it says DB_DBT_MULTIPLE has to be set. I don't know how to do that. Previously without the flags i was only getting the last entry. Any kind of help would be appreciated. Thanks in advance
If I'm reading your code correctly, you are calling get twice with the same key, which returns the same data for obvious reasons.
If you want to iterate over the records, you will need to use a Cursor, see Chapter 4 of Getting Started with Berkeley DB for a good reference for same.

How to view a ".db file in linux with no GUI

i have created a .db file using Berkeley DB using C. I want to view the contents inside the .db file. How to achieve this when I ahve no GUI on a linux machine?
if you system had been installed the Berkeley DB, you could use it like this, it is a demo to test, hope it could solve your problem:
#include <stdio.h>
#include <stdlib.h>
#include <db.h>
#define DATABASE "test.db"
typedef struct _data_struct {
int data_id;
char data[20];
} data_struct;
int main()
{
DBT key, data;
DB *dbp;
int ret;
data_struct my_data;
ret = db_create(&dbp, NULL, 0); // create the DB handle
if (ret != 0)
{
perror("create");
return 1;
}
ret = dbp->open(dbp, NULL, DATABASE, NULL, DB_BTREE, DB_CREATE, 0); // open the database
if (ret != 0)
{
perror("open");
return 1;
}
my_data.data_id = 1;
strcpy(my_data.data, "some data");
memset(&key, 0, sizeof(DBT));
memset(&data, 0, sizeof(DBT));
key.data = &(my_data.data_id);
key.size = sizeof(my_data.data_id);
data.data = &my_data;
data.size = sizeof(my_data);
ret = dbp->put(dbp, NULL, &key, &data, DB_NOOVERWRITE); // add the new data into the database
if (ret != 0)
{
printf("Data ID exists\n");
}
dbp->close(dbp, 0); // close the database
return 0;
}

Resources