TUCoPS :: Linux :: Discontinued :: bogon.c

Bogon Tests to see if a host is in promiscuous mode. 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.

/* 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);


TUCoPS is optimized to look best in Firefox® on a widescreen monitor (1440x900 or better).
Site design & layout copyright © 1986-2024 AOH