source: ocsinventory-agent/trunk/fuentes/resources/ipdiscover/ipdiscover.c @ 468

Last change on this file since 468 was 468, checked in by mabarracus, 4 years ago

Copyt trusty code

File size: 6.8 KB
Line 
1/*
2###############################################################################
3##OCSInventory Version NG Beta
4##Copyleft Pascal DANEK 2006
5##Web : http://ocsinventory.sourceforge.net
6##
7##This code is open source and may be copied and modified as long as the source
8##code is always made freely available.
9##Please refer to the General Public Licence http://www.gnu.org/ or Licence.txt
10################################################################################
11*/
12#include "ipdiscover.h"
13
14/* We get IP address, netmask, index number and mac address of the adapter */
15void get_iface_infos( packet *ppacket, int *index, char *iface, struct sockaddr_in *ipaddr, struct sockaddr_in *netmask){
16  int tmpsock;
17  struct ifreq  ifr;
18  if( ( tmpsock = socket( AF_INET, SOCK_STREAM, 0 ) ) < 0 ){
19    perror("Socket creation problem"); 
20                exit(1); 
21  }
22  /* Initialize */
23  memset( &ifr, 0x0, sizeof(struct ifreq));
24  /* We put into the ifreq struct the name of adapter */
25  strncpy(ifr.ifr_name, iface, IF_NAMESIZE-1);
26 
27  /* IP */
28  if(ioctl(tmpsock, SIOCGIFADDR, &ifr)< 0){
29    close(tmpsock); 
30    perror("Cannot get the ip address"); 
31                exit(1); 
32  }
33  memcpy( &ipaddr->sin_addr, &( (struct sockaddr_in *) &ifr.ifr_addr )->sin_addr, 4 );
34  memcpy( ppacket->arphdr.ar_sip, &( (struct sockaddr_in *) &ifr.ifr_addr )->sin_addr, 4 );
35  /*******************/
36 
37  /* SNM */
38   if(ioctl(tmpsock, SIOCGIFNETMASK, &ifr)< 0){
39    close(tmpsock); 
40    perror("Cannot get the net submask"); 
41                exit(1); 
42  }
43  memcpy(&netmask->sin_addr, &((struct sockaddr_in *) &ifr.ifr_netmask)->sin_addr, 4);
44  /*******************/
45 
46  /* MAC */
47  if(ioctl(tmpsock, SIOCGIFHWADDR, &ifr)< 0){
48    close(tmpsock); 
49    perror("Cannot get the mac address"); 
50                exit(1); 
51  }
52        memcpy( ppacket->ethhdr.h_source, (unsigned char *)&ifr.ifr_hwaddr.sa_data, ETH_ALEN );
53        memcpy( ppacket->arphdr.ar_sha, (unsigned char *)&ifr.ifr_hwaddr.sa_data, ETH_ALEN ); 
54  /*******************/
55 
56  /* INDEX */
57  if(ioctl(tmpsock, SIOCGIFINDEX, &ifr)< 0){
58    close(tmpsock); 
59    perror("Cannot get the interface index");
60                exit(1);
61  }
62  *index = ifr.ifr_ifindex;
63  /*******************/
64  close(tmpsock);
65} 
66
67void data_init( struct sockaddr_in *ipaddr, struct sockaddr_in *netmask, packet **ppacket, struct sockaddr_ll *sll, int index ){
68        memset(ipaddr, 0x00, sizeof(struct sockaddr_in));
69        memset(netmask, 0x00, sizeof(struct sockaddr_in));
70        /* Arp structure */
71        *ppacket = malloc( sizeof( packet ) );
72        /* Tie to adapter */
73        sll->sll_family = AF_PACKET;
74        sll->sll_protocol = htons(ETH_P_ARP);
75        /* Building the packet */
76        memset( (*ppacket)->ethhdr.h_dest, 0xFF, 6 );
77        (*ppacket)->ethhdr.h_proto = htons(0x806);
78       
79        /* arp header */
80        (*ppacket)->arphdr.arp_hrdad = htons(ARPHRD_ETHER);
81        (*ppacket)->arphdr.arp_prot = htons(ETH_P_IP);
82        (*ppacket)->arphdr.arp_halen = ETH_ALEN;
83        (*ppacket)->arphdr.arp_prlen = 4;
84        (*ppacket)->arphdr.arp_opcode = htons(ARPOP_REQUEST);
85        memset( (*ppacket)->arphdr.ar_tha, 0x0,ETH_ALEN );
86}
87
88void print_xml(struct in_addr *ipsrc, packet *ppacket_r, struct hostent* name){
89        printf("<H><I>%s</I><M>%02x:%02x:%02x:%02x:%02x:%02x</M><N>%s</N></H>\n",inet_ntoa(*ipsrc), *ppacket_r->arphdr.ar_sha,ppacket_r->arphdr.ar_sha[1],ppacket_r->arphdr.ar_sha[2], 
90                                 ppacket_r->arphdr.ar_sha[3],ppacket_r->arphdr.ar_sha[4],ppacket_r->arphdr.ar_sha[5], name?name->h_name:"-");
91}
92
93void create_socket(int *sd, struct sockaddr_ll *sll, int index){
94        /* Socket creation */
95        *sd = socket( PF_PACKET, SOCK_RAW, htons( ETH_P_ARP ) );
96       
97        /* Put the iface index in sockaddr_ll structure to bind */
98        sll->sll_ifindex = index;
99       
100        if( sd < 0 ){
101                perror("Socket creation problem");
102                exit(1);
103        }
104        if( fcntl( *sd, F_SETFL, O_NONBLOCK ) == -1 ){
105                perror("Cannot set socket mode to O_NONBLOCK");
106                exit(1);
107        } 
108        /* Bind */
109        if( bind( *sd, (struct sockaddr*)sll, sizeof(*sll) ) == -1 ){
110                perror("Bind error");
111                exit(1);
112        }
113}
114
115void validate_iface( struct sockaddr_in *ipaddr, struct sockaddr_in *netmask, packet *ppacket ){
116        char error_str[100];
117       
118        if( ntohl(netmask->sin_addr.s_addr) < 0xFFFF0000){
119                snprintf(error_str, 100, "Invalid netmask -> too large (%s). Stop\n", inet_ntoa(netmask->sin_addr));
120                perror( error_str );
121                exit(1);
122        }
123}
124
125void scan_init( unsigned long *unet, unsigned long *uhost, struct sockaddr_in *ipaddr, struct sockaddr_in *netmask, struct in_addr *ipsrc, packet **ppacket_r ){
126        /* Netid */
127  *unet = ntohl(ipaddr->sin_addr.s_addr) & ntohl(netmask->sin_addr.s_addr);
128        /* Supposed number of hosts */
129        *uhost = ~( ntohl(netmask->sin_addr.s_addr) );
130        memset(ipsrc, 0, sizeof(struct in_addr));
131        *ppacket_r = malloc( sizeof( packet ) );
132}
133
134int main(int argc, char ** argv){
135        /* Declarations */
136        /* full packet (tx and rx) */
137        packet *ppacket, *ppacket_r;
138        /* Socket descriptor, nic index */
139        int sd    = 0;
140        int flag  = 0;
141        int index = 0;
142        /* ip data */
143  unsigned long unet,uhost,ipdst,tip;
144  /* The name of the interface is given in parameter to the binary */
145  char * iface;
146        /* detected device's FQDN */
147  struct hostent* name;
148        /* ip level sockaddr */
149  struct sockaddr_in ipaddr, netmask;
150        /* Lowlevel sockaddr */
151  struct sockaddr_ll sll = {0x0};
152        /* source ip to put in packet */
153  struct in_addr ipsrc;
154        int request_latency = REQUEST_LATENCY_DEFAULT;
155       
156  int p=0;
157 
158        /* Take at least one argument */
159  if(argc<2){
160                printf("IPDISCOVER binary ver. %d \nUsage : ipdiscover [iface name] [latency in ms]\n", VERSION);
161                exit(0);
162  }else{
163                iface = argv[1];
164                if( argc==3 )
165                        request_latency = atoi( argv[2] );
166  }
167        /* Initialize data */
168        data_init( &ipaddr, &netmask, &ppacket, &sll, index );
169  /* Reading nic parameters */
170        get_iface_infos( ppacket, &index, iface, &ipaddr, &netmask );
171        /* Check iface settings */
172        validate_iface( &ipaddr, &netmask, ppacket );
173        /* Creating socket */
174        create_socket( &sd, &sll, index );
175        /* Initialize packet target ip, potential hosts number... */
176        scan_init( &unet, &uhost, &ipaddr, &netmask, &ipsrc, &ppacket_r );
177       
178  /* We are looking for all the possible connected host */
179        for(ipdst=1;ipdst<uhost;ipdst++){
180                tip = htonl(ipdst+unet);
181                memcpy( ppacket->arphdr.ar_tip, &tip, 4 );
182               
183                /* Sending the packet */
184                if( write( sd, ppacket, sizeof(packet) ) < 0 ){
185                        perror("Transmission error");
186                        exit(1);
187                }
188               
189                flag = 0;
190                usleep( request_latency * 1000 );
191               
192                while( flag>=0 ){
193                        memset( ppacket_r, 0, sizeof( packet ) );
194                        flag = read( sd, ppacket_r, sizeof( packet ) );
195                       
196                        if( flag>0 )
197                                memcpy(&ipsrc, ppacket_r->arphdr.ar_sip, sizeof(struct in_addr));
198                       
199                        if(ntohs(ppacket_r->arphdr.arp_opcode) == 2){
200                                char * c;
201                                if(p==0)
202                                        printf("<IPDISCOVER>\n");
203                                p++;
204                                name = gethostbyaddr(&ipsrc, sizeof(struct in_addr), AF_INET); 
205                                if(name){
206                                        while((c=strchr(name->h_name,'<')) || (c=strchr(name->h_name,'>'))){
207                                                strncpy(c,"x",sizeof(c));
208                                        }
209                                }
210                                usleep( NAME_RES_LATENCY );
211                                print_xml( &ipsrc, ppacket_r, name );
212                        }
213                }
214        }
215if(p)
216  printf("</IPDISCOVER>\n");
217/* That's all */
218  exit(0);
219}
220
Note: See TracBrowser for help on using the repository browser.