user2467899
user2467899

Reputation: 575

Canonical name or IP address - socket, linux and C

How can I know if a string is the canonical name or the IP address?

Because if argv[1] is the IP address I do:

sscanf(argv[2],"%" SCNu16,&server_port);
inet_aton(argv[1],&server_address);

remote_address.sin_family = AF_INET;
remote_address.sin_port = htons(server_port); 
remote_address.sin_addr = server_address;  

And if argv[1] is the canonical name I do:

h = gethostbyname(server);

indirizzo_remoto.sin_family = AF_INET;
indirizzo_remoto.sin_port = htons(porta_server); 
indirizzo_remoto.sin_addr = XYZ;

Also, what do I have to have in place of XYZ?

POSSIBLE SOLUTION:

struct in_addr indirizzo_server; 
struct hostent *h; 

h = gethostbyname(server); 

inet_aton(h->h_addr_list[0],&indirizzo_server); 

indirizzo_remoto.sin_family = AF_INET; 
indirizzo_remoto.sin_port = htons(porta_server); 
indirizzo_remoto.sin_addr = indirizzo_server;

Upvotes: 2

Views: 1614

Answers (2)

A.H.
A.H.

Reputation: 66273

Why the fuzz? gethostbyname already takes care of that. Quoting the manual:

[...]name is either a hostname, or an IPv4 address in standard dot notation (as for inet_addr(3)), or an IPv6 address in colon (and possibly dot) notation.

So delete the special handling with inet_aton and be done.

Regarding the XYZ part: The hostent structure contains two things you must copy into your in_addr:

  • the h_addrtype which might indicate IPv4 or IPv6. Copy it into sin_family.
  • the actual address(es) in h_add_list. Copy this into your sin_addr using memcpy and the length given in h_length.

This should both handle IPv4 and IPv6 automatically.

Upvotes: 2

Nikolai Fetissov
Nikolai Fetissov

Reputation: 84189

Get familiar with getaddrinfo(3) that can do either, and also supports IPv6.

Upvotes: 3

Related Questions