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