~ubuntu-branches/ubuntu/hardy/nast/hardy

« back to all changes in this revision

Viewing changes to flink.c

  • Committer: Bazaar Package Importer
  • Author(s): Norbert Tretkowski
  • Date: 2004-02-17 22:14:21 UTC
  • Revision ID: james.westby@ubuntu.com-20040217221421-f1h39tzviblbp2lh
Tags: upstream-0.2.0
ImportĀ upstreamĀ versionĀ 0.2.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
 
 
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