调整目录结构
This commit is contained in:
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
.vscode/*
|
||||
34
Makefile
34
Makefile
@@ -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
596
cJSON.c
@@ -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
143
cJSON.h
@@ -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
|
||||
47
common/include/kni_utils.h
Normal file
47
common/include/kni_utils.h
Normal 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);
|
||||
33
common/include/ssl_utils.h
Normal file
33
common/include/ssl_utils.h
Normal 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
0
common/src/kni_utils.cpp
Normal file
476
common/src/ssl_utils.cpp
Normal file
476
common/src/ssl_utils.cpp
Normal 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
68
entry/main.cpp
Normal 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;
|
||||
|
||||
}
|
||||
714
kni_comm.c
714
kni_comm.c
@@ -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;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
104
kni_comm.h
104
kni_comm.h
@@ -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
|
||||
|
||||
1901
kni_entry.c
1901
kni_entry.c
File diff suppressed because it is too large
Load Diff
517
kni_entry.h
517
kni_entry.h
@@ -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
|
||||
|
||||
1499
kni_intercept.c
1499
kni_intercept.c
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||
|
||||
122
kni_ratelimit.c
122
kni_ratelimit.c
@@ -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;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
682
kni_redirect.c
682
kni_redirect.c
@@ -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;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
272
kni_replace.c
272
kni_replace.c
@@ -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;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
216
kni_sendlog.c
216
kni_sendlog.c
@@ -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;
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
|
||||
10
kni_utils.h
10
kni_utils.h
@@ -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
49
vendor/CMakeLists.txt
vendored
Normal 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
BIN
vendor/cJSON-1.7.7.tar.gz
vendored
Normal file
Binary file not shown.
Reference in New Issue
Block a user