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>
35 #include <netinet/in.h>
37 #define MAX_PATTERN_LEN 1024
39 // 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
40 extern "C" gs_sp_t fta_names[]={0};
43 // Only used to construct constant strings ...
44 gs_retval_t Vstring_Constructor(vstring *tmp, gs_csp_t str) {
45 tmp->length = strlen(str);
47 tmp->offset = (gs_p_t)strdup(str);
48 tmp->reserved = SHALLOW_COPY;
52 // Assume str is INTERNAL or SHALLOW_COPY.
53 void hfta_vstr_destroy(vstring * str) {
54 if (str->length && str->reserved == INTERNAL) {
55 free((gs_sp_t)str->offset);
61 gs_retval_t hfta_vstr_length(vstring *str) {
65 // Assume that SRC is either INTERNAL or SHALLOW_COPY
66 void hfta_vstr_assign_with_copy_in_tuple(vstring32 * target, vstring * src,
67 gs_sp_t data_offset, gs_retval_t int_offset) {
68 target->length = src->length;
69 target->offset = int_offset;
70 target->reserved = PACKED;
72 memcpy(data_offset, (gs_sp_t)src->offset, src->length);
75 // Ted wrote the following function.
76 // make deep copy of src. Assume that dst is already empty.
77 // Assume that SRC is either INTERNAL or SHALLOW_COPY
78 void hfta_vstr_assign_with_copy(vstring *dst, vstring *src){
79 dst->length=src->length;
81 dst->offset=(gs_p_t)malloc(dst->length);
82 memcpy((gs_sp_t)(dst->offset),(gs_sp_t)(src->offset),dst->length);
84 dst->reserved=INTERNAL;
87 // Ted wrote the following function.
88 // Make a deep copy of src. garbage collect dst if needed.
89 // Assume that SRC is either INTERNAL or SHALLOW_COPY
90 void hfta_vstr_replace(vstring *dst, vstring *src){
91 hfta_vstr_destroy(dst);
92 hfta_vstr_assign_with_copy(dst,src);
95 #define HFTA_VSTR_LHASHFUNC_PRIME 12916008961267169387ull
96 gs_uint64_t hfta_vstr_long_hashfunc(const vstring *s) {
97 gs_uint64_t hash_code;
99 gs_int32_t substr_len;
101 gs_uint64_t sub_hash;
104 sv=(gs_sp_t)(s->offset);
106 n_steps = s->length / 4;
107 if(4*n_steps < s->length) n_steps++;
109 for (j = 0; j < n_steps; j++) {
110 if(4*(j+1) < s->length) substr_len = 4;
111 else substr_len = s->length - 4*j;
116 sub_hash = (sub_hash << 4) + *sv;
118 sub_hash = (sub_hash << 4);
122 hash_code = (sub_hash + hash_code * HFTA_VSTR_LHASHFUNC_PRIME);
128 #define HFTA_VSTR_HASHFUNC_PRIME 2995999
129 gs_uint32_t hfta_vstr_hashfunc(const vstring *s) {
130 gs_uint32_t hash_code;
132 gs_int32_t substr_len;
134 gs_uint32_t k, sub_hash;
137 sv=(gs_sp_t)(s->offset);
139 n_steps = s->length / 4;
140 if(4*n_steps < s->length) n_steps++;
142 for (j = 0; j < n_steps; j++) {
143 if(4*(j+1) < s->length) substr_len = 4;
144 else substr_len = s->length - 4*j;
149 sub_hash = (sub_hash << 4) + *sv;
151 sub_hash = (sub_hash << 4);
155 hash_code = (sub_hash + hash_code * HFTA_VSTR_HASHFUNC_PRIME);
162 // return negative if s1 < s2, 0 if s1==s2, positive if s1>s2
163 gs_retval_t hfta_vstr_compare(const vstring * s1, const vstring * s2) {
164 gs_int32_t minlen,cmp_ret;
165 minlen=(s1->length<s2->length?s1->length:s2->length);
166 cmp_ret=memcmp((void *)s1->offset,(void *)s2->offset,minlen);
168 if(cmp_ret) return cmp_ret;
169 return(s1->length - s2->length);
174 gs_param_handle_t register_handle_for_str_regex_match_slot_1(vstring* pattern) {
178 if ((reg=(regex_t *) malloc(sizeof(regex_t)))==0) {
179 gslog(LOG_EMERG, "No memory for regular expression %s\n",
180 (gs_sp_t)(pattern->offset));
184 if (regcomp(reg,(char*)(pattern->offset), REG_NEWLINE|REG_EXTENDED|REG_NOSUB)!=0) {
185 gslog(LOG_EMERG, "Illegal regular expression %s\n",
186 (gs_sp_t)(pattern->offset));
189 return (gs_param_handle_t) reg;
192 gs_uint32_t str_regex_match(vstring* str, gs_param_handle_t pattern_handle) {
193 regex_t * reg = (regex_t *) pattern_handle ;
196 static gs_uint32_t dlen=0;
197 // grow our static buffer to the longest string we ever see
198 if ((str->length+1) >= dlen) {
199 if (d!=0) free((void*)d);
202 if ((d=(gs_sp_t)malloc(str->length+1))==0) return 0;
206 if (str->length==0) return 0;
208 // copy the string and 0 terminate it
209 memcpy((void *)d,(void *) str->offset, str->length);
213 res = regexec(reg, d, 0, NULL, 0);
214 return (res==REG_NOMATCH)?0:1;
217 gs_retval_t deregister_handle_for_str_regex_match_slot_1(gs_param_handle_t handle) {
218 regex_t * x = (regex_t *) handle;
224 gs_param_handle_t register_handle_for_str_partial_regex_match_slot_1(vstring* pattern) {
228 if ((reg=(regex_t *) malloc(sizeof(regex_t)))==0) {
229 gslog(LOG_EMERG, "No memory for regular expression %s\n",
230 (gs_sp_t)(pattern->offset));
234 if (regcomp(reg,(gs_sp_t)(pattern->offset), REG_NEWLINE|REG_EXTENDED|REG_NOSUB)!=0) {
235 gslog(LOG_EMERG, "Illegal regular expression %s\n",
236 (gs_sp_t)(pattern->offset));
239 return (gs_param_handle_t) reg;
242 gs_uint32_t str_partial_regex_match(vstring* str, gs_param_handle_t pattern_handle,
244 regex_t * reg = (regex_t *) pattern_handle ;
248 static gs_uint32_t dlen=0;
249 // grow our static buffer to the longest string we ever see
250 if ((str->length+1) >= dlen) {
251 if (d!=0) free((void*)d);
254 if ((d=(gs_sp_t)malloc(str->length+1))==0) return 0;
258 if (str->length==0) return 0;
260 end=(maxlen>(str->length))?(str->length):maxlen;
262 // copy the string and 0 terminate it
263 memcpy((void *)d,(void *) str->offset, end);
267 res = regexec(reg, d,0, NULL, 0);
268 return (res==REG_NOMATCH)?0:1;
272 gs_retval_t deregister_handle_for_str_partial_regex_match_slot_1(
273 gs_param_handle_t handle) {
274 regex_t * x = (regex_t *) handle;
280 gs_param_handle_t register_handle_for_str_extract_regex_slot_1(vstring* pattern) {
283 if ((reg=(regex_t *) malloc(sizeof(regex_t)))==0) {
284 gslog(LOG_EMERG, "No memory for regular expression %s\n",
285 (gs_sp_t)(pattern->offset));
288 if (regcomp(reg,(gs_sp_t)(pattern->offset), REG_EXTENDED)!=0) {
289 gslog(LOG_EMERG, "Illegal regular expression %s\n",
290 (gs_sp_t)(pattern->offset));
293 return (gs_param_handle_t) reg;
297 /* partial function return 0 if the value is valid */
298 gs_retval_t str_extract_regex( vstring * result, vstring * str, gs_param_handle_t handle) {
299 regex_t * reg = (regex_t *) handle ;
300 gs_sp_t source = (gs_sp_t)(str->offset);
304 static gs_uint32_t dlen=0;
305 // grow our static buffer to the longest string we ever see
306 if ((str->length+1) >= dlen) {
307 if (d!=0) free((void*)d);
310 if ((d=(gs_sp_t)malloc(str->length+1))==0) return 1;
314 if (str->length==0) return 1;
316 // copy the string and 0 terminate it
317 memcpy((void *)d,(void *) str->offset, str->length);
321 res = regexec(reg, d, 1, &match, 0);
322 if (res==REG_NOMATCH) return 1;
323 result->offset= (gs_p_t) &source[match.rm_so];
324 result->length=match.rm_eo-match.rm_so;
325 result->reserved = SHALLOW_COPY;
329 gs_retval_t deregister_handle_for_str_extract_regex_slot_1(gs_param_handle_t handle) {
330 regex_t * x = (regex_t *) handle;
337 static gs_uint32_t nextint(struct vstring *str , gs_uint32_t * offset, gs_uint32_t *res) {
338 gs_uint8_t * s = (gs_uint8_t *)(str->offset);
341 while(*offset<str->length) {
342 if ((s[*offset]>='0') && (s[*offset]<='9')) {
344 *res= (*res*10) + (gs_uint32_t) (s[*offset]-'0');
346 if (v!=0) { // got some valid result
348 } // otherwise skip leading grabage
355 gs_uint32_t strtoi(gs_uint32_t * r, struct vstring * s)
359 if (nextint(s,&offset,r)==0) return 1;
363 gs_param_handle_t register_handle_for_strtoi_c_slot_0(vstring* istr) {
364 gs_uint32_t offset,r;
366 if (nextint(istr,&offset,&r)!=0)
367 return (gs_param_handle_t) r;
368 return (gs_param_handle_t) 0;
370 gs_retval_t deregister_handle_for_strtoi_c_slot_0(gs_param_handle_t h) {
375 gs_uint32_t strtoip(gs_uint32_t * r, struct vstring * s)
377 gs_uint32_t ip1,ip2,ip3,ip4,offset;
379 if (nextint(s,&offset,&ip1)==0) return 1;
380 //fprintf (stderr, "1 %u %u\n",ip1,offset);
381 if (nextint(s,&offset,&ip2)==0) return 1;
382 //fprintf (stderr, "2 %u %u\n",ip2,offset);
383 if (nextint(s,&offset,&ip3)==0) return 1;
384 //fprintf (stderr, "3 %u %u\n",ip3,offset);
385 if (nextint(s,&offset,&ip4)==0) return 1;
386 //fprintf (stderr, "4 %u %u\n",ip4,offset);
387 *r=ip1<<24|ip2<<16|ip3<<8|ip4;
391 gs_param_handle_t register_handle_for_strtoip_c_slot_0(vstring* istr) {
392 gs_uint32_t ip1,ip2,ip3,ip4,offset,r;
394 if (nextint(istr,&offset,&ip1)==0) return (gs_param_handle_t)0;
395 if (nextint(istr,&offset,&ip2)==0) return (gs_param_handle_t)0;
396 if (nextint(istr,&offset,&ip3)==0) return (gs_param_handle_t)0;
397 if (nextint(istr,&offset,&ip4)==0) return (gs_param_handle_t)0;
398 r=ip1<<24|ip2<<16|ip3<<8|ip4;
399 return (gs_param_handle_t)r;
401 gs_retval_t deregister_handle_for_strtoip_c_slot_0(gs_param_handle_t h) {
405 gs_uint32_t partn_hash( gs_uint32_t ip1, gs_uint32_t ip2) {
409 gs_uint32_t rand_hash() {
413 ///////////////////////////////////////
415 // return negative if s1 < s2, 0 if s1==s2, positive if s1>s2
416 gs_retval_t hfta_ipv6_compare(const hfta_ipv6_str &i1, const hfta_ipv6_str &i2) {
417 if(i1.v[0] > i2.v[0])
419 if(i1.v[0] < i2.v[0])
421 if(i1.v[1] > i2.v[1])
423 if(i1.v[1] < i2.v[1])
425 if(i1.v[2] > i2.v[2])
427 if(i1.v[2] < i2.v[2])
429 if(i1.v[3] > i2.v[3])
431 if(i1.v[3] < i2.v[3])
437 hfta_ipv6_str And_Ipv6(const hfta_ipv6_str &i1, const hfta_ipv6_str &i2){
439 ret.v[0] = i1.v[0] & i2.v[0];
440 ret.v[1] = i1.v[1] & i2.v[1];
441 ret.v[2] = i1.v[2] & i2.v[2];
442 ret.v[3] = i1.v[3] & i2.v[3];
446 hfta_ipv6_str Or_Ipv6(const hfta_ipv6_str &i1, const hfta_ipv6_str &i2){
448 ret.v[0] = i1.v[0] | i2.v[0];
449 ret.v[1] = i1.v[1] | i2.v[1];
450 ret.v[2] = i1.v[2] | i2.v[2];
451 ret.v[3] = i1.v[3] | i2.v[3];
455 gs_uint32_t hfta_ipv6_hashfunc(const hfta_ipv6_str *s) {
456 return s->v[0] ^ s->v[1] ^ s->v[2] ^ s->v[3];
459 hfta_ipv6_str hton_ipv6(hfta_ipv6_str s){
462 // ret.v[0] = htonl(s.v[0]);
463 // ret.v[1] = htonl(s.v[1]);
464 // ret.v[2] = htonl(s.v[2]);
465 // ret.v[3] = htonl(s.v[3]);
473 hfta_ipv6_str ntoh_ipv6(hfta_ipv6_str s){
475 // ret.v[0] = ntohl(s.v[0]);
476 // ret.v[1] = ntohl(s.v[1]);
477 // ret.v[2] = ntohl(s.v[2]);
478 // ret.v[3] = ntohl(s.v[3]);
486 int HFTA_Ipv6_Constructor(hfta_ipv6_str *s, gs_csp_t l) {
487 gs_uint32_t i0=0,i1=0,i2=0,i3=0,i4=0,i5=0,i6=0,i7=0;
488 sscanf(l,"%x:%x:%x:%x:%x:%x:%x:%x",&i0,&i1,&i2,&i3,&i4,&i5,&i6,&i7);
489 s->v[0] = ((i0 & 0xffff) << 16) | (i1 & 0xffff);
490 s->v[1] = ((i2 & 0xffff) << 16) | (i3 & 0xffff);
491 s->v[2] = ((i4 & 0xffff) << 16) | (i5 & 0xffff);
492 s->v[3] = ((i6 & 0xffff) << 16) | (i7 & 0xffff);
496 gs_retval_t str_exists_substr(vstring * s1,vstring * s2)
498 gs_uint8_t *st1 = (gs_uint8_t *)s1->offset;
499 gs_uint8_t *st2 = (gs_uint8_t *)s2->offset;
500 gs_uint8_t *s2f = (gs_uint8_t *)s2->offset;
501 gs_uint8_t len1 = s1->length-s2->length;
502 gs_uint8_t len2 = s2->length;
505 for (x=0; x<len1 ; x++)
509 for (y=0; y<len2 && st1[x+y]==st2[y];y++);
517 gs_retval_t str_compare(vstring *s1,vstring *s2)
519 return hfta_vstr_compare(s1,s2);
522 gs_uint32_t str_match_offset( gs_uint32_t offset, vstring *s1, vstring *s2)
524 gs_uint8_t *st1 = (gs_uint8_t *)s1->offset;
525 gs_uint8_t *st2 = &(((gs_uint8_t *)s2->offset)[offset]);
527 gs_int32_t len2 = s2->length-offset;
528 gs_int32_t len1 = s1->length;
533 for(x = 0; x < len1; x++)
535 if (st1[x] != st2[x])
541 gs_uint32_t byte_match_offset( gs_uint32_t offset, gs_uint32_t val,vstring *s2)
543 gs_uint8_t *st2 = (gs_uint8_t *)s2->offset;
544 gs_uint8_t v = (unsigned char) val;
546 // if ((s2->length <= offset)||(offset<0))
547 if (s2->length <= offset)
550 return (st2[offset]==v)?1:0;