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_HASHFUNC_PRIME 2995999
96 gs_uint32_t hfta_vstr_hashfunc(const vstring *s) {
97 gs_uint32_t hash_code;
99 gs_int32_t substr_len;
101 gs_uint32_t k, sub_hash;
105 sv=(gs_sp_t)(s->offset);
107 n_steps = s->length / 4;
108 if(4*n_steps < s->length) n_steps++;
110 for (j = 0; j < n_steps; j++) {
111 if(4*(j+1) < s->length) substr_len = 4;
112 else substr_len = s->length - 4*j;
117 sub_hash = (sub_hash << 4) + *sv;
119 sub_hash = (sub_hash << 4);
123 hash_code = (sub_hash + hash_code * HFTA_VSTR_HASHFUNC_PRIME);
129 // return negative if s1 < s2, 0 if s1==s2, positive if s1>s2
130 gs_retval_t hfta_vstr_compare(const vstring * s1, const vstring * s2) {
131 gs_int32_t minlen,cmp_ret;
132 minlen=(s1->length<s2->length?s1->length:s2->length);
133 cmp_ret=memcmp((void *)s1->offset,(void *)s2->offset,minlen);
135 if(cmp_ret) return cmp_ret;
136 return(s1->length - s2->length);
141 gs_param_handle_t register_handle_for_str_regex_match_slot_1(vstring* pattern) {
145 if ((reg=(regex_t *) malloc(sizeof(regex_t)))==0) {
146 gslog(LOG_EMERG, "No memory for regular expression %s\n",
147 (gs_sp_t)(pattern->offset));
151 if (regcomp(reg,(char*)(pattern->offset), REG_NEWLINE|REG_EXTENDED|REG_NOSUB)!=0) {
152 gslog(LOG_EMERG, "Illegal regular expression %s\n",
153 (gs_sp_t)(pattern->offset));
156 return (gs_param_handle_t) reg;
159 gs_uint32_t str_regex_match(vstring* str, gs_param_handle_t pattern_handle) {
160 regex_t * reg = (regex_t *) pattern_handle ;
163 static gs_uint32_t dlen=0;
164 // grow our static buffer to the longest string we ever see
165 if ((str->length+1) >= dlen) {
166 if (d!=0) free((void*)d);
169 if ((d=(gs_sp_t)malloc(str->length+1))==0) return 0;
173 if (str->length==0) return 0;
175 // copy the string and 0 terminate it
176 memcpy((void *)d,(void *) str->offset, str->length);
180 res = regexec(reg, d, 0, NULL, 0);
181 return (res==REG_NOMATCH)?0:1;
184 gs_retval_t deregister_handle_for_str_regex_match_slot_1(gs_param_handle_t handle) {
185 regex_t * x = (regex_t *) handle;
191 gs_param_handle_t register_handle_for_str_partial_regex_match_slot_1(vstring* pattern) {
195 if ((reg=(regex_t *) malloc(sizeof(regex_t)))==0) {
196 gslog(LOG_EMERG, "No memory for regular expression %s\n",
197 (gs_sp_t)(pattern->offset));
201 if (regcomp(reg,(gs_sp_t)(pattern->offset), REG_NEWLINE|REG_EXTENDED|REG_NOSUB)!=0) {
202 gslog(LOG_EMERG, "Illegal regular expression %s\n",
203 (gs_sp_t)(pattern->offset));
206 return (gs_param_handle_t) reg;
209 gs_uint32_t str_partial_regex_match(vstring* str, gs_param_handle_t pattern_handle,
211 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 end=(maxlen>(str->length))?(str->length):maxlen;
229 // copy the string and 0 terminate it
230 memcpy((void *)d,(void *) str->offset, end);
234 res = regexec(reg, d,0, NULL, 0);
235 return (res==REG_NOMATCH)?0:1;
239 gs_retval_t deregister_handle_for_str_partial_regex_match_slot_1(
240 gs_param_handle_t handle) {
241 regex_t * x = (regex_t *) handle;
247 gs_param_handle_t register_handle_for_str_extract_regex_slot_1(vstring* pattern) {
250 if ((reg=(regex_t *) malloc(sizeof(regex_t)))==0) {
251 gslog(LOG_EMERG, "No memory for regular expression %s\n",
252 (gs_sp_t)(pattern->offset));
255 if (regcomp(reg,(gs_sp_t)(pattern->offset), REG_EXTENDED)!=0) {
256 gslog(LOG_EMERG, "Illegal regular expression %s\n",
257 (gs_sp_t)(pattern->offset));
260 return (gs_param_handle_t) reg;
264 /* partial function return 0 if the value is valid */
265 gs_retval_t str_extract_regex( vstring * result, vstring * str, gs_param_handle_t handle) {
266 regex_t * reg = (regex_t *) handle ;
267 gs_sp_t source = (gs_sp_t)(str->offset);
271 static gs_uint32_t dlen=0;
272 // grow our static buffer to the longest string we ever see
273 if ((str->length+1) >= dlen) {
274 if (d!=0) free((void*)d);
277 if ((d=(gs_sp_t)malloc(str->length+1))==0) return 1;
281 if (str->length==0) return 1;
283 // copy the string and 0 terminate it
284 memcpy((void *)d,(void *) str->offset, str->length);
288 res = regexec(reg, d, 1, &match, 0);
289 if (res==REG_NOMATCH) return 1;
290 result->offset= (gs_p_t) &source[match.rm_so];
291 result->length=match.rm_eo-match.rm_so;
292 result->reserved = SHALLOW_COPY;
296 gs_retval_t deregister_handle_for_str_extract_regex_slot_1(gs_param_handle_t handle) {
297 regex_t * x = (regex_t *) handle;
304 static gs_uint32_t nextint(struct vstring *str , gs_uint32_t * offset, gs_uint32_t *res) {
305 gs_uint8_t * s = (gs_uint8_t *)(str->offset);
308 while(*offset<str->length) {
309 if ((s[*offset]>='0') && (s[*offset]<='9')) {
311 *res= (*res*10) + (gs_uint32_t) (s[*offset]-'0');
313 if (v!=0) { // got some valid result
315 } // otherwise skip leading grabage
322 gs_uint32_t strtoi(gs_uint32_t * r, struct vstring * s)
326 if (nextint(s,&offset,r)==0) return 1;
330 gs_param_handle_t register_handle_for_strtoi_c_slot_0(vstring* istr) {
331 gs_uint32_t offset,r;
333 if (nextint(istr,&offset,&r)!=0)
334 return (gs_param_handle_t) r;
335 return (gs_param_handle_t) 0;
337 gs_retval_t deregister_handle_for_strtoi_c_slot_0(gs_param_handle_t h) {
342 gs_uint32_t strtoip(gs_uint32_t * r, struct vstring * s)
344 gs_uint32_t ip1,ip2,ip3,ip4,offset;
346 if (nextint(s,&offset,&ip1)==0) return 1;
347 //fprintf (stderr, "1 %u %u\n",ip1,offset);
348 if (nextint(s,&offset,&ip2)==0) return 1;
349 //fprintf (stderr, "2 %u %u\n",ip2,offset);
350 if (nextint(s,&offset,&ip3)==0) return 1;
351 //fprintf (stderr, "3 %u %u\n",ip3,offset);
352 if (nextint(s,&offset,&ip4)==0) return 1;
353 //fprintf (stderr, "4 %u %u\n",ip4,offset);
354 *r=ip1<<24|ip2<<16|ip3<<8|ip4;
358 gs_param_handle_t register_handle_for_strtoip_c_slot_0(vstring* istr) {
359 gs_uint32_t ip1,ip2,ip3,ip4,offset,r;
361 if (nextint(istr,&offset,&ip1)==0) return (gs_param_handle_t)0;
362 if (nextint(istr,&offset,&ip2)==0) return (gs_param_handle_t)0;
363 if (nextint(istr,&offset,&ip3)==0) return (gs_param_handle_t)0;
364 if (nextint(istr,&offset,&ip4)==0) return (gs_param_handle_t)0;
365 r=ip1<<24|ip2<<16|ip3<<8|ip4;
366 return (gs_param_handle_t)r;
368 gs_retval_t deregister_handle_for_strtoip_c_slot_0(gs_param_handle_t h) {
372 gs_uint32_t partn_hash( gs_uint32_t ip1, gs_uint32_t ip2) {
376 gs_uint32_t rand_hash() {
380 ///////////////////////////////////////
382 // return negative if s1 < s2, 0 if s1==s2, positive if s1>s2
383 gs_retval_t hfta_ipv6_compare(const hfta_ipv6_str &i1, const hfta_ipv6_str &i2) {
384 if(i1.v[0] > i2.v[0])
386 if(i1.v[0] < i2.v[0])
388 if(i1.v[1] > i2.v[1])
390 if(i1.v[1] < i2.v[1])
392 if(i1.v[2] > i2.v[2])
394 if(i1.v[2] < i2.v[2])
396 if(i1.v[3] > i2.v[3])
398 if(i1.v[3] < i2.v[3])
404 hfta_ipv6_str And_Ipv6(const hfta_ipv6_str &i1, const hfta_ipv6_str &i2){
406 ret.v[0] = i1.v[0] & i2.v[0];
407 ret.v[1] = i1.v[1] & i2.v[1];
408 ret.v[2] = i1.v[2] & i2.v[2];
409 ret.v[3] = i1.v[3] & i2.v[3];
413 hfta_ipv6_str Or_Ipv6(const hfta_ipv6_str &i1, const hfta_ipv6_str &i2){
415 ret.v[0] = i1.v[0] | i2.v[0];
416 ret.v[1] = i1.v[1] | i2.v[1];
417 ret.v[2] = i1.v[2] | i2.v[2];
418 ret.v[3] = i1.v[3] | i2.v[3];
422 gs_uint32_t hfta_ipv6_hashfunc(const hfta_ipv6_str *s) {
423 return s->v[0] ^ s->v[1] ^ s->v[2] ^ s->v[3];
426 hfta_ipv6_str hton_ipv6(hfta_ipv6_str s){
429 // ret.v[0] = htonl(s.v[0]);
430 // ret.v[1] = htonl(s.v[1]);
431 // ret.v[2] = htonl(s.v[2]);
432 // ret.v[3] = htonl(s.v[3]);
440 hfta_ipv6_str ntoh_ipv6(hfta_ipv6_str s){
442 // ret.v[0] = ntohl(s.v[0]);
443 // ret.v[1] = ntohl(s.v[1]);
444 // ret.v[2] = ntohl(s.v[2]);
445 // ret.v[3] = ntohl(s.v[3]);
453 int HFTA_Ipv6_Constructor(hfta_ipv6_str *s, gs_csp_t l) {
454 gs_uint32_t i0=0,i1=0,i2=0,i3=0,i4=0,i5=0,i6=0,i7=0;
455 sscanf(l,"%x:%x:%x:%x:%x:%x:%x:%x",&i0,&i1,&i2,&i3,&i4,&i5,&i6,&i7);
456 s->v[0] = ((i0 & 0xffff) << 16) | (i1 & 0xffff);
457 s->v[1] = ((i2 & 0xffff) << 16) | (i3 & 0xffff);
458 s->v[2] = ((i4 & 0xffff) << 16) | (i5 & 0xffff);
459 s->v[3] = ((i6 & 0xffff) << 16) | (i7 & 0xffff);
463 gs_retval_t str_exists_substr(vstring * s1,vstring * s2)
465 gs_uint8_t *st1 = (gs_uint8_t *)s1->offset;
466 gs_uint8_t *st2 = (gs_uint8_t *)s2->offset;
467 gs_uint8_t *s2f = (gs_uint8_t *)s2->offset;
468 gs_uint8_t len1 = s1->length-s2->length;
469 gs_uint8_t len2 = s2->length;
472 for (x=0; x<len1 ; x++)
476 for (y=0; y<len2 && st1[x+y]==st2[y];y++);
484 gs_retval_t str_compare(vstring *s1,vstring *s2)
486 return hfta_vstr_compare(s1,s2);
489 gs_uint32_t str_match_offset( gs_uint32_t offset, vstring *s1, vstring *s2)
491 gs_uint8_t *st1 = (gs_uint8_t *)s1->offset;
492 gs_uint8_t *st2 = &(((gs_uint8_t *)s2->offset)[offset]);
494 gs_int32_t len2 = s2->length-offset;
495 gs_int32_t len1 = s1->length;
500 for(x = 0; x < len1; x++)
502 if (st1[x] != st2[x])
508 gs_uint32_t byte_match_offset( gs_uint32_t offset, gs_uint32_t val,vstring *s2)
510 gs_uint8_t *st2 = (gs_uint8_t *)s2->offset;
511 gs_uint8_t v = (unsigned char) val;
513 // if ((s2->length <= offset)||(offset<0))
514 if (s2->length <= offset)
517 return (st2[offset]==v)?1:0;