Вот код.
Код: Выделить всё
#include <pcap.h>
#include <stdio.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <net/ethernet.h>
#include <netinet/ip.h>
#include <netinet/udp.h>
#include <my_global.h>
#include <mysql.h>
#include <errmsg.h>
#include <mysqld_error.h>
#include <time.h>
#include <string.h>
#define INTERVAL 10
int howmany = 0;
const char *server = "xxxxxxxx";
const char *user = "xxxxx";
const char *password = "xxxxxxxx";
const char *database = "xxxxxxx";
MYSQL conn;
void dispatcher_handler(u_char *dumpfile,const struct pcap_pkthdr *header, const u_char *pkt_data);
void puterror(const char * str);
void alarm_wakeup (int i);
void exit_func (int i);
char * get_local_ips(char * filter);
int main(int argc, char *argv[])
{
pcap_t *handle; /* Session handle */
char *dev; /* The device to sniff on */
char *somedev;
char errbuf[PCAP_ERRBUF_SIZE]; /* Error string */
struct bpf_program fp; /* The compiled filter */
char filter_exp[1024] = "udp dst port 4000"; /* The filter expression */
bpf_u_int32 mask; /* Our netmask */
bpf_u_int32 net; /* Our IP */
struct pcap_pkthdr header; /* The header that pcap gives us */
const u_char *packet; /* The actual packet */
struct itimerval tout_val;
tout_val.it_interval.tv_sec = 0;
tout_val.it_interval.tv_usec = 0;
tout_val.it_value.tv_sec = INTERVAL; /* 10 seconds timer */
tout_val.it_value.tv_usec = 0;
setitimer(ITIMER_REAL, &tout_val,0);
signal(SIGALRM,alarm_wakeup); /* set the Alarm signal capture */
signal(SIGINT,exit_func);
get_local_ips(filter_exp);
//printf("%s\n", filter_exp);
if(!mysql_init(&conn)) puterror("Error: can't create MySQL-descriptor\n");
if(!mysql_real_connect(&conn, server, user, password, database, 0, NULL, 0)) puterror("Error: can't connect to MySQL server\n");
if(mysql_query(&conn, "SET NAMES 'cp1251'") != 0)
{
// Если кодировку установить невозможно - выводим сообщение об ошибке
fprintf(stderr, "Error: can't set character set\n");
}
dev = pcap_lookupdev(errbuf);
if (dev == NULL)
{
fprintf(stderr, "Couldn't find default device: %s\n", errbuf);
return(2);
}
/* Find the properties for the device */
if (pcap_lookupnet(dev, &net, &mask, errbuf) == -1)
{
fprintf(stderr, "Couldn't get netmask for device %s: %s\n", dev, errbuf);
net = 0;
mask = 0;
}
/* Open the session in promiscuous mode */
handle = pcap_open_live(dev, BUFSIZ, 1, 1000, errbuf);
if (handle == NULL)
{
fprintf(stderr, "Couldn't open device %s: %s\n", somedev, errbuf);
return(2);
}
/* Compile and apply the filter */
if (pcap_compile(handle, &fp, filter_exp, 0, net) == -1)
{
fprintf(stderr, "Couldn't parse filter %s: %s\n", filter_exp, pcap_geterr(handle));
return(2);
}
if (pcap_setfilter(handle, &fp) == -1)
{
fprintf(stderr, "Couldn't install filter %s: %s\n", filter_exp, pcap_geterr(handle));
return(2);
}
pcap_loop(handle, -1, dispatcher_handler, NULL);
return(0);
}
void dispatcher_handler(u_char *dumpfile,
const struct pcap_pkthdr *header, const u_char *pkt_data)
{
struct ether_header *eptr;
u_char *ptr;
u_int i=0;
u_int datalen=0;
u_int size_ip=0;
u_int size_udp=0;
struct ip *ips;
struct udphdr *udp;
char *addr;
char *dt;
struct timeval timev;
char sql[4096];
char sms[4096];
MYSQL_RES *res;
MYSQL_ROW row;
time_t rawtime;
time (&rawtime);
struct tm * timeinfo;
timeinfo = localtime (&rawtime) ; /* to access LOCAL date/time info*/
char cur_time [128] ;
eptr = (struct ether_header *) pkt_data;
ips = (struct ip*)(pkt_data + sizeof(struct ether_header));
udp = (struct udphdr*)(pkt_data + sizeof(struct ether_header) + sizeof(struct ip));
dt = (char*)(pkt_data + sizeof(struct ether_header) + sizeof(struct ip) + sizeof(struct udphdr));
timev = header->ts;
//printf("%d.%d %s %d\n", timev.tv_sec, timev.tv_usec, inet_ntoa(ips->ip_src), (unsigned char)dt[i]);
//-------------------------------------------------------------------------
snprintf(sql, sizeof(sql), "SELECT * FROM pingovalka_main WHERE ip='%s'", inet_ntoa(ips->ip_src));
if(mysql_query(&conn, sql) != 0)
{
fprintf(stderr, "%s\n", mysql_error(&conn));
puterror("Error: can't execute SQL-query\n");
}
// Получаем дескриптор результирующей таблицы
res = mysql_store_result(&conn);
if(res == NULL) puterror("Error: can't get the result description\n");
// Если нашли пинговалку идем дальше
if(mysql_num_rows(res) > 0)
{
// В цикле перебираем все записи результирующей таблицы
while((row = mysql_fetch_row(res)) != NULL)
{
//Сначала проверим если открытая сессия... А то вдруг наша пинговалка восстала из мертвых
int status = atoi(row[6]); // on_line 0 or 1
int sendsms = atoi(row[5]); //А нужно ли слать смску
if (status!=1) //если мы не on_line то делаем новую сессию
{
snprintf(sql, sizeof(sql), "INSERT INTO pingovalka_sessions (ping_id, session_begin, bit) VALUES ('%s', '%d', '%d')", row[0], timev.tv_sec, (unsigned char)dt[i]);
if(mysql_query(&conn, sql) != 0)
{
fprintf(stderr, "Error: can't create new session\n");
}
//Send SMS UP
if (sendsms !=0) //Нужно
{
snprintf(sql, sizeof(sql), "INSERT INTO pingovalka_sms_send (time, phone, text) SELECT NOW(), \
user_phone, '%s UP' FROM pingovalka_sms ps, tbl_members tm \
WHERE ps.member_id=tm.user_id AND ps.ping_id='%s'", row[1], row[0]);
if(mysql_query(&conn, sql) != 0)
{
fprintf(stderr, "Error: can't insert SMS task\n");
}
}
//End SMS
}
//Сморим не изменился ли BIT у данной пинговалки
int new_bits=(unsigned char)dt[i];
int old_bits = atoi(row[4]); // int atoi(const char* str)
if( old_bits != new_bits)
{
//Если биты не совпали то закрываем текущую сессию
snprintf(sql, sizeof(sql), "UPDATE pingovalka_sessions SET session_end='%d' \
WHERE ping_id='%s' AND session_end=''", timev.tv_sec, row[0]);
if(mysql_query(&conn, sql) != 0)
{
fprintf(stderr, "Error: can't close session by bits\n");
}
//А теперь открываем новую с новым битом
snprintf(sql, sizeof(sql), "INSERT INTO pingovalka_sessions (ping_id, session_begin, bit) \
VALUES ('%s', '%d', '%d')", row[0], timev.tv_sec, (unsigned char)dt[i]);
if(mysql_query(&conn, sql) != 0)
{
fprintf(stderr, "Error: can't create new session\n");
}
if (sendsms !=0) //Нужно
{
///Send SMS
int BIT1 = 1;
int BIT2 = 1 << 1;
int BIT3 = 1 << 2;
int BIT4 = 1 << 3;
if((old_bits & BIT3)!=(new_bits & BIT3))
{
if (new_bits & BIT3)
{
strcat(sms, "Door Close ");
}
else
{
strcat(sms, "Door Open ");
}
}
if((old_bits & BIT4)!=(new_bits & BIT4))
{
if (new_bits & BIT4)
{
strcat(sms, "Power UP");
}
else
{
strcat(sms, "Power DOWN");
}
}
//Send SMS UP
snprintf(sql, sizeof(sql), "INSERT INTO pingovalka_sms_send (time, phone, text) SELECT NOW(), \
user_phone, '%s %s' FROM pingovalka_sms ps, tbl_members tm \
WHERE ps.member_id=tm.user_id AND ps.ping_id='%s'", row[1], sms, row[0]);
if(mysql_query(&conn, sql) != 0)
{
fprintf(stderr, "Error: can't close session by time\n");
}
strcpy(sms,"");
///END OF SEND SMS
}
}
//Если биты совпали то просто обновляем данные по пинговалке
snprintf(sql, sizeof(sql), "UPDATE pingovalka_main SET last_packet_time='%d', on_line=1, bit='%d' \
WHERE id='%s'", timev.tv_sec, (unsigned char)dt[i], row[0]);
if(mysql_query(&conn, sql) != 0)
{
fprintf(stderr, "Error: can't update pingovalka info\n");
}
}
}
else
{
//Если пинговалки нет то создаём её
strftime (cur_time, 128 , "%Y-%m-%d" , timeinfo);
snprintf(sql, sizeof(sql), "INSERT INTO pingovalka_main (adress, ip, last_packet_time, bit, sendsms, on_line, hiden) \
VALUES ('AUTO-%s', '%s', '%d', '%d','1', '1', '0')", cur_time, inet_ntoa(ips->ip_src), timev.tv_sec, (unsigned char)dt[i]);
if(mysql_query(&conn, sql) != 0)
{
fprintf(stderr, "Error: can't execute INSERT-query\n");
fprintf (stderr, sql);
}
//Создали в таблице pingovalka_main
//Получаем id только что вставленной записи
snprintf(sql, sizeof(sql), "SELECT id FROM pingovalka_main WHERE ip='%s' LIMIT 1", inet_ntoa(ips->ip_src));
if(mysql_query(&conn, sql) != 0) puterror("Error: can't execute SQL-query Select ID NEW\n");
// Получаем дескриптор результирующей таблицы
res = mysql_store_result(&conn);
if(res == NULL) puterror("Error: can't get the result description\n");
row = mysql_fetch_row(res);
//И создаём для неё сессию с временем начала её работы
snprintf(sql, sizeof(sql), "INSERT INTO pingovalka_sessions (ping_id, session_begin, bit) VALUES ('%s', '%d', '%d')", row[0], timev.tv_sec, (unsigned char)dt[i]);
if(mysql_query(&conn, sql) != 0)
{
fprintf(stderr, "Error: can't execute INSERT-query\n");
}
}
mysql_free_result(res);
//-------------------------------------------------------------------------
datalen = ntohs(ips->ip_len) - sizeof(struct ip) - sizeof(struct udphdr);
}
void puterror(const char * str)
{
fprintf(stderr, str);
}
void alarm_wakeup (int i)
{
struct itimerval tout_val;
char sql[4096];
MYSQL conn_timer;
MYSQL_RES *res_timer;
MYSQL_ROW row_timer;
signal(SIGALRM,alarm_wakeup);
howmany += INTERVAL;
if(!mysql_init(&conn_timer)) puterror("Error: can't create MySQL-descriptor\n");
if(!mysql_real_connect(&conn_timer, server, user, password, database, 0, NULL, 0)) puterror("Error: can't connect to MySQL server\n");
if(mysql_query(&conn_timer, "SET NAMES 'cp1251'") != 0)
{
// Если кодировку установить невозможно - выводим сообщение об ошибке
fprintf(stderr, "Error: can't set character set\n");
}
//Теперь смотрим если у какой то пинговалки не было в течении 2-х минут ни одного пакета, то присваиваем ей статус offline и закрываем сессию
if(mysql_query(&conn_timer, "SELECT * FROM pingovalka_main WHERE (last_packet_time < (unix_timestamp()-130)) AND on_line=1") != 0)
puterror("Error: can't get offline ping\n");
// Получаем дескриптор результирующей таблицы
res_timer = mysql_store_result(&conn_timer);
if(res_timer == NULL) puterror("Error: can't get the result description\n");
// Если нашли пинговалку идем дальше
if(mysql_num_rows(res_timer) > 0)
{
// В цикле перебираем все записи результирующей таблицы
while((row_timer = mysql_fetch_row(res_timer)) != NULL)
{
int sendsms = atoi(row_timer[5]); //А нужно ли слать смску
//присваиваем ей статус offline
snprintf(sql, sizeof(sql), "UPDATE pingovalka_main SET on_line=0 WHERE id='%s'", row_timer[0]);
if(mysql_query(&conn_timer, sql) != 0)
{
fprintf(stderr, "Error: can't execute INSERT-query\n");
}
//Закрываем её текущую сессию
snprintf(sql, sizeof(sql), "UPDATE pingovalka_sessions SET session_end=UNIX_TIMESTAMP() \
WHERE ping_id='%s' AND session_end=''", row_timer[0]);
if(mysql_query(&conn_timer, sql) != 0)
{
fprintf(stderr, "Error: can't close session by time\n");
}
if (sendsms !=0) //Нужно
{
//Add record to send sms
snprintf(sql, sizeof(sql), "INSERT INTO pingovalka_sms_send (time, phone, text) SELECT NOW(), \
user_phone, '%s Down' FROM pingovalka_sms ps, tbl_members tm \
WHERE ps.member_id=tm.user_id AND ps.ping_id='%s'",row_timer[1], row_timer[0]);
if(mysql_query(&conn_timer, sql) != 0)
{
fprintf(stderr, "Error: can't close session by time\n");
}
}
}
}
mysql_free_result(res_timer);
mysql_close(&conn_timer);
tout_val.it_interval.tv_sec = 0;
tout_val.it_interval.tv_usec = 0;
tout_val.it_value.tv_sec = INTERVAL;
tout_val.it_value.tv_usec = 0;
setitimer(ITIMER_REAL, &tout_val,0);
}
void exit_func (int i)
{
signal(SIGINT,exit_func);
mysql_close(&conn);
printf("\nBye Bye!!!\n");
exit(0);
}
char * get_local_ips(char * filter)
{
FILE *fpipe;
char *command="ifconfig | grep -E 'inet.[0-9]' | awk '{ print $2}'";
char local_ip[256];
if (!(fpipe = (FILE*)popen(command,"r")))
{
perror("Problems with pipe");
}
while(fgets(local_ip, sizeof local_ip, fpipe))
{
strcat(filter, " and not src host ");
local_ip[strlen(local_ip)-1]=0;
strcat(filter, local_ip);
}
pclose(fpipe);
return filter;
}
Код: Выделить всё
link_flags:= -I/usr/local/include/mysql
ping_d: ping_d.o
g++ ping_d.o -o ping_d -lpcap -L/usr/local/lib/mysql -lmysqlclient
ping_d.o: ping_d.cpp
g++ -c $(link_flags) ping_d.cpp
clean:
rm *.o
Код: Выделить всё
mysql> DESCRIBE pingovalka_main;
+------------------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------------+------------------+------+-----+---------+----------------+
| id | int(11) unsigned | NO | PRI | NULL | auto_increment |
| adress | varchar(255) | NO | | NULL | |
| ip | varchar(18) | NO | | NULL | |
| last_packet_time | varchar(255) | NO | | NULL | |
| bit | int(2) | NO | | 0 | |
| sendsms | tinyint(1) | NO | | NULL | |
| on_line | tinyint(1) | NO | | 0 | |
| hiden | tinyint(1) | NO | | 0 | |
| def_bit | int(2) | NO | | 0 | |
+------------------+------------------+------+-----+---------+----------------+
mysql> DESCRIBE pingovalka_sessions;
+---------------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------------+------------------+------+-----+---------+----------------+
| session_id | int(11) unsigned | NO | PRI | NULL | auto_increment |
| ping_id | int(11) | NO | | NULL | |
| session_begin | varchar(255) | NO | | NULL | |
| session_end | varchar(255) | NO | | NULL | |
| bit | tinyint(2) | NO | | NULL | |
+---------------+------------------+------+-----+---------+----------------+
mysql> DESCRIBE pingovalka_sms;
+-----------+---------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------+---------+------+-----+---------+----------------+
| id_record | int(11) | NO | PRI | NULL | auto_increment |
| ping_id | int(11) | NO | | NULL | |
| member_id | int(11) | NO | | NULL | |
+-----------+---------+------+-----+---------+----------------+
mysql> DESCRIBE pingovalka_sms_send;
+--------+----------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------+----------------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| time | varchar(100) | NO | | NULL | |
| phone | varchar(20) | NO | | NULL | |
| text | varchar(160) | NO | | NULL | |
| status | smallint(1) unsigned | NO | | 0 | |
+--------+----------------------+------+-----+---------+----------------+
Ткните плиз где тут бред написан и отчего программка может зависать