2

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;
user2467899
  • 583
  • 2
  • 6
  • 19
  • just check if it's all digits and periods, e.g. [0-255].[0-255].[0-255].[0-255]. if it's got any non-digits/non-periods, then it's most likely a hostname. – Marc B Jun 14 '13 at 14:37
  • 1
    Won't getaddrinfo() work with either a host string or an IP address string? – Bert Jun 14 '13 at 14:39
  • If you check the digits, you'd have to turn the string into an integer value. Some canonical names will be in this range even though its not hte correct IP. – KrisSodroski Jun 14 '13 at 14:40

2 Answers2

3

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

Nikolai Fetissov
  • 82,306
  • 11
  • 110
  • 171
2

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.

A.H.
  • 63,967
  • 15
  • 92
  • 126
  • So, I can do this: 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; I try now! Thank for now! – user2467899 Jun 14 '13 at 15:29
  • Sorry but It seems to be not formatted. I edit my question so you can read better. See in my question the "POSSIBLE SOLUTION" section. – user2467899 Jun 14 '13 at 15:30