ether_addr_octet in host order byte - c

I would like convert struct ether_addr (ether_addr_octet) to integer host byte order representation. Any ideas?
ntohl(eth->ether_addr_octet)
not working, because ether_addr_octet is a char array.
Regards

I'm not sure what the semantics of this are going to be.
The ether is 48bit, and the largest ntoh* is for 32bit values.
I suppose you can create a 64bit value parsing the char array, and calling ntohl() twice...

You can convert it to char and then you can do something else you want...
char *ether_ntoa_my(const struct ether_addr *addr){
static char buf[18];
sprintf(buf, "%02x%02x:%02x%02x:%02x%02x",
addr->ether_addr_octet[0], addr->ether_addr_octet[1],
addr->ether_addr_octet[2], addr->ether_addr_octet[3],
addr->ether_addr_octet[4], addr->ether_addr_octet[5]);
return buf;
}
I hope it helps

Related

Convert float data to Char data that has to be sent over UDP

I'm using C socket to send data to a Server, I found some example on internet but all of them show a char data sent over the network.
Instead, my data are float, so I need to convert these data from float to a char to send it, and on the Server side I must convert it back to float.
I read about sprintf or snprintf, but I found some problems with using these functions.
My situation:
packet[4] = {112.3, 113.4, 234.8, 599.4} "For example"
I need to send it as char to the Server.
Thanks in advance
If you're careful, you can use a union for representing your float as an array of chars:
typedef union packet
{
float f;
char c[4];
} packet;
Barring endianness (you might have to twiddle the float) and char being signed on some platforms and unsigned on others (adjust to taste), this is well-defined. In particular, the standard guarantees that
The address of f is the same as the zeroth element of c.
the c array is contiguous.
I think you are confused with char buffer and char value. The char buffer which is meant in UDP communication, is 8bit/1Byte minimum space required to carry data info. This is also equal to char which is also 8bit/1Byte in size. Hence people call it as char buffer. This dosenot mean they only can carry char value.
Typical float value is 4 bytes in length and this can be carried in 4byte char buffer. Please use memcpy operation and copy the contents of float variable in to 4Byte char array buffer. In the server, based on source IP, this value could be easily type casted to float value(using atof) from received char array buffer.
code snippet:
//At Tx - from client
float flt =xx.xx;
char charbuff[4] ={0};
memcpy(&charbuff,&flt,4);
//At Rx - in server
if(Rx done from specific IP which sends float value)
{
float rflt = (float)atof(buffer); //build in function available
}
int main(void)
{
float value= 22.3;
char valbuff[4]={0};
memcpy(&valbuff,&value,4);
float values = (float)atof(valbuff);
printf("Valore %f ",values);
}
When I run this code the out value is 0.0000, …
Since you just copied the float value to the char valbuff[4], the atof(valbuff) to put the value back into a float is quite out of place; you rather need
float values;
memcpy(&values, valbuff, sizeof values);

How to read unsigned char from a socket

I have to receive a UDP packet from the socket. In this packet hour, min and sec are sent as UNSIGNED CHAR. When I receive it in a char[] and put in TextBox for displaying it is not displaying the actual data which are sent, but different values.
char buffer[10];
udpSocketRxCDP->readDatagram(buffer, sizeof(buffer));
ui->textEditsec->setText(buffer[2]);
Please suggest how I can get the actual data.
When you read from a socket, you are reading raw data. If you read it into a char[] buffer and use it as-is then the data is going to be interpreted as char. So either typecast the data to unsigned char when needed:
ui->textEditsec->setText( (unsigned char) buffer[2] );
Or define a suitable struct and typecast to that instead:
struct mypkt
{
unsigned char hour;
unsigned char minute;
unsigned char second;
...
};
ui->textEditsec->setText( ((mypkt*)buffer)->second );
Either way, assuming setText() actually expects a char* string as input, then use sprintf() or similar function to format a string:
char str[12];
sprintf(str, "%d", (int) ((mypkt*)buffer)->second);
ui->textEditsec->setText(str);
With the little given information, you might want to explicitly convert unsigned char to char.
Consider that some data may get corrupted. However, unless you really need it, you can send the data directly as signed char. We can't know whether it's a good choice or not though.

Passing values to a function in C

I am new to C and working on it since two months. I have a structure shown below:
struct profile_t
{
unsigned char length;
unsigned char type;
unsigned char *data;
};
typedef struct profile_datagram_t
{
unsigned char *src;
unsigned char *dst;
unsigned char ver;
unsigned char n;
struct profile_t profiles[MAXPROFILES];
} header;
header outObj;
Now the values inside the elements of the structure are read as outObj.src[i], outObj.dst[i], and outObj.profiles[i].type.
Now I want to call a function and pass the values read by me to a function which is actually a Berkeley DB.
void main()
{
struct pearson_record {
unsigned char src[6];
unsigned char dst[6];
unsigned char type;
};
DB *dbp;
int ret;
if ((ret = db_create(&dbp, dbenv, 0)) !=0)
handle_error(ret);
if ((ret = dbp->open(dbp, NULL, "pearson.db", NULL, DB_BTREE, DB_CREATE, 0600)) !=0)
handle_error(ret);
const DBT *pkey;
const DBT *pdata;
struct pearson_record p;
DBT data, key;
memset(&key, 0, sizeof(DBT));
memset(&data, 0, sizeof(DBT));
memset(&s, 0, sizeof(struct pearson_record));
Now the above code is written by looking at a example from the DB reference guide. but i don't understand what is const DBT. Also they have added the value inside structure using memcopy which I know is the right way, but now I want to memcopy the values passed which are mentioned above and store them in the structure pearson_record. How should I go with this?? Any kind of help would be appreciated.
Please post the complete code. You mention "they memcopy" (which I assume you refer to memcpy), but all I see is a bunch of memset(*,0). Hope you're not confusing them.
Also "they have added the value inside structure using memcopy which I know is the right way" is not entirely true. It's not necessarily wrong, BUT... char* is basically interpreted as a C string. that is an array of bytes which represent characters which MUST be null terminated (that is the last character must be 0, equivalent to '\0'). The proper way to copy strings is using strcpy() (or strcpy_s on windows), the difference is memcpy is faster and used in other situations (such as pointers\buffer management).
unsigned char* is not so used (at least I never saw it till now). As a note read about char, unsigned char, signed char, char[] and char* (not that it changes your code in any way, but just to make sure you understand the differences).
As for copying data, I assume you mean src, dst and type from pearson_record to header, correct ? If so, for the sake of simplicity I wanted to suggest memcpy but you say that each element is accessed as [i]. Does that mean header.src is an array of more than one pearson_record.src or does header.src[i] correspond to pearson_record.src[i] ? This is slightly unclear to me.
There is a difference between char* src and char* *src.

Copying between byte array and unsigned long

What's the best/recommended way to copy data between a byte array and an integer in C? Currently I'm using memcpy, which doesn't feel right to me. A sample of the sort of thing I'm doing is below.
struct alpha {
unsigned char byte_array[20];
}
void function(struct alpha *st) {
unsigned long num;
/* Do some stuff */
memcpy(st->byte_array, &num, sizeof(unsigned long));
/* Do more stuff */
memcpy(&num, st->byte_array, sizeof(unsigned long));
}
I assume I want to use casts somehow, but I'm not confident of how casting and pointer (de)referencing interacts, particularly when arrays get involved.
memcpy is the standard and portable tool for that effect. Modern optimized compilers will inline this call to something well adapted to your situation, e.g data types, allignement, size (if known at compile time), processor... So I think you should definitively stick to that and not mess around with some handmade optimizations.
It looks exactly the right way to me. Which is to say, when I had to do this, it was the way I did it.
Here's how to do it with casts:
/* Do some stuff */
*(unsigned long *)st = num;
/* Do more stuff */
num = *(unsigned long *)st;
You're casting your struct pointer to a pointer to an unsigned long, then dereferencing the pointer in the assignment statements.
It is not wrong, unless you know that "who" wrote the data into the array wrote them in an endianness different from the one used on your system. Say, e.g., if those data come from a "stream" sent by "someone" over the net. Then, if the protocol uses the so called "network byte order" (namely big endian), and your machine is not big endian, then you obtain wrong values.
Is there any particular reason you need to copy instead of just aliasing the two? e.g.:
union XXX {
char byte_array[20];
unsigned long num;
};
In theory, you don't get defined results when you write to one member of the union then read from the other member. In reality, there's essentially no possibility of getting anything different from what you're getting now -- except (of course) that you don't have to copy data to get from one view to the other -- you just use x.num to look at it as an unsigned long, and x.byte_array to look at it as an array of bytes.
memcpy is the safest way to do this sort of thing. If speed matters though, you can do some cast magic to let the compiler handle the copy natively for you:
*((unsigned long *)&st->byte_array[0]) = num;
num = *((unsigned long *)&st->byte_array[0]);
Both these will use built in register type copies instead of a function call of 4 bytes. If you want to read further into the byte_array, you must be careful of byte alignment issues with this though.
I prefer some default functions for this requirement,
for string to integer
int atoi ( const char * str );
and
for integer to string
char * itoa ( int value, char * str, int base );
#include <stdio.h>
#include <stdlib.h>
int main()
{
unsigned long int number;
unsigned char string[256];
printf ("Enter a number: ");
fgets ( string, 256, stdin );
number = atoi (string);
printf("number = %d\n",number);
//converting int to string
itoa (number,string,10); //10 is base here for decimal, 16 is used for Hex and 2 for Binary
printf ("string = %s\n",string);
return 0;
}
as per me atoi() function is fine. But in case you don't want to use itoa() or it is not available to you then you can just use sprintf()
sprintf (string,"%ld",number);
I hope it helps
Thanks
Alok.kr.

How to convert from byte array to word array in c

Using c, I have defined a byte and word as follows:
typedef unsigned char byte;
typedef union {
byte b[4];
unsigned long w;
} word;
This allows me to easy go from words to bytes, but I'm not sure of a good way to go the other way. Is it possible to do something like cast from byte* to word* or do I have to stick with iteratively copying bytes to words?
One of the great and terrible things about c is you can take a void pointer and cast it to anything. As long as you know what you are doing it will work, but not something you want to get in the habit of.
const byte input[] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};
unsigned long output[sizeof(input) / sizeof(unsigned long)];
memcpy(output, input, sizeof(input));

Resources