1 /* ------------------------------------------------
2 Copyright 2014 AT&T Intellectual Property
3 Licensed under the Apache License, Version 2.0 (the "License");
4 you may not use this file except in compliance with the License.
5 You may obtain a copy of the License at
7 http://www.apache.org/licenses/LICENSE-2.0
9 Unless required by applicable law or agreed to in writing, software
10 distributed under the License is distributed on an "AS IS" BASIS,
11 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 See the License for the specific language governing permissions and
13 limitations under the License.
14 ------------------------------------------- */
16 #include <sys/types.h>
23 #include <stringhash.h>
31 #include <host_tuple.h>
37 #include <netinet/in.h>
39 #define MAX_PATTERN_LEN 1024
41 // Defined here to avoid link errors as this array is auto generated for the lfta and referenced in the clearinghouse library which gets linked against the hfta
42 extern "C" gs_sp_t fta_names[]={0};
45 // Only used to construct constant strings ...
46 gs_retval_t Vstring_Constructor(vstring *tmp, gs_csp_t str) {
47 tmp->length = strlen(str);
49 tmp->offset = (gs_p_t)strdup(str);
50 tmp->reserved = SHALLOW_COPY;
54 // Assume str is INTERNAL or SHALLOW_COPY.
55 void hfta_vstr_destroy(vstring * str) {
56 if (str->length && str->reserved == INTERNAL) {
57 free((gs_sp_t)str->offset);
63 gs_retval_t hfta_vstr_length(vstring *str) {
67 // Assume that SRC is either INTERNAL or SHALLOW_COPY
68 void hfta_vstr_assign_with_copy_in_tuple(vstring32 * target,
69 const vstring * src, gs_sp_t data_offset, gs_retval_t int_offset) {
70 target->length = src->length;
71 target->offset = int_offset;
72 target->reserved = PACKED;
74 memcpy(data_offset, (gs_sp_t)src->offset, src->length);
77 // Ted wrote the following function.
78 // make deep copy of src. Assume that dst is already empty.
79 // Assume that SRC is either INTERNAL or SHALLOW_COPY
80 void hfta_vstr_assign_with_copy(vstring *dst, const vstring *src){
81 dst->length=src->length;
83 dst->offset=(gs_p_t)malloc(dst->length);
84 memcpy((gs_sp_t)(dst->offset),(gs_sp_t)(src->offset),dst->length);
86 dst->reserved=INTERNAL;
89 // Ted wrote the following function.
90 // Make a deep copy of src. garbage collect dst if needed.
91 // Assume that SRC is either INTERNAL or SHALLOW_COPY
92 void hfta_vstr_replace(vstring *dst, const vstring *src){
93 hfta_vstr_destroy(dst);
94 hfta_vstr_assign_with_copy(dst,src);
97 #define HFTA_VSTR_LHASHFUNC_PRIME 12916008961267169387ull
98 gs_uint64_t hfta_vstr_long_hashfunc(const vstring *s) {
99 gs_uint64_t hash_code;
101 gs_int32_t substr_len;
103 gs_uint64_t sub_hash;
106 sv=(gs_sp_t)(s->offset);
108 n_steps = s->length / 4;
109 if(4*n_steps < s->length) n_steps++;
111 for (j = 0; j < n_steps; j++) {
112 if(4*(j+1) < s->length) substr_len = 4;
113 else substr_len = s->length - 4*j;
118 sub_hash = (sub_hash << 4) + *sv;
120 sub_hash = (sub_hash << 4);
124 hash_code = (sub_hash + hash_code * HFTA_VSTR_LHASHFUNC_PRIME);
130 #define HFTA_VSTR_HASHFUNC_PRIME 2995999
131 gs_uint32_t hfta_vstr_hashfunc(const vstring *s) {
132 gs_uint32_t hash_code;
134 gs_int32_t substr_len;
136 gs_uint32_t k, sub_hash;
139 sv=(gs_sp_t)(s->offset);
141 n_steps = s->length / 4;
142 if(4*n_steps < s->length) n_steps++;
144 for (j = 0; j < n_steps; j++) {
145 if(4*(j+1) < s->length) substr_len = 4;
146 else substr_len = s->length - 4*j;
151 sub_hash = (sub_hash << 4) + *sv;
153 sub_hash = (sub_hash << 4);
157 hash_code = (sub_hash + hash_code * HFTA_VSTR_HASHFUNC_PRIME);
164 // return negative if s1 < s2, 0 if s1==s2, positive if s1>s2
165 gs_retval_t hfta_vstr_compare(const vstring * s1, const vstring * s2) {
166 gs_int32_t minlen,cmp_ret;
167 minlen=(s1->length<s2->length?s1->length:s2->length);
168 cmp_ret=memcmp((void *)s1->offset,(void *)s2->offset,minlen);
170 if(cmp_ret) return cmp_ret;
171 return(s1->length - s2->length);
174 gs_retval_t hfta_vstr_equal(const vstring * s1, const vstring * s2) {
177 if(s1->length != s2->length)
180 // cmp_ret=memcmp((void *)s1->offset,(void *)s2->offset,s1->length);
181 for(x=0;x<s1->length;x++) {
182 if (((char *)(s1->offset))[x]!=((char *)(s2->offset))[x]) {
193 gs_param_handle_t register_handle_for_str_regex_match_slot_1(vstring* pattern) {
197 if ((reg=(regex_t *) malloc(sizeof(regex_t)))==0) {
198 gslog(LOG_EMERG, "No memory for regular expression %s\n",
199 (gs_sp_t)(pattern->offset));
203 if (regcomp(reg,(char*)(pattern->offset), REG_NEWLINE|REG_EXTENDED|REG_NOSUB)!=0) {
204 gslog(LOG_EMERG, "Illegal regular expression %s\n",
205 (gs_sp_t)(pattern->offset));
208 return (gs_param_handle_t) reg;
211 gs_uint32_t str_regex_match(vstring* str, gs_param_handle_t pattern_handle) {
212 regex_t * reg = (regex_t *) pattern_handle ;
215 static gs_uint32_t dlen=0;
216 // grow our static buffer to the longest string we ever see
217 if ((str->length+1) >= dlen) {
218 if (d!=0) free((void*)d);
221 if ((d=(gs_sp_t)malloc(str->length+1))==0) return 0;
225 if (str->length==0) return 0;
227 // copy the string and 0 terminate it
228 memcpy((void *)d,(void *) str->offset, str->length);
232 res = regexec(reg, d, 0, NULL, 0);
233 return (res==REG_NOMATCH)?0:1;
236 gs_retval_t deregister_handle_for_str_regex_match_slot_1(gs_param_handle_t handle) {
237 regex_t * x = (regex_t *) handle;
243 gs_param_handle_t register_handle_for_str_partial_regex_match_slot_1(vstring* pattern) {
247 if ((reg=(regex_t *) malloc(sizeof(regex_t)))==0) {
248 gslog(LOG_EMERG, "No memory for regular expression %s\n",
249 (gs_sp_t)(pattern->offset));
253 if (regcomp(reg,(gs_sp_t)(pattern->offset), REG_NEWLINE|REG_EXTENDED|REG_NOSUB)!=0) {
254 gslog(LOG_EMERG, "Illegal regular expression %s\n",
255 (gs_sp_t)(pattern->offset));
258 return (gs_param_handle_t) reg;
261 gs_uint32_t str_partial_regex_match(vstring* str, gs_param_handle_t pattern_handle,
263 regex_t * reg = (regex_t *) pattern_handle ;
267 static gs_uint32_t dlen=0;
268 // grow our static buffer to the longest string we ever see
269 if ((str->length+1) >= dlen) {
270 if (d!=0) free((void*)d);
273 if ((d=(gs_sp_t)malloc(str->length+1))==0) return 0;
277 if (str->length==0) return 0;
279 end=(maxlen>(str->length))?(str->length):maxlen;
281 // copy the string and 0 terminate it
282 memcpy((void *)d,(void *) str->offset, end);
286 res = regexec(reg, d,0, NULL, 0);
287 return (res==REG_NOMATCH)?0:1;
291 gs_retval_t deregister_handle_for_str_partial_regex_match_slot_1(
292 gs_param_handle_t handle) {
293 regex_t * x = (regex_t *) handle;
299 gs_param_handle_t register_handle_for_str_extract_regex_slot_1(vstring* pattern) {
302 if ((reg=(regex_t *) malloc(sizeof(regex_t)))==0) {
303 gslog(LOG_EMERG, "No memory for regular expression %s\n",
304 (gs_sp_t)(pattern->offset));
307 if (regcomp(reg,(gs_sp_t)(pattern->offset), REG_EXTENDED)!=0) {
308 gslog(LOG_EMERG, "Illegal regular expression %s\n",
309 (gs_sp_t)(pattern->offset));
312 return (gs_param_handle_t) reg;
316 /* partial function return 0 if the value is valid */
317 gs_retval_t str_extract_regex( vstring * result, vstring * str, gs_param_handle_t handle) {
318 regex_t * reg = (regex_t *) handle ;
319 gs_sp_t source = (gs_sp_t)(str->offset);
323 static gs_uint32_t dlen=0;
324 // grow our static buffer to the longest string we ever see
325 if ((str->length+1) >= dlen) {
326 if (d!=0) free((void*)d);
329 if ((d=(gs_sp_t)malloc(str->length+1))==0) return 1;
333 if (str->length==0) return 1;
335 // copy the string and 0 terminate it
336 memcpy((void *)d,(void *) str->offset, str->length);
340 res = regexec(reg, d, 1, &match, 0);
341 if (res==REG_NOMATCH) return 1;
342 result->offset= (gs_p_t) &source[match.rm_so];
343 result->length=match.rm_eo-match.rm_so;
344 result->reserved = SHALLOW_COPY;
348 gs_retval_t deregister_handle_for_str_extract_regex_slot_1(gs_param_handle_t handle) {
349 regex_t * x = (regex_t *) handle;
356 static gs_uint32_t nextint(struct vstring *str , gs_uint32_t * offset, gs_uint32_t *res) {
357 gs_uint8_t * s = (gs_uint8_t *)(str->offset);
360 while(*offset<str->length) {
361 if ((s[*offset]>='0') && (s[*offset]<='9')) {
363 *res= (*res*10) + (gs_uint32_t) (s[*offset]-'0');
365 if (v!=0) { // got some valid result
367 } // otherwise skip leading grabage
374 gs_uint32_t strtoi(gs_uint32_t * r, struct vstring * s)
378 if (nextint(s,&offset,r)==0) return 1;
382 gs_param_handle_t register_handle_for_strtoi_c_slot_0(vstring* istr) {
383 gs_uint32_t offset,r;
385 if (nextint(istr,&offset,&r)!=0)
386 return (gs_param_handle_t) r;
387 return (gs_param_handle_t) 0;
389 gs_retval_t deregister_handle_for_strtoi_c_slot_0(gs_param_handle_t h) {
394 gs_uint32_t strtoip(gs_uint32_t * r, struct vstring * s)
396 gs_uint32_t ip1,ip2,ip3,ip4,offset;
398 if (nextint(s,&offset,&ip1)==0) return 1;
399 //fprintf (stderr, "1 %u %u\n",ip1,offset);
400 if (nextint(s,&offset,&ip2)==0) return 1;
401 //fprintf (stderr, "2 %u %u\n",ip2,offset);
402 if (nextint(s,&offset,&ip3)==0) return 1;
403 //fprintf (stderr, "3 %u %u\n",ip3,offset);
404 if (nextint(s,&offset,&ip4)==0) return 1;
405 //fprintf (stderr, "4 %u %u\n",ip4,offset);
406 *r=ip1<<24|ip2<<16|ip3<<8|ip4;
410 gs_param_handle_t register_handle_for_strtoip_c_slot_0(vstring* istr) {
411 gs_uint32_t ip1,ip2,ip3,ip4,offset,r;
413 if (nextint(istr,&offset,&ip1)==0) return (gs_param_handle_t)0;
414 if (nextint(istr,&offset,&ip2)==0) return (gs_param_handle_t)0;
415 if (nextint(istr,&offset,&ip3)==0) return (gs_param_handle_t)0;
416 if (nextint(istr,&offset,&ip4)==0) return (gs_param_handle_t)0;
417 r=ip1<<24|ip2<<16|ip3<<8|ip4;
418 return (gs_param_handle_t)r;
420 gs_retval_t deregister_handle_for_strtoip_c_slot_0(gs_param_handle_t h) {
424 gs_uint32_t partn_hash( gs_uint32_t ip1, gs_uint32_t ip2) {
428 gs_uint32_t rand_hash() {
432 ///////////////////////////////////////
434 // return negative if s1 < s2, 0 if s1==s2, positive if s1>s2
435 gs_retval_t hfta_ipv6_compare(const hfta_ipv6_str &i1, const hfta_ipv6_str &i2) {
436 if(i1.v[0] > i2.v[0])
438 if(i1.v[0] < i2.v[0])
440 if(i1.v[1] > i2.v[1])
442 if(i1.v[1] < i2.v[1])
444 if(i1.v[2] > i2.v[2])
446 if(i1.v[2] < i2.v[2])
448 if(i1.v[3] > i2.v[3])
450 if(i1.v[3] < i2.v[3])
456 hfta_ipv6_str And_Ipv6(const hfta_ipv6_str &i1, const hfta_ipv6_str &i2){
458 ret.v[0] = i1.v[0] & i2.v[0];
459 ret.v[1] = i1.v[1] & i2.v[1];
460 ret.v[2] = i1.v[2] & i2.v[2];
461 ret.v[3] = i1.v[3] & i2.v[3];
465 hfta_ipv6_str Or_Ipv6(const hfta_ipv6_str &i1, const hfta_ipv6_str &i2){
467 ret.v[0] = i1.v[0] | i2.v[0];
468 ret.v[1] = i1.v[1] | i2.v[1];
469 ret.v[2] = i1.v[2] | i2.v[2];
470 ret.v[3] = i1.v[3] | i2.v[3];
474 gs_uint32_t hfta_ipv6_hashfunc(const hfta_ipv6_str *s) {
475 return s->v[0] ^ s->v[1] ^ s->v[2] ^ s->v[3];
478 hfta_ipv6_str hton_ipv6(hfta_ipv6_str s){
481 // ret.v[0] = htonl(s.v[0]);
482 // ret.v[1] = htonl(s.v[1]);
483 // ret.v[2] = htonl(s.v[2]);
484 // ret.v[3] = htonl(s.v[3]);
492 hfta_ipv6_str ntoh_ipv6(hfta_ipv6_str s){
494 // ret.v[0] = ntohl(s.v[0]);
495 // ret.v[1] = ntohl(s.v[1]);
496 // ret.v[2] = ntohl(s.v[2]);
497 // ret.v[3] = ntohl(s.v[3]);
505 int HFTA_Ipv6_Constructor(hfta_ipv6_str *s, gs_csp_t l) {
506 gs_uint32_t i0=0,i1=0,i2=0,i3=0,i4=0,i5=0,i6=0,i7=0;
507 sscanf(l,"%x:%x:%x:%x:%x:%x:%x:%x",&i0,&i1,&i2,&i3,&i4,&i5,&i6,&i7);
508 s->v[0] = ((i0 & 0xffff) << 16) | (i1 & 0xffff);
509 s->v[1] = ((i2 & 0xffff) << 16) | (i3 & 0xffff);
510 s->v[2] = ((i4 & 0xffff) << 16) | (i5 & 0xffff);
511 s->v[3] = ((i6 & 0xffff) << 16) | (i7 & 0xffff);
515 gs_retval_t str_exists_substr(vstring * s1,vstring * s2)
517 gs_uint8_t *st1 = (gs_uint8_t *)s1->offset;
518 gs_uint8_t *st2 = (gs_uint8_t *)s2->offset;
519 gs_uint8_t *s2f = (gs_uint8_t *)s2->offset;
520 gs_uint8_t len1 = s1->length-s2->length;
521 gs_uint8_t len2 = s2->length;
524 for (x=0; x<len1 ; x++)
528 for (y=0; y<len2 && st1[x+y]==st2[y];y++);
536 gs_retval_t str_compare(vstring *s1,vstring *s2)
538 return hfta_vstr_compare(s1,s2);
541 gs_uint32_t str_match_offset( gs_uint32_t offset, vstring *s1, vstring *s2)
543 gs_uint8_t *st1 = (gs_uint8_t *)s1->offset;
544 gs_uint8_t *st2 = &(((gs_uint8_t *)s2->offset)[offset]);
546 gs_int32_t len2 = s2->length-offset;
547 gs_int32_t len1 = s1->length;
552 for(x = 0; x < len1; x++)
554 if (st1[x] != st2[x])
560 gs_uint32_t byte_match_offset( gs_uint32_t offset, gs_uint32_t val,vstring *s2)
562 gs_uint8_t *st2 = (gs_uint8_t *)s2->offset;
563 gs_uint8_t v = (unsigned char) val;
565 // if ((s2->length <= offset)||(offset<0))
566 if (s2->length <= offset)
569 return (st2[offset]==v)?1:0;
573 // -------------------------------------------------------
574 // map_int_to_string and its support functions, structs
576 struct int_to_string_map_struct{
577 std::map<gs_int64_t, vstring> i2s_map;
579 vstring empty_string;
582 gs_param_handle_t register_handle_for_int_to_string_map_slot_1(vstring *filename){
583 int_to_string_map_struct *map_struct;
585 map_struct = new int_to_string_map_struct();
586 if(map_struct == NULL){
587 gslog(LOG_EMERG, "int_to_string_map:: Could not allocate handle memory\n");
591 map_struct->empty_string.offset = (gs_p_t)malloc(1);
592 map_struct->empty_string.reserved = INTERNAL;
593 map_struct->empty_string.length = 0;
596 filenamec = (gs_sp_t)alloca(filename->length+1);
598 gslog(LOG_EMERG, "int_to_string_map:: Could not allocate filename memory\n");
601 memcpy(filenamec,(gs_sp_t)filename->offset,filename->length);
602 filenamec[filename->length]=0;
603 map_struct->fname = filenamec;
605 FILE *fl = fopen(filenamec, "r");
607 gslog(LOG_EMERG, "int_to_string_map:: Could not open regex file %s \n",filename);
611 gs_int32_t buflen = 10000;
612 char buf[buflen], buf_str[buflen];
615 fret = fgets(buf, buflen, fl);
617 int nvals = sscanf(buf, "%lld,%s", &val, buf_str);
620 new_str.reserved = SHALLOW_COPY;
621 new_str.length = strlen(buf_str);
622 new_str.offset = (gs_p_t)malloc(new_str.length);
623 memcpy((char *)new_str.offset, buf_str, new_str.length);
624 map_struct->i2s_map[val] = new_str;
626 fret = fgets(buf, buflen, fl);
631 return (gs_param_handle_t) map_struct;
634 gs_retval_t int_to_string_map(vstring *result, gs_int64_t val, gs_param_handle_t handle){
635 int_to_string_map_struct *map_struct = (int_to_string_map_struct *)handle;
636 if(map_struct->i2s_map.count(val)>0){
637 vstring ret = map_struct->i2s_map[val];
638 result->offset = ret.offset;
639 result->reserved = ret.reserved;
640 result->length = ret.length;
642 result->offset = map_struct->empty_string.offset;
643 result->reserved = map_struct->empty_string.reserved;
644 result->length = map_struct->empty_string.length;
650 gs_param_handle_t deregister_handle_for_int_to_string_map_slot_1(gs_param_handle_t handle){
651 int_to_string_map_struct *map_struct = (int_to_string_map_struct *)handle;
652 for(std::map<gs_int64_t, vstring>::iterator i2si = map_struct->i2s_map.begin(); i2si!=map_struct->i2s_map.end(); ++i2si){
653 free((void *)((*i2si).second.offset));
655 free((void *)(map_struct->empty_string.offset));