9cbb63c5dccb71e082b30be965d577fbb1cb73cd
[demo.git] / vnfs / VES5.0 / evel / evel-library / code / VESreporting_vAFX / afx_bgpsyslog.c
1  /*****************************************************************************//***
2  * Copyright(c) <2017>, AT&T Intellectual Property.  All other rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *
7  * 1. Redistributions of source code must retain the above copyright notice,
8  *    this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright notice,
10  *    this list of conditions and the following disclaimer in the documentation
11  *    and/or other materials provided with the distribution.
12  * 3. All advertising materials mentioning features or use of this software
13  *    must display the following acknowledgement:  This product includes
14  *    software developed by the AT&T.
15  * 4. Neither the name of AT&T nor the names of its contributors may be used to
16  *    endorse or promote products derived from this software without specific
17  *    prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY AT&T INTELLECTUAL PROPERTY ''AS IS'' AND ANY
20  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22  * DISCLAIMED. IN NO EVENT SHALL AT&T INTELLECTUAL PROPERTY BE LIABLE FOR ANY
23  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  *****************************************************************************/
30
31 #include <pthread.h>
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <ctype.h>
35 #include <string.h>
36 #include <stdint.h>
37 #include <unistd.h>
38 #include <sys/stat.h>
39 #include <sys/time.h>
40 #include <sys/types.h>
41
42 #include "evel.h"
43 #include "afx_ves_reporter.h"
44
45 /* tracks syslog file */
46 static unsigned long long prevpos=0;
47 /* memory for word parsing */
48 static char ** bgp_res  = NULL;
49 /* Search list of words */
50 char* searchlist[MAX_SYSLOG_WORDS];
51 int numWords=0;
52
53 /**************************************************************************//**
54  * Sends syslog message with parsed syslog info
55  *
56  * @param info      Pointer to the line
57  * @param tag       Matched TAG field
58  * @param sevrty    Severity of parsed line Emergency etc.
59  *
60  * @retvalue  int   
61  *****************************************************************************/
62 void report_syslog( char *info, char *tag, char *sevrty )
63 {
64   EVENT_SYSLOG * psyslog = NULL;
65   EVEL_ERR_CODES evel_rc = EVEL_SUCCESS;
66   char vesevid[128];
67
68   sprintf(vesevid,"Syslog_vAfx_%s",oam_intfaddr);
69   psyslog = evel_new_syslog("Syslog_vAfx", vesevid,
70                             EVEL_SOURCE_VIRTUAL_MACHINE,
71                            escape_json(info),
72                            tag);
73   if (psyslog != NULL)
74   {
75     evel_header_type_set((EVENT_HEADER *)psyslog, "applicationVnf");
76     evel_nfnamingcode_set((EVENT_HEADER *)psyslog, "AFX");
77     evel_nfcnamingcode_set((EVENT_HEADER *)psyslog, "AFX");
78     evel_syslog_event_source_host_set(psyslog, "Virtual host");
79     evel_syslog_facility_set(psyslog, EVEL_SYSLOG_FACILITY_LOCAL0);
80     evel_syslog_proc_set(psyslog, tag);
81     //evel_syslog_proc_id_set(psyslog, 1423);
82     evel_syslog_version_set(psyslog, 1);
83     //evel_syslog_addl_filter_set(psyslog, "Name1=Value1|Name2=Value2|Name3=Value3");
84     evel_syslog_severity_set(psyslog, sevrty);
85     //evel_syslog_sdid_set(psyslog, "ourSDID@32473");
86     //evel_syslog_s_data_set(psyslog,info);
87     evel_rc = evel_post_event((EVENT_HEADER *)psyslog);
88     if (evel_rc != EVEL_SUCCESS)
89     {
90       EVEL_ERROR(" AFX: Post failed %d (%s)", evel_rc, evel_error_string());
91     }
92   }
93   else
94   {
95     EVEL_ERROR("New Syslog failed");
96   }
97   EVEL_DEBUG("AFX: Processed full Syslog\n");
98
99 }
100
101 /**************************************************************************//**
102  * Parses Syslog line for exabgp messages
103  * Raises BGP Fault event for peer connection setup and teardown
104  * Sends Syslog events for matching lines
105  *
106  * @param line      Pointer to line
107  *
108  * @retvalue  int   Returns if matching line
109  *****************************************************************************/
110 int processLine(char *line)
111 {
112     int n_spaces = 0, i;
113     char *pos;
114     char *p;
115     int srchcondn = 0;
116     int peer_conn = 0;
117     int peer_reset = 0;
118     char vesevid[128];
119     char sevrty[128];
120     char *line_bk = NULL;
121     int status = 1; /** VFA Status is ACTIVE **/
122
123    if ((pos=strchr(line, '\n')) != NULL)
124            *pos = '\0';
125    line_bk = strdup(line);
126
127    if( !strstr(line,"EVEL") && !strstr(line,"commonEventHeader")  && strstr(line,"exabgp") )
128    {
129         if( strstr(line,"Connected to peer neighbor") ) peer_conn = 1;
130         else if( strstr(line,"peer reset") ) peer_reset = 1;
131
132        if( peer_conn || peer_reset )
133        {
134         n_spaces = 0;
135         p    = strtok (line, " ");
136         /* split string and append tokens to 'res' */
137
138         while (p) {
139           bgp_res = realloc (bgp_res, sizeof (char*) * ++n_spaces);
140
141           if (bgp_res == NULL){
142             EVEL_DEBUG("Memory allocation failed");
143             exit (-1); /* memory allocation failed */
144           }
145
146           bgp_res[n_spaces-1] = p;
147
148           p = strtok (NULL, " ");
149         }
150
151         /* realloc one extra element for the last NULL */
152         bgp_res = realloc (bgp_res, sizeof (char*) * (n_spaces+1));
153         bgp_res[n_spaces] = 0;
154
155           if( n_spaces > 0 && (peer_conn || peer_reset) )
156           {
157             EVEL_DEBUG ("Exabgp %d %d %d\n", peer_conn, peer_reset, n_spaces);
158            for (i = 0; i < (n_spaces+1); ++i)
159            {
160             if( bgp_res[i] != NULL )EVEL_DEBUG ("res[%d] = %s\n", i, bgp_res[i]);
161            }
162            if( peer_conn == 1 && n_spaces >= 21 )
163             //if( !strcmp(bgp_res[21],"(out)") )
164            {
165              char buf[256];
166              EVEL_DEBUG("****************sending clear fault\n");
167              sprintf(vesevid,"Fault_vAfx_bgp_nbr_%s",oam_intfaddr);
168              sprintf(buf," %s %s %s %s %s %s %s %s %s %s %s ", bgp_res[10], bgp_res[11], bgp_res[12], bgp_res[13], bgp_res[14],bgp_res[15], bgp_res[16], bgp_res[17], bgp_res[18], bgp_res[19],  bgp_res[20]);
169              report_fault("Fault_vAfx_bgp_nbr", vesevid, EVEL_SEVERITY_NORMAL, "routing", "lo:0", "Bgp neighbor up alarm","bgp session to remote router is up",bgp_res[16],bgp_res[18],bgp_res[10], status);
170            }
171            if( peer_reset == 1 && n_spaces >= 21 )
172             //if( !strcmp(bgp_res[21],"Shutdown]") )
173            { char buf[256];
174              EVEL_DEBUG("****************sending fault\n");
175              sprintf(vesevid,"Fault_vAfx_bgp_nbr_%s",oam_intfaddr);
176              sprintf(buf," %s %s %s %s %s %s %s ", bgp_res[15], bgp_res[16], bgp_res[17], bgp_res[18], bgp_res[19],bgp_res[20], bgp_res[21]);
177                report_fault("Fault_vAfx_bgp_nbr", vesevid, EVEL_SEVERITY_MAJOR,"routing","lo:0","Bgp neighbor down alarm","bgp session to remote router is down",bgp_res[9],bgp_res[4],bgp_res[7], status);
178            }
179           }
180         }
181
182       }// end exabgp
183
184
185    if( !strstr(line_bk,"EVEL") && !strstr(line,"commonEventHeader")  && numWords > 0 ){
186      for (i=0;i<numWords;i++)
187      {
188         if( strstr(line_bk,searchlist[i]) != NULL &&
189                     strstr(line_bk,"commonEventHeader") == NULL )
190         {
191           srchcondn = 1;
192           pos = searchlist[i];
193           break;
194         }
195         printf("srch:%s:%d:%d\n",searchlist[i],srchcondn,numWords);
196      }
197
198     if( srchcondn )
199     {
200      strcpy(sevrty,"Informational");
201      if( strcasestr(line,"Emergency") != NULL ) strcpy(sevrty,"Emergency");
202      else if( strcasestr(line_bk,"Alert") != NULL ) strcpy(sevrty,"Alert");
203      else if( strcasestr(line_bk,"Critical") != NULL ) strcpy(sevrty,"Critical");
204      else if( strcasestr(line_bk,"Error") != NULL ) strcpy(sevrty,"Error");
205      else if( strcasestr(line_bk,"Warn") != NULL ) strcpy(sevrty,"Warning");
206      else if( strcasestr(line_bk,"Notice") != NULL ) strcpy(sevrty,"Notice");
207      else if( strcasestr(line_bk,"Debug") != NULL ) strcpy(sevrty,"Debug");
208      report_syslog(line_bk,pos,sevrty);
209     }
210    }
211
212   if(!srchcondn) 
213     free(line_bk);
214   return srchcondn;
215
216 }
217
218
219 /**************************************************************************//**
220  * function to read last n lines from the file
221  * at any point without reading the entire file
222  *****************************************************************************/
223 void bgp_tail(FILE* in, int n)
224 {
225     int count = 0;  // To count '\n' characters
226
227     // unsigned long long pos (stores upto 2^64 – 1
228     // chars) assuming that long long int takes 8
229     // bytes
230     unsigned long long pos;
231     char str[2*BGPBUFSIZE] = {0};
232
233     // Go to End of file
234     if (fseek(in, 0, SEEK_END))
235         perror("fseek() failed");
236     else
237     {
238         // pos will contain no. of chars in
239         // input file.
240         pos = ftell(in);
241
242         // search for '\n' characters
243         while (pos>prevpos)
244         {
245             // Move 'pos' away from end of file.
246             if (!fseek(in, --pos, SEEK_SET))
247             {
248                 if (fgetc(in) == '\n')
249
250                     // stop reading when n newlines
251                     // is found
252                     if (count++ == n)
253                         break;
254             }
255             else
256                 perror("fseek() failed");
257         }
258         //printf("pos %d prevpos %d\n",pos,prevpos);
259
260         // print last n lines
261         prevpos = pos;
262         //printf("Printing %d lines %d -\n", n,pos);
263         while (fgets(str, sizeof(str), in))
264         {
265             //printf("%s\n", str);
266             processLine(strdup(str));
267             prevpos += strlen(str);
268         }
269     }
270     //printf("\n\n");
271 }
272
273
274 /**************************************************************************//**
275  * Thread function to Monitor Syslog for BGP connections 
276  * Reads the filter words from AFX Filter input file
277  * Starts tailing syslog for BGP messages and filter words
278  *
279  * @param threadarg  Thread arguments for startup message
280  *
281  *****************************************************************************/
282 void *BgpLoggingAfxThread(void *threadarg)
283 {
284     FILE* fp;
285     int i=0,j;
286     char line[64];
287     char *pos;
288     FILE *file;
289     int taskid, sum;
290     char *hello_msg;
291     struct thread_data *my_data;
292
293    my_data = (struct thread_data *) threadarg;
294    taskid = my_data->thread_id;
295    sum = my_data->sum;
296    hello_msg = my_data->message;
297    EVEL_DEBUG("Thread %d: %s  Sum=%d\n", taskid, hello_msg, sum);
298
299    sleep(1);
300
301    /* Opens filter file and reads word list */
302    file = fopen(AFX_SYSLOG_FILE, "r");
303
304     while(fgets(line, sizeof line, file)!=NULL) {
305         //check to be sure reading correctly
306         //printf("%s", line);
307         if ((pos=strchr(line, '\n')) != NULL)
308          *pos = '\0';
309         remove_spaces(line);
310         //add each filename into array of programs
311         if( strlen(line) > 0 )
312         {
313            searchlist[numWords]=strdup(line);
314            //count number of programs in file
315            numWords++;
316         }
317     }
318     fclose(file);
319
320     //check to be sure going into array correctly
321     for (int j=0 ; j<numWords; j++) {
322         EVEL_DEBUG("Search %s\n", searchlist[j]);
323     }
324
325
326     // Open file in read mode
327     fp = fopen("/var/log/syslog", "r");
328     if (fp == NULL)
329     {
330         printf("Error while opening file");
331         exit(EXIT_FAILURE);
332     }
333
334     // call tail() each time
335     while(1)
336     {
337         // read last index lines from the file
338         bgp_tail(fp, 8);
339
340         // sleep for 3 seconds
341         // note difference in timestamps in logs
342         sleep(1);
343     }
344
345     /* close the file before ending program */
346     fclose(fp);
347
348     if( bgp_res != NULL ) free(bgp_res);
349
350     return 0;
351 }
352
353