1 /*
2     Nast - map.c
3 
4     This program is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 2 of the License, or
7     (at your option) any later version.
8 
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13 
14     You should have received a copy of the GNU General Public License
15     along with this program; if not, write to the Free Software
16     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 
18 */
19 
20 /* pseudo BuG : If someone is arp-poisoning we must him as the owner of the ip!
21 
22 ------
23 
24  * This function receive 1 if it must print to stdout (nast -m)
25  * alse 0 if is used by another funz (run in silent mode)
26  *
27  *
28  * Return if called from another function:
29  * - NULL on error
30  * - n=0 if localhost is the only host in network segment
31  * - n>0 and struct host
32  */
33 
34 /* Don't touch here said embyte */
35 
36 #include "include/nast.h"
37 
38 int arpreply (u_char *t, char *dev, u_short mode, int lg);
39 int send_arp(libnet_t *l, u_char *device, u_char *ip_dst, u_char *enet_src, u_long ip_src);
40 struct host * map_lan(char *dev, u_short mode, u_short * n);
41 u_int scan_ulong(char *s, u_long *u);
42 
43 int line;
44 
45 u_char enet_dst[6] =        /* broadcast */
46 {
47    0xff, 0xff, 0xff, 0xff, 0xff, 0xff
48 };
49 
50 u_short k, count;
51 struct host * uphost;
52 char errbuf[256];
53 libnet_ptag_t ptag;
54 
map_lan(char * dev,u_short mode,u_short * n)55 struct host * map_lan(char *dev, u_short mode, u_short * n)
56 {
57    libnet_t *l;
58    struct libnet_ether_addr *e;
59    struct in_addr addr;
60    char r[3];
61    long ip_src;
62    u_long u;
63    u_int i;
64    u_char ip_dst[4], orig_ip[4];
65    u_char netmask[4], enet_src[6], offset[4];
66    char *net, *mask;
67    u_short j[4]; /* index */
68 
69 
70    count=k=ptag=0;
71    line = 7;
72 
73 #ifdef HAVE_LIBNCURSES
74    if(graph && mode)
75      init_scr();
76 #endif
77 
78    /* make uphost point to at least 1 cell to avoid conflict with NULL on error */
79    uphost = calloc (1, sizeof (struct host));
80 
81    if (demonize && mode)
82      {
83 	w_error(0,"Is very useless demonize me in mapping LAN! Omit");
84 	demonize=0;
85      }
86 
87    if ((l = libnet_init (LIBNET_LINK, dev, errbuf))==NULL)
88      {
89 	w_error(1, "libnet_init() : %s\n", errbuf);
90      }
91 
92    if ((e = libnet_get_hwaddr(l))==NULL)
93      {
94 	w_error(1, "Can't get hardware address: %s\n", errbuf);
95      }
96 
97    memcpy (enet_src, e->ether_addr_octet, 6);
98 
99    if((ip_src = libnet_get_ipaddr4(l))==-1)
100      {
101 	w_error(1, "Error getting ip source\n");
102      }
103 
104    if (pcap_lookupnet(dev, &netp, &maskp, errbuf)==-1)
105      {
106 	w_error(1, "Error: %s\n", errbuf);
107      }
108 
109    addr.s_addr = netp;
110    if ((net = inet_ntoa(addr))==NULL)
111      {
112 	w_error(1, "Impossible get the netaddress\n");
113      }
114 
115    /* netaddress */
116    i = scan_ulong(net,&u); if (!i) return NULL; ip_dst[0] = u; net += i;
117    if (*net != '.') return NULL; ++net;
118    i = scan_ulong(net,&u); if (!i) return NULL; ip_dst[1] = u; net += i;
119    if (*net != '.') return NULL; ++net;
120    i = scan_ulong(net,&u); if (!i) return NULL; ip_dst[2] = u; net += i;
121    if (*net != '.') return NULL; ++net;
122    i = scan_ulong(net,&u); if (!i) return NULL; ip_dst[3] = u; net += i;
123 
124    memcpy (orig_ip, ip_dst, 4);
125 
126    addr.s_addr = maskp;
127    if ((mask = inet_ntoa(addr))==NULL)
128      {
129 	w_error(1, "Impossible get the netmask\n");
130      }
131 
132    /* netmask */
133    i = scan_ulong(mask,&u); if (!i) return NULL; netmask[0] = u; mask += i;
134    if (*mask != '.') return NULL; ++mask;
135    i = scan_ulong(mask,&u); if (!i) return NULL; netmask[1] = u; mask += i;
136    if (*mask != '.') return NULL; ++mask;
137    i = scan_ulong(mask,&u); if (!i) return NULL; netmask[2] = u; mask += i;
138    if (*mask != '.') return NULL; ++mask;
139    i = scan_ulong(mask,&u); if (!i) return NULL; netmask[3] = u; mask += i;
140 
141    /* computate offset from netaddress and netmask */
142    for (i=0; i<=3; i++)     offset[i]=255-netmask[i];
143 
144    /* large netmask */
145    if (offset[1] && offset[2] && offset[3])
146      {
147 	if (mode)
148 	  {
149 	     n_print ("winfo",1,2,lg,"You are going to scan a large network (%s netmask)! Are you sure? (y/n) : ", nast_atoda(netmask));
150 	     fgets(r, 3, stdin);
151 	     if (!(r[0]=='s' || r[0]=='S' || r[0]=='y' || r[0]=='Y')) goto refuse;
152 	     printf ("\n");
153 	  }
154 	else
155 	  n_print ("winfo",2,2,lg,"Warning, scanning a large netmask (%s), this will take a long time\n", nast_atoda(netmask));
156      }
157 
158    /* begin to map */
159    if (mode)
160      {
161 	n_print("princ",1,1,lg,"Mapping the Lan for %s subnet ... please wait\n\n", nast_atoda(netmask));
162 	n_print("princ",3,1,lg,"MAC address\t\tIp address (hostname)\n");
163 	n_print("princ",4,1,lg,"===========================================================\n");
164      }
165 
166    /* print il localhost */
167    if (mode)
168      {
169 	n_print ("princ",6,1,lg,"%s\t", nast_hex_ntoa (e->ether_addr_octet));
170 	n_print ("princ",6,24,lg,"%s (%s) (*)\n",libnet_addr2name4(ip_src , 0),libnet_addr2name4(ip_src , LIBNET_RESOLVE));
171      }
172 
173    /* open descriptor to read */
174    if ((descr = pcap_open_live (dev, BUFSIZ, NOT_PROMISC, 10, errbuf))==NULL)
175      {
176 
177 	w_error(1, "pcap_open_live() error : %s\n", errbuf);
178      }
179 
180    /* put filter on arp */
181    if(pcap_compile(descr, &fp, "arp", 0, netp) == -1)
182      {
183 	w_error(1,"Error calling pcap_compile\n\n");
184      }
185    if(pcap_setfilter(descr, &fp) == -1)
186      {
187 	w_error(1, "Error calling pcap_setfilter\n\n");
188      }
189 
190    /* begin! */
191 
192    /* don't arp request subnet ip */
193    ip_dst[3]++;
194 
195    /* 255.255.255.XXX */
196    if (!offset[0] && !offset[1] && !offset[2] && offset[3])
197      for (j[3]=0; j[3]<=offset[3]; j[3]++)
198        {
199 	  if (send_arp(l, dev, ip_dst, enet_src, ip_src)==-1) goto error;
200 	  arpreply(ip_dst, dev, mode, lg);
201 	  ip_dst[3]++;
202        }
203    /* 255.255.XXX.XXX */
204    else if (!offset[0] && !offset[1] && offset[2] && offset[3])
205      for (j[2]=0; j[2]<=offset[2]; j[2]++)
206        {
207 	  for (j[3]=0; j[3]<=offset[3]; j[3]++)
208 	    {
209 	       if (send_arp(l, dev, ip_dst, enet_src, ip_src)==-1) goto error;
210 	       arpreply(ip_dst, dev, mode, lg);
211 	       ip_dst[3]++;
212 	    }
213 	  ip_dst[2]++;
214 	  ip_dst[3]=orig_ip[3];
215        }
216    /* 255.XXX.XXX.XXX */
217    else if (!offset[0] && offset[1] && offset[2] && offset[3])
218      {
219 	for (j[1]=0; j[1]<=offset[1]; j[1]++)
220 	  {
221 	     for (j[2]=0; j[2]<=offset[2]; j[2]++)
222 	       {
223 		  for (j[3]=0; j[3]<=offset[3]; j[3]++)
224 		    {
225 		       if (send_arp(l, dev, ip_dst, enet_src, ip_src)==-1) goto error;
226 		       arpreply(ip_dst, dev, mode, lg);
227 		       ip_dst[3]++;
228 		    }
229 		  ip_dst[2]++;
230 		  ip_dst[3]=orig_ip[3];
231 	       }
232 	     ip_dst[1]++;
233 	     ip_dst[2]=orig_ip[2];
234 	  }
235      }
236    /* XXX.XXX.XXX.XXX */
237    else if (offset[0] && offset[1] && offset[2] && offset[3])
238      {
239 	for (j[0]=0; j[0]<=offset[1]; j[0]++)
240 	  {
241 	     for (j[1]=0; j[1]<=offset[1]; j[1]++)
242 	       {
243 		  for (j[2]=0; j[2]<=offset[2]; j[2]++)
244 		    {
245 		       for (j[3]=0; j[3]<=offset[3]; j[3]++)
246 			 {
247 			    if (send_arp(l, dev, ip_dst, enet_src, ip_src)==-1) goto error;
248 			    arpreply(ip_dst, dev, mode, lg);
249 			    ip_dst[3]++;
250 			 }
251 		       ip_dst[2]++;
252 		       ip_dst[3]=orig_ip[3];
253 		    }
254 		  ip_dst[1]++;
255 		  ip_dst[2]=orig_ip[2];
256 	       }
257 	     ip_dst[0]++;
258 	     ip_dst[1]=orig_ip[1];
259 	  }
260      }
261    /* paranoic test */
262    else
263      {
264 	w_error(1, "Netmask error: %s is invalid\n\n", nast_atoda(netmask));
265      }
266 
267    error:
268    if (mode) n_print ("winfo",2,1,lg,"\n(*) This is localhost\n\n");
269    refuse:
270    if (descr) pcap_close (descr);
271    if (l) libnet_destroy(l);
272 
273    /* print to video (map has been called from cmd line) */
274    if (mode)
275      {
276 	n_print("winfo",1,1,lg,"                                                   \n");
277 	n_print("winfo",1,1,lg,"Finished\n");
278 	return NULL;
279      }
280    /* map has been called from another funz */
281    else
282      {
283         /* number of found hosts */
284 	*n = k;
285 	return (uphost);
286      }
287 
288 }
289 
290 /* stolen from arpreply by ? */
scan_ulong(char * s,u_long * u)291 u_int scan_ulong(char *s, u_long *u)
292 {
293    u_int pos;
294    u_long c, result;
295 
296    pos = result = 0;
297 
298    while ((c = (u_long) (u_char) (s[pos] - '0')) < 10)
299      {
300 	result = result * 10 + c;
301 	++pos;
302      }
303    *u = result;
304    return (pos);
305 }
306 
307 /* is it alive? */
arpreply(u_char * t,char * dev,u_short mode,int lg)308 int arpreply(u_char *t, char *dev, u_short mode,int lg)
309 {
310    struct nast_arp_hdr *arp;
311    struct libnet_ethernet_hdr *eptr;
312    u_short sd, pcount;
313    u_char ip[20];
314    struct timeval tv;
315    fd_set rfsd;
316 
317    /* retrive socket descriptor for select() funz */
318    sd = pcap_fileno(descr);
319 
320    /* timeout is 5 packet or timer.. */
321    pcount = 0;
322 
323    /* try for an answer ... */
324    for (;;)
325      {
326 	FD_ZERO (&rfsd);
327 	FD_SET (sd ,&rfsd);
328 	tv.tv_sec = 0;
329 	tv.tv_usec = 20000;
330 
331 	if (pcount == 5) break;
332 
333 	if (!select(sd+1, &rfsd, NULL, NULL, &tv))
334 	  break; /* timeout */
335 
336 	if ((packet = (u_char *) pcap_next (descr, &hdr))==NULL)
337 	  continue;
338 
339 	offset=(device(dev,descr));
340 	eptr = (struct libnet_ethernet_hdr *) (packet);
341 	arp = (struct nast_arp_hdr *)(packet+offset);
342 
343 	/* It's an arp reply! */
344 	if ((ntohs(arp->ar_op)) == 2)
345 	  {
346 	     sprintf (ip, "%d.%d.%d.%d", arp->__ar_sip[0],arp->__ar_sip[1],arp->__ar_sip[2],arp->__ar_sip[3]);
347 
348 	     if (memcmp (t, arp->__ar_sip, sizeof(arp->__ar_sip)))
349 	       continue;
350       	     /* it's it! */
351 	     else
352 	       {
353 		  if (mode)
354 		    {
355 		       n_print("princ",line,1,lg,"%s \t%s (%s)\n", nast_hex_ntoa (eptr->ether_shost), ip, libnet_addr2name4(inet_addr(ip), LIBNET_RESOLVE));
356 		       ++line;
357 		    }
358 		  else
359 		    {
360 		       /* ask for new memory */
361 		       if (k) uphost = realloc (uphost, (k+1)*sizeof(struct host));
362 		       memcpy (uphost[k].ip,  arp->__ar_sip, 4);
363 		       memcpy (uphost[k].mac, eptr->ether_shost, 6);
364 		       k++;
365 		    }
366 	       }
367 	     break;
368 	  }
369 	pcount ++;
370      }
371    return 0;
372 }
373 
374 /* Build our arp request */
send_arp(libnet_t * l,u_char * device,u_char * ip_dst,u_char * enet_src,u_long ip_src)375 int send_arp(libnet_t *l, u_char *device, u_char *ip_dst, u_char *enet_src, u_long ip_src)
376 {
377    if ((ptag = libnet_build_arp(ARPHRD_ETHER, ETHERTYPE_IP, 6, 4, ARPOP_REQUEST, enet_src,
378 				(u_char *)&ip_src, enet_dst, ip_dst, NULL, 0, l, ptag)) == -1)
379      {
380 	w_error(1, "libnet_build_arp error : %s\n", libnet_geterror(l));
381      }
382 
383    if (!count)
384      {
385 	count ++;
386 	if (libnet_build_ethernet(enet_dst, enet_src, ETHERTYPE_ARP, NULL, 0, l, 0)==-1)
387 	  {
388 	     w_error(1, "libnet_build_ethereal error : %s\n", libnet_geterror(l));
389 	  }
390      }
391    if (libnet_write(l)==-1)
392      {
393 	w_error(1, "Error writing arp request : %s\n", libnet_geterror(l));
394      }
395    return 0;
396 }
397