s_frank
s_frank

Reputation: 23

Dotted decimal to binary in C

I have an in_addr struct with an IP address that I'm trying to convert from dotted decimal to a binary value. What I really need to do, but can't make work, is something like

destn = inet_addr(inet_ntoa(addr));

where addr is the in_addr_t variable. I know that violates the syntax, but when I follow the syntax more carefully, I get an error:

storage size of ‘addr’ isn’t known.

Upvotes: 0

Views: 2809

Answers (2)

Steve
Steve

Reputation: 493

For future compatibility, you should handle both IP 4 and 6. Otherwise, you might have mentioned inet_ntoa instead of inet_ntop. (My phone uses IP 6, so I need to allow for it if I do IP programming on my phone.) So, how? Here's how I'd start:

char *address_string;

(Fill in the value of address_string.)

struct in_addr addr4;
int success4 = inet_pton(AF_INET, address_string, addr4);
struct in6_addr addr6;
int success6 = inet_pton(AF_INET6, address_string, addr6);

You'll want to add error handling, of course.

If you're trying to get a text representation of a binary IP number instead, this should do the job:

struct in_addr addr4;
struct in6_addr addr6;
bool address_is_ip6;

(Fill in the value of the IP 4 or 6 address, and note which one you're using.)

socklen_t ip6_maximum_length = 40;
char address_string[ip6_maximum_length];
char *result = inet_ntop(address_is_ip6 ? AF_INET6 : AF_INET, address_is_ip6 ? &addr6 : &addr4, address_string, ip6_maximum_length);

Again, you'll need error handling.

Upvotes: 1

Jonathon Reinhart
Jonathon Reinhart

Reputation: 137497

If you already have an IPv4 address in a struct in_addr variable, then there is nothing you need to do:

/* Internet address. */
struct in_addr {
    uint32_t       s_addr;     /* address in network byte order */
};

See ip(7). Simply access the s_addr field, and you have your IPv4 address in a simple 32-bit integer.

Example program:

#include <stdio.h>
#include <inttypes.h>
#include <arpa/inet.h>

int main(int argc, char *argv[])
{
    struct in_addr addr = {};
    const char *ip_str;

    if (argc < 2) {
        fprintf(stderr, "Usage: %s ip-addr\n", argv[0]);
        return 1;
    }
    ip_str = argv[1];

    if (!inet_aton(ip_str, &addr)) {
        fprintf(stderr, "Invalid IP address: %s\n", ip_str);
        return 1;
    }

    printf("Address: 0x%08"PRIX32"\n", addr.s_addr);
    // Just access the s_addr field --------^

    return 0;
}

Example usage:

$ gcc -Wall -Werror in.c 
$ ./a.out 192.168.7.4
Address: 0x0407A8C0
           ^ ^ ^ ^
           | | | \---- 192
           | | \------ 168
           | \-------- 7
           \---------- 4

Upvotes: 2

Related Questions