I get a mask as a string that I retrieve using strtol
and strtok
and that I want to save in an unsigned int x
, trail with zeros, and &
it with an IP represented also as unsigned int
in order to keep the MSBs only (At the end I'm going to compare that IP with another).
My idea was to set all the bits of x
, and then turn off all bits placed after the mask size:
#define IPV4_LENGTH 32
//subent is "123.34.45.66/31"
curr_IP->address = malloc(sizeof (struct in_addr));
token = strtok(subnet, "/");
inet_aton(token, curr_IP->address);
long mask = strtol(strtok(NULL, "/"), NULL, 10);
curr_IP->x = -1;
for(long i=mask; i<=IPV4_LENGTH; i++){
curr_IP->x &= ~(1U << i);
}
Example: if mask = 31, I want to end with 11111111111111111111111111111110 represented in unsigned int
-> FFFFFFFE in HEX
P.S mask can't be 0
UPDATE:
Memory view after curr_IP->x = -1;
We can see it indeed sets up all the bits
Memory view after curr_IP->x &= ~(1U << i);
when i = 31
expected fffffffe
I choose a different approach; turning off the mask and then setting the relevant bits to 1.
long mask = strtol(strtok(NULL, "/"), NULL, 10);
curr_IP->x = 0; //mask to 0
for(long i=IPV4_LENGTH - mask; i<IPV4_LENGTH; i++){
curr_IP->x |= (1U << i); //Sets the ith bit of the mask
}
Edit: As Morten Jensen pointed, it is better not to mix signed and unsigned integers, so the corrected code looks like that:
unsigned long mask = strtol(strtok(NULL, "/"), NULL, 10);
curr_IP->x = 0; //mask to 0
for(unsigned long i=IPV4_LENGTH - mask; i<IPV4_LENGTH; i++){
curr_IP->x |= (1U << i); //Sets the ith bit of the mask
}
Also, I struggled with debugging the code myself because I used the Memory view without realizing that I should read it from right to left.
In picture #2, I thought that I got fffffff7
when it was actually 7fffffff