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;
64 /* CSV access function using position as 3rd argument */
66 static inline gs_retval_t get_csv_uint(struct packet * p, gs_uint32_t * t,gs_uint32_t pos)
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);
74 static inline gs_retval_t get_csv_ullong(struct packet * p, gs_uint64_t * t,gs_uint32_t pos)
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);
82 static inline gs_retval_t get_csv_ip(struct packet * p, gs_uint32_t * t,gs_uint32_t pos)
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;
91 static inline gs_retval_t get_csv_ipv6(struct packet * p, struct ipv6_str * t,gs_uint32_t pos)
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]);
104 static inline gs_retval_t get_csv_string(struct packet * p, struct gs_string * t,gs_uint32_t pos)
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]);
113 t->length=p->record.csv.fields[pos] - p->record.csv.fields[pos-1] - 1;
117 static inline gs_retval_t get_csv_bool(struct packet * p, gs_uint32_t * t,gs_uint32_t pos)
119 if (p->ptype != PTYPE_CSV) return -1;
120 if (p->record.csv.numberfields < pos) return -1;
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) ) {
128 static inline gs_retval_t get_csv_int(struct packet * p, gs_int32_t * t,gs_uint32_t pos)
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);
135 static inline gs_retval_t get_csv_llong(struct packet * p, gs_int64_t * t,gs_uint32_t pos)
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);
142 static inline gs_retval_t get_csv_float(struct packet * p, gs_float_t * t,gs_uint32_t pos)
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);
150 #include <lfta/csv_macro.h>
152 static inline __attribute__((always_inline)) unsigned int gs_strtoul (const char *str, size_t len) {
153 unsigned int value = 0;
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');
172 static inline __attribute__((always_inline)) unsigned long long gs_strtoull (const char *str, size_t len) {
173 unsigned long long value = 0;
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');
202 static inline gs_retval_t get_csv2_uint(struct packet * p, gs_uint32_t * t,gs_uint32_t pos)
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]);
210 static inline gs_retval_t get_csv2_ullong(struct packet * p, gs_uint64_t * t,gs_uint32_t pos)
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]);
217 static inline gs_retval_t get_csv2_ip(struct packet * p, gs_uint32_t * t,gs_uint32_t pos)
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;
224 static inline gs_retval_t get_csv2_ipv6(struct packet * p, struct ipv6_str * t,gs_uint32_t pos)
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]);
235 static inline gs_retval_t get_csv2_string(struct packet * p, struct gs_string * t,gs_uint32_t pos)
237 t->data=(gs_sp_t)p->record.csv2.fields[pos-1];
239 if (pos == p->record.csv2.numberfields)
240 t->length=strlen((const char*)p->record.csv2.fields[pos-1]);
242 t->length=p->record.csv2.fields[pos] - p->record.csv2.fields[pos-1] - 1;
244 t->length=p->record.csv2.field_lens[pos-1];
248 static inline gs_retval_t get_csv2_bool(struct packet * p, gs_uint32_t * t,gs_uint32_t pos)
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) ) {
257 static inline gs_retval_t get_csv2_int(struct packet * p, gs_int32_t * t,gs_uint32_t pos)
259 *t = strtol((const char*)p->record.csv2.fields[pos-1], NULL, 10);
262 static inline gs_retval_t get_csv2_llong(struct packet * p, gs_int64_t * t,gs_uint32_t pos)
264 *t = strtoll((const char*)p->record.csv2.fields[pos-1], NULL, 10);
267 static inline gs_retval_t get_csv2_float(struct packet * p, gs_float_t * t,gs_uint32_t pos)
269 *t = strtod((const char*)p->record.csv2.fields[pos-1], NULL);
273 #include <lfta/csv2_macro.h>
275 /* GDAT access function using position as 3rd argument */
279 static inline gs_retval_t get_gdat_uint(struct packet * p, gs_uint32_t * t,gs_uint32_t pos)
281 struct access_result ar;
283 fprintf(stderr,"Decode uint");
285 if (p->ptype != PTYPE_GDAT) return -1;
289 if (p->record.gdat.numfields<pos) return -1;
293 ar=ftaschema_get_field_by_index(p->record.gdat.schema,pos-1,p->record.gdat.data,p->record.gdat.datasz);
297 if (ar.field_data_type!=UINT_TYPE) return -1;
299 fprintf(stderr,"DONE\n");
305 static inline gs_retval_t get_gdat_ullong(struct packet * p, gs_uint64_t * t,gs_uint32_t pos)
307 struct access_result ar;
309 fprintf(stderr,"Decode ullong");
311 if (p->ptype != PTYPE_GDAT) return -1;
315 if (p->record.gdat.numfields<pos) return -1;
319 ar=ftaschema_get_field_by_index(p->record.gdat.schema,pos-1,p->record.gdat.data,p->record.gdat.datasz);
323 if (ar.field_data_type!=ULLONG_TYPE) return -1;
325 fprintf(stderr,"DONE\n");
331 static inline gs_retval_t get_gdat_ip(struct packet * p, gs_uint32_t * t,gs_uint32_t pos)
333 struct access_result ar;
334 if (p->ptype != PTYPE_GDAT) return -1;
336 fprintf(stderr,"Decode ip");
338 if (p->record.gdat.numfields<pos) return -1;
342 ar=ftaschema_get_field_by_index(p->record.gdat.schema,pos-1,p->record.gdat.data,p->record.gdat.datasz);
346 if (ar.field_data_type!=IP_TYPE) return -1;
348 fprintf(stderr,"DONE\n");
353 static inline gs_retval_t get_gdat_ipv6(struct packet * p, struct ipv6_str * t,gs_uint32_t pos)
355 struct access_result ar;
356 if (p->ptype != PTYPE_GDAT) return -1;
358 fprintf(stderr,"Decode ipv6");
360 if (p->record.gdat.numfields<pos) return -1;
364 ar=ftaschema_get_field_by_index(p->record.gdat.schema,pos-1,p->record.gdat.data,p->record.gdat.datasz);
368 if (ar.field_data_type!=IPV6_TYPE) return -1;
370 fprintf(stderr,"DONE\n");
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];
378 static inline gs_retval_t get_gdat_string(struct packet * p, struct gs_string * t,gs_uint32_t pos)
380 struct access_result ar;
382 fprintf(stderr,"Decode string");
384 if (p->ptype != PTYPE_GDAT) return -1;
388 if (p->record.gdat.numfields<pos) return -1;
392 ar=ftaschema_get_field_by_index(p->record.gdat.schema,pos-1,p->record.gdat.data,p->record.gdat.datasz);
396 if (ar.field_data_type!=VSTR_TYPE) return -1;
398 fprintf(stderr,"DONE\n");
400 t->data=(gs_sp_t)ar.r.vs.offset;
401 t->length=ar.r.vs.length;
404 static inline gs_retval_t get_gdat_bool(struct packet * p, gs_uint32_t * t,gs_uint32_t pos)
406 struct access_result ar;
408 fprintf(stderr,"Decode bool");
410 if (p->ptype != PTYPE_GDAT) return -1;
414 if (p->record.gdat.numfields<pos) return -1;
418 ar=ftaschema_get_field_by_index(p->record.gdat.schema,pos-1,p->record.gdat.data,p->record.gdat.datasz);
422 if (ar.field_data_type!=BOOL_TYPE) return -1;
424 fprintf(stderr,"DONE\n");
429 static inline gs_retval_t get_gdat_int(struct packet * p, gs_int32_t * t,gs_uint32_t pos)
431 struct access_result ar;
433 fprintf(stderr,"Decode int");
435 if (p->ptype != PTYPE_GDAT) return -1;
439 if (p->record.gdat.numfields<pos) return -1;
443 ar=ftaschema_get_field_by_index(p->record.gdat.schema,pos-1,p->record.gdat.data,p->record.gdat.datasz);
447 if (ar.field_data_type!=INT_TYPE) return -1;
449 fprintf(stderr,"DONE\n");
454 static inline gs_retval_t get_gdat_llong(struct packet * p, gs_int64_t * t,gs_uint32_t pos)
456 struct access_result ar;
458 fprintf(stderr,"Decode llong");
460 if (p->ptype != PTYPE_GDAT) return -1;
464 if (p->record.gdat.numfields<pos) return -1;
468 ar=ftaschema_get_field_by_index(p->record.gdat.schema,pos-1,p->record.gdat.data,p->record.gdat.datasz);
472 if (ar.field_data_type!=LLONG_TYPE) return -1;
474 fprintf(stderr,"DONE\n");
479 static inline gs_retval_t get_gdat_float(struct packet * p, gs_float_t * t,gs_uint32_t pos)
481 struct access_result ar;
483 fprintf(stderr,"Decode float");
485 if (p->ptype != PTYPE_GDAT) return -1;
489 if (p->record.gdat.numfields<pos) return -1;
493 ar=ftaschema_get_field_by_index(p->record.gdat.schema,pos-1,p->record.gdat.data,p->record.gdat.datasz);
497 if (ar.field_data_type!=FLOAT_TYPE) return -1;
499 fprintf(stderr,"DONE\n");
505 #include <lfta/gdat_macro.h>
507 // External functions