1 #ifndef __SCHEMA_PROTOTYPES__
\r
2 #define __SCHEMA_PROTOTYPES__
\r
4 /* ------------------------------------------------
\r
5 Copyright 2014 AT&T Intellectual Property
\r
6 Licensed under the Apache License, Version 2.0 (the "License");
\r
7 you may not use this file except in compliance with the License.
\r
8 You may obtain a copy of the License at
\r
10 http://www.apache.org/licenses/LICENSE-2.0
\r
12 Unless required by applicable law or agreed to in writing, software
\r
13 distributed under the License is distributed on an "AS IS" BASIS,
\r
14 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
\r
15 See the License for the specific language governing permissions and
\r
16 limitations under the License.
\r
17 ------------------------------------------- */
\r
21 #include "gsconfig.h"
\r
22 #include "gstypes.h"
\r
25 #include "rts_external.h"
\r
27 #include "md_stdlib.h"
\r
28 #include "schemaparser.h"
\r
31 // *** SAMPLING RELATED CONSTANTS
\r
32 // ******************************
\r
34 // Make sure the hash table sizes are powers of 2-1 since they are used to compute the module with an and.
\r
35 // collions on the flow hash are handled properly so they are not that bad
\r
36 #define MAX_FLOWRECORD_HASH 0x1fffff
\r
37 // keep the collision rate low on denies
\r
38 #define MAX_DENY_HASH 0x7fffff
\r
39 // one out of SAMPLING_RATE+1 sampling
\r
40 #define SAMPLING_RATE 19
\r
41 // sampling probability
\r
42 #define FLOWSAMPPROB (((gs_float_t)1)/((gs_float_t)SAMPLING_RATE+1))
\r
43 // wait for SAMPLED_FLOW_TIMEOUT seconds idle time to time a flow out
\r
44 #define SAMPLED_FLOW_TIMEOUT 30
\r
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
\r
46 #define SAMPLED_FLOW_IDLE_TIME 30
\r
48 // PACKET SAMPLING RATE one in SAMPLED_PACKETS will be sampled
\r
49 #define SAMPLED_PACKETS 200
\r
50 // SAMPLING probability
\r
51 #define PACKETSAMPPROB (((gs_float_t)1)/((gs_float_t)SAMPLED_PACKETS))
\r
53 // COMBINE probability
\r
54 #define COMBINEDPROB (((gs_float_t)1)-(((gs_float_t)1)-FLOWSAMPPROB)*(((gs_float_t)1)-PACKETSAMPPROB))
\r
56 /* General packet access functions */
\r
58 static inline gs_retval_t get_system_time(struct packet * p, gs_uint32_t * t)
\r
60 *t=(gs_uint32_t) p->systemTime;
\r
63 static inline gs_retval_t get_schemaId(struct packet * p, gs_uint32_t * t)
\r
65 *t=(gs_uint32_t) p->schema;
\r
69 /* CSV access function using position as 3rd argument */
\r
71 static inline gs_retval_t get_csv_uint(struct packet * p, gs_uint32_t * t,gs_uint32_t pos)
\r
73 if (p->ptype != PTYPE_CSV) return -1;
\r
74 if (p->record.csv.numberfields < pos) return -1;
\r
75 *t = strtoul((const char*)p->record.csv.fields[pos-1], NULL, 10);
\r
79 static inline gs_retval_t get_csv_ullong(struct packet * p, gs_uint64_t * t,gs_uint32_t pos)
\r
81 if (p->ptype != PTYPE_CSV) return -1;
\r
82 if (p->record.csv.numberfields < pos) return -1;
\r
83 *t = strtoull((const char*)p->record.csv.fields[pos-1], NULL, 10);
\r
87 static inline gs_retval_t get_csv_ip(struct packet * p, gs_uint32_t * t,gs_uint32_t pos)
\r
89 unsigned ip1,ip2,ip3,ip4;
\r
90 if (p->ptype != PTYPE_CSV) return -1;
\r
91 if (p->record.csv.numberfields < pos) return -1;
\r
92 sscanf((const char*) p->record.csv.fields[pos-1],"%u.%u.%u.%u",&ip1,&ip2,&ip3,&ip4);
\r
93 *t=(ip1<<24)|(ip2<<16)|(ip3<<8)|ip4;
\r
96 static inline gs_retval_t get_csv_ipv6(struct packet * p, struct ipv6_str * t,gs_uint32_t pos)
\r
99 if (p->ptype != PTYPE_CSV) return -1;
\r
100 if (p->record.csv.numberfields < pos) return -1;
\r
101 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]);
\r
102 t->v[0]=htonl(v[0]<<16|v[1]);
\r
103 t->v[1]=htonl(v[2]<<16|v[3]);
\r
104 t->v[2]=htonl(v[4]<<16|v[5]);
\r
105 t->v[3]=htonl(v[6]<<16|v[7]);
\r
109 static inline gs_retval_t get_csv_string(struct packet * p, struct gs_string * t,gs_uint32_t pos)
\r
112 if (p->ptype != PTYPE_CSV) return -1;
\r
113 if (p->record.csv.numberfields < pos) return -1;
\r
114 t->data=(gs_sp_t)p->record.csv.fields[pos-1];
\r
115 if (pos == p->record.csv.numberfields)
\r
116 t->length=strlen((const char*)p->record.csv.fields[pos-1]);
\r
118 t->length=p->record.csv.fields[pos] - p->record.csv.fields[pos-1] - 1;
\r
122 static inline gs_retval_t get_csv_bool(struct packet * p, gs_uint32_t * t,gs_uint32_t pos)
\r
124 if (p->ptype != PTYPE_CSV) return -1;
\r
125 if (p->record.csv.numberfields < pos) return -1;
\r
127 if ((strlen((const char*)p->record.csv.fields[pos-1])==4) &&
\r
128 (strncasecmp("TRUE",(const char*)p->record.csv.fields[pos-1],4) ==0) ) {
\r
133 static inline gs_retval_t get_csv_int(struct packet * p, gs_int32_t * t,gs_uint32_t pos)
\r
135 if (p->ptype != PTYPE_CSV) return -1;
\r
136 if (p->record.csv.numberfields < pos) return -1;
\r
137 *t = strtol((const char*)p->record.csv.fields[pos-1], NULL, 10);
\r
140 static inline gs_retval_t get_csv_llong(struct packet * p, gs_int64_t * t,gs_uint32_t pos)
\r
142 if (p->ptype != PTYPE_CSV) return -1;
\r
143 if (p->record.csv.numberfields < pos) return -1;
\r
144 *t = strtoll((const char*)p->record.csv.fields[pos-1], NULL, 10);
\r
147 static inline gs_retval_t get_csv_float(struct packet * p, gs_float_t * t,gs_uint32_t pos)
\r
149 if (p->ptype != PTYPE_CSV) return -1;
\r
150 if (p->record.csv.numberfields < pos) return -1;
\r
151 *t = strtod((const char*)p->record.csv.fields[pos-1], NULL);
\r
155 #include <lfta/csv_macro.h>
\r
157 static inline __attribute__((always_inline)) unsigned int gs_strtoul (const char *str, size_t len) {
\r
158 unsigned int value = 0;
\r
160 switch (len) { // handle up to 10 digits, assume we're 32-bit
\r
161 case 10: value += (str[len-10] - '0') * 1000000000;
\r
162 case 9: value += (str[len- 9] - '0') * 100000000;
\r
163 case 8: value += (str[len- 8] - '0') * 10000000;
\r
164 case 7: value += (str[len- 7] - '0') * 1000000;
\r
165 case 6: value += (str[len- 6] - '0') * 100000;
\r
166 case 5: value += (str[len- 5] - '0') * 10000;
\r
167 case 4: value += (str[len- 4] - '0') * 1000;
\r
168 case 3: value += (str[len- 3] - '0') * 100;
\r
169 case 2: value += (str[len- 2] - '0') * 10;
\r
170 case 1: value += (str[len- 1] - '0');
\r
177 static inline __attribute__((always_inline)) unsigned long long gs_strtoull (const char *str, size_t len) {
\r
178 unsigned long long value = 0;
\r
180 switch (len) { // handle up to 10 digits, assume we're 32-bit
\r
181 case 20: value += (str[len-20] - '0') * 10000000000000000000UL;
\r
182 case 19: value += (str[len-19] - '0') * 1000000000000000000UL;
\r
183 case 18: value += (str[len-18] - '0') * 100000000000000000UL;
\r
184 case 17: value += (str[len-17] - '0') * 10000000000000000UL;
\r
185 case 16: value += (str[len-16] - '0') * 1000000000000000UL;
\r
186 case 15: value += (str[len-15] - '0') * 100000000000000UL;
\r
187 case 14: value += (str[len-14] - '0') * 10000000000000UL;
\r
188 case 13: value += (str[len-13] - '0') * 1000000000000UL;
\r
189 case 12: value += (str[len-12] - '0') * 100000000000UL;
\r
190 case 11: value += (str[len-11] - '0') * 10000000000UL;
\r
191 case 10: value += (str[len-10] - '0') * 1000000000UL;
\r
192 case 9: value += (str[len- 9] - '0') * 100000000UL;
\r
193 case 8: value += (str[len- 8] - '0') * 10000000UL;
\r
194 case 7: value += (str[len- 7] - '0') * 1000000UL;
\r
195 case 6: value += (str[len- 6] - '0') * 100000UL;
\r
196 case 5: value += (str[len- 5] - '0') * 10000UL;
\r
197 case 4: value += (str[len- 4] - '0') * 1000UL;
\r
198 case 3: value += (str[len- 3] - '0') * 100UL;
\r
199 case 2: value += (str[len- 2] - '0') * 10UL;
\r
200 case 1: value += (str[len- 1] - '0');
\r
207 static inline gs_retval_t get_csv2_uint(struct packet * p, gs_uint32_t * t,gs_uint32_t pos)
\r
209 // *t = strtoul((const char*)p->record.csv2.fields[pos-1], NULL, 10);
\r
210 *t = gs_strtoul((const char*)p->record.csv2.fields[pos-1], p->record.csv2.field_lens[pos-1]);
\r
215 static inline gs_retval_t get_csv2_ullong(struct packet * p, gs_uint64_t * t,gs_uint32_t pos)
\r
217 // *t = strtoull((const char*)p->record.csv2.fields[pos-1], NULL, 10);
\r
218 *t = gs_strtoull((const char*)p->record.csv2.fields[pos-1], p->record.csv2.field_lens[pos-1]);
\r
222 static inline gs_retval_t get_csv2_ip(struct packet * p, gs_uint32_t * t,gs_uint32_t pos)
\r
224 unsigned ip1,ip2,ip3,ip4;
\r
225 sscanf((const char*) p->record.csv2.fields[pos-1],"%u.%u.%u.%u",&ip1,&ip2,&ip3,&ip4);
\r
226 *t=(ip1<<24)|(ip2<<16)|(ip3<<8)|ip4;
\r
229 static inline gs_retval_t get_csv2_ipv6(struct packet * p, struct ipv6_str * t,gs_uint32_t pos)
\r
232 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]);
\r
233 t->v[0]=htonl(v[0]<<16|v[1]);
\r
234 t->v[1]=htonl(v[2]<<16|v[3]);
\r
235 t->v[2]=htonl(v[4]<<16|v[5]);
\r
236 t->v[3]=htonl(v[6]<<16|v[7]);
\r
240 static inline gs_retval_t get_csv2_string(struct packet * p, struct gs_string * t,gs_uint32_t pos)
\r
242 t->data=(gs_sp_t)p->record.csv2.fields[pos-1];
\r
244 if (pos == p->record.csv2.numberfields)
\r
245 t->length=strlen((const char*)p->record.csv2.fields[pos-1]);
\r
247 t->length=p->record.csv2.fields[pos] - p->record.csv2.fields[pos-1] - 1;
\r
249 t->length=p->record.csv2.field_lens[pos-1];
\r
253 static inline gs_retval_t get_csv2_bool(struct packet * p, gs_uint32_t * t,gs_uint32_t pos)
\r
256 if ((strlen((const char*)p->record.csv2.fields[pos-1])==4) &&
\r
257 (strncasecmp("TRUE",(const char*)p->record.csv2.fields[pos-1],4) ==0) ) {
\r
262 static inline gs_retval_t get_csv2_int(struct packet * p, gs_int32_t * t,gs_uint32_t pos)
\r
264 *t = strtol((const char*)p->record.csv2.fields[pos-1], NULL, 10);
\r
267 static inline gs_retval_t get_csv2_llong(struct packet * p, gs_int64_t * t,gs_uint32_t pos)
\r
269 *t = strtoll((const char*)p->record.csv2.fields[pos-1], NULL, 10);
\r
272 static inline gs_retval_t get_csv2_float(struct packet * p, gs_float_t * t,gs_uint32_t pos)
\r
274 *t = strtod((const char*)p->record.csv2.fields[pos-1], NULL);
\r
278 #include <lfta/csv2_macro.h>
\r
280 /* GDAT access function using position as 3rd argument */
\r
282 //#define GDATDEBUG
\r
284 static inline gs_retval_t get_gdat_uint(struct packet * p, gs_uint32_t * t,gs_uint32_t pos)
\r
286 struct access_result ar;
\r
288 fprintf(stderr,"Decode uint");
\r
290 if (p->ptype != PTYPE_GDAT) return -1;
\r
292 fprintf(stderr,".");
\r
294 if (p->record.gdat.numfields<pos) return -1;
\r
296 fprintf(stderr,".");
\r
298 ar=ftaschema_get_field_by_index(p->record.gdat.schema,pos-1,p->record.gdat.data,p->record.gdat.datasz);
\r
300 fprintf(stderr,".");
\r
302 if (ar.field_data_type!=UINT_TYPE) return -1;
\r
304 fprintf(stderr,"DONE\n");
\r
310 static inline gs_retval_t get_gdat_ullong(struct packet * p, gs_uint64_t * t,gs_uint32_t pos)
\r
312 struct access_result ar;
\r
314 fprintf(stderr,"Decode ullong");
\r
316 if (p->ptype != PTYPE_GDAT) return -1;
\r
318 fprintf(stderr,".");
\r
320 if (p->record.gdat.numfields<pos) return -1;
\r
322 fprintf(stderr,".");
\r
324 ar=ftaschema_get_field_by_index(p->record.gdat.schema,pos-1,p->record.gdat.data,p->record.gdat.datasz);
\r
326 fprintf(stderr,".");
\r
328 if (ar.field_data_type!=ULLONG_TYPE) return -1;
\r
330 fprintf(stderr,"DONE\n");
\r
336 static inline gs_retval_t get_gdat_ip(struct packet * p, gs_uint32_t * t,gs_uint32_t pos)
\r
338 struct access_result ar;
\r
339 if (p->ptype != PTYPE_GDAT) return -1;
\r
341 fprintf(stderr,"Decode ip");
\r
343 if (p->record.gdat.numfields<pos) return -1;
\r
345 fprintf(stderr,".");
\r
347 ar=ftaschema_get_field_by_index(p->record.gdat.schema,pos-1,p->record.gdat.data,p->record.gdat.datasz);
\r
349 fprintf(stderr,".");
\r
351 if (ar.field_data_type!=IP_TYPE) return -1;
\r
353 fprintf(stderr,"DONE\n");
\r
358 static inline gs_retval_t get_gdat_ipv6(struct packet * p, struct ipv6_str * t,gs_uint32_t pos)
\r
360 struct access_result ar;
\r
361 if (p->ptype != PTYPE_GDAT) return -1;
\r
363 fprintf(stderr,"Decode ipv6");
\r
365 if (p->record.gdat.numfields<pos) return -1;
\r
367 fprintf(stderr,".");
\r
369 ar=ftaschema_get_field_by_index(p->record.gdat.schema,pos-1,p->record.gdat.data,p->record.gdat.datasz);
\r
371 fprintf(stderr,".");
\r
373 if (ar.field_data_type!=IPV6_TYPE) return -1;
\r
375 fprintf(stderr,"DONE\n");
\r
377 t->v[0]=ar.r.ip6.v[0];
\r
378 t->v[1]=ar.r.ip6.v[1];
\r
379 t->v[2]=ar.r.ip6.v[2];
\r
380 t->v[3]=ar.r.ip6.v[3];
\r
383 static inline gs_retval_t get_gdat_string(struct packet * p, struct gs_string * t,gs_uint32_t pos)
\r
385 struct access_result ar;
\r
387 fprintf(stderr,"Decode string");
\r
389 if (p->ptype != PTYPE_GDAT) return -1;
\r
391 fprintf(stderr,".");
\r
393 if (p->record.gdat.numfields<pos) return -1;
\r
395 fprintf(stderr,".");
\r
397 ar=ftaschema_get_field_by_index(p->record.gdat.schema,pos-1,p->record.gdat.data,p->record.gdat.datasz);
\r
399 fprintf(stderr,".");
\r
401 if (ar.field_data_type!=VSTR_TYPE) return -1;
\r
403 fprintf(stderr,"DONE\n");
\r
405 t->data=(gs_sp_t)ar.r.vs.offset;
\r
406 t->length=ar.r.vs.length;
\r
409 static inline gs_retval_t get_gdat_bool(struct packet * p, gs_uint32_t * t,gs_uint32_t pos)
\r
411 struct access_result ar;
\r
413 fprintf(stderr,"Decode bool");
\r
415 if (p->ptype != PTYPE_GDAT) return -1;
\r
417 fprintf(stderr,".");
\r
419 if (p->record.gdat.numfields<pos) return -1;
\r
421 fprintf(stderr,".");
\r
423 ar=ftaschema_get_field_by_index(p->record.gdat.schema,pos-1,p->record.gdat.data,p->record.gdat.datasz);
\r
425 fprintf(stderr,".");
\r
427 if (ar.field_data_type!=BOOL_TYPE) return -1;
\r
429 fprintf(stderr,"DONE\n");
\r
434 static inline gs_retval_t get_gdat_int(struct packet * p, gs_int32_t * t,gs_uint32_t pos)
\r
436 struct access_result ar;
\r
438 fprintf(stderr,"Decode int");
\r
440 if (p->ptype != PTYPE_GDAT) return -1;
\r
442 fprintf(stderr,".");
\r
444 if (p->record.gdat.numfields<pos) return -1;
\r
446 fprintf(stderr,".");
\r
448 ar=ftaschema_get_field_by_index(p->record.gdat.schema,pos-1,p->record.gdat.data,p->record.gdat.datasz);
\r
450 fprintf(stderr,".");
\r
452 if (ar.field_data_type!=INT_TYPE) return -1;
\r
454 fprintf(stderr,"DONE\n");
\r
459 static inline gs_retval_t get_gdat_llong(struct packet * p, gs_int64_t * t,gs_uint32_t pos)
\r
461 struct access_result ar;
\r
463 fprintf(stderr,"Decode llong");
\r
465 if (p->ptype != PTYPE_GDAT) return -1;
\r
467 fprintf(stderr,".");
\r
469 if (p->record.gdat.numfields<pos) return -1;
\r
471 fprintf(stderr,".");
\r
473 ar=ftaschema_get_field_by_index(p->record.gdat.schema,pos-1,p->record.gdat.data,p->record.gdat.datasz);
\r
475 fprintf(stderr,".");
\r
477 if (ar.field_data_type!=LLONG_TYPE) return -1;
\r
479 fprintf(stderr,"DONE\n");
\r
484 static inline gs_retval_t get_gdat_float(struct packet * p, gs_float_t * t,gs_uint32_t pos)
\r
486 struct access_result ar;
\r
488 fprintf(stderr,"Decode float");
\r
490 if (p->ptype != PTYPE_GDAT) return -1;
\r
492 fprintf(stderr,".");
\r
494 if (p->record.gdat.numfields<pos) return -1;
\r
496 fprintf(stderr,".");
\r
498 ar=ftaschema_get_field_by_index(p->record.gdat.schema,pos-1,p->record.gdat.data,p->record.gdat.datasz);
\r
500 fprintf(stderr,".");
\r
502 if (ar.field_data_type!=FLOAT_TYPE) return -1;
\r
504 fprintf(stderr,"DONE\n");
\r
510 #include <lfta/gdat_macro.h>
\r
512 // External functions
\r