//**************This programme is written by ZRY******************************************************* //***********************************4.16********************************************************** //Compile command gcc -o pingevent.o pingevent.c -I/usr/local/include -DBROCCOLI -L/usr/local/lib -lbroccoli #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define MAX_LINE_SIZE 1000 #define FILE_NAME_LEN 120 #define DIR_SIZE 100 #define ITEM_SIZE 100 /*************************************************Used to send event ****BEGIN**********************************************/ char *host_default = "202.197.165.216"; char *port_default = "49889"; char *host_str; char *port_str; BroConn *bc = 0; char filename[FILE_NAME_LEN]; off_t file_chars = 0; off_t parsed_lines = 0; FILE *fp2; char parsed_lines_char[64]; int restart = 0; int serialization = 0; /*************************************************Used to send event ****END**********************************************/ /*************************************************Used to parse file ****BEGIN**********************************************/ void clean_mem(unsigned char * str,int len) { int i=0; while(1) { str[i]=0; i++; if(i==len) break; } } char * set_item(unsigned char * line, unsigned char * item) { int i=0; while(*line != '\t') { item[i]=*line; i++; line++; } return ++line; } void set_value_to_Brostring(unsigned char * item, BroString *bs) { (*bs).str_val = item; (*bs).str_len = strlen(item); //printf("Value is %s, len is %d. \n",(*bs).str_val,(*bs).str_len); } void send_event(unsigned char items[6][50]) { //uint64 seq = 0; //dbg int i = 0; printf("This log is %s ;%s ;%s ;%s ;%s ;%s \n",items[0],items[1],items[2],items[3],items[4],items[5]); BroEvent *ev; BroString bs[6]; for(i = 0; i<6; i++) set_value_to_Brostring(items[i],&bs[i]); bro_conn_process_input(bc); /* Create empty "ping" event */ if ( (ev = bro_event_new("alert"))) { for(i = 0; i<6; i++) bro_event_add_val(ev, BRO_TYPE_STRING, NULL, &bs[i]); bro_event_send(bc, ev); bro_event_free(ev); } //printf("Send event over.\n"); } void parse_line(char * line) //This is the snort alert line! { file_chars += strlen(line); unsigned char items[6][50]; //6items each 50chars int i,j=0; int s=0; for(i=0; i< 6; i++) clean_mem(items[i],50); i=0; while(*line != ' ') { items[i][j]=*line; //fetch the time line++; j++; } i++;j=0; while(1) //fetch alert ID { line++; if(*line == '[' && 1 == i) { i-=1; continue; } if(*line == '[' && 0 == i) { s=1;i=1; continue; } if(s ==1 && *line == ']') break; if(s == 1) { items[i][j] = *line; j++; } } s=0;i++;j=0; while(1) { line++; if(*line == '\n') break; if(*line == '}' && *(++line) == ' ') { s=1; continue; } if(1 == s && *line == ' ' && 2==i) //No port { i+=2;j=0; items[3][0] = 'n';items[3][1] = '/';items[3][2] = 'a'; items[5][0] = 'n';items[5][1] = '/';items[5][2] = 'a'; continue; } if(1 == s && *line == ':') //Have port { i++;j=0; continue; } if(1 == s && 3 == i && *line == ' ') //stop reading the source port { i++;j=0; continue; } if(1 == s && 4 == i) //" -> " { if(*line == '-' || *line =='>' || *line == ' ') continue; } if(i == 4 && *line == ':') { i++;j=0;continue; } if(1 == s) { items[i][j] = *line; j++; } } send_event(items); } int parse_alert_file(FILE * fp) { struct stat current_file; unsigned char line[MAX_LINE_SIZE]; unsigned char temp[MAX_LINE_SIZE]; clean_mem(line,MAX_LINE_SIZE); clean_mem(temp,MAX_LINE_SIZE); if(1 == restart) { int i; FILE * fp3 = fopen("line_parsed.ct","r"); if(fp3 != NULL) //The serialization file exists. { char number[64]; clean_mem(number,64); fgets(number,64,fp3); parsed_lines = atoi(number); for(i=0; i < parsed_lines; i++) //Ignore the parsed lines. { fgets(line,MAX_LINE_SIZE,fp); file_chars += strlen(line); printf("File chars is %d!\n",file_chars); clean_mem(line,MAX_LINE_SIZE); } } file_chars++; } if(0!=stat(filename,¤t_file)) { printf("Parse file error.\n"); return -1; } //printf("File not updated4 %d --- %d!\n",current_file.st_size, file_chars); fp2 = fopen("line_parsed.ct","w"); while(1) //Start reading a new line. { if(0!=stat(filename,¤t_file)) { printf("Parse file error.\n"); return -1; } clean_mem(line,MAX_LINE_SIZE); if(current_file.st_size == file_chars) //File not updated! { printf("File not updated!\n"); sleep(1); continue; } if(NULL == fgets(line,MAX_LINE_SIZE,fp)) //Read a new line. { //printf("File not updated3 %d --- %d!\n",current_file.st_size, file_chars); sleep(1); printf("End of file! \n"); continue; } else //Get a line successfully { if(line[0] == '\n' && strlen(line) == 1) { //sleep(1); //printf("asdf"); continue; } if(0 == strlen(line) || line[strlen(line)-1] != '\n') //The line is incomplete, buffer it and parse it next time. { printf("Partial line, wait a second!.\n"); strcat(temp,line); sleep(1); printf("File not updated1!\n"); continue; } else //Complete line read { printf("Length of this line is %d \n" , strlen(line)); if(strlen(temp) != 0) //a partial line read last time. { strcat(temp,line); parse_line(temp); clean_mem(temp,MAX_LINE_SIZE); } else { parse_line(line); if(1 == serialization) //Record the number of lines log parsed. { parsed_lines+=1; //itoa(parsed_lines,parsed_lines_char,10);//stdlib.h in linux did not have a function called itoa. sprintf(parsed_lines_char,"%d",parsed_lines); fp2 = fopen("line_parsed.ct","w"); fputs(parsed_lines_char,fp2); fclose(fp2); } } } } } return 0; } void usage() { printf("pingevent - reads snort alert logs and send them to bro as events.\n" "USAGE: pingevent [-d directory] [-r] [-s] [-h]\n" " -d Set the directory.\n" " -r Entering this programme in restart mode.\n" " -s Serialize the informations while processing.\n" " -h This message.\n"); exit(0); } /*************************************************Used to parse file ****END**********************************************/ int main(int argc, char *argv[]) { int opt = 0; FILE * fp; extern char *optarg; extern int optind; clean_mem(filename,FILE_NAME_LEN); while( (opt = getopt(argc, argv, "d:rsh")) != -1) //directory, restart, serialization { switch (opt) { case 'd': memcpy(filename,optarg,strlen(optarg)); printf("File name is %s \n",filename); break; case 'r': restart++; break; case 's': serialization++; break; case 'h': usage(); break; default: usage(); } } //clean_mem(filename,FILE_NAME_LEN); clean_mem(parsed_lines_char,64); //strcat(filename,"alert");///home/dsigma/workspace/alert_CSE2007/ //memcpy(filename,argv[1],strlen(argv[1])); fp = fopen(filename,"r"); if(NULL == fp) { printf("Open file error. \n"); return -1; } /***************************************From broping*******************************************************/ int port; char hostname[512]; int fd = -1; bro_init(NULL); host_str = host_default; port_str = port_default; port = strtol(port_str, NULL, 0); snprintf(hostname, 512, "%s:%s", host_str, port_str); if (! (bc = bro_conn_new_str(hostname, BRO_CFLAG_RECONNECT | BRO_CFLAG_ALWAYS_QUEUE))) { printf("Could not get Bro connection handle.\n"); exit(-1); } if (! bro_conn_connect(bc)) { printf("Could not connect to Bro at %s:%s.\n", host_str, port_str); exit(-1); } //send_alert_event(); parse_alert_file(fp); /* Disconnect from Bro and release state. */ bro_conn_delete(bc); return 0; }