1 /*
2     NAST
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 /* return -1 on error, else 0 */
21 
22 #include "include/nast.h"
23 
flink(u_char * dev)24 int flink (u_char *dev)
25 {
26    libnet_t *l = NULL;
27    pcap_t   *p = NULL;
28 
29    u_short ether_type;
30    struct libnet_icmpv4_hdr *icmp;
31    struct libnet_ether_addr *mymac;
32    struct host * uphost;
33    libnet_ptag_t ptag;
34 
35    u_long myip;
36    struct libnet_ipv4_hdr * ip;
37 
38    u_char errbuf[LIBNET_ERRBUF_SIZE];
39 
40    /*to be implemented*/
41    int lg;
42 
43    struct timeval tv;
44    fd_set rfsd;
45 
46    u_char testip[20]; /* ipsorci ritornati da map.c*/
47    u_char mac_src[6], mac_dst[6]; /* mac address */
48    u_long ip_src, ip_dst; /* ip da usare dopo */
49 
50    u_short i, k, sd, pcount, n; /* n=num of up hosts */
51 
52    i = n = k = ptag = ip_dst = sd = lg = 0;
53 
54    if (!dev)
55      {
56 	w_error(1, "Device is null!\n");
57      }
58 #ifdef HAVE_LIBNCURSES
59    if (graph)
60      init_scr();
61 #endif
62 
63    if (demonize)
64      {
65 	w_error (0,"Is very useless demonize me in finding link! Omit");
66 	demonize=0;
67      }
68 
69    n_print ("princ",2,2,lg,"- Searching for possible hosts to use for test : waiting please... ");
70    fflush (stdout);
71 
72    /* find two hosts for test */
73    if ((uphost = map_lan(dev, 0, &n))==NULL)
74      {
75 	if(w_error(0, "\nCan't build truly host list! mmhhh!\nReport bug to author please\n\n")==-1)
76 	  return(0);
77      }
78 
79    /* there are at least 3 host in lan? */
80    if (n<2)
81      {
82 	n_print ("princ",4,2,lg,"\nYou have only %d host in lan, test won't be truly...\n", n+1);
83 	n_print ("princ",5,2,lg,"Try again with at least 3 hosts up.\n\n");
84 	return -1;
85      }
86 
87    /* find a suitable host that reply to ping request */
88    if ((l = libnet_init (LIBNET_RAW4, NULL, errbuf))==NULL)
89      {
90 	w_error(1, "\nError : libnet_init: %s\n", errbuf);
91      }
92 
93    if (!(mymac = libnet_get_hwaddr(l)))
94      {
95 	w_error(1, "\nError : can't get hardware address: %s\n", libnet_geterror(l));
96      }
97 
98    /* MAC is my MAC ADDRESS*/
99    for (k=0; k<6; k++)
100      mac_src[k]=mymac->ether_addr_octet[k];
101 
102    myip = libnet_get_ipaddr4(l);
103    if (myip == -1)
104      {
105 	w_error(1, "\nError : autodetect device ip address failed: %s\n", libnet_geterror(l));
106      }
107 
108    if (libnet_build_icmpv4_echo(ICMP_ECHO, 0, 0, 1000, 5249, NULL, 0, l,0)==-1)
109      {
110         libnet_destroy(l);
111 	w_error(1, "\nError : can't build ICMP header : %s\n", libnet_geterror(l));
112      }
113 
114    for (i = 0; i<n; i++)
115      {
116 	sprintf(testip, "%d.%d.%d.%d", uphost[i].ip[0], uphost[i].ip[1], uphost[i].ip[2], uphost[i].ip[3]);
117 	if ( (ptag = libnet_build_ipv4(LIBNET_ICMPV4_ECHO_H + LIBNET_IPV4_H, 0x00, 1000, 0, 64, IPPROTO_ICMP, 0, myip, inet_addr(testip), NULL, 0, l, ptag)) ==-1)
118 	  {
119 	     libnet_destroy(l);
120 	     w_error(1, "\nError : can't build TCP header : %s\n", libnet_geterror(l));
121 	  }
122 
123 	if (libnet_write (l) == -1)
124 	  {
125 	     libnet_destroy(l);
126 	     w_error(1, "\nError writing packet on wire : %s\n", libnet_geterror(l));
127 
128 	  }
129 
130         /* open pcap device NOT in promisc mode */
131 	if ((p = pcap_open_live (dev, BUFSIZ, NOT_PROMISC, 10, errbuf))==NULL)
132 	  {
133 	     libnet_destroy(l);
134 	     w_error(1, "\nError : pcap_open_liver() error : %s\n", errbuf);
135 	  }
136 
137 	/* retrive socket descriptor for select() funz */
138 	sd = pcap_fileno(p);
139 
140 	/* timeout is 20 packet or timer.. */
141 	pcount = 1;
142 
143 	/* try for an answer ... */
144 	for (;;)
145 	  {
146 	     if (pcount == 20) break;
147 
148              /* set 2 secondz delay | DONT TOUCH! */
149 	     FD_ZERO (&rfsd);
150 	     FD_SET (sd ,&rfsd);
151 	     tv.tv_sec = 2;
152 	     tv.tv_usec = 0;
153 
154 	     if (!select(sd+1, &rfsd, NULL, NULL, &tv))
155 	       break;
156 
157 	     /* capture packet (packet) and pcap_header (hdr) */
158 	     packet = (u_char *) pcap_next (p, &hdr);
159 
160 	     if (packet==NULL) continue;
161 	     if ((ether_type = handle_ethernet (packet)) != ETHERTYPE_IP) continue;
162 
163 	     if ((offset = (device(dev,p)))==-1) return -1;
164 	     ip = (struct libnet_ipv4_hdr *) (packet + offset);
165 	     icmp = (struct libnet_icmpv4_hdr *) (packet + offset + LIBNET_IPV4_H);
166 
167 	     /* my destination victim hosts reply -> GOOD :-) */
168 	     if ((ip->ip_src.s_addr == inet_addr(testip)) && icmp->icmp_type==ICMP_ECHOREPLY && icmp->icmp_id == 1000)
169 	       {
170 		  /* sisitemo ip/mac dst */
171 		  ip_dst = ip->ip_src.s_addr;
172 		  for (k=0; k<6; k++)
173 		    mac_dst[k]=uphost[i].mac[k];
174 
175 		  /* sistemo ip src */
176 		  /* subito il primo host risponde ai ping */
177 		  if (!i)
178 		    sprintf(testip, "%d.%d.%d.%d", uphost[1].ip[0], uphost[1].ip[1], uphost[1].ip[2], uphost[1].ip[3]);
179 		  else
180 		    sprintf(testip, "%d.%d.%d.%d", uphost[0].ip[0], uphost[0].ip[1], uphost[0].ip[2], uphost[0].ip[3]);
181 
182 		  if ( (ip_src=inet_addr(testip)) == -1)
183 		    {
184 		       if(w_error(0, "\nError : uphost[].ip is not a valid ip. Mhh strange, contact developer please\n")==-1)
185 			 return(0);
186 		    }
187 
188 		  /* host found */
189 		  pcap_close (p);
190 		  goto rfound;
191 	       }
192 
193 	     /* altro pacchetto ricevuto */
194 	     pcount ++;
195 
196 	  }
197 
198 	/* l'host non risponde all'icmp request, vado al prossimo */
199 	pcap_close (p);
200      }
201 
202    n_print ("winfo",1,1,lg,"\n\nI don't find any host in you LAN which reply to an icmp request!\nI need at last one to resolve test. Try again later and adjust firewall if you can...\n\n");
203    return -1;
204 
205    /* --------------------------------------------------------------------- */
206 
207    rfound:
208    n_print ("princ",2,68,lg,"OK");
209 
210    if (uphost) free (uphost);
211 
212 
213    n_print ("princ",3,2,lg,"\n- Try to send icmp spoofed request... \n");
214 
215    if ((l = libnet_init (LIBNET_LINK, dev, errbuf))==NULL)
216      {
217 	w_error(1, "libnet_init: %s\n", errbuf);
218      }
219 
220    /* costruisco il pacchetto */
221    if (libnet_build_icmpv4_echo(ICMP_ECHO, 0, 0, 1000, 5249, NULL, 0, l,0)==-1)
222      {
223 	libnet_destroy(l);
224 	w_error(1, "Can't build ICMP header : %s\n", libnet_geterror(l));
225      }
226 
227    if (libnet_build_ipv4(LIBNET_ICMPV4_ECHO_H + LIBNET_IPV4_H, 0x00, 1000, 0, 64, IPPROTO_ICMP, 0, ip_src, ip_dst, NULL, 0, l, 0)==-1)
228      {
229 	libnet_destroy(l);
230 	w_error(1, "Can't build TCP header : %s\n", libnet_geterror(l));
231      }
232 
233    if (libnet_build_ethernet(mac_dst, mac_src, ETHERTYPE_IP, NULL, 0, l, 0)==-1)
234      {
235 	libnet_destroy(l);
236 	w_error(1, "Can't build ethernet header : %s\n", libnet_geterror(l));
237      }
238 
239    /* write packet */
240    if (libnet_write (l) == -1)
241      {
242 	libnet_destroy(l);
243 	w_error(1, "Error writing packet on wire : %s\n", libnet_geterror(l));
244      }
245 
246    /* open pcap device in promisc mode */
247    if ((p = pcap_open_live (dev, BUFSIZ, PROMISC, 10, errbuf))==NULL)
248      {
249 	libnet_destroy(l);
250 	w_error(1, "pcap_open_liver() error : %s\n", errbuf);
251      }
252 
253    /* recupero il descrittore per la select() */
254    sd = pcap_fileno(p);
255 
256    n_print ("princ",4,2,lg,"- Waiting for a possible reply...\n");
257 
258    /* per il traffico alto metto un timeout di 30 pacchetti */
259    pcount = 1;
260 
261    for (;;)
262      {
263 	if (pcount == 60)
264 	  {
265 	     n_print ("princ",6,2,lg,"- No answer -> supposed SWITCH present\n");
266 	     break;
267 	  }
268 
269         /* set 2 secondz delay | DON'T TOUCH! */
270 	FD_ZERO (&rfsd);
271 	FD_SET (sd ,&rfsd);
272 	tv.tv_sec = 2;
273 	tv.tv_usec = 0;
274 
275 	if (!select(sd+1, &rfsd, NULL, NULL, &tv))
276 	  {
277 	     n_print("princ",6,2,lg,"- No answer within two seconds -> supposed SWITCH present\n");
278 	     break;
279 	  }
280 
281 	/* capture packet (packet) and pcap_header (hdr) */
282 	packet = (u_char *) pcap_next (p, &hdr);
283 	if (packet==NULL)
284 	  {
285 	     //fprintf (stderr, "Null packet!\n");
286 	     break;
287 	  }
288 
289 	if ((ether_type = handle_ethernet (packet)) != ETHERTYPE_IP) continue;
290 
291 	offset = (device(dev,p));
292 	ip = (struct libnet_ipv4_hdr *) (packet + offset);
293 	icmp = (struct libnet_icmpv4_hdr *) (packet + offset + LIBNET_IPV4_H);
294 
295 	if ((ip->ip_src.s_addr == ip_dst) && icmp->icmp_type==ICMP_ECHOREPLY && icmp->icmp_id
296 	    == 1000)
297 	  {
298 	     n_print ("princ",6,2,lg,"- Supposed HUB present\n");
299 	     break;
300 	  }
301 
302 	/* altro pacchetto ricevuto */
303 	pcount ++;
304      }
305 
306    if(graph)
307    	n_print("winfo",2,1,0,"Finished\n");
308 
309    libnet_destroy(l);
310 
311    return 0;
312 }
313 
314