/* Test if a host is in promiscuous mode.
* Copyright (C) 1998 Richard W.M. Jones (rjones@orchestream.com)
* This program is GPL. It is derived from a program by
* Paul Gortmaker (called bogon.c), also under GPL.
*
* It works as follows: send out a ICMP echo request to the host
* in question, but wrap the echo request in a bogus ethernet packet.
* If the host is acting normally, it will ignore the bogus packet.
* If the host is listening to the network in promiscuous mode, then
* it will pick up the packet and push it up to the IP layer which
* will respond to the ping. This is obviously not foolproof, since
* you could modify your kernel to disallow responses to echo requests.
*/
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <malloc.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <net/if.h>
#include <netinet/if_ether.h>
#include <netinet/ip.h>
#include <netinet/in.h>
#include <netinet/ip_icmp.h>
#include <asm/checksum.h>
#define PACKET_SIZE 1024
// Bogus ethernet MAC address.
unsigned char bogus[ETH_ALEN] = { 0, 0x60, 0x97, 0xb4, 0x34, 0x82 };
unsigned char us[ETH_ALEN];
struct ifreq ifreq;
struct ethhdr *eth_pkt;
struct iphdr *ip_pkt;
struct icmphdr *icmp_pkt;
int fd, i, j;
unsigned char *packet;
struct in_addr ip_dest;
struct hostent *dest_name;
struct in_addr ip_source;
// Set the ethernet interface here.
#define INTERFACE "eth0"
struct sockaddr interface = { AF_INET, INTERFACE };
void
main (int argc, char **argv)
{
if (argc != 2)
{
fprintf (stderr, "Usage: promisc destination\n");
exit (1);
}
dest_name = gethostbyname (argv [1]);
if (dest_name == NULL) { perror (argv [1]); exit (1); }
ip_dest = *(struct in_addr *) (dest_name->h_addr);
printf ("Destination IP address: %s\n", inet_ntoa (ip_dest));
fd = socket (AF_INET, SOCK_PACKET, htons (ETH_P_802_3));
if (fd == -1)
{
perror ("socket");
exit (1);
}
strcpy (ifreq.ifr_name, INTERFACE);
if (ioctl (fd, SIOCGIFHWADDR, &ifreq) < 0)
{
perror ("SIOCGIFHWADDR");
exit (1);
}
memcpy (us, ifreq.ifr_hwaddr.sa_data, ETH_ALEN);
printf ("My ethernet address: ");
for (i = 0; i < ETH_ALEN; i++)
printf (" %X", us[i]);
printf ("\n");
strcpy (ifreq.ifr_name, INTERFACE);
if (ioctl (fd, SIOCGIFADDR, &ifreq) < 0)
{
perror ("SIOCGIFADDR");
exit (1);
}
memcpy (&ip_source, &((struct sockaddr_in *) &ifreq.ifr_ifru.ifru_addr)->sin_addr,
sizeof (struct sockaddr_in));
printf ("My IP address: %s\n", inet_ntoa (ip_source));
packet = (char *) malloc (PACKET_SIZE);
if (packet == NULL)
{
perror ("malloc");
exit (1);
}
memset (packet, 0, PACKET_SIZE);
/* Fill out the ethernet header. */
eth_pkt = (struct ethhdr *) packet;
memcpy (eth_pkt->h_dest, bogus, ETH_ALEN);
memcpy (eth_pkt->h_source, us, ETH_ALEN);
eth_pkt->h_proto = htons (ETH_P_IP);
/* Fill out the IP header. */
ip_pkt = (struct iphdr *) (packet + sizeof (struct ethhdr));
ip_pkt->ihl = 5; /* Header length / 4. Always 5 if no opts. */
ip_pkt->version = 4; /* IP version. Always 4. */
ip_pkt->tos = 0; /* Type of service. 8 bits. */
/* Total length. Bytes, up to 64K. */
ip_pkt->tot_len = htons (PACKET_SIZE - sizeof (struct ethhdr));
ip_pkt->id = 0; /* Identification. */
ip_pkt->frag_off = 0; /* Fragment offset. */
ip_pkt->ttl = 64; /* Time to live. 8 bits. */
ip_pkt->protocol = IPPROTO_ICMP; /* Protocol. IPPROTO_xxx */
/* Source address. IP address. */
ip_pkt->saddr = ip_source.s_addr;
/* Destination address.IP address. */
ip_pkt->daddr = ip_dest.s_addr;
/* Compute the IP header checksum. */
ip_pkt->check = 0;
ip_pkt->check = ip_fast_csum ((unsigned char *) ip_pkt, ip_pkt->ihl);
/* Construct the echo request. */
icmp_pkt = (struct icmphdr *) (packet + sizeof (struct ethhdr)
+ sizeof (struct iphdr));
icmp_pkt->type = ICMP_ECHO;
icmp_pkt->code = 0;
icmp_pkt->checksum = ip_fast_csum ((unsigned char *) icmp_pkt,
sizeof (struct icmphdr));
/* Send 10 packets. */
for (j = 0; j < 10; j++)
{
i = sendto (fd, packet, PACKET_SIZE, 0,
&interface, sizeof (struct sockaddr));
if (i < 0)
{
perror ("sendto");
exit (1);
}
}
printf ("sent %d bytes %d times.\n", i, j);
exit (0);
}
-------------------------------------------------------------------
--- /mnt/cdrom/c/promisc.c Thu Jan 29 13:28:52 1998
+++ promisc.c Tue Nov 10 17:53:01 1998
@@ -28,11 +28,22 @@
#include <netinet/ip.h>
#include <netinet/in.h>
#include <netinet/ip_icmp.h>
+
+/* Hack for kernel >= 2.1 */
+#if defined(linux)
+#include <linux/version.h>
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0)
+typedef unsigned short __u16;
+typedef unsigned int __u32;
+#define VERIFY_WRITE 0
+#endif
+#endif
+
#include <asm/checksum.h>
#define PACKET_SIZE 1024
-// Bogus ethernet MAC address.
+/* Bogus ethernet MAC address. */
unsigned char bogus[ETH_ALEN] = { 0, 0x60, 0x97, 0xb4, 0x34, 0x82 };
unsigned char us[ETH_ALEN];
@@ -49,11 +60,11 @@
struct in_addr ip_source;
-// Set the ethernet interface here.
+/* Set the ethernet interface here. */
#define INTERFACE "eth0"
struct sockaddr interface = { AF_INET, INTERFACE };
-void
+int
main (int argc, char **argv)
{
if (argc != 2)
@@ -155,6 +166,8 @@
perror ("sendto");
exit (1);
}
+
+ sleep (1);
}
printf ("sent %d bytes %d times.\n", i, j);
The entire AOH site is optimized to look best in Firefox® 3 on a widescreen monitor (1440x900 or better).
Site design & layout copyright © 1986-2009 AOH
We do not send spam. If you have received spam bearing an artofhacking.com email address, please forward it with full headers to abuse@artofhacking.com.