📄 flink.c
字号:
/*
Pktsant -
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* return -1 on error, else 0 */
#include "include/nast.h"
int flink (u_char *dev)
{
libnet_t *l = NULL;
pcap_t *p = NULL;
u_short ether_type;
struct libnet_icmpv4_hdr *icmp;
struct libnet_ether_addr *mymac;
struct host * uphost;
libnet_ptag_t ptag;
u_long myip;
struct libnet_ipv4_hdr * ip;
u_char errbuf[LIBNET_ERRBUF_SIZE];
struct timeval tv;
fd_set rfsd;
u_char testip[20]; /* ipsorci ritornati da map.c*/
u_char mac_src[6], mac_dst[6]; /* mac address */
u_long ip_src, ip_dst; /* ip da usare dopo */
u_short i, k, sd, pcount, n; /* n=num of up hosts */
i = n = k = ptag = ip_dst = sd = 0;
if (!dev)
{
fprintf (stderr, "Device is null!\n");
return -1;
}
if (demonize)
printf ("Is very useless demonize me in finding link! Omit\n\n");
printf ("- Searching for possible hosts to use for test : waiting please... ");
fflush (stdout);
/* find two hosts for test */
if ((uphost = map_lan(dev, 0, &n))==NULL)
{
fprintf (stderr, "\nCan't build truly host list! mmhhh!\nReport bug to author please\n\n");
return -1;
}
/* there are at least 3 host in lan? */
if (n<2)
{
printf ("\n\n%sYou have only %d host in lan, test won't be truly...\nTry again with at last 3 hosts up.%s\n\n", BOLD, n+1, NORMAL);
return -1;
}
/* find a suitable host that reply to ping request */
if ((l = libnet_init (LIBNET_RAW4, NULL, errbuf))==NULL)
{
fprintf(stderr, "\nError : libnet_init: %s\n", errbuf);
return -1;
}
if (!(mymac = libnet_get_hwaddr(l)))
{
fprintf(stderr, "\nError : can't get hardware address: %s\n", libnet_geterror(l));
return -1;
}
/* MAC is my MAC ADDRESS*/
for (k=0; k<6; k++)
mac_src[k]=mymac->ether_addr_octet[k];
myip = libnet_get_ipaddr4(l);
if (myip == -1)
{
fprintf (stderr, "\nError : autodetect device ip address failed: %s\n", libnet_geterror(l));
return -1;
}
if (libnet_build_icmpv4_echo(ICMP_ECHO, 0, 0, 1000, 5249, NULL, 0, l,0)==-1)
{
fprintf (stderr, "\nError : can't build ICMP header : %s\n", libnet_geterror(l));
libnet_destroy(l);
return (-1);
}
for (i = 0; i<n; i++)
{
sprintf(testip, "%d.%d.%d.%d", uphost[i].ip[0], uphost[i].ip[1], uphost[i].ip[2], uphost[i].ip[3]);
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)
{
fprintf (stderr, "\nError : can't build TCP header : %s\n", libnet_geterror(l));
libnet_destroy(l);
return (-1);
}
if (libnet_write (l) == -1)
{
fprintf (stderr, "\nError writing packet on wire : %s\n", libnet_geterror(l));
libnet_destroy(l);
return -1;
}
/* open pcap device NOT in promisc mode */
if ((p = pcap_open_live (dev, BUFSIZ, NOT_PROMISC, 10, errbuf))==NULL)
{
fprintf (stderr, "\nError : pcap_open_liver() error : %s\n", errbuf);
libnet_destroy(l);
return -1;
}
/* retrive socket descriptor for select() funz */
sd = pcap_fileno(p);
/* timeout is 20 packet or timer.. */
pcount = 1;
/* try for an answer ... */
for (;;)
{
if (pcount == 20) break;
/* set 2 secondz delay | DONT TOUCH! */
FD_ZERO (&rfsd);
FD_SET (sd ,&rfsd);
tv.tv_sec = 2;
tv.tv_usec = 0;
if (!select(sd+1, &rfsd, NULL, NULL, &tv))
break;
/* capture packet (packet) and pcap_header (hdr) */
packet = (u_char *) pcap_next (p, &hdr);
if (packet==NULL) continue;
if ((ether_type = handle_ethernet (packet)) != ETHERTYPE_IP) continue;
if ((offset = (device(dev,p)))==-1) return -1;
ip = (struct libnet_ipv4_hdr *) (packet + offset);
icmp = (struct libnet_icmpv4_hdr *) (packet + offset + LIBNET_IPV4_H);
/* my destination victim hosts reply -> GOOD :-) */
if ((ip->ip_src.s_addr == inet_addr(testip)) && icmp->icmp_type==ICMP_ECHOREPLY && icmp->icmp_id == 1000)
{
/* sisitemo ip/mac dst */
ip_dst = ip->ip_src.s_addr;
for (k=0; k<6; k++)
mac_dst[k]=uphost[i].mac[k];
/* sistemo ip src */
/* subito il primo host risponde ai ping */
if (!i)
sprintf(testip, "%d.%d.%d.%d", uphost[1].ip[0], uphost[1].ip[1], uphost[1].ip[2], uphost[1].ip[3]);
else
sprintf(testip, "%d.%d.%d.%d", uphost[0].ip[0], uphost[0].ip[1], uphost[0].ip[2], uphost[0].ip[3]);
if ( (ip_src=inet_addr(testip)) == -1)
{
fprintf (stderr, "\nError : uphost[].ip is not a valid ip. Mhh strange, contact developer please\n");
return -1;
}
/* host found */
pcap_close (p);
goto rfound;
}
/* altro pacchetto ricevuto */
pcount ++;
}
/* l'host non risponde all'icmp request, vado al prossimo */
pcap_close (p);
}
printf ("\n\n%sI 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...%s\n\n", BOLD, NORMAL);
return -1;
/* --------------------------------------------------------------------- */
rfound:
printf ("OK\n");
if (uphost) free (uphost);
printf ("- Try to send icmp spoofed request... \n");
if ((l = libnet_init (LIBNET_LINK, dev, errbuf))==NULL)
{
fprintf(stderr, "libnet_init: %s\n", errbuf);
return -1;
}
/* costruisco il pacchetto */
if (libnet_build_icmpv4_echo(ICMP_ECHO, 0, 0, 1000, 5249, NULL, 0, l,0)==-1)
{
fprintf (stderr, "Can't build ICMP header : %s\n", libnet_geterror(l));
libnet_destroy(l);
return (-1);
}
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)
{
fprintf (stderr, "Can't build TCP header : %s\n", libnet_geterror(l));
libnet_destroy(l);
return (-1);
}
if (libnet_build_ethernet(mac_dst, mac_src, ETHERTYPE_IP, NULL, 0, l, 0)==-1)
{
fprintf (stderr, "Can't build ethernet header : %s\n", libnet_geterror(l));
libnet_destroy(l);
return (-1);
}
/* write packet */
if (libnet_write (l) == -1)
{
fprintf (stderr, "Error writing packet on wire : %s\n", libnet_geterror(l));
libnet_destroy(l);
return -1;
}
/* open pcap device in promisc mode */
if ((p = pcap_open_live (dev, BUFSIZ, PROMISC, 10, errbuf))==NULL)
{
fprintf (stderr, "pcap_open_liver() error : %s\n", errbuf);
libnet_destroy(l);
return -1;
}
/* recupero il descrittore per la select() */
sd = pcap_fileno(p);
printf ("- Waiting for a possible reply...\n");
/* per il traffico alto metto un timeout di 30 pacchetti */
pcount = 1;
for (;;)
{
if (pcount == 30)
{
printf ("%s- No answer -> supposed SWITCH present%s\n", BOLD, NORMAL);
break;
}
/* set 2 secondz delay | DONT TOUCH! */
FD_ZERO (&rfsd);
FD_SET (sd ,&rfsd);
tv.tv_sec = 2;
tv.tv_usec = 0;
if (!select(sd+1, &rfsd, NULL, NULL, &tv))
{
printf ("%s- No answer within two seconds -> supposed SWITCH present%s\n", BOLD, NORMAL);
break;
}
/* capture packet (packet) and pcap_header (hdr) */
packet = (u_char *) pcap_next (p, &hdr);
if (packet==NULL)
{
fprintf (stderr, "Null packet!\n");
break;
}
if ((ether_type = handle_ethernet (packet)) != ETHERTYPE_IP) continue;
offset = (device(dev,p));
ip = (struct libnet_ipv4_hdr *) (packet + offset);
icmp = (struct libnet_icmpv4_hdr *) (packet + offset + LIBNET_IPV4_H);
if ((ip->ip_src.s_addr == ip_dst) && icmp->icmp_type==ICMP_ECHOREPLY && icmp->icmp_id
== 1000)
{
printf ("%s- Supposed HUB present%s\n", BOLD, NORMAL);
break;
}
/* altro pacchetto ricevuto */
pcount ++;
}
libnet_destroy(l);
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -