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);
62 // Make the vstring safe to destroy even if its never initialized
63 // (e.g. stack-allocated groups containing strings)
64 void hfta_vstr_init(vstring * str) {
68 gs_retval_t hfta_vstr_length(vstring *str) {
72 // Assume that SRC is either INTERNAL or SHALLOW_COPY
73 void hfta_vstr_assign_with_copy_in_tuple(vstring32 * target,
74 const vstring * src, gs_sp_t data_offset, gs_retval_t int_offset) {
75 target->length = src->length;
76 target->offset = int_offset;
77 target->reserved = PACKED;
79 memcpy(data_offset, (gs_sp_t)src->offset, src->length);
82 // Ted wrote the following function.
83 // make deep copy of src. Assume that dst is already empty.
84 // Assume that SRC is either INTERNAL or SHALLOW_COPY
85 void hfta_vstr_assign_with_copy(vstring *dst, const vstring *src){
86 dst->length=src->length;
88 dst->offset=(gs_p_t)malloc(dst->length);
89 memcpy((gs_sp_t)(dst->offset),(gs_sp_t)(src->offset),dst->length);
91 dst->reserved=INTERNAL;
94 // Ted wrote the following function.
95 // Make a deep copy of src. garbage collect dst if needed.
96 // Assume that SRC is either INTERNAL or SHALLOW_COPY
97 void hfta_vstr_replace(vstring *dst, const vstring *src){
98 hfta_vstr_destroy(dst);
99 hfta_vstr_assign_with_copy(dst,src);
102 #define HFTA_VSTR_LHASHFUNC_PRIME 12916008961267169387ull
103 gs_uint64_t hfta_vstr_long_hashfunc(const vstring *s) {
104 gs_uint64_t hash_code;
106 gs_int32_t substr_len;
108 gs_uint64_t sub_hash;
111 sv=(gs_sp_t)(s->offset);
113 n_steps = s->length / 4;
114 if(4*n_steps < s->length) n_steps++;
116 for (j = 0; j < n_steps; j++) {
117 if(4*(j+1) < s->length) substr_len = 4;
118 else substr_len = s->length - 4*j;
123 sub_hash = (sub_hash << 4) + *sv;
125 sub_hash = (sub_hash << 4);
129 hash_code = (sub_hash + hash_code * HFTA_VSTR_LHASHFUNC_PRIME);
135 #define HFTA_VSTR_HASHFUNC_PRIME 2995999
136 gs_uint32_t hfta_vstr_hashfunc(const vstring *s) {
137 gs_uint32_t hash_code;
139 gs_int32_t substr_len;
141 gs_uint32_t k, sub_hash;
144 sv=(gs_sp_t)(s->offset);
146 n_steps = s->length / 4;
147 if(4*n_steps < s->length) n_steps++;
149 for (j = 0; j < n_steps; j++) {
150 if(4*(j+1) < s->length) substr_len = 4;
151 else substr_len = s->length - 4*j;
156 sub_hash = (sub_hash << 4) + *sv;
158 sub_hash = (sub_hash << 4);
162 hash_code = (sub_hash + hash_code * HFTA_VSTR_HASHFUNC_PRIME);
169 // return negative if s1 < s2, 0 if s1==s2, positive if s1>s2
170 gs_retval_t hfta_vstr_compare(const vstring * s1, const vstring * s2) {
171 gs_int32_t minlen,cmp_ret;
172 minlen=(s1->length<s2->length?s1->length:s2->length);
173 cmp_ret=memcmp((void *)s1->offset,(void *)s2->offset,minlen);
175 if(cmp_ret) return cmp_ret;
176 return(s1->length - s2->length);
179 gs_retval_t hfta_vstr_equal(const vstring * s1, const vstring * s2) {
182 if(s1->length != s2->length)
185 // cmp_ret=memcmp((void *)s1->offset,(void *)s2->offset,s1->length);
186 for(x=0;x<s1->length;x++) {
187 if (((char *)(s1->offset))[x]!=((char *)(s2->offset))[x]) {
198 gs_param_handle_t register_handle_for_str_regex_match_slot_1(vstring* pattern) {
202 if ((reg=(regex_t *) malloc(sizeof(regex_t)))==0) {
203 gslog(LOG_EMERG, "No memory for regular expression %s\n",
204 (gs_sp_t)(pattern->offset));
208 if (regcomp(reg,(char*)(pattern->offset), REG_NEWLINE|REG_EXTENDED|REG_NOSUB)!=0) {
209 gslog(LOG_EMERG, "Illegal regular expression %s\n",
210 (gs_sp_t)(pattern->offset));
213 return (gs_param_handle_t) reg;
216 gs_uint32_t str_regex_match(vstring* str, gs_param_handle_t pattern_handle) {
217 regex_t * reg = (regex_t *) pattern_handle ;
220 static gs_uint32_t dlen=0;
221 // grow our static buffer to the longest string we ever see
222 if ((str->length+1) >= dlen) {
223 if (d!=0) free((void*)d);
226 if ((d=(gs_sp_t)malloc(str->length+1))==0) return 0;
230 if (str->length==0) return 0;
232 // copy the string and 0 terminate it
233 memcpy((void *)d,(void *) str->offset, str->length);
237 res = regexec(reg, d, 0, NULL, 0);
238 return (res==REG_NOMATCH)?0:1;
241 gs_retval_t deregister_handle_for_str_regex_match_slot_1(gs_param_handle_t handle) {
242 regex_t * x = (regex_t *) handle;
248 gs_param_handle_t register_handle_for_str_partial_regex_match_slot_1(vstring* pattern) {
252 if ((reg=(regex_t *) malloc(sizeof(regex_t)))==0) {
253 gslog(LOG_EMERG, "No memory for regular expression %s\n",
254 (gs_sp_t)(pattern->offset));
258 if (regcomp(reg,(gs_sp_t)(pattern->offset), REG_NEWLINE|REG_EXTENDED|REG_NOSUB)!=0) {
259 gslog(LOG_EMERG, "Illegal regular expression %s\n",
260 (gs_sp_t)(pattern->offset));
263 return (gs_param_handle_t) reg;
266 gs_uint32_t str_partial_regex_match(vstring* str, gs_param_handle_t pattern_handle,
268 regex_t * reg = (regex_t *) pattern_handle ;
272 static gs_uint32_t dlen=0;
273 // grow our static buffer to the longest string we ever see
274 if ((str->length+1) >= dlen) {
275 if (d!=0) free((void*)d);
278 if ((d=(gs_sp_t)malloc(str->length+1))==0) return 0;
282 if (str->length==0) return 0;
284 end=(maxlen>(str->length))?(str->length):maxlen;
286 // copy the string and 0 terminate it
287 memcpy((void *)d,(void *) str->offset, end);
291 res = regexec(reg, d,0, NULL, 0);
292 return (res==REG_NOMATCH)?0:1;
296 gs_retval_t deregister_handle_for_str_partial_regex_match_slot_1(
297 gs_param_handle_t handle) {
298 regex_t * x = (regex_t *) handle;
304 gs_param_handle_t register_handle_for_str_extract_regex_slot_1(vstring* pattern) {
307 if ((reg=(regex_t *) malloc(sizeof(regex_t)))==0) {
308 gslog(LOG_EMERG, "No memory for regular expression %s\n",
309 (gs_sp_t)(pattern->offset));
312 if (regcomp(reg,(gs_sp_t)(pattern->offset), REG_EXTENDED)!=0) {
313 gslog(LOG_EMERG, "Illegal regular expression %s\n",
314 (gs_sp_t)(pattern->offset));
317 return (gs_param_handle_t) reg;
321 /* partial function return 0 if the value is valid */
322 gs_retval_t str_extract_regex( vstring * result, vstring * str, gs_param_handle_t handle) {
323 regex_t * reg = (regex_t *) handle ;
324 gs_sp_t source = (gs_sp_t)(str->offset);
328 static gs_uint32_t dlen=0;
329 // grow our static buffer to the longest string we ever see
330 if ((str->length+1) >= dlen) {
331 if (d!=0) free((void*)d);
334 if ((d=(gs_sp_t)malloc(str->length+1))==0) return 1;
338 if (str->length==0) return 1;
340 // copy the string and 0 terminate it
341 memcpy((void *)d,(void *) str->offset, str->length);
345 res = regexec(reg, d, 1, &match, 0);
346 if (res==REG_NOMATCH) return 1;
347 result->offset= (gs_p_t) &source[match.rm_so];
348 result->length=match.rm_eo-match.rm_so;
349 result->reserved = SHALLOW_COPY;
353 gs_retval_t deregister_handle_for_str_extract_regex_slot_1(gs_param_handle_t handle) {
354 regex_t * x = (regex_t *) handle;
361 static gs_uint32_t nextint(struct vstring *str , gs_uint32_t * offset, gs_uint32_t *res) {
362 gs_uint8_t * s = (gs_uint8_t *)(str->offset);
365 while(*offset<str->length) {
366 if ((s[*offset]>='0') && (s[*offset]<='9')) {
368 *res= (*res*10) + (gs_uint32_t) (s[*offset]-'0');
370 if (v!=0) { // got some valid result
372 } // otherwise skip leading grabage
379 gs_uint32_t strtoi(gs_uint32_t * r, struct vstring * s)
383 if (nextint(s,&offset,r)==0) return 1;
387 gs_param_handle_t register_handle_for_strtoi_c_slot_0(vstring* istr) {
388 gs_uint32_t offset,r;
390 if (nextint(istr,&offset,&r)!=0)
391 return (gs_param_handle_t) r;
392 return (gs_param_handle_t) 0;
394 gs_retval_t deregister_handle_for_strtoi_c_slot_0(gs_param_handle_t h) {
399 gs_uint32_t strtoip(gs_uint32_t * r, struct vstring * s)
401 gs_uint32_t ip1,ip2,ip3,ip4,offset;
403 if (nextint(s,&offset,&ip1)==0) return 1;
404 //fprintf (stderr, "1 %u %u\n",ip1,offset);
405 if (nextint(s,&offset,&ip2)==0) return 1;
406 //fprintf (stderr, "2 %u %u\n",ip2,offset);
407 if (nextint(s,&offset,&ip3)==0) return 1;
408 //fprintf (stderr, "3 %u %u\n",ip3,offset);
409 if (nextint(s,&offset,&ip4)==0) return 1;
410 //fprintf (stderr, "4 %u %u\n",ip4,offset);
411 *r=ip1<<24|ip2<<16|ip3<<8|ip4;
415 gs_param_handle_t register_handle_for_strtoip_c_slot_0(vstring* istr) {
416 gs_uint32_t ip1,ip2,ip3,ip4,offset,r;
418 if (nextint(istr,&offset,&ip1)==0) return (gs_param_handle_t)0;
419 if (nextint(istr,&offset,&ip2)==0) return (gs_param_handle_t)0;
420 if (nextint(istr,&offset,&ip3)==0) return (gs_param_handle_t)0;
421 if (nextint(istr,&offset,&ip4)==0) return (gs_param_handle_t)0;
422 r=ip1<<24|ip2<<16|ip3<<8|ip4;
423 return (gs_param_handle_t)r;
425 gs_retval_t deregister_handle_for_strtoip_c_slot_0(gs_param_handle_t h) {
429 gs_uint32_t partn_hash( gs_uint32_t ip1, gs_uint32_t ip2) {
433 gs_uint32_t rand_hash() {
437 ///////////////////////////////////////
439 // return negative if s1 < s2, 0 if s1==s2, positive if s1>s2
440 gs_retval_t hfta_ipv6_compare(const hfta_ipv6_str &i1, const hfta_ipv6_str &i2) {
441 if(i1.v[0] > i2.v[0])
443 if(i1.v[0] < i2.v[0])
445 if(i1.v[1] > i2.v[1])
447 if(i1.v[1] < i2.v[1])
449 if(i1.v[2] > i2.v[2])
451 if(i1.v[2] < i2.v[2])
453 if(i1.v[3] > i2.v[3])
455 if(i1.v[3] < i2.v[3])
461 hfta_ipv6_str And_Ipv6(const hfta_ipv6_str &i1, const hfta_ipv6_str &i2){
463 ret.v[0] = i1.v[0] & i2.v[0];
464 ret.v[1] = i1.v[1] & i2.v[1];
465 ret.v[2] = i1.v[2] & i2.v[2];
466 ret.v[3] = i1.v[3] & i2.v[3];
470 hfta_ipv6_str Or_Ipv6(const hfta_ipv6_str &i1, const hfta_ipv6_str &i2){
472 ret.v[0] = i1.v[0] | i2.v[0];
473 ret.v[1] = i1.v[1] | i2.v[1];
474 ret.v[2] = i1.v[2] | i2.v[2];
475 ret.v[3] = i1.v[3] | i2.v[3];
479 gs_uint32_t hfta_ipv6_hashfunc(const hfta_ipv6_str *s) {
480 return s->v[0] ^ s->v[1] ^ s->v[2] ^ s->v[3];
483 hfta_ipv6_str hton_ipv6(hfta_ipv6_str s){
486 // ret.v[0] = htonl(s.v[0]);
487 // ret.v[1] = htonl(s.v[1]);
488 // ret.v[2] = htonl(s.v[2]);
489 // ret.v[3] = htonl(s.v[3]);
497 hfta_ipv6_str ntoh_ipv6(hfta_ipv6_str s){
499 // ret.v[0] = ntohl(s.v[0]);
500 // ret.v[1] = ntohl(s.v[1]);
501 // ret.v[2] = ntohl(s.v[2]);
502 // ret.v[3] = ntohl(s.v[3]);
510 int HFTA_Ipv6_Constructor(hfta_ipv6_str *s, gs_csp_t l) {
511 gs_uint32_t i0=0,i1=0,i2=0,i3=0,i4=0,i5=0,i6=0,i7=0;
512 sscanf(l,"%x:%x:%x:%x:%x:%x:%x:%x",&i0,&i1,&i2,&i3,&i4,&i5,&i6,&i7);
513 s->v[0] = ((i0 & 0xffff) << 16) | (i1 & 0xffff);
514 s->v[1] = ((i2 & 0xffff) << 16) | (i3 & 0xffff);
515 s->v[2] = ((i4 & 0xffff) << 16) | (i5 & 0xffff);
516 s->v[3] = ((i6 & 0xffff) << 16) | (i7 & 0xffff);
520 gs_retval_t str_exists_substr(vstring * s1,vstring * s2)
522 gs_uint8_t *st1 = (gs_uint8_t *)s1->offset;
523 gs_uint8_t *st2 = (gs_uint8_t *)s2->offset;
524 gs_uint8_t *s2f = (gs_uint8_t *)s2->offset;
525 gs_uint8_t len1 = s1->length-s2->length;
526 gs_uint8_t len2 = s2->length;
529 for (x=0; x<len1 ; x++)
533 for (y=0; y<len2 && st1[x+y]==st2[y];y++);
541 gs_retval_t str_compare(vstring *s1,vstring *s2)
543 return hfta_vstr_compare(s1,s2);
546 gs_uint32_t str_match_offset( gs_uint32_t offset, vstring *s1, vstring *s2)
548 gs_uint8_t *st1 = (gs_uint8_t *)s1->offset;
549 gs_uint8_t *st2 = &(((gs_uint8_t *)s2->offset)[offset]);
551 gs_int32_t len2 = s2->length-offset;
552 gs_int32_t len1 = s1->length;
557 for(x = 0; x < len1; x++)
559 if (st1[x] != st2[x])
565 gs_uint32_t byte_match_offset( gs_uint32_t offset, gs_uint32_t val,vstring *s2)
567 gs_uint8_t *st2 = (gs_uint8_t *)s2->offset;
568 gs_uint8_t v = (unsigned char) val;
570 // if ((s2->length <= offset)||(offset<0))
571 if (s2->length <= offset)
574 return (st2[offset]==v)?1:0;
578 // -------------------------------------------------------
579 // map_int_to_string and its support functions, structs
581 struct int_to_string_map_struct{
582 std::map<gs_int64_t, vstring> i2s_map;
584 vstring empty_string;
587 gs_param_handle_t register_handle_for_int_to_string_map_slot_1(vstring *filename){
588 int_to_string_map_struct *map_struct;
590 map_struct = new int_to_string_map_struct();
591 if(map_struct == NULL){
592 gslog(LOG_EMERG, "int_to_string_map:: Could not allocate handle memory\n");
596 map_struct->empty_string.offset = (gs_p_t)malloc(1);
597 map_struct->empty_string.reserved = INTERNAL;
598 map_struct->empty_string.length = 0;
601 filenamec = (gs_sp_t)alloca(filename->length+1);
603 gslog(LOG_EMERG, "int_to_string_map:: Could not allocate filename memory\n");
606 memcpy(filenamec,(gs_sp_t)filename->offset,filename->length);
607 filenamec[filename->length]=0;
608 map_struct->fname = filenamec;
610 FILE *fl = fopen(filenamec, "r");
612 gslog(LOG_EMERG, "int_to_string_map:: Could not open regex file %s \n",filename);
616 gs_int32_t buflen = 10000;
617 char buf[buflen], buf_str[buflen];
620 fret = fgets(buf, buflen, fl);
622 int nvals = sscanf(buf, "%lld,%s", &val, buf_str);
625 new_str.reserved = SHALLOW_COPY;
626 new_str.length = strlen(buf_str);
627 new_str.offset = (gs_p_t)malloc(new_str.length);
628 memcpy((char *)new_str.offset, buf_str, new_str.length);
629 map_struct->i2s_map[val] = new_str;
631 fret = fgets(buf, buflen, fl);
636 return (gs_param_handle_t) map_struct;
639 gs_retval_t int_to_string_map(vstring *result, gs_int64_t val, gs_param_handle_t handle){
640 int_to_string_map_struct *map_struct = (int_to_string_map_struct *)handle;
641 if(map_struct->i2s_map.count(val)>0){
642 vstring ret = map_struct->i2s_map[val];
643 result->offset = ret.offset;
644 result->reserved = ret.reserved;
645 result->length = ret.length;
647 result->offset = map_struct->empty_string.offset;
648 result->reserved = map_struct->empty_string.reserved;
649 result->length = map_struct->empty_string.length;
655 gs_param_handle_t deregister_handle_for_int_to_string_map_slot_1(gs_param_handle_t handle){
656 int_to_string_map_struct *map_struct = (int_to_string_map_struct *)handle;
657 for(std::map<gs_int64_t, vstring>::iterator i2si = map_struct->i2s_map.begin(); i2si!=map_struct->i2s_map.end(); ++i2si){
658 free((void *)((*i2si).second.offset));
660 free((void *)(map_struct->empty_string.offset));