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