Sunday, October 31, 2010

How to program for IP - resolver against a host-name

For this matter u need to have some prerequisite :-
1)Knowledge of C language
2)Unix based system on ur Box


Now here we go is the code for resolving the IP address from given hostnames:
given program in line no 40 gets the address info with help of getaddrinfo( ) function line no. 46 to 61 prints the Ip addresses. Loop from 46 to 61 is for the case if server is having multiple Ip's .User can give n numbers of hostname and corresponding IP'll be resolved.
Explanation of program is described just after the program .

1:  //   Ipresolver.c  
2:  //     
3:  //   Copyright 2010 ananya <ananya@kgeek-laptop>   
4:  //     
5:  //   This program is free software; you can redistribute it and/or modify  
6:  //   it under the terms of the GNU General Public License as published by  
7:  //   the Free Software Foundation; either version 2 of the License, or  
8:  //   (at your option) any later version.  
9:  //     
10:  //   This program is distributed in the hope that it will be useful,  
11:  //   but WITHOUT ANY WARRANTY; without even the implied warranty of  
12:  //   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the  
13:  //   GNU General Public License for more details.  
14:  //     
15:  //   You should have received a copy of the GNU General Public License  
16:  //   along with this program; if not, write to the Free Software  
17:  //   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,  
18:  //   MA 02110-1301, USA.  
19:  #include <stdio.h>  
20:  #include <string.h>  
21:  #include <sys/types.h>  
22:  #include <sys/socket.h>  
23:  #include <netdb.h>  
24:  #include <arpa/inet.h>  
25:  int main(int argc, char *argv[])  
26:  {  
27:    struct addrinfo hints, *res, *p;  
28:    int status,i;  
29:    char ipstr[INET6_ADDRSTRLEN];  
30:    if (argc == 1) {  
31:      fprintf(stderr,"usage: showip hostname[n]\n");  
32:      return 1;  
33:    }  
34:   for(i=1;i<argc;i++)  
35:   {  
36:    printf("************************************************\n");  
37:    memset(&hints, 0, sizeof hints);  
38:    hints.ai_family = AF_UNSPEC;   
39:    hints.ai_socktype = SOCK_STREAM;  
40:    if ((status = getaddrinfo(argv[i], NULL, &hints, &res)) != 0) {      //getaddrinfo() call goes here   
41:      fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(status));      //Ip and other info regarding hostname is stored in struct addrinfo res     
42:      return 2;  
43:    }  
44:    //printf("%d\n",status);  
45:    printf("IP addresses for %s:\n\n", argv[i]);  
46:    for(p = res;p != NULL; p = p->ai_next) {                  //Loop goes for different Ips if hostname has multiple Ip's  
47:      void *addr;  
48:      //in_port_t port;  
49:      char *ipver;  
50:      if (p->ai_family == AF_INET) {                    //If it is IPv4  
51:        struct sockaddr_in *ipv4 = (struct sockaddr_in *)p->ai_addr;     
52:        addr = &(ipv4->sin_addr);                     //Extracting Ip address in binary format   
53:        //port=ipv4->sin_port;  
54:        ipver = "IPv4";                            
55:      } else {                               //If it is IPv6                
56:        struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)p->ai_addr;    
57:        addr = &(ipv6->sin6_addr);  
58:        ipver = "IPv6";  
59:      }  
60:      inet_ntop(p->ai_family, addr, ipstr, sizeof ipstr);          //convert binary Ip notation in text i.e dotted decimal form  
61:      printf(" %s: %s \n", ipver, ipstr);  
62:    }  
63:  }  
64:    freeaddrinfo(res);   
65:    return 0;  
66:  }  

Compiling Info:-

$ gcc IPresolver.c -o Ipresolver.o  


$ ./Ipresolver.o www.nitk.ac.in www.google.com www.slashdot.org

Corresponding Output:-


 ************************************************  
 IP addresses for www.nitk.ac.in:  
  IPv4: 210.212.194.8   
 ************************************************  
 IP addresses for www.google.com:  
  IPv4: 72.14.213.105   
  IPv4: 72.14.213.106   
  IPv4: 72.14.213.147   
  IPv4: 72.14.213.99   
  IPv4: 72.14.213.103   
  IPv4: 72.14.213.104   
 ************************************************  
 IP addresses for www.slashdot.org:  
  IPv4: 216.34.181.48   

so here we go:-
Socket Descriptor it is of type int.
1:   struct addrinfo {  
2:          int       ai_flags;              // AI_PASSIVE, AI_CANONNAME, etc.  
3:          int       ai_family;             //AF_INET (IPv_4),AF_INET6 (IPV_6)  
4:          int       ai_socktype;          //SOCK_STREAM,SOCK_DGRM  
5:          int       ai_protocol;           //Usually "0"  
6:          size_t     ai_addrlen;           // size of ai_addr in bytes   
7:          struct sockaddr *ai_addr;         //struct sockaddr_in or _in6          
8:          char      *ai_canonname;       //full canonical hostname  
9:          struct addrinfo *ai_next;          //next node in lineked list  
10:        };  
u can even get this struct info using konsole command :-
$ man getaddrinfo  

1:  struct sockaddr {  
2:          sa_family_t sa_family;  
3:          char    sa_data[14];  
4:        }  
the only purpose of above is to cast the structure pointer passed in addr in order to avoid compiler warnings.
u can even get this struct info using konsole command :-
$ man bind  
To deal with struct sockaddr, programmers created a parallel structure: struct sockaddr_in ("in" for "Internet") to be used with IPv4. and sockaddr_in6 for IPv6
Structure sockaddr_in6
1:  struct sockaddr_in6 {  
2:          sa_family_t   sin6_family;  /* AF_INET6 */  
3:          in_port_t    sin6_port;   /* port number */  
4:          uint32_t    sin6_flowinfo; /* IPv6 flow information */  
5:          struct in6_addr sin6_addr;   /* IPv6 address */  
6:          uint32_t    sin6_scope_id; /* Scope ID (new in 2.4) */  
7:        };  
8:        struct in6_addr {  
9:          unsigned char  s6_addr[16];  /* IPv6 address */  
10:        };  
u can even get this struct info using konsole command :-
$ man ipv6   
similarly struct sockaddr_in for IPv4 cab b viewed .
First, let's say you have a struct sockaddr_in ina, and you have an IP address "192.168.0.48" or "2001:db8:63b3:1::3490" that you want to store into it. The function you want to use, inet_pton(), converts an IP address in numbers-and-dots notation into either a struct in_addr or astruct in6_addr depending on whether you specify AF_INET or AF_INET6. ("pton" stands for "presentation to network"—you can call it "printable to network" if that's easier to remember.) The conversion can be made as follows:
1:  inet_pton(AF_INET, "192.168.0.48", &(sa.sin_addr)); // IPv4  
2:  inet_pton(AF_INET6, "2001:db8:63b3:1::3490", &(sa6.sin6_addr)); // IPv6 
u can get infomation about inet_pton() using following command in konsole:-
$ man inet_pton  
getaddrinfo()
It used to be that you would use a function called gethostbyname() to do DNS lookups. Then you'd load that information by hand into a struct sockaddr_in, and use that in your calls.
In these modern times, you now have the function getaddrinfo() that does all kinds of good stuff for you, including DNS and service name lookups, and fills out the structs you need, besides!
1:   #include <sys/types.h>  
2:   #include <sys/socket.h>  
3:   #include <netdb.h>  
4:   int getaddrinfo(const char *node, const char *service,  
5:              const struct addrinfo *hints,  
6:              struct addrinfo **res);  
7:   void freeaddrinfo(struct addrinfo *res);  
8:   const char *gai_strerror(int errcode);  
U can get hell lot of information about this function using konsole command:
$ man getaddrinfo  
                                    
                  Enjoy Rest in peace 

No comments:

Post a Comment