Calculate IP Address
Initialize before using


    int bit_counter, net_bit_counter = 0;



There are a couple problems.  First, if you declare and initialize in the same statement, you should only declare one variable.  

    int bit_counter = 0;
    int net_bit_counter = 0;


If you have two variables, declare them on two lines.  Only declare multiple variables on a single line if you initialize none of them.  And some would argue not even then.  There's no functional difference, but it is much easier to read with every initialized declaration on a separate line.  

Second, you don't initialize bit_counter.  C does not automatically initialize variables to default values, so this can cause bizarre behavior.  When I first tried to run this code, it gave me a runtime error until I initialized all the variables.  

Know your bounds


    while (bit_counter != 33) {



This is a bit fragile.  You currently allow bit_counter to be incremented multiple times per iteration of this loop.  What if when it is 32, you increment to 34 without hitting this check?  The check will keep succeeding until the the program crashes (possibly due to trying to write outside the array).  

    while (bit_counter &lt;= 32) {


This is much more robust.  It no longer has to hit the mark exactly to stop.  Now it will stop for any value greater than 32, not just 33.  

Another benefit, for readability, is that it now says 32, which is the critical number here.  Previously it said 33, which is one more than the last number.  

But this is actually a bug.  It should be 

    while (bit_counter &lt; 32) {


because literal_bit_mask is only 32 long.  The first element is 0.  The last element is 31.  Now it won't write past the end of the array.  

C has an increment by one operator


            net_bit_counter += 1;
            bit_counter += 1;



You can write this more idiomatically as 

            ++net_bit_counter;
            ++bit_counter;


This shouldn't make much functional difference (perhaps not any on many platforms), but most C programmers would find this more recognizable.  

I used the prefix form because some C compilers may not be smart enough to avoid the copy step of the postfix form.  I would expect most compilers to optimize that out, but we don't need to rely on that.  It's unlikely to make a noticeable difference here.  

++bit_counter increments bit_counter and returns that value.  bit_counter++ returns the value it had before incrementing.  If you don't use the value (as you don't here), there is no real functional difference.  It's possible that the compiler may return different machine instructions.  In particular, it might copy the value to another register and then increment.  That's unnecessary if the 

The following are functionally equivalent (leave the variables with the same values at the end):  

int var = bit_counter++;


and 

int var = bit_counter;
bit_counter++;


and 

int var = bit_counter;
++bit_counter;


The following are different from the previous three, but are functionally equivalent to each other:  

bit_counter++;
int var = bit_counter;


and 

++bit_counter;
int var = bit_counter;


and 

int var = ++bit_counter;


If bit_counter starts as 0 and is incremented to 1, then the first three will set var to 0.  The last three will set var to 1.  

Many consider it easier to read if the variables are changed on separate lines.  This makes it obvious that the variables are changing.  Doing two things on the same line is less obvious, because people may see one and miss the other.