1 #ifndef __SCHEMA_PROTOTYPES__
2 #define __SCHEMA_PROTOTYPES__
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
10 http://www.apache.org/licenses/LICENSE-2.0
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 ------------------------------------------- */
25 #include "rts_external.h"
27 #include "md_stdlib.h"
28 #include "schemaparser.h"
31 // *** SAMPLING RELATED CONSTANTS
32 // ******************************
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
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))
53 // COMBINE probability
54 #define COMBINEDPROB (((gs_float_t)1)-(((gs_float_t)1)-FLOWSAMPPROB)*(((gs_float_t)1)-PACKETSAMPPROB))
56 /* General packet access functions */
58 static inline gs_retval_t get_system_time(struct packet * p, gs_uint32_t * t)
60 *t=(gs_uint32_t) p->systemTime;
63 static inline gs_retval_t get_schemaId(struct packet * p, gs_uint32_t * t)
65 *t=(gs_uint32_t) p->schema;
69 /* CSV access function using position as 3rd argument */
71 static inline gs_retval_t get_csv_uint(struct packet * p, gs_uint32_t * t,gs_uint32_t pos)
73 if (p->ptype != PTYPE_CSV) return -1;
74 if (p->record.csv.numberfields < pos) return -1;
75 *t = strtoul((const char*)p->record.csv.fields[pos-1], NULL, 10);
79 static inline gs_retval_t get_csv_ullong(struct packet * p, gs_uint64_t * t,gs_uint32_t pos)
81 if (p->ptype != PTYPE_CSV) return -1;
82 if (p->record.csv.numberfields < pos) return -1;
83 *t = strtoull((const char*)p->record.csv.fields[pos-1], NULL, 10);
87 static inline gs_retval_t get_csv_ip(struct packet * p, gs_uint32_t * t,gs_uint32_t pos)
89 unsigned ip1,ip2,ip3,ip4;
90 if (p->ptype != PTYPE_CSV) return -1;
91 if (p->record.csv.numberfields < pos) return -1;
92 sscanf((const char*) p->record.csv.fields[pos-1],"%u.%u.%u.%u",&ip1,&ip2,&ip3,&ip4);
93 *t=(ip1<<24)|(ip2<<16)|(ip3<<8)|ip4;
96 static inline gs_retval_t get_csv_ipv6(struct packet * p, struct ipv6_str * t,gs_uint32_t pos)
99 if (p->ptype != PTYPE_CSV) return -1;
100 if (p->record.csv.numberfields < pos) return -1;
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]);
102 t->v[0]=htonl(v[0]<<16|v[1]);
103 t->v[1]=htonl(v[2]<<16|v[3]);
104 t->v[2]=htonl(v[4]<<16|v[5]);
105 t->v[3]=htonl(v[6]<<16|v[7]);
109 static inline gs_retval_t get_csv_string(struct packet * p, struct gs_string * t,gs_uint32_t pos)
112 if (p->ptype != PTYPE_CSV) return -1;
113 if (p->record.csv.numberfields < pos) return -1;
114 t->data=(gs_sp_t)p->record.csv.fields[pos-1];
115 if (pos == p->record.csv.numberfields)
116 t->length=strlen((const char*)p->record.csv.fields[pos-1]);
118 t->length=p->record.csv.fields[pos] - p->record.csv.fields[pos-1] - 1;
122 static inline gs_retval_t get_csv_bool(struct packet * p, gs_uint32_t * t,gs_uint32_t pos)
124 if (p->ptype != PTYPE_CSV) return -1;
125 if (p->record.csv.numberfields < pos) return -1;
127 if ((strlen((const char*)p->record.csv.fields[pos-1])==4) &&
128 (strncasecmp("TRUE",(const char*)p->record.csv.fields[pos-1],4) ==0) ) {
133 static inline gs_retval_t get_csv_int(struct packet * p, gs_int32_t * t,gs_uint32_t pos)
135 if (p->ptype != PTYPE_CSV) return -1;
136 if (p->record.csv.numberfields < pos) return -1;
137 *t = strtol((const char*)p->record.csv.fields[pos-1], NULL, 10);
140 static inline gs_retval_t get_csv_llong(struct packet * p, gs_int64_t * t,gs_uint32_t pos)
142 if (p->ptype != PTYPE_CSV) return -1;
143 if (p->record.csv.numberfields < pos) return -1;
144 *t = strtoll((const char*)p->record.csv.fields[pos-1], NULL, 10);
147 static inline gs_retval_t get_csv_float(struct packet * p, gs_float_t * t,gs_uint32_t pos)
149 if (p->ptype != PTYPE_CSV) return -1;
150 if (p->record.csv.numberfields < pos) return -1;
151 *t = strtod((const char*)p->record.csv.fields[pos-1], NULL);
155 #include <lfta/csv_macro.h>
157 static inline __attribute__((always_inline)) unsigned int gs_strtoul (const char *str, size_t len) {
158 unsigned int value = 0;
160 switch (len) { // handle up to 10 digits, assume we're 32-bit
161 case 10: value += (str[len-10] - '0') * 1000000000;
162 case 9: value += (str[len- 9] - '0') * 100000000;
163 case 8: value += (str[len- 8] - '0') * 10000000;
164 case 7: value += (str[len- 7] - '0') * 1000000;
165 case 6: value += (str[len- 6] - '0') * 100000;
166 case 5: value += (str[len- 5] - '0') * 10000;
167 case 4: value += (str[len- 4] - '0') * 1000;
168 case 3: value += (str[len- 3] - '0') * 100;
169 case 2: value += (str[len- 2] - '0') * 10;
170 case 1: value += (str[len- 1] - '0');
177 static inline __attribute__((always_inline)) unsigned long long gs_strtoull (const char *str, size_t len) {
178 unsigned long long value = 0;
180 switch (len) { // handle up to 10 digits, assume we're 32-bit
181 case 20: value += (str[len-20] - '0') * 10000000000000000000UL;
182 case 19: value += (str[len-19] - '0') * 1000000000000000000UL;
183 case 18: value += (str[len-18] - '0') * 100000000000000000UL;
184 case 17: value += (str[len-17] - '0') * 10000000000000000UL;
185 case 16: value += (str[len-16] - '0') * 1000000000000000UL;
186 case 15: value += (str[len-15] - '0') * 100000000000000UL;
187 case 14: value += (str[len-14] - '0') * 10000000000000UL;
188 case 13: value += (str[len-13] - '0') * 1000000000000UL;
189 case 12: value += (str[len-12] - '0') * 100000000000UL;
190 case 11: value += (str[len-11] - '0') * 10000000000UL;
191 case 10: value += (str[len-10] - '0') * 1000000000UL;
192 case 9: value += (str[len- 9] - '0') * 100000000UL;
193 case 8: value += (str[len- 8] - '0') * 10000000UL;
194 case 7: value += (str[len- 7] - '0') * 1000000UL;
195 case 6: value += (str[len- 6] - '0') * 100000UL;
196 case 5: value += (str[len- 5] - '0') * 10000UL;
197 case 4: value += (str[len- 4] - '0') * 1000UL;
198 case 3: value += (str[len- 3] - '0') * 100UL;
199 case 2: value += (str[len- 2] - '0') * 10UL;
200 case 1: value += (str[len- 1] - '0');
207 static inline gs_retval_t get_csv2_uint(struct packet * p, gs_uint32_t * t,gs_uint32_t pos)
209 // *t = strtoul((const char*)p->record.csv2.fields[pos-1], NULL, 10);
210 *t = gs_strtoul((const char*)p->record.csv2.fields[pos-1], p->record.csv2.field_lens[pos-1]);
215 static inline gs_retval_t get_csv2_ullong(struct packet * p, gs_uint64_t * t,gs_uint32_t pos)
217 // *t = strtoull((const char*)p->record.csv2.fields[pos-1], NULL, 10);
218 *t = gs_strtoull((const char*)p->record.csv2.fields[pos-1], p->record.csv2.field_lens[pos-1]);
222 static inline gs_retval_t get_csv2_ip(struct packet * p, gs_uint32_t * t,gs_uint32_t pos)
224 unsigned ip1,ip2,ip3,ip4;
225 sscanf((const char*) p->record.csv2.fields[pos-1],"%u.%u.%u.%u",&ip1,&ip2,&ip3,&ip4);
226 *t=(ip1<<24)|(ip2<<16)|(ip3<<8)|ip4;
229 static inline gs_retval_t get_csv2_ipv6(struct packet * p, struct ipv6_str * t,gs_uint32_t pos)
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]);
233 t->v[0]=htonl(v[0]<<16|v[1]);
234 t->v[1]=htonl(v[2]<<16|v[3]);
235 t->v[2]=htonl(v[4]<<16|v[5]);
236 t->v[3]=htonl(v[6]<<16|v[7]);
240 static inline gs_retval_t get_csv2_string(struct packet * p, struct gs_string * t,gs_uint32_t pos)
242 t->data=(gs_sp_t)p->record.csv2.fields[pos-1];
244 if (pos == p->record.csv2.numberfields)
245 t->length=strlen((const char*)p->record.csv2.fields[pos-1]);
247 t->length=p->record.csv2.fields[pos] - p->record.csv2.fields[pos-1] - 1;
249 t->length=p->record.csv2.field_lens[pos-1];
253 static inline gs_retval_t get_csv2_bool(struct packet * p, gs_uint32_t * t,gs_uint32_t pos)
256 if ((strlen((const char*)p->record.csv2.fields[pos-1])==4) &&
257 (strncasecmp("TRUE",(const char*)p->record.csv2.fields[pos-1],4) ==0) ) {
262 static inline gs_retval_t get_csv2_int(struct packet * p, gs_int32_t * t,gs_uint32_t pos)
264 *t = strtol((const char*)p->record.csv2.fields[pos-1], NULL, 10);
267 static inline gs_retval_t get_csv2_llong(struct packet * p, gs_int64_t * t,gs_uint32_t pos)
269 *t = strtoll((const char*)p->record.csv2.fields[pos-1], NULL, 10);
272 static inline gs_retval_t get_csv2_float(struct packet * p, gs_float_t * t,gs_uint32_t pos)
274 *t = strtod((const char*)p->record.csv2.fields[pos-1], NULL);
278 #include <lfta/csv2_macro.h>
280 /* GDAT access function using position as 3rd argument */
284 static inline gs_retval_t get_gdat_uint(struct packet * p, gs_uint32_t * t,gs_uint32_t pos)
286 struct access_result ar;
288 fprintf(stderr,"Decode uint");
290 if (p->ptype != PTYPE_GDAT) return -1;
294 if (p->record.gdat.numfields<pos) return -1;
298 ar=ftaschema_get_field_by_index(p->record.gdat.schema,pos-1,p->record.gdat.data,p->record.gdat.datasz);
302 if (ar.field_data_type!=UINT_TYPE) return -1;
304 fprintf(stderr,"DONE\n");
310 static inline gs_retval_t get_gdat_ullong(struct packet * p, gs_uint64_t * t,gs_uint32_t pos)
312 struct access_result ar;
314 fprintf(stderr,"Decode ullong");
316 if (p->ptype != PTYPE_GDAT) return -1;
320 if (p->record.gdat.numfields<pos) return -1;
324 ar=ftaschema_get_field_by_index(p->record.gdat.schema,pos-1,p->record.gdat.data,p->record.gdat.datasz);
328 if (ar.field_data_type!=ULLONG_TYPE) return -1;
330 fprintf(stderr,"DONE\n");
336 static inline gs_retval_t get_gdat_ip(struct packet * p, gs_uint32_t * t,gs_uint32_t pos)
338 struct access_result ar;
339 if (p->ptype != PTYPE_GDAT) return -1;
341 fprintf(stderr,"Decode ip");
343 if (p->record.gdat.numfields<pos) return -1;
347 ar=ftaschema_get_field_by_index(p->record.gdat.schema,pos-1,p->record.gdat.data,p->record.gdat.datasz);
351 if (ar.field_data_type!=IP_TYPE) return -1;
353 fprintf(stderr,"DONE\n");
358 static inline gs_retval_t get_gdat_ipv6(struct packet * p, struct ipv6_str * t,gs_uint32_t pos)
360 struct access_result ar;
361 if (p->ptype != PTYPE_GDAT) return -1;
363 fprintf(stderr,"Decode ipv6");
365 if (p->record.gdat.numfields<pos) return -1;
369 ar=ftaschema_get_field_by_index(p->record.gdat.schema,pos-1,p->record.gdat.data,p->record.gdat.datasz);
373 if (ar.field_data_type!=IPV6_TYPE) return -1;
375 fprintf(stderr,"DONE\n");
377 t->v[0]=ar.r.ip6.v[0];
378 t->v[1]=ar.r.ip6.v[1];
379 t->v[2]=ar.r.ip6.v[2];
380 t->v[3]=ar.r.ip6.v[3];
383 static inline gs_retval_t get_gdat_string(struct packet * p, struct gs_string * t,gs_uint32_t pos)
385 struct access_result ar;
387 fprintf(stderr,"Decode string");
389 if (p->ptype != PTYPE_GDAT) return -1;
393 if (p->record.gdat.numfields<pos) return -1;
397 ar=ftaschema_get_field_by_index(p->record.gdat.schema,pos-1,p->record.gdat.data,p->record.gdat.datasz);
401 if (ar.field_data_type!=VSTR_TYPE) return -1;
403 fprintf(stderr,"DONE\n");
405 t->data=(gs_sp_t)ar.r.vs.offset;
406 t->length=ar.r.vs.length;
409 static inline gs_retval_t get_gdat_bool(struct packet * p, gs_uint32_t * t,gs_uint32_t pos)
411 struct access_result ar;
413 fprintf(stderr,"Decode bool");
415 if (p->ptype != PTYPE_GDAT) return -1;
419 if (p->record.gdat.numfields<pos) return -1;
423 ar=ftaschema_get_field_by_index(p->record.gdat.schema,pos-1,p->record.gdat.data,p->record.gdat.datasz);
427 if (ar.field_data_type!=BOOL_TYPE) return -1;
429 fprintf(stderr,"DONE\n");
434 static inline gs_retval_t get_gdat_int(struct packet * p, gs_int32_t * t,gs_uint32_t pos)
436 struct access_result ar;
438 fprintf(stderr,"Decode int");
440 if (p->ptype != PTYPE_GDAT) return -1;
444 if (p->record.gdat.numfields<pos) return -1;
448 ar=ftaschema_get_field_by_index(p->record.gdat.schema,pos-1,p->record.gdat.data,p->record.gdat.datasz);
452 if (ar.field_data_type!=INT_TYPE) return -1;
454 fprintf(stderr,"DONE\n");
459 static inline gs_retval_t get_gdat_llong(struct packet * p, gs_int64_t * t,gs_uint32_t pos)
461 struct access_result ar;
463 fprintf(stderr,"Decode llong");
465 if (p->ptype != PTYPE_GDAT) return -1;
469 if (p->record.gdat.numfields<pos) return -1;
473 ar=ftaschema_get_field_by_index(p->record.gdat.schema,pos-1,p->record.gdat.data,p->record.gdat.datasz);
477 if (ar.field_data_type!=LLONG_TYPE) return -1;
479 fprintf(stderr,"DONE\n");
484 static inline gs_retval_t get_gdat_float(struct packet * p, gs_float_t * t,gs_uint32_t pos)
486 struct access_result ar;
488 fprintf(stderr,"Decode float");
490 if (p->ptype != PTYPE_GDAT) return -1;
494 if (p->record.gdat.numfields<pos) return -1;
498 ar=ftaschema_get_field_by_index(p->record.gdat.schema,pos-1,p->record.gdat.data,p->record.gdat.datasz);
502 if (ar.field_data_type!=FLOAT_TYPE) return -1;
504 fprintf(stderr,"DONE\n");
510 #include <lfta/gdat_macro.h>
512 // External functions