I'm trying to confirm/get the unsigned int (base 10 / decimal) value of an hex'd mpi value. I'm using the following code:
#include <gcrypt.h>
#include <stdio.h>
static gcry_mpi_t privkey = NULL;
int main(){
char *parmstr = "48BFDA215C31A9F0B226B3DB11F862450A0F30DA";
printf("starting program\n");
gcry_mpi_scan(&privkey, GCRYMPI_FMT_HEX, (char *)parmstr, 0, NULL);
printf("printing hashed (?) mpi\n");
gcry_mpi_dump(privkey);
printf("\n");
size_t gablen;
unsigned char *result;
/* get length */
gcry_mpi_print (GCRYMPI_FMT_USG, NULL, 0, &gablen, privkey);
result = gcry_malloc_secure(gablen);
/* get actual value */
gcry_mpi_print (GCRYMPI_FMT_USG, result, gablen, NULL, privkey);
/* print actual value */
printf("result: %s\n", result);
printf("finished\n");
}
and i'm getting the following result:
$ ./foo
starting program
printing hashed (?) mpi
48BFDA215C31A9F0B226B3DB11F862450A0F30DA
result: H¿Ú!\1©ð²&³ÛøbE
0Ú
finished
I would the 'result: ' line to print the actual unsigned int (base 10 / decimal) value.
The private key is taking from the Off-The-Record Pidgin plug-in that i'm trying to work with.
EDIT:
can anybody confirm that the actual unsigned int (base 10 / decimal) value should be
415325779662433871844955547383752003988573073626
I could probably update the program to create a new mpi in gcrypt with this value and see if the HEX value is the same as what i already have. I will do this later today.
EDIT 2:
So i'm trying to do the following to print the HEX value of the int value mentioned above. Something is going wrong:
gcry_mpi_t cript_prime;
char buffer[50] = {0};
char number[50] = {0};
cript_prime = gcry_mpi_new(50);
strcpy(number,"415325779662433871844955547383752003988573073626");
gcry_mpi_scan(&cript_prime,GCRYMPI_FMT_USG,number,sizeof(number),NULL);
gcry_mpi_print(GCRYMPI_FMT_USG,buffer,sizeof(buffer),NULL,cript_prime);
printf("The number tested is: %s\n",buffer);
printf("trying to convert to HEX\n");
/* get actual value */
gcry_mpi_print (GCRYMPI_FMT_HEX, buffer, sizeof(buffer), NULL, cript_prime);
/* print actual value */
printf("result: %s\n", buffer);
The output is:
result: 48BFDA215C31A9F0B226B3DB11F862450A0F30DA
The number tested is: 415325779662433871844955547383752003988573073626
trying to convert to HEX
result: 415325779662433871844955547383752003988573073626
EDIT 3:
I updated the post a bit, basically i'm trying to print the base10 decimal value of an hex value that is generated by the gcrypt library. I'm looking for this value to confirm an implementation that i made to read these values. I was looking for a gcrypt function to achieve this. It seems that gcrypt doesn't supports this?
result[1] = (gablen >> 24) & 0xff;
This line puts a nul byte into the byte at offset 1 into result. I don't see where you ever initialize the byte at offset zero, but the bytes at offsets 2 and later are past the end of the string you've constructed. The string it's formatting starts at result+5, so that's what you should print here:
gcry_mpi_print (GCRYMPI_FMT_USG, result + 5, gablen, NULL, privkey);
...
printf("result: %s\n", result + 5);
Here is a working script, the buffer was too small
#include <gcrypt.h>
#include <stdio.h>
int main(){
gcry_error_t err;
gcry_mpi_t cript_prime;
unsigned char buffer[401] = {0};
char number[101] = {0};
cript_prime = gcry_mpi_new(101);
strcpy(number, "415325779662433871844955547383752003988573073626");
gcry_mpi_scan(&cript_prime, GCRYMPI_FMT_USG, number, sizeof(number), NULL);
err = gcry_mpi_print(GCRYMPI_FMT_USG, buffer, sizeof(buffer), NULL, cript_prime);
if (err != 0){
printf("error: %d\n", err);
return -1;
}
printf("The number tested is: %s\n",buffer);
printf("trying to convert to HEX\n");
/* get actual value */
err = gcry_mpi_print(GCRYMPI_FMT_HEX, buffer, sizeof(buffer), NULL, cript_prime);
if (err != 0){
gcry_err_code_t code = gcry_err_code(err);
printf("error: %d\n", code);
return -1;
}
/* print actual value */
printf("result: %s\n", buffer);
printf("finished\n");
return 0;
}
I also confirmed my thoughts using this website: http://www.unitconversion.org/numbers/base-10-to-base-16-conversion.html
This will show that hex (base-16) 48BFDA215C31A9F0B226B3DB11F862450A0F30DA actual is 415325779662433762080404206464628666084640806848 (base-10)
Related
When I run this code on my microcontroller, it crashes when attempting to printf on "price_right_of_period".
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define DEBUG
char *str = "$3.45";
int main()
{
char *decimal_pos; // where the decimal place is in the string
char buffer[64]; // temporary working buffer
int half_price_auto_calc = 1;
// the cost of the product price difference for half price mode
int price_save_left, price_save_right = 0;
int price_half_left, price_half_right = 0;
// EG: let's say we get the string "$2.89"
char *price_left_of_period; // this will contain "2"
char *price_right_of_period; // this will contain "89"
// find where the decimal is
decimal_pos = strstr(str, ".");
if (decimal_pos != NULL)
{
printf("\nThe decimal point was found at array index %d\n", decimal_pos - str);
printf("Splitting the string \"%s\" into left and right segments\n\n", str);
}
// get everything before the period
strcpy(buffer, str); // copy the string
price_left_of_period = strtok(buffer, ".");
// if the dollar sign exists, skip over it
if (price_left_of_period[0] == '$') price_left_of_period++;
#ifdef DEBUG
printf("price_left_of_period = \"%s\"\n", price_left_of_period);
#endif
// get everything after the period
//
// strtok remembers the last string it worked with and where it ended
// to get the next string, call it again with NULL as the first argument
price_right_of_period = strtok(NULL, "");
#ifdef DEBUG
printf("price_right_of_period = \"%s\"\n\n", price_right_of_period);
#endif
if (half_price_auto_calc == 1)
{
// calculate the amount we saved (before the decimal)
price_save_left = atoi((const char *)price_left_of_period);
// halve the value if half price value is true
price_half_left = price_save_left / 2;
// calculate the amount we saved (before the decimal)
price_save_right = atoi((const char *)price_right_of_period);
// halve the value if half price value is true
price_half_right = price_save_right / 2;
#ifdef DEBUG
printf("price_half_left = \"%d\"\n", price_half_left);
printf("price_half_right = \"%d\"", price_half_right);
#endif
}
return 0;
}
The code runs and works fine here: https://onlinegdb.com/kDAw2cJyz. However as mentioned above, on my MCU it crashes (image below).
Would anyone have any ideas why this might be happening as a result of my code? The code looks right to me but it's always nice to get a second opinion from other C experts :)
SOLUTION:
Your code does have one bug. %d\n", decimal_pos - str doesn't work because decimal_pos - str has the wrong type to
print through %d. You need to cast it (I doubt that's causing the
crash but you can test by commenting it out and re-testing)
The code indeed has a bug here:
printf("\nThe decimal point was found at array index %d\n", decimal_pos - str);
The difference of 2 pointers has type ptrdiff_t which may be different from int expected for %d. You should either use %td or cast the difference as (int)(decimal_pos - str). It is however very surprising that this type mismatch be the cause of your problem.
Note that you copy the string without testing its length in strcpy(buffer, str); which for this example is OK but might have undefined behavior if str points to a longer string.
The code is too complicated: there is no need for strtok() as you already have the offset to the decimal point if any. You can use atoi() with a pointer to the beginning of the integral portion without patching the . with a null byte. You could also use strtol() to avoid strstr() too.
Note also that the code will compute an incorrect price in most cases: "$3.45" will be changed to "$1.22" which is substantially more than a 50% rebate.
You should just convert the number as an integral number of cents and use that to compute the reduced price.
Here is a simplified version:
#include <stdio.h>
#include <stdlib.h>
int half_price_auto_calc = 1;
char *str = "$3.45";
int main() {
int cents;
char *p = str;
if (*p == '$')
p++;
// use strtol to convert dollars and cents
cents = strtol(p, &p, 10) * 100;
if (*p == '.') {
cents += strtol(p + 1, NULL, 10);
}
if (half_price_auto_calc) {
cents /= 2;
}
printf("reduced price: $%d.%02d\n", cents / 100, cents % 100);
return 0;
}
Hi I am trying to use a kobject to write to a int array from sysfs. So the input is a char* and a size variable. I cant seem to get this to work however. My expected input is "num1 num2 num3 "
static ssize_t pids_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count) {
int num_count = 0;
int i = 0;
int result = 0;
int cur_pid = 0;
char *dst;
char *ddst;
printk(KERN_INFO "GPIO_DEGUG: enter");
dst = buf;
ddst = buf;
printk(KERN_INFO "GPIO_DEGUG: size of buffer %d ",count);
while(ddst < (buf + sizeof(size_t)*count)) {
ddst ++;
if (ddst[0] == ' ') {
result = kstrtoint(dst,10,&cur_pid);
dst=ddst+1;
printk(KERN_INFO "GPIO_DEGUG: kstrtoint suceeded %d ",cur_pid);
printk(KERN_INFO "GPIO_DEGUG: kstrtoint suceeded res: %d ",result);
pids[num_count] = cur_pid;
num_count += 1;
}
}
for(i=0;i<num_count;i++) {
printk(KERN_INFO "GPIO_TEST: pid: %d \n", pids[i]);
}
printk(KERN_INFO "GPIO_DEBUG: leaving\n");
return count;
}
When I echo "100 " > /sys/vt/vt7/pids I get
[ 2765.712770] GPIO_DEGUG: enter
[ 2765.724468] GPIO_DEGUG: size of buffer 5
[ 2765.735101] GPIO_DEGUG: kstrtoint suceeded 0
[ 2765.746526] GPIO_DEGUG: kstrtoint suceeded res: -22
[ 2765.757746] GPIO_DEBUG: leaving
I suppose this is an argument error any help would be nice, thanks.
Function kstrtoint expects full string to contain single integer value. The only exception is a newline character at the end of the string:
The string must be null-terminated, and may also include a single newline before its terminating null.
As you can see, string "100 " doesn't fit for that requirement: it contains exceeded space.
For parse only part of the string as an integer, you may use simple_strtol:
long val = simple_strtol(dst, &ddst, 10);
if(ddst == ddst) {/* Parsing has been failed. */};
While this function is marked as an obsolete, there is still some code in the kernel which uses it.
Another possibility is to use sscanf. It expects fixed number of integers in the string, but it is an usual situation with attributes: having complex representation of the attributes is not recommended:
The conventions for sysfs state that each attribute should contain a single, human-readable value; if you have a lot of information to return, you may want to consider splitting it into multiple attributes.
(Linux Device Drivers 3, chapter 14).
The kstrtoint function is defined here:
http://lxr.free-electrons.com/source/lib/kstrtox.c#L245
If you notice the last value of *res defined in the function is the value you wish to use. In your case cur_pid should be the value in which you want to print, the result should always be zero if it was successful. I would suggest checking result to make sure that the conversion has succeeded.
This should work:
int cur_pid, result;
char *dst = NULL;
cur_pid = result = 0;
dst = buf;
result = kstrtoint(dst, 10, &cur_pid);
if (result)
printk(KERN_INFO "GPIO_DEGUG: kstrtoint suceeded res: %d ", cur_pid);
else
printk(KERN_INFO "ERROR");
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
I understand the general idea of C and how making a log file would go. Reading/writing to a file and such.
My concern is the following format that is desired:
[![enter image description here][1]][1]
I've gotten a good chunk done now but am concerned with how to append to my log file after the first record. I increment the file's record count (in the top 2 bytes) and write the first record after it. How would I then setup to add the 2nd/3rd/etc records to showup after each other?
//confirm a file exists in the directory
bool fileExists(const char* file)
{
struct stat buf;
return (stat(file, &buf) == 0);
}
int rightBitShift(int val, int space)
{
return ((val >> space) & 0xFF);
}
int leftBitShift(int val, int space)
{
return (val << space);
}
int determineRecordCount(char * logName)
{
unsigned char record[2];
FILE *fp = fopen(logName, "rb");
fread(record, sizeof(record), 1, fp);
//display the record number
int recordNum = (record[0] << 8) | record[1];
recordNum = recordNum +1;
return (recordNum);
}
void createRecord(int argc, char **argv)
{
int recordNum;
int aux = 0;
int dst;
char* logName;
char message[30];
memset(message,' ',30);
//check argument count and validation
if (argc == 7 && strcmp("-a", argv[2]) ==0 && strcmp("-f", argv[3]) ==0 && strcmp("-t", argv[5]) ==0)
{
//aux flag on
aux = 1;
logName = argv[4];
strncpy(message, argv[6],strlen(argv[6]));
}
else if (argc == 6 && strcmp("-f", argv[2]) ==0 && strcmp("-t", argv[4]) ==0)
{
logName = argv[3];
strncpy(message, argv[5],strlen(argv[5]));
}
else
{
printf("Invalid Arguments\n");
exit(0);
}
//check if log exists to get latest recordNum
if (fileExists(logName))
{
recordNum = determineRecordCount(logName);
printf("%i\n",recordNum);
}
else
{
printf("Logfile %s not found\n", logName);
recordNum = 1;
}
//Begin creating record
unsigned char record[40]; /* One record takes up 40 bytes of space */
memset(record, 0, sizeof(record));
//recordCount---------------------------------------------------------------------
record[0] = rightBitShift (recordNum, 8); /* Upper byte of sequence number */
record[1] = rightBitShift (recordNum, 0); /* Lower byte of sequence number */
//get aux/dst flags---------------------------------------------------------------
//get date and time
time_t timeStamp = time(NULL);
struct tm *date = localtime( &timeStamp );
if (date->tm_isdst)
dst = 1;
record[2] |= aux << 7; //set 7th bit
record[2] |= dst << 6; //set 6th
//timeStamp-----------------------------------------------------------------------
record[3] |= rightBitShift(timeStamp, 24);//high byte
record[4] |= rightBitShift(timeStamp, 16);
record[5] |= rightBitShift(timeStamp, 8);
record[6] |= rightBitShift(timeStamp, 0); //low byte
//leave bytes 7-8, set to 0 -----------------------------------------
record[7] = 0;
record[8] = 0;
//store message--------------------------------------------
strncpy(&record[9], message, strlen(message));
//write record to log-----------------------------------------------------------------
FILE *fp = fopen(logName, "w+");
unsigned char recordCount[4];
recordCount[0] = rightBitShift (recordNum, 8); /* Upper byte of sequence number */
recordCount[1] = rightBitShift (recordNum, 0); /* Lower byte of sequence number */
recordCount[2] = 0;
recordCount[3] = 0;
fwrite(recordCount, sizeof(recordCount), 1, fp);
fwrite(record, sizeof(record), 1, fp);
fclose(fp);
printf("Record saved successfully\n");
}
NOTE: I've never had to do this before in C, take it with a grain of salt.
This is a very specific binary formatting where each bit is precisely accounted for. It's using the Least-Significant-Bit numbering scheme (LSB 0) where the bits are numbered from 7 to 0.
Specifying that the "upper byte" comes first means this format is big-endian. The most significant bits come first. This is like how we write our numbers, four thousand, three hundred, and twenty one is 4321. 1234 would be little-endian. For example, the Number Of Records and Sequence are both 16 bit big-endian numbers.
Finally, the checksum is a number calculated from the rest of the record to verify there were no mistakes in transmission. The spec defines how to make the checksum.
Your job is to precisely reproduce this format, probably using the fixed-sized types found in stdint.h or unsigned char. For example, the sequence would be a uint16_t or unsigned char[2].
The function to produce a record might have a signature like this:
unsigned char *make_record( const char *message, bool aux );
The user only has to supply you with the message and the aux flag. The rest you can be figured out by the function. You might decide to let them pass in the timestamp and sequence. Point is, the function needs to be passed just the data, it takes care of the formatting.
This byte-ordering means you can't just write out integers, they might be the wrong size or the wrong byte order. That means any multi-byte integers must be serialized before you can write them to the record. This answer covers ways to do that and I'll be using the ones from this answer because they proved a bit more convenient.
#include <stdio.h>
#include <stdint.h>
#include <time.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
unsigned char *make_record( const char *message, bool aux ) {
// Allocate and zero memory for the buffer.
// Zeroing means no risk of accidentally sending garbage.
unsigned char *buffer = calloc( 40, sizeof(unsigned char) );
// As we add to the buffer, pos will track the next byte to be written.
unsigned char *pos = buffer;
// I decided not make the user responsible for
// the sequence number. YMMV.
static uint16_t sequence = 1;
pos = serialize_uint16( pos, sequence );
// Get the timestamp and DST.
time_t timestamp = time(NULL);
struct tm *date = localtime( ×tamp );
// 2nd row is all flags and a bunch of 0s. Start with them all off.
uint8_t flags = 0;
if( aux ) {
// Flip the 7th bit on.
flags |= 0x80;
}
if( date->tm_isdst ) {
// Flip the 6th bit on.
flags |= 0x40;
}
// That an 8 bit integer has no endianness, this is to ensure
// pos is consistently incremented.
pos = serialize_uint8(pos, flags);
// I don't know what their timestamp format is.
// This is just a guess. It's probably wrong.
pos = serialize_uint32(pos, (uint32_t)timestamp);
// "Spare" is all zeros.
// The spec says this is 3 bytes, but only gives it bytes
// 7 and 8. I'm going with 2 bytes.
pos = serialize_uint16(pos, 0);
// Copy the message in, 30 bytes.
// strncpy() does not guarantee the message will be null
// terminated. This is probably fine as the field is fixed width.
// More info about the format would be necessary to know for sure.
strncpy( pos, message, 30 );
pos += 30;
// Checksum the first 39 bytes.
// Sorry, I don't know how to do 1's compliment sums.
pos = serialize_uint8( pos, record_checksum( buffer, 39 ) );
// pos has moved around, but buffer remains at the start
return buffer;
}
int main() {
unsigned char *record = make_record("Basset hounds got long ears", true);
fwrite(record, sizeof(unsigned char), 40, stdout);
}
At this point my expertise is exhausted, I've never had to do this before. I'd appreciate folks fixing up the little mistakes in edits and suggesting better ways to do it in the comments, like what to do with the timestamp. And maybe someone else can cover how to do 1's compliment checksums in another answer.
As a byte is composed by 8 bits (from 0 to 7) you can use bitwise operations to modify them as asked in your specifications. Take a look for general information (https://en.wikipedia.org/wiki/Bitwise_operations_in_C). As a preview, you can use >> or << operators to determine which bit to modify, and use logical operators | and & to set it's values.
I have been using strcat to join several strings. Everything appears to be correct, prints:
/proc/573/fd/ <- with the backslash
13 <- length
After I try to copy the "src" string with strcpy to another string, the trailing character doesn't print in either the "dest" or the "src" strings:
/proc/573/fd <- same string prints without the backslash?
13 <- length is unchanged?
If I call strlen the length shows it is unchanged though?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// This function counts the number of digit places in 'pid'
int pid_digit_places(int pid)
{
int n = pid;
int places = 0;
while (n)
n /= 10;
places++;
return places;
}
char *construct_path(int pid, char *dir)
{
// get count of places in pid
int places = pid_digit_places(pid);
char *pid_str = calloc(places, sizeof(char));
// create string of pid
sprintf(pid_str, "%d", pid);
char *proc = "/proc/";
size_t plen = strlen(proc);
size_t dlen = strlen(dir) + 1;
char *path = calloc(plen + dlen + places, sizeof(char));
strcat(path, proc);
strcat(path, pid_str);
strcat(path, dir);
return path;
}
void fd_walk(int pid)
{
char *fd = "/fd/";
char *fdpath = construct_path(pid, fd);
// prints "/proc/573/fd/ - as expected
printf("Before: %s\n", fdpath);
// shows a length of 13
printf("Size Before: %d\n", (int)strlen(fdpath));
char *test = calloc(strlen(fdpath) + 1, sizeof(char));
strcpy(test, fdpath);
// prints "/proc/573/fd" no trailing "/"
printf("Copied Str: %s\n", test);
//shows a length of 13 though
printf("Copied Size: %d\n", (int)strlen(test));
// prints "/proc/573/fd" no trailing "/" now
printf("After: %s\n", fdpath);
// still shows length of 13
printf("Size After: %d\n", (int)strlen(fdpath));
}
int main(void)
{
// integer to create path around
int pid = 573;
fd_walk(pid);
return 0;
}
I'm compiling on gcc-4.8.2 with -Wall:
gcc -o src src.c -Wall
I've popped this small example into ideone.
I've made sure to add an extra space for the null-terminator when allocating memory.
I've thought to re-examine how I'm intializing my pointers first and haven't seen anything wrong? How is the string printing as expected with printf and then after copying it, printf prints something different -- undefined behavior?
I have executed your exact code with no troubles. Nonetheless, I see two possible problems:
// This function counts the number of digit places in 'pid'
int pid_digit_places(int pid)
{
int n = pid;
int places = 0;
while (n) { // <-- The braces were missing here.
n /= 10;
places++;
}
return places;
}
char *construct_path(int pid, char *dir)
{
// get count of places in pid
int places = pid_digit_places(pid);
// You need "places" bytes for the digits, plus one for the zero
char *pid_str = calloc(places + 1, sizeof(char));
However, in general, I wouldn't waste time to allocate exactly the memory I needed; the extra code more than compensates in size and complexity.
Just make a guess on the largest possible value, and enforce that guess:
// avoid pid_digit_places altogether
pid_str = malloc(16);
if (pid > 999999999999L) {
// fprintf an error and abort.
// Better yet, see whether this is a limit #define'd in the OS,
// and place an appropriate compile-time # warning. Chances are
// that unless your code's trivial, running it on a system with
// such large PIDs (and therefore likely so different an arch!)
// would cause some other troube to pop up.
// With an # error in place, you save also the pid check!
}
I'm having some difficulties extracting data from a buffer using memcpy.
First, I memcpy some variables into a buffer:
int l1_connect(const char* hostname, int port) {
// Variables to be stored in the buffer
char *msg = "Hi, I'm a message"; // strlen(msg) == 17
uint16_t sender_id = htons(1); // sizeof(sender_id) == 2
uint16_t packet_size = htons(sizeof(packet_size)+sizeof(sender_id)+strlen(msg)); // sizeof(packet_size) == 2
// Checking values
printf("l1_connect():\nsender_id: %d, packet_size: %d\n\n", ntohs(sender_id), ntohs(packet_size));
// sender_id == 1, packet_size == 21
// The buffer
char buf[100];
// Copying everything
memcpy(&buf, &sender_id, sizeof(sender_id));
memcpy(&buf+sizeof(sender_id), &packet_size, sizeof(packet_size));
memcpy(&buf+sizeof(sender_id)+sizeof(packet_size), &msg, strlen(msg));
// Passing buf to another function
int bytes_sent = l1_send(1, buf, sizeof(buf));
}
I then try to extract that data (checking, before sending over UDP socket):
int l1_send( int device, const char* buf, int length ) {
// Variables in which to store extracted data
uint16_t id = 0;
uint16_t size = 0;
char msg[50];
memcpy(&id, &buf, sizeof(id));
memcpy(&size, &buf+sizeof(id), sizeof(size));
int remaining = ntohs(size) - (sizeof(id) + sizeof(size));
printf("l1_send():\nremaining: %d\n", remaining); // -37041
// memcpy-ing with correct(?) offset
memcpy(&msg, &buf+sizeof(id)+sizeof(size), 50);
msg[49] = '\0';
printf("id: %d\n", ntohs(id)); // 8372
printf("size: %d\n", ntohs(size)); // 37045
printf("msg: %s\n", msg); // ��$_�
return 0; // For now
}
As you can see, the values aren't quite what I'm expecting. Can anyone tell me what I'm doing wrong?
Your pointer math is incorrect. You're using &buf where you should just be using buf. If this doesn't explain what is wrong, nothing else I can say will:
#include <stdio.h>
int main(int argc, char **argv)
{
char buff[100];
printf("buff : %p\nbuff+10 : %p\n&buff+10 : %p\n", buff, buff+10, &buff+10);
return 0;
}
Output (varies by platform, obviously)
buff : 0xbf87a8bc
buff+10 : 0xbf87a8c6
&buff+10 : 0xbf87aca4
See it live. The math you're doing is incrementing by type, which for &buf is a pointer to array of 100 chars; not a simple char address. Therefore, &buff + 10 (in my sample) says "give me the 10th array of 100 chars from where I am now.". The subsequent write is invoking undefined behavior as a consequence.
Valgrind is your buddy here, btw. It would have caught this in a heartbeat.
Update
May as well fill in the entire gambit while I'm here. This is also wrong in l1_send:
memcpy(&id, &buf, sizeof(id));
// this------^
and the subsequent other areas you're using it in that function. You're taking the address of a parameter pointer, not the value within it. I'm confident you need buf there as well.
Try this:
memcpy(buf, &sender_id, sizeof(sender_id));
memcpy(buf + sizeof(sender_id), &packet_size, sizeof(packet_size));
memcpy(buf + sizeof(sender_id) + sizeof(packet_size), msg, strlen(msg));
To help you understand what is wrong with your code, you can read this.
Related: Pointer math vs. Array index