Initial commit
[com/gs-lite.git] / include / lfta / schema_prototypes.h
1 #ifndef __SCHEMA_PROTOTYPES__
2 #define __SCHEMA_PROTOTYPES__
3
4 /* ------------------------------------------------
5  Copyright 2014 AT&T Intellectual Property
6  Licensed under the Apache License, Version 2.0 (the "License");
7  you may not use this file except in compliance with the License.
8  You may obtain a copy of the License at
9  
10  http://www.apache.org/licenses/LICENSE-2.0
11  
12  Unless required by applicable law or agreed to in writing, software
13  distributed under the License is distributed on an "AS IS" BASIS,
14  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  See the License for the specific language governing permissions and
16  limitations under the License.
17  ------------------------------------------- */
18
19
20 #define PRECOMP
21 #include "gsconfig.h"
22 #include "gstypes.h"
23
24 #include "fta.h"
25 #include "rts_external.h"
26 #include "packet.h"
27 #include "md_stdlib.h"
28 #include "schemaparser.h"
29
30
31 // *** SAMPLING RELATED CONSTANTS
32 // ******************************
33
34 // Make sure the hash table sizes are powers of 2-1 since they are used to compute the module with an and.
35 // collions on the flow hash are handled properly so they are not that bad
36 #define MAX_FLOWRECORD_HASH 0x1fffff
37 // keep the collision rate low on denies
38 #define MAX_DENY_HASH 0x7fffff
39 // one out of SAMPLING_RATE+1 sampling
40 #define SAMPLING_RATE 19
41 // sampling probability
42 #define FLOWSAMPPROB (((gs_float_t)1)/((gs_float_t)SAMPLING_RATE+1))
43 // wait for SAMPLED_FLOW_TIMEOUT  seconds idle time to time a flow out
44 #define SAMPLED_FLOW_TIMEOUT 30
45 // check if we haven't seen that flow in SAMPLED_FLOW_IDLE_TIME seconds to make sure we don't catch it in the midle
46 #define SAMPLED_FLOW_IDLE_TIME 30
47
48 // PACKET SAMPLING RATE one in SAMPLED_PACKETS will be sampled
49 #define SAMPLED_PACKETS 200
50 // SAMPLING probability
51 #define PACKETSAMPPROB (((gs_float_t)1)/((gs_float_t)SAMPLED_PACKETS))
52
53 // COMBINE probability
54 #define COMBINEDPROB (((gs_float_t)1)-(((gs_float_t)1)-FLOWSAMPPROB)*(((gs_float_t)1)-PACKETSAMPPROB))
55
56 /* General packet access functions */
57
58 static inline gs_retval_t get_system_time(struct packet * p, gs_uint32_t * t)
59 {
60         *t=(gs_uint32_t) p->systemTime;
61         return 0;
62 }
63
64 /* CSV access function using position as 3rd argument */
65
66 static inline gs_retval_t get_csv_uint(struct packet * p, gs_uint32_t * t,gs_uint32_t pos)
67 {
68         if (p->ptype != PTYPE_CSV) return -1;
69         if (p->record.csv.numberfields < pos) return -1;
70     *t = strtoul((const char*)p->record.csv.fields[pos-1], NULL, 10);
71         return 0;
72 }
73
74 static inline gs_retval_t get_csv_ullong(struct packet * p, gs_uint64_t * t,gs_uint32_t pos)
75 {
76     if (p->ptype != PTYPE_CSV) return -1;
77     if (p->record.csv.numberfields < pos) return -1;
78     *t = strtoull((const char*)p->record.csv.fields[pos-1], NULL, 10);    
79     return 0;
80 }
81
82 static inline gs_retval_t get_csv_ip(struct packet * p, gs_uint32_t * t,gs_uint32_t pos)
83 {
84         unsigned ip1,ip2,ip3,ip4;
85     if (p->ptype != PTYPE_CSV) return -1;
86     if (p->record.csv.numberfields < pos) return -1;
87     sscanf((const char*) p->record.csv.fields[pos-1],"%u.%u.%u.%u",&ip1,&ip2,&ip3,&ip4);
88         *t=(ip1<<24)|(ip2<<16)|(ip3<<8)|ip4;
89     return 0;
90 }
91 static inline gs_retval_t get_csv_ipv6(struct packet * p, struct ipv6_str * t,gs_uint32_t pos)
92 {
93     gs_uint32_t v[8];
94         if (p->ptype != PTYPE_CSV) return -1;
95     if (p->record.csv.numberfields < pos) return -1;
96     sscanf((const char*) p->record.csv.fields[pos-1],"%x:%x:%x:%x:%x:%x:%x:%x",&v[0],&v[1],&v[2],&v[3],&v[4],&v[5],&v[6],&v[7]);
97         t->v[0]=htonl(v[0]<<16|v[1]);
98         t->v[1]=htonl(v[2]<<16|v[3]);
99         t->v[2]=htonl(v[4]<<16|v[5]);
100         t->v[3]=htonl(v[6]<<16|v[7]);
101         
102     return 0;
103 }
104 static inline gs_retval_t get_csv_string(struct packet * p, struct gs_string * t,gs_uint32_t pos)
105 {
106     
107     if (p->ptype != PTYPE_CSV) return -1;
108     if (p->record.csv.numberfields < pos) return -1;
109         t->data=(gs_sp_t)p->record.csv.fields[pos-1];
110     if (pos == p->record.csv.numberfields)
111         t->length=strlen((const char*)p->record.csv.fields[pos-1]);
112     else
113         t->length=p->record.csv.fields[pos] - p->record.csv.fields[pos-1] - 1;
114         t->owner=0;
115     return 0;
116 }
117 static inline gs_retval_t get_csv_bool(struct packet * p, gs_uint32_t * t,gs_uint32_t pos)
118 {
119     if (p->ptype != PTYPE_CSV) return -1;
120     if (p->record.csv.numberfields < pos) return -1;
121         *t=0;
122         if ((strlen((const char*)p->record.csv.fields[pos-1])==4) &&
123                 (strncasecmp("TRUE",(const char*)p->record.csv.fields[pos-1],4) ==0) ) {
124                 *t=1;
125         }
126     return 0;
127 }
128 static inline gs_retval_t get_csv_int(struct packet * p, gs_int32_t * t,gs_uint32_t pos)
129 {
130     if (p->ptype != PTYPE_CSV) return -1;
131     if (p->record.csv.numberfields < pos) return -1;
132     *t = strtol((const char*)p->record.csv.fields[pos-1], NULL, 10);
133     return 0;
134 }
135 static inline gs_retval_t get_csv_llong(struct packet * p, gs_int64_t * t,gs_uint32_t pos)
136 {
137     if (p->ptype != PTYPE_CSV) return -1;
138     if (p->record.csv.numberfields < pos) return -1;
139     *t = strtoll((const char*)p->record.csv.fields[pos-1], NULL, 10);
140     return 0;
141 }
142 static inline gs_retval_t get_csv_float(struct packet * p, gs_float_t * t,gs_uint32_t pos)
143 {
144     if (p->ptype != PTYPE_CSV) return -1;
145     if (p->record.csv.numberfields < pos) return -1;
146     *t = strtod((const char*)p->record.csv.fields[pos-1], NULL);
147     return 0;
148 }
149
150 #include <lfta/csv_macro.h>
151
152 static inline __attribute__((always_inline)) unsigned int gs_strtoul (const char *str, size_t len) {
153         unsigned int value = 0;
154
155         switch (len) { // handle up to 10 digits, assume we're 32-bit
156             case 10:    value += (str[len-10] - '0') * 1000000000;
157             case  9:    value += (str[len- 9] - '0') * 100000000;
158             case  8:    value += (str[len- 8] - '0') * 10000000;
159             case  7:    value += (str[len- 7] - '0') * 1000000;
160             case  6:    value += (str[len- 6] - '0') * 100000;
161             case  5:    value += (str[len- 5] - '0') * 10000;
162             case  4:    value += (str[len- 4] - '0') * 1000;
163             case  3:    value += (str[len- 3] - '0') * 100;
164             case  2:    value += (str[len- 2] - '0') * 10;
165             case  1:    value += (str[len- 1] - '0');
166                 return value;
167             default:
168                 return 0;
169         }
170 }
171
172 static inline __attribute__((always_inline)) unsigned long long gs_strtoull (const char *str, size_t len) {
173         unsigned long long value = 0;
174
175         switch (len) { // handle up to 10 digits, assume we're 32-bit
176             case 20:    value += (str[len-20] - '0') * 10000000000000000000UL;
177             case 19:    value += (str[len-19] - '0') * 1000000000000000000UL;
178             case 18:    value += (str[len-18] - '0') * 100000000000000000UL;
179             case 17:    value += (str[len-17] - '0') * 10000000000000000UL;
180             case 16:    value += (str[len-16] - '0') * 1000000000000000UL;
181             case 15:    value += (str[len-15] - '0') * 100000000000000UL;
182             case 14:    value += (str[len-14] - '0') * 10000000000000UL;
183             case 13:    value += (str[len-13] - '0') * 1000000000000UL;
184             case 12:    value += (str[len-12] - '0') * 100000000000UL;
185             case 11:    value += (str[len-11] - '0') * 10000000000UL;
186             case 10:    value += (str[len-10] - '0') * 1000000000UL;
187             case  9:    value += (str[len- 9] - '0') * 100000000UL;
188             case  8:    value += (str[len- 8] - '0') * 10000000UL;
189             case  7:    value += (str[len- 7] - '0') * 1000000UL;
190             case  6:    value += (str[len- 6] - '0') * 100000UL;
191             case  5:    value += (str[len- 5] - '0') * 10000UL;
192             case  4:    value += (str[len- 4] - '0') * 1000UL;
193             case  3:    value += (str[len- 3] - '0') * 100UL;
194             case  2:    value += (str[len- 2] - '0') * 10UL;
195             case  1:    value += (str[len- 1] - '0');
196                 return value;
197             default:
198                 return 0;
199         }
200 }
201
202 static inline gs_retval_t get_csv2_uint(struct packet * p, gs_uint32_t * t,gs_uint32_t pos)
203 {
204 //    *t = strtoul((const char*)p->record.csv2.fields[pos-1], NULL, 10);
205     *t = gs_strtoul((const char*)p->record.csv2.fields[pos-1], p->record.csv2.field_lens[pos-1]);
206     
207         return 0;
208 }
209
210 static inline gs_retval_t get_csv2_ullong(struct packet * p, gs_uint64_t * t,gs_uint32_t pos)
211 {
212 //    *t = strtoull((const char*)p->record.csv2.fields[pos-1], NULL, 10);    
213     *t = gs_strtoull((const char*)p->record.csv2.fields[pos-1], p->record.csv2.field_lens[pos-1]);
214     return 0;
215 }
216
217 static inline gs_retval_t get_csv2_ip(struct packet * p, gs_uint32_t * t,gs_uint32_t pos)
218 {
219         unsigned ip1,ip2,ip3,ip4;
220     sscanf((const char*) p->record.csv2.fields[pos-1],"%u.%u.%u.%u",&ip1,&ip2,&ip3,&ip4);
221         *t=(ip1<<24)|(ip2<<16)|(ip3<<8)|ip4;
222     return 0;
223 }
224 static inline gs_retval_t get_csv2_ipv6(struct packet * p, struct ipv6_str * t,gs_uint32_t pos)
225 {
226     gs_uint32_t v[8];
227     sscanf((const char*) p->record.csv2.fields[pos-1],"%x:%x:%x:%x:%x:%x:%x:%x",&v[0],&v[1],&v[2],&v[3],&v[4],&v[5],&v[6],&v[7]);
228         t->v[0]=htonl(v[0]<<16|v[1]);
229         t->v[1]=htonl(v[2]<<16|v[3]);
230         t->v[2]=htonl(v[4]<<16|v[5]);
231         t->v[3]=htonl(v[6]<<16|v[7]);
232         
233     return 0;
234 }
235 static inline gs_retval_t get_csv2_string(struct packet * p, struct gs_string * t,gs_uint32_t pos)
236
237         t->data=(gs_sp_t)p->record.csv2.fields[pos-1];
238     /*
239     if (pos == p->record.csv2.numberfields)
240         t->length=strlen((const char*)p->record.csv2.fields[pos-1]);
241     else
242         t->length=p->record.csv2.fields[pos] - p->record.csv2.fields[pos-1] - 1;
243     */
244     t->length=p->record.csv2.field_lens[pos-1];
245         t->owner=0;
246     return 0;
247 }
248 static inline gs_retval_t get_csv2_bool(struct packet * p, gs_uint32_t * t,gs_uint32_t pos)
249 {
250         *t=0;
251         if ((strlen((const char*)p->record.csv2.fields[pos-1])==4) &&
252                 (strncasecmp("TRUE",(const char*)p->record.csv2.fields[pos-1],4) ==0) ) {
253                 *t=1;
254         }
255     return 0;
256 }
257 static inline gs_retval_t get_csv2_int(struct packet * p, gs_int32_t * t,gs_uint32_t pos)
258 {
259     *t = strtol((const char*)p->record.csv2.fields[pos-1], NULL, 10);
260     return 0;
261 }
262 static inline gs_retval_t get_csv2_llong(struct packet * p, gs_int64_t * t,gs_uint32_t pos)
263 {
264     *t = strtoll((const char*)p->record.csv2.fields[pos-1], NULL, 10);
265     return 0;
266 }
267 static inline gs_retval_t get_csv2_float(struct packet * p, gs_float_t * t,gs_uint32_t pos)
268 {
269     *t = strtod((const char*)p->record.csv2.fields[pos-1], NULL);
270     return 0;
271 }
272
273 #include <lfta/csv2_macro.h>
274
275 /* GDAT access function using position as 3rd argument */
276
277 //#define GDATDEBUG
278
279 static inline gs_retval_t get_gdat_uint(struct packet * p, gs_uint32_t * t,gs_uint32_t pos)
280 {
281     struct access_result ar;
282 #ifdef GDATDEBUG
283         fprintf(stderr,"Decode uint");
284 #endif
285         if (p->ptype != PTYPE_GDAT) return -1;
286 #ifdef GDATDEBUG
287     fprintf(stderr,".");
288 #endif
289         if (p->record.gdat.numfields<pos) return -1;
290 #ifdef GDATDEBUG
291     fprintf(stderr,".");
292 #endif
293         ar=ftaschema_get_field_by_index(p->record.gdat.schema,pos-1,p->record.gdat.data,p->record.gdat.datasz);
294 #ifdef GDATDEBUG
295     fprintf(stderr,".");
296 #endif
297         if (ar.field_data_type!=UINT_TYPE) return -1;
298 #ifdef GDATDEBUG
299     fprintf(stderr,"DONE\n");
300 #endif
301         *t=ar.r.ui;
302     return 0;
303 }
304
305 static inline gs_retval_t get_gdat_ullong(struct packet * p, gs_uint64_t * t,gs_uint32_t pos)
306 {
307     struct access_result ar;
308 #ifdef GDATDEBUG
309     fprintf(stderr,"Decode ullong");
310 #endif
311     if (p->ptype != PTYPE_GDAT) return -1;
312 #ifdef GDATDEBUG
313     fprintf(stderr,".");
314 #endif
315     if (p->record.gdat.numfields<pos) return -1;
316 #ifdef GDATDEBUG
317     fprintf(stderr,".");
318 #endif
319     ar=ftaschema_get_field_by_index(p->record.gdat.schema,pos-1,p->record.gdat.data,p->record.gdat.datasz);
320 #ifdef GDATDEBUG
321     fprintf(stderr,".");
322 #endif
323     if (ar.field_data_type!=ULLONG_TYPE) return -1;
324 #ifdef GDATDEBUG
325     fprintf(stderr,"DONE\n");
326 #endif
327     *t=ar.r.ul;
328     return 0;
329 }
330
331 static inline gs_retval_t get_gdat_ip(struct packet * p, gs_uint32_t * t,gs_uint32_t pos)
332 {
333     struct access_result ar;
334     if (p->ptype != PTYPE_GDAT) return -1;
335 #ifdef GDATDEBUG
336     fprintf(stderr,"Decode ip");
337 #endif
338     if (p->record.gdat.numfields<pos) return -1;
339 #ifdef GDATDEBUG
340     fprintf(stderr,".");
341 #endif
342     ar=ftaschema_get_field_by_index(p->record.gdat.schema,pos-1,p->record.gdat.data,p->record.gdat.datasz);
343 #ifdef GDATDEBUG
344     fprintf(stderr,".");
345 #endif
346     if (ar.field_data_type!=IP_TYPE) return -1;
347 #ifdef GDATDEBUG
348     fprintf(stderr,"DONE\n");
349 #endif
350     *t=ar.r.ui;
351     return 0;
352 }
353 static inline gs_retval_t get_gdat_ipv6(struct packet * p, struct ipv6_str * t,gs_uint32_t pos)
354 {
355     struct access_result ar;
356     if (p->ptype != PTYPE_GDAT) return -1;
357 #ifdef GDATDEBUG
358     fprintf(stderr,"Decode ipv6");
359 #endif
360     if (p->record.gdat.numfields<pos) return -1;
361 #ifdef GDATDEBUG
362     fprintf(stderr,".");
363 #endif
364     ar=ftaschema_get_field_by_index(p->record.gdat.schema,pos-1,p->record.gdat.data,p->record.gdat.datasz);
365 #ifdef GDATDEBUG
366     fprintf(stderr,".");
367 #endif
368     if (ar.field_data_type!=IPV6_TYPE) return -1;
369 #ifdef GDATDEBUG
370     fprintf(stderr,"DONE\n");
371 #endif
372     t->v[0]=ar.r.ip6.v[0];
373     t->v[1]=ar.r.ip6.v[1];
374     t->v[2]=ar.r.ip6.v[2];
375     t->v[3]=ar.r.ip6.v[3];
376     return 0;
377 }
378 static inline gs_retval_t get_gdat_string(struct packet * p, struct gs_string * t,gs_uint32_t pos)
379 {
380     struct access_result ar;
381 #ifdef GDATDEBUG
382     fprintf(stderr,"Decode string");
383 #endif
384     if (p->ptype != PTYPE_GDAT) return -1;
385 #ifdef GDATDEBUG
386     fprintf(stderr,".");
387 #endif
388     if (p->record.gdat.numfields<pos) return -1;
389 #ifdef GDATDEBUG
390     fprintf(stderr,".");
391 #endif
392     ar=ftaschema_get_field_by_index(p->record.gdat.schema,pos-1,p->record.gdat.data,p->record.gdat.datasz);
393 #ifdef GDATDEBUG
394     fprintf(stderr,".");
395 #endif
396     if (ar.field_data_type!=VSTR_TYPE) return -1;
397 #ifdef GDATDEBUG
398     fprintf(stderr,"DONE\n");
399 #endif
400     t->data=(gs_sp_t)ar.r.vs.offset;
401         t->length=ar.r.vs.length;
402     return 0;
403 }
404 static inline gs_retval_t get_gdat_bool(struct packet * p, gs_uint32_t * t,gs_uint32_t pos)
405 {
406     struct access_result ar;
407 #ifdef GDATDEBUG
408     fprintf(stderr,"Decode bool");
409 #endif
410     if (p->ptype != PTYPE_GDAT) return -1;
411 #ifdef GDATDEBUG
412     fprintf(stderr,".");
413 #endif
414     if (p->record.gdat.numfields<pos) return -1;
415 #ifdef GDATDEBUG
416     fprintf(stderr,".");
417 #endif
418     ar=ftaschema_get_field_by_index(p->record.gdat.schema,pos-1,p->record.gdat.data,p->record.gdat.datasz);
419 #ifdef GDATDEBUG
420     fprintf(stderr,".");
421 #endif
422     if (ar.field_data_type!=BOOL_TYPE) return -1;
423 #ifdef GDATDEBUG
424     fprintf(stderr,"DONE\n");
425 #endif
426     *t=ar.r.ui;
427     return 0;
428 }
429 static inline gs_retval_t get_gdat_int(struct packet * p, gs_int32_t * t,gs_uint32_t pos)
430 {
431     struct access_result ar;
432 #ifdef GDATDEBUG
433     fprintf(stderr,"Decode int");
434 #endif
435     if (p->ptype != PTYPE_GDAT) return -1;
436 #ifdef GDATDEBUG
437     fprintf(stderr,".");
438 #endif
439     if (p->record.gdat.numfields<pos) return -1;
440 #ifdef GDATDEBUG
441     fprintf(stderr,".");
442 #endif
443     ar=ftaschema_get_field_by_index(p->record.gdat.schema,pos-1,p->record.gdat.data,p->record.gdat.datasz);
444 #ifdef GDATDEBUG
445     fprintf(stderr,".");
446 #endif
447     if (ar.field_data_type!=INT_TYPE) return -1;
448 #ifdef GDATDEBUG
449     fprintf(stderr,"DONE\n");
450 #endif
451     *t=ar.r.i;
452     return 0;
453 }
454 static inline gs_retval_t get_gdat_llong(struct packet * p, gs_int64_t * t,gs_uint32_t pos)
455 {
456     struct access_result ar;
457 #ifdef GDATDEBUG
458     fprintf(stderr,"Decode llong");
459 #endif
460     if (p->ptype != PTYPE_GDAT) return -1;
461 #ifdef GDATDEBUG
462     fprintf(stderr,".");
463 #endif
464     if (p->record.gdat.numfields<pos) return -1;
465 #ifdef GDATDEBUG
466     fprintf(stderr,".");
467 #endif
468     ar=ftaschema_get_field_by_index(p->record.gdat.schema,pos-1,p->record.gdat.data,p->record.gdat.datasz);
469 #ifdef GDATDEBUG
470     fprintf(stderr,".");
471 #endif
472     if (ar.field_data_type!=LLONG_TYPE) return -1;
473 #ifdef GDATDEBUG
474     fprintf(stderr,"DONE\n");
475 #endif
476     *t=ar.r.l;
477     return 0;
478 }
479 static inline gs_retval_t get_gdat_float(struct packet * p, gs_float_t * t,gs_uint32_t pos)
480 {
481     struct access_result ar;
482 #ifdef GDATDEBUG
483     fprintf(stderr,"Decode float");
484 #endif
485     if (p->ptype != PTYPE_GDAT) return -1;
486 #ifdef GDATDEBUG
487     fprintf(stderr,".");
488 #endif
489     if (p->record.gdat.numfields<pos) return -1;
490 #ifdef GDATDEBUG
491     fprintf(stderr,".");
492 #endif
493     ar=ftaschema_get_field_by_index(p->record.gdat.schema,pos-1,p->record.gdat.data,p->record.gdat.datasz);
494 #ifdef GDATDEBUG
495     fprintf(stderr,".");
496 #endif
497     if (ar.field_data_type!=FLOAT_TYPE) return -1;
498 #ifdef GDATDEBUG
499     fprintf(stderr,"DONE\n");
500 #endif
501     *t=ar.r.f;
502     return 0;
503 }
504
505 #include <lfta/gdat_macro.h>
506
507 // External functions
508
509
510
511
512 #endif
513