调整目录结构

This commit is contained in:
崔一鸣
2019-05-09 15:14:01 +08:00
parent a48d99ec26
commit 5cda54c8d4
26 changed files with 674 additions and 6951 deletions

1
.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
.vscode/*

View File

@@ -1,34 +0,0 @@
CC = g++
CFLAGS = -g -Wall -fPIC
OBJECTS = kni_entry.o kni_comm.o kni_intercept.o kni_ratelimit.o kni_replace.o cJSON.o kni_sendlog.o kni_redirect.o
TARGET = kni.so
INCS = -I./
#INCS += -I/opt/MESA/include/
INCS += -I/opt/MESA/include/MESA
LD_DICTATOR =-L/opt/MESA/lib
MODULES = -lMESA_htable -lMESA_prof_load -lMESA_handle_logger -lrulescan -lmaatframe -lpcre -lssl -lrdkafka
.c.o:
$(CC) -c -o $@ $(CFLAGS) $(INCS) $<
.PHONY: all clean
all: $(TARGET)
$(TARGET):$(OBJECTS)
$(CC) -o $(TARGET) $(CFLAGS) $(OBJECTS) $(MODULES) $(LD_DICTATOR) -shared
# $(CC) -o $(TARGET) $(CFLAGS) $(OBJECTS) $(MODULES) -Wl,--whole-archive $(WHOLE_MODULES) -wL,--NO-WHOLE-ARCHIVE $(LD_DICTATOR)
kni_entry.o:kni_entry.c
kni_comm.o:kni_comm.c
kni_intercept.o:kni_intercept.c
kni_ratelimit.o:kni_ratelimit.c
kni_replace.o:kni_replace.c
cJSON.o:cJSON.c
kni_sendlog.o:kni_sendlog.c
kni_redirect.o:kni_redirect.c
clean:
rm -f $(TARGET) $(OBJECTS)

596
cJSON.c
View File

@@ -1,596 +0,0 @@
/*
Copyright (c) 2009 Dave Gamble
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
/* cJSON */
/* JSON parser in C. */
#include <string.h>
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <float.h>
#include <limits.h>
#include <ctype.h>
#include "cJSON.h"
static const char *ep;
const char *cJSON_GetErrorPtr(void) {return ep;}
static int cJSON_strcasecmp(const char *s1,const char *s2)
{
if (!s1) return (s1==s2)?0:1;if (!s2) return 1;
for(; tolower(*s1) == tolower(*s2); ++s1, ++s2) if(*s1 == 0) return 0;
return tolower(*(const unsigned char *)s1) - tolower(*(const unsigned char *)s2);
}
static void *(*cJSON_malloc)(size_t sz) = malloc;
static void (*cJSON_free)(void *ptr) = free;
static char* cJSON_strdup(const char* str)
{
size_t len;
char* copy;
len = strlen(str) + 1;
if (!(copy = (char*)cJSON_malloc(len))) return 0;
memcpy(copy,str,len);
return copy;
}
void cJSON_InitHooks(cJSON_Hooks* hooks)
{
if (!hooks) { /* Reset hooks */
cJSON_malloc = malloc;
cJSON_free = free;
return;
}
cJSON_malloc = (hooks->malloc_fn)?hooks->malloc_fn:malloc;
cJSON_free = (hooks->free_fn)?hooks->free_fn:free;
}
/* Internal constructor. */
static cJSON *cJSON_New_Item(void)
{
cJSON* node = (cJSON*)cJSON_malloc(sizeof(cJSON));
if (node) memset(node,0,sizeof(cJSON));
return node;
}
/* Delete a cJSON structure. */
void cJSON_Delete(cJSON *c)
{
cJSON *next;
while (c)
{
next=c->next;
if (!(c->type&cJSON_IsReference) && c->child) cJSON_Delete(c->child);
if (!(c->type&cJSON_IsReference) && c->valuestring) cJSON_free(c->valuestring);
if (c->string) cJSON_free(c->string);
cJSON_free(c);
c=next;
}
}
/* Parse the input text to generate a number, and populate the result into item. */
static const char *parse_number(cJSON *item,const char *num)
{
double n=0,sign=1,scale=0;int subscale=0,signsubscale=1;
if (*num=='-') sign=-1,num++; /* Has sign? */
if (*num=='0') num++; /* is zero */
if (*num>='1' && *num<='9') do n=(n*10.0)+(*num++ -'0'); while (*num>='0' && *num<='9'); /* Number? */
if (*num=='.' && num[1]>='0' && num[1]<='9') {num++; do n=(n*10.0)+(*num++ -'0'),scale--; while (*num>='0' && *num<='9');} /* Fractional part? */
if (*num=='e' || *num=='E') /* Exponent? */
{ num++;if (*num=='+') num++; else if (*num=='-') signsubscale=-1,num++; /* With sign? */
while (*num>='0' && *num<='9') subscale=(subscale*10)+(*num++ - '0'); /* Number? */
}
n=sign*n*pow(10.0,(scale+subscale*signsubscale)); /* number = +/- number.fraction * 10^+/- exponent */
item->valuedouble=n;
item->valueint=(int)n;
item->type=cJSON_Number;
return num;
}
/* Render the number nicely from the given item into a string. */
static char *print_number(cJSON *item)
{
char *str;
double d=item->valuedouble;
if (fabs(((double)item->valueint)-d)<=DBL_EPSILON && d<=INT_MAX && d>=INT_MIN)
{
str=(char*)cJSON_malloc(21); /* 2^64+1 can be represented in 21 chars. */
if (str) sprintf(str,"%d",item->valueint);
}
else
{
str=(char*)cJSON_malloc(64); /* This is a nice tradeoff. */
if (str)
{
if (fabs(floor(d)-d)<=DBL_EPSILON && fabs(d)<1.0e60)sprintf(str,"%.0f",d);
else if (fabs(d)<1.0e-6 || fabs(d)>1.0e9) sprintf(str,"%e",d);
else sprintf(str,"%f",d);
}
}
return str;
}
static unsigned parse_hex4(const char *str)
{
unsigned h=0;
if (*str>='0' && *str<='9') h+=(*str)-'0'; else if (*str>='A' && *str<='F') h+=10+(*str)-'A'; else if (*str>='a' && *str<='f') h+=10+(*str)-'a'; else return 0;
h=h<<4;str++;
if (*str>='0' && *str<='9') h+=(*str)-'0'; else if (*str>='A' && *str<='F') h+=10+(*str)-'A'; else if (*str>='a' && *str<='f') h+=10+(*str)-'a'; else return 0;
h=h<<4;str++;
if (*str>='0' && *str<='9') h+=(*str)-'0'; else if (*str>='A' && *str<='F') h+=10+(*str)-'A'; else if (*str>='a' && *str<='f') h+=10+(*str)-'a'; else return 0;
h=h<<4;str++;
if (*str>='0' && *str<='9') h+=(*str)-'0'; else if (*str>='A' && *str<='F') h+=10+(*str)-'A'; else if (*str>='a' && *str<='f') h+=10+(*str)-'a'; else return 0;
return h;
}
/* Parse the input text into an unescaped cstring, and populate item. */
static const unsigned char firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
static const char *parse_string(cJSON *item,const char *str)
{
const char *ptr=str+1;char *ptr2;char *out;int len=0;unsigned uc,uc2;
if (*str!='\"') {ep=str;return 0;} /* not a string! */
while (*ptr!='\"' && *ptr && ++len) if (*ptr++ == '\\') ptr++; /* Skip escaped quotes. */
out=(char*)cJSON_malloc(len+1); /* This is how long we need for the string, roughly. */
if (!out) return 0;
ptr=str+1;ptr2=out;
while (*ptr!='\"' && *ptr)
{
if (*ptr!='\\') *ptr2++=*ptr++;
else
{
ptr++;
switch (*ptr)
{
case 'b': *ptr2++='\b'; break;
case 'f': *ptr2++='\f'; break;
case 'n': *ptr2++='\n'; break;
case 'r': *ptr2++='\r'; break;
case 't': *ptr2++='\t'; break;
case 'u': /* transcode utf16 to utf8. */
uc=parse_hex4(ptr+1);ptr+=4; /* get the unicode char. */
if ((uc>=0xDC00 && uc<=0xDFFF) || uc==0) break; /* check for invalid. */
if (uc>=0xD800 && uc<=0xDBFF) /* UTF16 surrogate pairs. */
{
if (ptr[1]!='\\' || ptr[2]!='u') break; /* missing second-half of surrogate. */
uc2=parse_hex4(ptr+3);ptr+=6;
if (uc2<0xDC00 || uc2>0xDFFF) break; /* invalid second-half of surrogate. */
uc=0x10000 + (((uc&0x3FF)<<10) | (uc2&0x3FF));
}
len=4;if (uc<0x80) len=1;else if (uc<0x800) len=2;else if (uc<0x10000) len=3; ptr2+=len;
switch (len) {
case 4: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
case 3: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
case 2: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
case 1: *--ptr2 =(uc | firstByteMark[len]);
}
ptr2+=len;
break;
default: *ptr2++=*ptr; break;
}
ptr++;
}
}
*ptr2=0;
if (*ptr=='\"') ptr++;
item->valuestring=out;
item->type=cJSON_String;
return ptr;
}
/* Render the cstring provided to an escaped version that can be printed. */
static char *print_string_ptr(const char *str)
{
const char *ptr;char *ptr2,*out;int len=0;unsigned char token;
if (!str) return cJSON_strdup("");
ptr=str;while ((token=*ptr) && ++len) {if (strchr("\"\\\b\f\n\r\t",token)) len++; else if (token<32) len+=5;ptr++;}
out=(char*)cJSON_malloc(len+3);
if (!out) return 0;
ptr2=out;ptr=str;
*ptr2++='\"';
while (*ptr)
{
if ((unsigned char)*ptr>31 && *ptr!='\"' && *ptr!='\\') *ptr2++=*ptr++;
else
{
*ptr2++='\\';
switch (token=*ptr++)
{
case '\\': *ptr2++='\\'; break;
case '\"': *ptr2++='\"'; break;
case '\b': *ptr2++='b'; break;
case '\f': *ptr2++='f'; break;
case '\n': *ptr2++='n'; break;
case '\r': *ptr2++='r'; break;
case '\t': *ptr2++='t'; break;
default: sprintf(ptr2,"u%04x",token);ptr2+=5; break; /* escape and print */
}
}
}
*ptr2++='\"';*ptr2++=0;
return out;
}
/* Invote print_string_ptr (which is useful) on an item. */
static char *print_string(cJSON *item) {return print_string_ptr(item->valuestring);}
/* Predeclare these prototypes. */
static const char *parse_value(cJSON *item,const char *value);
static char *print_value(cJSON *item,int depth,int fmt);
static const char *parse_array(cJSON *item,const char *value);
static char *print_array(cJSON *item,int depth,int fmt);
static const char *parse_object(cJSON *item,const char *value);
static char *print_object(cJSON *item,int depth,int fmt);
/* Utility to jump whitespace and cr/lf */
static const char *skip(const char *in) {while (in && *in && (unsigned char)*in<=32) in++; return in;}
/* Parse an object - create a new root, and populate. */
cJSON *cJSON_ParseWithOpts(const char *value,const char **return_parse_end,int require_null_terminated)
{
const char *end=0;
cJSON *c=cJSON_New_Item();
ep=0;
if (!c) return 0; /* memory fail */
end=parse_value(c,skip(value));
if (!end) {cJSON_Delete(c);return 0;} /* parse failure. ep is set. */
/* if we require null-terminated JSON without appended garbage, skip and then check for a null terminator */
if (require_null_terminated) {end=skip(end);if (*end) {cJSON_Delete(c);ep=end;return 0;}}
if (return_parse_end) *return_parse_end=end;
return c;
}
/* Default options for cJSON_Parse */
cJSON *cJSON_Parse(const char *value) {return cJSON_ParseWithOpts(value,0,0);}
/* Render a cJSON item/entity/structure to text. */
char *cJSON_Print(cJSON *item) {return print_value(item,0,1);}
char *cJSON_PrintUnformatted(cJSON *item) {return print_value(item,0,0);}
/* Parser core - when encountering text, process appropriately. */
static const char *parse_value(cJSON *item,const char *value)
{
if (!value) return 0; /* Fail on null. */
if (!strncmp(value,"null",4)) { item->type=cJSON_NULL; return value+4; }
if (!strncmp(value,"false",5)) { item->type=cJSON_False; return value+5; }
if (!strncmp(value,"true",4)) { item->type=cJSON_True; item->valueint=1; return value+4; }
if (*value=='\"') { return parse_string(item,value); }
if (*value=='-' || (*value>='0' && *value<='9')) { return parse_number(item,value); }
if (*value=='[') { return parse_array(item,value); }
if (*value=='{') { return parse_object(item,value); }
ep=value;return 0; /* failure. */
}
/* Render a value to text. */
static char *print_value(cJSON *item,int depth,int fmt)
{
char *out=0;
if (!item) return 0;
switch ((item->type)&255)
{
case cJSON_NULL: out=cJSON_strdup("null"); break;
case cJSON_False: out=cJSON_strdup("false");break;
case cJSON_True: out=cJSON_strdup("true"); break;
case cJSON_Number: out=print_number(item);break;
case cJSON_String: out=print_string(item);break;
case cJSON_Array: out=print_array(item,depth,fmt);break;
case cJSON_Object: out=print_object(item,depth,fmt);break;
}
return out;
}
/* Build an array from input text. */
static const char *parse_array(cJSON *item,const char *value)
{
cJSON *child;
if (*value!='[') {ep=value;return 0;} /* not an array! */
item->type=cJSON_Array;
value=skip(value+1);
if (*value==']') return value+1; /* empty array. */
item->child=child=cJSON_New_Item();
if (!item->child) return 0; /* memory fail */
value=skip(parse_value(child,skip(value))); /* skip any spacing, get the value. */
if (!value) return 0;
while (*value==',')
{
cJSON *new_item;
if (!(new_item=cJSON_New_Item())) return 0; /* memory fail */
child->next=new_item;new_item->prev=child;child=new_item;
value=skip(parse_value(child,skip(value+1)));
if (!value) return 0; /* memory fail */
}
if (*value==']') return value+1; /* end of array */
ep=value;return 0; /* malformed. */
}
/* Render an array to text */
static char *print_array(cJSON *item,int depth,int fmt)
{
char **entries;
char *out=0,*ptr,*ret;int len=5;
cJSON *child=item->child;
int numentries=0,i=0,fail=0;
/* How many entries in the array? */
while (child) numentries++,child=child->next;
/* Explicitly handle numentries==0 */
if (!numentries)
{
out=(char*)cJSON_malloc(3);
if (out) strcpy(out,"[]");
return out;
}
/* Allocate an array to hold the values for each */
entries=(char**)cJSON_malloc(numentries*sizeof(char*));
if (!entries) return 0;
memset(entries,0,numentries*sizeof(char*));
/* Retrieve all the results: */
child=item->child;
while (child && !fail)
{
ret=print_value(child,depth+1,fmt);
entries[i++]=ret;
if (ret) len+=strlen(ret)+2+(fmt?1:0); else fail=1;
child=child->next;
}
/* If we didn't fail, try to malloc the output string */
if (!fail) out=(char*)cJSON_malloc(len);
/* If that fails, we fail. */
if (!out) fail=1;
/* Handle failure. */
if (fail)
{
for (i=0;i<numentries;i++) if (entries[i]) cJSON_free(entries[i]);
cJSON_free(entries);
return 0;
}
/* Compose the output array. */
*out='[';
ptr=out+1;*ptr=0;
for (i=0;i<numentries;i++)
{
strcpy(ptr,entries[i]);ptr+=strlen(entries[i]);
if (i!=numentries-1) {*ptr++=',';if(fmt)*ptr++=' ';*ptr=0;}
cJSON_free(entries[i]);
}
cJSON_free(entries);
*ptr++=']';*ptr++=0;
return out;
}
/* Build an object from the text. */
static const char *parse_object(cJSON *item,const char *value)
{
cJSON *child;
if (*value!='{') {ep=value;return 0;} /* not an object! */
item->type=cJSON_Object;
value=skip(value+1);
if (*value=='}') return value+1; /* empty array. */
item->child=child=cJSON_New_Item();
if (!item->child) return 0;
value=skip(parse_string(child,skip(value)));
if (!value) return 0;
child->string=child->valuestring;child->valuestring=0;
if (*value!=':') {ep=value;return 0;} /* fail! */
value=skip(parse_value(child,skip(value+1))); /* skip any spacing, get the value. */
if (!value) return 0;
while (*value==',')
{
cJSON *new_item;
if (!(new_item=cJSON_New_Item())) return 0; /* memory fail */
child->next=new_item;new_item->prev=child;child=new_item;
value=skip(parse_string(child,skip(value+1)));
if (!value) return 0;
child->string=child->valuestring;child->valuestring=0;
if (*value!=':') {ep=value;return 0;} /* fail! */
value=skip(parse_value(child,skip(value+1))); /* skip any spacing, get the value. */
if (!value) return 0;
}
if (*value=='}') return value+1; /* end of array */
ep=value;return 0; /* malformed. */
}
/* Render an object to text. */
static char *print_object(cJSON *item,int depth,int fmt)
{
char **entries=0,**names=0;
char *out=0,*ptr,*ret,*str;int len=7,i=0,j;
cJSON *child=item->child;
int numentries=0,fail=0;
/* Count the number of entries. */
while (child) numentries++,child=child->next;
/* Explicitly handle empty object case */
if (!numentries)
{
out=(char*)cJSON_malloc(fmt?depth+4:3);
if (!out) return 0;
ptr=out;*ptr++='{';
if (fmt) {*ptr++='\n';for (i=0;i<depth-1;i++) *ptr++='\t';}
*ptr++='}';*ptr++=0;
return out;
}
/* Allocate space for the names and the objects */
entries=(char**)cJSON_malloc(numentries*sizeof(char*));
if (!entries) return 0;
names=(char**)cJSON_malloc(numentries*sizeof(char*));
if (!names) {cJSON_free(entries);return 0;}
memset(entries,0,sizeof(char*)*numentries);
memset(names,0,sizeof(char*)*numentries);
/* Collect all the results into our arrays: */
child=item->child;depth++;if (fmt) len+=depth;
while (child)
{
names[i]=str=print_string_ptr(child->string);
entries[i++]=ret=print_value(child,depth,fmt);
if (str && ret) len+=strlen(ret)+strlen(str)+2+(fmt?2+depth:0); else fail=1;
child=child->next;
}
/* Try to allocate the output string */
if (!fail) out=(char*)cJSON_malloc(len);
if (!out) fail=1;
/* Handle failure */
if (fail)
{
for (i=0;i<numentries;i++) {if (names[i]) cJSON_free(names[i]);if (entries[i]) cJSON_free(entries[i]);}
cJSON_free(names);cJSON_free(entries);
return 0;
}
/* Compose the output: */
*out='{';ptr=out+1;if (fmt)*ptr++='\n';*ptr=0;
for (i=0;i<numentries;i++)
{
if (fmt) for (j=0;j<depth;j++) *ptr++='\t';
strcpy(ptr,names[i]);ptr+=strlen(names[i]);
*ptr++=':';if (fmt) *ptr++='\t';
strcpy(ptr,entries[i]);ptr+=strlen(entries[i]);
if (i!=numentries-1) *ptr++=',';
if (fmt) *ptr++='\n';*ptr=0;
cJSON_free(names[i]);cJSON_free(entries[i]);
}
cJSON_free(names);cJSON_free(entries);
if (fmt) for (i=0;i<depth-1;i++) *ptr++='\t';
*ptr++='}';*ptr++=0;
return out;
}
/* Get Array size/item / object item. */
int cJSON_GetArraySize(cJSON *array) {cJSON *c=array->child;int i=0;while(c)i++,c=c->next;return i;}
cJSON *cJSON_GetArrayItem(cJSON *array,int item) {cJSON *c=array->child; while (c && item>0) item--,c=c->next; return c;}
cJSON *cJSON_GetObjectItem(cJSON *object,const char *string) {cJSON *c=object->child; while (c && cJSON_strcasecmp(c->string,string)) c=c->next; return c;}
/* Utility for array list handling. */
static void suffix_object(cJSON *prev,cJSON *item) {prev->next=item;item->prev=prev;}
/* Utility for handling references. */
static cJSON *create_reference(cJSON *item) {cJSON *ref=cJSON_New_Item();if (!ref) return 0;memcpy(ref,item,sizeof(cJSON));ref->string=0;ref->type|=cJSON_IsReference;ref->next=ref->prev=0;return ref;}
/* Add item to array/object. */
void cJSON_AddItemToArray(cJSON *array, cJSON *item) {cJSON *c=array->child;if (!item) return; if (!c) {array->child=item;} else {while (c && c->next) c=c->next; suffix_object(c,item);}}
void cJSON_AddItemToObject(cJSON *object,const char *string,cJSON *item) {if (!item) return; if (item->string) cJSON_free(item->string);item->string=cJSON_strdup(string);cJSON_AddItemToArray(object,item);}
void cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item) {cJSON_AddItemToArray(array,create_reference(item));}
void cJSON_AddItemReferenceToObject(cJSON *object,const char *string,cJSON *item) {cJSON_AddItemToObject(object,string,create_reference(item));}
cJSON *cJSON_DetachItemFromArray(cJSON *array,int which) {cJSON *c=array->child;while (c && which>0) c=c->next,which--;if (!c) return 0;
if (c->prev) c->prev->next=c->next;if (c->next) c->next->prev=c->prev;if (c==array->child) array->child=c->next;c->prev=c->next=0;return c;}
void cJSON_DeleteItemFromArray(cJSON *array,int which) {cJSON_Delete(cJSON_DetachItemFromArray(array,which));}
cJSON *cJSON_DetachItemFromObject(cJSON *object,const char *string) {int i=0;cJSON *c=object->child;while (c && cJSON_strcasecmp(c->string,string)) i++,c=c->next;if (c) return cJSON_DetachItemFromArray(object,i);return 0;}
void cJSON_DeleteItemFromObject(cJSON *object,const char *string) {cJSON_Delete(cJSON_DetachItemFromObject(object,string));}
/* Replace array/object items with new ones. */
void cJSON_ReplaceItemInArray(cJSON *array,int which,cJSON *newitem) {cJSON *c=array->child;while (c && which>0) c=c->next,which--;if (!c) return;
newitem->next=c->next;newitem->prev=c->prev;if (newitem->next) newitem->next->prev=newitem;
if (c==array->child) array->child=newitem; else newitem->prev->next=newitem;c->next=c->prev=0;cJSON_Delete(c);}
void cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem){int i=0;cJSON *c=object->child;while(c && cJSON_strcasecmp(c->string,string))i++,c=c->next;if(c){newitem->string=cJSON_strdup(string);cJSON_ReplaceItemInArray(object,i,newitem);}}
/* Create basic types: */
cJSON *cJSON_CreateNull(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_NULL;return item;}
cJSON *cJSON_CreateTrue(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_True;return item;}
cJSON *cJSON_CreateFalse(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_False;return item;}
cJSON *cJSON_CreateBool(int b) {cJSON *item=cJSON_New_Item();if(item)item->type=b?cJSON_True:cJSON_False;return item;}
cJSON *cJSON_CreateNumber(double num) {cJSON *item=cJSON_New_Item();if(item){item->type=cJSON_Number;item->valuedouble=num;item->valueint=(int)num;}return item;}
cJSON *cJSON_CreateString(const char *string) {cJSON *item=cJSON_New_Item();if(item){item->type=cJSON_String;item->valuestring=cJSON_strdup(string);}return item;}
cJSON *cJSON_CreateArray(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_Array;return item;}
cJSON *cJSON_CreateObject(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_Object;return item;}
/* Create Arrays: */
cJSON *cJSON_CreateIntArray(const int *numbers,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && i<count;i++){n=cJSON_CreateNumber(numbers[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
cJSON *cJSON_CreateFloatArray(const float *numbers,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && i<count;i++){n=cJSON_CreateNumber(numbers[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
cJSON *cJSON_CreateDoubleArray(const double *numbers,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && i<count;i++){n=cJSON_CreateNumber(numbers[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
cJSON *cJSON_CreateStringArray(const char **strings,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && i<count;i++){n=cJSON_CreateString(strings[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
/* Duplication */
cJSON *cJSON_Duplicate(cJSON *item,int recurse)
{
cJSON *newitem,*cptr,*nptr=0,*newchild;
/* Bail on bad ptr */
if (!item) return 0;
/* Create new item */
newitem=cJSON_New_Item();
if (!newitem) return 0;
/* Copy over all vars */
newitem->type=item->type&(~cJSON_IsReference),newitem->valueint=item->valueint,newitem->valuedouble=item->valuedouble;
if (item->valuestring) {newitem->valuestring=cJSON_strdup(item->valuestring); if (!newitem->valuestring) {cJSON_Delete(newitem);return 0;}}
if (item->string) {newitem->string=cJSON_strdup(item->string); if (!newitem->string) {cJSON_Delete(newitem);return 0;}}
/* If non-recursive, then we're done! */
if (!recurse) return newitem;
/* Walk the ->next chain for the child. */
cptr=item->child;
while (cptr)
{
newchild=cJSON_Duplicate(cptr,1); /* Duplicate (with recurse) each item in the ->next chain */
if (!newchild) {cJSON_Delete(newitem);return 0;}
if (nptr) {nptr->next=newchild,newchild->prev=nptr;nptr=newchild;} /* If newitem->child already set, then crosswire ->prev and ->next and move on */
else {newitem->child=newchild;nptr=newchild;} /* Set newitem->child and move to it */
cptr=cptr->next;
}
return newitem;
}
void cJSON_Minify(char *json)
{
char *into=json;
while (*json)
{
if (*json==' ') json++;
else if (*json=='\t') json++; // Whitespace characters.
else if (*json=='\r') json++;
else if (*json=='\n') json++;
else if (*json=='/' && json[1]=='/') while (*json && *json!='\n') json++; // double-slash comments, to end of line.
else if (*json=='/' && json[1]=='*') {while (*json && !(*json=='*' && json[1]=='/')) json++;json+=2;} // multiline comments.
else if (*json=='\"'){*into++=*json++;while (*json && *json!='\"'){if (*json=='\\') *into++=*json++;*into++=*json++;}*into++=*json++;} // string literals, which are \" sensitive.
else *into++=*json++; // All other characters.
}
*into=0; // and null-terminate.
}

143
cJSON.h
View File

@@ -1,143 +0,0 @@
/*
Copyright (c) 2009 Dave Gamble
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#ifndef cJSON__h
#define cJSON__h
#ifdef __cplusplus
extern "C"
{
#endif
/* cJSON Types: */
#define cJSON_False 0
#define cJSON_True 1
#define cJSON_NULL 2
#define cJSON_Number 3
#define cJSON_String 4
#define cJSON_Array 5
#define cJSON_Object 6
#define cJSON_IsReference 256
/* The cJSON structure: */
typedef struct cJSON {
struct cJSON *next,*prev; /* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */
struct cJSON *child; /* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */
int type; /* The type of the item, as above. */
char *valuestring; /* The item's string, if type==cJSON_String */
int valueint; /* The item's number, if type==cJSON_Number */
double valuedouble; /* The item's number, if type==cJSON_Number */
char *string; /* The item's name string, if this item is the child of, or is in the list of subitems of an object. */
} cJSON;
typedef struct cJSON_Hooks {
void *(*malloc_fn)(size_t sz);
void (*free_fn)(void *ptr);
} cJSON_Hooks;
/* Supply malloc, realloc and free functions to cJSON */
extern void cJSON_InitHooks(cJSON_Hooks* hooks);
/* Supply a block of JSON, and this returns a cJSON object you can interrogate. Call cJSON_Delete when finished. */
extern cJSON *cJSON_Parse(const char *value);
/* Render a cJSON entity to text for transfer/storage. Free the char* when finished. */
extern char *cJSON_Print(cJSON *item);
/* Render a cJSON entity to text for transfer/storage without any formatting. Free the char* when finished. */
extern char *cJSON_PrintUnformatted(cJSON *item);
/* Delete a cJSON entity and all subentities. */
extern void cJSON_Delete(cJSON *c);
/* Returns the number of items in an array (or object). */
extern int cJSON_GetArraySize(cJSON *array);
/* Retrieve item number "item" from array "array". Returns NULL if unsuccessful. */
extern cJSON *cJSON_GetArrayItem(cJSON *array,int item);
/* Get item "string" from object. Case insensitive. */
extern cJSON *cJSON_GetObjectItem(cJSON *object,const char *string);
/* For analysing failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back to make sense of it. Defined when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */
extern const char *cJSON_GetErrorPtr(void);
/* These calls create a cJSON item of the appropriate type. */
extern cJSON *cJSON_CreateNull(void);
extern cJSON *cJSON_CreateTrue(void);
extern cJSON *cJSON_CreateFalse(void);
extern cJSON *cJSON_CreateBool(int b);
extern cJSON *cJSON_CreateNumber(double num);
extern cJSON *cJSON_CreateString(const char *string);
extern cJSON *cJSON_CreateArray(void);
extern cJSON *cJSON_CreateObject(void);
/* These utilities create an Array of count items. */
extern cJSON *cJSON_CreateIntArray(const int *numbers,int count);
extern cJSON *cJSON_CreateFloatArray(const float *numbers,int count);
extern cJSON *cJSON_CreateDoubleArray(const double *numbers,int count);
extern cJSON *cJSON_CreateStringArray(const char **strings,int count);
/* Append item to the specified array/object. */
extern void cJSON_AddItemToArray(cJSON *array, cJSON *item);
extern void cJSON_AddItemToObject(cJSON *object,const char *string,cJSON *item);
/* Append reference to item to the specified array/object. Use this when you want to add an existing cJSON to a new cJSON, but don't want to corrupt your existing cJSON. */
extern void cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item);
extern void cJSON_AddItemReferenceToObject(cJSON *object,const char *string,cJSON *item);
/* Remove/Detatch items from Arrays/Objects. */
extern cJSON *cJSON_DetachItemFromArray(cJSON *array,int which);
extern void cJSON_DeleteItemFromArray(cJSON *array,int which);
extern cJSON *cJSON_DetachItemFromObject(cJSON *object,const char *string);
extern void cJSON_DeleteItemFromObject(cJSON *object,const char *string);
/* Update array items. */
extern void cJSON_ReplaceItemInArray(cJSON *array,int which,cJSON *newitem);
extern void cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem);
/* Duplicate a cJSON item */
extern cJSON *cJSON_Duplicate(cJSON *item,int recurse);
/* Duplicate will create a new, identical cJSON item to the one you pass, in new memory that will
need to be released. With recurse!=0, it will duplicate any children connected to the item.
The item->next and ->prev pointers are always zero on return from Duplicate. */
/* ParseWithOpts allows you to require (and check) that the JSON is null terminated, and to retrieve the pointer to the final byte parsed. */
extern cJSON *cJSON_ParseWithOpts(const char *value,const char **return_parse_end,int require_null_terminated);
extern void cJSON_Minify(char *json);
/* Macros for creating things quickly. */
#define cJSON_AddNullToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateNull())
#define cJSON_AddTrueToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateTrue())
#define cJSON_AddFalseToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateFalse())
#define cJSON_AddBoolToObject(object,name,b) cJSON_AddItemToObject(object, name, cJSON_CreateBool(b))
#define cJSON_AddNumberToObject(object,name,n) cJSON_AddItemToObject(object, name, cJSON_CreateNumber(n))
#define cJSON_AddStringToObject(object,name,s) cJSON_AddItemToObject(object, name, cJSON_CreateString(s))
/* When assigning an integer value, it needs to be propagated to valuedouble too. */
#define cJSON_SetIntValue(object,val) ((object)?(object)->valueint=(object)->valuedouble=(val):(val))
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,47 @@
//TODO: 日志打印出文件名 + 行号
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <pthread.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <time.h>
#include "MESA/MESA_handle_logger.h"
#include "MESA/MESA_htable.h"
#include "MESA/MESA_prof_load.h"
#include "field_stat2.h"
#include "Maat_rule.h"
#include "Maat_command.h"
#define KNI_STRING_MAX 2048
#define KNI_PATH_MAX 256
#define KNI_SYMBOL_MAX 64
#define likely(expr) __builtin_expect((expr), 1)
#define unlikely(expr) __builtin_expect((expr), 0)
#define ALLOC(type, number) ((type *)calloc(sizeof(type), number))
#define FREE(p) {free(*p);*p=NULL;}
#define KNI_LOG_ERROR(handler, fmt, ...) \
do { \
char location[KNI_PATH_MAX]; \
snprintf(location, KNI_PATH_MAX, "%s: line %d", __FILE__, __LINE__); \
MESA_handle_runtime_log(handler, RLOG_LV_FATAL, location, fmt, ##__VA_ARGS__); } while(0)
#define KNI_LOG_INFO(handler, fmt, ...) \
do { \
char location[KNI_PATH_MAX]; \
snprintf(location, KNI_PATH_MAX, "%s: line %d", __FILE__, __LINE__); \
MESA_handle_runtime_log(handler, RLOG_LV_INFO, location, fmt, ##__VA_ARGS__); } while(0)
#define KNI_LOG_DEBUG(handler, fmt, ...) \
do { \
char location[KNI_PATH_MAX]; \
snprintf(location, KNI_PATH_MAX, "%s: line %d", __FILE__, __LINE__); \
MESA_handle_runtime_log(handler, RLOG_LV_DEBUG, location, fmt, ##__VA_ARGS__); } while(0)
//fprintf(stderr, fmt "\n", ##__VA_ARGS__);
MESA_htable_handle KNI_utils_create_htable(const char *profile, const char *section, void *free_data_cb, void *expire_notify_cb, void *logger);

View File

@@ -0,0 +1,33 @@
struct cipher_suite
{
int value;
const char* name;
};
enum chello_parse_result
{
CHELLO_PARSE_SUCCESS = 0,
CHELLO_PARSE_INVALID_FORMAT = -1,
CHELLO_PARSE_NOT_ENOUGH_BUFF = -2
};
struct ssl_version
{
uint8_t minor;
uint8_t major;
uint16_t ossl_format;
};
struct ssl_chello
{
struct ssl_version min_version;
struct ssl_version max_version;
char* sni;
char* alpn;
char* cipher_suites;
char* cipher_suites_tls13;
};
struct ssl_chello* ssl_chello_parse(const unsigned char* buff, size_t buff_len, enum chello_parse_result* result);
void ssl_chello_free(struct ssl_chello* chello);

0
common/src/kni_utils.cpp Normal file
View File

476
common/src/ssl_utils.cpp Normal file
View File

@@ -0,0 +1,476 @@
#include <stdio.h>
#include <stdlib.h>
#include <ssl_utils.h>
struct cipher_suite cipher_suite_list[] =
{
{0xC030, "ECDHE-RSA-AES256-GCM-SHA384"},
{0xC02C, "ECDHE-ECDSA-AES256-GCM-SHA384"},
{0xC028, "ECDHE-RSA-AES256-SHA384"},
{0xC024, "ECDHE-ECDSA-AES256-SHA384"},
{0xC014, "ECDHE-RSA-AES256-SHA"},
{0xC00A, "ECDHE-ECDSA-AES256-SHA"},
{0x00A5, "DH-DSS-AES256-GCM-SHA384"},
{0x00A3, "DHE-DSS-AES256-GCM-SHA384"},
{0x00A1, "DH-RSA-AES256-GCM-SHA384"},
{0x009F, "DHE-RSA-AES256-GCM-SHA384"},
{0x006B, "DHE-RSA-AES256-SHA256"},
{0x006A, "DHE-DSS-AES256-SHA256"},
{0x0069, "DH-RSA-AES256-SHA256"},
{0x0068, "DH-DSS-AES256-SHA256"},
{0x0039, "DHE-RSA-AES256-SHA"},
{0x0038, "DHE-DSS-AES256-SHA"},
{0x0037, "DH-RSA-AES256-SHA"},
{0x0036, "DH-DSS-AES256-SHA"},
{0x0088, "DHE-RSA-CAMELLIA256-SHA"},
{0x0087, "DHE-DSS-CAMELLIA256-SHA"},
{0x0086, "DH-RSA-CAMELLIA256-SHA"},
{0x0085, "DH-DSS-CAMELLIA256-SHA"},
{0xC019, "AECDH-AES256-SHA"},
{0x00A7, "ADH-AES256-GCM-SHA384"},
{0x006D, "ADH-AES256-SHA256"},
{0x003A, "ADH-AES256-SHA"},
{0x0089, "ADH-CAMELLIA256-SHA"},
{0xC032, "ECDH-RSA-AES256-GCM-SHA384"},
{0xC02E, "ECDH-ECDSA-AES256-GCM-SHA384"},
{0xC02A, "ECDH-RSA-AES256-SHA384"},
{0xC026, "ECDH-ECDSA-AES256-SHA384"},
{0xC00F, "ECDH-RSA-AES256-SHA"},
{0xC005, "ECDH-ECDSA-AES256-SHA"},
{0x009D, "AES256-GCM-SHA384"},
{0x003D, "AES256-SHA256"},
{0x0035, "AES256-SHA"},
{0x0084, "CAMELLIA256-SHA"},
{0x008D, "PSK-AES256-CBC-SHA"},
{0xC02F, "ECDHE-RSA-AES128-GCM-SHA256"},
{0xC02B, "ECDHE-ECDSA-AES128-GCM-SHA256"},
{0xC027, "ECDHE-RSA-AES128-SHA256"},
{0xC023, "ECDHE-ECDSA-AES128-SHA256"},
{0xC013, "ECDHE-RSA-AES128-SHA"},
{0xC009, "ECDHE-ECDSA-AES128-SHA"},
{0x00A4, "DH-DSS-AES128-GCM-SHA256"},
{0x00A2, "DHE-DSS-AES128-GCM-SHA256"},
{0x00A0, "DH-RSA-AES128-GCM-SHA256"},
{0x009E, "DHE-RSA-AES128-GCM-SHA256"},
{0x0067, "DHE-RSA-AES128-SHA256"},
{0x0040, "DHE-DSS-AES128-SHA256"},
{0x003F, "DH-RSA-AES128-SHA256"},
{0x003E, "DH-DSS-AES128-SHA256"},
{0x0033, "DHE-RSA-AES128-SHA"},
{0x0032, "DHE-DSS-AES128-SHA"},
{0x0031, "DH-RSA-AES128-SHA"},
{0x0030, "DH-DSS-AES128-SHA"},
{0x009A, "DHE-RSA-SEED-SHA"},
{0x0099, "DHE-DSS-SEED-SHA"},
{0x0098, "DH-RSA-SEED-SHA"},
{0x0097, "DH-DSS-SEED-SHA"},
{0x0045, "DHE-RSA-CAMELLIA128-SHA"},
{0x0044, "DHE-DSS-CAMELLIA128-SHA"},
{0x0043, "DH-RSA-CAMELLIA128-SHA"},
{0x0042, "DH-DSS-CAMELLIA128-SHA"},
{0xC018, "AECDH-AES128-SHA"},
{0x00A6, "ADH-AES128-GCM-SHA256"},
{0x006C, "ADH-AES128-SHA256"},
{0x0034, "ADH-AES128-SHA"},
{0x009B, "ADH-SEED-SHA"},
{0x0046, "ADH-CAMELLIA128-SHA"},
{0xC031, "ECDH-RSA-AES128-GCM-SHA256"},
{0xC02D, "ECDH-ECDSA-AES128-GCM-SHA256"},
{0xC029, "ECDH-RSA-AES128-SHA256"},
{0xC025, "ECDH-ECDSA-AES128-SHA256"},
{0xC00E, "ECDH-RSA-AES128-SHA"},
{0xC004, "ECDH-ECDSA-AES128-SHA"},
{0x009C, "AES128-GCM-SHA256"},
{0x003C, "AES128-SHA256"},
{0x002F, "AES128-SHA"},
{0x0096, "SEED-SHA"},
{0x0041, "CAMELLIA128-SHA"},
{0x008C, "PSK-AES128-CBC-SHA"},
{0xC012, "ECDHE-RSA-DES-CBC3-SHA"},
{0xC008, "ECDHE-ECDSA-DES-CBC3-SHA"},
{0x0016, "EDH-RSA-DES-CBC3-SHA"},
{0x0013, "EDH-DSS-DES-CBC3-SHA"},
{0x0010, "DH-RSA-DES-CBC3-SHA"},
{0x000D, "DH-DSS-DES-CBC3-SHA"},
{0xC017, "AECDH-DES-CBC3-SHA"},
{0x001B, "ADH-DES-CBC3-SHA"},
{0xC00D, "ECDH-RSA-DES-CBC3-SHA"},
{0xC003, "ECDH-ECDSA-DES-CBC3-SHA"},
{0x000A, "DES-CBC3-SHA"},
{0x0007, "IDEA-CBC-SHA"},
{0x008B, "PSK-3DES-EDE-CBC-SHA"},
{0x0021, "KRB5-IDEA-CBC-SHA"},
{0x001F, "KRB5-DES-CBC3-SHA"},
{0x0025, "KRB5-IDEA-CBC-MD5"},
{0x0023, "KRB5-DES-CBC3-MD5"},
{0xC011, "ECDHE-RSA-RC4-SHA"},
{0xC007, "ECDHE-ECDSA-RC4-SHA"},
{0xC016, "AECDH-RC4-SHA"},
{0x0018, "ADH-RC4-MD5"},
{0xC00C, "ECDH-RSA-RC4-SHA"},
{0xC002, "ECDH-ECDSA-RC4-SHA"},
{0x0005, "RC4-SHA"},
{0x0004, "RC4-MD5"},
{0x008A, "PSK-RC4-SHA"},
{0x0020, "KRB5-RC4-SHA"},
{0x0024, "KRB5-RC4-MD5"},
{0xC010, "ECDHE-RSA-NULL-SHA"},
{0xC006, "ECDHE-ECDSA-NULL-SHA"},
{0xC015, "AECDH-NULL-SHA"},
{0xC00B, "ECDH-RSA-NULL-SHA"},
{0xC001, "ECDH-ECDSA-NULL-SHA"},
{0x003B, "NULL-SHA256"},
{0x0002, "NULL-SHA"},
{0x0001, "NULL-MD5"}
};
struct cipher_suite cipher_suite_list_tls13[] =
{
{0x1301, "TLS_AES_128_GCM_SHA256"},
{0x1302, "TLS_AES_256_GCM_SHA384"},
{0x1303, "TLS_CHACHA20_POLY1305_SHA256"},
{0x1304, "TLS_AES_128_CCM_SHA256"},
{0x1305, "TLS_AES_128_CCM_8_SHA256"}
};
//TODO: parse完记得调用free,防止内存泄漏
void ssl_chello_free(struct ssl_chello* chello)
{
if(chello==NULL)
{
return;
}
free(chello->sni);
chello->sni = NULL;
free(chello->alpn);
chello->alpn = NULL;
free(chello->cipher_suites);
chello->cipher_suites = NULL;
free(chello->cipher_suites_tls13);
chello->cipher_suites_tls13 = NULL;
free(chello);
}
static char* parse_alpn_extension(const unsigned char* buff, size_t buff_len, enum chello_parse_result* result)
{
size_t pos = 0;
size_t len = ((size_t)buff[pos] << 8) + (size_t)buff[pos + 1];
if(2 + len != buff_len)
{
*result = CHELLO_PARSE_INVALID_FORMAT;
return NULL;
}
char* alpn = ALLOC(char, len + 1);
strncpy((char*)alpn, (const char*)buff + 2, len);
alpn[len] = '\0';
*result = CHELLO_PARSE_SUCCESS;
return alpn;
}
static char* parse_server_name_extension(const unsigned char* buff, size_t buff_len, enum chello_parse_result* result)
{
size_t pos = 2; /* skip server name list length */
size_t len;
char* sni = NULL;
while (pos + 3 < buff_len)
{
len = ((size_t)buff[pos + 1] << 8) + (size_t)buff[pos + 2];
if (pos + 3 + len > buff_len)
{
*result = CHELLO_PARSE_INVALID_FORMAT;
return NULL;
}
switch (buff[pos])
{
case 0x00: /* host_name */
sni = (char*)malloc(len + 1);
strncpy(sni, (const char*)buff + pos + 3, len);
sni[len] = '\0';
*result = CHELLO_PARSE_SUCCESS;
}
pos += 3 + len;
}
if (pos != buff_len)
{
*result = CHELLO_PARSE_INVALID_FORMAT;
}
return sni;
}
static enum chello_parse_result parse_extensions(const unsigned char* buff, size_t buff_len, struct ssl_chello* chello) {
size_t pos = 0;
/* Parse each 4 bytes for the extension header */
while (pos + 4 <= buff_len)
{
size_t len = ((size_t)buff[pos + 2] << 8) + (size_t)buff[pos + 3];
/* Check if it's a server name extension */
if (buff[pos] == 0x00 && buff[pos + 1] == 0x00)
{
if (pos + 4 + len > buff_len)
{
return CHELLO_PARSE_INVALID_FORMAT;
}
enum chello_parse_result result = CHELLO_PARSE_SUCCESS;
chello->sni = parse_server_name_extension(buff + pos + 4, len, &result);
if(result != CHELLO_PARSE_SUCCESS)
{
return result;
}
}
/* Check if it's a alpn extension */
if (buff[pos] == 0x00 && buff[pos + 1] == 0x10)
{
if (pos + 4 + len > buff_len)
{
return CHELLO_PARSE_INVALID_FORMAT;
}
enum chello_parse_result result = CHELLO_PARSE_SUCCESS;
chello->alpn = parse_alpn_extension(buff + pos + 4, len, &result);
if(result != CHELLO_PARSE_SUCCESS)
{
return result;
}
}
pos += (4 + len);
}
/* Check we ended where we expected to */
if (pos != buff_len)
{
return CHELLO_PARSE_INVALID_FORMAT;
}
return CHELLO_PARSE_SUCCESS;
}
static char* parse_cipher_suites(struct cipher_suite* _cipher_suite_list, int n, const unsigned char* buff, size_t buff_len, enum chello_parse_result* result)
{
char* cipher_suites_str = (char* )malloc(TFE_STRING_MAX);
cipher_suites_str[0] = '\0';
size_t pos = 0;
int flag = 0;
while(pos < buff_len)
{
int i = 0;
for(i = 0;i < n; i++)
{
int val = (buff[pos] << 8) + buff[pos + 1];
if(_cipher_suite_list[i].value == val)
{
if(strnlen(_cipher_suite_list[i].name, TFE_STRING_MAX) + strnlen(cipher_suites_str, TFE_STRING_MAX) + 1 > TFE_STRING_MAX)
{
flag = 1;
break;
}
strncat(cipher_suites_str, _cipher_suite_list[i].name, TFE_STRING_MAX);
strncat(cipher_suites_str, ":", TFE_STRING_MAX);
}
}
pos += 2;
if(flag == 1)
{
break;
}
}
int len = strnlen(cipher_suites_str, TFE_STRING_MAX);
if(len > 0)
{
cipher_suites_str[len-1] = '\0';
}
if(pos != buff_len && flag == 0)
{
*result = CHELLO_PARSE_INVALID_FORMAT;
free(cipher_suites_str);
return NULL;
}
*result = CHELLO_PARSE_SUCCESS;
return cipher_suites_str;
}
struct ssl_chello* ssl_chello_parse(const unsigned char* buff, size_t buff_len, enum chello_parse_result* result)
{
if(buff == NULL)
{
*result = CHELLO_PARSE_INVALID_FORMAT;
return NULL;
}
if(buff_len < 1)
{
*result = CHELLO_PARSE_NOT_ENOUGH_BUFF;
return NULL;
}
if(buff[0] != 0x80 && buff[0] != 0x16)
{
*result = CHELLO_PARSE_INVALID_FORMAT;
return NULL;
}
/* SSL 2.0 compatible Client Hello
* High bit of first byte (length) and content type is Client Hello
* See RFC5246 Appendix E.2
* if it is SSL 2.0, only parse version
*/
if(buff[0] == 0x80)
{
struct ssl_chello* _chello = (struct ssl_chello*)ALLOC(struct ssl_chello, 1);
_chello->min_version.major = 0x02;
if(buff_len < 2)
{
*result = CHELLO_PARSE_NOT_ENOUGH_BUFF;
return _chello;
}
size_t len = (size_t)buff[1];
if (buff_len < len + 2)
{
*result = CHELLO_PARSE_NOT_ENOUGH_BUFF;
return _chello;
}
buff_len = len + 2;
size_t pos = 2;
/* Handshark Message Type: Client Hello */
if (pos + 1 > buff_len)
{
*result = CHELLO_PARSE_INVALID_FORMAT;
return _chello;
}
if (buff[pos] != 0x01)
{
*result = CHELLO_PARSE_INVALID_FORMAT;
return _chello;
}
pos += 1;
/* Version */
if(pos + 2 > buff_len)
{
*result = CHELLO_PARSE_INVALID_FORMAT;
return _chello;
}
_chello->max_version.major = buff[pos];
_chello->max_version.minor = buff[pos + 1];
_chello->max_version.ossl_format=(uint16_t)_chello->max_version.major<<8|_chello->max_version.minor;
*result = CHELLO_PARSE_SUCCESS;
return _chello;
}
else
{
if (buff_len < 5)
{
*result = CHELLO_PARSE_NOT_ENOUGH_BUFF;
return NULL;
}
if(buff[1] != 3 || buff[2] > 4 || buff[2] < 0)
{
*result = CHELLO_PARSE_INVALID_FORMAT;
return NULL;
}
struct ssl_chello* _chello = (struct ssl_chello*)ALLOC(struct ssl_chello, 1);
_chello->min_version.major = buff[1];
_chello->min_version.minor = buff[2];
_chello->min_version.ossl_format=(uint16_t)_chello->min_version.major<<8|_chello->min_version.minor;
_chello->max_version.major = -1;
_chello->max_version.minor = -1;
_chello->sni = NULL;
_chello->alpn = NULL;
_chello->cipher_suites = NULL;
_chello->cipher_suites_tls13 = NULL;
/* TLS record length */
size_t len = ((size_t)buff[3] << 8) + (size_t)buff[4] + 5;
if (buff_len < len)
{
*result = CHELLO_PARSE_NOT_ENOUGH_BUFF;
return _chello;
}
buff_len = len;
size_t pos = 5;
if (pos + 1 > buff_len)
{
*result = CHELLO_PARSE_INVALID_FORMAT;
return _chello;
}
if (buff[pos] != 0x01)
{
*result = CHELLO_PARSE_INVALID_FORMAT;
return _chello;
}
pos += 4;
if(pos + 2 > buff_len)
{
*result = CHELLO_PARSE_INVALID_FORMAT;
return _chello;
}
_chello->max_version.major = buff[pos];
_chello->max_version.minor = buff[pos+1];
_chello->max_version.ossl_format=(uint16_t)_chello->max_version.major<<8|_chello->max_version.minor;
pos += 34;
/* Session ID */
if (pos + 1 > buff_len)
{
*result = CHELLO_PARSE_INVALID_FORMAT;
return _chello;
}
len = (size_t)buff[pos];
pos += 1 + len;
/* Cipher Suites */
if (pos + 2 > buff_len)
{
*result = CHELLO_PARSE_INVALID_FORMAT;
return _chello;
}
len = ((size_t)buff[pos] << 8) + (size_t)buff[pos + 1];
pos += 2;
if(pos + len > buff_len)
{
*result = CHELLO_PARSE_INVALID_FORMAT;
return _chello;
}
int n = sizeof(cipher_suite_list) / sizeof(struct cipher_suite);
_chello->cipher_suites = parse_cipher_suites(cipher_suite_list, n, buff + pos, len, result);
if(*result != CHELLO_PARSE_SUCCESS)
{
return _chello;
}
n = sizeof(cipher_suite_list_tls13) / sizeof(struct cipher_suite);
_chello->cipher_suites_tls13 = parse_cipher_suites(cipher_suite_list_tls13, n, buff + pos, len, result);
if(*result != CHELLO_PARSE_SUCCESS)
{
return _chello;
}
pos += len;
/* Compression Methods */
if (pos >= buff_len)
{
*result = CHELLO_PARSE_INVALID_FORMAT;
return _chello;
}
len = (size_t)buff[pos];
pos += 1 + len;
/* ssl 3.0, no extensions */
if(_chello->min_version.major == 3 && _chello->min_version.minor == 0)
{
if(pos == buff_len)
{
*result = CHELLO_PARSE_SUCCESS;
return _chello;
}
else
{
*result = CHELLO_PARSE_INVALID_FORMAT;
return _chello;
}
}
/* Extensions */
if (pos + 2 > buff_len)
{
*result = CHELLO_PARSE_INVALID_FORMAT;
return _chello;
}
len = ((size_t)buff[pos] << 8) + (size_t)buff[pos + 1];
pos += 2;
if (pos + len > buff_len)
{
*result = CHELLO_PARSE_INVALID_FORMAT;
return _chello;
}
enum chello_parse_result rtn = parse_extensions(buff + pos, len, _chello);
*result = rtn;
return _chello;
}
}

68
entry/main.cpp Normal file
View File

@@ -0,0 +1,68 @@
//syn包开始回调
extern "C" char kni_tcpall_entry(const struct streaminfo* pstream, void** pme, int thread_seq, const void* a_packet){
//当前包bypass, 剩下包bypass
char ret = APP_STATE_FAWPKT|APP_STATE_DROPME;
struct kni_ipv6_hdr* ipv6_hdr = NULL;
struct kni_pme_info *pmeinfo = *(struct kni_pme_info **)pme;
if(pstream->addr.addrtype==ADDR_TYPE_IPV6){
ipv6_hdr = (struct kni_ipv6_hdr*)a_packet;
if((a_packet != NULL) && (ipv6_hdr->ip6_nex_hdr != NEXTHDR_TCP)){
kni_filestate2_set(thread_seq,FS_DROP_IPV6OPT,0,1);
return ret;
}
}
switch(pstream->pktstate){
case OP_STATE_PENDING:
kni_filestate2_set(thread_seq,FS_PENDING,0,1);
kni_filestate2_set(thread_seq,FS_PMENUM,0,1);
*pme=pmeinfo=kni_pmeinfo_new();
ret=kni_pending_opstate(pstream, pmeinfo, thread_seq, a_packet, PROTO_TYPE_TCP);
break;
case OP_STATE_DATA:
ret=kni_data_opstate(pstream, pmeinfo, thread_seq,a_packet, PROTO_TYPE_TCP);
break;
case OP_STATE_CLOSE:
if(a_packet == NULL)
{
kni_filestate2_set(thread_seq,FS_CLOSE_TIMEOUT,0,1);
}
else
{
kni_filestate2_set(thread_seq,FS_CLOSE_FIN,0,1);
}
ret=kni_close_opstate(pstream,(struct kni_pme_info*)*pme,thread_seq,a_packet,PROTO_TYPE_TCP);
break;
default:
break;
}
if((ret&APP_STATE_DROPME)&& pmeinfo!=NULL)
{
kni_filestate2_set(thread_seq,FS_PMENUM,0,-1);
kni_free_pmeinfo(pmeinfo);
*pme=NULL;
if(pstream->pktstate != OP_STATE_CLOSE)
{
kni_filestate2_set(thread_seq,FS_CLOSE_DROPME,0,1);
}
}
clock_gettime(CLOCK_MONOTONIC, &end);
elapse=(end.tv_sec-start.tv_sec)*1000000+(end.tv_nsec-start.tv_nsec)/1000;
FS_operate(g_kni_fs2_info.handler, g_kni_fs2_info.metric_sapp_proc, 0, FS_OP_SET, elapse);
return ret;
}

View File

@@ -1,714 +0,0 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <ctype.h>
#include <stdarg.h>
#include <assert.h>
#include <arpa/inet.h>
#include "stream.h"
#include "MESA_prof_load.h"
#include "MESA_handle_logger.h"
#include "field_stat2.h"
#include "kni_entry.h"
#include "kni_comm.h"
char* kni_memncasemem(const char *strsrc,int len1,const char *substr,int len2)
{
char *p1,*p2,*pend;
unsigned char *p;
unsigned char *substrS;
int i,lenth;
if((strsrc==NULL)||substr==NULL)
return NULL;
if(len1<len2) return NULL;
lenth=len2;
substrS=(unsigned char *)malloc(sizeof(unsigned char)*(lenth+1));
if(substrS==NULL)
return NULL;
for(i=0;i<lenth;i++)
{
substrS[i]=tolower(*(substr+i));
}
substrS[lenth]=0;
lenth=len1;
pend =(char *)strsrc + lenth;
for(p1 =(char *) strsrc; p1 != pend;p1++)
{
for(p2 = p1,p = substrS;*p != '\0'&& p2 != pend;p++,p2++)
{
if(tolower(*p2) != *p)
break;
}
if(*p == '\0')
{
free(substrS);
return p1;
}
}
free(substrS);
return NULL;
}
int kni_log_info(const char* module,const struct layer_addr* addr,unsigned short protocol,char* domain,char* scan_result,char* action,struct kni_pme_info* pmeinfo)
{
unsigned short sport=0;
unsigned short dport=0;
char saddr_str[INET6_ADDRSTRLEN ]={0};
char daddr_str[INET6_ADDRSTRLEN ]={0};
if(addr->addrtype == ADDR_TYPE_IPV4)
{
sport = ntohs(addr->tuple4_v4->source);
dport = ntohs(addr->tuple4_v4->dest);
inet_ntop(AF_INET, (void *)&(addr->tuple4_v4->saddr), saddr_str, INET_ADDRSTRLEN);
inet_ntop(AF_INET, (void *)&(addr->tuple4_v4->daddr), daddr_str, INET_ADDRSTRLEN);
}
else if(addr->addrtype == ADDR_TYPE_IPV6)
{
sport = ntohs(addr->tuple4_v6->source);
dport = ntohs(addr->tuple4_v6->dest);
inet_ntop(AF_INET6, (void *)&(addr->tuple4_v6->saddr), saddr_str, INET6_ADDRSTRLEN);
inet_ntop(AF_INET6, (void *)&(addr->tuple4_v6->daddr), daddr_str, INET6_ADDRSTRLEN);
}
else
{
MESA_handle_runtime_log(g_kni_comminfo.logger,RLOG_LV_INFO,module,"addr->type is %d",addr->addrtype);
return -1;
}
if(protocol==KNI_FLAG_HTTP)
{
MESA_handle_runtime_log(g_kni_comminfo.logger,RLOG_LV_INFO,module,"addr:%s,%d,%s,%d,%s,domain:%s,%s,%s,config_id:%d,keyring_id:%d,c_fd:%d,s_fd:%d",
saddr_str,sport,daddr_str,dport,"HTTP",domain,scan_result,action,pmeinfo->cfg_id,pmeinfo->keyring_id,pmeinfo->client_fd,pmeinfo->server_fd);
}
else if(protocol==KNI_FLAG_SSL)
{
MESA_handle_runtime_log(g_kni_comminfo.logger,RLOG_LV_INFO,module,"addr:%s,%d,%s,%d,%s,domain:%s,%s,%s,config_id:%d,keyring_id:%d,c_fd:%d,s_fd:%d",
saddr_str,sport,daddr_str,dport,"SSL",domain,scan_result,action,pmeinfo->cfg_id,pmeinfo->keyring_id,pmeinfo->client_fd,pmeinfo->server_fd);
}
else
{
MESA_handle_runtime_log(g_kni_comminfo.logger,RLOG_LV_INFO,module,"addr:%s,%d,%s,%d,domain:%s,%s,%s,config_id:%d",saddr_str,sport,daddr_str,dport,domain,scan_result,action,pmeinfo->cfg_id);
}
return 0;
}
int kni_log_debug(int level, const char* module,const void* a_packet,const char* format,...)
{
if(level<g_kni_comminfo.logger_level)
{
return 0;
}
unsigned short sport=0;
unsigned short dport=0;
char saddr_str[INET6_ADDRSTRLEN ]={0};
char daddr_str[INET6_ADDRSTRLEN ]={0};
int protocol=0;
struct ip* ipv4_hdr = (struct ip*)a_packet;
struct kni_ipv6_hdr* ipv6_hdr = (struct kni_ipv6_hdr*)a_packet;
struct kni_tcp_hdr* tcphdr=NULL;
struct kni_udp_hdr* udphdr=NULL;
char buf[4096] = {0};
va_list list;
va_start(list, format);
vsnprintf(buf, 4069, format, list);
va_end(list);
if(a_packet == NULL)
{
MESA_handle_runtime_log(g_kni_comminfo.logger,level,module,"%s",buf);
return 0;
}
if(ipv4_hdr->ip_v==4)
{
tcphdr=(struct kni_tcp_hdr*)((char*)ipv4_hdr+4*(ipv4_hdr->ip_hl));
udphdr=(struct kni_udp_hdr*)((char*)ipv4_hdr+4*(ipv4_hdr->ip_hl));
inet_ntop(AF_INET, (void *)&((ipv4_hdr->ip_src).s_addr), saddr_str, INET_ADDRSTRLEN);
inet_ntop(AF_INET, (void *)&((ipv4_hdr->ip_dst).s_addr), daddr_str, INET_ADDRSTRLEN);
protocol = ipv4_hdr->ip_p;
}
else if((ipv6_hdr->ip6_flags[0] & 0xF0) == 0x60)
{
if(ipv6_hdr->ip6_nex_hdr != NEXTHDR_TCP)
{
return -1;
}
tcphdr =(struct kni_tcp_hdr*)( (unsigned char*)ipv6_hdr + sizeof(struct kni_ipv6_hdr));
udphdr =(struct kni_udp_hdr*)( (unsigned char*)ipv6_hdr + sizeof(struct kni_ipv6_hdr));
inet_ntop(AF_INET6, (void *)&(ipv6_hdr->ip6_src), saddr_str, INET6_ADDRSTRLEN);
inet_ntop(AF_INET6, (void *)&(ipv6_hdr->ip6_dst), daddr_str, INET6_ADDRSTRLEN);
protocol= ipv6_hdr->ip6_nex_hdr;
}
if(protocol == PROTO_TYPE_TCP)
{
sport=ntohs(tcphdr->th_sport);
dport=ntohs(tcphdr->th_dport);
}
else if(protocol == PROTO_TYPE_UDP)
{
sport=ntohs(udphdr->uh_sport);
dport=ntohs(udphdr->uh_dport);
}
MESA_handle_runtime_log(g_kni_comminfo.logger,level,module,"addr:%s,%d,%s,%d %s",saddr_str,sport,daddr_str,dport,buf);
return 0;
}
int kni_log_debug_bak(int level,const char* module,const void* a_packet,char* content)
{
unsigned short sport=0;
unsigned short dport=0;
char saddr_str[INET6_ADDRSTRLEN ]={0};
char daddr_str[INET6_ADDRSTRLEN ]={0};
struct ip* ipv4_hdr = (struct ip*)a_packet;
struct kni_ipv6_hdr* ipv6_hdr = (struct kni_ipv6_hdr*)a_packet;
struct tcphdr* tcphdr = NULL;
if(ipv4_hdr->ip_v==4)
{
tcphdr=(struct tcphdr*)((char*)ipv4_hdr+4*(ipv4_hdr->ip_hl));
inet_ntop(AF_INET, (void *)&((ipv4_hdr->ip_src).s_addr), saddr_str, INET_ADDRSTRLEN);
inet_ntop(AF_INET, (void *)&((ipv4_hdr->ip_dst).s_addr), daddr_str, INET_ADDRSTRLEN);
}
else if((ipv6_hdr->ip6_flags[0] & 0xF0) == 0x60)
{
if(ipv6_hdr->ip6_nex_hdr != NEXTHDR_TCP)
{
return -1;
}
tcphdr =(struct tcphdr*)( (unsigned char*)ipv6_hdr + sizeof(struct kni_ipv6_hdr));
inet_ntop(AF_INET, (void *)&(ipv6_hdr->ip6_src), saddr_str, INET6_ADDRSTRLEN);
inet_ntop(AF_INET, (void *)&(ipv6_hdr->ip6_dst), daddr_str, INET6_ADDRSTRLEN);
}
sport=ntohs(tcphdr->source);
dport=ntohs(tcphdr->dest);
MESA_handle_runtime_log(g_kni_comminfo.logger,level,module,"addr:%s,%d,%s,%d %s",saddr_str,sport,daddr_str,dport,content);
return 0;
}
/****************************************************************************
if(sport<dport) server=s
else if((sport==dport)&&(sip<dip)) server=s
else server=d
****************************************************************************/
int kni_get_ipaddr_v4(void* a_packet,struct stream_tuple4_v4* ipaddr)
{
int reverse_flag=0;
unsigned short sport=0;
unsigned short dport =0;
struct ip* iphdr=(struct ip*)a_packet;
struct tcphdr* tcphdr=NULL;
iphdr=(struct ip*)a_packet;
tcphdr=(struct tcphdr*)((char*)iphdr+4*(iphdr->ip_hl));
sport=ntohs(tcphdr->source);
dport=ntohs(tcphdr->dest);
if((sport<dport)||((sport==dport)&&(ntohl((iphdr->ip_src).s_addr)<ntohl((iphdr->ip_dst).s_addr))))
{
reverse_flag=1;
}
if(reverse_flag==1)
{
ipaddr->saddr=(iphdr->ip_dst).s_addr;
ipaddr->daddr=(iphdr->ip_src).s_addr;
ipaddr->source=tcphdr->dest;
ipaddr->dest=tcphdr->source;
}
else
{
ipaddr->saddr=(iphdr->ip_src).s_addr;
ipaddr->daddr=(iphdr->ip_dst).s_addr;
ipaddr->source=tcphdr->source;
ipaddr->dest=tcphdr->dest;
}
return reverse_flag;
}
/****************************************************************************
if(sport<dport) server=s
else if((sport==dport)&&(sip<dip)) server=s
else server=d
****************************************************************************/
int kni_get_ipaddr_v6(void* a_packet,struct stream_tuple4_v6* ipaddr)
{
int reverse_flag=0;
unsigned short sport=0;
unsigned short dport =0;
struct kni_ipv6_hdr* ipv6_hdr=(struct kni_ipv6_hdr*)a_packet;
struct tcphdr* tcphdr=(struct tcphdr*)((unsigned char*)a_packet+sizeof(struct kni_ipv6_hdr));
sport=ntohs(tcphdr->source);
dport=ntohs(tcphdr->dest);
if(sport<dport)
{
reverse_flag=1;
}
if(reverse_flag==1)
{
memcpy(ipaddr->saddr, ipv6_hdr->ip6_dst.s6_addr32, sizeof(ipaddr->saddr));
memcpy(ipaddr->daddr, ipv6_hdr->ip6_src.s6_addr32, sizeof(ipaddr->daddr));
ipaddr->source=tcphdr->dest;
ipaddr->dest=tcphdr->source;
}
else
{
memcpy(ipaddr->saddr, ipv6_hdr->ip6_src.s6_addr32, sizeof(ipaddr->saddr));
memcpy(ipaddr->daddr, ipv6_hdr->ip6_dst.s6_addr32, sizeof(ipaddr->daddr));
ipaddr->source=tcphdr->source;
ipaddr->dest=tcphdr->dest;
}
return reverse_flag;
}
int kni_get_tcpinfo(struct kni_wndpro_reply_info* lastpkt_info,struct kni_tcp_hdr* tcphdr,int tcplen)
{
lastpkt_info->seq=ntohl(tcphdr->th_seq);
lastpkt_info->ack=ntohl(tcphdr->th_ack);
lastpkt_info->len=tcplen;
lastpkt_info->wndsize=ntohs(tcphdr->th_win);
if(tcphdr->th_flags&TH_SYN)
{
lastpkt_info->syn_flag=1;
}
return 0;
}
#include <netinet/tcp.h>
void kni_get_tcpopt(struct kni_tcp_hdr* tcphdr,int tcp_hdr_len,
unsigned short* mss, unsigned char* wscale_perm, unsigned char* wscale, unsigned char* sack, unsigned char* timestamps)
{
*mss=KNI_DEFAULT_MSS;
*wscale=KNI_DEFAULT_WINSCLE;
const unsigned char *ptr = ((const unsigned char*)tcphdr+TCPHDR_DEFAULT_LEN);
int length = tcp_hdr_len - TCPHDR_DEFAULT_LEN;
while (length > 0)
{
int opcode = *ptr++;
int opsize;
switch (opcode) {
case TCPOPT_EOL:
return;
case TCPOPT_NOP: /* Ref: RFC 793 section 3.1 */
length--;
continue;
default:
opsize = *ptr++;
if (opsize < 2) /* "silly options" */
return;
if (opsize > length)
return; /* don't parse partial options */
switch (opcode)
{
case TCPOPT_MAXSEG:
if (opsize == TCPOLEN_MAXSEG)
{
uint16_t in_mss = *(uint16_t *)ptr;
if (in_mss) *mss = ntohs(in_mss);
}
break;
case TCPOPT_WINDOW:
if (opsize == TCPOLEN_WINDOW)
{
uint8_t snd_wscale = *(uint8_t *)ptr;
// rfc7323 page9: Thus, the shift count MUST be limited to 14 (which allows windows of 2^30 = 1 GiB).
// If a Window Scale option is received with a shift.cnt value larger than 14,
// the TCP SHOULD log the error but MUST use 14 instead of the specified value. */
*wscale = snd_wscale;
if(*wscale>14)
{
*wscale=14;
}
*wscale_perm=1;
}
break;
case TCPOPT_TIMESTAMP:
if ((opsize == TCPOLEN_TIMESTAMP))
{
*timestamps = 1;
}
break;
case TCPOPT_SACK_PERMITTED:
if (opsize == TCPOLEN_SACK_PERMITTED)
{
*sack = 1;
}
break;
}
ptr += opsize-2;
length -= opsize;
}
}
return;
}
char* kni_get_payload(const struct streaminfo* pstream,int* datalen)
{
char* data=NULL;
if(pstream->type==STREAM_TYPE_TCP)
{
data=(char*)(pstream->ptcpdetail->pdata);
*datalen=pstream->ptcpdetail->datalen;
}
else if(pstream->type==STREAM_TYPE_UDP)
{
data=(char*)(pstream->pudpdetail->pdata);
*datalen=pstream->pudpdetail->datalen;
}
else
{
data=NULL;
*datalen=0;
}
return data;
}
int kni_filestate2_set(int thread_seq,enum kni_FS_COLUME colum_index,int bytes,int pktnum)
{
g_kni_fs2_info.column_value_pkt[thread_seq][colum_index]+=pktnum;
g_kni_fs2_info.column_value_bytes[thread_seq][colum_index]+=bytes;
return 0;
}
int kni_filestate2_init()
{
// int i=0;
// int j=0;
int value=1;
unsigned int fs2_sport=0;
char fs2_filename[KNI_MAX_BUFLEN]={0};
char fs2_sip[KNI_MAX_BUFLEN]={0};
MESA_load_profile_string_def((char*)KNI_CONF_FILENAME,(char*)KNI_FS_MODE,(char*)"filestat2_filename",fs2_filename,KNI_MAX_BUFLEN,(char*)"./log/kni_fs2.log");
MESA_load_profile_string_def((char*)KNI_CONF_FILENAME,(char*)KNI_FS_MODE,(char*)"filestat2_sip",fs2_sip,KNI_MAX_BUFLEN,(char*)"0.0.0.0");
MESA_load_profile_uint_def((char*)KNI_CONF_FILENAME,(char*)KNI_FS_MODE,(char*)"filestat2_sport",(unsigned int*)&fs2_sport,0);
g_kni_fs2_info.handler=FS_create_handle();
FS_set_para(g_kni_fs2_info.handler, OUTPUT_DEVICE,fs2_filename, strlen(fs2_filename)+1);
FS_set_para(g_kni_fs2_info.handler, PRINT_MODE, &value, sizeof(value));
FS_set_para(g_kni_fs2_info.handler, STAT_CYCLE, &value, sizeof(value));
FS_set_para(g_kni_fs2_info.handler, CREATE_THREAD, &value, sizeof(value));
FS_set_para(g_kni_fs2_info.handler, APP_NAME, FS2_APPNAME, strlen(FS2_APPNAME)+1);
if(fs2_sport!=0)
{
FS_set_para(g_kni_fs2_info.handler, STATS_SERVER_IP, fs2_sip, strlen(fs2_sip)+1);
FS_set_para(g_kni_fs2_info.handler, STATS_SERVER_PORT,&fs2_sport,sizeof(int));
}
g_kni_fs2_info.field_id[FS_PENDING]=FS_register(g_kni_fs2_info.handler, FS_STYLE_FIELD, FS_CALC_CURRENT,"link_pending");
g_kni_fs2_info.field_id[FS_CLOSE_TIMEOUT]=FS_register(g_kni_fs2_info.handler, FS_STYLE_FIELD, FS_CALC_CURRENT,"link_cls_to");
g_kni_fs2_info.field_id[FS_CLOSE_FIN]=FS_register(g_kni_fs2_info.handler, FS_STYLE_FIELD, FS_CALC_CURRENT,"link_cls_fin");
g_kni_fs2_info.field_id[FS_CLOSE_DROPME]=FS_register(g_kni_fs2_info.handler, FS_STYLE_FIELD, FS_CALC_CURRENT,"link_cls_dropme");
g_kni_fs2_info.field_id[FS_HTTP]=FS_register(g_kni_fs2_info.handler, FS_STYLE_FIELD, FS_CALC_CURRENT,"link_http");
g_kni_fs2_info.field_id[FS_SSL]=FS_register(g_kni_fs2_info.handler, FS_STYLE_FIELD, FS_CALC_CURRENT,"link_ssl");
g_kni_fs2_info.field_id[FS_CLIENT_HELLO]=FS_register(g_kni_fs2_info.handler, FS_STYLE_FIELD, FS_CALC_CURRENT,"link_hello");
g_kni_fs2_info.field_id[FS_SNI]=FS_register(g_kni_fs2_info.handler, FS_STYLE_FIELD, FS_CALC_CURRENT,"link_sni");
g_kni_fs2_info.field_id[FS_NOT_HTTP_SSL]=FS_register(g_kni_fs2_info.handler, FS_STYLE_FIELD, FS_CALC_CURRENT,"link_unknown");
g_kni_fs2_info.field_id[FS_NOT_DOUBLE]=FS_register(g_kni_fs2_info.handler, FS_STYLE_FIELD, FS_CALC_CURRENT, "link_asym");
g_kni_fs2_info.field_id[FS_NOT_HIT]=FS_register(g_kni_fs2_info.handler, FS_STYLE_FIELD, FS_CALC_CURRENT,"link_not_hit");
g_kni_fs2_info.field_id[FS_WHITELIST]=FS_register(g_kni_fs2_info.handler, FS_STYLE_FIELD, FS_CALC_CURRENT,"link_whitelist");
g_kni_fs2_info.field_id[FS_INTERCEPT]=FS_register(g_kni_fs2_info.handler, FS_STYLE_FIELD, FS_CALC_CURRENT,"link_intercept");
g_kni_fs2_info.field_id[FS_REDIRECT]=FS_register(g_kni_fs2_info.handler, FS_STYLE_FIELD, FS_CALC_CURRENT,"link_redirect");
g_kni_fs2_info.field_id[FS_REDIRECT_REPLY]=FS_register(g_kni_fs2_info.handler, FS_STYLE_FIELD, FS_CALC_CURRENT,"redirect_reply");
g_kni_fs2_info.field_id[FS_RATELIMIT]=FS_register(g_kni_fs2_info.handler, FS_STYLE_FIELD, FS_CALC_CURRENT,"link_ratelimit");
g_kni_fs2_info.field_id[FS_RATELIMIT_UDP]=FS_register(g_kni_fs2_info.handler, FS_STYLE_FIELD, FS_CALC_CURRENT,"ratelimit_udp_pkt");
g_kni_fs2_info.field_id[FS_REPLACE_UDP]=FS_register(g_kni_fs2_info.handler, FS_STYLE_FIELD, FS_CALC_CURRENT,"replace_udp_pkt");
g_kni_fs2_info.field_id[FS_REPAIR_TOTAL]=FS_register(g_kni_fs2_info.handler, FS_STYLE_FIELD, FS_CALC_CURRENT,"repair_total");
g_kni_fs2_info.field_id[FS_REPAIR_SOCK_ERR]=FS_register(g_kni_fs2_info.handler, FS_STYLE_FIELD, FS_CALC_CURRENT,"repair_sock_err");
g_kni_fs2_info.field_id[FS_REPAIR_SET_ERR]=FS_register(g_kni_fs2_info.handler, FS_STYLE_FIELD, FS_CALC_CURRENT,"repair_set_err");
g_kni_fs2_info.field_id[FS_REPAIR_JOINLQ_ERR]=FS_register(g_kni_fs2_info.handler, FS_STYLE_FIELD, FS_CALC_CURRENT,"repair_e_joinq");
g_kni_fs2_info.field_id[FS_REPAIR_SEND_SUCC]=FS_register(g_kni_fs2_info.handler, FS_STYLE_FIELD, FS_CALC_CURRENT,"repair_send");
g_kni_fs2_info.field_id[FS_REPAIR_SEND_ERR]=FS_register(g_kni_fs2_info.handler, FS_STYLE_FIELD, FS_CALC_CURRENT,"repair_send_err");
g_kni_fs2_info.field_id[FS_PKT_ADD_LQ_SUCC]=FS_register(g_kni_fs2_info.handler, FS_STYLE_FIELD, FS_CALC_CURRENT,"pkt_qin");
g_kni_fs2_info.field_id[FS_PKT_ADD_LQ_ERR]=FS_register(g_kni_fs2_info.handler, FS_STYLE_FIELD, FS_CALC_CURRENT,"pkt_qin_err");
g_kni_fs2_info.field_id[FS_PKT_GET_LQ_SUCC]=FS_register(g_kni_fs2_info.handler, FS_STYLE_FIELD, FS_CALC_CURRENT,"pkt_qout");
g_kni_fs2_info.field_id[FS_PKT_GET_LQ_ERR]=FS_register(g_kni_fs2_info.handler, FS_STYLE_FIELD, FS_CALC_CURRENT,"pkt_qout_err");
g_kni_fs2_info.field_id[FS_WR_PKTS]=FS_register(g_kni_fs2_info.handler, FS_STYLE_FIELD, FS_CALC_CURRENT,"wr_pkts");
g_kni_fs2_info.field_id[FS_WR_ERR_PKTS]=FS_register(g_kni_fs2_info.handler, FS_STYLE_FIELD, FS_CALC_CURRENT,"wr_err_pkts");
g_kni_fs2_info.field_id[FS_WR_BYTES]=FS_register(g_kni_fs2_info.handler, FS_STYLE_FIELD, FS_CALC_CURRENT,"wr_bytes");
g_kni_fs2_info.field_id[FS_RD_PKTS]=FS_register(g_kni_fs2_info.handler, FS_STYLE_FIELD, FS_CALC_CURRENT,"rd_pkts");
g_kni_fs2_info.field_id[FS_RD_BYTES]=FS_register(g_kni_fs2_info.handler, FS_STYLE_FIELD, FS_CALC_CURRENT,"rd_bytes");
g_kni_fs2_info.field_id[FS_RX_PKTS]=FS_register(g_kni_fs2_info.handler, FS_STYLE_FIELD, FS_CALC_CURRENT,"rx_pkts");
g_kni_fs2_info.field_id[FS_RX_BYTES]=FS_register(g_kni_fs2_info.handler, FS_STYLE_FIELD, FS_CALC_CURRENT,"rx_bytes");
g_kni_fs2_info.field_id[FS_TX_PKTS]=FS_register(g_kni_fs2_info.handler, FS_STYLE_FIELD, FS_CALC_CURRENT,"tx_pkts");
g_kni_fs2_info.field_id[FS_TX_BYTES]=FS_register(g_kni_fs2_info.handler, FS_STYLE_FIELD, FS_CALC_CURRENT,"tx_bytes");
g_kni_fs2_info.field_id[FS_DROP_IPV6OPT]=FS_register(g_kni_fs2_info.handler, FS_STYLE_FIELD, FS_CALC_CURRENT,"d_ipv6_opt");
g_kni_fs2_info.field_id[FS_DROP_NOTIN_HTABLE]=FS_register(g_kni_fs2_info.handler, FS_STYLE_FIELD, FS_CALC_CURRENT,"d_notin_htab");
g_kni_fs2_info.field_id[FS_DROP_NOTIPV46_SAPP]=FS_register(g_kni_fs2_info.handler, FS_STYLE_FIELD, FS_CALC_CURRENT,"d_not_ipv46_s");
g_kni_fs2_info.field_id[FS_DROP_NOTIPV46_TUN]=FS_register(g_kni_fs2_info.handler, FS_STYLE_FIELD, FS_CALC_CURRENT,"d_not_ipv46_t");
g_kni_fs2_info.field_id[FS_DROP_ADDHTABLE_ERROR]=FS_register(g_kni_fs2_info.handler, FS_STYLE_FIELD, FS_CALC_CURRENT,"d_add_htal_err");
g_kni_fs2_info.field_id[FS_PMENUM]=FS_register(g_kni_fs2_info.handler, FS_STYLE_FIELD, FS_CALC_CURRENT,"pme_num");
g_kni_fs2_info.field_id[FS_REPLAY_WINDOW]=FS_register(g_kni_fs2_info.handler, FS_STYLE_FIELD, FS_CALC_CURRENT,"replay_win");
g_kni_fs2_info.field_id[FS_HTABLE_ADD]=FS_register(g_kni_fs2_info.handler, FS_STYLE_FIELD, FS_CALC_CURRENT,"add_htab");
g_kni_fs2_info.field_id[FS_HTABLE_DEL]=FS_register(g_kni_fs2_info.handler, FS_STYLE_FIELD, FS_CALC_CURRENT,"del_htab");
g_kni_fs2_info.field_id[FS_PRO_ERROR]=FS_register(g_kni_fs2_info.handler, FS_STYLE_FIELD, FS_CALC_CURRENT,"http_proj_err");
g_kni_fs2_info.metric_tun_read=FS_register_histogram(g_kni_fs2_info.handler, FS_CALC_CURRENT, "tun_read(us)" ,1,1000000,2);
g_kni_fs2_info.metric_forward=FS_register_histogram(g_kni_fs2_info.handler, FS_CALC_CURRENT, "forward(us)" ,1,1000000,2);
g_kni_fs2_info.metric_sapp_proc=FS_register_histogram(g_kni_fs2_info.handler, FS_CALC_CURRENT, "sapp_proc(us)" ,1,1000000,2);
g_kni_fs2_info.metric_tcprepair=FS_register_histogram(g_kni_fs2_info.handler, FS_CALC_CURRENT, "tcprepair(us)" ,1,1000000,2);
g_kni_fs2_info.metric_tun_write=FS_register_histogram(g_kni_fs2_info.handler, FS_CALC_CURRENT, "tun_write(us)" ,1,1000000,2);
g_kni_fs2_info.metric_sendfd=FS_register_histogram(g_kni_fs2_info.handler, FS_CALC_CURRENT, "send_fds(us)" ,1,1000000,2);
g_kni_fs2_info.metric_qout_fd=FS_register_histogram(g_kni_fs2_info.handler, FS_CALC_CURRENT, "q_out_fds(us)" ,1,1000000,2);
g_kni_fs2_info.metric_qout_pkt=FS_register_histogram(g_kni_fs2_info.handler, FS_CALC_CURRENT, "q_out_pkts(us)" ,1,1000000,2);
FS_start(g_kni_fs2_info.handler);
return 0;
}
void* kni_filestat2(void* arg)
{
int i=0;
int j=0;
unsigned long long column_value[FS2_COLUMN_NUM];
kni_filestate2_init();
while(1)
{
for(i=0;i<FS2_COLUMN_NUM;i++)
{
column_value[i]=0;
for(j=0;j<g_iThreadNum;j++)
{
column_value[i]+=g_kni_fs2_info.column_value_pkt[j][i];
}
FS_operate(g_kni_fs2_info.handler,g_kni_fs2_info.field_id[i], 0,FS_OP_SET,column_value[i]);
}
sleep(1);
}
return NULL;
}
int kni_order_action(int old_action,int new_action)
{
if((old_action == KNI_ACTION_WHITELIST) || (new_action == KNI_ACTION_WHITELIST))
{
return KNI_ACTION_WHITELIST;
}
else if((old_action == KNI_ACTION_MONITOR) || (new_action == KNI_ACTION_MONITOR))
{
return KNI_ACTION_MONITOR;
}
else if((old_action == KNI_ACTION_REDIRECT) || (new_action == KNI_ACTION_REDIRECT))
{
return KNI_ACTION_REDIRECT;
}
else if((old_action == KNI_ACTION_REPLACE) || (new_action == KNI_ACTION_REPLACE))
{
return KNI_ACTION_REPLACE;
}
else if((old_action == KNI_ACTION_RATELIMIT) || (new_action == KNI_ACTION_RATELIMIT))
{
return KNI_ACTION_RATELIMIT;
}
return KNI_ACTION_NONE;
}
int kni_get_service_defined(int new_action,struct Maat_rule_t* maat_result,struct kni_pme_info* pmeinfo)
{
// if((new_action == KNI_ACTION_REPLACE) || (new_action == KNI_ACTION_RATELIMIT))
{
if(maat_result->serv_def_len > KNI_SERVICE_LEN)
{
pmeinfo->ser_def_len = 0;
MESA_handle_runtime_log(g_kni_comminfo.logger,RLOG_LV_FATAL,(char*)"get_service_defined",
"maat_result->serv_def_len is %d,large than KNI_SERVICE_LEN %d",maat_result->serv_def_len,KNI_SERVICE_LEN);
return -1;
}
pmeinfo->cfg_id = maat_result->config_id;
pmeinfo->ser_def_len = maat_result->serv_def_len;
assert((int)sizeof(pmeinfo->service_defined) > maat_result->serv_def_len);
memcpy(pmeinfo->service_defined,maat_result->service_defined,maat_result->serv_def_len);
}
return 0;
}
int kni_get_keyring(struct kni_pme_info* pmeinfo)
{
char* tmp = NULL;
tmp = kni_memncasemem(pmeinfo->service_defined, pmeinfo->ser_def_len,(char*)"keyring_id=", strlen("keyring_id="));
if(tmp == NULL)
{
MESA_handle_runtime_log(g_kni_comminfo.logger,RLOG_LV_FATAL,"KEYRING_ID","there is no keyring id!cfg_id:%d,region:%s",pmeinfo->cfg_id,pmeinfo->service_defined);
return -1;
}
tmp += strlen("keyring_id=");
pmeinfo->keyring_id= atoi(tmp);
return 0;
}
int kni_process_maatresult(int result_num,struct Maat_rule_t* maat_result,struct kni_pme_info* pmeinfo)
{
int i=0;
int cur_action = KNI_ACTION_NONE;
int old_action = pmeinfo->action;
int keyring_id_old = 0;
for(i=0;i<result_num;i++)
{
cur_action = abs(maat_result[i].action);
if(cur_action == KNI_ACTION_WHITELIST)
{
pmeinfo->action=cur_action;
pmeinfo->cfg_id=maat_result[i].config_id;
return 0;
}
old_action = pmeinfo->action;
pmeinfo->action= kni_order_action(old_action,cur_action);
if(old_action != pmeinfo->action)
{
kni_get_service_defined(cur_action,&maat_result[i],pmeinfo);
}
if((pmeinfo->ipsscan_action!= KNI_ACTION_MONITOR) && (pmeinfo->action == KNI_ACTION_MONITOR))
{
keyring_id_old = pmeinfo->keyring_id;
kni_get_keyring(pmeinfo);
pmeinfo->keyring_id = pmeinfo->keyring_id>keyring_id_old ? pmeinfo->keyring_id : keyring_id_old;
}
}
if((result_num == -2) && (pmeinfo->action == KNI_ACTION_NONE))
{
pmeinfo->action = KNI_ACTION_HALFHIT;
}
return 0;
}

View File

@@ -1,104 +0,0 @@
#ifndef KNI_COMMON_H
#define KNI_COMMON_H
#ifndef KNI_MAX_THREADNUM
#define KNI_MAX_THREADNUM 64
#endif
//#define FS2_COLUMN_NUM 44
#define FS2_APPNAME "KNI"
enum kni_FS_COLUME
{
FS_PENDING=0,
FS_CLOSE_TIMEOUT,
FS_CLOSE_FIN,
FS_CLOSE_DROPME,
FS_HTTP,
FS_SSL,
FS_CLIENT_HELLO,
FS_SNI,
FS_NOT_HTTP_SSL,
FS_NOT_DOUBLE,
FS_WHITELIST,
FS_INTERCEPT,
FS_RATELIMIT,
FS_REDIRECT,
FS_REDIRECT_REPLY,
FS_NOT_HIT,
FS_RATELIMIT_UDP,
FS_REPLACE_UDP,
FS_REPAIR_TOTAL,
FS_REPAIR_SOCK_ERR,
FS_REPAIR_SET_ERR,
FS_REPAIR_JOINLQ_ERR,
FS_REPAIR_SEND_SUCC,
FS_REPAIR_SEND_ERR,
FS_PKT_ADD_LQ_SUCC,
FS_PKT_ADD_LQ_ERR,
FS_PKT_GET_LQ_SUCC,
FS_PKT_GET_LQ_ERR,
FS_WR_PKTS,
FS_WR_ERR_PKTS,
FS_WR_BYTES,
FS_RD_PKTS,
FS_RD_BYTES,
FS_RX_PKTS,
FS_RX_BYTES,
FS_TX_PKTS,
FS_TX_BYTES,
FS_DROP_IPV6OPT,
FS_DROP_NOTIN_HTABLE,
FS_DROP_NOTIPV46_SAPP,
FS_DROP_NOTIPV46_TUN,
FS_DROP_ADDHTABLE_ERROR,
FS_PMENUM,
FS_REPLAY_WINDOW,
FS_HTABLE_ADD,
FS_HTABLE_DEL,
FS_PRO_ERROR,
FS2_COLUMN_NUM
};
//field stat2
struct kni_fs2_info
{
screen_stat_handle_t handler;
int field_id[FS2_COLUMN_NUM];
unsigned long long column_value_pkt[KNI_MAX_THREADNUM][FS2_COLUMN_NUM];
unsigned long long column_value_bytes[KNI_MAX_THREADNUM][FS2_COLUMN_NUM];
int metric_tun_read;
int metric_forward;
int metric_sapp_proc;
int metric_tcprepair;
int metric_tun_write;
int metric_sendfd;
int metric_qout_fd;
int metric_qout_pkt;
};
int kni_log_info(const char* module,const struct layer_addr* addr,unsigned short protocol,char* domain,char* scan_result,char* action,struct kni_pme_info* pmeinfo);
int kni_log_debug(int level, const char* module,const void* a_packet,const char * format,...);
int kni_get_ipaddr_v4(void* a_packet,struct stream_tuple4_v4* ipaddr);
int kni_get_ipaddr_v6(void* a_packet,struct stream_tuple4_v6* ipaddr);
int kni_get_tcpinfo(struct kni_wndpro_reply_info* lastpkt_info,struct kni_tcp_hdr* tcphdr,int tcplen);
void kni_get_tcpopt(struct kni_tcp_hdr* tcphdr,int tcp_hdr_len,
unsigned short* mss, unsigned char* wscale_perm, unsigned char* wscale, unsigned char* sack, unsigned char* timestamps);
char* kni_get_payload(const struct streaminfo* pstream,int* datalen);
int kni_filestate2_set(int thread_seq,enum kni_FS_COLUME colum_index,int bytes,int pktnum);
void* kni_filestat2(void* arg);
int kni_order_action(int old_action,int new_action);
int kni_process_maatresult(int result_num,struct Maat_rule_t* maat_result,struct kni_pme_info* pmeinfo);
char* kni_memncasemem(const char *strsrc,int len1,const char *substr,int len2);
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -1,517 +0,0 @@
#ifndef KNI_PROCESS_H
#define KNI_PROCESS_H
#include <time.h>
#include "stream.h"
#include "MESA_prof_load.h"
#include "MESA_handle_logger.h"
#include "MESA_htable.h"
#include "MESA_list_queue.h"
#include "field_stat2.h"
#include "Maat_rule.h"
#include "kni_comm.h"
#include "kni_intercept.h"
#include "kni_ratelimit.h"
#include "kni_utils.h"
#include "kni_redirect.h"
#ifndef TH_FIN
#define TH_FIN 0x01
#endif
#ifndef TH_SYN
#define TH_SYN 0x02
#endif
#ifndef TH_RST
#define TH_RST 0x04
#endif
#ifndef TH_PUSH
#define TH_PUSH 0x08
#endif
#ifndef TH_ACK
#define TH_ACK 0x10
#endif
#ifndef TH_URG
#define TH_URG 0x20
#endif
//#define KNI_DEBUG_TCPREPAIR 1
//#define KNI_DEBUG_KEEPALIVE 1
#define KNI_MAX_THREADNUM 64
#define KNI_ETHER_LEN 14
#define TCPHDR_DEFAULT_LEN 20
//only for get domain_len
#define KNI_DEFAULT_MTU 1500
//for read config and packet
#define KNI_MAX_BUFLEN 2000
//work module
#define KNI_MODE_WORK 0
#define KNI_MODE_BYPASS 1
//runtime log
#define KNI_MODULE_INIT "kni_init"
#define KNI_MODULE_READTUN "pthread_process_tun"
#define KNI_MODULE_SENDPKT "kni_sendpkt"
#define KNI_MODULE_WRITETUN "kni_write_tun"
#define KNI_MODULE_IPENTRY "kni_process"
#define KNI_MODULE_INFO "kni_info"
#define KNI_MODULE_DEBUG "kni_debug"
#define KNI_MODULE_SENDFD "send_fds"
#define KNI_MODULE_SENDLOG "kni_sendlog"
#define KNI_ACTION_EXIT "exit..."
//init profile info
#define KNI_CONF_MAXLEN 1024
#define KNI_CONF_FILENAME "./kniconf/kni.conf"
#define KNI_MAIN_MODE "main"
#define KNI_FS_MODE "field_stat"
#define KNI_DYNMAAT_MODE "dynmic_maat"
#define KNI_STATIC_MAAT_MODE "static_maat"
#define KNI_TUN_MODE "tun"
#define KNI_SENDLOG_MODE "send_log"
#define KNI_CONF_MODE "Module"
#define KNI_CONF_FILENAME_MAIN "./conf/main.conf"
#define KNI_OFFSET_ROUTDIR 1
#define KNI_OFFSET_CARDNAME 3
#define KNI_CARD_NUM 2
#define PROTO_TYPE_TCP 6
#define PROTO_TYPE_UDP 17
//maat
#define KNI_ACTION_NONE 0x00
#define KNI_ACTION_MONITOR 0x01
#define KNI_ACTION_REDIRECT 0X30
#define KNI_ACTION_RATELIMIT 0x40
#define KNI_ACTION_REPLACE 0x50
#define KNI_ACTION_WHITELIST 0x80
#define KNI_ACTION_HALFHIT -2
#define KNI_ACTION_NOTPROC -1
#define KNI_MAX_SAMENUM 10
#define KNI_TABLENAME_IP "WHITE_LIST_IP"
#define KNI_TABLENAME_DOMAIN "WHITE_LIST_DOMAIN"
#define KNI_TABLENAME_PKTBIN "PXY_INTERCEPT_PKT_BIN"
#define KNI_TABLENAME_SPOOFING_IP "PXY_OBJ_SPOOFING_IP_POOL"
#define KNI_TABLENAME_DNY_DOMAIN "IPD_RELATED_DOMAIN"
#define KNI_READCONF_IRIS 0
#define KNI_READCONF_JSON 1
#define KNI_READCONF_REDIS 2
#define KNI_SCANDIR_INTERVAL 1000
#define KNI_EFFECT_INTERVAL 60000
#define KNI_MAATJSON_FILEPATH "./kniconf/maat_test.json"
#define KNI_TABLEINFO_PATH "./kniconf/maat_table_info.conf"
#define KNI_FULLCFG_FILEPATH "/home/config/full/index"
#define KNI_INCCFG_FILEPATH "/home/config/inc/index"
#define KNI_STAT_FILEPATH "./log/kni_maat_stat"
#define KNI_DYN_STAT_FILEPATH "./log/kni_dyn_maat_stat"
//lqueue info
#define KNI_THREAD_SAFE 16
#define KNI_USLEEP_TIME 10
#define KNI_LQUEUE_MAXNUM 100000
//htable_info
#define KNI_HTABLE_SIZE 1024*1024
#define KNI_HTABLE_MAXNUM 100000
#define KNI_HTABLE_EXPIRE_TIME 60*60*24
//ssl info
#define KNI_SSL_PORT 443
#define KNI_SNI_MAXLEN 65535
#define SSL_HEADER_LEN 5
#define SSL_CONTENTTYPE_HANDSHAKE 0x16
#define SSL_VERSION_TLS1_0 0x0301
#define SSL_VERSION_TLS1_1 0x0302
#define SSL_VERSION_TLS1_2 0x0303
#define SSL_BODY_LEN 4
#define SSL_HANDSHAR_TYPE_CLIENTHELLO 0x01
#define SSL_EXTENSION_TYPE_SNI 0x0
#define KNI_MACADDR_LEN 6
//default tcp opt
#define KNI_DEFAULT_WINSCLE 0
#define KNI_DEFAULT_MSS 1460
//tcp opt type
#define KNI_TCPOPT_MSS 2
#define KNI_TCPOPT_WINSCALE 3
#define KNI_TCPOPT_SACKOK 4
#define KNI_TCPOPT_TIMESTAMP 8
#define KNI_DIR_DOUBLE 2
#define KNI_DIR_C2S 0
#define KNI_DIR_S2C 1
#define KNI_TCPREPAIR_OPT_NUM 4
#define KNI_PROJECT_NAME "protocol_tag"
#define KNI_DEFAULT_MODE_INTERCEPT 0
#define KNI_DEFAULT_MODE_BYPASS 1
#define KNI_SERVICE_LEN 4096
//tlv info
enum
{
KNI_TLV_MAGIC = 0x4d5a
};
enum KNI_TLV_TYPE
{
KNI_TLV_TYPE_PROTOCOL = 0x0001,
KNI_TLV_TYPE_KEYRING_ID = 0x0002
};
enum KNI_TLV_VALUE
{
KNI_TLV_VALUE_HTTP = 0x01,
KNI_TLV_VALUE_SSL = 0x02,
};
struct kni_tlv_header
{
uint16_t magic;
uint16_t counts;
};
struct kni_tlv_info
{
uint16_t type;
uint16_t len;
// uint8_t value[0];
};
struct kni_repaired_fds
{
int client_fd;
int server_fd;
int protocol;
int keyring;
};
struct kni_inject_pkt
{
int addr_type;
int buflen;
struct timespec start;
char* buf;
};
enum kni_flag
{
KNI_FLAG_UNKNOW=0,
KNI_FLAG_HTTP,
KNI_FLAG_SSL,
KNI_FLAG_OUTUSER,
KNI_FLAG_WHITELIST_IP,
KNI_FLAG_WHITELIST_DOMAIN,
KNI_FLAG_DROP,
KNI_FLAG_NOTPROC,
};
struct kni_switch_info
{
int maat_default_mode; //0:INTERCEPT 1:BYPASS
int replay_win_update; //0:not replay;1:replay
int ratelimit_switch;
int replace_switch;
int sendpkt_mode; //0:mesa_sendpkt_option;1:socket
int write_listq_switch; //0:no listq;1:has listq
int send_fds_mode; //0:has listq;1:no listq
int send_log_switch; //0:not send log;1:send log
};
struct kni_http_project
{
int host_len;
char host[KNI_DEFAULT_MTU];
};
//global variable
//comm
struct kni_var_comm
{
int project_id;
int kni_mode_cur; //0:work 1:bypass
int thread_num;
int tun_threadnum;
int fd_domain;
int mark;
int logger_level;
char tun_name[KNI_CONF_MAXLEN];
char domain_path[KNI_CONF_MAXLEN];
char card_in[KNI_CONF_MAXLEN];
char card_out[KNI_CONF_MAXLEN];
int* fd_tun;
void* logger;
int* fd_sendpkt;
};
//htable and lqueue
struct kni_var_struct
{
MESA_htable_handle htable_to_tun_v4;
MESA_htable_handle htable_to_tun_v6;
MESA_htable_handle htable_redirect;
MESA_lqueue_head lqueue_send_fds;
MESA_lqueue_head lqueue_write_tun[KNI_MAX_THREADNUM];
};
//maat
struct kni_var_maat
{
Maat_feather_t maat_feather;
Maat_feather_t ipd_dyn_maat_feather;
short tableid_ip;
short tableid_area;
short tableid_domain;
short tableid_pktbin;
short tableid_spoofing_ip;
short tableid_dynamic_domain;
};
//for get tcp option
struct kni_tcp_opt_format
{
char type;
char len;
char content[32];
};
struct common_tcp_opt
{
unsigned char sack_ok;
unsigned char wnscale;
unsigned short mss; //host order
unsigned int timestamp;
};
struct kni_wndpro_reply_info
{
unsigned int seq; //host order
unsigned int ack; //host order
unsigned int syn_flag;
unsigned int len; //tcp payload len:host order
unsigned short wndsize; //host order
};
struct kni_tcpopt_info
{
unsigned short mss; //host order
unsigned char wscale_perm;
unsigned char wscale; //host order
unsigned char sack_perm;
unsigned char timestamps;
};
//tcp retelimit config
struct kni_ratelimit_info
{
int molecule;
int denominator;
};
//tcpall/udp_entry pmeinfo
struct kni_pme_info
{
//test
int tun_index;
//end
int is_tcp_repaired;
int action;
int cfg_id;
int keyring_id;
int ipsscan_action;
int protocol;
int ser_def_len;
int client_fd; //only for log,not real fd
int server_fd; //only for log,not read fd
int maat_result_num;
scan_status_t mid;
char service_defined[KNI_SERVICE_LEN]; //for replace and ratelimited
struct stream_tuple4_v4 ipv4_addr;
struct stream_tuple4_v6 ipv6_addr;
struct Maat_rule_t maat_result[KNI_MAX_SAMENUM];
struct kni_ratelimit_info ratelimit_info;
struct redirect_htable_data redirect_info;
struct kni_tcpopt_info tcpopt_info[KNI_DIR_DOUBLE]; //for monitor,tcp repair
struct kni_wndpro_reply_info lastpkt_info[KNI_DIR_DOUBLE]; //for monitor,reply windows update
void* redirect_htable_key;
int redirect_key_len;
};
//htable_data_info ipv4
struct kni_htable_datainfo
{
//for sendpkt
int route_dir; //TODO:CHAR
unsigned char smac[KNI_MACADDR_LEN];
unsigned char dmac[KNI_MACADDR_LEN];
//send wnd pro reply
int wndprob_flag[KNI_DIR_DOUBLE];
struct kni_wndpro_reply_info lastpkt_info[KNI_DIR_DOUBLE];
};
//set tcp repair info
struct kni_tcp_state
{
struct sockaddr* src_addr;
struct sockaddr* dst_addr;
unsigned int seq;
unsigned int ack;
unsigned short win;
unsigned short mss_src;
unsigned short mss_dst;
unsigned char wscale_perm;
unsigned char wscale_src;
unsigned char wscale_dst;
unsigned char sack_src;
unsigned char sack_dst;
unsigned char timestamps_src;
unsigned char timestamps_dst;
};
struct args_read_tun
{
int thread_seq; //in
int iprevers; //in
int iplen; //in
int routdir; //out
char* a_packet; //in
unsigned char smac[KNI_MACADDR_LEN]; //out
unsigned char dmac[KNI_MACADDR_LEN]; //ouit
};
/*
#ifndef TCP_REPAIR_WINDOW
#define TCP_REPAIR_WINDOW 29
#endif
struct tcp_repair_window {
__u32 snd_wl1;
__u32 snd_wnd;
__u32 max_window;
__u32 rcv_wnd;
__u32 rcv_wup;
};
*/
//as same as sapp
#define NEXTHDR_HOP 0 /* Hop-by-hop option header. */
#define NEXTHDR_IPIP 4 /* IPIP header. */
#define NEXTHDR_TCP 6 /* TCP segment. */
#define NEXTHDR_UDP 17 /* UDP message. */
#define NEXTHDR_IPV6 41 /* IPv6 in IPv6 */
#define NEXTHDR_ROUTING 43 /* Routing header. */
#define NEXTHDR_FRAGMENT 44 /* Fragmentation/reassembly header. */
#define NEXTHDR_ESP 50 /* Encapsulating security payload. */
#define NEXTHDR_AUTH 51 /* Authentication header. */
#define NEXTHDR_ICMP 58 /* ICMP for IPv6. */
#define NEXTHDR_NONE 59 /* No next header */
#define NEXTHDR_DEST 60 /* Destination options header. */
#define NEXTHDR_MOBILITY 135 /* Mobility header. */
struct kni_ipv6_hdr
{
unsigned char ip6_flags[4];
unsigned short ip6_payload_len;
unsigned char ip6_nex_hdr;
unsigned char ip6_hop;
struct in6_addr ip6_src;
struct in6_addr ip6_dst;
};
struct kni_udp_hdr
{
unsigned short uh_sport; /* soure port */
unsigned short uh_dport; /* destination port */
unsigned short uh_ulen; /* length */
unsigned short uh_sum; /* checksum */
};
struct kni_tcp_hdr
{
unsigned short th_sport;
unsigned short th_dport;
unsigned int th_seq;
unsigned int th_ack;
# if __BYTE_ORDER == __LITTLE_ENDIAN
unsigned char th_x2:4,
th_off:4;
# elif __BYTE_ORDER == __BIG_ENDIAN
unsigned char th_off:4,
th_x2:4;
# else
# error "Adjust your <bits/endian.h> defines"
# endif
unsigned char th_flags;
unsigned short th_win;
unsigned short thsum;
unsigned short th_urp;
};
extern struct kni_var_comm g_kni_comminfo;
extern struct kni_var_struct g_kni_structinfo;
extern struct kni_var_maat g_kni_maatinfo;
extern struct kni_fs2_info g_kni_fs2_info;
extern struct kni_switch_info g_kni_switch_info;
extern int g_iThreadNum;
extern char g_kni_cardname[KNI_CARD_NUM][KNI_CONF_MAXLEN];
int kni_htable_del(const struct streaminfo* pstream,struct kni_pme_info* pmeinfo,const void* a_packet);
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -1,24 +0,0 @@
#ifndef KNI_CONNECT_H
#define KNI_CONNECT_H
#define KNI_SENDFD_NUM 2
int kni_send_fds(int socket, int *fds, int n,int protocol);
char tun_write_data(int fd, const char* send_buf, size_t send_buflen,struct streaminfo* pstream,int thread_seq,struct kni_pme_info* pmeinfo);
char tun_write_data_listq(int fd,char* send_buf,int send_buflen,int thread_seq);
int kni_unixdomain_create();
int init_kni_unixdomain();
int init_kni_tun();
void* pthread_process_tun(void* arg);
char kni_add_lqueue(int addrtype,int thread_seq,char* send_buf,int send_buflen,const struct streaminfo* pstream,int index,struct kni_pme_info* pmeinfo);
int tcp_repair_process(const struct streaminfo* pstream,const void* a_packet,struct kni_pme_info* pmeinfo,int protocol);
#endif

View File

@@ -1,122 +0,0 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include "kni_entry.h"
#include "kni_sendlog.h"
#include "kni_ratelimit.h"
char kni_judge_droppkt(int molecule,int denominator)
{
int i = random() % denominator;
if(i < molecule)
{
return APP_STATE_DROPPKT;
}
return APP_STATE_FAWPKT;
}
int kni_get_ratelimit(int cfg_id,struct kni_ratelimit_info* ratelimit_info,int ser_def_len,char* service_defined)
{
int i= 0;
int molecule_len = 0;
char* value = NULL;
char* molecule = NULL;
char* tmp = NULL;
tmp = kni_memncasemem(service_defined, ser_def_len,(char*)"Droprate=", strlen("Droprate="));
if(tmp == NULL)
{
MESA_handle_runtime_log(g_kni_comminfo.logger,RLOG_LV_FATAL,"RATELIMIT","service defined error!cfg_id:%d,region:%s",cfg_id,service_defined);
return -1;
}
value = kni_memncasemem(service_defined, ser_def_len,(char*)"=", strlen("="));
if(value == NULL)
{
MESA_handle_runtime_log(g_kni_comminfo.logger,RLOG_LV_FATAL,"RATELIMIT","service defined error!cfg_id:%d,region:%s",cfg_id,service_defined);
return -1;
}
value = value + 1;
if((value != NULL) && (value[0] == 1) && (value[1] == '.'))
{
ratelimit_info->denominator = 1;
ratelimit_info->molecule = 1;
return 0;
}
molecule = kni_memncasemem(service_defined, ser_def_len,(char*)".", strlen("."));
if(molecule == NULL)
{
MESA_handle_runtime_log(g_kni_comminfo.logger,RLOG_LV_FATAL,"RATELIMIT","service defined error!cfg_id:%d,region:%s",cfg_id,service_defined);
return -1;
}
molecule = molecule + 1;
if((molecule != NULL))
{
molecule_len = strlen(molecule) - 1;
ratelimit_info->denominator = 1;
for(i=0;i<=molecule_len;i++)
{
ratelimit_info->denominator *= 10;
}
ratelimit_info->molecule = atoi(molecule);
}
return 0;
}
char kni_process_ratelimit(int thread_seq,const struct streaminfo* pstream,const void* a_packet,struct kni_pme_info* pmeinfo)
{
if((pmeinfo == NULL) || (g_kni_switch_info.ratelimit_switch == 0))
{
return APP_STATE_DROPME;
}
kni_filestate2_set(thread_seq,FS_RATELIMIT_UDP,0,1);
char ret = APP_STATE_GIVEME;
struct kni_ratelimit_info* ratelimit_info = &(pmeinfo->ratelimit_info);
struct kni_log sendlog_msg;
if((ratelimit_info->denominator == 0) && (ratelimit_info->molecule == 0))
{
if(kni_get_ratelimit(pmeinfo->cfg_id,ratelimit_info,pmeinfo->ser_def_len,pmeinfo->service_defined) < 0)
{
kni_log_debug(RLOG_LV_FATAL,(char*)"RATELIMIT",a_packet,(char*)"kni_get_ratelimit error");
return APP_STATE_DROPME;
}
sendlog_msg.stream = pstream;
sendlog_msg.result = pmeinfo->maat_result;
sendlog_msg.result_num = pmeinfo->maat_result_num;
kni_send_log(&sendlog_msg,NULL,NULL);
kni_log_debug(RLOG_LV_INFO,(char*)"RATELIMIT",a_packet,(char*)"config_id:%d,molecule:%d,denominator:%d",pmeinfo->cfg_id,ratelimit_info->molecule,ratelimit_info->denominator);
}
ret = kni_judge_droppkt(ratelimit_info->molecule,ratelimit_info->denominator);
return ret;
}

View File

@@ -1,7 +0,0 @@
#ifndef KNI_RATELIMIT_H
#define KNI_RATELIMIT_H
char kni_process_ratelimit(int thread_seq,const struct streaminfo* pstream,const void* a_packet,struct kni_pme_info* pmeinfo);
#endif

View File

@@ -1,682 +0,0 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include <arpa/inet.h>
#include "stream.h"
#include "Maat_rule.h"
#include "kni_redirect.h"
#include "kni_sendlog.h"
#include "kni_entry.h"
#include "kni_comm.h"
extern "C" int sendpacket_do_checksum(unsigned char* buf,int protocol,int len);
long redirect_htable_search_cb(void* data,const unsigned char* key,unsigned int size,void* user_arg)
{
long result=0;
if(data!=NULL)
{
memcpy(user_arg,data,sizeof(struct redirect_htable_data));
result = 1;
}
return result;
}
//only snat_replay_pending or dnat_replay_pending call this function
//1:exit;0:not exit -1:error
int redirect_search_htable(unsigned char addr_type,struct kni_pme_info* pmeinfo,int thread_seq,const void* a_packet,int protocol)
{
struct ip* ipv4_hdr = NULL;
struct kni_ipv6_hdr* ipv6_hdr = NULL;
struct kni_tcp_hdr* tcphdr=NULL;
struct kni_udp_hdr* udphdr=NULL;
long result = 0;
struct stream_tuple4_v4 htable_key_v4;
struct stream_tuple4_v6 htable_key_v6;
if(addr_type==ADDR_TYPE_IPV4)
{
ipv4_hdr = (struct ip*)a_packet;
htable_key_v4.saddr=(ipv4_hdr->ip_src).s_addr;
htable_key_v4.daddr=(ipv4_hdr->ip_dst).s_addr;
if(protocol==PROTO_TYPE_TCP)
{
tcphdr=(struct kni_tcp_hdr*)((char*)ipv4_hdr+4*(ipv4_hdr->ip_hl));
htable_key_v4.source=tcphdr->th_sport;
htable_key_v4.dest=tcphdr->th_dport;
}
else if(protocol == PROTO_TYPE_UDP)
{
udphdr=(struct kni_udp_hdr*)((char*)ipv4_hdr+4*(ipv4_hdr->ip_hl));
htable_key_v4.source=udphdr->uh_sport;
htable_key_v4.dest=udphdr->uh_dport;
}
else
{
htable_key_v4.source=0;
htable_key_v4.dest=0;
}
MESA_htable_search_cb(g_kni_structinfo.htable_redirect,(unsigned char*)&htable_key_v4,sizeof(htable_key_v4),redirect_htable_search_cb,(void*)&(pmeinfo->redirect_info),&result);
}
else if(addr_type==ADDR_TYPE_IPV6)
{
ipv6_hdr = (struct kni_ipv6_hdr*)a_packet;
memcpy(htable_key_v6.saddr,&(ipv6_hdr->ip6_src),sizeof(htable_key_v6.saddr));
memcpy(htable_key_v6.daddr,&(ipv6_hdr->ip6_dst),sizeof(htable_key_v6.daddr));
if(protocol==PROTO_TYPE_TCP)
{
// tcphdr=(struct kni_tcp_hdr*)((char*)ipv4_hdr+4*(ipv4_hdr->ip_hl));
tcphdr =(struct kni_tcp_hdr*)( (unsigned char*)ipv6_hdr + sizeof(struct kni_ipv6_hdr));
htable_key_v6.source=tcphdr->th_sport;
htable_key_v6.dest=tcphdr->th_dport;
}
else if(protocol == PROTO_TYPE_UDP)
{
// udphdr=(struct kni_udp_hdr*)((char*)ipv4_hdr+4*(ipv4_hdr->ip_hl));
udphdr=(struct kni_udp_hdr*)( (unsigned char*)ipv6_hdr + sizeof(struct kni_ipv6_hdr));
htable_key_v6.source=udphdr->uh_sport;
htable_key_v6.dest=udphdr->uh_dport;
}
else
{
htable_key_v6.source=0;
htable_key_v6.dest=0;
}
MESA_htable_search_cb(g_kni_structinfo.htable_redirect,(unsigned char*)&htable_key_v6,sizeof(htable_key_v6),redirect_htable_search_cb,(void*)&(pmeinfo->redirect_info),&result);
}
if(result == 1)
{
pmeinfo->action=KNI_ACTION_REDIRECT;
kni_log_debug(RLOG_LV_DEBUG,(char*)"redirect_search_htable",a_packet,"search htable_data succ!");
kni_filestate2_set(thread_seq,FS_REDIRECT_REPLY,0,1);
}
return result;
}
int redirect_add_htable(unsigned char addr_type,struct kni_pme_info* pmeinfo,int thread_seq,const void* a_packet,int protocol)
{
int ret =0;
struct ip* ipv4_hdr = NULL;
struct kni_ipv6_hdr* ipv6_hdr = NULL;
struct kni_tcp_hdr* tcphdr=NULL;
struct kni_udp_hdr* udphdr=NULL;
struct stream_tuple4_v4 htable_key_v4;
struct stream_tuple4_v6 htable_key_v6;
struct redirect_htable_data* htable_data=(struct redirect_htable_data*)malloc(sizeof(struct redirect_htable_data));
memset(htable_data,0,sizeof(struct redirect_htable_data));
htable_data->addr_type=addr_type;
if(addr_type==4)
{
ipv4_hdr = (struct ip*)a_packet;
if(pmeinfo->redirect_info.nat_type == REDIRECT_SNAT_TYPE)
{
htable_data->nat_type=REDIRECT_SNAT_REPLAY;
htable_data->ipv4=(ipv4_hdr->ip_src).s_addr;
htable_key_v4.saddr=(ipv4_hdr->ip_dst).s_addr;
htable_key_v4.daddr=pmeinfo->redirect_info.ipv4;
}
else if(pmeinfo->redirect_info.nat_type == REDIRECT_DNAT_TYPE)
{
htable_data->nat_type=REDIRECT_DNAT_REPLAY;
htable_data->ipv4=(ipv4_hdr->ip_dst).s_addr;
htable_key_v4.saddr=pmeinfo->redirect_info.ipv4;
htable_key_v4.daddr=(ipv4_hdr->ip_src).s_addr;
}
else
{
MESA_handle_runtime_log(g_kni_comminfo.logger,RLOG_LV_FATAL,"redirect","redirect_add_htable err,nat_type:%d",pmeinfo->redirect_info.nat_type);
return -1;
}
if(protocol==PROTO_TYPE_TCP)
{
tcphdr=(struct kni_tcp_hdr*)((char*)ipv4_hdr+4*(ipv4_hdr->ip_hl));
htable_key_v4.source=tcphdr->th_dport;
htable_key_v4.dest=tcphdr->th_sport;
}
else if(protocol == PROTO_TYPE_UDP)
{
udphdr=(struct kni_udp_hdr*)((char*)ipv4_hdr+4*(ipv4_hdr->ip_hl));
htable_key_v4.source=udphdr->uh_dport;
htable_key_v4.dest=udphdr->uh_sport;
}
else
{
htable_key_v4.source=0;
htable_key_v4.dest=0;
}
pmeinfo->redirect_key_len=sizeof(htable_key_v4);
pmeinfo->redirect_htable_key=(char*)malloc(pmeinfo->redirect_key_len);
memcpy(pmeinfo->redirect_htable_key,&htable_key_v4,pmeinfo->redirect_key_len);
ret = MESA_htable_add(g_kni_structinfo.htable_redirect,(unsigned char*)pmeinfo->redirect_htable_key,pmeinfo->redirect_key_len,(const void *)htable_data);
kni_log_debug(RLOG_LV_DEBUG,(char*)"redirect_htable_add",a_packet,"key:%u,%d,%u,%d,data:%u",
htable_key_v4.saddr,htable_key_v4.source,htable_key_v4.daddr,htable_key_v4.dest,htable_data->ipv4);
}
else if(addr_type==6)
{
ipv6_hdr = (struct kni_ipv6_hdr*)a_packet;
if(pmeinfo->redirect_info.nat_type == REDIRECT_SNAT_TYPE)
{
htable_data->nat_type=REDIRECT_SNAT_REPLAY;
memcpy(htable_data->ipv6,&(ipv6_hdr->ip6_src),sizeof(htable_data->ipv6));
memcpy(htable_key_v6.saddr,&(ipv6_hdr->ip6_dst),sizeof(htable_key_v6.saddr));
memcpy(htable_key_v6.daddr,pmeinfo->redirect_info.ipv6,sizeof(htable_key_v6.daddr));
}
else if(pmeinfo->redirect_info.nat_type == REDIRECT_DNAT_TYPE)
{
htable_data->nat_type=REDIRECT_DNAT_REPLAY;
memcpy(htable_data->ipv6,&(ipv6_hdr->ip6_dst),sizeof(htable_data->ipv6));
memcpy(htable_key_v6.saddr,pmeinfo->redirect_info.ipv6,sizeof(htable_key_v6.saddr));
memcpy(htable_key_v6.daddr,&(ipv6_hdr->ip6_src),sizeof(htable_key_v6.daddr));
}
else
{
MESA_handle_runtime_log(g_kni_comminfo.logger,RLOG_LV_FATAL,"redirect","redirect_add_htable err,nat_type:%d",pmeinfo->redirect_info.nat_type);
return -1;
}
if(protocol==PROTO_TYPE_TCP)
{
tcphdr=(struct kni_tcp_hdr*)((char*)ipv4_hdr+4*(ipv4_hdr->ip_hl));
htable_key_v6.source=tcphdr->th_dport;
htable_key_v6.dest=tcphdr->th_sport;
}
else if(protocol == PROTO_TYPE_UDP)
{
udphdr=(struct kni_udp_hdr*)((char*)ipv4_hdr+4*(ipv4_hdr->ip_hl));
htable_key_v6.source=udphdr->uh_dport;
htable_key_v6.dest=udphdr->uh_sport;
}
else
{
htable_key_v6.source=0;
htable_key_v6.dest=0;
}
pmeinfo->redirect_key_len=sizeof(htable_key_v6);
pmeinfo->redirect_htable_key=(char*)malloc(pmeinfo->redirect_key_len);
memcpy(pmeinfo->redirect_htable_key,&htable_key_v6,pmeinfo->redirect_key_len);
ret = MESA_htable_add(g_kni_structinfo.htable_redirect,(unsigned char*)pmeinfo->redirect_htable_key,pmeinfo->redirect_key_len,(const void *)htable_data);
}
return ret;
}
void redirect_free_htable_data(void* data)
{
if(data != NULL)
{
free(data);
}
data=NULL;
return;
}
int redirect_del_htable(void* htable_key,int key_len)
{
MESA_htable_del(g_kni_structinfo.htable_redirect,(const unsigned char*)htable_key,key_len,redirect_free_htable_data);
return 0;
}
/*
int redirect_get_service_define(char* service_defined,int ser_def_len,struct redirect_serdef_info* out)
{
int ip_pool_len =0;
int nat_type_len = 0;
char* ip_pool = NULL;
char* nat_type = NULL;
// char* tmp = NULL;
ip_pool = kni_memncasemem(service_defined, ser_def_len,(char*)"spoofing_ip_pool=", strlen("spoofing_ip_pool="));
if(ip_pool == NULL)
{
return -1;
}
ip_pool += 1;
ip_pool_len = strlen(ip_pool);
nat_type = kni_memncasemem(ip_pool,ip_pool_len,(char*)"nat_type=", strlen("nat_type="));
if(nat_type == NULL)
{
return -1;
}
nat_type += 1;
nat_type_len = strlen(nat_type);
out->ip_pool_len= nat_type - ip_pool -1;
assert((int)sizeof(out->ip_pool)>=out->ip_pool_len);
memcpy(out->ip_pool,ip_pool,out->ip_pool_len);
out->nat_type_len= nat_type_len-1;
assert((int)sizeof(out->nat_type)>=out->nat_type_len);
memcpy(out->nat_type,nat_type,out->nat_type_len);
return 0;
}
*/
int redirect_get_service_define(char* service_defined,int ser_def_len,struct redirect_serdef_info* out)
{
int ret = sscanf(service_defined, "nat_type=%[^;];spoofing_ip_pool=%[^\n]", out->nat_type, out->ip_pool);
assert(ret == 2);
return 0;
}
static int get_column_pos(const char* line, int column_seq, size_t *offset, size_t *len)
{
const char* seps=" \t";
char* saveptr=NULL, *subtoken=NULL, *str=NULL;
char* dup_line = (char *)malloc(strlen(line) + 1);
strcpy(dup_line, line);
int i=0, ret=-1;
for (str = dup_line; ; str = NULL)
{
subtoken = strtok_r(str, seps, &saveptr);
if (subtoken == NULL)
break;
if(i==column_seq-1)
{
*offset=subtoken-dup_line;
*len=strlen(subtoken);
ret=0;
break;
}
i++;
}
free(dup_line);
return ret;
}
void plugin_EX_new_cb(int table_id, const char* key, const char* table_line, MAAT_PLUGIN_EX_DATA* ad, long argl, void *argp)
{
struct redirect_plugin_ex_data* add_data = (struct redirect_plugin_ex_data*)calloc(sizeof(struct redirect_plugin_ex_data), 1);
int ret = 0;
size_t offset=0, len=0;
*ad=NULL;
ret=get_column_pos(table_line, 2, &offset, &len);
if(ret<0)
{
return;
}
sscanf(table_line+offset, "%d", &(add_data->addr_type));
ret=get_column_pos(table_line, 4, &offset, &len);
if(ret<0)
{
return;
}
assert(len<=sizeof(add_data->spoofing_ip));
strncpy(add_data->spoofing_ip, table_line+offset, len);
*ad=add_data;
return;
}
void plugin_EX_free_cb(int table_id, MAAT_PLUGIN_EX_DATA* ad, long argl, void *argp)
{
struct redirect_plugin_ex_data* free_data=(struct redirect_plugin_ex_data*)(*ad);
free(free_data);
*ad=NULL;
return ;
}
void plugin_EX_dup_cb(int table_id, MAAT_PLUGIN_EX_DATA *to, MAAT_PLUGIN_EX_DATA *from, long argl, void *argp)
{
struct redirect_plugin_ex_data* dup_data=(struct redirect_plugin_ex_data*)malloc(sizeof(struct redirect_plugin_ex_data));
memcpy(dup_data,*from,sizeof(struct redirect_plugin_ex_data));
*to=dup_data;
return;
}
int redirect_sendpkt_v4(int protocol,unsigned char dir,int thread_seq,struct ip* a_packet,struct redirect_htable_data* sendpkt_args)
{
int ret = 0;
unsigned short sendbuf_len = ntohs(a_packet->ip_len);
struct ip* iphdr_sendbuf = NULL;
char* sendbuf = (char*)malloc(sendbuf_len);
memcpy(sendbuf,(char*)a_packet,sendbuf_len);
iphdr_sendbuf=(struct ip*)sendbuf;
if((sendpkt_args->nat_type == REDIRECT_SNAT_TYPE)||(sendpkt_args->nat_type == REDIRECT_DNAT_REPLAY))
{
iphdr_sendbuf->ip_src.s_addr=sendpkt_args->ipv4;
}
else
{
iphdr_sendbuf->ip_dst.s_addr=sendpkt_args->ipv4;
}
if(protocol == PROTO_TYPE_TCP)
{
sendpacket_do_checksum((unsigned char*)sendbuf,IPPROTO_TCP,(sendbuf_len-4*(a_packet->ip_hl)));
}
else if(protocol == PROTO_TYPE_UDP)
{
sendpacket_do_checksum((unsigned char*)sendbuf,IPPROTO_UDP,(sendbuf_len-4*(a_packet->ip_hl)));
}
sendpacket_do_checksum((unsigned char*)sendbuf,IPPROTO_IP,sizeof(struct ip));
MESA_sendpacket_iplayer(thread_seq,sendbuf,sendbuf_len,dir);
free(sendbuf);
sendbuf = NULL;
return ret;
}
int redirect_sendpkt_v6(int protocol,unsigned char dir,int thread_seq,struct kni_ipv6_hdr* ipv6_hdr,struct redirect_htable_data* sendpkt_args)
{
struct kni_ipv6_hdr* ipv6_hdr_sendbuf=NULL;
int sendbuf_len = ntohs(ipv6_hdr->ip6_payload_len) + sizeof(struct kni_ipv6_hdr);
char* sendbuf = (char*)malloc(sendbuf_len);
memcpy(sendbuf,ipv6_hdr,sendbuf_len);
ipv6_hdr_sendbuf = (struct kni_ipv6_hdr*)sendbuf;
if((sendpkt_args->nat_type == REDIRECT_SNAT_TYPE)||(sendpkt_args->nat_type == REDIRECT_DNAT_REPLAY))
{
memcpy(&(ipv6_hdr_sendbuf->ip6_src),sendpkt_args->ipv6,sizeof(ipv6_hdr_sendbuf->ip6_src));
}
else
{
memcpy(&(ipv6_hdr_sendbuf->ip6_dst),sendpkt_args->ipv6,sizeof(ipv6_hdr_sendbuf->ip6_dst));
}
if(protocol == PROTO_TYPE_TCP)
{
sendpacket_do_checksum((unsigned char*)sendbuf,IPPROTO_TCP,ntohs(ipv6_hdr->ip6_payload_len));
}
else if(protocol == PROTO_TYPE_UDP)
{
sendpacket_do_checksum((unsigned char*)sendbuf,IPPROTO_UDP,ntohs(ipv6_hdr->ip6_payload_len));
}
// sendpacket_do_checksum((unsigned char*)sendbuf,IPPROTO_IP,sizeof(struct ip));
MESA_sendpacket_iplayer(thread_seq,sendbuf,sendbuf_len,dir);
free(sendbuf);
sendbuf = NULL;
return 0;
}
int redirect_sendlog(const struct streaminfo* pstream,struct kni_pme_info* pmeinfo,int thread_seq,struct redirect_plugin_ex_data* dup_data,const void* a_packet)
{
struct kni_log log_msg;
struct ip* ipv4_hdr = (struct ip*)a_packet;
struct kni_ipv6_hdr* ipv6_hdr = (struct kni_ipv6_hdr*)a_packet;
char content[1024]={0};
char orginal_ip[INET6_ADDRSTRLEN]={0};
if(pmeinfo->redirect_info.nat_type ==REDIRECT_SNAT_TYPE)
{
if(dup_data->addr_type == 4)
{
inet_ntop(AF_INET, (void *)&((ipv4_hdr->ip_src).s_addr), orginal_ip, INET_ADDRSTRLEN);
}
else
{
inet_ntop(AF_INET, (void *)&(ipv6_hdr->ip6_src), orginal_ip, INET6_ADDRSTRLEN);
}
}
else if(pmeinfo->redirect_info.nat_type ==REDIRECT_DNAT_TYPE)
{
if(dup_data->addr_type == 4)
{
inet_ntop(AF_INET, (void *)&((ipv4_hdr->ip_dst).s_addr), orginal_ip, INET_ADDRSTRLEN);
}
else
{
inet_ntop(AF_INET, (void *)&(ipv6_hdr->ip6_dst), orginal_ip, INET6_ADDRSTRLEN);
}
}
sprintf(content,"%s->%s",orginal_ip,dup_data->spoofing_ip);
log_msg.stream = pstream;
log_msg.result = pmeinfo->maat_result;
log_msg.result_num = pmeinfo->maat_result_num;
kni_send_log(&log_msg,(char*)"redirect",content);
kni_log_debug(RLOG_LV_DEBUG,(char*)"redirect_pending",a_packet,"content:%s",content);
kni_filestate2_set(thread_seq,FS_REDIRECT,0,1);
return 0;
}
char process_redirect_pending(const struct streaminfo* pstream,struct kni_pme_info* pmeinfo,int thread_seq,const void* a_packet,int protocol,unsigned char dir)
{
char ret=APP_STATE_FAWPKT|APP_STATE_DROPME;
int result=0;
struct in_addr ipv4_addr;
struct in6_addr ipv6_addr;
struct redirect_plugin_ex_data* dup_data=NULL;
struct redirect_serdef_info redirect_args;
memset(&redirect_args,0,sizeof(redirect_args));
//get service_defined
// result=sscanf(pmeinfo->service_defined,"spoofing_ip_pool=%s;nat_type=%s",redirect_args.ip_pool,redirect_args.nat_type);
result=redirect_get_service_define(pmeinfo->service_defined,pmeinfo->ser_def_len,&redirect_args);
if(result < 0)
{
MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,(char*)"redirect","redirect_get_service_define() error,cfg_id:%d,service_def:%s",pmeinfo->cfg_id,pmeinfo->service_defined);
return ret;
}
//get dup_data
dup_data=(struct redirect_plugin_ex_data*)Maat_plugin_get_EX_data(g_kni_maatinfo.maat_feather,g_kni_maatinfo.tableid_spoofing_ip,redirect_args.ip_pool);
if(dup_data == NULL)
{
MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,(char*)"redirect","Maat_plugin_get_EX_data() get NULL,key:%s!",redirect_args.ip_pool);
return ret;
}
//set pmeinfo->redirect_info
if(strcasecmp(redirect_args.nat_type,"snat") == 0)
{
pmeinfo->redirect_info.nat_type=REDIRECT_SNAT_TYPE;
}
else if(strcasecmp(redirect_args.nat_type,"dnat") == 0)
{
pmeinfo->redirect_info.nat_type=REDIRECT_DNAT_TYPE;
}
else
{
MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,(char*)"redirect","nat_type:%s,error!",redirect_args.nat_type);
return ret;
}
pmeinfo->redirect_info.addr_type=dup_data->addr_type;
if(pmeinfo->redirect_info.addr_type == 4)
{
inet_pton(AF_INET,dup_data->spoofing_ip,&ipv4_addr);
pmeinfo->redirect_info.ipv4 = ipv4_addr.s_addr;
redirect_sendpkt_v4(protocol,dir,thread_seq,(struct ip*)a_packet,&(pmeinfo->redirect_info));
}
else if(pmeinfo->redirect_info.addr_type == 6)
{
inet_pton(AF_INET6,dup_data->spoofing_ip,&ipv6_addr);
memcpy(pmeinfo->redirect_info.ipv6 ,&(ipv6_addr),sizeof(pmeinfo->redirect_info.ipv6));
redirect_sendpkt_v6(protocol,dir,thread_seq,(struct kni_ipv6_hdr*)a_packet,&pmeinfo->redirect_info);
}
else
{
MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,(char*)"redirect","addr_type:%d,error!",pmeinfo->redirect_info.addr_type);
return ret;
}
//send_log
redirect_sendlog(pstream,pmeinfo,thread_seq,dup_data,a_packet);
//add htable
result=redirect_add_htable(pmeinfo->redirect_info.addr_type,pmeinfo,thread_seq,a_packet,protocol);
if(result < 0)
{
MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,(char*)"redirect","redirect_add_htable() error,ret:%d",result);
return ret;
}
return APP_STATE_GIVEME|APP_STATE_DROPPKT;
}
char process_redirect_data(const struct streaminfo* pstream,struct kni_pme_info* pmeinfo,int thread_seq,const void* a_packet,int protocol,unsigned char dir)
{
char ret=APP_STATE_GIVEME|APP_STATE_DROPPKT;
if(pmeinfo->redirect_info.addr_type==4)
{
redirect_sendpkt_v4(protocol,dir,thread_seq,(struct ip*)a_packet,&pmeinfo->redirect_info);
}
else if(pmeinfo->redirect_info.addr_type==6)
{
redirect_sendpkt_v6(protocol,dir,thread_seq,(struct kni_ipv6_hdr*)a_packet,&pmeinfo->redirect_info);
}
else
{
MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,(char*)"redirect","process_redirect_data() error,addr_type:%d",pmeinfo->redirect_info.addr_type);
return APP_STATE_DROPPKT|APP_STATE_DROPME;
}
return ret;
}
char process_redirect_close(const struct streaminfo* pstream,struct kni_pme_info* pmeinfo,int thread_seq,const void* a_packet,int protocol,unsigned char dir)
{
char ret=APP_STATE_GIVEME|APP_STATE_DROPPKT;
if(a_packet != NULL)
{
process_redirect_data(pstream,pmeinfo,thread_seq,a_packet,protocol,dir);
}
redirect_del_htable(pmeinfo->redirect_htable_key,pmeinfo->redirect_key_len);
free(pmeinfo->redirect_htable_key);
pmeinfo->redirect_htable_key=NULL;
return ret;
}
int kni_init_redirect_htable()
{
MESA_htable_create_args_t hash_frags;
memset(&hash_frags,0,sizeof(hash_frags));
hash_frags.thread_safe=KNI_THREAD_SAFE;
hash_frags.recursive=1;
hash_frags.hash_slot_size=KNI_HTABLE_SIZE;
hash_frags.max_elem_num=KNI_HTABLE_MAXNUM;
hash_frags.eliminate_type=HASH_ELIMINATE_ALGO_FIFO;
hash_frags.expire_time=0;
hash_frags.key_comp=NULL;
hash_frags.key2index=NULL;
hash_frags.data_free=NULL;
hash_frags.data_expire_with_condition=NULL;
g_kni_structinfo.htable_redirect=MESA_htable_create(&hash_frags,sizeof(MESA_htable_create_args_t));
if(g_kni_structinfo.htable_redirect==NULL)
{
MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,KNI_MODULE_INIT,"htable_redirect MESA_htable_create() error!");
return -1;
}
return 0;
}

View File

@@ -1,56 +0,0 @@
#ifndef KNI_REDIRECT_H
#define KNI_REDIRECT_H
#ifndef IPV6_ADDR_LEN
#define IPV6_ADDR_LEN (sizeof(struct in6_addr))
#endif
#define REDIRECT_SERDEF_LEN 16
#define REDIRECT_SNAT_TYPE 1
#define REDIRECT_DNAT_TYPE 2
#define REDIRECT_SNAT_REPLAY 3
#define REDIRECT_DNAT_REPLAY 4
//maat plugin ex data
struct redirect_plugin_ex_data
{
int addr_type;
char spoofing_ip[INET6_ADDRSTRLEN];
};
//redirect htable data
struct redirect_htable_data
{
int nat_type;
int addr_type;
unsigned int ipv4;
char ipv6[IPV6_ADDR_LEN];
};
struct redirect_serdef_info
{
char ip_pool[REDIRECT_SERDEF_LEN];
char nat_type[REDIRECT_SERDEF_LEN];
};
int redirect_search_htable(unsigned char addr_type,struct kni_pme_info* pmeinfo,int thread_seq,const void* a_packet,int protocol);
char process_redirect_pending(const struct streaminfo* pstream,struct kni_pme_info* pmeinfo,int thread_seq,const void* a_packet,int protocol,unsigned char dir);
char process_redirect_data(const struct streaminfo* pstream,struct kni_pme_info* pmeinfo,int thread_seq,const void* a_packet,int protocol,unsigned char dir);
char process_redirect_close(const struct streaminfo* pstream,struct kni_pme_info* pmeinfo,int thread_seq,const void* a_packet,int protocol,unsigned char dir);
void plugin_EX_new_cb(int table_id, const char* key, const char* table_line, MAAT_PLUGIN_EX_DATA* ad, long argl, void *argp);
void plugin_EX_free_cb(int table_id, MAAT_PLUGIN_EX_DATA* ad, long argl, void *argp);
void plugin_EX_dup_cb(int table_id, MAAT_PLUGIN_EX_DATA *to, MAAT_PLUGIN_EX_DATA *from, long argl, void *argp);
int kni_init_redirect_htable();
#endif

View File

@@ -1,272 +0,0 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include "kni_sendlog.h"
#include "kni_replace.h"
#include "kni_entry.h"
extern "C" int sendpacket_do_checksum(unsigned char* buf,int protocol,int len);
int kni_get_replace(int cfg_id,int ser_def_len,char* service_defined,struct kni_replace_info* replace_info)
{
int original_len =0;
int replace_len = 0;
char* original = NULL;
char* replace = NULL;
char* tmp = NULL;
tmp = kni_memncasemem(service_defined, ser_def_len,(char*)"zone=pkt_payload;substitute=", strlen("zone=pkt_payload;substitute="));
if(tmp == NULL)
{
MESA_handle_runtime_log(g_kni_comminfo.logger,RLOG_LV_FATAL,"REPLACE","service defined error!cfg_id:%d,region:%s",cfg_id,service_defined);
return -1;
}
original = kni_memncasemem(service_defined, ser_def_len,(char*)"/", strlen("/"));
if(original == NULL)
{
MESA_handle_runtime_log(g_kni_comminfo.logger,RLOG_LV_FATAL,"REPLACE","service defined error!cfg_id:%d,region:%s",cfg_id,service_defined);
return -1;
}
original += 1;
original_len = strlen(original);
replace = kni_memncasemem(original+1,original_len-1,(char*)"/", strlen("/"));
if(replace == NULL)
{
MESA_handle_runtime_log(g_kni_comminfo.logger,RLOG_LV_FATAL,"REPLACE","service defined error!cfg_id:%d,region:%s",cfg_id,service_defined);
return -1;
}
replace += 1;
replace_len = strlen(replace);
replace_info->original_len = replace - original -1;
assert((int)sizeof(replace_info->find)>=replace_info->original_len);
memcpy(replace_info->find,original,replace_info->original_len);
replace_info->replace_len = replace_len;
assert((int)sizeof(replace_info->replace)>=replace_info->replace_len);
memcpy(replace_info->replace,replace,replace_info->replace_len);
return 0;
}
int kni_build_send_ipv4(unsigned char dir,int thread_seq,struct ip* a_packet,struct kni_pme_info* pmeinfo,struct kni_replace_info* replace_info)
{
// char ret = APP_STATE_DROPPKT | APP_STATE_DROPME;
char ret = APP_STATE_DROPPKT | APP_STATE_GIVEME;
struct ip* iphdr = NULL;
struct kni_udp_hdr* udphdr = NULL;
char* payload = ((char*)a_packet+4*(a_packet->ip_hl));
unsigned short iplen = ntohs(a_packet->ip_len);
unsigned short udplen = 0;
int payload_len = iplen - 4*(a_packet->ip_hl);
char* pos = NULL;
char* sendbuf = NULL;
unsigned short sendbuf_len = 0;
int tmp_len = 0;
pos = (char*)memmem(payload, payload_len,(replace_info->find), replace_info->original_len);
if(pos != NULL)
{
sendbuf_len = iplen - replace_info->original_len + replace_info->replace_len;
sendbuf = (char*)malloc(sendbuf_len);
memcpy(sendbuf,(char*)a_packet,(pos-(char*)a_packet));
tmp_len += pos-(char*)a_packet;
memcpy(sendbuf+tmp_len,replace_info->replace,replace_info->replace_len);
tmp_len += replace_info->replace_len;
memcpy(sendbuf+tmp_len,(pos+replace_info->original_len),sendbuf_len-tmp_len);
iphdr = (struct ip*)sendbuf;
iphdr->ip_len = ntohs(sendbuf_len);
// if(iphdr->ip_p == PROTO_TYPE_UDP)
{
udphdr = (struct kni_udp_hdr*)(sendbuf + 4*(iphdr->ip_hl));
udplen = ntohs(udphdr->uh_ulen);
udphdr->uh_ulen = htons(udplen - replace_info->original_len + replace_info->replace_len);
}
sendpacket_do_checksum((unsigned char*)sendbuf,IPPROTO_UDP,(sendbuf_len-4*(iphdr->ip_hl)));
sendpacket_do_checksum((unsigned char*)sendbuf,IPPROTO_IP,sizeof(struct ip));
MESA_sendpacket_iplayer(thread_seq,sendbuf,sendbuf_len,dir);
free(sendbuf);
sendbuf = NULL;
}
else
{
ret = APP_STATE_FAWPKT | APP_STATE_GIVEME;
}
return ret;
}
int kni_build_send_ipv6(unsigned char dir,int thread_seq,struct kni_ipv6_hdr* ipv6_hdr,struct kni_pme_info* pmeinfo,struct kni_replace_info* replace_info)
{
/*
char ret = APP_STATE_DROPPKT | APP_STATE_DROPME;
return ret;
*/
// char ret = APP_STATE_DROPPKT | APP_STATE_DROPME;
if((ipv6_hdr == NULL) || (ipv6_hdr->ip6_nex_hdr != NEXTHDR_UDP))
{
MESA_handle_runtime_log(g_kni_comminfo.logger,RLOG_LV_FATAL,KNI_MODULE_SENDPKT,"kni_build_send_ipv6():ipv6_hdr->ip6_nex_hdr != NEXTHDR_UDP");
return APP_STATE_DROPPKT | APP_STATE_DROPME;
}
char ret = APP_STATE_DROPPKT | APP_STATE_GIVEME;
struct kni_ipv6_hdr* send_ipv6_hdr=NULL;
struct kni_udp_hdr* send_udphdr =NULL;
unsigned short send_udplen = 0;
char* payload = ((char*)((unsigned char*)ipv6_hdr + sizeof(struct kni_ipv6_hdr)));
int payload_len = ntohs(ipv6_hdr->ip6_payload_len);
int iplen = ntohs(ipv6_hdr->ip6_payload_len) + sizeof(struct kni_ipv6_hdr);
char* pos = NULL;
char* sendbuf = NULL;
unsigned short sendbuf_len = 0;
int tmp_len = 0;
pos = (char*)memmem(payload, payload_len,(replace_info->find), replace_info->original_len);
if(pos != NULL)
{
sendbuf_len = iplen - replace_info->original_len + replace_info->replace_len;
sendbuf = (char*)malloc(sendbuf_len);
memcpy(sendbuf,(char*)ipv6_hdr,(pos-(char*)ipv6_hdr));
tmp_len += pos-(char*)ipv6_hdr;
memcpy(sendbuf+tmp_len,replace_info->replace,replace_info->replace_len);
tmp_len += replace_info->replace_len;
memcpy(sendbuf+tmp_len,(pos+replace_info->original_len),sendbuf_len-tmp_len);
send_ipv6_hdr = (struct kni_ipv6_hdr*)sendbuf;
send_ipv6_hdr->ip6_payload_len = ntohs(sendbuf_len)-sizeof(struct kni_ipv6_hdr);
// if(iphdr->ip_p == PROTO_TYPE_UDP)
{
send_udphdr = (struct kni_udp_hdr*)(sendbuf + sizeof(struct kni_ipv6_hdr));
send_udplen = ntohs(send_udphdr->uh_ulen);
send_udphdr->uh_ulen = htons(send_udplen - replace_info->original_len + replace_info->replace_len);
}
sendpacket_do_checksum((unsigned char*)sendbuf,IPPROTO_UDP,(sendbuf_len-sizeof(struct kni_ipv6_hdr)));
// sendpacket_do_checksum((unsigned char*)sendbuf,IPPROTO_IP,sizeof(struct ip));
MESA_sendpacket_iplayer(thread_seq,sendbuf,sendbuf_len,dir);
free(sendbuf);
sendbuf = NULL;
}
else
{
ret = APP_STATE_FAWPKT | APP_STATE_GIVEME;
}
return ret;
}
int replace_sendlog(const struct streaminfo* pstream,struct kni_pme_info* pmeinfo,char* orginal,char* replace)
{
struct kni_log log_msg;
char content[1024]={0};
if(strlen(orginal)+strlen(replace)+2>1024)
{
return 0;
}
sprintf(content,"%s->%s",orginal,replace);
log_msg.stream = pstream;
log_msg.result = pmeinfo->maat_result;
log_msg.result_num = pmeinfo->maat_result_num;
kni_send_log(&log_msg,(char*)"replace",content);
return 0;
}
char kni_process_replace(unsigned char dir,int thread_seq,const struct streaminfo* pstream,const void* a_packet,struct kni_pme_info* pmeinfo)
{
if(g_kni_switch_info.replace_switch == 0)
{
return APP_STATE_DROPME;
}
kni_filestate2_set(thread_seq,FS_REPLACE_UDP,0,1);
// char ret = APP_STATE_DROPPKT | APP_STATE_DROPME;
char ret = APP_STATE_DROPPKT | APP_STATE_GIVEME;
struct kni_replace_info replace_info;
memset(&replace_info,0,sizeof(struct kni_replace_info));
if(kni_get_replace(pmeinfo->cfg_id,pmeinfo->ser_def_len,pmeinfo->service_defined,&replace_info) < 0)
{
kni_log_debug(RLOG_LV_FATAL,(char*)"REPLACE",a_packet,(char*)"kni_get_replace error");
return APP_STATE_DROPME;
}
if(*(char*)a_packet == 0x45)
{
ret = kni_build_send_ipv4(dir,thread_seq,(struct ip*)a_packet,pmeinfo,&replace_info);
}
else
{
ret = kni_build_send_ipv6(dir,thread_seq,(struct kni_ipv6_hdr*)a_packet,pmeinfo,&replace_info);
}
if(ret & APP_STATE_DROPPKT)
{
kni_log_debug(RLOG_LV_FATAL,(char*)"REPLACE",a_packet,(char*)"config id:%d,original:%s,replace:%s",pmeinfo->cfg_id,replace_info.find,replace_info.replace);
replace_sendlog(pstream, pmeinfo, replace_info.find,replace_info.replace);
}
//20181030 modify for muti replace
Maat_clean_status(&(pmeinfo->mid));
pmeinfo->ipsscan_action = KNI_ACTION_NONE;
//end
return ret;
}

View File

@@ -1,21 +0,0 @@
#ifndef KNI_REPLACE_H
#define KNI_REPLACE_H
#include "kni_entry.h"
struct kni_replace_info
{
int original_len;
int replace_len;
char find[KNI_SERVICE_LEN];
char replace[KNI_SERVICE_LEN];
};
char kni_replace_scan();
char kni_process_replace(unsigned char dir,int thread_seq,const struct streaminfo* pstream,const void* a_packet,struct kni_pme_info* pmeinfo);
#endif

View File

@@ -1,216 +0,0 @@
#include <MESA/MESA_handle_logger.h>
#include <MESA/MESA_prof_load.h>
#include <assert.h>
#include <arpa/inet.h>
#include <time.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <pthread.h>
#include <errno.h>
#include "cJSON.h"
#include "kni_entry.h"
#include "kni_sendlog.h"
struct kni_logger* g_kni_sendlog;
static unsigned int get_ip_by_eth_name(const char *ifname)
{
int sockfd;
struct ifreq ifr;
unsigned int ip;
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (-1 == sockfd)
{
goto error;
}
strcpy(ifr.ifr_name,ifname);
if (ioctl(sockfd, SIOCGIFADDR, &ifr) < 0)
{
goto error;
}
ip = ((struct sockaddr_in*)&(ifr.ifr_addr))->sin_addr.s_addr;
close(sockfd);
return ip;
error:
close(sockfd);
return INADDR_NONE;
}
static rd_kafka_t * create_kafka_handle(const char* brokerlist)
{
char kafka_errstr[1024];
rd_kafka_t *handle=NULL;
rd_kafka_conf_t *rdkafka_conf = NULL;
rdkafka_conf = rd_kafka_conf_new();
rd_kafka_conf_set(rdkafka_conf, "queue.buffering.max.messages", "1000000", kafka_errstr, sizeof(kafka_errstr));
rd_kafka_conf_set(rdkafka_conf, "topic.metadata.refresh.interval.ms", "600000",kafka_errstr, sizeof(kafka_errstr));
rd_kafka_conf_set(rdkafka_conf, "security.protocol", "MG", kafka_errstr, sizeof(kafka_errstr));
//The conf object is freed by this function and must not be used or destroyed by the application sub-sequently.
handle = rd_kafka_new(RD_KAFKA_PRODUCER, rdkafka_conf, kafka_errstr, sizeof(kafka_errstr));
rdkafka_conf=NULL;
if (handle==NULL)
{
return NULL;
}
if (rd_kafka_brokers_add(handle, brokerlist) == 0)
{
rd_kafka_destroy(handle);
return NULL;
}
return handle;
}
void kni_sendlog_init()
{
int ret=-1;
char nic_name[64]={0};
g_kni_sendlog=ALLOC(struct kni_logger,1);
MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,KNI_MODULE_SENDLOG,"kni log is inititating from %s section %s.", KNI_CONF_FILENAME, KNI_SENDLOG_MODE);
MESA_load_profile_int_def(KNI_CONF_FILENAME, KNI_SENDLOG_MODE, "send_log_switch",&(g_kni_switch_info.send_log_switch),0);
if(g_kni_switch_info.send_log_switch == 0)
{
goto error_out;
}
MESA_load_profile_string_def(KNI_CONF_FILENAME, KNI_SENDLOG_MODE, "NIC_NAME",nic_name,sizeof(nic_name),"eth0");
g_kni_sendlog->local_ip_nr=get_ip_by_eth_name(nic_name);
if(g_kni_sendlog->local_ip_nr==INADDR_NONE)
{
MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,KNI_MODULE_SENDLOG,"%s get NIC_NAME: %s error.", __FUNCTION__, nic_name);
goto error_out;
}
inet_ntop(AF_INET,&(g_kni_sendlog->local_ip_nr),g_kni_sendlog->local_ip_str,sizeof(g_kni_sendlog->local_ip_str));
MESA_load_profile_int_def(KNI_CONF_FILENAME, KNI_SENDLOG_MODE, "ENTRANCE_ID",&(g_kni_sendlog->entry_id),0);
ret=MESA_load_profile_string_def(KNI_CONF_FILENAME, KNI_SENDLOG_MODE,"KAFKA_BROKERLIST", g_kni_sendlog->brokerlist, sizeof(g_kni_sendlog->brokerlist), NULL);
if(ret<0)
{
MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,KNI_MODULE_SENDLOG,"kni log init failed, no brokerlist in profile %s section %s.", KNI_CONF_FILENAME, KNI_SENDLOG_MODE);
goto error_out;
}
g_kni_sendlog->kafka_handle=create_kafka_handle(g_kni_sendlog->brokerlist);
if(g_kni_sendlog->kafka_handle==NULL)
{
MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,KNI_MODULE_SENDLOG,"kni log init failed. Cannot create lafka handle with brokerlist: %s.", g_kni_sendlog->brokerlist);
goto error_out;
}
g_kni_sendlog->topic_name="NTC-OPENVPN-LOG";
g_kni_sendlog->kafka_topic = rd_kafka_topic_new(g_kni_sendlog->kafka_handle,g_kni_sendlog->topic_name, NULL);
return;
error_out:
free(g_kni_sendlog);
return;
}
int kni_send_log(const struct kni_log* log_msg,char* user_region,char* content)
{
if(g_kni_switch_info.send_log_switch == 0)
{
return 0;
}
if(log_msg->stream == NULL)
{
MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,KNI_MODULE_SENDLOG,"log_msg->stream is NULL,not send log");
return -1;
}
const struct layer_addr* addr=&(log_msg->stream->addr);
// const char* tmp_val=NULL;
cJSON *common_obj=NULL, *per_hit_obj=NULL;
char* log_payload=NULL;
int kafka_status=0;
int send_cnt=0;
time_t cur_time;
char src_ip_str[MAX(INET6_ADDRSTRLEN,INET_ADDRSTRLEN)] = {0};
char dst_ip_str[MAX(INET6_ADDRSTRLEN,INET_ADDRSTRLEN)] = {0};
common_obj=cJSON_CreateObject();
cur_time = time(NULL);
cJSON_AddNumberToObject(common_obj, "found_time", cur_time);
cJSON_AddNumberToObject(common_obj, "recv_time", cur_time);
switch(addr->addrtype)
{
case ADDR_TYPE_IPV4:
cJSON_AddNumberToObject(common_obj, "addr_type", 4);
inet_ntop(AF_INET, &addr->tuple4_v4->saddr, src_ip_str, sizeof(src_ip_str));
inet_ntop(AF_INET, &addr->tuple4_v4->daddr, dst_ip_str, sizeof(dst_ip_str));
cJSON_AddStringToObject(common_obj, "s_ip", src_ip_str);
cJSON_AddStringToObject(common_obj, "d_ip", dst_ip_str);
cJSON_AddNumberToObject(common_obj, "s_port", ntohs(addr->tuple4_v4->source));
cJSON_AddNumberToObject(common_obj, "d_port", ntohs(addr->tuple4_v4->dest));
cJSON_AddStringToObject(common_obj, "trans_proto", "IPv4_TCP");
break;
case ADDR_TYPE_IPV6:
cJSON_AddNumberToObject(common_obj, "addr_type", 6);
inet_ntop(AF_INET6, &addr->tuple4_v6->saddr, src_ip_str, sizeof(src_ip_str));
inet_ntop(AF_INET6, &addr->tuple4_v6->daddr, dst_ip_str, sizeof(dst_ip_str));
cJSON_AddStringToObject(common_obj, "s_ip", src_ip_str);
cJSON_AddStringToObject(common_obj, "d_ip", dst_ip_str);
cJSON_AddNumberToObject(common_obj, "s_port", ntohs(addr->tuple4_v6->source));
cJSON_AddNumberToObject(common_obj, "d_port", ntohs(addr->tuple4_v6->dest));
cJSON_AddStringToObject(common_obj, "trans_proto", "IPv6_TCP");
break;
default:
break;
}
cJSON_AddNumberToObject(common_obj, "direction", 0);
cJSON_AddNumberToObject(common_obj, "stream_dir", 3); //1:c2s, 2:s2c, 3:double
cJSON_AddStringToObject(common_obj, "cap_ip", g_kni_sendlog->local_ip_str);
cJSON_AddNumberToObject(common_obj, "entrance_id", g_kni_sendlog->entry_id);
cJSON_AddNumberToObject(common_obj, "device_id", 0);
if(user_region !=NULL)
{
cJSON_AddStringToObject(common_obj, "user_region", user_region);
cJSON_AddStringToObject(common_obj, "version", content);
}
else
{
cJSON_AddStringToObject(common_obj, "user_region", "null");
}
for(size_t i=0; i<log_msg->result_num; i++)
{
if(log_msg->result[i].do_log==0)
{
continue;
}
per_hit_obj=cJSON_Duplicate(common_obj, 1);
cJSON_AddNumberToObject(per_hit_obj, "cfg_id", log_msg->result[i].config_id);
cJSON_AddNumberToObject(per_hit_obj, "service", log_msg->result[i].service_id);
log_payload = cJSON_Print(per_hit_obj);
fprintf(stderr, "%s\n", log_payload);
kafka_status = rd_kafka_produce(g_kni_sendlog->kafka_topic, RD_KAFKA_PARTITION_UA, RD_KAFKA_MSG_F_COPY,
log_payload, strlen(log_payload), NULL, 0, NULL);
free(log_payload);
cJSON_Delete(per_hit_obj);
if(kafka_status<0)
{
MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,KNI_MODULE_SENDLOG,"Kafka produce failed: %s", rd_kafka_err2name(rd_kafka_last_error()));
}
send_cnt++;
}
cJSON_Delete(common_obj);
return send_cnt;
}

View File

@@ -1,33 +0,0 @@
#include <MESA/Maat_rule.h>
#include <librdkafka/rdkafka.h>
#include "kni_entry.h"
struct kni_log
{
const struct streaminfo *stream;
const Maat_rule_t*result;
size_t result_num;
};
struct kni_logger
{
char local_ip_str[INET6_ADDRSTRLEN];
int entry_id;
unsigned int local_ip_nr;
rd_kafka_t *kafka_handle;
rd_kafka_topic_t* kafka_topic;
char brokerlist[KNI_CONF_MAXLEN];
const char* topic_name;
unsigned long long send_cnt;
char local_log_path[KNI_CONF_MAXLEN];
};
void kni_sendlog_init();
//return 0 if SUCCESS, otherwise return -1
int kni_send_log(const struct kni_log* log_msg,char* user_region,char* content);

View File

@@ -1,10 +0,0 @@
#define ALLOC(type, number) ((type *)calloc(sizeof(type), number))
#define FREE(p) {free(*p);*p=NULL;}
#ifndef MAX
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
#endif
#ifndef MIN
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
#endif

49
vendor/CMakeLists.txt vendored Normal file
View File

@@ -0,0 +1,49 @@
# CMakeFiles for 3rd vendor library
include(ExternalProject)
### IPLocator
ExternalProject_Add(IPLocator
PREFIX IPLocator
URL ${CMAKE_CURRENT_SOURCE_DIR}/IPLocator-master.tar.gz
URL_MD5 685979caaa2b309221a21d5aab5e9cd5
CONFIGURE_COMMAND ./configure --prefix=<INSTALL_DIR> --disable-shared
BUILD_IN_SOURCE 1)
ExternalProject_Get_Property(IPLocator INSTALL_DIR)
file(MAKE_DIRECTORY ${INSTALL_DIR}/include)
add_library(IPLocator-static STATIC IMPORTED GLOBAL)
set_property(TARGET IPLocator-static PROPERTY IMPORTED_LOCATION ${INSTALL_DIR}/lib/libmaxminddb.a)
set_property(TARGET IPLocator-static PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${INSTALL_DIR}/include)
### MESA Framework
set(MESA_FRAMEWORK_LIB_DIR /opt/MESA/lib)
set(MESA_FRAMEWORK_INCLUDE_DIR /opt/MESA/include)
add_library(MESA_handle_logger SHARED IMPORTED GLOBAL)
set_property(TARGET MESA_handle_logger PROPERTY IMPORTED_LOCATION ${MESA_FRAMEWORK_LIB_DIR}/libMESA_handle_logger.so)
set_property(TARGET MESA_handle_logger PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${MESA_FRAMEWORK_INCLUDE_DIR})
add_library(MESA_prof_load SHARED IMPORTED GLOBAL)
set_property(TARGET MESA_prof_load PROPERTY IMPORTED_LOCATION ${MESA_FRAMEWORK_LIB_DIR}/libMESA_prof_load.so)
set_property(TARGET MESA_prof_load PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${MESA_FRAMEWORK_INCLUDE_DIR})
add_library(wiredcfg SHARED IMPORTED GLOBAL)
set_property(TARGET wiredcfg PROPERTY IMPORTED_LOCATION ${MESA_FRAMEWORK_LIB_DIR}/libwiredcfg.so)
set_property(TARGET wiredcfg PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${MESA_FRAMEWORK_INCLUDE_DIR})
add_library(MESA_htable SHARED IMPORTED GLOBAL)
set_property(TARGET MESA_htable PROPERTY IMPORTED_LOCATION ${MESA_FRAMEWORK_LIB_DIR}/libMESA_htable.so)
set_property(TARGET MESA_htable PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${MESA_FRAMEWORK_INCLUDE_DIR})
add_library(maatframe SHARED IMPORTED GLOBAL)
set_property(TARGET maatframe PROPERTY IMPORTED_LOCATION ${MESA_FRAMEWORK_LIB_DIR}/libmaatframe.so)
set_property(TARGET maatframe PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${MESA_FRAMEWORK_INCLUDE_DIR})
add_library(MESA_field_stat SHARED IMPORTED GLOBAL)
set_property(TARGET MESA_field_stat PROPERTY IMPORTED_LOCATION ${MESA_FRAMEWORK_LIB_DIR}/libMESA_field_stat2.so)
set_property(TARGET MESA_field_stat PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${MESA_FRAMEWORK_INCLUDE_DIR})

BIN
vendor/cJSON-1.7.7.tar.gz vendored Normal file

Binary file not shown.