Advertisement
onthar

Untitled

Mar 11th, 2013
163
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 120.79 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <ctime>
  5. #include <errno.h>
  6. #include <arpa/inet.h>
  7.  
  8. //номер версии программы
  9. #define VERS_PROG 21
  10. /*даты изменения
  11.  
  12. 6 авг 2010
  13. 17 авг 2010
  14. 1 сент 2010
  15. 9 сент 2010
  16. 25 нояб 2010 - calcPopr
  17. */
  18.  
  19. //максимальное количество строк считывемое из лог файла
  20. #define MAX_STR_LOG 130000
  21.  
  22. //максисальная длина подстроки на которые разбивается строка запроса, если больше то обрезаем
  23. #define MAX_LEN_SUBSTR 200
  24.  
  25. //максимальное количество различных вариантов запроса, если больше, то сообщается о ошибке
  26. #define MAX_REQWEST_COUNT 90000
  27.  
  28. //максимальная сохраняемая длина строки запроса, если больше то обрезается
  29. #define MAX_LEN_REQWEST 100
  30.  
  31. //максимально количество разных реферреров, если больше, то сообщается о ошибке
  32. #define MAX_REFERRER_COUNT 30000
  33.  
  34. //максимальная длина строки реферрера, если больше то обрезается
  35. #define MAX_REFERRER_LEN 150
  36.  
  37. //максимально количество разных юзер ангетов, если больше, то сообщается о ошибке
  38. #define MAX_USER_AGENT_COUNT 25000
  39.  
  40. //максимальная длина строки юзер агента, если больше то обрезается
  41. #define MAX_USER_AGENT_LEN 200
  42.  
  43. //максимальная длина строки анализируемая в лог файле, если больше, то сообщается о ошибке
  44. #define MAX_LEN_STR 19000
  45.  
  46. //максимальное количество коннектов анализируемое в команде netstat
  47. #define MAX_LEN_NETSTAT 10000
  48.  
  49. //максимальное количество строк в стоп листе
  50. #define MAX_COUNT_BAD_STR 100
  51.  
  52. //максимальная длина строки в стоп листе
  53. #define MAX_LEN_BAD_STR 30
  54.  
  55. //максимальное количество строк считываемое из файла белых подсетей по ключу w
  56. #define MAX_COUNT_WHITE_IP 6000
  57.  
  58. //////////////////
  59. struct oneHeat{ //инфорсация о одной строке из лог файла
  60.     int ip; //IP адрес
  61.     time_t t;   //UNIX время в секундах этой троки запроса
  62.     int num_r;  //номер строки запроса из таблицы запросов
  63.     int num_ua; //номер строки юзер агента таблицы юзер агентов
  64.     int num_ref;//номер строки реферрера таблицы реферреров
  65.     int c_double;//количество повторений, будет расчитанно
  66.     int len_str;//длина исходной строки запроса
  67.     int code_otv;//код ответа веб сервера
  68.     int cookie;//
  69. };
  70. //////
  71. struct command{
  72.     char command;
  73.     int par[4];
  74. };
  75. //////
  76. struct netstat_t{   //статистика одного IP адреса в выдаче команды netstat
  77. //    int ip_loc;  
  78.     int ip_for;
  79. //    int port_loc;
  80. //    int state;
  81.     int count;
  82.     int c_SYN_RECV;
  83.     int c_ESTABLISHED;
  84.     int c_TIME_WAIT;
  85.     int c_SYN_SENT;
  86.     int c_FIN_WAIT1;
  87.     int c_FIN_WAIT2;
  88.     int c_CLOSING;
  89.     int c_CLOSE_WAIT;
  90.     int c_LAST_ACK;
  91. };
  92. ////////////////////////////////////////////////////////////////
  93. //разбивает строку s на подстроки по разделителю - пробел
  94. //возвращает количество подстрок
  95. //то что заключено в кавычки - на подстроки не разбиваеься, даже если в кавычках есть пробелы
  96. //результирующие подстроки помещабтся в массив m[20][MAX_LEN_REQWEST] 20 сток длиной MAX_LEN_REQWEST символов
  97. ////////////////////////////////////////////////////////////////
  98. int strBreak(
  99.     const char *s,
  100.     char m[20][MAX_LEN_SUBSTR],
  101.     int allow_z){
  102. const int maxx=MAX_LEN_SUBSTR-1;    //максимальная длина одной подстроки, Если длинее, то обрезается
  103. const int maxy=19;  //Максимальное количество подстрок. Если больше, то не учитываются.
  104. int x=0,y=0;
  105. int isQ, isSlash=0;
  106.  
  107. isQ=0;
  108. while (*s)
  109. {
  110.     if ((*s=='"') && !isSlash)  //если кавычка, то ждем закрывающую
  111.     isQ=!isQ;
  112.     else if ((*s==' ') && !isQ)
  113.     {   m[y][x]=0;
  114.     if (allow_z || (x>0))
  115.     {
  116.         if (y>=maxy-1)
  117.         return y+1;
  118.         y++;
  119.         x=0;
  120.     }
  121.     }else
  122.     {   if (x<maxx)
  123.     {   m[y][x]=*s;
  124.         x++;
  125.     }
  126.     else
  127.         m[y][x]=0;  //если текущая подстрока длинее maxx, то ее обрезаем
  128.     }
  129.     if (*s=='\\')
  130.     isSlash=1;
  131.     else
  132.     isSlash=0;
  133.  
  134.     s++;
  135. }
  136. m[y][x]=0;
  137. return y+1;
  138. }
  139.  
  140. ///////////////////////////////////////////////////
  141. //разбивает строку s на подстроки по разделителю - / и :
  142. //возвращает количество подстрок
  143. //////////////////////////////////////////////////
  144. int strBreak2(const char *s, char m[11][8]){
  145. const int maxx=6;   //максимальная длина одной подстроки, Если длинее, то обрезается
  146. const int maxy=10;  //Максимальное количество подстрок. Если больше, то не учитываются.
  147. int x=0,y=0 ,nn=0;
  148. while (*s)
  149. {
  150.     if (*s=='[')// пропускаем этот символ
  151.     nn=0;
  152.     else if ((*s=='/') || (*s==':'))
  153.     {   m[y][x]=0;
  154.     if (x>0)
  155.     {  
  156.         if (y>=maxy-1)
  157.         return y+1;
  158.         y++;
  159.         x=0;
  160.     }
  161.     }else
  162.     {   if (x<maxx)
  163.     {   m[y][x]=*s;
  164.         x++;
  165.     }
  166.     else
  167.         m[y][x]=0;  //если текущая подстрока длинее maxx, то ее обрезаем
  168.    
  169.     }
  170.     s++;
  171. }
  172. m[y][x]=0;
  173. return y+1;
  174. }
  175.  
  176. // элемент массива для сортировки.
  177. //sort_data -хранится номер элемента
  178. //sort_key - поле по которому происзодит сортировка
  179. struct sort_item{
  180. int sort_data;
  181. int sort_key;
  182. };
  183. ////////////
  184.  
  185. int sort_2(struct sort_item *m){//сортировка массива ровно из 2-х элементов
  186. struct sort_item t;
  187. if (m->sort_key < (m+1)->sort_key)
  188. {   t=*m;
  189.     *m=*(m+1);
  190.     *(m+1)=t;
  191. }
  192. }
  193.  
  194. ///////////////////////////////////////////////////////////////////////////////////////
  195. // сортировка Хоара для массива элементов на первый элемент которого указывает p
  196. // n - длина массива
  197. // исползование индексной адресации и указателей
  198. // память под временные массивы выделяется динамически
  199. ///////////////////////////////////////////////////////////////////////////////////////
  200. void hoar_sort(int n, struct sort_item *p){
  201. //printf("\nСортировка Хоара n=%d\n",n);
  202. int i,k,k1,k2,kr,   //счетчики
  203.     key;        //Ключ первого элемента
  204.  
  205. struct sort_item    //Указатели для прбегания по массивам
  206.     *lp,    // Указатель для пробегания по исходному массиву
  207.     *lp1,   // Указатель для пробегания по массиву меньших элементов
  208.     *lp2,   // Указатель для пробегания по массиву больших элементов
  209.     *lpr;   // Указатель для пробегания по массиву равных элементов
  210.  
  211. struct sort_item    *mr,    //указатель на массив для хранния элементов равных первому
  212.             *m1,    //указатель на массив для хранния элементов меньше первого
  213.             *m2;    //указатель на массив для хранния элементов больше первого
  214.  
  215. //динамическре выделение памяти
  216. mr=(struct sort_item *)malloc(n*sizeof(sort_item));if (!mr) exit(1);
  217. m1=(struct sort_item *)malloc((n-1)*sizeof(sort_item));if (!m1) exit(1);
  218. m2=(struct sort_item *)malloc((n-1)*sizeof(sort_item));if (!m2) exit(1);
  219.  
  220. key=p->sort_key;    //записываем значение ключа первого элемента
  221. kr=1;k1=0;k2=0; //счетчики для временных массивов
  222. lp=p;       // Указатель для пробегания по исходному массиву ставим на 0-й элемент
  223. lp1=m1;     // Указатель для пробегания по массиву меньших элементов ставим на начало выделенной области
  224. lp2=m2;     // Указатель для пробегания по массиву больших элементов ставим на начало выделенной области
  225. lpr=mr;     // Указатель для пробегания по массиву равных элементов ставим на начало выделенной области
  226.  
  227. *lpr++=*lp++;   //записываем значение первого элемента в массив равных
  228.  
  229. for(k=1;k<n;k++)//все элементы (кроме 1-го) исходного массива сравниваем с первым элементом
  230. {
  231.     if (key > lp->sort_key )
  232.     {   *lp1++=*lp;//те которые меньше записываем во временный массив m1 и передвигаем указатель
  233.     k1++;       //увеличиваем счетчик элемнтов в этом массиве
  234.     }else if (key < lp->sort_key)
  235.     {   *lp2++=*lp;//те которые больше записываем во временный массив m2 и передвигаем указатель
  236.     k2++;   //увеличиваем счетчик элемнтов в этом массиве
  237.     }else
  238.     {   *lpr++=*lp;//те которые равны записываем во временный массив mr и передвигаем указатель
  239.     kr++;   //увеличиваем счетчик элемнтов в этом массиве
  240.     }
  241.     lp++;
  242. }
  243.  
  244. if (k1==2)  //если временный массив содержит ровно 2 элемента,
  245.     sort_2(m1); //то вызываем быструю функцию сортировки для двух элементов
  246. else if (k1>2)  //если временные массивы содержат более 2 элементов, то сортируем их рекурсивным вызовом
  247.     hoar_sort(k1,m1);
  248.    
  249. if (k2==2)  //если временный массив содержит ровно 2 элемента,
  250.     sort_2(m2);//то вызываем быструю функцию сортировки для двух элесентов
  251. else if (k2>2) //если временные массивы содержат более 2 элементов, то сортируем их рекурсивным вызовом
  252.     hoar_sort(k2,m2);
  253.  
  254.  
  255. k=0;    lp=p;   //в начало исходного массива
  256. lp1=m1; lp2=m2; lpr=mr;
  257.  
  258. for(i=0;i<k2;i++)//в исходный массив записываем отсортированный массив больших элементов,
  259.     *lp++ = *lp2++;
  260.  
  261. for(i=0;i<kr;i++)//в исходный массив записываем отсортированный массив равных элементов,
  262.     *lp++ = *lpr++;
  263.  
  264. for(i=0;i<k1;i++)//в исходный массив записываем отсортированный массив меньших элементов,
  265.     *lp++ = *lp1++;
  266.  
  267. free(mr);//освобождаем память
  268. free(m1);
  269. free(m2);
  270. }
  271.  
  272. //преобразовать названия месяца в номер. Для анализа даты из лог файла.
  273. int monToi(char *m){
  274. if (!strcmp(m,"Jan"))       return 0;
  275. else if (!strcmp(m,"Feb"))  return 1;
  276. else if (!strcmp(m,"Mar"))  return 2;
  277. else if (!strcmp(m,"Apr"))  return 3;
  278. else if (!strcmp(m,"May"))  return 4;
  279. else if (!strcmp(m,"Jun"))  return 5;
  280. else if (!strcmp(m,"Jul"))  return 6;
  281. else if (!strcmp(m,"Aug"))  return 7;
  282. else if (!strcmp(m,"Sep"))  return 8;
  283. else if (!strcmp(m,"Oct"))  return 9;
  284. else if (!strcmp(m,"Nov"))  return 10;
  285. else if (!strcmp(m,"Dec"))  return 11;
  286. else return 11;
  287. }
  288.  
  289. /////////////////////////////////////////////////////////////////
  290. // преобразует строковый формат даты в количество сикунд от 1970
  291. // Если преобразовать не удалось, то возвращает -1
  292. ////////////////////////////////////////////////////////////////
  293. int strToTime(char *s){
  294. tm tt;
  295. int t;
  296. char m[11][8];
  297. t=strBreak2(s,m);
  298. if (t!=6)
  299. {
  300. //    printf ("t=%d\n",t);
  301.     return -1;
  302. }
  303. //for (int i=0;i<t;i++)
  304. //    printf("%s ",m[i]);
  305. //printf ("\n--------\n");
  306. time_t v;
  307. tt.tm_sec=atoi(m[5]);
  308. tt.tm_min=atoi(m[4]);
  309. tt.tm_hour=atoi(m[3]);
  310. tt.tm_mday=atoi(m[0]);
  311. tt.tm_mon=monToi(m[1]);
  312. tt.tm_year=atoi(m[2]) - 1900;
  313.  
  314. v=mktime(&tt);
  315. return v;
  316. }
  317.  
  318. /////////////////////////////
  319. // проверить есть ли значение val в массиве целых чисел ar
  320. /////////////////////////////
  321. int inArray(
  322.     int ar_c,   //количество элементов в массиве ar
  323.     int *ar,    //массив целых чисел в котором ищем
  324.     int val){   //целое число, которое ищем
  325. int n;
  326. for (n=0;n<ar_c;n++)
  327.     if (ar[n]==val)
  328.     return 1;
  329. return 0;
  330. }
  331. /////////////////////////////////////////////////////////////////////////
  332. // проверить есть ли значение val в массиве целых чисел ar, массив ar заканчивается нулеаым элементом
  333. ////////////////////////////////////////////////////////////////////////
  334. int inArray_z(int *ar,int val){
  335. while (*ar)
  336.     if (*ar++==val)
  337.     return 1;
  338. return 0;
  339. }
  340.  
  341. int inArray_m(int *ar,int val){
  342. while ( (*ar)!=-1 )
  343.     if (*ar++==val)
  344.     return 1;
  345. return 0;
  346. }
  347. /////////////////////////
  348. //отличается от предыдущих тем что сравнение происходит по маске
  349. /////////////////////////
  350. int inArray_ip_mask(
  351.     int *ar_ip,     //массив ip адресов, заканчивается нулевым элементом
  352.     int *ar_mask,   //массив масок для каждого ip
  353.     int ip){        //ip который ищется
  354. while (*ar_ip)
  355.     if (*ar_ip++ == (ip & *ar_mask++) )
  356.     return 1;
  357. return 0;
  358. }
  359. ///////
  360. int myTimeToStr(time_t *t, char *s){
  361. tm *e;
  362. e = localtime(t);
  363. sprintf(s,"%d.%d.%d %d:%02d:%02d",e->tm_mday,e->tm_mon+1,e->tm_year+1900,e->tm_hour,e->tm_min,e->tm_sec);
  364. //s= asctime(e_tm);
  365. }
  366.  
  367. //////////////////////////////////////////////////////////////////////////////////
  368. //вывести на экран содержимое структуры с информацией о одной строке лог файла //
  369. //////////////////////////////////////////////////////////////////////////////////
  370. int showOneHeat(
  371.             int logLen,
  372.             struct oneHeat *oh,
  373.             char (*reqwest) [MAX_REQWEST_COUNT][MAX_LEN_REQWEST],
  374.             int one_ip,
  375.             int c_print
  376.             ){
  377. int n,counter=0;
  378. in_addr ad;
  379. char *ipstr, timeStr[20];
  380. printf(" *** Log *** ");
  381. if (one_ip)
  382. {   ad.s_addr=one_ip;
  383.     ipstr = inet_ntoa(ad);
  384.     printf("One IP=%s",ipstr);
  385. }
  386. printf("\n");
  387. for (n=0;n<logLen;n++)
  388.     if (one_ip && (one_ip == oh[n].ip) || !one_ip)
  389.     {
  390.         if (counter>=c_print)
  391.     {   printf("%d of %d\n",counter,logLen);
  392.         return 1;
  393.     }
  394.     counter++;
  395.     ad.s_addr=oh[n].ip;
  396.     ipstr = inet_ntoa(ad);
  397.     myTimeToStr(&oh[n].t,timeStr);
  398.     printf("%-15s %-19s %d  %s %d %d\n",   
  399.         ipstr,
  400.         timeStr,
  401.         oh[n].num_r,
  402.         (*reqwest)[ oh[n].num_r ],
  403.         oh[n].code_otv,
  404.         oh[n].cookie
  405.         );
  406.     }
  407. }
  408.  
  409. /***********************************************************
  410. создает массив структур ipInfo для дальнейшей сортировки
  411. Возврящает количество элементов в созданном массиве
  412. ************************************************************/
  413. int makeIpInfo(
  414.     int logLen,     //количество элементов в исходном лог массиве
  415.     struct oneHeat *log,//указатель на исходный лог в массиве
  416.     struct sort_item *ipInfo){//будет создан массив структур
  417. int c_ip=0, //счетчик разных IP
  418.     n,      //счетчик цикла
  419.     k,
  420.     isi;//был ли данный IP ранее
  421. for (n=0;n<logLen; n++)     //пробегаем по всем элементам исходного лог файла
  422. {   // printf("i=%d\n",log[n].ip);
  423.     isi=0;
  424.     for (k=0;k<c_ip; k++)   //проверяем все ранее добавленные IP
  425.     if (ipInfo[k].sort_data == log[n].ip )
  426.     {    ipInfo[k].sort_key++;  //если такой IP уже был добавлен, то увеличиваем его количество
  427.         isi=1;
  428.         break;
  429.     }
  430.     if (!isi)//если IP нет, то его добавляем
  431.     {   ipInfo[c_ip].sort_data =log[n].ip;
  432.     ipInfo[c_ip].sort_key=1;
  433.     c_ip++;
  434.     }
  435. }
  436. return c_ip;
  437. }
  438.  
  439. /***********************************************************
  440. создает массив структур codeInfo для дальнейшей сортировки
  441. Возврящает количество элементов в созданном массиве
  442. ************************************************************/
  443. int makeCodeInfo(
  444.     int logLen,     //количество элементов в исходном лог массиве
  445.     struct oneHeat *log,//указатель на исходный лог в массиве
  446.     struct sort_item *codeInfo){//будет создан массив структур
  447. int c_code=0, //счетчик разных IP
  448.     n,      //счетчик цикла
  449.     k,      //счетчик вложенного цикла
  450.     is_code;    //был ли данный код ранее
  451. for (n=0;n<logLen; n++)     //пробегаем по всем элементам исходного лог файла
  452. {   // printf("i=%d\n",log[n].ip);
  453.     is_code=0;
  454.     for (k=0;k<c_code; k++) //проверяем все ранее добавленные коды
  455.     if (codeInfo[k].sort_data == log[n].code_otv )
  456.     {    codeInfo[k].sort_key++;    //если такой код уже был добавлен, то увеличиваем его количество
  457.         is_code=1;
  458.         break;
  459.     }
  460.     if (!is_code)//если IP нет, то его добавляем
  461.     {   codeInfo[c_code].sort_data =log[n].code_otv;
  462.     codeInfo[c_code].sort_key=1;
  463.     c_code++;
  464.     }
  465. }
  466. return c_code;
  467. }
  468. /****************************************************************
  469. посчитать количество уникальных URL для одного IP
  470. *****************************************************************/
  471. int calcUniqUrlForIP(
  472.         int logLen,     //количество элементов в массиве log
  473.         struct oneHeat *log,    //массив типа oneHeat с информацией о одной строке лог файла
  474.         int ip          //IP для которого считаем количество
  475.         ){
  476. int count_r=0,      //счетчик количества найденных запросов для этого IP
  477.     n,          //счетчик цикла
  478.     ar_r[MAX_REQWEST_COUNT];
  479.  
  480. for(n=0;n<logLen;n++)   //пробегаем по всем строкам лог файла
  481.     if (log[n].ip == ip)        //если в лог файле нашли запрос с нужным IP
  482.     if (!inArray(count_r, ar_r, log[n].num_r ))
  483.         ar_r[count_r++]=log[n].num_r;
  484. return count_r;
  485. }
  486. /**************************************************************************************
  487. вычислить коэффициент (в процентах) на который умножаются лимиты, когда лог файл длинный по времени.
  488. То есть ддос атаки скорее всего нет
  489. **************************************************************************************/
  490. int calcPopr(int len_time_sec){
  491. const int leng=7;//длина лог файла в минутах, когда начинает использоваться поправочный коэфициент
  492.  
  493. if (len_time_sec >60*leng)
  494. //    return leng * len_time_sec/60;
  495.     return (len_time_sec*10) / (leng*6);
  496. else
  497.     return 100;
  498. }
  499. /*******************************************************
  500. найти ip адреса по критерию превышение количества повторов
  501.  
  502. забанить ip адреса удовлетоворяющие всем 3 условиям
  503. 1) болше limit повторов в логе (limit_white - для белого списка)
  504. 2) у IP процент уникальных URL менее procent_uniq
  505. 3) таких IP найдено более 3
  506.  
  507. ********************************************************/
  508. void findIPbyLimit (
  509.             int logLen,     //количество элементов в массиве log
  510.             struct oneHeat *log,    //массив типа oneHeat с информацией о одной строке лог файла
  511.  
  512.             int countIpInfo,        //количество элементов в массиве ipInfo
  513.             struct sort_item *ipInfo,   //указатель на массив структур с информацией о одном ip
  514.            
  515.             int limit,      //лимит на количество повторений одного ip адреса
  516.             int limit_white,    //лимит на количество повторений одного ip адреса для IP из белого списка
  517.             int procent_uniq,   //процент уникальных кликов для одного IP, если процент ниже этого значения, то это бот
  518.             int count_ban,  //сколько должно быть найдено IP , что бы они забанились
  519.            
  520.             int countClickLastMinute,
  521.             int koef,
  522.             int len_time_sec,   //длина лога в секундах
  523.            
  524.             int *ar_res_ip, //массив забаненных, сюда же добавляем найденных ботов
  525.             int &c_ddos_ip, //количество элементов массива ar_res_ip
  526.            
  527.             int *ar_white_ip,   //белый список IP
  528.             int *ar_white_mask  //маска для белого списка
  529.             ){
  530. int n,  numUniqUrlForIP, p, ip_val, ip_count,
  531.     ar_ip[2000],    //не более 2000 ip удовлетворяющих условиям
  532.     ar_c[2000],    
  533.     ar_u[2000],    
  534.     count_ar=0,
  535.     white_ip;
  536. in_addr ad;
  537. char *ipstr;
  538. if (koef)
  539. {   limit=limit*koef/100;
  540.     limit_white=limit_white*koef/100;
  541. }
  542. limit= limit * calcPopr(len_time_sec) / 100;
  543. limit_white= limit_white * calcPopr(len_time_sec) / 100;
  544. time_t timer1;
  545. char str_time[30];
  546. for(n=0;n<countIpInfo;n++)// проходим по всем уникальным IP
  547. {
  548.     ip_count=ipInfo[n].sort_key;
  549.     if (ip_count>=limit)// если один IP повторялся в логе более limit раз
  550.     {
  551.     ip_val=ipInfo[n].sort_data;
  552.  
  553.     if (inArray_ip_mask( ar_white_ip, ar_white_mask,  ip_val ) )
  554.         white_ip=1; //если это IP из белого списка
  555.     else
  556.         white_ip=0;
  557.  
  558.     if (!white_ip || (ip_count>=limit_white) )
  559.     {
  560.         //найти количество уникальных URL для этого IP
  561.         numUniqUrlForIP=calcUniqUrlForIP(logLen,log, ip_val);
  562.        
  563.         p=100 * numUniqUrlForIP / ip_count;
  564.         if (p<procent_uniq)
  565.         {
  566.  
  567. //      ad.s_addr=ip_val;//преобразуем ip адрес из типа int в строку
  568. //      ipstr = inet_ntoa(ad);
  569. //      printf("ip=%s, c=%d, url=%d, p=%d\n",
  570. //          ipstr,
  571. //          ipInfo[n].sort_key,
  572. //          numUniqUrlForIP,
  573. //          p);
  574.            
  575.         ar_ip[count_ar]=ip_val;
  576.         ar_c[count_ar]=ip_count;
  577.         ar_u[count_ar]=numUniqUrlForIP;
  578.         count_ar++;
  579.         }
  580.     }
  581.     }
  582. }
  583. //printf("count_ar=%d\n",count_ar);
  584. //printf("count_ban=%d\n",count_ban);
  585.  
  586. if (count_ar>=count_ban)
  587. {
  588.     time(&timer1);
  589.     myTimeToStr(&timer1,str_time);
  590.  
  591.     for(n=0;n<count_ar;n++)
  592.     {
  593.     if (!inArray(c_ddos_ip, ar_res_ip,   ar_ip[n]  )  )
  594.     {
  595.         ar_res_ip[c_ddos_ip++]=ar_ip[n];
  596.        
  597.         ad.s_addr=ar_ip[n];//преобразуем ip адрес из типа int в строку
  598.         ipstr = inet_ntoa(ad);
  599.  
  600.         if (koef)
  601.         printf("k=%d,",koef);
  602.        
  603.        
  604.         if (white_ip)
  605.         printf("-mW %d,",
  606.         limit_white);
  607.         else
  608.         printf("-m %d,",
  609.         limit);
  610.        
  611.         printf("%d,%d.",procent_uniq,count_ban);
  612.        
  613.         printf("ip=%s,c=%d,u=%d,Cm=%d,t=%s,",
  614.         ipstr,
  615.         ar_c[n],
  616.         ar_u[n],
  617.         countClickLastMinute,
  618.         str_time
  619.         );
  620.  
  621.         if (len_time_sec<400)
  622.         printf("Tl=%ds\n",len_time_sec);
  623.         else if (len_time_sec<7200)
  624.         printf("Tl=%dm\n",len_time_sec/60);
  625.         else
  626.         printf("Tl=%dh\n,",len_time_sec/3600);
  627.     }
  628.     }
  629. }
  630. }
  631.  
  632. /***********************************************************************************
  633. подсчитать количество разных запросов и юзерагентов для заданногго IP
  634. ***********************************************************************************/
  635. void calcCountForIP(
  636.         int logLen,     //количество элементов в массиве log
  637.         struct oneHeat *log,    //массив типа oneHeat с информацией о одной строке лог файла
  638.         int ip,         //IP для которого считаем количество
  639.         int &count_r,       //счетчик количества найденных запросов для этого IP
  640.         int &last_code,
  641.         int &count_ref,
  642.         int &count_ua,      //счетчик количества найденных юзер агентов для этого IP
  643.         int &last_url,
  644.         int &last_ua
  645.         ){
  646. int n,          //счетчик цикла
  647.     ar_r[MAX_REQWEST_COUNT],
  648.     ar_ref[MAX_REFERRER_COUNT],
  649.     ar_u[MAX_USER_AGENT_COUNT];
  650.    
  651. count_r=0;
  652. count_ref=0;
  653. count_ua=0;
  654. for(n=0;n<logLen;n++)   //пробегаем по всем строкам лог файла
  655.     if (log[n].ip == ip)        //если в лог файле нашли запрос с нужным IP
  656.     {
  657.     last_url=log[n].num_r;
  658.     last_code=log[n].code_otv;
  659.     last_ua=log[n].num_ua;
  660.    
  661.     if (!inArray(count_r, ar_r, log[n].num_r ))
  662.         ar_r[count_r++]=log[n].num_r;
  663.  
  664.     if (!inArray(count_ref, ar_ref, log[n].num_ref ))
  665.         ar_ref[count_ref++]=log[n].num_ref;
  666.  
  667.     if (!inArray(count_ua, ar_u, log[n].num_ua ))
  668.         ar_u[count_ua++]=log[n].num_ua;
  669.     }
  670. }
  671.  
  672. /***********************************************************************************
  673. подсчитать количество разных ip и юзерагентов для заданной страницы
  674. ***********************************************************************************/
  675. void calcCountForReqwest(
  676.         int logLen,     //количество элементов в массиве log
  677.         struct oneHeat *log,    //массив типа oneHeat с информацией о одной строке лог файла
  678.         int num_r,      //запрос для которого считаем количество
  679.         int &count_ip,     
  680.         int &count_ref,
  681.         int &count_ua,
  682.         int &exemple_code
  683.         ){
  684. int n,          //счетчик цикла
  685.     ar_ip[MAX_STR_LOG],
  686.     ar_ref[MAX_REFERRER_COUNT],
  687.     ar_u[MAX_USER_AGENT_COUNT];
  688. count_ip=0;
  689. count_ref=0;
  690. count_ua=0;
  691. for(n=0;n<logLen;n++)   //пробегаем по всем строкам лог файла
  692.     if (log[n].num_r == num_r)      //если в лог файле нашли запрос с нужным IP
  693.     {
  694.     if (!inArray(count_ip, ar_ip, log[n].ip ))
  695.         ar_ip[count_ip++]=log[n].ip;
  696.  
  697.     if (!inArray(count_ref, ar_ref, log[n].num_ref ))
  698.         ar_ref[count_ref++]=log[n].num_ref;
  699.  
  700.     if (!inArray(count_ua, ar_u, log[n].num_ua ))
  701.         ar_u[count_ua++]=log[n].num_ua;
  702.     exemple_code=log[n].code_otv;
  703.     }
  704. }
  705. /***********************************************************************************
  706. ***********************************************************************************/
  707. void calcCountForCode(
  708.         int logLen,     //количество элементов в массиве log
  709.         struct oneHeat *log,    //массив типа oneHeat с информацией о одной строке лог файла
  710.         int code_otv, //
  711.         int &count_ip,
  712.         int &count_r,
  713.         int &count_ua,
  714.         int &exemple_ip,
  715.         int &exemple_r
  716.         ){
  717. int n,          //счетчик цикла
  718.     ar_ip[MAX_STR_LOG],
  719.     ar_r[MAX_REQWEST_COUNT],
  720.     ar_u[MAX_USER_AGENT_COUNT];
  721. count_ip=0;
  722. count_r=0;
  723. count_ua=0;
  724. for(n=0;n<logLen;n++)   //пробегаем по всем строкам лог файла
  725.     if (log[n].code_otv == code_otv)        //если в лог файле нашли запрос с нужным IP
  726.     {
  727.     if (!inArray(count_ip, ar_ip, log[n].ip ))
  728.     {    ar_ip[count_ip++]=log[n].ip;
  729.         exemple_ip=log[n].ip;
  730.     }
  731.  
  732.     if (!inArray(count_r, ar_r, log[n].num_r ))
  733.     {    ar_r[count_r++]=log[n].num_r;
  734.         exemple_r=log[n].num_r;
  735.     }
  736.  
  737.     if (!inArray(count_ua, ar_u, log[n].num_ua ))
  738.         ar_u[count_ua++]=log[n].num_ua;
  739.     }
  740. }
  741.  
  742. /***********************************************
  743. Функция используется для создания отчета -I
  744. Подсчитать сколько максимум кликов делается за период времени per.
  745. Подсчет идет по режиму mode
  746. ************************************************/
  747. int findDDOS_one_ip(
  748.     int one_ip,
  749.         int logLen,
  750.     struct oneHeat *log,
  751. //  int limit_d,    //сколько раз за периуд времени должен повторится запрос, что бы считать его ддосом
  752.     int per,    //период времени в течении которгго производится подсчет повторов
  753.     int mode
  754.     ){
  755. int n,n2, max_c_double;
  756.  
  757. for (n=0;n<logLen;n++)//пробегаеся по всему логу
  758. {   log[n].c_double=1;
  759.  
  760.     if (log[n].ip==one_ip)
  761.     {
  762.     if ( (mode==4) && (log[n].code_otv!=404) )
  763.     continue;
  764.     n2=n+1; //пробегаем по оставшейся части лога после этого клика на период времени per    
  765.     while ((n2<logLen) && (log[n2].t - log[n].t <per) )//пробегаем пока либо не достигнем конца лога либо время время не достигнет per
  766.     {   if (log[n].ip==log[n2].ip)
  767.     {   if (mode==1)
  768.         {   if ((log[n].num_r==log[n2].num_r) )
  769.             log[n].c_double++;
  770.         else
  771.         {   log[n].c_double=0;
  772.             break;
  773.         }
  774.         }
  775.         else
  776.         if (mode==2)
  777.         {   if ((log[n].num_r==log[n2].num_r) )
  778.             log[n].c_double++;
  779.         }
  780.         else
  781.         if (mode==3)
  782.         log[n].c_double++;
  783.         else
  784.         if (mode==4)
  785.         {   if (log[n2].code_otv==404)
  786.             log[n].c_double++;
  787.         else
  788.         {
  789.             log[n].c_double=0;
  790.             break;
  791.         }
  792.         }
  793.     }
  794.     n2++;
  795.     }
  796.     }
  797. }
  798.  
  799. max_c_double = 1;
  800. for (n=0;n<logLen;n++)
  801.     if ( (log[n].ip == one_ip) &&  (log[n].c_double > max_c_double) )
  802.     max_c_double = log[n].c_double;
  803.  
  804. return max_c_double;
  805. }
  806. /////////////////////////
  807. int calcCookie(
  808.     int logLen,     //количество элементов в массиве log
  809.     struct oneHeat *log,    //исходный лог
  810.     int ip){
  811. int n,res=0;
  812.  
  813. for (n=0;n<logLen;n++)
  814. {
  815. //    printf("q\n");
  816.     if (log[n].ip==ip)
  817.     if (log[n].cookie>0)
  818.         res++;
  819. }
  820. return res;
  821. }
  822. /******************************
  823. Вывести топ IP
  824. ******************************/
  825. void showIpInfo(int countIpInfo,    //количество элементов в массиве ipInfo
  826.         struct sort_item *ipInfo,//указатель на массив структур с информацией о каждом ip
  827.         int logLen,     //количество элементов в массиве log
  828.         struct oneHeat *log,    //исходный лог
  829.         char (*reqwest) [MAX_REQWEST_COUNT][MAX_LEN_REQWEST],   //массив строк запроса
  830.         char (*user_agent) [MAX_USER_AGENT_COUNT][MAX_USER_AGENT_LEN],      //
  831.         int verbose,    //для каждого выводимого ip подсчитывать количество разных запросов и печатать
  832.         int c_print,    //сколько строк выводить
  833.         int show_d
  834.         ){
  835. //int ar[MAX_STR_LOG],//массив для хранения разных варимантов запроса для каждого ip
  836. //          //варианты запроса хранятся по номерам из строк массива reqwest
  837. //    c_reqv,   //счетчик для количества элементов массива ar
  838. int    last_url,    //номер первого запроса для ip
  839.     last_ua,n;
  840.    
  841. int count_r,
  842.     count_ref,
  843.     count_ua,
  844.     exemple_code ,
  845.     ccookie;
  846.  
  847. in_addr ad;
  848. char *ipstr;
  849. char str[3000], str1[200];
  850.  
  851. if (verbose)
  852. {    printf(" * Top IP=%d *\n",countIpInfo);
  853.     if (show_d)
  854.     printf("   ip              c        d1        d2          d3  url  co   ref  ua   last_url       last ua\n");
  855.     else
  856.     printf("   ip               c/c60 url  co   ref  ua   last_url                                      last_ua\n");
  857. //  printf("   ip               c/coo/c60 url  co   ref  ua   last_url                                  last_ua\n");
  858. }
  859. for (n=0;n<countIpInfo; n++)    //пробегаем по всем элементам массива ipInfo
  860. {  
  861.     if (n>=c_print)     //если превышен лимит на количество выводимых строк то выходим
  862.     {   if (verbose)       
  863.         printf("%d of %d\n",n,countIpInfo);//вывести количество напечатанных строк
  864.     return;
  865.     }
  866.  
  867.     ad.s_addr=ipInfo[n].sort_data;//преобразуем ip адрес из типа int в строку
  868.     ipstr = inet_ntoa(ad);
  869.  
  870.     if (verbose)
  871.     {
  872.     calcCountForIP(
  873.         logLen,     //количество элементов в массиве log
  874.         log,    //массив типа oneHeat с информацией о одной строке лог файла
  875.         ipInfo[n].sort_data,            //IP для которого считаем количество
  876.         count_r,        //счетчик количества найденных запросов для этого IP
  877.         exemple_code,
  878.         count_ref,
  879.         count_ua,       //счетчик количества найденных юзер агентов для этого IP
  880.         last_url,
  881.         last_ua
  882.         );
  883.  
  884.     if (show_d)
  885.     {
  886.         printf("%-16s %3d ",
  887.         ipstr,
  888.         ipInfo[n].sort_key);
  889.        
  890.         sprintf(str1,"%d/%d/%d",
  891.         findDDOS_one_ip(ipInfo[n].sort_data,logLen,log,60,1),
  892.         findDDOS_one_ip(ipInfo[n].sort_data,logLen,log,120,1),
  893.         findDDOS_one_ip(ipInfo[n].sort_data,logLen,log,180,1));
  894.         printf("%9s ",str1);
  895.        
  896.         sprintf(str1,"%d/%d/%d",
  897.         findDDOS_one_ip(ipInfo[n].sort_data,logLen,log,60,2),
  898.         findDDOS_one_ip(ipInfo[n].sort_data,logLen,log,120,2),
  899.         findDDOS_one_ip(ipInfo[n].sort_data,logLen,log,180,2));
  900.         printf("%9s ",str1);
  901.  
  902.         sprintf(str1,"%d/%d/%d",
  903.         findDDOS_one_ip(ipInfo[n].sort_data,logLen,log,60,3),
  904.         findDDOS_one_ip(ipInfo[n].sort_data,logLen,log,120,3),
  905.         findDDOS_one_ip(ipInfo[n].sort_data,logLen,log,180,3));
  906.         printf("%11s ",str1);
  907.  
  908.        
  909.  
  910.         if (ipInfo[n].sort_key == count_r)
  911.         printf("     ");
  912.         else
  913.         printf("%-4d ",count_r);
  914.  
  915.         printf("%-4d %-4d %-4d ",
  916.         exemple_code,
  917.         count_ref,
  918.         count_ua);
  919.  
  920.         strcpy(str, (*reqwest)[last_url]);
  921.         str[30]=0;
  922.         printf("%-31s ",str);
  923.  
  924.         strcpy(str, (*user_agent)[last_ua]);
  925.         str[19]=0;
  926.         printf("%s\n",str);
  927.     }else
  928.     {  
  929.         ccookie=calcCookie(
  930.         logLen,     //количество элементов в массиве log
  931.         log,    //исходный лог);
  932.         ipInfo[n].sort_data);
  933.        
  934.         printf("%-16s %4d/%-3d ",
  935.         ipstr,
  936.         ipInfo[n].sort_key,
  937. //      ccookie,
  938.         findDDOS_one_ip(
  939.             ipInfo[n].sort_data,
  940.             logLen,log,
  941.             60,3)
  942.         );
  943.  
  944.         if (ipInfo[n].sort_key == count_r)
  945.         printf("     ");
  946.         else
  947.         printf("%-4d ",count_r);
  948.  
  949.         strcpy(str, (*reqwest)[last_url]);
  950.         str[44]=0;
  951.  
  952.         printf("%-4d %-4d %-4d %-45s ",
  953.         exemple_code,
  954.         count_ref,
  955.         count_ua,
  956.         str);
  957.  
  958.         strcpy(str, (*user_agent)[last_ua]);
  959.         str[31]=0;
  960.    
  961.         printf("%s\n",str);
  962.     }
  963.  
  964.     }
  965.     else
  966.     printf("%s\n",ipstr);
  967. }
  968. }
  969.  
  970. /******************************
  971. Вывести топ кодов ответа
  972. ******************************/
  973. void showCodeInfo(int countCodeInfo,    //количество элементов в массиве CodeInfo
  974.         struct sort_item *codeInfo,//указатель на массив структур с информацией о одном Code
  975.         int logLen,     //количество элементов в массиве log
  976.         struct oneHeat *log,    //исходный лог
  977.         char (*reqwest) [MAX_REQWEST_COUNT][MAX_LEN_REQWEST],   //массив строк запроса
  978.         int c_print //сколько строк выводить
  979.         ){
  980. int  n,
  981.     count_ip,
  982.     count_r,
  983.     count_ua,
  984.     exemple_ip,
  985.     exemple_r;
  986.  
  987. in_addr ad;
  988. char *ipstr;
  989.  
  990. printf(" * TOP response code=%d *\n",countCodeInfo);
  991. printf("code c      ip   url    ua   last_ip          last_url\n");
  992. for (n=0;n<countCodeInfo; n++)  //пробегаем по всем элементам массива ipInfo
  993. {  
  994.     if (n>=c_print)     //если превышен лимит на количество выводимых строк то выходим
  995.     {
  996.     printf("%d of %d\n",n,countCodeInfo);//вывести количество напечатанных строк
  997.     return;
  998.     }
  999.  
  1000.     calcCountForCode(
  1001.     logLen,     //количество элементов в массиве log
  1002.     log,        //массив типа oneHeat с информацией о одной строке лог файла
  1003.     codeInfo[n].sort_data,      //запрос для которого считаем количество
  1004.     count_ip,
  1005.     count_r,
  1006.     count_ua,
  1007.     exemple_ip,
  1008.     exemple_r
  1009.     );
  1010.    
  1011.     ad.s_addr=exemple_ip;//преобразуем ip адрес из типа int в строку
  1012.     ipstr = inet_ntoa(ad);
  1013.    
  1014.     printf("%-4d %-6d %-4d %-6d %-4d %-16s %s\n",
  1015.     codeInfo[n].sort_data,
  1016.     codeInfo[n].sort_key,
  1017.     count_ip,
  1018.     count_r,
  1019.     count_ua,
  1020.     ipstr,
  1021.     (*reqwest)[exemple_r]
  1022.     );
  1023. }
  1024. }
  1025.  
  1026. /****************************
  1027. Вывести топ запросов
  1028. *****************************/
  1029. int printReqvInfo(
  1030.     int logLen,     //количество элементов в массиве log
  1031.     struct oneHeat *log,    //массив типа oneHeat с информацией о одной строке лог файла
  1032.     int count , //количество элементов в массиве reqv_info
  1033.     struct sort_item * reqv_info,//отсортированный массив с указанием на запрос и количеством(отсортирован по количеству)
  1034.     char (*reqwest) [MAX_REQWEST_COUNT][MAX_LEN_REQWEST],   //текст самих запросов(не повторяются)
  1035.     int c_print         //сколько строк выводить на экран
  1036. ){
  1037. int n,
  1038.     count_ip,
  1039.     count_ref,
  1040.     count_ua,
  1041.     exemple_code;
  1042.    
  1043. printf(" * TOP urls=%d *\n",count);
  1044. printf("c    ip   co   ref  ua   url\n");
  1045.  
  1046. for (n=0; n<count; n++)
  1047. {   if (n>=c_print)
  1048.     {   printf("%d of %d\n",n,count);
  1049.     return 1;
  1050.     }
  1051.    
  1052.     calcCountForReqwest(
  1053.     logLen,     //количество элементов в массиве log
  1054.     log,        //массив типа oneHeat с информацией о одной строке лог файла
  1055.     reqv_info[n].sort_data,     //запрос для которого считаем количество
  1056.     count_ip,
  1057.     count_ref,
  1058.     count_ua,
  1059.     exemple_code);
  1060.    
  1061.     printf("%-4d %-4d %-4d %-4d %-4d %s\n",
  1062.     reqv_info[n].sort_key,
  1063.     count_ip,
  1064.     exemple_code,
  1065.     count_ref,
  1066.     count_ua,
  1067.     (*reqwest) [    reqv_info[n].sort_data  ]
  1068.     );
  1069.  
  1070. }
  1071. }
  1072.  
  1073. //////////////
  1074.  
  1075. void printDdos(
  1076.     int ip,time_t t,
  1077.     char * reqw_str,
  1078.     int verbose){
  1079. in_addr ad;
  1080. char *ipstr, timeStr[20];
  1081. ad.s_addr=ip;
  1082. ipstr = inet_ntoa(ad);
  1083. if (verbose)
  1084. {
  1085.     myTimeToStr(&t,timeStr);
  1086.     printf("ip=%s %s %s\n",ipstr,   timeStr,    reqw_str);
  1087. }
  1088. else
  1089.     printf("%s\n",ipstr);
  1090.  
  1091. }
  1092.  
  1093. /////////////////////////
  1094. /*
  1095. int ipUseURLs(  int ip,
  1096.         struct oneHeat *log,
  1097.         int *ar_ddos_url,
  1098.         int count_ddos_url){
  1099. struct oneHeat *p;
  1100. p=log;
  1101. while(p->ip)
  1102. {
  1103.     if (p->ip==ip)
  1104.     if (inArray(count_ddos_url,ar_ddos_url, p->num_r))
  1105.         return 1;
  1106.     p++;
  1107. }
  1108. return 0;
  1109. }
  1110. */
  1111. /***********************************************
  1112. проверить были ли обращения с одного ip к URL НЕ из списка ar_ddos_url
  1113. ***********************************************/
  1114. int ipUseOtherURLs( int ip,     //анализируемый ip
  1115.             struct oneHeat *log,    //исходный лог
  1116.             int *ar_ddos_url,   //список url которе ддосят
  1117.             int count_ddos_url, //количество элементов в массиве ar_ddos_url
  1118.             int &count_ref//заодно расчитываем и возвращаем количество уникальных url для этого ip
  1119.             ){
  1120. int ar_ref[MAX_REFERRER_COUNT];//массив для хранения уникальных url этого ip
  1121. count_ref=0;
  1122.  
  1123. int url;
  1124. struct oneHeat *p;//указатель на структуру с информацией о одной строке лога
  1125. p=log;      //присваиваем указателю адрес первого элемента в логе
  1126. while(p->ip)    //пробегаемся по всему логу
  1127. {       //значение IP после последнего в логе рпавно 0
  1128.  
  1129.     if (p->ip==ip)//если эта строка лога сделана анализируемым ip
  1130.     {
  1131.     if (!inArray(count_ref, ar_ref,   p->num_r ))//если это новый уникальный url для этого ip
  1132.         ar_ref[count_ref++]=   p->num_r ;
  1133.  
  1134.     if (!inArray (count_ddos_url,ar_ddos_url, p->num_r))//если url этой строки не входит в список ar_ddos_url
  1135.         return 1;
  1136.        
  1137.     }
  1138.     p++;
  1139. }
  1140. return 0;
  1141. }
  1142.  
  1143.  
  1144.  
  1145. ///////////
  1146.  
  1147. void findGroupURL(
  1148.     int logLen,             //количество элементов в массиве log
  1149.     struct oneHeat *log,        //массив типа oneHeat с информацией о каждой строке лог файла
  1150.     int count_reqv ,            //количество элементов в массиве reqv_info
  1151.     struct sort_item * reqv_info,   //отсортированный массив с указанием на запрос и количеством(отсортирован по количеству)
  1152.     char (*reqwest) [MAX_REQWEST_COUNT][MAX_LEN_REQWEST],   //текст самих запросов(не повторяются)
  1153.     int limit_r,    //находит URL с количеством обращений со всех IP больше этого значения
  1154.     int limit_2,    //находит IP, которые сделали больше этого чисоа кликов и клики были только к URL найденным ранее
  1155.     int countClickLastMinute,
  1156.     int len_time_sec,
  1157.     int koef,
  1158.     int *ar_res_ip, //указатель на масив найденных IP
  1159.     int &c_ddos_ip, //количество найденных IP
  1160.  
  1161.     int *ar_white_ip,   //
  1162.     int *ar_white_mask  //
  1163. ){
  1164. int n,n2,    countIpInfo,    count_ip,    count_ref,    count_ua,    exemple_code,    ip_val,    count_ddos_url=0,
  1165.     isZag=0,    numUniqUrl,
  1166.     ar_ddos_url[2000];//сюда будем добавлять найденные номера запросов, которые превысили лимит на количество кликов
  1167.  
  1168. if (koef)
  1169.     limit_r=limit_r*koef/100;
  1170.  
  1171. limit_r= limit_r * calcPopr(len_time_sec) / 100;
  1172.  
  1173. time_t timer1;
  1174. char str_time[30];
  1175. time(&timer1);
  1176. myTimeToStr(&timer1,str_time);
  1177.  
  1178. struct sort_item ipInfo[MAX_STR_LOG];
  1179. in_addr ad;
  1180. char *ipstr;
  1181.  
  1182. for (n=0; n<count_reqv; n++)    //пробегаем по всем вариантам запросов
  1183.     if (reqv_info[n].sort_key>=limit_r) //если какой то запрос был сделан более лимита
  1184.     {
  1185.    
  1186.     calcCountForReqwest(
  1187.         logLen,     //количество элементов в массиве log
  1188.         log,        //массив типа oneHeat с информацией о одной строке лог файла
  1189.         reqv_info[n].sort_data,     //номер запроса для которого считаем количество
  1190.         count_ip,
  1191.         count_ref,
  1192.         count_ua,
  1193.         exemple_code);
  1194.    
  1195.     ar_ddos_url[count_ddos_url++]=reqv_info[n].sort_data;//добавляем найденный номер запроса в список
  1196.  
  1197.     if (!isZag)
  1198.     {
  1199.         printf("-x %d %d,",limit_r,limit_2);
  1200.    
  1201.         if (koef)
  1202.         printf("k=%d,",koef);
  1203.    
  1204.         printf("Rd=%d,Cm=%d,",logLen,countClickLastMinute);
  1205.  
  1206.         if (len_time_sec<400)
  1207.         printf("Tl=%ds",len_time_sec);
  1208.         else if (len_time_sec<7200)
  1209.         printf("Tl=%dm",len_time_sec/60);
  1210.         else
  1211.         printf("Tl=%dh",len_time_sec/3600);
  1212.    
  1213.         printf(",%s\n",str_time);
  1214.         isZag=1;
  1215.     }
  1216.    
  1217.     printf("c=%d,ip=%d,ref=%d,ua=%d,co=%d %s\n",
  1218.         reqv_info[n].sort_key,
  1219.         count_ip,
  1220.         count_ref,
  1221.         count_ua,
  1222.         exemple_code,
  1223.        
  1224.         (*reqwest) [    reqv_info[n].sort_data  ]
  1225.         );
  1226.     }
  1227.  
  1228. //printf("count_ddos_url=%d\n",count_ddos_url);
  1229.  
  1230. if (!count_ddos_url)//если нет ни одного запроса превысевшего количество кликов
  1231.     return;
  1232.  
  1233. //создаем массив ipInfo с информацией о количестве кликов каждого IP
  1234. //это нужно, что бы получить список уникальных IP
  1235. //что бы перебирать именно уникальные IP без повторов
  1236.  
  1237. countIpInfo= //количество разных ip(длина мкассива ipInfo)
  1238.     makeIpInfo( //создание массива ipInfo
  1239.     logLen, //количество элементов в массиве log
  1240.     log,    //массив типа oneHeat с информацией о одной строке лог файла
  1241.     ipInfo);//указатель на массив элементов типа sort_item,
  1242.  
  1243. for (n=0; n<countIpInfo; n++)//перебераем все варианты IP (не повторяются)
  1244. {
  1245.  
  1246. /*    if ( ipUseURLs(//если IP обращается к URL из списка ддос урлов
  1247.         ipInfo[n].sort_data,
  1248.         log,
  1249.         ar_ddos_url,
  1250.         count_ddos_url) )*/
  1251.  
  1252.     if (ipInfo[n].sort_key >=  limit_2 )//если количество кликов с этого IP больше лимита
  1253.    
  1254.         if (! ipUseOtherURLs(//если IP не обращается к URL не из списка ддос урлов
  1255.         ipInfo[n].sort_data,    //анализипуемый IP
  1256.         log,            //исходный массив лога
  1257.         ar_ddos_url,        //массив номеров атакуемых URL
  1258.         count_ddos_url,     //количество URL под атакой
  1259.         numUniqUrl) )   //заодно расчитываем количестов уникальных URL для этого ip
  1260.  
  1261.         {
  1262.         ip_val=ipInfo[n].sort_data;//значение IP
  1263.         if (!inArray(c_ddos_ip,ar_res_ip,ip_val))//если IP еще нет в списке ar_res_ip
  1264.         {
  1265.             if (!inArray_ip_mask(ar_white_ip,ar_white_mask,ip_val) )//если IP нет в белом спаске ar_white_ip
  1266.             {
  1267.             ar_res_ip[c_ddos_ip++]=ip_val;
  1268.             ad.s_addr=ip_val;
  1269.             ipstr = inet_ntoa(ad);
  1270.             printf("x: %d,u=%d -  %s\n",
  1271.                 ipInfo[n].sort_key,
  1272.                 numUniqUrl,
  1273.                 ipstr);
  1274.             }
  1275.         }
  1276.         }
  1277.  
  1278. }
  1279. ar_res_ip[c_ddos_ip]=0;
  1280. }
  1281. //подсчитать сколько разных IP используют данный юзерагент
  1282. int calcIPbyUA(
  1283.     int id_user_agent,
  1284.     int logLen,         //длина лога
  1285.     struct oneHeat *log){
  1286. int n, ar_ip[MAX_STR_LOG], count_ip=0;
  1287. for(n=0;n<logLen;n++)   //пробегаем по всем строкам лог файла
  1288.     if (log[n].num_ua == id_user_agent)     //если в лог файле нашли запрос с нужным юзер агентом
  1289.     if (!inArray(count_ip, ar_ip, log[n].ip ))  //если запроса с этим ip еще не было
  1290.         ar_ip[count_ip++]=log[n].ip;    //то добавляем этот запрос в массив ar_int и увеличиваем количество элементов в массиве
  1291. return count_ip;
  1292. }
  1293.  
  1294. //подсчитать сколько разных IP используют данный реферрер
  1295. int calcIPbyRef(
  1296.     int id_referer,
  1297.     int logLen,         //длина лога
  1298.     struct oneHeat *log){
  1299. int n, ar_ip[MAX_STR_LOG], count_ip=0;
  1300. for(n=0;n<logLen;n++)   //пробегаем по всем строкам лог файла
  1301.     if (log[n].num_ref == id_referer)       //если в лог файле нашли запрос с нужным юзер агентом
  1302.     if (!inArray(count_ip, ar_ip, log[n].ip ))  //если запроса с этим ip еще не было
  1303.         ar_ip[count_ip++]=log[n].ip;    //то добавляем этот запрос в массив ar_int и увеличиваем количество элементов в массиве
  1304. return count_ip;
  1305. }
  1306.  
  1307. int banAllLastM(
  1308.         int logLen,
  1309.     struct oneHeat *log,
  1310.     int *ar_res_ip,
  1311.     int &c_ddos_ip,
  1312.    
  1313.     int *ar_white_ip,
  1314.     int *ar_white_mask
  1315.     ){
  1316. int n,  t2=0,   c=0, ip;
  1317. time_t last_time;
  1318.  
  1319. in_addr ad;
  1320. char *ipstr;
  1321.  
  1322. if (logLen<3)
  1323.     return 0;
  1324. last_time=log[logLen-1].t;
  1325. for(n=logLen-2;n>=0;n--)
  1326. {
  1327.     t2=last_time-log[n].t;
  1328.     if (t2>60)
  1329.     break;
  1330.     ip=log[n].ip;
  1331.    
  1332.     if (!inArray_ip_mask( ar_white_ip, ar_white_mask, ip) )
  1333.     if (! inArray(c_ddos_ip  , ar_res_ip ,ip)  )
  1334.     {
  1335.     ar_res_ip[ c_ddos_ip++ ]= ip;
  1336.     ad.s_addr=ip;
  1337.     ipstr = inet_ntoa(ad);
  1338.     printf("-A:%s\n",ipstr);
  1339.     }
  1340. }
  1341. return c;
  1342. }
  1343. /**************************************************************
  1344. подсчитать количество не забаненных кликов в последнюю минуту
  1345. ***************************************************************/
  1346. int calcNumNotBanLastM(
  1347.         int logLen,     //количество элементов массива log
  1348.     struct oneHeat *log,    //массив элементов лога
  1349.     int *ban_ip,        //массив забаненных IP
  1350.     int &numIPlastM){   //заодно расчитываем и возвращаем количество уникальных IP за последнюю минуту
  1351. int n,
  1352.     t2=0,
  1353.     c=0,
  1354.     ip,
  1355.     ar_ip[MAX_STR_LOG];//массив используется для подсчета количества уникальных IP
  1356. time_t last_time;
  1357. numIPlastM=0;
  1358. if (logLen<3)
  1359.     return 0;
  1360. last_time=log[logLen-1].t;//время последнего клика
  1361. for(n=logLen-2;n>=0;n--)  //пробегаем по логу начиная с последнего элемента и до тех пор пока не закончится минута
  1362. {   t2=last_time-log[n].t;
  1363.     if (t2>60)
  1364.     break;
  1365.     ip=log[n].ip;
  1366.     if (!inArray_z(ban_ip,ip)  )//если клик сделан с не забаненного IP то увеличиваем счетчик не забаненых кликов
  1367.     c++;
  1368.    
  1369.     if (!inArray(numIPlastM, ar_ip, ip)  ) //если такого ip еще нет в массиве ar_ip то добавояем его в  
  1370.     ar_ip[numIPlastM++]=ip;        //ar_ip и увеличиваем счетчик уникальных IP
  1371. }
  1372. return c;
  1373. }
  1374. /***********************
  1375. алгоритм банит всех кто зашел в последнюю минуту в случае выполнения всех 4 условий
  1376. 1) количество забаненных IP предыдущими алгоритмами в этом вызове программы менее 10
  1377. 2) количество кликов в последнюю минуту больше или равно limit_lastm
  1378. 3) количестово уникальных IP в последнюю минуту больше или равно limit_countIP
  1379. 4) процент не забаненных кликов в последнюю минуту болше или равен limit_proc_ban
  1380. ***********************/
  1381. void armagedon(
  1382.         int logLen,     //количество элементов в логе (в массиве log)
  1383.     struct oneHeat *log,    //массив элементов исходного лога
  1384.  
  1385.     int limit_lastm,    //лимит на количество кликов в роследнюю минуту
  1386.     int limit_countIP,  //лимит на количество IP в последнюю минуту
  1387.     int limit_proc_ban, //лимит на процент не забаненных кликов в последнюю минуту
  1388.  
  1389.     int countClickLastMinute,//количестово кликов за последнюю минуту
  1390.     int countIpInfo,    //количество уникальных IP в логе
  1391.         //это число может быть вычислено предыдущими алгоритмами
  1392.         //Если оно вычислено, то оно используется для сравнения с limit_countIP
  1393.         //и может предотвратить лишние расчеты.
  1394.         //если это значение предыдущими алгоритмами не вычеслено, то его значение должно быть 0
  1395.  
  1396.     int len_time_sec,   //длина лога в секундах
  1397. //  int koef,       //???????
  1398.  
  1399.     int *ar_res_ip,     //массив забаненных IP, сюда добавляем обнаруженных ботов
  1400.     int &c_ddos_ip,     //уоличество элементов в массиве ar_res_ip
  1401.  
  1402.     int *ar_white_ip,   //белый список IP
  1403.     int *ar_white_mask  //маска белого списка
  1404.     ){
  1405. int numNotBanLastM,proc_not_ban,numIPlastM;
  1406. struct sort_item ipInfo[MAX_STR_LOG];
  1407.  
  1408. time_t timer1;
  1409. char str_time[30];
  1410.  
  1411. //printf("armagedon\n");
  1412. //printf("countClickLastMinute=%d\n",countClickLastMinute);
  1413. //printf("limit_countIP=%d\n",limit_countIP);
  1414. //printf("countIpInfo=%d\n",countIpInfo);
  1415. //printf("limit_lastm=%d\n",limit_lastm);
  1416. //printf("limit_proc_ban=%d\n",limit_proc_ban);
  1417. //printf("c_ddos_ip=%d\n",c_ddos_ip);
  1418.  
  1419. if (  (c_ddos_ip<10) &&  (countClickLastMinute>2) && (countClickLastMinute >= limit_lastm ) )
  1420. {
  1421.     if (  !countIpInfo  || (countIpInfo >= limit_countIP ) )
  1422.     {
  1423.     ar_res_ip[c_ddos_ip]=0;
  1424.     //подсчитать количество не забаненных кликов в последнюю минуту
  1425.     numNotBanLastM=calcNumNotBanLastM(
  1426.         logLen,
  1427.         log,
  1428.         ar_res_ip,
  1429.         numIPlastM);//заодно расчитываем и возвращаем количество уникальных IP за последнюю минуту
  1430.  
  1431.     proc_not_ban=100 * numNotBanLastM/countClickLastMinute;// находим процент не забаненных кликов
  1432.  
  1433. //  printf("numNotBanLastM=%d\n",numNotBanLastM);
  1434. //  printf("proc_not_ban=%d\n",proc_not_ban);
  1435. //  printf("numIPlastM=%d\n",numIPlastM);
  1436.  
  1437.     if (( numIPlastM >= limit_countIP) && ( proc_not_ban >= limit_proc_ban ) )
  1438.     {  
  1439.         time(&timer1);
  1440.         myTimeToStr(&timer1,str_time);
  1441.        
  1442.         printf("-A %d %d %d, Cm=%d,IpM=%d,Pn=%d %s\n",
  1443.         limit_lastm,
  1444.         limit_countIP,
  1445.         limit_proc_ban,
  1446.         countClickLastMinute,
  1447.         numIPlastM,
  1448.         proc_not_ban,
  1449.         str_time
  1450.         );
  1451.         banAllLastM(
  1452.         logLen,
  1453.         log,
  1454.         ar_res_ip,
  1455.         c_ddos_ip,
  1456.        
  1457.         ar_white_ip,
  1458.         ar_white_mask);
  1459.     }
  1460.     }
  1461. }
  1462. }
  1463.  
  1464. /*************************
  1465. какой длины limit_len должна быть строка и сколько раз она должна повториться limit_d за период времени per
  1466. Что бы считать этот ддосом
  1467. ***************************/
  1468. void findLongStr(
  1469.         int logLen,
  1470.     struct oneHeat *log,
  1471.     char (*reqwest) [MAX_REQWEST_COUNT][MAX_LEN_REQWEST],
  1472.     int limit_d,    //сколько раз за периуд времени должен повторится запрос, что бы считать его ддосом
  1473.     int per,    //периуд времени в течении которгго производится подсчет повторов
  1474.     int limit_len,
  1475.     int verbose,
  1476.     int c_print,
  1477.     int *ar_res_ip,
  1478.     int &c_ddos_ip
  1479.     ){
  1480. int n,n2, max_c_double;
  1481.  
  1482. //printf("-s limit_d=%d , per=%d , limit_len=%d\n",limit_d,per,limit_len);
  1483. for (n=0;n<logLen;n++)
  1484. {   if (log[n].len_str >  limit_len)
  1485.     {   log[n].c_double=1;
  1486.     n2=n+1;
  1487.     while ((n2<logLen) && (log[n2].t - log[n].t <per) )
  1488.         {  
  1489.         if (log[n].ip==log[n2].ip)
  1490.         if (log[n2].len_str >  limit_len)
  1491.             log[n].c_double++;
  1492.         n2++;
  1493.     }
  1494.     }else
  1495.     log[n].c_double=0;
  1496. };
  1497. for (n=0;n<logLen;n++)
  1498.     if (log[n].c_double>=limit_d)
  1499.     if (!inArray(c_ddos_ip, ar_res_ip,log[n].ip)  )
  1500.     {   max_c_double = log[n].c_double;
  1501.         for (n2=n;n2<logLen;n2++)
  1502.         if ( (log[n].ip == log[n2].ip) &&  (log[n2].c_double > max_c_double) )
  1503.             max_c_double = log[n2].c_double;
  1504.         ar_res_ip[c_ddos_ip]=log[n].ip;
  1505.         c_ddos_ip++;
  1506.        
  1507.         printf("-s %d %d %d:L=%d,c=%d,", limit_d,per, limit_len, log[n].len_str, max_c_double);
  1508.         printDdos(
  1509.         log[n].ip,
  1510.         log[n].t,
  1511.         (*reqwest)[ log[n].num_r ],
  1512.         verbose);
  1513.  
  1514. /*      if (c_ddos_ip>=c_print)
  1515.         {   ar_res_ip[c_ddos_ip]=0;
  1516.         if (verbose)
  1517.             printf("Первые %d. Не все.\n",c_ddos_ip);
  1518.         return;
  1519.         }*/
  1520.     }
  1521.  
  1522. ar_res_ip[c_ddos_ip]=0;
  1523. }
  1524. //////////
  1525. /*************************
  1526. какой длины limit_len должна быть строка и сколько раз она должна повториться limit_d за период времени per
  1527. Что бы считать этот ддосом
  1528. ***************************/
  1529. void findDirki(
  1530.         int logLen,
  1531.     struct oneHeat *log,
  1532.     char (*reqwest) [MAX_REQWEST_COUNT][MAX_LEN_REQWEST],
  1533.     int per1,   //сколько раз за периуд времени должен повторится запрос, что бы считать его ддосом
  1534.     int per2,   //периуд времени в течении которгго производится подсчет повторов
  1535.     int verbose,
  1536.     int c_print,
  1537.     int *ar_res_ip,
  1538.     int &c_ddos_ip,
  1539.    
  1540.     int *ar_white_ip,
  1541.     int *ar_white_mask
  1542.     ){
  1543. int n,n2, t_old , d ,maxd;
  1544. //printf("-z per1=%d , per2=%d\n",per1,per2);
  1545. for (n=0;n<logLen;n++)
  1546. {
  1547. //    printf("n=%d\n",n);
  1548.     if (inArray_ip_mask(ar_white_ip,ar_white_mask,log[n].ip) )
  1549.     {
  1550.     log[n].c_double=per2;
  1551.     continue;
  1552.     }
  1553.  
  1554.     maxd=0; t_old=log[n].t;    n2=n+1;
  1555.     while ((n2<logLen) && (log[n2].t - log[n].t <per2) )
  1556.     {  
  1557.     if (log[n].ip==log[n2].ip)
  1558.     {
  1559.         d=log[n2].t - t_old;
  1560.         t_old=log[n2].t;
  1561.         if (d>maxd)
  1562.         {
  1563.         maxd=d;
  1564.         if (maxd>per1)
  1565.             break;
  1566.         }
  1567.    
  1568. //      printf("n2=%d d=%d, ",n2,d);
  1569.     }
  1570.     n2++;
  1571.     }
  1572.     d= log[n].t + per2 - t_old;
  1573.     if (d>maxd)
  1574.     maxd=d;
  1575. //    printf("n=%d maxd=%d\n",n,maxd);
  1576.     log[n].c_double=maxd;
  1577. };
  1578.  
  1579. for (n=0;n<logLen;n++)
  1580.     if (log[n].c_double<per1)
  1581.     if (!inArray(c_ddos_ip, ar_res_ip,log[n].ip)  )
  1582.     {   maxd = log[n].c_double;
  1583. //      printf("rrr n=%d maxd=%d\n",n,maxd);
  1584. //      for (n2=n;n2<logLen;n2++)
  1585. //      if ( (log[n].ip == log[n2].ip) &&  (log[n2].c_double > maxd) )
  1586. //          maxd = log[n2].c_double;
  1587.         ar_res_ip[c_ddos_ip]=log[n].ip;
  1588.         c_ddos_ip++;
  1589.        
  1590.         printf("-z %d %d: c=%d ", per1, per2, maxd);
  1591.         printDdos(
  1592.         log[n].ip,
  1593.         log[n].t,
  1594.         (*reqwest) [ log[n].num_r ],
  1595.         verbose);
  1596.     }
  1597. ar_res_ip[c_ddos_ip]=0;
  1598. }
  1599. ////////
  1600. void printHelp(){
  1601. printf(" *** Поиск DDOS в лог файле web сервера ***\n");
  1602. printf("\n");
  1603. }
  1604. ////////
  1605. int strIPportToIP(char *s){
  1606. in_addr ad; //структура для хранения IP адреса
  1607. int razdc=0;
  1608. char *n;
  1609. n=s;
  1610. while(*n)
  1611. {
  1612.     if ((*n=='.') || (*n==':') )
  1613.     {
  1614.     if (razdc>=3)
  1615.     {
  1616.         *n=0;
  1617.         break;
  1618.     }else
  1619.         razdc++;
  1620.     }
  1621.     n++;
  1622. }
  1623. //printf("s=%s\n",s);
  1624. if (inet_aton(s,&ad) ==0)   //преобразуем строковый вормат IP адреса в 4-х байтовое целое
  1625.     return -1;          // если формат не верный выходим
  1626.  
  1627. return ad.s_addr;
  1628. }
  1629.  
  1630. ////////////
  1631. void printNetstat(
  1632.     int count,
  1633.     netstat_t *netstat,
  1634.     int sockCount,
  1635.     int koef,
  1636.     sort_item *order,
  1637.     int max_row,
  1638.     int *ar_res_ip,
  1639.     struct netstat_t netstat_limit,
  1640.     char *comment_str
  1641.     ){
  1642. int n,num, print_counter=0;
  1643. in_addr ad;
  1644. char *ipstr;
  1645. time_t timer1;
  1646. char str_time[30];
  1647. time(&timer1);
  1648. myTimeToStr(&timer1,str_time);
  1649.  
  1650. if (koef)
  1651. {
  1652.     netstat_limit.count     =   netstat_limit.count     *koef/100;
  1653.     netstat_limit.c_SYN_RECV    =   netstat_limit.c_SYN_RECV    *koef/100;
  1654.     netstat_limit.c_SYN_SENT    =   netstat_limit.c_SYN_SENT    *koef/100;
  1655.     netstat_limit.c_ESTABLISHED =   netstat_limit.c_ESTABLISHED *koef/100;
  1656.     netstat_limit.c_TIME_WAIT   =   netstat_limit.c_TIME_WAIT   *koef/100;
  1657.     netstat_limit.c_FIN_WAIT1   =   netstat_limit.c_FIN_WAIT1   *koef/100;
  1658.     netstat_limit.c_FIN_WAIT2   =   netstat_limit.c_FIN_WAIT2   *koef/100;
  1659.     netstat_limit.c_CLOSING     =   netstat_limit.c_CLOSING     *koef/100;
  1660.     netstat_limit.c_CLOSE_WAIT  =   netstat_limit.c_CLOSE_WAIT  *koef/100;
  1661.     netstat_limit.c_LAST_ACK    =   netstat_limit.c_LAST_ACK    *koef/100;
  1662. }
  1663.  
  1664. for (n=0;n<count;n++)
  1665. {   if (print_counter>=max_row)
  1666.     {   printf("%d of %d\n",print_counter,count);
  1667.     ar_res_ip[print_counter]=0;
  1668.     return;
  1669.     }
  1670.     num=order[n].sort_data;
  1671.     if (
  1672.         (netstat[num].count >= netstat_limit.count )        && netstat_limit.count      ||
  1673.         (netstat[num].c_SYN_RECV >= netstat_limit.c_SYN_RECV)   && netstat_limit.c_SYN_RECV     ||
  1674.         (netstat[num].c_SYN_SENT >= netstat_limit.c_SYN_SENT )  && netstat_limit.c_SYN_SENT     ||
  1675.         (netstat[num].c_ESTABLISHED >= netstat_limit.c_ESTABLISHED )&& netstat_limit.c_ESTABLISHED  ||
  1676.         (netstat[num].c_TIME_WAIT >= netstat_limit.c_TIME_WAIT )    && netstat_limit.c_TIME_WAIT    ||
  1677.         (netstat[num].c_FIN_WAIT1 >= netstat_limit.c_FIN_WAIT1 )    && netstat_limit.c_FIN_WAIT1    ||
  1678.         (netstat[num].c_FIN_WAIT2 >= netstat_limit.c_FIN_WAIT2 )    && netstat_limit.c_FIN_WAIT2    ||
  1679.         (netstat[num].c_CLOSING >= netstat_limit.c_CLOSING )    && netstat_limit.c_CLOSING  ||
  1680.         (netstat[num].c_CLOSE_WAIT >= netstat_limit.c_CLOSE_WAIT )  && netstat_limit.c_CLOSE_WAIT   ||
  1681.         (netstat[num].c_LAST_ACK >= netstat_limit.c_LAST_ACK )  && netstat_limit.c_LAST_ACK
  1682.     )
  1683.     {  
  1684.    
  1685.     if (comment_str)
  1686.         printf("%s ",comment_str);
  1687.    
  1688.     if (koef)
  1689.         printf("k=%d,",koef);
  1690.     printf("s=%d,%s ",sockCount,str_time);
  1691.    
  1692.     ad.s_addr=netstat[num].ip_for;
  1693.     ipstr = inet_ntoa(ad);
  1694.     printf("%-3d %-17s",netstat[num].count ,ipstr);
  1695.    
  1696.     if (netstat[num].c_SYN_RECV)    printf(" sr=%d",netstat[num].c_SYN_RECV);
  1697.     if (netstat[num].c_SYN_SENT)    printf(" ss=%d",netstat[num].c_SYN_SENT);
  1698.     if (netstat[num].c_ESTABLISHED) printf(" est=%d",netstat[num].c_ESTABLISHED);
  1699.     if (netstat[num].c_TIME_WAIT)   printf(" tw=%d",netstat[num].c_TIME_WAIT);
  1700.     if (netstat[num].c_FIN_WAIT1)   printf(" fw1=%d",netstat[num].c_FIN_WAIT1);
  1701.     if (netstat[num].c_FIN_WAIT2)   printf(" fw2=%d",netstat[num].c_FIN_WAIT2);
  1702.     if (netstat[num].c_CLOSING) printf(" clo=%d",netstat[num].c_CLOSING);
  1703.     if (netstat[num].c_CLOSE_WAIT)  printf(" clw=%d",netstat[num].c_CLOSE_WAIT);
  1704.     if (netstat[num].c_LAST_ACK)    printf(" la=%d",netstat[num].c_LAST_ACK);
  1705.     printf("\n");
  1706.     ar_res_ip[print_counter]=netstat[num].ip_for;
  1707.     print_counter++;
  1708.     }
  1709. }
  1710. ar_res_ip[print_counter]=0;
  1711. };
  1712. ///////
  1713. int chekState(char *s, struct netstat_t *netstat){
  1714. //printf("chekState %s\n",s);
  1715. if (strcmp(s,"SYN_RECV")==0)        netstat->c_SYN_RECV++;
  1716. else if (strcmp(s,"SYN_SENT")==0)   netstat->c_SYN_SENT++;
  1717. else if (strcmp(s,"ESTABLISHED")==0)    netstat->c_ESTABLISHED++;
  1718. else if (strcmp(s,"TIME_WAIT")==0)  netstat->c_TIME_WAIT++;
  1719. else if (strcmp(s,"FIN_WAIT1")==0)  netstat->c_FIN_WAIT1++;
  1720. else if (strcmp(s,"FIN_WAIT2")==0)  netstat->c_FIN_WAIT2++;
  1721. else if (strcmp(s,"CLOSING")==0)    netstat->c_CLOSING++;
  1722. else if (strcmp(s,"CLOSE_WAIT")==0) netstat->c_CLOSE_WAIT++;
  1723. else if (strcmp(s,"LAST_ACK")==0)   netstat->c_LAST_ACK++;
  1724.  
  1725. // for freeBSD
  1726. // В freeBSD состояния сокета называются по другиму
  1727. else if (strcmp(s,"CLOSED")==0) netstat->c_CLOSING++; // CLOSING или CLOSE_WAIT ? Не известно чему соответсвует.
  1728. else if (strcmp(s,"SYN_RCVD")==0)       netstat->c_SYN_RECV++;
  1729. else if (strcmp(s,"FIN_WAIT_1")==0) netstat->c_FIN_WAIT1++;
  1730. else if (strcmp(s,"FIN_WAIT_2")==0) netstat->c_FIN_WAIT2++;
  1731.  
  1732. else
  1733.     printf("no: %s\n",s);
  1734. }
  1735. ///////
  1736. void set_all_netstat(netstat_t &n, int v){
  1737. n.count=v;
  1738. n.c_SYN_RECV=v;
  1739. n.c_ESTABLISHED=v;
  1740. n.c_TIME_WAIT=v;
  1741. n.c_SYN_SENT=v;
  1742. n.c_FIN_WAIT1=v;
  1743. n.c_FIN_WAIT2=v;
  1744. n.c_CLOSING=v;
  1745. n.c_CLOSE_WAIT=v;
  1746. n.c_LAST_ACK=v;
  1747. }
  1748. /////////
  1749. //////
  1750. int strToNetstat(
  1751.     char *s,
  1752.     int logLen,
  1753.     struct netstat_t *netstat,
  1754.     int *ar_banned_ip,
  1755.     int *ar_white_ip,
  1756.     int *ar_white_mask
  1757.     ){
  1758. //printf("strToNetstat logLen=%d\n",logLen);
  1759. char m[20][MAX_LEN_SUBSTR]; //массив для хранения 20 подстрок длиной MAX_LEN_SUBSTR разбитых по пробелу
  1760. int k,ip;
  1761.  
  1762. k=strBreak(s,m,0);//разбиваем строку по разделителю пробел
  1763. if ((k!=7)&&(k!=6))
  1764.     return -1;
  1765.  
  1766. ip=strIPportToIP(m[4]);
  1767. if (ip==-1)
  1768.     return -1;
  1769.  
  1770. if (inArray_z(ar_banned_ip, ip))
  1771.     return -2;
  1772.  
  1773. if (inArray_ip_mask(
  1774.     ar_white_ip,
  1775.     ar_white_mask,
  1776.     ip) )
  1777.     return -2;
  1778. ////////////////////
  1779.  
  1780. for(k=0; k<logLen;k++)
  1781.     if (netstat[k].ip_for==ip)
  1782.     {
  1783.     netstat[k].count++;
  1784.     chekState(m[5],&netstat[k]);
  1785.     return 1;
  1786.     }
  1787. netstat[logLen].ip_for=ip;
  1788.  
  1789. set_all_netstat(netstat[logLen], 0);
  1790.  
  1791. netstat[logLen].count=1;
  1792. chekState(m[5],&netstat[logLen]);
  1793. return 0;
  1794. };
  1795. /********************************************
  1796. прочитать из файла logFileName статистику команды netstat
  1797. ********************************************/
  1798. int readNetstat(
  1799.     char *logFileName,
  1800.     netstat_t *netstat, //указатель на массив элеменов, каждый элемент содержит информацию о одном IP
  1801.                 //IP не повторяются
  1802.    
  1803.     int &readCount, //сюда заносим количество строк в считываемом файле(количестов коннектов)
  1804.     sort_item *IPinfo,  //массив для сортировки ip адресов по количеству повторений
  1805.                 //каждый элемент содержит IP и количество повторений
  1806.     int *ar_banned_ip,  //не считывем
  1807.     int showHeader,
  1808.     int *ar_white_ip,   //эти ip не считываем по маске
  1809.     int *ar_white_mask, //
  1810.    
  1811.     char *comment_str   //
  1812.     ){
  1813. FILE *fp;
  1814. char s[200],c,*ps;
  1815. int IPcount=0,
  1816.     logError=0,
  1817.     strLoss=0,
  1818.     res,
  1819.     n=0,
  1820.     IPalreadyBanned=0;
  1821.  
  1822. readCount=0;//общее количество коннектов или количество прочитанных строк
  1823.  
  1824. if( (fp= fopen(logFileName,"r") ) ==NULL)
  1825. {   printf("Error %d: %s :  %s\n",errno, logFileName, strerror(errno));
  1826.     return 0;
  1827. }
  1828. n=0; ps=s;
  1829. while (!feof(fp))
  1830. {   c=fgetc(fp);
  1831.     if (c!=EOF)
  1832.     {
  1833.     if (c=='\n')
  1834.     {
  1835.         *ps=0;
  1836.             if (IPcount < MAX_LEN_NETSTAT)
  1837.         {  
  1838. //      printf("%s\n",s);
  1839.         res=strToNetstat(
  1840.             s,          //добавляемая строка
  1841.             IPcount,        //количество уже добавленных IP
  1842.             netstat,        //указатель на массив информации о статистике IP
  1843.             ar_banned_ip,   //массив IP которые не читаем
  1844.             ar_white_ip,    //массив IP которые не читаем по маске
  1845.             ar_white_mask
  1846.             );
  1847.         if (res==-1)//не верный формат строки лог файла
  1848.         {   logError++;
  1849. //          if (logError<3)
  1850.                 printf("ERR: %s\n",s);
  1851.         }
  1852.         else if (res==0)//формат верный и IP добавлен
  1853.         {
  1854.             readCount++;
  1855.             IPcount++;
  1856.         }
  1857.         else if (res==1)//формат верный, но IP уже был
  1858.         {
  1859.             readCount++;
  1860.         }
  1861.         else if (res==-2)
  1862.         {
  1863.             IPalreadyBanned++;
  1864.         }
  1865.        
  1866.         }else
  1867.         {
  1868.         strLoss=1; //Прочитанны не все строки, так как много строк
  1869.         break;
  1870.         }
  1871.         n=0; ps=s;
  1872.     }else
  1873.     {
  1874.         if (n<200)
  1875.         *ps++=c;
  1876.         n++;
  1877.     }
  1878.     }
  1879. }
  1880. fclose(fp);
  1881. //////
  1882.  
  1883. //заполняем массив IPinfo. Количество элементов в нем равно количеству элементов массива netstat
  1884. //
  1885. for (n=0;n<IPcount;n++)
  1886. {
  1887.     IPinfo[n].sort_key=netstat[n].count;
  1888.     IPinfo[n].sort_data=n;
  1889. }
  1890. if (showHeader)
  1891. {
  1892.     if (comment_str)
  1893.     printf("%s ",comment_str);
  1894.    
  1895.     printf("ReadCount:%d, IPcount=%d",readCount,IPcount);
  1896.     if (IPalreadyBanned)
  1897.     printf(",AllreadyBanAndWhite:%d",IPalreadyBanned);
  1898.     if (strLoss)
  1899.     printf("(Не все)");
  1900.     if (logError)
  1901.     printf("(Не распознанно=%d)",logError);
  1902.     printf("\n");
  1903. }
  1904. return IPcount;
  1905. }
  1906.  
  1907. int calc_hash(char *s){
  1908. int res=0;
  1909. int c=0;
  1910.  
  1911. int i;
  1912.  
  1913. while (*s)
  1914. {    
  1915.     i=(*s) -32 ;
  1916.     res+=i + c*128 ;
  1917.     s++;
  1918.     if (c>100)
  1919.     break;
  1920.     c++;
  1921. }
  1922. return res;
  1923. }
  1924. //////////////////////////////////////////////////
  1925. /********************************************************
  1926. разбирает одну строку лог файла и выделяет из нее данные
  1927. если формат верный, то возвращает 0, если не верный -1.
  1928. Если собираем лишь 1 IP адрес, формат строки верный, но это не тот IP адрес, то возвращаем -2
  1929. Если превышен лимит количества возможных вариантов запроса MAX_REQWEST_COUNT, то возвращаем -3
  1930.  
  1931. Данные помещаются
  1932. в структуру oneHeat: ip, t-время, num_r - номер строки в таблице запросов
  1933. добавляется строка в таблицуу запросов reqwest и reqv_info, если ее не было( при этом увеличиваем reqwest_c)
  1934. *********************************************************/
  1935. int strToOneHeat(
  1936.     char *s,
  1937.     struct oneHeat *oh,
  1938.  
  1939.     char (*reqwest) [MAX_REQWEST_COUNT][MAX_LEN_REQWEST],       //массив вариантов запросов
  1940.  
  1941.     int reqwest_hash[MAX_REQWEST_COUNT],
  1942.     int referrer_hash[MAX_REFERRER_COUNT],
  1943.     int user_agent_hash[MAX_USER_AGENT_COUNT],
  1944.    
  1945.     struct sort_item reqv_info[],   //массив с информацией о количестве каждого запроса
  1946.     int &reqwest_c,             //количество элементов в таблице reqwest и reqv_info
  1947.  
  1948.     char (*referrer) [MAX_REFERRER_COUNT][MAX_REFERRER_LEN] ,//массив строк, в каждой строке один вариант реферрера(не повторяются)
  1949.     struct sort_item referrer_info[],   //массив структур. номер строки из таблицы referrer и количетво повторов
  1950.     int &referrer_c,    //количество строк в таблице referrer и referrer_info
  1951.  
  1952.     char (*user_agent) [MAX_USER_AGENT_COUNT][MAX_USER_AGENT_LEN] , //массив строк, в каждой строке один вариант юзер агента(юзер агенты не повторяются)
  1953.     struct sort_item user_agent_info[], //массив структур. номер строки из таблицы reqwest и количетво повторов
  1954.     int &user_agent_c,  //количество строк в таблице user_agent
  1955.  
  1956.     int *ar_banned_ip,  //массив ip которые считывать не нужно, заканчивается нулевым элементом
  1957.     int *ar_mask,
  1958.     int one_ip,     //если собираем лишь 1 IP адрес, иначе 0
  1959.     int need_reqwest_info//заполняем таблицу reqwest
  1960.     ){
  1961. //printf("s=%s\n",s);
  1962. char m[20][MAX_LEN_SUBSTR]; //массив для хранения 20 подстрок длиной MAX_LEN_SUBSTR разбитых по пробелу
  1963. int k;
  1964.  
  1965. int new_hash;
  1966. int str_is;//был ли этот запрос ранее
  1967.  
  1968. in_addr ad; //структура для хранения IP адреса
  1969. k=strBreak(s,m,1);//разбиваем строку по разделителю пробел
  1970.  
  1971. if (k<10) //Не верный формат строки лог файла.
  1972. {    
  1973. //    printf("k=%d\n",k);
  1974.     return -1;
  1975. }
  1976.  
  1977. //printf("k=%d\n",k);
  1978.  
  1979. if (inet_aton(m[0],&ad) ==0)    //преобразуем строковый вормат IP адреса в 4-х байтовое целое
  1980. {
  1981.      return -1;         // если формат не верный выходим
  1982. }
  1983. oh->ip=ad.s_addr;
  1984.  
  1985. if (inArray_ip_mask(ar_banned_ip,ar_mask, ad.s_addr))//если этот ip в списке уже забаненных
  1986.     return -2;
  1987.  
  1988. if (one_ip && (one_ip != oh->ip) )//если мы собираем лишь 1 IP адрес и это не тот адрес
  1989.     return -2;
  1990.  
  1991. if  ((oh->t=strToTime(m[3])) ==-1)//преобразуем время из строки в число секунд начиная с 1970
  1992. {
  1993.     return -1;
  1994. }
  1995.  
  1996. //if ( ( *m[5]=='-' ) && ( * (m[5] + 1)==0 ) ){
  1997. //    printf("408\n");
  1998. //    printf("%s\n",s);
  1999. //     return -408;
  2000. //}
  2001.  
  2002. if (!need_reqwest_info)//если ускоренный вариант, то не заполняем таблицу reqwest,referrer и user_agent
  2003. {
  2004. //    oh->num_r=0;
  2005.     return 0;
  2006. }
  2007. oh->code_otv=atoi(m[6]);
  2008.  
  2009. if (k==11)
  2010.     oh->cookie=atoi(m[10]);
  2011. else
  2012.     oh->cookie=0;
  2013.  
  2014. //printf("%s\n",m[9]);
  2015.  
  2016. //уменьшаем длину строки запроса
  2017. m[5][MAX_LEN_REQWEST-1]=0;
  2018.  
  2019. //уменьшаем длину строки реферрера
  2020. m[8][MAX_REFERRER_LEN-1]=0;
  2021.  
  2022. //уменьшаем длину строки юзер агкента
  2023. m[9][MAX_USER_AGENT_LEN-1]=0;
  2024.  
  2025. str_is=0;
  2026. new_hash=calc_hash(m[5]);
  2027. for (k=0; k < reqwest_c; k++)       //Ищем запрос в таблице запросов
  2028.     if (reqwest_hash[k] == new_hash)
  2029.     if ( !strcmp (m[5] , (*reqwest)[k] ) )  //если находим, то
  2030.     {   oh->num_r=k;            //записываем номер строки в таблице запросов
  2031.     reqv_info[k].sort_key++;    //увеличиваем счеттчик количества таких запросов
  2032.     str_is=1;
  2033.     break;
  2034.     }
  2035. if (!str_is)//если этого запроса еще не было то добавляем его
  2036. {
  2037.     if (reqwest_c >=  MAX_REQWEST_COUNT-1)
  2038.     return -1;
  2039.     reqv_info[reqwest_c].sort_key=1;    //если в таблице запросов, такого нет, до добавляем его
  2040.     reqv_info[reqwest_c].sort_data=reqwest_c;
  2041.     strcpy((* reqwest)[reqwest_c], m[5]);
  2042.    
  2043.     reqwest_hash[reqwest_c]=new_hash;
  2044.     oh->num_r=reqwest_c;
  2045.     reqwest_c++;
  2046. }
  2047. //////////////////////////////
  2048.  
  2049. str_is=0;
  2050. new_hash=calc_hash(m[8]);
  2051. for (k=0; k < referrer_c; k++)      //Ищем referrer в таблице referrer
  2052.     if (referrer_hash[k] == new_hash)
  2053.     if ( !strcmp (m[8] , (*referrer)[k] ) ) //если находим, то
  2054.     {   oh->num_ref=k;          //записываем номер строки в таблице
  2055.     referrer_info[k].sort_key++;    //увеличиваем счеттчик количества
  2056.     str_is=1;
  2057.     break;
  2058.     }
  2059.  
  2060. if (!str_is)//если этого реферрера еще не было то добавляем его
  2061. {
  2062.     if (referrer_c >=  MAX_REFERRER_COUNT-1)
  2063.     return -1;
  2064.     referrer_info[referrer_c].sort_key=1;   //если в таблице, такого нет, до добавляем его
  2065.     referrer_info[referrer_c].sort_data=referrer_c;
  2066.     strcpy((*referrer)[referrer_c], m[8]);
  2067.    
  2068.     referrer_hash[referrer_c]=new_hash;
  2069.     oh->num_ref=referrer_c;
  2070.     referrer_c++;
  2071. }
  2072. ////////////
  2073. str_is=0;
  2074. new_hash=calc_hash(m[9]);
  2075. for (k=0; k < user_agent_c; k++)        //Ищем юзер агент в таблице юзер агентов
  2076.     if (user_agent_hash[k] == new_hash)
  2077.     if ( !strcmp (m[9] , (*user_agent)[k] ) )   //если находим, то
  2078.     {   oh->num_ua=k;           //записываем номер строки в таблице юзер агентов
  2079.     user_agent_info[k].sort_key++;  //увеличиваем счеттчик количества таких юзер агентов
  2080.     str_is=1;
  2081.     break;
  2082.     }
  2083.  
  2084. if (!str_is)//если этого юзер агента еще не было то добавляем его
  2085. {
  2086.     if (user_agent_c >=  MAX_USER_AGENT_COUNT-1)
  2087.     return -1;
  2088.     user_agent_info[user_agent_c].sort_key=1;   //если в таблице юзер агентов, такого нет, до добавляем его
  2089.     user_agent_info[user_agent_c].sort_data=user_agent_c;
  2090.     strcpy((*user_agent)[user_agent_c], m[9]);
  2091.    
  2092.     user_agent_hash[user_agent_c]=new_hash;
  2093.     oh->num_ua=user_agent_c;
  2094.     user_agent_c++;
  2095. }
  2096. return 0;
  2097. }
  2098.  
  2099.  
  2100. int calcClickLastMinute(
  2101.         int logLen,
  2102.     struct oneHeat *log){
  2103. int n,  t2=0,   c=1;
  2104. time_t last_time;
  2105. if (logLen<3)
  2106.     return 0;
  2107. //printf("logLen=%d\n",logLen);
  2108. last_time=log[logLen-1].t;
  2109. for(n=logLen-2;n>=0;n--)
  2110. {   t2=last_time-log[n].t;
  2111.     if (t2>60)
  2112.     break;
  2113.     c++;
  2114. //    printf("%d  %d  %d\n",    n,log[n].code_otv, t2);
  2115. }
  2116. return c;
  2117. }
  2118.  
  2119.  
  2120. /*************************************************************************
  2121. считываем лог файл
  2122. **************************************************************************/
  2123. int readLogFile(
  2124. //входные данные
  2125.     char *logFileName,  //имя лог файла
  2126. //выходные данные
  2127.     struct oneHeat *log,    //указатель на массив структур с информацией о каждой строке лог файла
  2128.     char (*reqwest) [MAX_REQWEST_COUNT][MAX_LEN_REQWEST],//таблица вариантов запросов, запросы не повторяются
  2129.     struct sort_item reqv_info[],   //массив структур. номер строки из таблицы reqwest и количетво повторов
  2130.     int &reqwest_c,         //количество строк в таблице reqwest, равное количеству элементов в массиве reqv_info
  2131.     int &countClickLastMinute,
  2132.  
  2133.     char (*referrer) [MAX_REFERRER_COUNT][MAX_REFERRER_LEN] ,   //массив строк, в каждой строке один вариант реферрера(реферреры не повторяются)
  2134.     struct sort_item referrer_info[],   //массив структур. номер строки из таблицы referrer и количетво повторов
  2135.     int &referrer_c,    //количество строк в таблице referrer
  2136.  
  2137.     char (*user_agent) [MAX_USER_AGENT_COUNT][MAX_USER_AGENT_LEN] , //массив строк, в каждой строке один вариант юзер агента(юзер агенты не повторяются)
  2138.     struct sort_item user_agent_info[], //массив структур. номер строки из таблицы reqwest и количетво повторов, этот массив заполняется при рпаботе этой функции
  2139.     int &user_agent_c,  //количество строк в таблице user_agent
  2140.  
  2141.     int &len_time_sec,      //длина лога в секундах
  2142. //входные данные
  2143.     int *ar_banned_ip,      //массив ip которые считывать не нужно, заканчивается нулевым элементом
  2144.     int *ar_mask,           //массив масок для каждого IP из массива ar_banned_ip
  2145.     int one_ip,         //если собираем лишь 1 IP адрес, иначе 0
  2146.     int verbose,            //
  2147.     int showHeader,         //
  2148.     int need_reqwest_info//заполняем таблицу reqwest и user_agent
  2149.     ){
  2150. in_addr ad;
  2151. char *ipstr;
  2152.  
  2153. int reqwest_hash[MAX_REQWEST_COUNT];
  2154. int referrer_hash[MAX_REFERRER_COUNT];
  2155. int user_agent_hash[MAX_USER_AGENT_COUNT];
  2156.  
  2157. int logLen=0, logError=0,strLoss=0, n=0, res , err_408=0;
  2158. char s[MAX_LEN_STR+1],c,*ps;
  2159. FILE *fp;
  2160. if( (fp= fopen(logFileName,"r") ) ==NULL)
  2161. {
  2162.     printf("Error %d: %s :  %s\n",errno, logFileName, strerror(errno));
  2163.     return 0;
  2164. }
  2165. n=0; ps=s;
  2166.  
  2167. while (!feof(fp))
  2168. {   c=fgetc(fp);
  2169.     if (c!=EOF)
  2170.     {
  2171.     if (c=='\n')
  2172.     {
  2173.         *ps=0;
  2174.             if (logLen < MAX_STR_LOG)
  2175.         {  
  2176.         res=strToOneHeat(   //функция для добавления одной строки из лог файла в массивы
  2177.             s,          //добавляемая строка лог файла
  2178.             &log[logLen],
  2179.  
  2180.             reqwest,        //массив вариантов запросов
  2181.            
  2182.             reqwest_hash,   //
  2183.             referrer_hash,
  2184.             user_agent_hash,
  2185.            
  2186.             reqv_info,      //массив с информацией о количестве каждого запроса
  2187.             reqwest_c,      //Количество элементов в таблице reqwest и reqv_info
  2188.                 // количество элементов массива reqv_info, равно количеству элементов массива reqwest
  2189.  
  2190.             referrer ,  //массив строк, в каждой строке один вариант реферрера(не повторяются)
  2191.             referrer_info,
  2192.             referrer_c, //количество строк в таблице referrer и referrer_info
  2193.  
  2194.             user_agent ,    //массив строк, в каждой строке один вариант юзер агента(юзер агенты не повторяются)
  2195.             user_agent_info,
  2196.             user_agent_c,   //количество строк в таблице user_agent и user_agent_info
  2197.  
  2198.             ar_banned_ip,//массив ip которые считывать не нужно, заканчивается нулевым элементом
  2199.             ar_mask,
  2200.             one_ip, //если собираем лишь 1 IP адрес, иначе 0
  2201.             need_reqwest_info//заполняем таблицу reqwest
  2202.             );
  2203.         if (res==-1)//не верный формат строки лог файла
  2204.         {   logError++;
  2205.             if (logError<3)
  2206.                 printf("ERR: %s\n",s);
  2207.         }
  2208.         else if (res==-408)
  2209.             err_408++;
  2210.         else if (res==0)//формат верный и строка добавлена
  2211.         {
  2212.             log[logLen].len_str=strlen(s);
  2213.             logLen++;
  2214.         }
  2215.         }else
  2216.         {
  2217.         strLoss=1; //Прочитанны не все строки, так как много строк
  2218.         break;
  2219.         }
  2220.         n=0; ps=s;
  2221.     }else
  2222.     {
  2223.         if (n<MAX_LEN_STR)
  2224.         *ps++=c;
  2225.         n++;
  2226.     }
  2227.     }
  2228. }
  2229. fclose(fp);
  2230. (*reqwest)[reqwest_c][0]=0;
  2231. log[logLen].ip=0;
  2232.  
  2233. if (logLen>2)
  2234.     len_time_sec=log[logLen-1].t-log[0].t;
  2235. else
  2236.     len_time_sec=1;
  2237.  
  2238. countClickLastMinute=calcClickLastMinute(logLen,log);
  2239.  
  2240. if (verbose && showHeader)
  2241. {
  2242.     printf("Read:%d,Cm=%d,urls:%d,ref=%d,ua=%d,",logLen,countClickLastMinute,  reqwest_c,referrer_c,user_agent_c);
  2243.     if (one_ip)
  2244.     {   ad.s_addr=one_ip;
  2245.         ipstr = inet_ntoa(ad);
  2246.     printf(" Один IP=%s",ipstr);
  2247.     }
  2248.  
  2249.     if (strLoss)
  2250.     printf("(Не все)");
  2251.     if (logError)
  2252.     printf("(Не распознанно=%d)",logError);
  2253.     if (err_408)
  2254.     printf("ERR408=%d,",err_408);
  2255.     char  timeStr[20];
  2256.     myTimeToStr(&log[0].t, timeStr);
  2257.     printf(" t:%s",timeStr);
  2258.  
  2259.     if (logLen>2)
  2260.     {
  2261.     if (len_time_sec>3600*3)
  2262.         printf("-(%d h) ", (int ) len_time_sec/3600);
  2263.     else if (len_time_sec>60*3)
  2264.         printf("-(%d m) ", (int ) len_time_sec/60);
  2265.     else
  2266.         printf("-(%d s) ", (int ) len_time_sec);
  2267.     }
  2268.     printf("\n");
  2269.    
  2270. //    for (int k=0;k<30;k++)
  2271. //  printf("%d ",reqwest_hash[k]);
  2272. }
  2273. return logLen;
  2274. }
  2275. ///////////
  2276. int readBadStrs(char *fileBadStrs,char bad_strs[][MAX_LEN_BAD_STR]){
  2277.  
  2278. //printf("readBadStrs %s\n",fileBadStrs);
  2279. char s[MAX_LEN_BAD_STR],c,*ps;
  2280. int c_str=0,n;
  2281. FILE *fp;
  2282. if( (fp= fopen(fileBadStrs,"r") ) ==NULL)
  2283. {   printf("Error %d: %s :  %s\n",errno, fileBadStrs, strerror(errno));
  2284.     return -1;
  2285. }
  2286. ps=s;
  2287. while (!feof(fp))
  2288. {   c=fgetc(fp);
  2289.     if (c!=EOF)
  2290.     {
  2291.     if (c=='\n')
  2292.     {  
  2293.         *ps=0;
  2294. //      printf("s=%s\n",s);
  2295.         if (c_str<MAX_COUNT_BAD_STR)
  2296.         strcpy(bad_strs[c_str++],s);
  2297.         n=0; ps=s;
  2298.     }else
  2299.     {
  2300.         if (n<MAX_LEN_BAD_STR)
  2301.         *ps++=c;
  2302.         n++;
  2303.     }
  2304.     }
  2305. }
  2306. fclose(fp);
  2307. bad_strs[c_str][0]=0;
  2308. return c_str;
  2309. }
  2310.  
  2311. /**************************************
  2312. преобразование IP адреса с маской в тестовом формате в числовой
  2313. возвращаем
  2314.     1 - все нормально
  2315.     0 - ошибка в ip адресе
  2316.     2 - это строка слишком короткая, считаем комментарием
  2317. ***************************************/
  2318. int str2ip_mask(char *s,int &ip,int &mask){
  2319. in_addr ad;
  2320. char *p;
  2321. mask=32;
  2322. int lenStr=0;
  2323. p=s;
  2324. while(*p)//обрезаем комментарий по символу '#' или ' ', заменяея его на 0
  2325. {   lenStr++;
  2326.     if ( (*p=='#') ||  (*p==' '))
  2327.     {   *p=0;
  2328.     break;
  2329.     }
  2330.     p++;
  2331. }
  2332. if (lenStr<5)//если строка слишком корроткая, то это строка комментаий
  2333.     return 2;
  2334. p=s;
  2335. while(*p)
  2336. {
  2337.     if (*p=='/')
  2338.     {
  2339.     *p=0;
  2340.     p++;
  2341.     mask=atoi(p);
  2342.     if (mask>32)
  2343.         return 0;
  2344.     break;
  2345.     }
  2346.     p++;
  2347. }
  2348. //printf("%s \n",s);printf("%s \n",p);
  2349.  
  2350. if (inet_aton(s,&ad) )
  2351. {   ip=ad.s_addr;
  2352.     return 1;
  2353. }
  2354. else
  2355.     return 0;
  2356. }
  2357. //////////////////////////////////////////////////////////////////////////
  2358. //преобразует маску из числового формата в битовый формат       //
  2359. // /24 => 11111111.11111111.11111111.00000000               //
  2360. //результат возвращается в сетевом порядке байт             //
  2361. //////////////////////////////////////////////////////////////////////////
  2362. int maskNumToMaskNet(int mask){
  2363. int t,k;
  2364. t=0;
  2365. mask=32-mask;
  2366. for(k=0;k<mask;k++)
  2367. {   t=t<<1;
  2368.     t=t|1;
  2369. }
  2370. t=~htonl(t);
  2371. return t;
  2372. }
  2373. /////////
  2374. int readIPmask(
  2375.     char *file_name,
  2376.     int *ar_ip,
  2377.     int *ar_mask,
  2378.     int max_num_read
  2379.     ){
  2380. char s[100],c,*ps;
  2381. int c_ip=0,n=0,ip,mask, res;
  2382.  
  2383. FILE *fp;
  2384. if( (fp= fopen(file_name,"r") ) ==NULL)
  2385. {   printf("Error %d: %s :  %s\n",errno, file_name, strerror(errno));
  2386.     return -1;
  2387. }
  2388. //printf("readBannedIP = %s\n",file_name);
  2389. //in_addr ad;
  2390. //char *ipstr;
  2391. ps=s;
  2392. while (!feof(fp))
  2393. {   c=fgetc(fp);
  2394.     if (c!=EOF)
  2395.     {   if (c=='\n')
  2396.     {   *ps=0;//поставить завершающий ноль в строку
  2397. //      printf("s=%s\n",s);
  2398.         res=str2ip_mask(s,ip,mask);
  2399.         if (res==1)
  2400.         {   mask=maskNumToMaskNet(mask);
  2401.         ar_mask[c_ip]=mask;
  2402.         ar_ip[c_ip]=ip&mask;
  2403.         c_ip++;
  2404.         if (c_ip>= max_num_read)
  2405.         {   printf("too many ip/mask\n");
  2406.             ar_ip[c_ip]=0;ar_mask[c_ip]=0;
  2407.             return c_ip;
  2408.         }
  2409.         }
  2410.         else if (res==0)
  2411.         printf("Error ip/mask: %s\n",s);
  2412.         n=0; ps=s;
  2413.     }else
  2414.     {   if (n<100)
  2415.         *ps++=c;
  2416.         n++;
  2417.     }
  2418.     }
  2419. }
  2420. fclose(fp);
  2421.  
  2422. *ps=0;//поставить завершающий ноль в строку
  2423. //printf("last s=%s\n",s);
  2424. res=str2ip_mask(s,ip,mask);
  2425. if (res==1)
  2426. {   mask=maskNumToMaskNet(mask);
  2427.     ar_mask[c_ip]=mask;
  2428.     ar_ip[c_ip]=ip&mask;
  2429.     c_ip++;
  2430. }
  2431.  
  2432. ar_ip[c_ip]=0;ar_mask[c_ip]=0;
  2433. return c_ip;
  2434. }
  2435. ///////////
  2436. /*
  2437. int readBannedIP(
  2438.     char *file_banned_ip,
  2439.     int *ar_banned_ip
  2440.     ){
  2441. char s[100],c,*ps;
  2442. int c_banned_ip=0, Error=0,n=0,ip;
  2443. in_addr ad;
  2444. FILE *fp;
  2445. if( (fp= fopen(file_banned_ip,"r") ) ==NULL)
  2446. {   printf("Error %d: %s :  %s\n",errno, file_banned_ip, strerror(errno));
  2447.     return -1;
  2448. }
  2449. //printf("readBannedIP = %s\n",file_banned_ip);
  2450. ps=s;
  2451. while (!feof(fp))
  2452. {   c=fgetc(fp);
  2453.     if (c!=EOF)
  2454.     {
  2455.     if (c=='\n')
  2456.     {  
  2457.         *ps=0;
  2458. //      printf("s=%s\n",s);
  2459.         if (inet_aton(s,&ad) )  //преобразуем строковый вормат IP адреса в 4-х байтовое целое
  2460.         ar_banned_ip[c_banned_ip++]=ad.s_addr;
  2461.         n=0; ps=s;
  2462.     }else
  2463.     {
  2464.         if (n<100)
  2465.         *ps++=c;
  2466.         n++;
  2467.     }
  2468.     }
  2469. }
  2470. fclose(fp);
  2471. ar_banned_ip[c_banned_ip]=0;
  2472. return c_banned_ip;
  2473. }
  2474. */
  2475.  
  2476. //////////////
  2477. void print_ar(int *ar){
  2478. in_addr ad;
  2479. char *ipstr;
  2480. while(*ar)
  2481. {
  2482.     ad.s_addr=*ar++;
  2483.     ipstr = inet_ntoa(ad);
  2484.     printf("%s\n",ipstr);
  2485. }
  2486. }
  2487. //////////////
  2488. void print_ar_ar(int *ar,int *ar2){
  2489. in_addr ad;
  2490. char *ipstr;
  2491. while(*ar)
  2492. {
  2493.     ad.s_addr=*ar++;
  2494.     ipstr = inet_ntoa(ad);
  2495.     printf("%s",ipstr);
  2496.    
  2497.     ad.s_addr=*ar2++;
  2498.     ipstr = inet_ntoa(ad);
  2499.     printf("/%s",ipstr);
  2500.     printf("\n");
  2501. }
  2502. }
  2503.  
  2504. void print_ar_to_file(int count, int *ar, char *file_name){
  2505. in_addr ad;
  2506. char *ipstr;
  2507. FILE *fp;
  2508. if( (fp= fopen(file_name,"w") ) ==NULL)
  2509. {   printf("Error %d: %s :  %s\n",errno,file_name, strerror(errno));
  2510.     return ;
  2511. }
  2512. //printf("count2=%d\n",count);
  2513.  
  2514. while (*ar)
  2515. {
  2516.     ad.s_addr=*ar++;
  2517.     ipstr = inet_ntoa(ad);
  2518.     fputs(ipstr,fp);
  2519.  
  2520. /*
  2521.     if (count>2000)
  2522.     fputs("/16",fp);
  2523.     else if (count>1000)
  2524.     fputs("/24",fp);
  2525. */
  2526.  
  2527.     fputc('\n',fp);
  2528. }
  2529. fclose(fp);
  2530. }
  2531.  
  2532.  
  2533.  
  2534. int findBad_str(
  2535.     char (*reqwest) [MAX_REQWEST_COUNT][MAX_LEN_REQWEST],
  2536.     char bad_strs[][MAX_LEN_BAD_STR],
  2537.     struct oneHeat *log,
  2538.     int *ar_res_ip,
  2539.     int &c_ddos_ip,
  2540.  
  2541.     int *ar_white_ip,
  2542.     int *ar_white_mask
  2543.     ){
  2544. int n,n2,n3;
  2545. in_addr ad;
  2546. char *ipstr, timeStr[20];
  2547. //printf("findBad_str limit_count=%d\n",limit_count);
  2548.  
  2549. n=0;
  2550. while( (*reqwest) [n] [0] )//перебераем все строки вариантов запроса
  2551. {
  2552.     n2=0;
  2553.     while(bad_strs[n2] [0])//перебераем весь черный список
  2554.     {
  2555.     if (strcasestr( (*reqwest)[n] , bad_strs[n2]))//если строка из черного списка совподает с одной из строк запроса
  2556.     if (!strcasestr((*reqwest)[n] , "?find=" ) )//если в строке запроса нет подстроки
  2557.     {
  2558.         n3=0;
  2559.         while(log[n3].ip)//перебераем весь исходный лог в поисках строк с этим запросом
  2560.         {
  2561.         if (log[n3].num_r==n)//если нашли строку с плохим запросом
  2562.             if (!inArray_ip_mask( ar_white_ip, ar_white_mask, log[n3].ip) )
  2563.             if (!inArray(c_ddos_ip, ar_res_ip,log[n3].ip)  )
  2564.             {
  2565.                 ad.s_addr=log[n3].ip;
  2566.                 ipstr = inet_ntoa(ad);
  2567.                 myTimeToStr(&log[n3].t,timeStr);
  2568.                 printf("BadStr:%s,%s %s %s\n",bad_strs[n2],ipstr, timeStr, (*reqwest)[n]);
  2569.                 ar_res_ip[c_ddos_ip++]=log[n3].ip;
  2570.             }
  2571.         n3++;
  2572.         }
  2573.     }
  2574.     n2++;
  2575.     }
  2576.     n++;
  2577. }
  2578. ar_res_ip[c_ddos_ip]=0;
  2579. return 0;
  2580. }
  2581. //////////
  2582.  
  2583. int read_one_netstat_limit(char *s, netstat_t &netstat_limit){
  2584. //printf("read_one_netstat_limit:%s\n",s);
  2585. int n=0,n_val=0,v;
  2586. char com[10],val[10];
  2587. while(s[n] && (s[n]!='=') )
  2588. {   com[n]=s[n];   n++;
  2589. }
  2590. com[n]=0;
  2591. n++;//пропуск =
  2592. while(s[n] )
  2593. {   val[n_val]=s[n];   n_val++; n++;
  2594. }
  2595. val[n_val]=0;
  2596. v=atoi(val);
  2597. if (v<=0)
  2598.     return 0;
  2599.  
  2600. if (strcmp(com,"all")==0)
  2601.     set_all_netstat(netstat_limit,v);
  2602. else if (strcmp(com,"c")==0)
  2603.     netstat_limit.count=v;
  2604. else if (strcmp(com,"sr")==0)
  2605.     netstat_limit.c_SYN_RECV=v;
  2606. else if (strcmp(com,"est")==0)
  2607.     netstat_limit.c_ESTABLISHED=v;
  2608. else if (strcmp(com,"tw")==0)
  2609.     netstat_limit.c_TIME_WAIT=v;
  2610. else if (strcmp(com,"ss")==0)
  2611.     netstat_limit.c_SYN_SENT=v;
  2612. else if (strcmp(com,"fw1")==0)
  2613.     netstat_limit.c_FIN_WAIT1=v;
  2614. else if (strcmp(com,"fw2")==0)
  2615.     netstat_limit.c_FIN_WAIT2=v;
  2616. else if (strcmp(com,"clo")==0)
  2617.     netstat_limit.c_CLOSING=v;
  2618. else if (strcmp(com,"clw")==0)
  2619.     netstat_limit.c_CLOSE_WAIT=v;
  2620. else if (strcmp(com,"la")==0)
  2621.     netstat_limit.c_LAST_ACK=v;
  2622. else
  2623.     return 0;
  2624.  
  2625. return 1;
  2626. }
  2627. //////////
  2628. void printNS(struct netstat_t n){
  2629. printf("count=%d\n",n.count);
  2630. printf("c_SYN_RECV=%d\n",n.c_SYN_RECV);
  2631. printf("c_ESTABLISHED=%d\n",n.c_ESTABLISHED);
  2632. printf("c_TIME_WAIT=%d\n",n.c_TIME_WAIT);
  2633. printf("c_SYN_SENT=%d\n",n.c_SYN_SENT);
  2634. printf("c_FIN_WAIT1=%d\n",n.c_FIN_WAIT1);
  2635. printf("c_FIN_WAIT2=%d\n",n.c_FIN_WAIT2);
  2636. printf("c_CLOSING=%d\n",n.c_CLOSING);
  2637. printf("c_CLOSE_WAIT=%d\n",n.c_CLOSE_WAIT);
  2638. printf("c_LAST_ACK=%d\n",n.c_LAST_ACK);
  2639. }
  2640. //////////
  2641.  
  2642. /////////
  2643. int read_netstat_limit(char *s,netstat_t &netstat_limit){
  2644. char *first,*f2;
  2645. char *sub_string,*s2;
  2646. set_all_netstat(netstat_limit,0);
  2647. //printf("read_netstat_limit:%s\n",s);
  2648. first=strtok(s,",");
  2649. if (!read_one_netstat_limit(first,  netstat_limit))
  2650.     return 0;
  2651. //printf("first:%s\n",first);
  2652. while ( (sub_string=strtok(NULL, ",")) != NULL)
  2653.     if (!read_one_netstat_limit(sub_string, netstat_limit))
  2654.     return 0;
  2655.  
  2656. return 1;
  2657. }
  2658.  
  2659. int read_par_int(
  2660.     int n,
  2661.     char *argv[],
  2662.     int argc,
  2663.     char command,
  2664.     int num_par,
  2665.     struct command ar_command[],
  2666.     int &c_command){
  2667. int i;
  2668. /*printf("n=%d\n",n);
  2669. printf("argc=%d\n",argc);
  2670. printf("command=%c\n",command);
  2671. printf("num_par=%d\n",num_par);
  2672. printf("c_command=%d\n",c_command);
  2673. printf("argc-n-2=%d\n",argc-n-2);*/
  2674.  
  2675. ar_command[c_command].command=command;
  2676. if (argc-n-2<num_par)
  2677. {
  2678.     printf("Мало параметров у команды %c(%d) Должно быть=%d. argc=%d\n",command,n,num_par,argc);
  2679.     return 1;
  2680. }
  2681.  
  2682. for (i=0;i<num_par;i++)
  2683. {
  2684. //    printf("i=%d\n, n+i+1=%d \n",i, n+i+1);
  2685.     if (*(argv[n+i+1])=='-')
  2686.     {
  2687.         printf("Мало параметров (-) у команды %c(%d) Должно быть=%d. argc=%d\n",command,n,num_par,argc);
  2688.     return 1;
  2689.     }
  2690.     ar_command[c_command].par[i]=atoi(argv[n+i+1]);
  2691.     if (!ar_command[c_command].par[i])
  2692.     {
  2693.         printf("Не удалось преобразовать параметр %s в целое число у команды %c(%d) Должно быть=%d. argc=%d\n",
  2694.         argv[n+i+1],command,n,num_par,argc);
  2695.     return 1;
  2696.     }
  2697. }
  2698. c_command++;
  2699. return 0;
  2700. }
  2701.  
  2702. /***********************************************************************************
  2703. подсчитать количество разных ip адресов и разных запросов для юзерагента номер id_user_agent
  2704. ***********************************************************************************/
  2705. int calcCountForUA(
  2706.         int logLen,     //количество элементов в массиве log
  2707.         struct oneHeat *log,    //массив типа oneHeat с информацией о одной строке лог файла
  2708.         int id_user_agent,  //номер юзер агента для которого считаем количество ip
  2709.         int &count_ip,      //счетчик количества найденных ip для этого юзер агента
  2710.         int &count_r,       //счетчик количества найденных запросов для этого юзер агента
  2711.         int &count_ref
  2712.         ){
  2713. int n,          //счетчик цикла
  2714.     ar_ip[MAX_STR_LOG], //массив уже найденных ip для юзер агента
  2715.     ar_r[MAX_REQWEST_COUNT],    //массив уже найденных запросов для юзер агента
  2716.     ar_ref[MAX_REFERRER_COUNT];
  2717.    
  2718. count_ip=0;count_r=0;count_ref=0;
  2719. for(n=0;n<logLen;n++)   //пробегаем по всем строкам лог файла
  2720.     if (log[n].num_ua == id_user_agent)     //если в лог файле нашли запрос с нужным юзер агентом
  2721.     {
  2722.     if (!inArray(count_ip, ar_ip, log[n].ip ))  //если запроса с этим ip еще не было
  2723.         ar_ip[count_ip++]=log[n].ip;    //то добавляем этот запрос в массив ar_int и увеличиваем количество элементов в массиве
  2724.  
  2725.     if (!inArray(count_r, ar_r, log[n].num_r )) //если запроса этого еще не было
  2726.         ar_r[count_r++]=log[n].num_r;   //то добавляем этот запрос в массив ar_int и увеличиваем количество элементов в массиве
  2727.  
  2728.     if (!inArray(count_ref, ar_ref, log[n].num_ref ))   //
  2729.         ar_ref[count_ref++]=log[n].num_ref;     //
  2730.  
  2731.     }
  2732. }
  2733.  
  2734. /***********************************************************************************
  2735. подсчитать количество разных ip адресов,разных запросов и юзер агентов для реферрера
  2736. ***********************************************************************************/
  2737. int calcCountForRef(
  2738.         int logLen,     //количество элементов в массиве log
  2739.         struct oneHeat *log,    //массив типа oneHeat с информацией о одной строке лог файла
  2740.         int id_referrer,    //номер юзер агента для которого считаем количество ip
  2741.         int &count_ip,      //счетчик количества найденных ip для этого юзер агента
  2742.         int &count_r,       //счетчик количества найденных запросов для этого юзер агента
  2743.         int &count_ua
  2744.         ){
  2745. int n,          //счетчик цикла
  2746.     ar_ip[MAX_STR_LOG], //массив уже найденных ip для referrer
  2747.     ar_r[MAX_REQWEST_COUNT],    //массив уже найденных запросов для referrer
  2748.     ar_ua[MAX_USER_AGENT_COUNT];
  2749.    
  2750. count_ip=0;
  2751. count_r=0;
  2752. count_ua=0;
  2753. for(n=0;n<logLen;n++)   //пробегаем по всем строкам лог файла
  2754.     if (log[n].num_ref == id_referrer)      //если в лог файле нашли запрос с нужным referrer
  2755.     {
  2756.     if (!inArray(count_ip, ar_ip, log[n].ip ))  //если запроса с этим ip еще не было
  2757.         ar_ip[count_ip++]=log[n].ip;    //то добавляем этот запрос в массив ar_int и увеличиваем количество элементов в массиве
  2758.  
  2759.     if (!inArray(count_r, ar_r, log[n].num_r )) //если запроса этого еще не было
  2760.         ar_r[count_r++]=log[n].num_r;   //то добавляем этот запрос в массив ar_int и увеличиваем количество элементов в массиве
  2761.  
  2762.     if (!inArray(count_ua, ar_ua, log[n].num_ua ))  //если запроса этого еще не было
  2763.         ar_ua[count_ua++]=log[n].num_ua;    //то добавляем этот запрос в массив ar_int и увеличиваем количество элементов в массиве
  2764.     }
  2765. }
  2766.  
  2767. ///////////////////////
  2768.  
  2769. void printUserAgent(
  2770.         int logLen, //количество элементов в массиве log
  2771.         struct oneHeat *log,//массив типа oneHeat с информацией о одной строке лог файла
  2772.         char (*user_agent) [MAX_USER_AGENT_COUNT][MAX_USER_AGENT_LEN],
  2773.         struct sort_item user_agent_info[],
  2774.         int user_agent_c,
  2775.         int c_print
  2776.         ){
  2777. printf(" * TOP useragents=%d *\n",user_agent_c);
  2778. printf("c    ip  url  ref  ua\n");
  2779. int n,count_ip,count_r,count_ref;
  2780. for(n=0;n<user_agent_c;n++)
  2781. {
  2782.     if (n>=c_print)
  2783.     {
  2784.     printf("%d of %d\n",c_print,user_agent_c);
  2785.     return;
  2786.     }
  2787.    
  2788.     calcCountForUA(
  2789.     logLen,log,
  2790.     user_agent_info[n].sort_data,
  2791.     count_ip,
  2792.     count_r,
  2793.     count_ref);
  2794.  
  2795.     printf("%-4d %-3d %-4d %-4d %s\n",
  2796.     user_agent_info[n].sort_key,
  2797.     count_ip,
  2798.     count_r,
  2799.     count_ref,
  2800.     (*user_agent) [ user_agent_info[n].sort_data  ]);
  2801. }
  2802. }
  2803. ////////////////////////////////////
  2804.  
  2805. void printReferrer(
  2806.         int logLen, //количество элементов в массиве log
  2807.         struct oneHeat *log,//массив типа oneHeat с информацией о одной строке лог файла
  2808.         char (*referrer) [MAX_REFERRER_COUNT][MAX_REFERRER_LEN],
  2809.         struct sort_item referrer_info[],
  2810.         int referrer_c,
  2811.         int c_print
  2812.         ){
  2813. printf(" * TOP referrer=%d *\n",referrer_c);
  2814. printf("c    ip  url  ua    ref\n");
  2815. int n,count_ip,count_r, count_ua;
  2816. for(n=0;n<referrer_c;n++)
  2817. {
  2818.     if (n>=c_print)
  2819.     {
  2820.     printf("%d of %d\n",c_print,referrer_c);
  2821.     return;
  2822.     }
  2823.    
  2824.     calcCountForRef(
  2825.     logLen,log,
  2826.     referrer_info[n].sort_data,
  2827.     count_ip,
  2828.     count_r,
  2829.     count_ua);
  2830.  
  2831.     printf("%-4d %-3d %-4d %-4d %s\n",
  2832.     referrer_info[n].sort_key,
  2833.     count_ip,
  2834.     count_r,
  2835.     count_ua,
  2836.     (*referrer)[ referrer_info[n].sort_data  ]);
  2837. }
  2838. }
  2839.  
  2840. int calcPopravku(
  2841.     int countClickLastMinute,
  2842.     int c_click,
  2843.     int koef,
  2844.     int mode,
  2845.     char *comment_str
  2846.     ){
  2847.  
  2848. time_t timer1;
  2849. char str_time[30];
  2850.  
  2851.  
  2852. if (mode==2)
  2853. {   if (countClickLastMinute> c_click)
  2854.     {
  2855.     time(&timer1);
  2856.     myTimeToStr(&timer1,str_time);
  2857.    
  2858.     if (comment_str)
  2859.         printf("%s ",comment_str);
  2860.     printf("Get lim %d (%d)-%s\n", c_click, countClickLastMinute, str_time);
  2861.     return koef;
  2862.     }
  2863.     else
  2864.     return 0;
  2865. }else{
  2866.     if (countClickLastMinute< c_click)
  2867.     return koef;
  2868.     else
  2869.     return 0;
  2870. }
  2871. }
  2872. void make_file_next_count(
  2873.     int logLen,
  2874.     int len_time_sec,
  2875.     int need_len_time_sec,
  2876.     int min_logLen,
  2877.     char *file_name){
  2878. /*
  2879. printf("logLen=%d\n",logLen);
  2880. printf("len_time_sec=%d\n",len_time_sec);
  2881. printf("need_len_time_sec=%d\n",need_len_time_sec);
  2882. printf("min_logLen=%d\n",min_logLen);
  2883. printf("file_name=%s\n",file_name);
  2884. */
  2885.  
  2886. FILE *fp;
  2887. char str[40];
  2888. int res;
  2889. if( (fp= fopen(file_name,"w") ) ==NULL)
  2890. {   printf("Error %d: %s :  %s\n",errno,file_name, strerror(errno));
  2891.     return ;
  2892. }
  2893.  
  2894. if (len_time_sec <=0 )
  2895.     len_time_sec=1;
  2896.  
  2897. res=need_len_time_sec*logLen    /   len_time_sec;
  2898.  
  2899. if (res<min_logLen)
  2900.     res=min_logLen;
  2901.  
  2902. if (res>50000)
  2903.     res=50000;
  2904.  
  2905. sprintf(str,"%d",res);
  2906. fputs(str,fp);
  2907. //fputc('\n',fp);
  2908. fclose(fp);
  2909. }
  2910.  
  2911. //////////////////////////////////////////////////////////////////////////////////////////
  2912. //              Cтартовая функция main                   //
  2913. //////////////////////////////////////////////////////////////////////////////////////////
  2914. int main(int argc,char *argv[]){
  2915.  
  2916. time_t time_start=0,time_finish;
  2917. //time(&time_start);
  2918.  
  2919. int one_ip=0;
  2920. struct command ar_command[100];
  2921. int c_command=0;
  2922. char
  2923.     *file_banned_ip=0,
  2924.     *file_white_ip=0,
  2925.     *file_ip_res=0,
  2926.     *file_next_count=0;
  2927.  
  2928. char *comment_str=0;
  2929. char bad_strs[MAX_COUNT_BAD_STR][MAX_LEN_BAD_STR];
  2930. *bad_strs[0]=0;
  2931. int show_banned_ip;
  2932. int c_banned_ip=0, c_white_ipm=0;
  2933. int koef=0;
  2934. int countClickLastMinute;
  2935.  
  2936. int ar_white_ip  [MAX_COUNT_WHITE_IP];
  2937. int ar_white_mask[MAX_COUNT_WHITE_IP];
  2938.  
  2939. int ar_int[MAX_STR_LOG+1]//в нем сначала хранится список уже забаненных ip, потом туда добавляются найденные IP для бана
  2940.     ar_mask[MAX_STR_LOG+1],
  2941.     c_ddos_ip=0;
  2942. int verbose=1,    showHeader=1,
  2943.     do_netstat=0;
  2944. struct oneHeat *log;
  2945. struct netstat_t *netstat;
  2946. struct netstat_t netstat_limit;
  2947.  
  2948. int need_reqwest_info=0;//нужна ли таблица reqwest
  2949.  
  2950. int len_time_sec;//длина лога в секундах
  2951. int err=0;//наличие ошибки
  2952. int c_print=35;//сколько строк результата выводить на экран
  2953. int logLen, n;
  2954.  
  2955.  
  2956. //Количество элементов в таблице reqwest и reqv_info
  2957. // количество элементов массива reqv_info, равно количеству элементов массива reqwest
  2958.  
  2959. char (*reqwest) [MAX_REQWEST_COUNT][MAX_LEN_REQWEST];//массив строк для хранения вариантов запросов
  2960.  
  2961. char (*referrer) [MAX_REFERRER_COUNT][MAX_REFERRER_LEN];    //массив строк для хранения вариантов реффереров
  2962. int referrer_c=0;
  2963.  
  2964. char (*user_agent) [MAX_USER_AGENT_COUNT][MAX_USER_AGENT_LEN];  //массив строк для хранения вариантов юзер агентов
  2965. int user_agent_c=0;
  2966.  
  2967. //char reqwest [MAX_REQWEST_COUNT+1][MAX_LEN_REQWEST]; 
  2968.                 //массив элементов с информацией о количесве повторов каждого варианта запроса
  2969.  
  2970. int reqwest_c=0;
  2971.  
  2972. //  reqv_info[].sort_data;  номер элемента в таблице reqwest
  2973. //  reqv_info[].sort_key;   количество запросов
  2974. struct sort_item *reqv_info;
  2975. struct sort_item *ipInfo;
  2976. struct sort_item *user_agent_info;
  2977. struct sort_item *referrer_info;
  2978.  
  2979. int countIpInfo=0;
  2980.  
  2981. //printf("argc=%d\n",argc);
  2982.  
  2983. if ((argc==2) && (*(argv[1])=='-' ) && (*(argv[1]+1)=='v' ) )
  2984. {   printf("%d\n", VERS_PROG);
  2985. //    return 0;
  2986.     exit(0);
  2987. }
  2988.  
  2989. if (argc<=2)
  2990. {   printf("Too few params=%d\n",argc);
  2991.     exit(1);
  2992. }
  2993.  
  2994. //////////
  2995. for(n=1;n<argc-1;n++)
  2996. {
  2997.     if (*argv[n]=='-')
  2998.     {
  2999.     switch(*(argv[n]+1)  ){
  3000.     case 'i':   //топ IP
  3001.         ar_command[c_command++].command='i';
  3002.         need_reqwest_info=1;
  3003.         break;
  3004.     case 'I':   //топ IP
  3005.         ar_command[c_command++].command='I';
  3006.         need_reqwest_info=1;
  3007.         break;
  3008.     case 'h':   //
  3009.         need_reqwest_info=1;
  3010.         err=read_par_int(n,argv,argc,'h',  3,ar_command,c_command);
  3011.         break;
  3012.     case 'y'://статистика по кодам ответа
  3013.         ar_command[c_command++].command='y';
  3014.         need_reqwest_info=1;
  3015.         break;
  3016.     case 'm'://найти ip адреса превышающие количество повторов
  3017.         err=read_par_int(n,argv,argc,'m',  4,ar_command,c_command);
  3018.         need_reqwest_info=1;
  3019.         break;
  3020.     case 'c'://комментарий
  3021.         if ( (argc-n-2>=1) &&
  3022.             (*(argv[n+1])!='-')
  3023.         )
  3024.         comment_str=argv[n+1];
  3025.         else
  3026.         err=1;
  3027.         break;
  3028.     case 'n':
  3029.              do_netstat=1;
  3030.              if ( (argc-n-2>=1) &&
  3031.                   (*(argv[n+1])!='-')
  3032.         )
  3033.              {
  3034.                 if (!read_netstat_limit(argv[n+1],  netstat_limit))
  3035.             err=1;
  3036.              }else
  3037.              err=1;
  3038.          break;
  3039.     case 'g':
  3040.         time_start=1;
  3041.         break;
  3042.  
  3043.     case 'a'://все отчеты
  3044.         need_reqwest_info=1;
  3045.         ar_command[c_command++].command='i';
  3046.         ar_command[c_command++].command='u';
  3047.         ar_command[c_command++].command='y';
  3048.         ar_command[c_command++].command='e';
  3049.         ar_command[c_command++].command='U';
  3050.         c_print=20;
  3051.         break;
  3052.     case 'x':
  3053.         need_reqwest_info=1;
  3054.         err=read_par_int(n,argv,argc,'x',  2,ar_command,c_command);
  3055.         break;
  3056.     case 'A'://
  3057.         need_reqwest_info=1;
  3058.         err=read_par_int(n,argv,argc,'A',  3,ar_command,c_command);
  3059.         break;
  3060.     case 'r'://
  3061.         need_reqwest_info=1;
  3062.         err=read_par_int(n,argv,argc,'r',  2,ar_command,c_command);
  3063.         break;
  3064.     case 'R'://
  3065.         need_reqwest_info=1;
  3066.         err=read_par_int(n,argv,argc,'R',  4,ar_command,c_command);
  3067.         break;
  3068.     case 'u'://топ запросов
  3069.         need_reqwest_info=1;
  3070.         ar_command[c_command++].command='u';
  3071.         break;
  3072.     case 'U'://топ по user agent
  3073.         need_reqwest_info=1;
  3074.         ar_command[c_command++].command='U';
  3075.         break;
  3076.     case 'e'://статистика по реферрерам
  3077.         need_reqwest_info=1;
  3078.         ar_command[c_command++].command='e';
  3079.         break;
  3080.     case 's'://длинные запросы
  3081.         need_reqwest_info=1;
  3082.         err=read_par_int(n,argv,argc,'s',  3,ar_command,c_command);
  3083.         break;
  3084.     case 'z'://поиск ботов работающих без пауз
  3085.         need_reqwest_info=1;
  3086.         err=read_par_int(n,argv,argc,'z',  2,ar_command,c_command);
  3087.         break;
  3088.     case 'l'://показать исходный лог
  3089.         need_reqwest_info=1;
  3090.         ar_command[c_command++].command='l';break;
  3091.  
  3092.     case 't'://плохие слова в запросе
  3093.         need_reqwest_info=1;
  3094.         ar_command[c_command].command='t';
  3095.         if ( (argc-n-2>=1) &&
  3096.             (*(argv[n+1])!='-')
  3097.         )
  3098.         readBadStrs(argv[n+1],bad_strs);
  3099.         else
  3100.         err=1;
  3101.         c_command++;
  3102.         break;
  3103.     case 'j'://вычислить количество строк лог файла для следующего анализа
  3104.         if ( (argc-n-2>=3) && (*(argv[n+3])!='-')  ){
  3105.         file_next_count=argv[n+3];
  3106.         err=read_par_int(n,argv,argc,'j',  2,ar_command,c_command);
  3107.         }
  3108.         else
  3109.         err=1;
  3110.         break;
  3111.  
  3112.     case 'f'://сохранение в файл
  3113.         if ( (argc-n-2>=1) && (*(argv[n+1])!='-') )
  3114.         file_ip_res=argv[n+1];
  3115.         else
  3116.         err=1;
  3117.         break;
  3118.     case 'b'://список уже забаненных
  3119.         if ( (argc-n-2>=1) && (*(argv[n+1])!='-') )
  3120.         file_banned_ip=argv[n+1];
  3121.         else
  3122.         err=1;
  3123.         show_banned_ip=0;
  3124.         break;
  3125.        
  3126.     case 'w'://список белых IP и подсетей
  3127.         if ( (argc-n-2>=1) && (*(argv[n+1])!='-') )
  3128.         file_white_ip=argv[n+1];
  3129.         else
  3130.         err=1;
  3131.         break;
  3132.     case 'B'://список уже забаненных
  3133.         if ( (argc-n-2>=1) && (*(argv[n+1])!='-') )
  3134.         file_banned_ip=argv[n+1];
  3135.         else
  3136.         err=1;
  3137.         show_banned_ip=1;
  3138.         break;
  3139.     case 'o'://один IP
  3140.         need_reqwest_info=1;
  3141.         if ( (argc-n-2>=1) && (*(argv[n+1])!='-') )
  3142.         {
  3143.         in_addr ad; //структура для хранения IP адреса
  3144.         if (inet_aton(argv[n+1],&ad) ==0)   //преобразуем строковый вормат IP адреса в 4-х байтовое целое
  3145.         {    err=1;         // если формат IP не верный
  3146.             printf("Не верный IP адрес %s\n\n",argv[n+1]);
  3147.         }
  3148.         one_ip=ad.s_addr;
  3149.         }
  3150.         else
  3151.             err=1;
  3152.         break;
  3153.     case 'q':   verbose=0;  break;
  3154.     case 'k':   showHeader=0;  break;
  3155.     case 'p':  
  3156.         if ( (argc-n-2>=1) && (*(argv[n+1])!='-') )
  3157.         c_print=atoi(argv[n+1]);
  3158.         else
  3159.         err=1;
  3160.         if (!c_print)
  3161.         err=1;
  3162.         break;
  3163.     default:    printHelp();return 0;
  3164.     }
  3165.     }
  3166. }
  3167.  
  3168. ar_command[c_command].command=0;//поставить 0 после последней комманды
  3169.  
  3170. if (time_start==1)
  3171.     time(&time_start);
  3172.  
  3173. if (    err ||
  3174.     !c_command ||
  3175.     (*(argv[ argc -1 ]) == '-')
  3176.     )
  3177. {  
  3178.     printf("Error.\n");
  3179.     //printHelp();
  3180.     exit(1);
  3181. }
  3182.  
  3183.  
  3184. if (file_banned_ip)
  3185. {
  3186.     c_banned_ip=readIPmask(
  3187.     file_banned_ip,
  3188.         ar_int,
  3189.         ar_mask,
  3190.         100000);
  3191.     if (c_banned_ip== -1)
  3192.     return 0;
  3193.  
  3194.     if (showHeader)
  3195.     printf("B:%d.",c_banned_ip);
  3196.     if (show_banned_ip)
  3197.     {
  3198.     printf("\n");
  3199.     print_ar_ar(ar_int,ar_mask);
  3200.     }
  3201. }
  3202.  
  3203. ar_white_ip[0]=0;
  3204. ar_white_mask[0]=0;
  3205.  
  3206. if (file_white_ip)
  3207. {
  3208.     c_white_ipm=readIPmask(
  3209.     file_white_ip,
  3210.         ar_white_ip,
  3211.         ar_white_mask,
  3212.         MAX_COUNT_WHITE_IP);
  3213.  
  3214. //    printf("white ip\n");
  3215. //    print_ar(ar_white_ip);
  3216. //    printf("white mask\n");
  3217. //    print_ar(ar_white_mask);
  3218. }
  3219.  
  3220. ///////////
  3221. if (do_netstat)
  3222. {
  3223.     netstat= (netstat_t *) malloc(MAX_LEN_NETSTAT * sizeof(netstat_t) );
  3224.     if (!netstat) { printf("Память не выделена. 1\n\n\n");exit(1);}
  3225.  
  3226.     ipInfo    = (sort_item *) malloc((MAX_LEN_NETSTAT+1)* sizeof(sort_item) ) ;
  3227.     if (!ipInfo)  {printf("Память не выделена. 2\n\n\n");free(netstat);exit(1);}
  3228.  
  3229.     logLen=readNetstat(
  3230.     argv[ argc -1 ],
  3231.     netstat,
  3232.     countClickLastMinute,   //сюда заносим количество строк в считываемом файле(количестов коннектов)
  3233.     ipInfo, //массив для сортировки ip адресов по количеству повторений
  3234.     ar_int,//массив ранее забаненных IP
  3235.     showHeader,
  3236.     ar_white_ip,
  3237.         ar_white_mask,
  3238.         comment_str);
  3239. }
  3240. else
  3241. {
  3242.     log= (oneHeat *) malloc((MAX_STR_LOG+1)* sizeof(oneHeat) );
  3243.     if (!log)
  3244.     {   printf("Память для log выделена.\n\n\n");
  3245.     exit(1);
  3246.     }
  3247.  
  3248.     reqwest= (char (*) [MAX_REQWEST_COUNT][MAX_LEN_REQWEST]  ) malloc(  sizeof( char [MAX_REQWEST_COUNT][MAX_LEN_REQWEST] ) );
  3249.     if (!reqwest)
  3250.     {   printf("Память для reqwest выделена.\n\n\n");
  3251.     free(log);
  3252.     exit(1);
  3253.     }
  3254.  
  3255.     referrer= (char (*) [MAX_REFERRER_COUNT][MAX_REFERRER_LEN]  ) malloc(  sizeof( char [MAX_REFERRER_COUNT][MAX_REFERRER_LEN] ) );
  3256.     if (!reqwest)
  3257.     {   printf("Память для referrer выделена.\n\n\n");
  3258.     free(log);
  3259.     free(reqwest);
  3260.     exit(1);
  3261.     }
  3262.  
  3263.     user_agent= (char (*) [MAX_USER_AGENT_COUNT][MAX_USER_AGENT_LEN]  ) malloc(  sizeof( char [MAX_USER_AGENT_COUNT][MAX_USER_AGENT_LEN] ) );
  3264.     if (!reqwest)
  3265.     {   printf("Память для user_agent выделена.\n\n\n");
  3266.     free(log);
  3267.     free(reqwest);
  3268.     free(referrer);
  3269.     exit(1);
  3270.     }
  3271.  
  3272.     ipInfo    = (sort_item *) malloc((MAX_STR_LOG+1)* sizeof(sort_item) ) ;
  3273.     if (!ipInfo)
  3274.     {   printf("Память не выделена. 4\n\n\n");
  3275.     free(log);
  3276.     free(reqwest);
  3277.     free(referrer);
  3278.     free(user_agent);
  3279.     exit(1);
  3280.     }
  3281.  
  3282.     reqv_info = (sort_item *) malloc((MAX_REQWEST_COUNT+1)* sizeof(sort_item) ) ;
  3283.     if (!reqv_info)
  3284.     {   printf("Память не выделена. 2\n\n\n");
  3285.     free(log);
  3286.     free(reqwest);
  3287.     free(referrer);
  3288.     free(user_agent);
  3289.     free(ipInfo);
  3290.     exit(1);
  3291.     }
  3292.  
  3293.     referrer_info = (sort_item *) malloc((MAX_REFERRER_COUNT+1)* sizeof(sort_item) ) ;
  3294.     if (!referrer_info)
  3295.     {   printf("Память не выделена. 3\n\n\n");
  3296.     free(log);
  3297.     free(reqwest);
  3298.     free(referrer);
  3299.     free(user_agent);
  3300.     free(ipInfo);
  3301.     free(reqv_info);
  3302.     exit(1);
  3303.     }
  3304.  
  3305.     user_agent_info = (sort_item *) malloc((MAX_USER_AGENT_COUNT+1)* sizeof(sort_item) ) ;
  3306.     if (!user_agent_info)
  3307.     {   printf("Память не выделена. 3\n\n\n");
  3308.     free(log);
  3309.     free(reqwest);
  3310.     free(referrer);
  3311.     free(user_agent);
  3312.     free(ipInfo);
  3313.     free(reqv_info);
  3314.     free(referrer_info);
  3315.     exit(1);
  3316.     }
  3317.  
  3318. if (time_start)
  3319. {
  3320.     time(&time_finish);
  3321.     unsigned int time_work=time_finish - time_start;
  3322.     printf("Начало рабты =%d сек.\n", time_work);
  3323. }
  3324.  
  3325.     logLen=readLogFile(
  3326.     argv[ argc -1 ],//имя читаемого лог файла
  3327.     log,        //массив структур куда сохраняем прочитанную информацию о каждой строке запроса
  3328.  
  3329.     reqwest,    //массив строк, в каждой строке один вариант запроса(запросы не повторяются)
  3330.     reqv_info,  //массив структур. в каждой структуре номер запроса из таблицы reqwest и  количество повторов
  3331.             //нужно для дальнейшей сортировки по количеству повторов
  3332.     reqwest_c,  //количество строк в таблице reqwest, равное количеству строк в таблие reqv_info
  3333.     countClickLastMinute,
  3334.    
  3335.     referrer,   //массив строк, в каждой строке один вариант реферрера(не повторяются)
  3336.     referrer_info,  //массив структур. в каждой структуре номер запроса из таблицы referrer и количество повторов
  3337.             //нужно для дальнейшей сортировки по количеству повторов реферрера
  3338.     referrer_c, //количество строк в таблице referrer и referrer_info
  3339.             //этот массив заполняется при рпаботе этой функции
  3340.  
  3341.     user_agent, //массив строк, в каждой строке один вариант юзер агента(юзер агенты не повторяются)
  3342.     user_agent_info,//массив структур. в каждой структуре номер запроса из таблицы user_agent и количество повторов
  3343.             //нужно для дальнейшей сортировки по количеству повторов юзер агентов
  3344.             // этот массив заполняется при рпаботе этой функции
  3345.            
  3346.     user_agent_c,   //количество строк в таблице user_agent и user_agent_info
  3347.  
  3348.     len_time_sec,   //длина лога в секундах
  3349.     ar_int,     //массив уже забаненных ip, заканчивающийся нулевым элементом. Их не считываем.
  3350.     ar_mask,    //массив масок для каждого IP из массива ar_int
  3351.     one_ip,     //если считываем только 1 ip, иначе 0
  3352.     verbose,    //
  3353.     showHeader,
  3354.     need_reqwest_info//заполняем таблицу reqwest
  3355.     );
  3356.  
  3357. }
  3358. if (time_start)
  3359. {
  3360.     time(&time_finish);
  3361.     unsigned int time_work=time_finish - time_start;
  3362.     printf("Построены индексы=%d сек.\n", time_work);
  3363. }
  3364.  
  3365. ar_int[0]=0;//обнулить массив, так как до этого в нем был список уже забаненных, а теперь будет список новых забаненных
  3366.  
  3367. if ( (logLen>2)  || ((logLen>0) && do_netstat)  )
  3368. {
  3369. //    printf("c_command=%d\n",c_command);
  3370.     for (int num_command=0;num_command<c_command;num_command++)
  3371.     switch (ar_command[num_command].command){
  3372.     case 'i':
  3373.         if (do_netstat)
  3374.         {
  3375.         hoar_sort(logLen,ipInfo);
  3376.         printNetstat(
  3377.             logLen, //количество разных IP в команде netstat
  3378.             netstat,    //статистика по каждому IP
  3379.             countClickLastMinute,//количество строк прочитанное из файла(количество сокетов)
  3380.             koef,
  3381.             ipInfo, //отсортированный по количеству массив ip адресов
  3382.             c_print,    //сколько IP выводим на экран
  3383.             ar_int, //массив найденных IP заканчиваюзиеся нулевым элементом
  3384.             netstat_limit,//структура с информацией по лимитам на каждое состояние
  3385.             comment_str);//
  3386. //      printNS(netstat_limit);
  3387.         }else
  3388.         {
  3389.         countIpInfo= //количество разных ip(длина мкассива ipInfo)
  3390.             makeIpInfo( //создание массива ipInfo
  3391.             logLen, //количество элементов в массиве log
  3392.             log,    //массив типа oneHeat с информацией о одной строке лог файла
  3393.             ipInfo);//указатель на массив элементов типа sort_item, для дальнейшей сортировки IP по количеству повторений
  3394.         hoar_sort(countIpInfo,ipInfo);//сортировка массива ipInfo по количеству повторений ip
  3395.        
  3396.         showIpInfo( //
  3397.             countIpInfo,//
  3398.             ipInfo, //
  3399.             logLen, //
  3400.             log,    //
  3401.             reqwest,    //
  3402.             user_agent, //
  3403.             verbose,    //
  3404.             c_print,
  3405.             0); //
  3406.         };
  3407.         break;
  3408.     case 'I':
  3409.         countIpInfo= //количество разных ip(длина мкассива ipInfo)
  3410.             makeIpInfo( //создание массива ipInfo
  3411.             logLen, //количество элементов в массиве log
  3412.             log,    //массив типа oneHeat с информацией о одной строке лог файла
  3413.             ipInfo);//указатель на массив элементов типа sort_item, для дальнейшей сортировки IP по количеству повторений
  3414.         hoar_sort(countIpInfo,ipInfo);//сортировка массива ipInfo по количеству повторений ip
  3415.        
  3416.         showIpInfo( //
  3417.             countIpInfo,//
  3418.             ipInfo, //
  3419.             logLen, //
  3420.             log,    //
  3421.             reqwest,    //
  3422.             user_agent, //
  3423.             verbose,    //
  3424.             c_print,
  3425.             1); //
  3426.         break;
  3427.     case 'y':
  3428.         countIpInfo= //количество разных ip(длина мкассива ipInfo)
  3429.             makeCodeInfo(   //создание массива ipInfo
  3430.             logLen, //количество элементов в массиве log
  3431.             log,    //массив типа oneHeat с информацией о одной строке лог файла
  3432.             ipInfo);//указатель на массив типа sort_item, для дальнейшей сортировки IP по количеству повторений
  3433.         hoar_sort(countIpInfo,ipInfo);//сортировка массива ipInfo по количеству повторений ip
  3434.         showCodeInfo(   //
  3435.             countIpInfo,//
  3436.             ipInfo, //
  3437.             logLen, //
  3438.             log,    //
  3439.             reqwest,    //
  3440.             c_print);   //
  3441.         break;
  3442.     case 'j':
  3443.         make_file_next_count(
  3444.         logLen,
  3445.         len_time_sec,
  3446.         ar_command[num_command].par[0],
  3447.         ar_command[num_command].par[1],
  3448.         file_next_count);
  3449.         break;
  3450.     case 'U':
  3451.         hoar_sort(user_agent_c,user_agent_info);//сортировка массива user_agent_info по количеству повторений
  3452.         printUserAgent(
  3453.         logLen, //количество элементов в массиве log
  3454.         log,    //массив типа oneHeat с информацией о одной строке лог файла
  3455.         user_agent,
  3456.         user_agent_info,
  3457.         user_agent_c,
  3458.         c_print
  3459.         );
  3460.         break;
  3461.     case 'e':
  3462.         hoar_sort(referrer_c,referrer_info);//сортировка массива referrer_info по количеству повторений
  3463.         printReferrer(
  3464.         logLen, //количество элементов в массиве log
  3465.         log,    //массив типа oneHeat с информацией о одной строке лог файла
  3466.         referrer,
  3467.         referrer_info,
  3468.         referrer_c,
  3469.         c_print
  3470.         );
  3471.         break;
  3472.     case 'l':
  3473.         showOneHeat(logLen, log, reqwest, one_ip, c_print);break;
  3474.     case 'x':
  3475.         findGroupURL(
  3476.         logLen,     //количество элементов в массиве log
  3477.         log,    //массив типа oneHeat с информацией о одной строке лог файла
  3478.         reqwest_c,
  3479.         reqv_info,
  3480.         reqwest,
  3481.         ar_command[num_command].par[0],
  3482.         ar_command[num_command].par[1],
  3483.         countClickLastMinute,
  3484.         len_time_sec,
  3485.         koef,
  3486.         ar_int,
  3487.         c_ddos_ip,
  3488.  
  3489.         ar_white_ip,
  3490.         ar_white_mask
  3491.         );
  3492.         break;
  3493.     case 'u':
  3494.         hoar_sort(reqwest_c,reqv_info);
  3495.         printReqvInfo(
  3496.         logLen,     //количество элементов в массиве log
  3497.         log,    //массив типа oneHeat с информацией о одной строке лог файла
  3498.         reqwest_c,
  3499.         reqv_info,
  3500.         reqwest,
  3501.         c_print); break;
  3502.     case 'm':
  3503.         countIpInfo= //количество разных ip(длина массива ipInfo)
  3504.             makeIpInfo( //создание массива ipInfo
  3505.             logLen, //количество элементов в массиве log
  3506.             log,    //массив типа oneHeat с информацией о одной строке лог файла
  3507.             ipInfo);//указатель на массив типа sort_item, с информацией о количестве кликов каждого IP
  3508.  
  3509.         hoar_sort(countIpInfo,ipInfo);
  3510.  
  3511.         findIPbyLimit (
  3512.             logLen, //количество элементов в массиве log
  3513.             log,    //массив типа oneHeat с информацией о одной строке лог файла
  3514.        
  3515.             countIpInfo,//количество разных ip в логе
  3516.             ipInfo,
  3517.             ar_command[num_command].par[0],
  3518.             ar_command[num_command].par[1],
  3519.             ar_command[num_command].par[2],
  3520.             ar_command[num_command].par[3],
  3521.             countClickLastMinute,//количество кликов за последню минуту
  3522.             koef,
  3523.             len_time_sec,   //длина лога в секндах
  3524.        
  3525.             ar_int, //массив уже забаненных, сюда же добавляем найденных ботов
  3526.             c_ddos_ip,  //количество строк массива ar_int
  3527.        
  3528.             ar_white_ip,    //массив белого списка IP и подсетей
  3529.             ar_white_mask   //маска для массива белого списка
  3530.             );
  3531.             break;
  3532.     case 'h':
  3533.         if (!koef)
  3534.         koef=calcPopravku(
  3535.             countClickLastMinute,
  3536.             ar_command[num_command].par[0],
  3537.             ar_command[num_command].par[1],
  3538.             ar_command[num_command].par[2],
  3539.             comment_str);
  3540.         break;
  3541.  
  3542.     case 'A'://
  3543.         armagedon(
  3544.         logLen,
  3545.         log,
  3546.         ar_command[num_command].par[0],
  3547.         ar_command[num_command].par[1],
  3548.         ar_command[num_command].par[2],
  3549.         countClickLastMinute,
  3550.         countIpInfo,
  3551.         len_time_sec,
  3552. //      koef,
  3553.         ar_int,
  3554.         c_ddos_ip,
  3555.        
  3556.         ar_white_ip,
  3557.         ar_white_mask
  3558.         );
  3559.         break;
  3560.     case 't':
  3561.         findBad_str(
  3562.         reqwest,
  3563.         bad_strs,
  3564.         log,
  3565.         ar_int,
  3566.         c_ddos_ip,
  3567.  
  3568.         ar_white_ip,
  3569.         ar_white_mask
  3570.         );
  3571.         break;
  3572.     case 's':
  3573.         findLongStr(
  3574.         logLen,
  3575.         log,
  3576.         reqwest,
  3577.         ar_command[num_command].par[0],
  3578.         ar_command[num_command].par[1],
  3579.         ar_command[num_command].par[2],
  3580.         verbose,
  3581.         c_print,
  3582.         ar_int,
  3583.         c_ddos_ip
  3584.         );
  3585.         break;
  3586.     case 'z':
  3587.         findDirki(
  3588.         logLen,
  3589.         log,
  3590.         reqwest,
  3591.         ar_command[num_command].par[0],
  3592.         ar_command[num_command].par[1],
  3593.         verbose,
  3594.         c_print,
  3595.         ar_int,
  3596.         c_ddos_ip,
  3597.         ar_white_ip,
  3598.         ar_white_mask
  3599.         );
  3600.         break;
  3601.     }
  3602. }
  3603.  
  3604. if (file_ip_res)
  3605. {
  3606. //    printf("c_ddos_ip=%d\n",c_ddos_ip);
  3607. //    printf("c_banned_ip=%d\n",c_banned_ip);
  3608.  
  3609.     print_ar_to_file(
  3610.             c_ddos_ip + c_banned_ip ,
  3611.             ar_int,
  3612.             file_ip_res  );
  3613.  
  3614. }
  3615. if (do_netstat)
  3616. {
  3617.     free(netstat);
  3618.     free(ipInfo);
  3619. }
  3620. else
  3621. {
  3622.     free(log);
  3623.     free(reqwest);
  3624.     free(referrer);
  3625.     free(user_agent);    
  3626.     free(ipInfo);
  3627.     free(reqv_info);
  3628.     free(referrer_info);
  3629.     free(user_agent_info);
  3630. }
  3631.  
  3632. if (time_start)
  3633. {
  3634.     time(&time_finish);
  3635.     unsigned int time_work=time_finish - time_start;
  3636.     printf("Время рабты=%d сек.\n", time_work);
  3637. }
  3638. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement