add socks_decoder, stratum_decoder and session_flags

This commit is contained in:
root
2024-09-03 07:01:58 +00:00
parent a8206cffc0
commit 6f1ac6b36b
160 changed files with 11861 additions and 1 deletions

View File

@@ -1,2 +1,5 @@
add_subdirectory(http)
add_subdirectory(lpi)
add_subdirectory(socks)
add_subdirectory(stratum)
add_subdirectory(session_flags)

View File

@@ -0,0 +1,15 @@
add_subdirectory(mesa_sts)
add_definitions(-fPIC)
set(SESSION_FLAGS_SRC session_flags_plugin.cpp session_flags.cpp fet.cpp tunneling.cpp onlinemean.c)
add_library(session_flags STATIC ${SESSION_FLAGS_SRC})
add_library(session_flags_dyn SHARED ${SESSION_FLAGS_SRC})
set_target_properties(session_flags PROPERTIES LINK_FLAGS "-Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/version.map")
target_include_directories(session_flags PUBLIC ${CMAKE_SOURCE_DIR}/deps/)
include_directories(${CMAKE_BINARY_DIR}/vendors/cjson/src/cjson/include)
target_link_libraries(session_flags toml cjson-static hyperscan_static hyperscan_runtime_static libmesa_sts)
set_target_properties(session_flags PROPERTIES PREFIX "")
set_target_properties(session_flags_dyn PROPERTIES PREFIX "")
target_link_libraries(session_flags_dyn toml cjson-static hyperscan_static hyperscan_runtime_static libmesa_sts)

View File

@@ -0,0 +1,123 @@
/*ref: https://github.com/apernet/OpenGFW/blob/1dce82745d0bc8b3813aea147954ba3a2294ef30/analyzer/tcp/fet.go
https://www.usenix.org/system/files/usenixsecurity23-wu-mingshi.pdf
*/
#include <string.h>
#include <stdlib.h>
#include "fet.h"
bool isPrintable(unsigned char b) {
return b >= 0x20 && b <= 0x7e;
}
int popCount(unsigned char b) {
int count = 0;
while (b != 0) {
count += (int)(b & 1);
b >>= 1;
}
return count;
}
float averagePopCount(const unsigned char* bytes, int bytes_len) {
if (bytes_len == 0) {
return 0;
}
int total = 0;
for (int i = 0; i < bytes_len; i++) {
total += popCount(bytes[i]);
}
return (float)total / (float)bytes_len;
}
bool isFirstSixPrintable(const unsigned char* bytes, int bytes_len) {
if (bytes_len < 6) {
return false;
}
for (int i = 0; i < 6; i++) {
if (!isPrintable(bytes[i])) {
return false;
}
}
return true;
}
float printablePercentage(const unsigned char* bytes, int bytes_len) {
if (bytes_len == 0) {
return 0;
}
int count = 0;
for (int i = 0; i < bytes_len; i++) {
if (isPrintable(bytes[i])) {
count++;
}
}
return (float)count / (float)bytes_len;
}
int contiguousPrintable(const unsigned char* bytes, int bytes_len) {
if (bytes_len == 0) {
return 0;
}
int maxCount = 0;
int current = 0;
for (int i = 0; i < bytes_len; i++) {
if (isPrintable(bytes[i])) {
current++;
} else {
if (current > maxCount) {
maxCount = current;
}
current = 0;
}
}
if (current > maxCount) {
maxCount = current;
}
return maxCount;
}
bool isTLS(const unsigned char* bytes, int bytes_len) {
if (bytes_len < 3) {
return false;
}
// "We observe that the GFW exempts any connection whose first
// three bytes match the following regular expression:
// [\x16-\x17]\x03[\x00-\x09]" - from the paper in Section 4.3
if (bytes[0] >= 0x16 && bytes[0] <= 0x17 &&
bytes[1] == 0x03 && bytes[2] <= 0x09) {
return true;
}
return false;
}
bool isHTTP(const unsigned char* bytes, int bytes_len) {
if (bytes_len < 3) {
return false;
}
// HTTP request
bool result = memcmp(bytes, "GET", 3) == 0 || memcmp(bytes, "HEA", 3) == 0 || memcmp(bytes, "POS", 3) == 0 ||
memcmp(bytes, "PUT", 3) == 0 || memcmp(bytes, "DEL", 3) == 0 || memcmp(bytes, "CON", 3) == 0 ||
memcmp(bytes, "OPT", 3) == 0 || memcmp(bytes, "TRA", 3) == 0 || memcmp(bytes, "PAT", 3) == 0;
return result;
}
int is_data_fet(unsigned char* data, int data_len, struct fet_detail* detail) {
if (data_len == 0) {
return 0;
}
float ex1 = averagePopCount(data, data_len);
bool ex2 = isFirstSixPrintable(data, data_len);
float ex3 = printablePercentage(data, data_len);
int ex4 = contiguousPrintable(data, data_len);
bool ex5 = isTLS(data, data_len);
bool ex6 = isHTTP(data, data_len);
bool exempt = (ex1 <= 3.4 || ex1 >= 4.6) || ex2 || ex3 > 0.5 || ex4 > 20 || ex5 || ex6;
detail->is_tls = ex5;
return !exempt;
}

View File

@@ -0,0 +1,7 @@
#pragma once
struct fet_detail {
bool is_tls;
};
int is_data_fet(unsigned char* data, int data_len, struct fet_detail* detail);

View File

@@ -0,0 +1,15 @@
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/src/)
file(GLOB STS_SRC
"src/*.c"
)
#add_compile_options(-Wno-error=unused-parameter -Wno-unused-but-set-variable -Wno-error=misleading-indentation -Wno-unused-variable -Wno-maybe-uninitialized -Wno-error=unused-function)
add_library(libmesa_sts ${STS_SRC})
target_include_directories(libmesa_sts PUBLIC ${CMAKE_SOURCE_DIR}/decoders/session_flags/mesa_sts/include)
target_compile_options(libmesa_sts PRIVATE -Wno-error=unused-parameter -Wno-unused-but-set-variable -Wno-error=misleading-indentation -Wno-unused-variable -Wno-maybe-uninitialized -Wno-error=unused-function)
set_target_properties(libmesa_sts PROPERTIES LINK_FLAGS
"-Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/version.map")
add_subdirectory(test)

View File

@@ -0,0 +1,57 @@
#ifndef _MESA_STS_H_
#define _MESA_STS_H_
#define STS_RANDOM_JUDGE_NUM 15
#define STS_SET_FLAG(flag, idx) (flag |= (1 << idx))
#define STS_TEST_FLAG(flag, idx) (flag & (1 << idx))
enum sts_random_judge_list_idx
{
STS_FREQUENCY = 0,
STS_BLOCK_FREQUENCY,
STS_CUMULATIVE_SUMS,
STS_RUNS,
STS_LONGEST_RUN,
STS_RANK,
STS_NON_OVERLAPPING_TEMPLATE_MATCHING,
STS_OVERLAPPING_TEMPLATE_MATCHING,
STS_UNIVERSAL,
STS_RANDOM_EXCURSIONS,
STS_RANDOM_EXCURSIONS_VARIANT,
STS_POKER_DETECT,
STS_RUNS_DISTRIBUTION,
STS_SELF_CORRELATION,
STS_BINARY_DERIVATE,
STS_RANDOM_IDX_MAX
};
struct sts_result {
unsigned char frequency;
unsigned char block_frequency;
unsigned char cumulative_sums;
unsigned char runs;
unsigned char longest_run;
unsigned char rank;
unsigned char non_overlapping_template_matching;
unsigned char overlapping_template_matching;
unsigned char universal;
unsigned char random_excursions;
unsigned char random_excursions_variant;
unsigned char poker_detect;
unsigned char runs_distribution;
unsigned char self_correlation;
unsigned char binary_derivative;
};
#ifdef __cplusplus
extern "C" {
#endif
int mesa_statistical_test_suite(void* data,unsigned int datalen, struct sts_result* result, unsigned int random_judge_switch_flag);
#ifdef __cplusplus
}
#endif
#endif /* _MESA_STS_H_ */

View File

@@ -0,0 +1,72 @@
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include "include/externs.h"
#include "include/cephes.h"
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
A P P R O X I M A T E E N T R O P Y T E S T
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
int
ApproximateEntropy(int m, int n, BitSequence *epsilon)
{
int i, j, k, r, blockSize, seqLength, powLen, index;
double sum, numOfBlocks, ApEn[2], apen, chi_squared, p_value;
unsigned int *P;
seqLength = n;
r = 0;
for ( blockSize=m; blockSize<=m+1; blockSize++ ) {
if ( blockSize == 0 ) {
ApEn[0] = 0.00;
r++;
}
else {
numOfBlocks = (double)seqLength;
powLen = (int)pow(2, blockSize+1)-1;
if ( (P = (unsigned int*)calloc(powLen,sizeof(unsigned int)))== NULL ) {
return 0;
}
for ( i=1; i<powLen-1; i++ )
P[i] = 0;
for ( i=0; i<numOfBlocks; i++ ) { /* COMPUTE FREQUENCY */
k = 1;
for ( j=0; j<blockSize; j++ ) {
k <<= 1;
if ( (int)epsilon[(i+j) % seqLength] == 1 )
k++;
}
P[k-1]++;
}
/* DISPLAY FREQUENCY */
sum = 0.0;
index = (int)pow(2, blockSize)-1;
for ( i=0; i<(int)pow(2, blockSize); i++ ) {
if ( P[index] > 0 )
sum += P[index]*log(P[index]/numOfBlocks);
index++;
}
sum /= numOfBlocks;
ApEn[r] = sum;
r++;
free(P);
}
}
apen = ApEn[0] - ApEn[1];
chi_squared = 2.0*seqLength*(log(2) - apen);
p_value = cephes_igamc(pow(2, m-1), chi_squared/2.0);
if ( m > (int)(log(seqLength)/log(2)-5) ) {
return 0;
}
if (p_value < ALPHA) {
return 0;
} else {
return 1;
}
}

View File

@@ -0,0 +1,30 @@
#include <math.h>
#include "include/stat_fncs.h"
int BinaryDerivate(int k, int n, BitSequence *epsilon, int epsilon_l)
{
int i = 0, j = 0;
int Sn_k = 0;
int n_k = n - k;
double V = 0.0, p_value = 0.0, sqrt2 = 1.41421356237309504880;
for (i = 0; i < k; ++i) {
for (j = 0; j < epsilon_l - 1; ++j) {
epsilon[j] = epsilon[j] ^ epsilon[j + 1];
}
}
for (i = 0; i < n_k; ++i) {
Sn_k += (2 * (int)epsilon[i]) - 1;
}
V = fabs(Sn_k) / sqrt(n_k);
p_value = erfc(fabs(V) / sqrt2);
if (p_value < ALPHA) {
return 0;
} else {
return 1;
}
}

View File

@@ -0,0 +1,36 @@
#include <stdio.h>
#include <math.h>
#include <string.h>
#include "include/externs.h"
#include "include/cephes.h"
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
B L O C K F R E Q U E N C Y T E S T
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
int
BlockFrequency(int M, int n, BitSequence *epsilon)
{
int i, j, N, blockSum;
double p_value, sum, pi, v, chi_squared;
N = n/M; /* # OF SUBSTRING BLOCKS */
sum = 0.0;
for ( i=0; i<N; i++ ) {
blockSum = 0;
for ( j=0; j<M; j++ )
blockSum += epsilon[j+i*M];
pi = (double)blockSum/(double)M;
v = pi - 0.5;
sum += v*v;
}
chi_squared = 4.0 * M * sum;
p_value = cephes_igamc(N/2.0, chi_squared/2.0);
if (p_value < ALPHA) {
return 0;
} else {
return 1;
}
}

View File

@@ -0,0 +1,31 @@
#include "include/stat_fncs.h"
static unsigned char _compute(unsigned char b, unsigned char factor)
{
if ((factor & b) == factor) {
return 0x01;
} else {
return 0x00;
}
}
int BytesToBitSequence(unsigned char *in, int inl, BitSequence *outbuf, int bufsize)
{
int j = 0, i = 0;
if (bufsize < inl * 8) {
return 0;
}
for (i = 0; i < inl; ++i) {
j = i * 8;
outbuf[j] = (BitSequence) (_compute(in[i], 0x80));
outbuf[j + 1] = (BitSequence) (_compute(in[i], 0x40));
outbuf[j + 2] = (BitSequence) (_compute(in[i], 0x20));
outbuf[j + 3] = (BitSequence) (_compute(in[i], 0x10));
outbuf[j + 4] = (BitSequence) (_compute(in[i], 0x08));
outbuf[j + 5] = (BitSequence) (_compute(in[i], 0x04));
outbuf[j + 6] = (BitSequence) (_compute(in[i], 0x02));
outbuf[j + 7] = (BitSequence) (_compute(in[i], 0x01));
}
return 1;
}

View File

@@ -0,0 +1,348 @@
#include <stdio.h>
#include <math.h>
#include "include/cephes.h"
static const double rel_error = 1E-12;
double MACHEP = 1.11022302462515654042E-16; // 2**-53
double MAXLOG = 7.09782712893383996732224E2; // log(MAXNUM)
double MAXNUM = 1.7976931348623158E308; // 2**1024*(1-MACHEP)
double PI = 3.14159265358979323846; // pi, duh!
static double big = 4.503599627370496e15;
static double biginv = 2.22044604925031308085e-16;
int sgngam = 0;
double
cephes_igamc(double a, double x)
{
double ans, ax, c, yc, r, t, y, z;
double pk, pkm1, pkm2, qk, qkm1, qkm2;
if ( (x <= 0) || ( a <= 0) )
return( 1.0 );
if ( (x < 1.0) || (x < a) )
return( 1.e0 - cephes_igam(a,x) );
ax = a * log(x) - x - cephes_lgam(a);
if ( ax < -MAXLOG ) {
printf("igamc: UNDERFLOW\n");
return 0.0;
}
ax = exp(ax);
/* continued fraction */
y = 1.0 - a;
z = x + y + 1.0;
c = 0.0;
pkm2 = 1.0;
qkm2 = x;
pkm1 = x + 1.0;
qkm1 = z * x;
ans = pkm1/qkm1;
do {
c += 1.0;
y += 1.0;
z += 2.0;
yc = y * c;
pk = pkm1 * z - pkm2 * yc;
qk = qkm1 * z - qkm2 * yc;
if ( qk != 0 ) {
r = pk/qk;
t = fabs( (ans - r)/r );
ans = r;
}
else
t = 1.0;
pkm2 = pkm1;
pkm1 = pk;
qkm2 = qkm1;
qkm1 = qk;
if ( fabs(pk) > big ) {
pkm2 *= biginv;
pkm1 *= biginv;
qkm2 *= biginv;
qkm1 *= biginv;
}
} while ( t > MACHEP );
return ans*ax;
}
double
cephes_igam(double a, double x)
{
double ans, ax, c, r;
if ( (x <= 0) || ( a <= 0) )
return 0.0;
if ( (x > 1.0) && (x > a ) )
return 1.e0 - cephes_igamc(a,x);
/* Compute x**a * exp(-x) / gamma(a) */
ax = a * log(x) - x - cephes_lgam(a);
if ( ax < -MAXLOG ) {
printf("igam: UNDERFLOW\n");
return 0.0;
}
ax = exp(ax);
/* power series */
r = a;
c = 1.0;
ans = 1.0;
do {
r += 1.0;
c *= x/r;
ans += c;
} while ( c/ans > MACHEP );
return ans * ax/a;
}
union A_Array {
double d[5];
unsigned short us[20];
};
union BC_Array {
double d[6];
unsigned short us[24];
};
/* A[]: Stirling's formula expansion of log gamma
* B[], C[]: log gamma function between 2 and 3
*/
/**/
static union A_Array A = {
.us = {
0x6661,0x2733,0x9850,0x3f4a,
0xe943,0xb580,0x7fbd,0xbf43,
0x5ebb,0x20dc,0x019f,0x3f4a,
0xa5a1,0x16b0,0xc16c,0xbf66,
0x554b,0x5555,0x5555,0x3fb5
}
};
static union BC_Array B = {
.us = {
0x6761,0x8ff3,0x8901,0xc095,
0xb93e,0x355b,0xf234,0xc0e2,
0x89e5,0xf890,0x3d73,0xc114,
0xdb51,0xf994,0xbc82,0xc131,
0xf20b,0x0219,0x4589,0xc13a,
0x055e,0x5418,0x0c67,0xc12a
}
};
static union BC_Array C = {
/*0x0000,0x0000,0x0000,0x3ff0,*/
.us = {
0x12b2,0x1cf3,0xfd0d,0xc075,
0xd757,0x7b89,0xaa0d,0xc0d0,
0x4c9b,0xb974,0xeb84,0xc10a,
0x0043,0x7195,0x6286,0xc131,
0xf34c,0x892f,0x5255,0xc143,
0xe14a,0x6a11,0xce4b,0xc13e
}
};
#define MAXLGM 2.556348e305
/* Logarithm of gamma function */
double
cephes_lgam(double x)
{
double p, q, u, w, z;
int i;
sgngam = 1;
if ( x < -34.0 ) {
q = -x;
w = cephes_lgam(q); /* note this modifies sgngam! */
p = floor(q);
if ( p == q ) {
lgsing:
goto loverf;
}
i = (int)p;
if ( (i & 1) == 0 )
sgngam = -1;
else
sgngam = 1;
z = q - p;
if ( z > 0.5 ) {
p += 1.0;
z = p - q;
}
z = q * sin( PI * z );
if ( z == 0.0 )
goto lgsing;
/* z = log(PI) - log( z ) - w;*/
z = log(PI) - log( z ) - w;
return z;
}
if ( x < 13.0 ) {
z = 1.0;
p = 0.0;
u = x;
while ( u >= 3.0 ) {
p -= 1.0;
u = x + p;
z *= u;
}
while ( u < 2.0 ) {
if ( u == 0.0 )
goto lgsing;
z /= u;
p += 1.0;
u = x + p;
}
if ( z < 0.0 ) {
sgngam = -1;
z = -z;
}
else
sgngam = 1;
if ( u == 2.0 )
return( log(z) );
p -= 2.0;
x = x + p;
p = x * cephes_polevl( x, (double *)B.d, 5 ) / cephes_p1evl( x, (double *)C.d, 6);
return log(z) + p;
}
if ( x > MAXLGM ) {
loverf:
printf("lgam: OVERFLOW\n");
return sgngam * MAXNUM;
}
q = ( x - 0.5 ) * log(x) - x + log( sqrt( 2*PI ) );
if ( x > 1.0e8 )
return q;
p = 1.0/(x*x);
if ( x >= 1000.0 )
q += (( 7.9365079365079365079365e-4 * p
- 2.7777777777777777777778e-3) *p
+ 0.0833333333333333333333) / x;
else
q += cephes_polevl( p, (double *)A.d, 4 ) / x;
return q;
}
double
cephes_polevl(double x, double *coef, int N)
{
double ans;
int i;
double *p;
p = coef;
ans = *p++;
i = N;
do
ans = ans * x + *p++;
while ( --i );
return ans;
}
double
cephes_p1evl(double x, double *coef, int N)
{
double ans;
double *p;
int i;
p = coef;
ans = x + *p++;
i = N-1;
do
ans = ans * x + *p++;
while ( --i );
return ans;
}
double
cephes_erf(double x)
{
static const double two_sqrtpi = 1.128379167095512574;
double sum = x, term = x, xsqr = x * x;
int j = 1;
if ( fabs(x) > 2.2 )
return 1.0 - cephes_erfc(x);
do {
term *= xsqr/j;
sum -= term/(2*j+1);
j++;
term *= xsqr/j;
sum += term/(2*j+1);
j++;
} while ( fabs(term)/sum > rel_error );
return two_sqrtpi*sum;
}
double
cephes_erfc(double x)
{
static const double one_sqrtpi = 0.564189583547756287;
double a = 1, b = x, c = x, d = x*x + 0.5;
double q1, q2 = b/d, n = 1.0, t;
if ( fabs(x) < 2.2 )
return 1.0 - cephes_erf(x);
if ( x < 0 )
return 2.0 - cephes_erfc(-x);
do {
t = a*n + b*x;
a = b;
b = t;
t = c*n + d*x;
c = d;
d = t;
n += 0.5;
q1 = q2;
q2 = b/d;
} while ( fabs(q1-q2)/q2 > rel_error );
return one_sqrtpi*exp(-x*x)*q2;
}
double
cephes_normal(double x)
{
double arg, result, sqrt2=1.414213562373095048801688724209698078569672;
if (x > 0) {
arg = x/sqrt2;
result = 0.5 * ( 1 + erf(arg) );
}
else {
arg = -x/sqrt2;
result = 0.5 * (erfc(arg) );
}
return( result);
}

View File

@@ -0,0 +1,95 @@
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include "include/externs.h"
#include "include/cephes.h"
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
C U M U L A T I V E S U M S T E S T
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
int
CumulativeSums(int n, BitSequence *epsilon)
{
int S, sup, inf, z=1, zrev, k;
double sum1, sum2, p_value;
S = 0;
sup = 0;
inf = 0;
for ( k=0; k<n; k++ ) {
epsilon[k] ? S++ : S--;
if ( S > sup )
sup++;
if ( S < inf )
inf--;
z = (sup > -inf) ? sup : -inf;
zrev = (sup-S > S-inf) ? sup-S : S-inf;
}
// forward
sum1 = 0.0;
for ( k=(-n/z+1)/4; k<=(n/z-1)/4; k++ ) {
sum1 += cephes_normal(((4*k+1)*z)/sqrt(n));
sum1 -= cephes_normal(((4*k-1)*z)/sqrt(n));
}
sum2 = 0.0;
for ( k=(-n/z-3)/4; k<=(n/z-1)/4; k++ ) {
sum2 += cephes_normal(((4*k+3)*z)/sqrt(n));
sum2 -= cephes_normal(((4*k+1)*z)/sqrt(n));
}
p_value = 1.0 - sum1 + sum2;
// fprintf(stats[TEST_CUSUM], "\t\t CUMULATIVE SUMS (FORWARD) TEST\n");
// fprintf(stats[TEST_CUSUM], "\t\t-------------------------------------------\n");
// fprintf(stats[TEST_CUSUM], "\t\tCOMPUTATIONAL INFORMATION:\n");
// fprintf(stats[TEST_CUSUM], "\t\t-------------------------------------------\n");
// fprintf(stats[TEST_CUSUM], "\t\t(a) The maximum partial sum = %d\n", z);
// fprintf(stats[TEST_CUSUM], "\t\t-------------------------------------------\n");
if ( isNegative(p_value) || isGreaterThanOne(p_value) ) {
// fprintf(stats[TEST_CUSUM], "\t\tWARNING: P_VALUE IS OUT OF RANGE\n");
return 0;
}
// fprintf(stats[TEST_CUSUM], "%s\t\tp_value = %f\n\n", p_value < ALPHA ? "FAILURE" : "SUCCESS", p_value);
// fprintf(results[TEST_CUSUM], "%f\n", p_value);
if (p_value < ALPHA) {
return 0;
}
// backwards
sum1 = 0.0;
for ( k=(-n/zrev+1)/4; k<=(n/zrev-1)/4; k++ ) {
sum1 += cephes_normal(((4*k+1)*zrev)/sqrt(n));
sum1 -= cephes_normal(((4*k-1)*zrev)/sqrt(n));
}
sum2 = 0.0;
for ( k=(-n/zrev-3)/4; k<=(n/zrev-1)/4; k++ ) {
sum2 += cephes_normal(((4*k+3)*zrev)/sqrt(n));
sum2 -= cephes_normal(((4*k+1)*zrev)/sqrt(n));
}
p_value = 1.0 - sum1 + sum2;
// fprintf(stats[TEST_CUSUM], "\t\t CUMULATIVE SUMS (REVERSE) TEST\n");
// fprintf(stats[TEST_CUSUM], "\t\t-------------------------------------------\n");
// fprintf(stats[TEST_CUSUM], "\t\tCOMPUTATIONAL INFORMATION:\n");
// fprintf(stats[TEST_CUSUM], "\t\t-------------------------------------------\n");
// fprintf(stats[TEST_CUSUM], "\t\t(a) The maximum partial sum = %d\n", zrev);
// fprintf(stats[TEST_CUSUM], "\t\t-------------------------------------------\n");
if ( isNegative(p_value) || isGreaterThanOne(p_value) ) {
// fprintf(stats[TEST_CUSUM], "\t\tWARNING: P_VALUE IS OUT OF RANGE\n");
return 0;
}
// fprintf(stats[TEST_CUSUM], "%s\t\tp_value = %f\n\n", p_value < ALPHA ? "FAILURE" : "SUCCESS", p_value); fflush(stats[TEST_CUSUM]);
// fprintf(results[TEST_CUSUM], "%f\n", p_value); fflush(results[TEST_CUSUM]);
if (p_value < ALPHA) {
return 0;
} else {
return 1;
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,60 @@
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include "include/externs.h"
#include "include/cephes.h"
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
D I S C R E T E F O U R I E R T R A N S F O R M T E S T
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void __ogg_fdrffti(int n, double *wsave, int *ifac);
void __ogg_fdrfftf(int n, double *X, double *wsave, int *ifac);
int
DiscreteFourierTransform(int n, BitSequence *epsilon)
{
double p_value, upperBound, percentile, N_l, N_o, d, *m, *X, *wsave;
int i, count, ifac[15];
if ( ((X = (double*) calloc(n,sizeof(double))) == NULL) ||
((wsave = (double *)calloc(2*n,sizeof(double))) == NULL) ||
((m = (double*)calloc(n/2+1, sizeof(double))) == NULL) ) {
if( X != NULL )
free(X);
if( wsave != NULL )
free(wsave);
if( m != NULL )
free(m);
return 0;
}
for ( i=0; i<n; i++ )
X[i] = 2*(int)epsilon[i] - 1;
__ogg_fdrffti(n, wsave, ifac); /* INITIALIZE WORK ARRAYS */
__ogg_fdrfftf(n, X, wsave, ifac); /* APPLY FORWARD FFT */
m[0] = sqrt(X[0]*X[0]); /* COMPUTE MAGNITUDE */
for ( i=0; i<n/2; i++ )
m[i+1] = sqrt(pow(X[2*i+1],2)+pow(X[2*i+2],2));
count = 0; /* CONFIDENCE INTERVAL */
upperBound = sqrt(2.995732274*n);
for ( i=0; i<n/2; i++ )
if ( m[i] < upperBound )
count++;
percentile = (double)count/(n/2)*100;
N_l = (double) count; /* number of peaks less than h = sqrt(3*n) */
N_o = (double) 0.95*n/2.0;
d = (N_l - N_o)/sqrt(n/4.0*0.95*0.05);
p_value = erfc(fabs(d)/sqrt(2.0));
free(X);
free(wsave);
free(m);
if (p_value < ALPHA) {
return 0;
} else {
return 1;
}
}

View File

@@ -0,0 +1,38 @@
#include <stdio.h>
#include <math.h>
#include <string.h>
#include "include/externs.h"
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
F R E Q U E N C Y T E S T
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
int
Frequency(int n, BitSequence *epsilon)
{
int i;
double f, s_obs, p_value, sum, sqrt2 = 1.41421356237309504880;
sum = 0.0;
for ( i=0; i<n; i++ )
sum += 2*(int)epsilon[i]-1;
s_obs = fabs(sum)/sqrt(n);
f = s_obs/sqrt2;
p_value = erfc(f);
// fprintf(stats[TEST_FREQUENCY], "\t\t\t FREQUENCY TEST\n");
// fprintf(stats[TEST_FREQUENCY], "\t\t---------------------------------------------\n");
// fprintf(stats[TEST_FREQUENCY], "\t\tCOMPUTATIONAL INFORMATION:\n");
// fprintf(stats[TEST_FREQUENCY], "\t\t---------------------------------------------\n");
// fprintf(stats[TEST_FREQUENCY], "\t\t(a) The nth partial sum = %d\n", (int)sum);
// fprintf(stats[TEST_FREQUENCY], "\t\t(b) S_n/n = %f\n", sum/n);
// fprintf(stats[TEST_FREQUENCY], "\t\t---------------------------------------------\n");
// fprintf(stats[TEST_FREQUENCY], "%s\t\tp_value = %f\n\n", p_value < ALPHA ? "FAILURE" : "SUCCESS", p_value); fflush(stats[TEST_FREQUENCY]);
// fprintf(results[TEST_FREQUENCY], "%f\n", p_value); fflush(results[TEST_FREQUENCY]);
if (p_value < ALPHA) {
return 0;
} else {
return 1;
}
}

View File

@@ -0,0 +1,667 @@
/*
* file: mp.c
*
* DESCRIPTION
*
* These functions comprise a multi-precision integer arithmetic
* and discrete function package.
*/
#include "include/genutils.h"
#define MAXPLEN 384
/*****************************************
** greater - Test if x > y *
** *
** Returns TRUE (1) if x greater than y, *
** otherwise FALSE (0). *
** *
** Parameters: *
** *
** x Address of array x *
** y Address of array y *
** l Length both x and y in bytes *
** *
******************************************/
int greater(BYTE *x, BYTE *y, int l)
{
int i;
for ( i=0; i<l; i++ )
if ( x[i] != y[i] )
break;
if ( i == l )
return 0;
if ( x[i] > y[i] )
return 1;
return 0;
}
/*****************************************
** less - Test if x < y *
** *
** Returns TRUE (1) if x less than y, *
** otherwise FALSE (0). *
** *
** Parameters: *
** *
** x Address of array x *
** y Address of array y *
** l Length both x and y in bytes *
** *
******************************************/
int less(BYTE *x, BYTE *y, int l)
{
int i;
for ( i=0; i<l; i++ )
if ( x[i] != y[i] )
break;
if ( i == l ) {
return 0;
}
if ( x[i] < y[i] ) {
return 1;
}
return 0;
}
/*****************************************
** bshl - shifts array left *
** by one bit. *
** *
** x = x * 2 *
** *
** Parameters: *
** *
** x Address of array x *
** l Length array x in bytes *
** *
******************************************/
BYTE bshl(BYTE *x, int l)
{
BYTE *p;
int c1, c2;
p = x + l - 1;
c1 = 0;
c2 = 0;
while ( p != x ) {
if ( *p & 0x80 )
c2 = 1;
*p <<= 1; /* shift the word left once (ls bit = 0) */
if ( c1 )
*p |= 1;
c1 = c2;
c2 = 0;
p--;
}
if ( *p & 0x80 )
c2 = 1;
*p <<= 1; /* shift the word left once (ls bit = 0) */
if ( c1 )
*p |= (DIGIT)1;
return (BYTE)c2;
}
/*****************************************
** bshr - shifts array right *
** by one bit. *
** *
** x = x / 2 *
** *
** Parameters: *
** *
** x Address of array x *
** l Length array x in bytes *
** *
******************************************/
void bshr(BYTE *x, int l)
{
BYTE *p;
int c1,c2;
p = x;
c1 = 0;
c2 = 0;
while ( p != x+l-1 ) {
if ( *p & 0x01 )
c2 = 1;
*p >>= 1; /* shift the word right once (ms bit = 0) */
if ( c1 )
*p |= 0x80;
c1 = c2;
c2 = 0;
p++;
}
*p >>= 1; /* shift the word right once (ms bit = 0) */
if ( c1 )
*p |= 0x80;
}
/*****************************************
** Mult - Multiply two integers *
** *
** A = B * C *
** *
** Parameters: *
** *
** A Address of the result *
** B Address of the multiplier *
** C Address of the multiplicand *
** LB Length of B in bytes *
** LC Length of C in bytes *
** *
** NOTE: A MUST be LB+LC in length *
** *
******************************************/
int Mult(BYTE *A, BYTE *B, int LB, BYTE *C, int LC)
{
int i, j, k, LA;
DIGIT result;
LA = LB + LC;
for ( i=LB-1; i>=0; i-- ) {
result = 0;
for ( j=LC-1; j>=0; j-- ) {
k = i+j+1;
result = (DIGIT)A[k] + ((DIGIT)(B[i] * C[j])) + (result >> 8);
A[k] = (BYTE)result;
}
A[--k] = (BYTE)(result >> 8);
}
return 0;
}
void ModSqr(BYTE *A, BYTE *B, int LB, BYTE *M, int LM)
{
Square(A, B, LB);
Mod(A, 2*LB, M, LM);
}
void ModMult(BYTE *A, BYTE *B, int LB, BYTE *C, int LC, BYTE *M, int LM)
{
Mult(A, B, LB, C, LC);
Mod(A, (LB+LC), M, LM);
}
/*****************************************
** smult - Multiply array by a scalar. *
** *
** A = b * C *
** *
** Parameters: *
** *
** A Address of the result *
** b Scalar (1 BYTE) *
** C Address of the multiplicand *
** L Length of C in bytes *
** *
** NOTE: A MUST be L+1 in length *
** *
******************************************/
void smult(BYTE *A, BYTE b, BYTE *C, int L)
{
int i;
DIGIT result;
result = 0;
for ( i=L-1; i>0; i-- ) {
result = A[i] + ((DIGIT)b * C[i]) + (result >> 8);
A[i] = (BYTE)(result & 0xff);
A[i-1] = (BYTE)(result >> 8);
}
}
/*****************************************
** Square() - Square an integer *
** *
** A = B^2 *
** *
** Parameters: *
** *
** A Address of the result *
** B Address of the operand *
** L Length of B in bytes *
** *
** NOTE: A MUST be 2*L in length *
** *
******************************************/
void Square(BYTE *A, BYTE *B, int L)
{
Mult(A, B, L, B, L);
}
/*****************************************
** ModExp - Modular Exponentiation *
** *
** A = B ** C (MOD M) *
** *
** Parameters: *
** *
** A Address of result *
** B Address of mantissa *
** C Address of exponent *
** M Address of modulus *
** LB Length of B in bytes *
** LC Length of C in bytes *
** LM Length of M in bytes *
** *
** NOTE: The integer B must be less *
** than the modulus M. *
** NOTE: A must be at least 3*LM *
** bytes long. However, the *
** result stored in A will be *
** only LM bytes long. *
******************************************/
void ModExp(BYTE *A, BYTE *B, int LB, BYTE *C, int LC, BYTE *M, int LM)
{
BYTE wmask;
int bits;
bits = LC*8;
wmask = 0x80;
A[LM-1] = 1;
while ( !sniff_bit(C,wmask) ) {
wmask >>= 1;
bits--;
if ( !wmask ) {
wmask = 0x80;
C++;
}
}
while ( bits-- ) {
memset(A+LM, 0x00, LM*2);
/* temp = A*A (MOD M) */
ModSqr(A+LM, A,LM, M,LM);
/* A = lower L bytes of temp */
memcpy(A, A+LM*2, LM);
memset(A+LM, 0x00, 2*LM);
if ( sniff_bit(C,wmask) ) {
memset(A+LM, 0x00, (LM+LB));
ModMult(A+LM, B,LB, A,LM, M,LM); /* temp = B * A (MOD M) */
memcpy(A, A+LM+(LM+LB)-LM, LM); /* A = lower LM bytes of temp */
memset(A+LM, 0x00, 2*LM);
}
wmask >>= 1;
if ( !wmask ) {
wmask = 0x80;
C++;
}
}
}
/* DivMod:
*
* computes:
* quot = x / n
* rem = x % n
* returns:
* length of "quot"
*
* len of rem is lenx+1
*/
int DivMod(BYTE *x, int lenx, BYTE *n, int lenn, BYTE *quot, BYTE *rem)
{
BYTE *tx, *tn, *ttx, *ts, bmult[1];
int i, shift, lgth_x, lgth_n, t_len, lenq;
DIGIT tMSn, mult;
unsigned long tMSx;
int underflow;
tx = x;
tn = n;
/* point to the MSD of n */
for ( i=0, lgth_n=lenn; i<lenn; i++, lgth_n-- ) {
if ( *tn )
break;
tn++;
}
if ( !lgth_n )
return 0;
/* point to the MSD of x */
for ( i=0, lgth_x=lenx; i<lenx; i++, lgth_x-- ) {
if ( *tx )
break;
tx++;
}
if ( !lgth_x )
return 0;
if ( lgth_x < lgth_n )
lenq = 1;
else
lenq = lgth_x - lgth_n + 1;
memset(quot, 0x00, lenq);
/* Loop while x > n, WATCH OUT if lgth_x == lgth_n */
while ( (lgth_x > lgth_n) || ((lgth_x == lgth_n) && !less(tx, tn, lgth_n)) ) {
shift = 1;
if ( lgth_n == 1 ) {
if ( *tx < *tn ) {
tMSx = (DIGIT) (((*tx) << 8) | *(tx+1));
tMSn = *tn;
shift = 0;
}
else {
tMSx = *tx;
tMSn = *tn;
}
}
else if ( lgth_n > 1 ) {
tMSx = (DIGIT) (((*tx) << 8) | *(tx+1));
tMSn = (DIGIT) (((*tn) << 8) | *(tn+1));
if ( (tMSx < tMSn) || ((tMSx == tMSn) && less(tx, tn, lgth_n)) ) {
tMSx = (tMSx << 8) | *(tx+2);
shift = 0;
}
}
else {
tMSx = (DIGIT) (((*tx) << 8) | *(tx+1));
tMSn = *tn;
shift = 0;
}
mult = (DIGIT) (tMSx / tMSn);
if ( mult > 0xff )
mult = 0xff;
bmult[0] = mult & 0xff;
ts = rem;
do {
memset(ts, 0x00, lgth_x+1);
Mult(ts, tn, lgth_n, bmult, 1);
underflow = 0;
if ( shift ) {
if ( ts[0] != 0 )
underflow = 1;
else {
for ( i=0; i<lgth_x; i++ )
ts[i] = ts[i+1];
ts[lgth_x] = 0x00;
}
}
if ( greater(ts, tx, lgth_x) || underflow ) {
bmult[0]--;
underflow = 1;
}
else
underflow = 0;
} while ( underflow );
sub(tx, lgth_x, ts, lgth_x);
if ( shift )
quot[lenq - (lgth_x - lgth_n) - 1] = bmult[0];
else
quot[lenq - (lgth_x - lgth_n)] = bmult[0];
ttx = tx;
t_len = lgth_x;
for ( i=0, lgth_x=t_len; i<t_len; i++, lgth_x-- ) {
if ( *ttx )
break;
ttx++;
}
tx = ttx;
}
memset(rem, 0x00, lenn);
if ( lgth_x )
memcpy(rem+lenn-lgth_x, tx, lgth_x);
return lenq;
}
/*
* Mod - Computes an integer modulo another integer
*
* x = x (mod n)
*
*/
void Mod(BYTE *x, int lenx, BYTE *n, int lenn)
{
BYTE quot[MAXPLEN+1], rem[2*MAXPLEN+1];
memset(quot, 0x00, sizeof(quot));
memset(rem, 0x00, sizeof(rem));
if ( DivMod(x, lenx, n, lenn, quot, rem) ) {
memset(x, 0x00, lenx);
memcpy(x+lenx-lenn, rem, lenn);
}
}
/*
* Div - Computes the integer division of two numbers
*
* x = x / n
*
*/
void Div(BYTE *x, int lenx, BYTE *n, int lenn)
{
BYTE quot[MAXPLEN+1], rem[2*MAXPLEN+1];
int lenq;
memset(quot, 0x00, sizeof(quot));
memset(rem, 0x00, sizeof(rem));
if ( (lenq = DivMod(x, lenx, n, lenn, quot, rem)) != 0 ) {
memset(x, 0x00, lenx);
memcpy(x+lenx-lenq, quot, lenq);
}
}
/*****************************************
** sub - Subtract two integers *
** *
** A = A - B *
** *
** *
** Parameters: *
** *
** A Address of subtrahend integer *
** B Address of subtractor integer *
** L Length of A and B in bytes *
** *
** NOTE: In order to save RAM, B is *
** two's complemented twice, *
** rather than using a copy of B *
** *
******************************************/
void sub(BYTE *A, int LA, BYTE *B, int LB)
{
BYTE *tb;
tb = (BYTE *)calloc(LA, 1);
memcpy(tb, B, LB);
negate(tb, LB);
add(A, LA, tb, LA);
FREE(tb);
}
/*****************************************
** negate - Negate an integer *
** *
** A = -A *
** *
** *
** Parameters: *
** *
** A Address of integer to negate *
** L Length of A in bytes *
** *
******************************************/
int negate(BYTE *A, int L)
{
int i, tL;
DIGIT accum;
/* Take one's complement of A */
for ( i=0; i<L; i++ )
A[i] = ~(A[i]);
/* Add one to get two's complement of A */
accum = 1;
tL = L-1;
while ( accum && (tL >= 0) ) {
accum += A[tL];
A[tL--] = (BYTE)(accum & 0xff);
accum = accum >> 8;
}
return accum;
}
/*
* add()
*
* A = A + B
*
* LB must be <= LA
*
*/
BYTE add(BYTE *A, int LA, BYTE *B, int LB)
{
int i, indexA, indexB;
DIGIT accum;
indexA = LA - 1; /* LSD of result */
indexB = LB - 1; /* LSD of B */
accum = 0;
for ( i = 0; i < LB; i++ ) {
accum += A[indexA];
accum += B[indexB--];
A[indexA--] = (BYTE)(accum & 0xff);
accum = accum >> 8;
}
if ( LA > LB )
while ( accum && (indexA >= 0) ) {
accum += A[indexA];
A[indexA--] = (BYTE)(accum & 0xff);
accum = accum >> 8;
}
return (BYTE)accum;
}
void prettyprintBstr(char *S, BYTE *A, int L)
{
int i, extra, ctrb, ctrl;
if ( L == 0 )
printf("%s <empty>", S);
else
printf("%s\n\t", S);
extra = L % 24;
if ( extra ) {
ctrb = 0;
for ( i=0; i<24-extra; i++ ) {
printf(" ");
if ( ++ctrb == 4) {
printf(" ");
ctrb = 0;
}
}
for ( i=0; i<extra; i++ ) {
printf("%02X", A[i]);
if ( ++ctrb == 4) {
printf(" ");
ctrb = 0;
}
}
printf("\n\t");
}
ctrb = ctrl = 0;
for ( i=extra; i<L; i++ ) {
printf("%02X", A[i]);
if ( ++ctrb == 4) {
ctrl++;
if ( ctrl == 6 ) {
printf("\n\t");
ctrl = 0;
}
else
printf(" ");
ctrb = 0;
}
}
printf("\n\n");
}
/**********************************************************************/
/* Performs byte reverse for PC based implementation (little endian) */
/**********************************************************************/
void byteReverse(unsigned long *buffer, int byteCount)
{
unsigned long value;
int count;
byteCount /= sizeof( unsigned long );
for( count = 0; count < byteCount; count++ ) {
value = ( buffer[ count ] << 16 ) | ( buffer[ count ] >> 16 );
buffer[ count ] = ( ( value & 0xFF00FF00L ) >> 8 ) | ( ( value & 0x00FF00FFL ) << 8 );
}
}
void
ahtopb (char *ascii_hex, BYTE *p_binary, int bin_len)
{
BYTE nibble;
int i;
for ( i=0; i<bin_len; i++ ) {
nibble = ascii_hex[i * 2];
if ( nibble > 'F' )
nibble -= 0x20;
if ( nibble > '9' )
nibble -= 7;
nibble -= '0';
p_binary[i] = nibble << 4;
nibble = ascii_hex[i * 2 + 1];
if ( nibble > 'F' )
nibble -= 0x20;
if ( nibble > '9' )
nibble -= 7;
nibble -= '0';
p_binary[i] += nibble;
}
}

View File

@@ -0,0 +1,13 @@
#ifndef _NIST_CEPHES_H_
#define _NIST_CEPHES_H_
double cephes_igamc(double a, double x);
double cephes_igam(double a, double x);
double cephes_lgam(double x);
double cephes_p1evl(double x, double *coef, int N);
double cephes_polevl(double x, double *coef, int N);
double cephes_erf(double x);
double cephes_erfc(double x);
double cephes_normal(double x);
#endif /* _CEPHES_H_ */

View File

@@ -0,0 +1,52 @@
#if defined(__cplusplus)
extern "C" {
#endif
#ifndef _NIST_CONFIG_H_
#define _NIST_CONFIG_H_
#define WINDOWS32
//#define PROTOTYPES
//#define LITTLE_ENDIAN
//#define LOWHI
/*
* AUTO DEFINES (DON'T TOUCH!)
*/
#ifndef CSTRTD
typedef char *CSTRTD;
#endif
#ifndef BSTRTD
typedef unsigned char *BSTRTD;
#endif
#ifndef BYTE
typedef unsigned char BYTE;
#endif
#ifndef UINT
typedef unsigned int UINT;
#endif
#ifndef USHORT
typedef unsigned short USHORT;
#endif
//#ifndef ULONG
//typedef unsigned long ULONG;
//#endif
#ifndef DIGIT
typedef USHORT DIGIT; /* 16-bit word */
#endif
#ifndef DBLWORD
typedef unsigned long DBLWORD; /* 32-bit word */
#endif
#ifndef WORD64
typedef unsigned long WORD64[2]; /* 64-bit word */
#endif
#endif /* _CONFIG_H_ */
#if defined(__cplusplus)
}
#endif

View File

@@ -0,0 +1,24 @@
#ifndef _NIST_DECLS_H_
#define _NIST_DECLS_H_
#include <stdio.h>
#include "defs.h"
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
G L O B A L D A T A S T R U C T U R E S
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
BitSequence *epsilon; // BIT STREAM
TP tp; // TEST PARAMETER STRUCTURE
FILE *stats[NUMOFTESTS+1]; // FILE OUTPUT STREAM
FILE *results[NUMOFTESTS+1]; // FILE OUTPUT STREAM
FILE *freqfp; // FILE OUTPUT STREAM
FILE *summary; // FILE OUTPUT STREAM
int testVector[NUMOFTESTS+1];
char generatorDir[NUMOFGENERATORS][20] = { "AlgorithmTesting", "LCG", "QCG1", "QCG2","CCG", "XOR",
"MODEXP", "BBS", "MS", "G-SHA1" };
#endif

View File

@@ -0,0 +1,73 @@
#ifndef _NIST_DEFS_H_
#define _NIST_DEFS_H_
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
D E B U G G I N G A I D E S
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include "config.h"
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
M A C R O S
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#define MAX(x,y) ((x) < (y) ? (y) : (x))
#define MIN(x,y) ((x) > (y) ? (y) : (x))
#define isNonPositive(x) ((x) <= 0.e0 ? 1 : 0)
#define isPositive(x) ((x) > 0.e0 ? 1 : 0)
#define isNegative(x) ((x) < 0.e0 ? 1 : 0)
#define isGreaterThanOne(x) ((x) > 1.e0 ? 1 : 0)
#define isZero(x) ((x) == 0.e0 ? 1 : 0)
#define isOne(x) ((x) == 1.e0 ? 1 : 0)
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
G L O B A L C O N S T A N T S
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#define ALPHA 0.01 /* SIGNIFICANCE LEVEL */
#define MAXNUMOFTEMPLATES 148 /* APERIODIC TEMPLATES: 148=>temp_length=9 */
#define NUMOFGENERATORS 10 /* MAX PRNGs */
#define MAXFILESPERMITTEDFORPARTITION 148
#define TEST_FREQUENCY 1
#define TEST_BLOCK_FREQUENCY 2
#define TEST_CUSUM 3
#define TEST_RUNS 4
#define TEST_LONGEST_RUN 5
#define TEST_RANK 6
#define TEST_FFT 7
#define TEST_NONPERIODIC 8
#define TEST_OVERLAPPING 9
#define TEST_UNIVERSAL 10
#define TEST_APEN 11
#define TEST_RND_EXCURSION 12
#define TEST_RND_EXCURSION_VAR 13
#define TEST_SERIAL 14
#define TEST_LINEARCOMPLEXITY 15
#define TEST_POKER_DETECT 16
#define TEST_RUNS_DISTRIBUTION 17
#define TEST_BIN_DERIVATE 18
#define TEST_SELF_CORR 19
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
G L O B A L D A T A S T R U C T U R E S
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
typedef unsigned char BitSequence;
typedef struct _testParameters {
int n;
int blockFrequencyBlockLength;
int nonOverlappingTemplateBlockLength;
int overlappingTemplateBlockLength;
int serialBlockLength;
int linearComplexitySequenceLength;
int approximateEntropyBlockLength;
int PokerDetectMLength;
int BinaryDerivateKLength;
int SelfCorrelationDLength;
int numOfBitStreams;
} TP;
#endif

View File

@@ -0,0 +1,21 @@
#ifndef _NIST_EXTERNS_H_
#define _NIST_EXTERNS_H_
#include "defs.h"
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
G L O B A L D A T A S T R U C T U R E S
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
//extern BitSequence *epsilon; // BIT STREAM
//extern TP tp; // TEST PARAMETER STRUCTURE
//extern FILE *stats[NUMOFTESTS+1]; // FILE OUTPUT STREAM
//extern FILE *results[NUMOFTESTS+1]; // FILE OUTPUT STREAM
//extern FILE *freqfp; // FILE OUTPUT STREAM
//extern FILE *summary; // FILE OUTPUT STREAM
//extern int testVector[NUMOFTESTS+1];
//
//extern char generatorDir[NUMOFGENERATORS][20];
//extern char testNames[NUMOFTESTS+1][32];
#endif

View File

@@ -0,0 +1,78 @@
#ifndef _NIST_GENERATORS_H_
#define _NIST_GENERATORS_H_
/* The circular shifts. */
#define CS1(x) ((((ULONG)x)<<1)|(((ULONG)x)>>31))
#define CS5(x) ((((ULONG)x)<<5)|(((ULONG)x)>>27))
#define CS30(x) ((((ULONG)x)<<30)|(((ULONG)x)>>2))
/* K constants */
#define K0 0x5a827999L
#define K1 0x6ed9eba1L
#define K2 0x8f1bbcdcL
#define K3 0xca62c1d6L
#define f1(x,y,z) ( (x & (y ^ z)) ^ z )
#define f3(x,y,z) ( (x & ( y ^ z )) ^ (z & y) )
#define f2(x,y,z) ( x ^ y ^ z ) /* Rounds 20-39 */
#define expand(x) Wbuff[x%16] = CS1(Wbuff[(x - 3)%16 ] ^ Wbuff[(x - 8)%16 ] ^ Wbuff[(x - 14)%16] ^ Wbuff[x%16])
#define sub1Round1(count) { \
temp = CS5(A) + f1(B, C, D) + E + Wbuff[count] + K0; \
E = D; \
D = C; \
C = CS30( B ); \
B = A; \
A = temp; \
} \
#define sub2Round1(count) \
{ \
expand(count); \
temp = CS5(A) + f1(B, C, D) + E + Wbuff[count%16] + K0; \
E = D; \
D = C; \
C = CS30( B ); \
B = A; \
A = temp; \
} \
#define Round2(count) \
{ \
expand(count); \
temp = CS5( A ) + f2( B, C, D ) + E + Wbuff[count%16] + K1; \
E = D; \
D = C; \
C = CS30( B ); \
B = A; \
A = temp; \
} \
#define Round3(count) \
{ \
expand(count); \
temp = CS5( A ) + f3( B, C, D ) + E + Wbuff[count%16] + K2; \
E = D; \
D = C; \
C = CS30( B ); \
B = A; \
A = temp; \
}
#define Round4(count) \
{ \
expand(count); \
temp = CS5( A ) + f2( B, C, D ) + E + Wbuff[count%16] + K3; \
E = D; \
D = C; \
C = CS30( B ); \
B = A; \
A = temp; \
}
#endif

View File

@@ -0,0 +1,47 @@
#ifndef _NIST_GENUTILS_H_
#define _NIST_GENUTILS_H_
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "config.h"
typedef struct _MP_struct {
int size; /* in bytes */
int bitlen; /* in bits, duh */
BYTE *val;
} MP;
#define FREE(A) if ( (A) ) { free((A)); (A) = NULL; }
#define ASCII2BIN(ch) ( (((ch) >= '0') && ((ch) <= '9')) ? ((ch) - '0') : (((ch) >= 'A') && ((ch) <= 'F')) ? ((ch) - 'A' + 10) : ((ch) - 'a' + 10) )
#ifndef EXPWD
#define EXPWD ((DBLWORD)1<<NUMLEN)
#endif
#define sniff_bit(ptr,mask) (*(ptr) & mask)
/*
* Function Declarations
*/
int greater(BYTE *x, BYTE *y, int l);
int less(BYTE *x, BYTE *y, int l);
BYTE bshl(BYTE *x, int l);
void bshr(BYTE *x, int l);
int Mult(BYTE *A, BYTE *B, int LB, BYTE *C, int LC);
void ModSqr(BYTE *A, BYTE *B, int LB, BYTE *M, int LM);
void ModMult(BYTE *A, BYTE *B, int LB, BYTE *C, int LC, BYTE *M, int LM);
void smult(BYTE *A, BYTE b, BYTE *C, int L);
void Square(BYTE *A, BYTE *B, int L);
void ModExp(BYTE *A, BYTE *B, int LB, BYTE *C, int LC, BYTE *M, int LM);
int DivMod(BYTE *x, int lenx, BYTE *n, int lenn, BYTE *quot, BYTE *rem);
void Mod(BYTE *x, int lenx, BYTE *n, int lenn);
void Div(BYTE *x, int lenx, BYTE *n, int lenn);
void sub(BYTE *A, int LA, BYTE *B, int LB);
int negate(BYTE *A, int L);
BYTE add(BYTE *A, int LA, BYTE *B, int LB);
void prettyprintBstr(char *S, BYTE *A, int L);
void byteReverse(unsigned long *buffer, int byteCount);
void ahtopb (char *ascii_hex, BYTE *p_binary, int bin_len);
#endif /* _GENUTILS_H_ */

View File

@@ -0,0 +1,18 @@
#ifndef _NIST_MATRIX_H_
#define _NIST_MATRIX_H_
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
R A N K A L G O R I T H M F U N C T I O N P R O T O T Y P E S
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
int computeRank(int M, int Q, BitSequence **matrix);
void perform_elementary_row_operations(int flag, int i, int M, int Q, BitSequence **A);
int find_unit_element_and_swap(int flag, int i, int M, int Q, BitSequence **A);
int swap_rows(int i, int index, int Q, BitSequence **A);
int determine_rank(int m, int M, int Q, BitSequence **A);
BitSequence** create_matrix(int M, int Q);
void display_matrix(int M, int Q, BitSequence **m);
void def_matrix(int M, int Q, BitSequence **m, int k, BitSequence *epsilon);
void delete_matrix(int M, BitSequence **matrix);
#endif

View File

@@ -0,0 +1,166 @@
#ifndef _STAT_FNCS_H_
#define _STAT_FNCS_H_
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
S T A T I S T I C A L T E S T F U N C T I O N P R O T O T Y P E S
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include "defs.h"
/**
*
* @param in
* @param inl
* @param out 外部预先分配缓冲区缓冲区大小因最少为字节数的8倍
* @param outbufsize
* @return
*/
int BytesToBitSequence(unsigned char *in, int inl, BitSequence *outbuf, int bufsize);
/**
* 单比特频数检测
* @param n
* @return
*/
int Frequency(int n, BitSequence *epsilon);
/**
* 块内频数检测
* @param M
* @param n
* @return
*/
int BlockFrequency(int M, int n, BitSequence *epsilon);
/**
* 累加和检测
* @param n
* @return
*/
int CumulativeSums(int n, BitSequence *epsilon);
/**
* 游程总数检测
* @param n
* @return
*/
int Runs(int n, BitSequence *epsilon);
/**
* 块内最大“1”游程检测
* @param n
* @return
*/
int LongestRunOfOnes(int n, BitSequence *epsilon);
/**
* 矩阵秩检测
* @param n
* @return
*/
int Rank(int n, BitSequence *epsilon);
/**
* 离散傅立叶检测
* @param n
* @return
*/
int DiscreteFourierTransform(int n, BitSequence *epsilon);
/**
* 非重叠模版匹配测试
* @param m
* @param n
* @return
*/
int NonOverlappingTemplateMatchings(int m, int n, BitSequence *epsilon);
/**
* 重叠模版匹配测试
* @param m
* @param n
* @return
*/
int OverlappingTemplateMatchings(int m, int n, BitSequence *epsilon);
/**
* 通用统计检测
* @param n
* @return
*/
int Universal(int n, BitSequence *epsilon);
/**
* 近似熵检测
* @param m
* @param n
* @return
*/
int ApproximateEntropy(int m, int n, BitSequence *epsilon);
/**
* 自由游程测试
* @param n
* @return
*/
int RandomExcursions(int n, BitSequence *epsilon);
/**
* 自由变量测试
* @param n
* @return
*/
int RandomExcursionsVariant(int n, BitSequence *epsilon);
/**
* 线性复杂度检测
* @param M
* @param n
* @return
*/
int LinearComplexity(int M, int n, BitSequence *epsilon);
/**
* 重叠子序列检测
* @param m
* @param n
* @return
*/
int Serial(int m, int n, BitSequence *epsilon);
/**
* 二元推导检测
* @param k
* @param n
* @param epsilon
* @return
*/
int BinaryDerivate(int k, int n, BitSequence *epsilon, int epsilon_l);
/**
* 自相关测试
* @param d
* @param n
* @param epsilon
* @return
*/
int SelfCorrelation(int d, int n, BitSequence *epsilon);
/**
* 扑克检测
* @param M
* @param n
* @param epsilon
* @return
*/
int PokerDetect(int M, int n, BitSequence *epsilon);
/**
* 游程分布检测
* @param n
* @param epsilon
* @return
*/
int RunsDistribution(int n, BitSequence *epsilon);
#endif

View File

@@ -0,0 +1,4 @@
#include "include/config.h"
#include "include/defs.h"
int convertToBits(BYTE *x, int xBitLength, int bitsNeeded, int *num_0s, int *num_1s, int *bitsRead, BitSequence* epsilon);

View File

@@ -0,0 +1,135 @@
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include "include/externs.h"
#include "include/cephes.h"
int
LinearComplexity(int M, int n, BitSequence *epsilon)
{
int i, ii, j, d, N, L, m, N_, parity, sign, K = 6;
double p_value, T_, mean, nu[7], chi2;
const double pi[7] = { 0.01047, 0.03125, 0.12500, 0.50000, 0.25000, 0.06250, 0.020833 };
BitSequence *T, *P, *B_, *C;
N = (int)floor(n/M);
if ( ((B_ = (BitSequence *) calloc(M, sizeof(BitSequence))) == NULL) ||
((C = (BitSequence *) calloc(M, sizeof(BitSequence))) == NULL) ||
((P = (BitSequence *) calloc(M, sizeof(BitSequence))) == NULL) ||
((T = (BitSequence *) calloc(M, sizeof(BitSequence))) == NULL) ) {
printf("Insufficient Memory for Work Space:: Linear Complexity Test\n");
if ( B_!= NULL )
free(B_);
if ( C != NULL )
free(C);
if ( P != NULL )
free(P);
if ( T != NULL )
free(T);
return 0;
}
// fprintf(stats[TEST_LINEARCOMPLEXITY], "-----------------------------------------------------\n");
// fprintf(stats[TEST_LINEARCOMPLEXITY], "\tL I N E A R C O M P L E X I T Y\n");
// fprintf(stats[TEST_LINEARCOMPLEXITY], "-----------------------------------------------------\n");
// fprintf(stats[TEST_LINEARCOMPLEXITY], "\tM (substring length) = %d\n", M);
// fprintf(stats[TEST_LINEARCOMPLEXITY], "\tN (number of substrings) = %d\n", N);
// fprintf(stats[TEST_LINEARCOMPLEXITY], "-----------------------------------------------------\n");
// fprintf(stats[TEST_LINEARCOMPLEXITY], " F R E Q U E N C Y \n");
// fprintf(stats[TEST_LINEARCOMPLEXITY], "-----------------------------------------------------\n");
// fprintf(stats[TEST_LINEARCOMPLEXITY], " C0 C1 C2 C3 C4 C5 C6 CHI2 P-value\n");
// fprintf(stats[TEST_LINEARCOMPLEXITY], "-----------------------------------------------------\n");
// fprintf(stats[TEST_LINEARCOMPLEXITY], "\tNote: %d bits were discarded!\n", n%M);
for ( i=0; i<K+1; i++ )
nu[i] = 0.00;
for ( ii=0; ii<N; ii++ ) {
for ( i=0; i<M; i++ ) {
B_[i] = 0;
C[i] = 0;
T[i] = 0;
P[i] = 0;
}
L = 0;
m = -1;
d = 0;
C[0] = 1;
B_[0] = 1;
/* DETERMINE LINEAR COMPLEXITY */
N_ = 0;
while ( N_ < M ) {
d = (int)epsilon[ii*M+N_];
for ( i=1; i<=L; i++ )
d += C[i] * epsilon[ii*M+N_-i];
d = d%2;
if ( d == 1 ) {
for ( i=0; i<M; i++ ) {
T[i] = C[i];
P[i] = 0;
}
for ( j=0; j<M; j++ )
if ( B_[j] == 1 )
P[j+N_-m] = 1;
for ( i=0; i<M; i++ )
C[i] = (C[i] + P[i])%2;
if ( L <= N_/2 ) {
L = N_ + 1 - L;
m = N_;
for ( i=0; i<M; i++ )
B_[i] = T[i];
}
}
N_++;
}
if ( (parity = (M+1)%2) == 0 )
sign = -1;
else
sign = 1;
mean = M/2.0 + (9.0+sign)/36.0 - 1.0/pow(2, M) * (M/3.0 + 2.0/9.0);
if ( (parity = M%2) == 0 )
sign = 1;
else
sign = -1;
T_ = sign * (L - mean) + 2.0/9.0;
if ( T_ <= -2.5 )
nu[0]++;
else if ( T_ <= -1.5 )
nu[1]++;
else if (T_ <= -0.5 )
nu[2]++;
else if ( T_ <= 0.5 )
nu[3]++;
else if ( T_ <= 1.5 )
nu[4]++;
else if (T_ <= 2.5 )
nu[5]++;
else
nu[6]++;
}
chi2 = 0.00;
// for ( i=0; i<K+1; i++ ) {
// fprintf(stats[TEST_LINEARCOMPLEXITY], "%4d ", (int) nu[i]);
// }
for ( i=0; i<K+1; i++ ) {
chi2 += pow(nu[i] - N * pi[i], 2) / (N * pi[i]);
}
p_value = cephes_igamc(K/2.0, chi2/2.0);
// fprintf(stats[TEST_LINEARCOMPLEXITY], "%9.6f%9.6f\n", chi2, p_value); fflush(stats[TEST_LINEARCOMPLEXITY]);
// fprintf(results[TEST_LINEARCOMPLEXITY], "%f\n", p_value); fflush(results[TEST_LINEARCOMPLEXITY]);
free(B_);
free(P);
free(C);
free(T);
if (p_value < ALPHA) {
return 0;
} else {
return 1;
}
}

View File

@@ -0,0 +1,125 @@
/* got rid of unused 'k' */
#include <stdio.h>
#include <math.h>
#include <string.h>
#include "include/externs.h"
#include "include/cephes.h"
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
L O N G E S T R U N S T E S T
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
int
LongestRunOfOnes(int n, BitSequence *epsilon)
{
double pval, chi2, pi[7];
int run, v_n_obs, N, i, j, K, M, V[7];
unsigned int nu[7] = { 0, 0, 0, 0, 0, 0, 0 };
if ( n < 128 ) {
// fprintf(stats[TEST_LONGEST_RUN], "\t\t\t LONGEST RUNS OF ONES TEST\n");
// fprintf(stats[TEST_LONGEST_RUN], "\t\t---------------------------------------------\n");
// fprintf(stats[TEST_LONGEST_RUN], "\t\t n=%d is too short\n", n);
return 0;
}
if ( n < 6272 ) {
K = 3;
M = 8;
V[0] = 1; V[1] = 2; V[2] = 3; V[3] = 4;
pi[0] = 0.21484375;
pi[1] = 0.3671875;
pi[2] = 0.23046875;
pi[3] = 0.1875;
}
else if ( n < 750000 ) {
K = 5;
M = 128;
V[0] = 4; V[1] = 5; V[2] = 6; V[3] = 7; V[4] = 8; V[5] = 9;
pi[0] = 0.1174035788;
pi[1] = 0.242955959;
pi[2] = 0.249363483;
pi[3] = 0.17517706;
pi[4] = 0.102701071;
pi[5] = 0.112398847;
}
else {
K = 6;
M = 10000;
V[0] = 10; V[1] = 11; V[2] = 12; V[3] = 13; V[4] = 14; V[5] = 15; V[6] = 16;
pi[0] = 0.0882;
pi[1] = 0.2092;
pi[2] = 0.2483;
pi[3] = 0.1933;
pi[4] = 0.1208;
pi[5] = 0.0675;
pi[6] = 0.0727;
}
N = n/M;
for ( i=0; i<N; i++ ) {
v_n_obs = 0;
run = 0;
for ( j=0; j<M; j++ ) {
if ( epsilon[i*M+j] == 1 ) {
run++;
if ( run > v_n_obs )
v_n_obs = run;
}
else
run = 0;
}
if ( v_n_obs < V[0] )
nu[0]++;
for ( j=0; j<=K; j++ ) {
if ( v_n_obs == V[j] )
nu[j]++;
}
if ( v_n_obs > V[K] )
nu[K]++;
}
chi2 = 0.0;
for ( i=0; i<=K; i++ )
chi2 += ((nu[i] - N * pi[i]) * (nu[i] - N * pi[i])) / (N * pi[i]);
pval = cephes_igamc((double)(K/2.0), chi2 / 2.0);
// fprintf(stats[TEST_LONGEST_RUN], "\t\t\t LONGEST RUNS OF ONES TEST\n");
// fprintf(stats[TEST_LONGEST_RUN], "\t\t---------------------------------------------\n");
// fprintf(stats[TEST_LONGEST_RUN], "\t\tCOMPUTATIONAL INFORMATION:\n");
// fprintf(stats[TEST_LONGEST_RUN], "\t\t---------------------------------------------\n");
// fprintf(stats[TEST_LONGEST_RUN], "\t\t(a) N (# of substrings) = %d\n", N);
// fprintf(stats[TEST_LONGEST_RUN], "\t\t(b) M (Substring Length) = %d\n", M);
// fprintf(stats[TEST_LONGEST_RUN], "\t\t(c) Chi^2 = %f\n", chi2);
// fprintf(stats[TEST_LONGEST_RUN], "\t\t---------------------------------------------\n");
// fprintf(stats[TEST_LONGEST_RUN], "\t\t F R E Q U E N C Y\n");
// fprintf(stats[TEST_LONGEST_RUN], "\t\t---------------------------------------------\n");
// if ( K == 3 ) {
// fprintf(stats[TEST_LONGEST_RUN], "\t\t <=1 2 3 >=4 P-value Assignment");
// fprintf(stats[TEST_LONGEST_RUN], "\n\t\t %3d %3d %3d %3d ", nu[0], nu[1], nu[2], nu[3]);
// }
// else if ( K == 5 ) {
// fprintf(stats[TEST_LONGEST_RUN], "\t\t<=4 5 6 7 8 >=9 P-value Assignment");
// fprintf(stats[TEST_LONGEST_RUN], "\n\t\t %3d %3d %3d %3d %3d %3d ", nu[0], nu[1], nu[2],
// nu[3], nu[4], nu[5]);
// }
// else {
// fprintf(stats[TEST_LONGEST_RUN],"\t\t<=10 11 12 13 14 15 >=16 P-value Assignment");
// fprintf(stats[TEST_LONGEST_RUN],"\n\t\t %3d %3d %3d %3d %3d %3d %3d ", nu[0], nu[1], nu[2],
// nu[3], nu[4], nu[5], nu[6]);
// }
if ( isNegative(pval) || isGreaterThanOne(pval) ) {
// fprintf(stats[TEST_LONGEST_RUN], "WARNING: P_VALUE IS OUT OF RANGE.\n");
return 0;
}
// fprintf(stats[TEST_LONGEST_RUN], "%s\t\tp_value = %f\n\n", pval < ALPHA ? "FAILURE" : "SUCCESS", pval); fflush(stats[TEST_LONGEST_RUN]);
// fprintf(results[TEST_LONGEST_RUN], "%f\n", pval); fflush(results[TEST_LONGEST_RUN]);
if (pval < ALPHA) {
return 0;
} else {
return 1;
}
}

View File

@@ -0,0 +1,170 @@
#include <stdio.h>
#include <stdlib.h>
#include "include/externs.h"
#include "include/matrix.h"
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
R A N K A L G O R I T H M R O U T I N E S
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#define MATRIX_FORWARD_ELIMINATION 0
#define MATRIX_BACKWARD_ELIMINATION 1
int
computeRank(int M, int Q, BitSequence **matrix)
{
int i, rank, m=MIN(M,Q);
/* FORWARD APPLICATION OF ELEMENTARY ROW OPERATIONS */
for ( i=0; i<m-1; i++ ) {
if ( matrix[i][i] == 1 )
perform_elementary_row_operations(MATRIX_FORWARD_ELIMINATION, i, M, Q, matrix);
else { /* matrix[i][i] = 0 */
if ( find_unit_element_and_swap(MATRIX_FORWARD_ELIMINATION, i, M, Q, matrix) == 1 )
perform_elementary_row_operations(MATRIX_FORWARD_ELIMINATION, i, M, Q, matrix);
}
}
/* BACKWARD APPLICATION OF ELEMENTARY ROW OPERATIONS */
for ( i=m-1; i>0; i-- ) {
if ( matrix[i][i] == 1 )
perform_elementary_row_operations(MATRIX_BACKWARD_ELIMINATION, i, M, Q, matrix);
else { /* matrix[i][i] = 0 */
if ( find_unit_element_and_swap(MATRIX_BACKWARD_ELIMINATION, i, M, Q, matrix) == 1 )
perform_elementary_row_operations(MATRIX_BACKWARD_ELIMINATION, i, M, Q, matrix);
}
}
rank = determine_rank(m, M, Q, matrix);
return rank;
}
void
perform_elementary_row_operations(int flag, int i, int M, int Q, BitSequence **A)
{
int j, k;
if ( flag == MATRIX_FORWARD_ELIMINATION ) {
for ( j=i+1; j<M; j++ )
if ( A[j][i] == 1 )
for ( k=i; k<Q; k++ )
A[j][k] = (A[j][k] + A[i][k]) % 2;
}
else {
for ( j=i-1; j>=0; j-- )
if ( A[j][i] == 1 )
for ( k=0; k<Q; k++ )
A[j][k] = (A[j][k] + A[i][k]) % 2;
}
}
int
find_unit_element_and_swap(int flag, int i, int M, int Q, BitSequence **A)
{
int index, row_op=0;
if ( flag == MATRIX_FORWARD_ELIMINATION ) {
index = i+1;
while ( (index < M) && (A[index][i] == 0) )
index++;
if ( index < M )
row_op = swap_rows(i, index, Q, A);
}
else {
index = i-1;
while ( (index >= 0) && (A[index][i] == 0) )
index--;
if ( index >= 0 )
row_op = swap_rows(i, index, Q, A);
}
return row_op;
}
int
swap_rows(int i, int index, int Q, BitSequence **A)
{
int p;
BitSequence temp;
for ( p=0; p<Q; p++ ) {
temp = A[i][p];
A[i][p] = A[index][p];
A[index][p] = temp;
}
return 1;
}
int
determine_rank(int m, int M, int Q, BitSequence **A)
{
int i, j, rank, allZeroes;
/* DETERMINE RANK, THAT IS, COUNT THE NUMBER OF NONZERO ROWS */
rank = m;
for ( i=0; i<M; i++ ) {
allZeroes = 1;
for ( j=0; j<Q; j++) {
if ( A[i][j] == 1 ) {
allZeroes = 0;
break;
}
}
if ( allZeroes == 1 )
rank--;
}
return rank;
}
BitSequence**
create_matrix(int M, int Q)
{
int i;
BitSequence **matrix;
if ( (matrix = (BitSequence **) calloc(M, sizeof(BitSequence *))) == NULL ) {
printf("ERROR IN FUNCTION create_matrix: Insufficient memory available.\n");
return NULL;
}
else {
for ( i=0; i<M; i++ ) {
if ( (matrix[i] = calloc(Q, sizeof(BitSequence))) == NULL ) {
printf("ERROR IN FUNCTION create_matrix: Insufficient memory for %dx%d matrix.\n", M, M);
return NULL;
}
}
return matrix;
}
}
void
def_matrix(int M, int Q, BitSequence **m, int k, BitSequence *epsilon)
{
int i,j;
for ( i=0; i<M; i++ )
for ( j=0; j<Q; j++ )
m[i][j] = epsilon[k*(M*Q)+j+i*M];
}
void
delete_matrix(int M, BitSequence **matrix)
{
int i;
if (matrix != NULL) {
for (i = 0; i < M; i++) {
if (matrix[i] != NULL) {
free(matrix[i]);
matrix[i] = NULL;
}
}
free(matrix);
}
}

View File

@@ -0,0 +1,114 @@
#include <stdlib.h>
#include "include/utilities.h"
#include "include/stat_fncs.h"
#include "mesa_sts.h"
int mesa_statistical_test_suite(void* data,unsigned int datalen, struct sts_result* result, unsigned int random_judge_switch_flag)
{
TP tp;
tp.n = datalen;
tp.blockFrequencyBlockLength = 128;
tp.nonOverlappingTemplateBlockLength = 9;
tp.overlappingTemplateBlockLength = 9;
tp.approximateEntropyBlockLength = 10;
tp.serialBlockLength = 16;
tp.linearComplexitySequenceLength = 500;
tp.numOfBitStreams = 1;
tp.PokerDetectMLength = 8;
tp.BinaryDerivateKLength = 3;
tp.SelfCorrelationDLength = 8;
BitSequence* epsilon = (BitSequence *)calloc(tp.n,sizeof(BitSequence));
int done, num_0s, num_1s, bitsRead;
num_0s = 0;
num_1s = 0;
bitsRead = 0;
done = 0;
done = convertToBits((BYTE*)data,datalen,tp.n,&num_0s,&num_1s,&bitsRead,epsilon);
if (STS_TEST_FLAG(random_judge_switch_flag, STS_FREQUENCY))
{
result->frequency = Frequency(tp.n,epsilon);
}
if (STS_TEST_FLAG(random_judge_switch_flag, STS_BLOCK_FREQUENCY))
{
result->block_frequency = BlockFrequency(tp.blockFrequencyBlockLength, tp.n,epsilon);
}
if (STS_TEST_FLAG(random_judge_switch_flag, STS_CUMULATIVE_SUMS))
{
result->cumulative_sums = CumulativeSums(tp.n,epsilon);
}
if (STS_TEST_FLAG(random_judge_switch_flag, STS_RUNS))
{
result->runs = Runs(tp.n,epsilon);
}
if (STS_TEST_FLAG(random_judge_switch_flag, STS_LONGEST_RUN))
{
result->longest_run = LongestRunOfOnes(tp.n,epsilon);
}
if (STS_TEST_FLAG(random_judge_switch_flag, STS_RANK))
{
result->rank = Rank(tp.n,epsilon);
}
//result->discrete_fourier_transform = DiscreteFourierTransform(tp.n,epsilon);//cost too much time
if (STS_TEST_FLAG(random_judge_switch_flag, STS_NON_OVERLAPPING_TEMPLATE_MATCHING))
{
result->non_overlapping_template_matching = NonOverlappingTemplateMatchings(tp.nonOverlappingTemplateBlockLength, tp.n,epsilon);
}
if (STS_TEST_FLAG(random_judge_switch_flag, STS_OVERLAPPING_TEMPLATE_MATCHING))
{
result->overlapping_template_matching = OverlappingTemplateMatchings(tp.overlappingTemplateBlockLength, tp.n,epsilon);
}
if (STS_TEST_FLAG(random_judge_switch_flag, STS_UNIVERSAL))
{
result->universal = Universal(tp.n,epsilon);
}
//result->approximate_entropy = ApproximateEntropy(tp.approximateEntropyBlockLength, tp.n,epsilon);//cost too much time
if (STS_TEST_FLAG(random_judge_switch_flag, STS_RANDOM_EXCURSIONS))
{
result->random_excursions = RandomExcursions(tp.n,epsilon);
}
if (STS_TEST_FLAG(random_judge_switch_flag, STS_RANDOM_EXCURSIONS_VARIANT))
{
result->random_excursions_variant = RandomExcursionsVariant(tp.n,epsilon);
}
//result->serial = Serial(tp.serialBlockLength,tp.n,epsilon);//cost too much time
//sresult->linear_complexity = LinearComplexity(tp.linearComplexitySequenceLength, tp.n,epsilon);//cost too much time
if (STS_TEST_FLAG(random_judge_switch_flag, STS_POKER_DETECT))
{
result->poker_detect = PokerDetect(tp.PokerDetectMLength,tp.n,epsilon);
}
if (STS_TEST_FLAG(random_judge_switch_flag, STS_RUNS_DISTRIBUTION))
{
result->runs_distribution = RunsDistribution(tp.n,epsilon);
}
if (STS_TEST_FLAG(random_judge_switch_flag, STS_SELF_CORRELATION))
{
result->self_correlation = SelfCorrelation(tp.SelfCorrelationDLength,tp.n,epsilon);
}
if (STS_TEST_FLAG(random_judge_switch_flag, STS_BINARY_DERIVATE))
{
result->binary_derivative = BinaryDerivate(tp.BinaryDerivateKLength,tp.n,epsilon,tp.n);//this function will change the value of epsilon, must be the last one
}
free(epsilon);
epsilon = NULL;
return 0;
}

View File

@@ -0,0 +1,281 @@
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include "include/externs.h"
#include "include/cephes.h"
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
N O N O V E R L A P P I N G T E M P L A T E T E S T
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static unsigned int template9[] = {
0,0,0,0,0,0,0,0,1,
0,0,0,0,0,0,0,1,1,
0,0,0,0,0,0,1,0,1,
0,0,0,0,0,0,1,1,1,
0,0,0,0,0,1,0,0,1,
0,0,0,0,0,1,0,1,1,
0,0,0,0,0,1,1,0,1,
0,0,0,0,0,1,1,1,1,
0,0,0,0,1,0,0,0,1,
0,0,0,0,1,0,0,1,1,
0,0,0,0,1,0,1,0,1,
0,0,0,0,1,0,1,1,1,
0,0,0,0,1,1,0,0,1,
0,0,0,0,1,1,0,1,1,
0,0,0,0,1,1,1,0,1,
0,0,0,0,1,1,1,1,1,
0,0,0,1,0,0,0,1,1,
0,0,0,1,0,0,1,0,1,
0,0,0,1,0,0,1,1,1,
0,0,0,1,0,1,0,0,1,
0,0,0,1,0,1,0,1,1,
0,0,0,1,0,1,1,0,1,
0,0,0,1,0,1,1,1,1,
0,0,0,1,1,0,0,1,1,
0,0,0,1,1,0,1,0,1,
0,0,0,1,1,0,1,1,1,
0,0,0,1,1,1,0,0,1,
0,0,0,1,1,1,0,1,1,
0,0,0,1,1,1,1,0,1,
0,0,0,1,1,1,1,1,1,
0,0,1,0,0,0,0,1,1,
0,0,1,0,0,0,1,0,1,
0,0,1,0,0,0,1,1,1,
0,0,1,0,0,1,0,1,1,
0,0,1,0,0,1,1,0,1,
0,0,1,0,0,1,1,1,1,
0,0,1,0,1,0,0,1,1,
0,0,1,0,1,0,1,0,1,
0,0,1,0,1,0,1,1,1,
0,0,1,0,1,1,0,1,1,
0,0,1,0,1,1,1,0,1,
0,0,1,0,1,1,1,1,1,
0,0,1,1,0,0,1,0,1,
0,0,1,1,0,0,1,1,1,
0,0,1,1,0,1,0,1,1,
0,0,1,1,0,1,1,0,1,
0,0,1,1,0,1,1,1,1,
0,0,1,1,1,0,1,0,1,
0,0,1,1,1,0,1,1,1,
0,0,1,1,1,1,0,1,1,
0,0,1,1,1,1,1,0,1,
0,0,1,1,1,1,1,1,1,
0,1,0,0,0,0,0,1,1,
0,1,0,0,0,0,1,1,1,
0,1,0,0,0,1,0,1,1,
0,1,0,0,0,1,1,1,1,
0,1,0,0,1,0,0,1,1,
0,1,0,0,1,0,1,1,1,
0,1,0,0,1,1,0,1,1,
0,1,0,0,1,1,1,1,1,
0,1,0,1,0,0,0,1,1,
0,1,0,1,0,0,1,1,1,
0,1,0,1,0,1,0,1,1,
0,1,0,1,0,1,1,1,1,
0,1,0,1,1,0,0,1,1,
0,1,0,1,1,0,1,1,1,
0,1,0,1,1,1,0,1,1,
0,1,0,1,1,1,1,1,1,
0,1,1,0,0,0,1,1,1,
0,1,1,0,0,1,1,1,1,
0,1,1,0,1,0,1,1,1,
0,1,1,0,1,1,1,1,1,
0,1,1,1,0,1,1,1,1,
0,1,1,1,1,1,1,1,1,
1,0,0,0,0,0,0,0,0,
1,0,0,0,1,0,0,0,0,
1,0,0,1,0,0,0,0,0,
1,0,0,1,0,1,0,0,0,
1,0,0,1,1,0,0,0,0,
1,0,0,1,1,1,0,0,0,
1,0,1,0,0,0,0,0,0,
1,0,1,0,0,0,1,0,0,
1,0,1,0,0,1,0,0,0,
1,0,1,0,0,1,1,0,0,
1,0,1,0,1,0,0,0,0,
1,0,1,0,1,0,1,0,0,
1,0,1,0,1,1,0,0,0,
1,0,1,0,1,1,1,0,0,
1,0,1,1,0,0,0,0,0,
1,0,1,1,0,0,1,0,0,
1,0,1,1,0,1,0,0,0,
1,0,1,1,0,1,1,0,0,
1,0,1,1,1,0,0,0,0,
1,0,1,1,1,0,1,0,0,
1,0,1,1,1,1,0,0,0,
1,0,1,1,1,1,1,0,0,
1,1,0,0,0,0,0,0,0,
1,1,0,0,0,0,0,1,0,
1,1,0,0,0,0,1,0,0,
1,1,0,0,0,1,0,0,0,
1,1,0,0,0,1,0,1,0,
1,1,0,0,1,0,0,0,0,
1,1,0,0,1,0,0,1,0,
1,1,0,0,1,0,1,0,0,
1,1,0,0,1,1,0,0,0,
1,1,0,0,1,1,0,1,0,
1,1,0,1,0,0,0,0,0,
1,1,0,1,0,0,0,1,0,
1,1,0,1,0,0,1,0,0,
1,1,0,1,0,1,0,0,0,
1,1,0,1,0,1,0,1,0,
1,1,0,1,0,1,1,0,0,
1,1,0,1,1,0,0,0,0,
1,1,0,1,1,0,0,1,0,
1,1,0,1,1,0,1,0,0,
1,1,0,1,1,1,0,0,0,
1,1,0,1,1,1,0,1,0,
1,1,0,1,1,1,1,0,0,
1,1,1,0,0,0,0,0,0,
1,1,1,0,0,0,0,1,0,
1,1,1,0,0,0,1,0,0,
1,1,1,0,0,0,1,1,0,
1,1,1,0,0,1,0,0,0,
1,1,1,0,0,1,0,1,0,
1,1,1,0,0,1,1,0,0,
1,1,1,0,1,0,0,0,0,
1,1,1,0,1,0,0,1,0,
1,1,1,0,1,0,1,0,0,
1,1,1,0,1,0,1,1,0,
1,1,1,0,1,1,0,0,0,
1,1,1,0,1,1,0,1,0,
1,1,1,0,1,1,1,0,0,
1,1,1,1,0,0,0,0,0,
1,1,1,1,0,0,0,1,0,
1,1,1,1,0,0,1,0,0,
1,1,1,1,0,0,1,1,0,
1,1,1,1,0,1,0,0,0,
1,1,1,1,0,1,0,1,0,
1,1,1,1,0,1,1,0,0,
1,1,1,1,0,1,1,1,0,
1,1,1,1,1,0,0,0,0,
1,1,1,1,1,0,0,1,0,
1,1,1,1,1,0,1,0,0,
1,1,1,1,1,0,1,1,0,
1,1,1,1,1,1,0,0,0,
1,1,1,1,1,1,0,1,0,
1,1,1,1,1,1,1,0,0,
1,1,1,1,1,1,1,1,0,
};
static size_t template_size = sizeof(template9)/sizeof(template9[0]);
int
NonOverlappingTemplateMatchings(int m, int n, BitSequence *epsilon)
{
int ret = 0;
int numOfTemplates[100] = {0, 0, 2, 4, 6, 12, 20, 40, 74, 148, 284, 568, 1116,
2232, 4424, 8848, 17622, 35244, 70340, 140680, 281076, 562152};
/*----------------------------------------------------------------------------
NOTE: Should additional templates lengths beyond 21 be desired, they must
first be constructed, saved into files and then the corresponding
number of nonperiodic templates for that file be stored in the m-th
position in the numOfTemplates variable.
----------------------------------------------------------------------------*/
unsigned int W_obs, nu[6], *Wj = NULL;
size_t template_idx = 0;
double sum, chi2, p_value, lambda, pi[6], varWj;
int i, j, jj, k, match, SKIP, M, N, K = 5;
BitSequence *sequence = NULL;
N = 8;
M = n/N;
if ( (Wj = (unsigned int*)calloc(N, sizeof(unsigned int))) == NULL ) {
return 0;
}
lambda = (M-m+1)/pow(2, m);
varWj = M*(1.0/pow(2.0, m) - (2.0*m-1.0)/pow(2.0, 2.0*m));
if ( ((isNegative(lambda)) || (isZero(lambda))) ||
((sequence = (BitSequence *) calloc(m, sizeof(BitSequence))) == NULL) ) {
goto end;
}
else {
if ( numOfTemplates[m] < MAXNUMOFTEMPLATES )
SKIP = 1;
else
SKIP = (int)(numOfTemplates[m]/MAXNUMOFTEMPLATES);
numOfTemplates[m] = (int)numOfTemplates[m]/SKIP;
sum = 0.0;
for ( i=0; i<2; i++ ) { /* Compute Probabilities */
pi[i] = exp(-lambda+i*log(lambda)-cephes_lgam(i+1));
sum += pi[i];
}
pi[0] = sum;
for ( i=2; i<=K; i++ ) { /* Compute Probabilities */
pi[i-1] = exp(-lambda+i*log(lambda)-cephes_lgam(i+1));
sum += pi[i-1];
}
pi[K] = 1 - sum;
for( jj=0; jj<MIN(MAXNUMOFTEMPLATES, numOfTemplates[m]); jj++ ) {
sum = 0;
for ( k=0; k<m; k++ ) {
if (template_idx < template_size) {
sequence[k] = template9[template_idx];
template_idx++;
}
else {
sequence[k] = 0;
}
// fprintf(stats[TEST_NONPERIODIC], "%d", sequence[k]);
}
// fprintf(stats[TEST_NONPERIODIC], " ");
for ( k=0; k<=K; k++ )
nu[k] = 0;
for ( i=0; i<N; i++ ) {
W_obs = 0;
for ( j=0; j<M-m+1; j++ ) {
match = 1;
for ( k=0; k<m; k++ ) {
if ( (int)sequence[k] != (int)epsilon[i*M+j+k] ) {
match = 0;
break;
}
}
if ( match == 1 )
W_obs++;
}
Wj[i] = W_obs;
}
sum = 0;
chi2 = 0.0; /* Compute Chi Square */
for ( i=0; i<N; i++ ) {
// if ( m == 10 )
// fprintf(stats[TEST_NONPERIODIC], "%3d ", Wj[i]);
// else
// fprintf(stats[TEST_NONPERIODIC], "%4d ", Wj[i]);
chi2 += pow(((double)Wj[i] - lambda)/pow(varWj, 0.5), 2);
}
p_value = cephes_igamc(N/2.0, chi2/2.0);
if ( isNegative(p_value) || isGreaterThanOne(p_value) ) {
// fprintf(stats[TEST_NONPERIODIC], "\t\tWARNING: P_VALUE IS OUT OF RANGE.\n");
goto end;
}
// fprintf(stats[TEST_NONPERIODIC], "%9.6f %f %s %3d\n", chi2, p_value, p_value < ALPHA ? "FAILURE" : "SUCCESS", jj);
if ( SKIP > 1 )
template_idx += (SKIP-1)*2*m;
// fprintf(results[TEST_NONPERIODIC], "%f\n", p_value); fflush(results[TEST_NONPERIODIC]);
if (p_value < ALPHA) {
goto end;
}
}
}
ret = 1;
// fprintf(stats[TEST_NONPERIODIC], "\n"); fflush(stats[TEST_NONPERIODIC]);
end:
if (Wj != NULL) {
free(Wj);
}
if (sequence != NULL) {
free(sequence);
}
return ret;
}

View File

@@ -0,0 +1,97 @@
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include "include/externs.h"
#include "include/cephes.h"
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
O V E R L A P P I N G T E M P L A T E T E S T
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
double Pr(int u, double eta);
int
OverlappingTemplateMatchings(int m, int n, BitSequence *epsilon)
{
int ret = 0;
int i, k, match;
double W_obs, eta, sum, chi2, p_value, lambda;
int M, N, j, K = 5;
unsigned int nu[6] = { 0, 0, 0, 0, 0, 0 };
double pi[6] = { 0.143783, 0.139430, 0.137319, 0.124314, 0.106209, 0.348945 };
BitSequence *sequence;
M = 1032;
N = n/M;
if ( (sequence = (BitSequence *) calloc(m, sizeof(BitSequence))) == NULL ) {
return 0;
}
else {
for (i = 0; i < m; i++)
sequence[i] = 1;
}
lambda = (double)(M-m+1)/pow(2,m);
eta = lambda/2.0;
sum = 0.0;
for ( i=0; i<K; i++ ) { /* Compute Probabilities */
pi[i] = Pr(i, eta);
sum += pi[i];
}
pi[K] = 1 - sum;
for ( i=0; i<N; i++ ) {
W_obs = 0;
for ( j=0; j<M-m+1; j++ ) {
match = 1;
for ( k=0; k<m; k++ ) {
if ( sequence[k] != epsilon[i*M+j+k] )
match = 0;
}
if ( match == 1 )
W_obs++;
}
if ( W_obs <= 4 )
nu[(int)W_obs]++;
else
nu[K]++;
}
sum = 0;
chi2 = 0.0; /* Compute Chi Square */
for ( i=0; i<K+1; i++ ) {
chi2 += pow((double)nu[i] - (double)N*pi[i], 2)/((double)N*pi[i]);
sum += nu[i];
}
p_value = cephes_igamc(K/2.0, chi2/2.0);
if ( isNegative(p_value) || isGreaterThanOne(p_value) ) {
goto end;
}
if (p_value < ALPHA) {
goto end;
}
ret = 1;
end:
free(sequence);
return ret;
}
double
Pr(int u, double eta)
{
int l;
double sum, p;
if ( u == 0 )
p = exp(-eta);
else {
sum = 0.0;
for ( l=1; l<=u; l++ )
sum += exp(-eta-u*log(2)+l*log(eta)-cephes_lgam(l+1)+cephes_lgam(u)-cephes_lgam(l)-cephes_lgam(u-l+1));
p = sum;
}
return p;
}

View File

@@ -0,0 +1,79 @@
#include <stdlib.h>
#include <math.h>
#include "include/stat_fncs.h"
#include "include/cephes.h"
typedef struct _PokerNi {
unsigned int flag;
unsigned int count;
} PokerNi;
unsigned char toByte(BitSequence *subEpsilon, int M)
{
int i = 0;
unsigned char result = 0;
for (i = 0; i < M; ++i) {
result |= (subEpsilon[i] << (M - i - 1));
}
return result;
}
int findIndex(PokerNi *tab, int tabSize, unsigned int flag)
{
int i = 0;
for (i = 0; i < tabSize; ++i) {
if (tab[i].flag == flag) {
return i;
}
}
return -1;
}
int PokerDetect(int M, int n, BitSequence *epsilon)
{
int ret = 0;
int i = 0, j = 0, N = n / M, index = 0, c = 0;
int maxElements = (int) pow(2, M);
double p_value = 0.0, sum_ni = 0.0, mp = 0.0, V = 0.0;
unsigned int flag = 0;
PokerNi *tab = NULL;
if (M > 8) {
return 0;
}
tab = (PokerNi *)calloc(maxElements, sizeof(PokerNi));
if (NULL == tab) {
return 0;
}
for (i = 0; i < maxElements; ++i) {
tab[i].flag = (unsigned int) i;
tab[i].count = 0;
}
for (i = 0, j = 0; j < N; ++j, i += M) {
flag = toByte(epsilon + i, M);
index = findIndex(tab, maxElements, flag);
if (-1 == index) {
goto end;
}
tab[index].count += 1;
}
for (i = 0; i < maxElements; ++i) {
sum_ni += pow(tab[i].count, 2);
}
mp = (double)maxElements / N;
V = mp * sum_ni - N;
p_value = cephes_igamc((double)(maxElements - 1) / 2, V / 2);
if (p_value < ALPHA) {
goto end;
}
ret = 1;
end:
free(tab);
return ret;
}

View File

@@ -0,0 +1,116 @@
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include "include/externs.h"
#include "include/cephes.h"
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
R A N D O M E X C U R S I O N S T E S T
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
int
RandomExcursions(int n, BitSequence *epsilon)
{
int ret = 0;
int b, i, j, k, J, x;
int cycleStart, cycleStop, *cycle = NULL, *S_k = NULL;
const int stateX[8] = { -4, -3, -2, -1, 1, 2, 3, 4 };
int counter[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
double p_value, sum, constraint, nu[6][8];
double pi[5][6] = { {0.0000000000, 0.00000000000, 0.00000000000, 0.00000000000, 0.00000000000, 0.0000000000},
{0.5000000000, 0.25000000000, 0.12500000000, 0.06250000000, 0.03125000000, 0.0312500000},
{0.7500000000, 0.06250000000, 0.04687500000, 0.03515625000, 0.02636718750, 0.0791015625},
{0.8333333333, 0.02777777778, 0.02314814815, 0.01929012346, 0.01607510288, 0.0803755143},
{0.8750000000, 0.01562500000, 0.01367187500, 0.01196289063, 0.01046752930, 0.0732727051} };
if ( ((S_k = (int *)calloc(n, sizeof(int))) == NULL) ||
((cycle = (int *)calloc(MAX(1000, n/100), sizeof(int))) == NULL) ) {
printf("Random Excursions Test: Insufficent Work Space Allocated.\n");
if ( S_k != NULL )
free(S_k);
if ( cycle != NULL )
free(cycle);
return 0;
}
J = 0; /* DETERMINE CYCLES */
S_k[0] = 2*(int)epsilon[0] - 1;
for( i=1; i<n; i++ ) {
S_k[i] = S_k[i-1] + 2*epsilon[i] - 1;
if ( S_k[i] == 0 ) {
J++;
if ( J > MAX(1000, n/100) ) {
printf("ERROR IN FUNCTION randomExcursions: EXCEEDING THE MAX NUMBER OF CYCLES EXPECTED\n.");
goto end;
}
cycle[J] = i;
}
}
if ( S_k[n-1] != 0 )
J++;
cycle[J] = n;
constraint = MAX(0.005*pow(n, 0.5), 500);
if (J < constraint) {
ret = 1; //TODO
goto end;
}
else {
cycleStart = 0;
cycleStop = cycle[1];
for ( k=0; k<6; k++ )
for ( i=0; i<8; i++ )
nu[k][i] = 0.;
for ( j=1; j<=J; j++ ) { /* FOR EACH CYCLE */
for ( i=0; i<8; i++ )
counter[i] = 0;
for ( i=cycleStart; i<cycleStop; i++ ) {
if ( (S_k[i] >= 1 && S_k[i] <= 4) || (S_k[i] >= -4 && S_k[i] <= -1) ) {
if ( S_k[i] < 0 )
b = 4;
else
b = 3;
counter[S_k[i]+b]++;
}
}
cycleStart = cycle[j]+1;
if ( j < J )
cycleStop = cycle[j+1];
for ( i=0; i<8; i++ ) {
if ( (counter[i] >= 0) && (counter[i] <= 4) )
nu[counter[i]][i]++;
else if ( counter[i] >= 5 )
nu[5][i]++;
}
}
for ( i=0; i<8; i++ ) {
x = stateX[i];
sum = 0.;
for ( k=0; k<6; k++ )
sum += pow(nu[k][i] - J*pi[(int)fabs(x)][k], 2) / (J*pi[(int)fabs(x)][k]);
p_value = cephes_igamc(2.5, sum/2.0);
if ( isNegative(p_value) || isGreaterThanOne(p_value) ) {
// fprintf(stats[TEST_RND_EXCURSION], "WARNING: P_VALUE IS OUT OF RANGE.\n");
goto end;
}
// fprintf(stats[TEST_RND_EXCURSION], "%s\t\tx = %2d chi^2 = %9.6f p_value = %f\n",
// p_value < ALPHA ? "FAILURE" : "SUCCESS", x, sum, p_value);
// fprintf(results[TEST_RND_EXCURSION], "%f\n", p_value); fflush(results[TEST_RND_EXCURSION]);
if (p_value < ALPHA) {
goto end;
}
}
}
// fprintf(stats[TEST_RND_EXCURSION], "\n"); fflush(stats[TEST_RND_EXCURSION]);
ret = 1;
end:
free(S_k);
free(cycle);
return ret;
}

View File

@@ -0,0 +1,61 @@
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include "include/externs.h"
#include "include/cephes.h"
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
R A N D O M E X C U R S I O N S V A R I A N T T E S T
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
int
RandomExcursionsVariant(int n, BitSequence *epsilon)
{
int ret = 0;
int i, p, J, x, constraint, count, *S_k = NULL;
const int stateX[18] = { -9, -8, -7, -6, -5, -4, -3, -2, -1, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
double p_value;
if ( (S_k = (int *)calloc(n, sizeof(int))) == NULL ) {
return 0;
}
J = 0;
S_k[0] = 2*(int)epsilon[0] - 1;
for ( i=1; i<n; i++ ) {
S_k[i] = S_k[i-1] + 2*epsilon[i] - 1;
if ( S_k[i] == 0 )
J++;
}
if ( S_k[n-1] != 0 )
J++;
constraint = (int)MAX(0.005*pow(n, 0.5), 500);
if (J < constraint) {
ret = 1; //TODO
goto end;
}
else {
for ( p=0; p<=17; p++ ) {
x = stateX[p];
count = 0;
for ( i=0; i<n; i++ )
if ( S_k[i] == x )
count++;
p_value = erfc(fabs(count-J)/(sqrt(2.0*J*(4.0*fabs(x)-2))));
if ( isNegative(p_value) || isGreaterThanOne(p_value) ) {
goto end;
}
if (p_value < ALPHA) {
goto end;
}
}
}
ret = 1;
end:
free(S_k);
return ret;
}

View File

@@ -0,0 +1,76 @@
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include "include/externs.h"
#include "include/cephes.h"
#include "include/matrix.h"
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
R A N K T E S T
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
int
Rank(int n, BitSequence *epsilon)
{
int ret = 0;
int N, i, k, r;
double p_value, product, chi_squared, arg1, p_32, p_31, p_30, R, F_32, F_31, F_30;
BitSequence **matrix = create_matrix(32, 32);
N = n/(32*32);
if ( isZero(N) ) {
p_value = 0.00;
}
else {
r = 32; /* COMPUTE PROBABILITIES */
product = 1;
for ( i=0; i<=r-1; i++ )
product *= ((1.e0-pow(2, i-32))*(1.e0-pow(2, i-32)))/(1.e0-pow(2, i-r));
p_32 = pow(2, r*(32+32-r)-32*32) * product;
r = 31;
product = 1;
for ( i=0; i<=r-1; i++ )
product *= ((1.e0-pow(2, i-32))*(1.e0-pow(2, i-32)))/(1.e0-pow(2, i-r));
p_31 = pow(2, r*(32+32-r)-32*32) * product;
p_30 = 1 - (p_32+p_31);
F_32 = 0;
F_31 = 0;
for ( k=0; k<N; k++ ) { /* FOR EACH 32x32 MATRIX */
def_matrix(32, 32, matrix, k, epsilon);
#if (DISPLAY_MATRICES == 1)
display_matrix(32, 32, matrix);
#endif
R = computeRank(32, 32, matrix);
if ( R == 32 )
F_32++; /* DETERMINE FREQUENCIES */
if ( R == 31 )
F_31++;
}
F_30 = (double)N - (F_32+F_31);
chi_squared =(pow(F_32 - N*p_32, 2)/(double)(N*p_32) +
pow(F_31 - N*p_31, 2)/(double)(N*p_31) +
pow(F_30 - N*p_30, 2)/(double)(N*p_30));
arg1 = -chi_squared/2.e0;
p_value = exp(arg1);
if ( isNegative(p_value) || isGreaterThanOne(p_value) ) {
goto end;
}
}
if (p_value < ALPHA) {
goto end;
}
ret = 1;
end:
delete_matrix(32, matrix);
return ret;
}

View File

@@ -0,0 +1,46 @@
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include "include/externs.h"
#include "include/cephes.h"
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
R U N S T E S T
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
int
Runs(int n, BitSequence *epsilon)
{
int S, k;
double pi, V, erfc_arg, p_value;
S = 0;
for ( k=0; k<n; k++ )
if ( epsilon[k] )
S++;
pi = (double)S / (double)n;
if ( fabs(pi - 0.5) > (2.0 / sqrt(n)) ) {
p_value = 0.0;
}
else {
V = 1;
for ( k=1; k<n; k++ )
if ( epsilon[k] != epsilon[k-1] )
V++;
erfc_arg = fabs(V - 2.0 * n * pi * (1-pi)) / (2.0 * pi * (1-pi) * sqrt(2*n));
p_value = erfc(erfc_arg);
if ( isNegative(p_value) || isGreaterThanOne(p_value) ) {
return 0;
}
}
if (p_value < ALPHA) {
return 0;
} else {
return 1;
}
}

View File

@@ -0,0 +1,82 @@
#include <stdlib.h>
#include <math.h>
#include "include/stat_fncs.h"
#include "include/cephes.h"
int RunsDistribution(int n, BitSequence *epsilon)
{
int ret = 0;
int i = 0, j = 0, k = 0;
unsigned char runFlag = 0x00;
double p_value = 0.0, sum_bi = 0.0, sum_gi = 0.0, V = 0.0;
double *bi = NULL, *gi = NULL, *e = NULL;
double bit = 0.0, git = 0.0, et = 0.0;
bi = (double *)calloc(n, sizeof(double));
if (NULL == bi) {
goto end;
}
gi = (double *)calloc(n, sizeof(double));
if (NULL == gi) {
goto end;
}
e = (double *)calloc(n, sizeof(double));
if (NULL == e) {
goto end;
}
for (i = 1; i <= n; ++i) {
e[i - 1] = (double)(n - i + 3) / pow(2, i + 2);
if (e[i - 1] >= 5) {
k = i;
}
}
runFlag = epsilon[0];
j = 1;
for (i = 1; i < n; ++i) {
if (epsilon[i] != runFlag) {
if (runFlag == 0x00) {
gi[j - 1] += 1;
} else if (runFlag == 0x01) {
bi[j - 1] += 1;
}
runFlag = epsilon[i];
j = 1;
} else {
++j;
}
}
for (i = 0; i < k; ++i) {
bit = bi[i];
et = e[i];
sum_bi += pow(bit - et, 2) / et;
}
for (i = 0; i < k; ++i) {
git = gi[i];
et = e[i];
sum_gi += pow(git - et, 2) / et;
}
V = sum_bi + sum_gi;
p_value = cephes_igamc(k - 1, V / 2);
if (p_value < ALPHA) {
goto end;
}
ret = 1;
end:
if (NULL != bi) {
free(bi);
}
if (NULL != gi) {
free(gi);
}
if (NULL != e) {
free(e);
}
return ret;
}

View File

@@ -0,0 +1,25 @@
#include <math.h>
#include "include/stat_fncs.h"
int SelfCorrelation(int d, int n, BitSequence *epsilon)
{
int i = 0;
int n_d = n - d;
int Ad = 0;
double V = 0.0, p_value = 0.0, sqrt2 = 1.41421356237309504880;
for (i = 0; i < n_d - 1; ++i) {
Ad += (epsilon[i] ^ epsilon[i + d]);
}
V = 2 * ((double)Ad - ((double)n_d / 2)) / sqrt(n_d);
p_value = erfc(fabs(V) / sqrt2);
if (p_value < ALPHA) {
return 0;
} else {
return 1;
}
}

View File

@@ -0,0 +1,65 @@
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include "include/externs.h"
#include "include/cephes.h"
double psi2(int m, int n, BitSequence *epsilon);
int
Serial(int m, int n, BitSequence *epsilon)
{
double p_value1, p_value2, psim0, psim1, psim2, del1, del2;
psim0 = psi2(m, n, epsilon);
psim1 = psi2(m - 1, n, epsilon);
psim2 = psi2(m - 2, n, epsilon);
del1 = psim0 - psim1;
del2 = psim0 - 2.0*psim1 + psim2;
p_value1 = cephes_igamc(pow(2, m-1)/2, del1/2.0);
p_value2 = cephes_igamc(pow(2, m-2)/2, del2/2.0);
if (p_value1 < ALPHA || p_value2 < ALPHA) {
return 0;
} else {
return 1;
}
}
double
psi2(int m, int n, BitSequence *epsilon)
{
int i, j, k, powLen;
double sum, numOfBlocks;
unsigned int *P;
if ( (m == 0) || (m == -1) )
return 0.0;
numOfBlocks = n;
powLen = (int)pow(2, m+1)-1;
if ( (P = (unsigned int*)calloc(powLen,sizeof(unsigned int)))== NULL ) {
// fprintf(stats[TEST_SERIAL], "Serial Test: Insufficient memory available.\n");
// fflush(stats[TEST_SERIAL]);
return 0.0;
}
for ( i=1; i<powLen-1; i++ )
P[i] = 0; /* INITIALIZE NODES */
for ( i=0; i<numOfBlocks; i++ ) { /* COMPUTE FREQUENCY */
k = 1;
for ( j=0; j<m; j++ ) {
if ( epsilon[(i+j)%n] == 0 )
k *= 2;
else if ( epsilon[(i+j)%n] == 1 )
k = 2*k+1;
}
P[k-1]++;
}
sum = 0.0;
for ( i=(int)pow(2, m)-1; i<(int)pow(2, m+1)-1; i++ )
sum += pow(P[i], 2);
sum = (sum * pow(2, m)/(double)n) - (double)n;
free(P);
return sum;
}

View File

@@ -0,0 +1,88 @@
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include "include/externs.h"
#include "include/cephes.h"
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
U N I V E R S A L T E S T
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
int
Universal(int n, BitSequence *epsilon)
{
int ret = 0;
int i, j, p, L, Q, K;
double arg, sqrt2, sigma, phi, sum, p_value, c;
long *T, decRep;
const double expected_value[17] = { 0, 0, 0, 0, 0, 0, 5.2177052, 6.1962507, 7.1836656,
8.1764248, 9.1723243, 10.170032, 11.168765,
12.168070, 13.167693, 14.167488, 15.167379 };
const double variance[17] = { 0, 0, 0, 0, 0, 0, 2.954, 3.125, 3.238, 3.311, 3.356, 3.384,
3.401, 3.410, 3.416, 3.419, 3.421 };
/* * * * * * * * * ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* THE FOLLOWING REDEFINES L, SHOULD THE CONDITION: n >= 1010*2^L*L *
* NOT BE MET, FOR THE BLOCK LENGTH L. *
* * * * * * * * * * ** * * * * * * * * * * * * * * * * * * * * * * * * * * * */
L = 5;
if ( n >= 387840 ) L = 6;
if ( n >= 904960 ) L = 7;
if ( n >= 2068480 ) L = 8;
if ( n >= 4654080 ) L = 9;
if ( n >= 10342400 ) L = 10;
if ( n >= 22753280 ) L = 11;
if ( n >= 49643520 ) L = 12;
if ( n >= 107560960 ) L = 13;
if ( n >= 231669760 ) L = 14;
if ( n >= 496435200 ) L = 15;
if ( n >= 1059061760 ) L = 16;
Q = 10*(int)pow(2, L);
K = (int) (floor(n/L) - (double)Q); /* BLOCKS TO TEST */
p = (int)pow(2, L);
if ( (L < 6) || (L > 16) || ((double)Q < 10*pow(2, L)) ||
((T = (long *)calloc(p, sizeof(long))) == NULL) ) {
return 0;
}
/* COMPUTE THE EXPECTED: Formula 16, in Marsaglia's Paper */
c = 0.7 - 0.8/(double)L + (4 + 32/(double)L)*pow(K, -3/(double)L)/15;
sigma = c * sqrt(variance[L]/(double)K);
sqrt2 = sqrt(2);
sum = 0.0;
for ( i=0; i<p; i++ )
T[i] = 0;
for ( i=1; i<=Q; i++ ) { /* INITIALIZE TABLE */
decRep = 0;
for ( j=0; j<L; j++ )
decRep += epsilon[(i-1)*L+j] * (long)pow(2, L-1-j);
T[decRep] = i;
}
for ( i=Q+1; i<=Q+K; i++ ) { /* PROCESS BLOCKS */
decRep = 0;
for ( j=0; j<L; j++ )
decRep += epsilon[(i-1)*L+j] * (long)pow(2, L-1-j);
sum += log(i - T[decRep])/log(2);
T[decRep] = i;
}
phi = (double)(sum/(double)K);
arg = fabs(phi-expected_value[L])/(sqrt2 * sigma);
p_value = erfc(arg);
if ( isNegative(p_value) || isGreaterThanOne(p_value) ) {
goto end;
}
if (p_value < ALPHA) {
goto end;
}
ret = 1;
end:
free(T);
return ret;
}

View File

@@ -0,0 +1,45 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
U T I L I T I E S
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#include "include/utilities.h"
int
convertToBits(BYTE *x, int xBitLength, int bitsNeeded, int *num_0s, int *num_1s, int *bitsRead, BitSequence* epsilon)
{
int i, j, count, bit;
BYTE mask;
int zeros, ones;
count = 0;
zeros = ones = 0;
for ( i=0; i<(xBitLength+7)/8; i++ ) {
mask = 0x80;
for ( j=0; j<8; j++ ) {
if ( *(x+i) & mask ) {
bit = 1;
(*num_1s)++;
ones++;
}
else {
bit = 0;
(*num_0s)++;
zeros++;
}
mask >>= 1;
epsilon[*bitsRead] = bit;
(*bitsRead)++;
if ( *bitsRead == bitsNeeded )
return 1;
if ( ++count == xBitLength )
return 0;
}
}
return 0;
}

View File

@@ -0,0 +1,6 @@
{
global:
statistical_test_suite;
GIT_VERSION*;
local: *;
};

View File

@@ -0,0 +1,6 @@
cmake_minimum_required (VERSION 3.5)
add_executable(gtest_mesa gtest_mesa_sts.cpp)
target_link_libraries(gtest_mesa gtest pcap pthread libmesa_sts)
file(COPY pcap DESTINATION ./)

View File

@@ -0,0 +1,256 @@
#include <netinet/ip6.h>
#include <netinet/ip.h>
#include <netinet/if_ether.h>
#include <netinet/tcp.h>
#include <netinet/udp.h>
#include <pcap/pcap.h>
#include "gtest/gtest.h"
#include "mesa_sts.h"
#define MAX_PKT_CNT 1
static int read_pcap_and_judge_randomness(const char* pcap_file, struct sts_result* result)
{
pcap_t *handle;
struct pcap_pkthdr *header; // pcap报文头部结构
const u_char *packet; // 报文数据指针
char errbuf[PCAP_ERRBUF_SIZE];
char content[2048] = {0};
int content_len = 0;
int payload_len;
char *payload;
int pkt_cnt = 0;
handle = pcap_open_offline(pcap_file, errbuf);
while (pcap_next_ex(handle, &header, &packet) > 0) {
unsigned short eth_type = ntohs(*(unsigned short *)(packet + 12));
if (eth_type == ETH_P_IP) {
int l4_proto = *(unsigned char *)(packet + sizeof(struct ethhdr) + 9);
if (l4_proto == IPPROTO_TCP) {
int tcp_header_len = (*(unsigned char *)(packet + sizeof(struct ethhdr) + sizeof(struct iphdr) + 12) & 0xf0) >> 2;
payload_len = header->caplen - sizeof(struct ethhdr) - sizeof(struct iphdr) - tcp_header_len;
payload = (char *)packet + sizeof(struct ethhdr) + sizeof(struct iphdr) + tcp_header_len;
} else if (l4_proto == IPPROTO_UDP) {
payload_len = header->caplen - sizeof(struct ethhdr) - sizeof(struct iphdr) - sizeof(struct udphdr);
payload = (char *)packet + sizeof(struct ethhdr) + sizeof(struct iphdr) + sizeof(struct udphdr);
} else {
continue;
}
} else if (eth_type == ETH_P_IPV6) {
int l4_proto = *(unsigned char *)(packet + sizeof(struct ethhdr) + 6);
if (l4_proto == IPPROTO_TCP) {
int tcp_header_len = (*(unsigned char *)(packet + sizeof(struct ethhdr) + sizeof(struct ip6_hdr) + 12) & 0xf0) >> 2;
payload_len = header->caplen - sizeof(struct ethhdr) - sizeof(struct ip6_hdr) - tcp_header_len;
payload = (char *)packet + sizeof(struct ethhdr) + sizeof(struct ip6_hdr) + tcp_header_len;
} else if (l4_proto == IPPROTO_UDP) {
payload_len = header->caplen - sizeof(struct ethhdr) - sizeof(struct ip6_hdr) - sizeof(struct udphdr);
payload = (char *)packet + sizeof(struct ethhdr) + sizeof(struct ip6_hdr) + sizeof(struct udphdr);
} else {
continue;
}
}
if (payload_len < 100) {
continue;
}
memcpy(content + content_len, payload, payload_len);
content_len += payload_len;
pkt_cnt++;
if (pkt_cnt == MAX_PKT_CNT) {
break;
}
}
mesa_statistical_test_suite(content, content_len, result, 0xffffffff);
pcap_close(handle);
return 0;
}
TEST(random_looking, telegram_mtproto_ipv4_key1)
{
struct sts_result result;
read_pcap_and_judge_randomness("pcap/telegram_mtproto_ipv4_key_1.pcap", &result);
EXPECT_EQ(result.frequency, 1);
EXPECT_EQ(result.block_frequency, 1);
EXPECT_EQ(result.cumulative_sums, 1);
EXPECT_EQ(result.runs, 1);
EXPECT_EQ(result.longest_run, 1);
EXPECT_EQ(result.rank, 0);
EXPECT_EQ(result.non_overlapping_template_matching, 0);
EXPECT_EQ(result.overlapping_template_matching, 1);
EXPECT_EQ(result.universal, 0);
EXPECT_EQ(result.random_excursions, 1);
EXPECT_EQ(result.random_excursions_variant, 1);
EXPECT_EQ(result.poker_detect, 1);
EXPECT_EQ(result.runs_distribution, 1);
EXPECT_EQ(result.self_correlation, 1);
EXPECT_EQ(result.binary_derivative, 1);
}
TEST(random_looking, telegram_mtproto_ipv4_key2)
{
struct sts_result result;
read_pcap_and_judge_randomness("pcap/telegram_mtproto_ipv4_key_2_dd.pcap", &result);
EXPECT_EQ(result.frequency, 1);
EXPECT_EQ(result.block_frequency, 1);
EXPECT_EQ(result.cumulative_sums, 1);
EXPECT_EQ(result.runs, 1);
EXPECT_EQ(result.longest_run, 1);
EXPECT_EQ(result.rank, 0);
EXPECT_EQ(result.non_overlapping_template_matching, 0);
EXPECT_EQ(result.overlapping_template_matching, 1);
EXPECT_EQ(result.universal, 0);
EXPECT_EQ(result.random_excursions, 1);
EXPECT_EQ(result.random_excursions_variant, 1);
EXPECT_EQ(result.poker_detect, 1);
EXPECT_EQ(result.runs_distribution, 1);
EXPECT_EQ(result.self_correlation, 1);
EXPECT_EQ(result.binary_derivative, 1);
}
TEST(random_looking, telegram_mtproto_ipv4_key3)
{
struct sts_result result;
read_pcap_and_judge_randomness("pcap/telegram_mtproto_ipv4_key_3_ee.pcap", &result);
EXPECT_EQ(result.frequency, 1);
EXPECT_EQ(result.block_frequency, 0);
EXPECT_EQ(result.cumulative_sums, 1);
EXPECT_EQ(result.runs, 0);
EXPECT_EQ(result.longest_run, 1);
EXPECT_EQ(result.rank, 0);
EXPECT_EQ(result.non_overlapping_template_matching, 0);
EXPECT_EQ(result.overlapping_template_matching, 1);
EXPECT_EQ(result.universal, 0);
EXPECT_EQ(result.random_excursions, 1);
EXPECT_EQ(result.random_excursions_variant, 1);
EXPECT_EQ(result.poker_detect, 0);
EXPECT_EQ(result.runs_distribution, 1);
EXPECT_EQ(result.self_correlation, 1);
EXPECT_EQ(result.binary_derivative, 1);
}
TEST(random_looking, telegram_mtproto_ipv6_key1)
{
struct sts_result result;
read_pcap_and_judge_randomness("pcap/telegram_mtproto_ipv6_key_1.pcap", &result);
EXPECT_EQ(result.frequency, 1);
EXPECT_EQ(result.block_frequency, 1);
EXPECT_EQ(result.cumulative_sums, 1);
EXPECT_EQ(result.runs, 1);
EXPECT_EQ(result.longest_run, 1);
EXPECT_EQ(result.rank, 0);
EXPECT_EQ(result.non_overlapping_template_matching, 0);
EXPECT_EQ(result.overlapping_template_matching, 1);
EXPECT_EQ(result.universal, 0);
EXPECT_EQ(result.random_excursions, 1);
EXPECT_EQ(result.random_excursions_variant, 1);
EXPECT_EQ(result.poker_detect, 1);
EXPECT_EQ(result.runs_distribution, 1);
EXPECT_EQ(result.self_correlation, 1);
EXPECT_EQ(result.binary_derivative, 1);
}
TEST(random_looking, telegram_mtproto_ipv6_key2)
{
struct sts_result result;
read_pcap_and_judge_randomness("pcap/telegram_mtproto_ipv6_key_2_dd.pcap", &result);
EXPECT_EQ(result.frequency, 1);
EXPECT_EQ(result.block_frequency, 1);
EXPECT_EQ(result.cumulative_sums, 1);
EXPECT_EQ(result.runs, 1);
EXPECT_EQ(result.longest_run, 1);
EXPECT_EQ(result.rank, 0);
EXPECT_EQ(result.non_overlapping_template_matching, 0);
EXPECT_EQ(result.overlapping_template_matching, 1);
EXPECT_EQ(result.universal, 0);
EXPECT_EQ(result.random_excursions, 1);
EXPECT_EQ(result.random_excursions_variant, 1);
EXPECT_EQ(result.poker_detect, 1);
EXPECT_EQ(result.runs_distribution, 1);
EXPECT_EQ(result.self_correlation, 1);
EXPECT_EQ(result.binary_derivative, 1);
}
TEST(random_looking, telegram_mtproto_ipv6_key3)
{
struct sts_result result;
read_pcap_and_judge_randomness("pcap/telegram_mtproto_ipv6_key_3_ee.pcap", &result);
EXPECT_EQ(result.frequency, 1);
EXPECT_EQ(result.block_frequency, 0);
EXPECT_EQ(result.cumulative_sums, 1);
EXPECT_EQ(result.runs, 1);
EXPECT_EQ(result.longest_run, 1);
EXPECT_EQ(result.rank, 0);
EXPECT_EQ(result.non_overlapping_template_matching, 0);
EXPECT_EQ(result.overlapping_template_matching, 1);
EXPECT_EQ(result.universal, 0);
EXPECT_EQ(result.random_excursions, 1);
EXPECT_EQ(result.random_excursions_variant, 1);
EXPECT_EQ(result.poker_detect, 0);
EXPECT_EQ(result.runs_distribution, 1);
EXPECT_EQ(result.self_correlation, 1);
EXPECT_EQ(result.binary_derivative, 1);
}
TEST(non_random_looking, wechat_voice_call)
{
struct sts_result result;
read_pcap_and_judge_randomness("pcap/202202161604_win_wifi_30M_pure_wechat_wechat3.5.0.46_voice-call_120s_2_multinat.pcap", &result);
EXPECT_EQ(result.frequency, 0);
EXPECT_EQ(result.block_frequency, 1);
EXPECT_EQ(result.cumulative_sums, 0);
EXPECT_EQ(result.runs, 0);
EXPECT_EQ(result.longest_run, 0);
EXPECT_EQ(result.rank, 0);
EXPECT_EQ(result.non_overlapping_template_matching, 0);
EXPECT_EQ(result.overlapping_template_matching, 1);
EXPECT_EQ(result.universal, 0);
EXPECT_EQ(result.random_excursions, 1);
EXPECT_EQ(result.random_excursions_variant, 1);
EXPECT_EQ(result.poker_detect, 1);
EXPECT_EQ(result.runs_distribution, 0);
EXPECT_EQ(result.self_correlation, 0);
EXPECT_EQ(result.binary_derivative, 1);
}
TEST(non_random_looking, http)
{
struct sts_result result;
read_pcap_and_judge_randomness("pcap/xingongsuo_kouling_http_C2S.pcap", &result);
EXPECT_EQ(result.frequency, 0);
EXPECT_EQ(result.block_frequency, 0);
EXPECT_EQ(result.cumulative_sums, 0);
EXPECT_EQ(result.runs, 1);
EXPECT_EQ(result.longest_run, 0);
EXPECT_EQ(result.rank, 1);
EXPECT_EQ(result.non_overlapping_template_matching, 0);
EXPECT_EQ(result.overlapping_template_matching, 1);
EXPECT_EQ(result.universal, 0);
EXPECT_EQ(result.random_excursions, 1);
EXPECT_EQ(result.random_excursions_variant, 1);
EXPECT_EQ(result.poker_detect, 0);
EXPECT_EQ(result.runs_distribution, 0);
EXPECT_EQ(result.self_correlation, 0);
EXPECT_EQ(result.binary_derivative, 1);
}
int main(int argc, char **argv)
{
testing::InitGoogleTest(&argc, argv);
//testing::GTEST_FLAG(filter) = "random_looking.telegram_mtproto_ipv6_key1";
return RUN_ALL_TESTS();
}

View File

@@ -0,0 +1,37 @@
#include <math.h>
#include "onlinemean.h"
void OnlineMean_Init(OnlineMean_t *oMean) {
OnlineMean_Reset(oMean);
}
void OnlineMean_Update(OnlineMean_t *oMean, float newValue) {
oMean->count++;
if (oMean->count > 1) {
float delta = newValue - oMean->mean;
oMean->mean += delta / oMean->count;
oMean->varsum += delta * (newValue - oMean->mean);
} else {
oMean->mean = newValue;
}
}
float OnlineMean_GetMean(OnlineMean_t *oMean) {
return oMean->mean;
}
float OnlineMean_GetStd(OnlineMean_t *oMean) {
if (oMean->count == 0)
return 0;
#if UNBIASED_ESTIMATOR
return sqrt(oMean->varsum / (oMean->count - 1));
#else
return sqrt(oMean->varsum / oMean->count);
#endif /* UNBIASED_ESTIMATOR */
}
void OnlineMean_Reset(OnlineMean_t *oMean) {
oMean->count = 0;
oMean->mean = 0.f;
oMean->varsum = 0.f;
}

View File

@@ -0,0 +1,30 @@
#ifndef ONLINEMEAN_H_
#define ONLINEMEAN_H_
#ifdef __cplusplus
extern "C" {
#endif
/* Set to 1 to return unbiased (sample) variance
* rather than a population variance */
#define UNBIASED_ESTIMATOR 0
#include <stdint.h>
typedef struct OnlineMean {
float mean;
float varsum; // variance sum
uint32_t count;
} OnlineMean_t;
void OnlineMean_Init(OnlineMean_t *oMean);
void OnlineMean_Update(OnlineMean_t *oMean, float newValue);
float OnlineMean_GetMean(OnlineMean_t *oMean);
float OnlineMean_GetStd(OnlineMean_t *oMean);
void OnlineMean_Reset(OnlineMean_t *oMean);
#ifdef __cplusplus
}
#endif
#endif /* ONLINEMEAN_H_ */

View File

@@ -0,0 +1,824 @@
#include <stdio.h>
#include <unistd.h>
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <math.h>
#include <cJSON.h>
#include <pthread.h>
#include "onlinemean.h"
#include "session_flags_internal.h"
#include "fet.h"
#include "stellar/stellar.h"
#include "mesa_sts.h"
#include "stellar/session.h"
#include "stellar/log.h"
#define SESSION_BUKLY_THRESHORD 0.95
#define SESSION_DOWNLOAD_THRESHORD 0.95
#define SESSION_CBR_STREAMING_THRESHORD 0.15
#define SESSION_STREAMING_THRESHORD 0.86
#define SESSION_PSEUDO_UNIDIRECTIONA_THRESHORD 0.95
#define SESSION_INTERACTIVE_THRESHORD 0.7
#define SESSION_BIDIRECTIONAL_THRESHORD_MIN 0.7
#define SESSION_BIDIRECTIONAL_THRESHORD_MAX 1.43
#define SESSION_EWMA_FACTOR 0.9
#define SESSION_RANDOM_LOOKING_PAYLOAD_LEN_MIN 100
#define SESSION_ITER_INTERVAL_MS 1000
#define SESSION_EWMA_ITER_CNT_MIN 5
#define LARGE_PKT_SIZE_MIN 600
#define LARGE_PKT_SIZE_MAX 1400
#define SESSION_FLAGS_IDENTIFY_STR_LEN 256
extern struct session_flags_init_conf g_sf_conf;
extern uint32_t sts_random_switch;
thread_local OnlineMean_t g_large_pkt_omean = {
.mean = 0,
.varsum = 0,
.count = 0
};//record the mean and std of packet size, to calculate large packet size
thread_local uint64_t g_large_pkt_size_update_ms = 0;
thread_local uint32_t g_large_pkt_size = 0;
#define LARGE_PKT_SIZE_UPDATE_COUNT_MIN 10000
#define LARGE_PKT_SIZE_UPDATE_INTERVAL_MS 10000
static void session_flags_calculate_local(struct session_flags_stat *stat, enum session_direction session_dir)
{
if (session_dir == SESSION_DIRECTION_INBOUND)
{
stat->result.flags |= SESSION_FLAGS_LOCAL_SERVER;
stat->result.identify[session_flags_local_server_mask] = 1;
}
else
{
stat->result.flags |= SESSION_FLAGS_LOCAL_CLIENT;
stat->result.identify[session_flags_local_client_mask] = 1;
}
return;
}
void session_flags_stat_init(struct session_flags_stat *stat, enum session_direction session_dir)
{
session_flags_calculate_local(stat, session_dir);
OnlineMean_Init(&stat->iter.c2s.omean);
OnlineMean_Init(&stat->iter.s2c.omean);
stat->main_dir = MAIN_DIR_UNKONWN;
return;
};
static void session_flags_EWMA_iter(float *ori_value, float iter_value)
{
float temp = *ori_value;
if (temp == 0)
{
temp = iter_value;
}
else
{
temp = SESSION_EWMA_FACTOR * temp + (1 - SESSION_EWMA_FACTOR) * iter_value;
}
*ori_value = temp;
}
static void session_flags_calculate_pseudo_unidirection(struct session_flags_stat *stat, uint64_t all_pkts)
{
if (stat->result.flags & SESSION_FLAGS_PSEUDO_UNIDIRECTIONAL)
return ;
float c2s_ratio, s2c_ratio;
float pseudo_unidirectional;
uint64_t delta_payload_pkts = stat->c2s.delta_payload_pkts + stat->s2c.delta_payload_pkts;
if (delta_payload_pkts == 0)
{
return;
}
c2s_ratio = stat->c2s.delta_payload_pkts * 1.f / delta_payload_pkts;
s2c_ratio = stat->s2c.delta_payload_pkts * 1.f / delta_payload_pkts;
session_flags_EWMA_iter(&stat->iter.c2s.pseudo_unidirectional, c2s_ratio);
session_flags_EWMA_iter(&stat->iter.s2c.pseudo_unidirectional, s2c_ratio);
if (stat->iter.iter_cnt < SESSION_EWMA_ITER_CNT_MIN || stat->main_dir == MAIN_DIR_UNKONWN)
{
return;
}
if (stat->main_dir == FLOW_TYPE_C2S)
{
pseudo_unidirectional = stat->iter.c2s.pseudo_unidirectional;
}
else
{
pseudo_unidirectional = stat->iter.s2c.pseudo_unidirectional;
}
if (pseudo_unidirectional > SESSION_PSEUDO_UNIDIRECTIONA_THRESHORD)
{
stat->result.flags |= SESSION_FLAGS_PSEUDO_UNIDIRECTIONAL;
stat->result.identify[session_flags_pseudo_unidirectional_mask] = all_pkts;
}
}
static void session_flags_calculate_unidirection(struct session_flags_stat *stat, uint64_t all_pkts)
{
if (stat->result.flags & SESSION_FLAGS_UNIDIRECTIONAL || stat->s2c.pkts == 0 || stat->c2s.pkts == 0)
return ;
if (stat->c2s.payload_pkts == 0 || stat->s2c.payload_pkts == 0)
{
stat->result.flags |= SESSION_FLAGS_UNIDIRECTIONAL;
stat->result.identify[session_flags_unidirectional_mask] = all_pkts;
}
}
static void session_flags_calculate_streaming(struct session_flags_stat *stat, uint64_t all_pkts)
{
if (stat->result.flags & SESSION_FLAGS_STREAMING)
return;
float c2s_ratio, s2c_ratio;
float streaming;
uint64_t delta_bytes = stat->c2s.delta_bytes + stat->s2c.delta_bytes;
if (delta_bytes == 0)
{
return;
}
c2s_ratio = stat->c2s.delta_bytes * 1.f / delta_bytes;
s2c_ratio = stat->s2c.delta_bytes * 1.f / delta_bytes;
session_flags_EWMA_iter(&stat->iter.c2s.streaming, c2s_ratio);
session_flags_EWMA_iter(&stat->iter.s2c.streaming, s2c_ratio);
if (stat->iter.iter_cnt < SESSION_EWMA_ITER_CNT_MIN || stat->main_dir == MAIN_DIR_UNKONWN)
{
return;
}
if (stat->main_dir == FLOW_TYPE_C2S)
{
streaming = stat->iter.c2s.streaming;
}
else
{
streaming = stat->iter.s2c.streaming;
}
if (streaming > SESSION_STREAMING_THRESHORD)
{
stat->result.flags |= SESSION_FLAGS_STREAMING;
stat->result.identify[session_flags_streaming_mask] = all_pkts;
}
}
static void session_flags_calculate_download(struct session_flags_stat *stat, uint64_t all_pkts)
{
if (stat->result.flags & SESSION_FLAGS_DOWNLOAD)
return ;
float c2s_ratio, s2c_ratio;
float download;
uint64_t delta_payload_pkts = stat->c2s.delta_payload_pkts + stat->s2c.delta_payload_pkts;
if (delta_payload_pkts == 0)
{
return;
}
c2s_ratio = stat->c2s.delta_large_pkts * 1.f / delta_payload_pkts;
s2c_ratio = stat->s2c.delta_large_pkts * 1.f / delta_payload_pkts;
session_flags_EWMA_iter(&stat->iter.c2s.download, c2s_ratio);
session_flags_EWMA_iter(&stat->iter.s2c.download, s2c_ratio);
if (stat->iter.iter_cnt < SESSION_EWMA_ITER_CNT_MIN || stat->main_dir == MAIN_DIR_UNKONWN)
{
return;
}
if (stat->main_dir == FLOW_TYPE_C2S)
{
download = stat->iter.c2s.download;
}
else
{
download = stat->iter.s2c.download;
}
if (download > SESSION_DOWNLOAD_THRESHORD)
{
stat->result.flags |= SESSION_FLAGS_DOWNLOAD;
stat->result.identify[session_flags_download_mask] = all_pkts;
}
}
static void session_flags_calculate_bulky(struct session_flags_stat *stat, uint64_t all_pkts)
{
if (stat->result.flags & SESSION_FLAGS_BULKY)
return ;
float bulky;
if (stat->c2s.delta_pkts != 0)
{
float c2s_ratio;
c2s_ratio = stat->c2s.delta_large_pkts * 1.f / stat->c2s.delta_pkts;
session_flags_EWMA_iter(&stat->iter.c2s.bulky, c2s_ratio);
}
if (stat->s2c.delta_pkts != 0)
{
float s2c_ratio;
s2c_ratio = stat->s2c.delta_large_pkts * 1.f / stat->s2c.delta_pkts;
session_flags_EWMA_iter(&stat->iter.s2c.bulky, s2c_ratio);
}
if (stat->iter.iter_cnt < SESSION_EWMA_ITER_CNT_MIN || stat->main_dir == MAIN_DIR_UNKONWN)
{
return;
}
if (stat->main_dir == FLOW_TYPE_C2S)
{
bulky = stat->iter.c2s.bulky;
}
else
{
bulky = stat->iter.s2c.bulky;
}
if (bulky > SESSION_BUKLY_THRESHORD)
{
stat->result.flags |= SESSION_FLAGS_BULKY;
stat->result.identify[session_flags_bulky_mask] = all_pkts;
}
}
static void flow_stat_update(struct session *session, struct flow_stat *flow, uint64_t bytes)
{
flow->bytes += bytes;
flow->pkts++;
flow->delta_pkts++;
flow->delta_bytes += bytes;
const struct packet *pkt = session_get0_current_packet(session);
size_t payload_len = packet_get_payload_len(pkt);
if (payload_len > 0)
{
flow->payload_pkts++;
flow->delta_payload_pkts++;
}
if (bytes > g_large_pkt_size)
{
flow->large_pkts++;
flow->delta_large_pkts++;
}
return;
}
static void session_flags_calculate_main_dir(struct session_flags_stat *stat)
{
if (stat->main_dir != MAIN_DIR_UNKONWN)
{
return;
}
if (stat->c2s.bytes > stat->s2c.bytes)
{
stat->main_dir = FLOW_TYPE_C2S;
}
else
{
stat->main_dir = FLOW_TYPE_S2C;
}
}
float session_flags_calculate_CV(OnlineMean_t * omean)
{
float CV = -1.f;
float mean = OnlineMean_GetMean(omean);
if (mean!= 0)
{
CV = OnlineMean_GetStd(omean) / mean;
}
// printf("CV:%lf\n", CV);
return CV;
}
static void session_flags_calculate_CBR(struct session_flags_stat *stat, uint64_t all_pkts)
{
if (stat->result.flags & SESSION_FLAGS_CBR)
return;
float CBR;
OnlineMean_Update(&stat->iter.c2s.omean, stat->c2s.rate);
OnlineMean_Update(&stat->iter.s2c.omean, stat->s2c.rate);
stat->iter.c2s.CBR = session_flags_calculate_CV(&stat->iter.c2s.omean);
stat->iter.s2c.CBR = session_flags_calculate_CV(&stat->iter.s2c.omean);
if (stat->main_dir == MAIN_DIR_UNKONWN)
{
return;
}
if (stat->main_dir == FLOW_TYPE_C2S)
{
CBR = stat->iter.c2s.CBR;
}
else
{
CBR = stat->iter.s2c.CBR;
}
if (CBR < SESSION_CBR_STREAMING_THRESHORD && CBR > 0.0)
{
stat->result.flags |= SESSION_FLAGS_CBR;
stat->result.identify[session_flags_cbr_mask] = all_pkts;
}
}
static void session_flags_calculate_interactive(struct session_flags_stat *stat, uint64_t all_pkts)
{
if (stat->result.flags & SESSION_FLAGS_INTERACTIVE || stat->c2s.pkts == 0 || stat->s2c.pkts == 0)
return;
if (stat->stream_live_time_ms > g_sf_conf.interactive_starttime_ms && stat->interactive_pulse_num > g_sf_conf.interactive_pulse_num)
{
stat->result.flags |= SESSION_FLAGS_INTERACTIVE;
stat->result.identify[session_flags_interactive_mask] = all_pkts;
}
}
static void session_flags_calculate_interactive_pulse(struct session_flags_stat *stat, uint64_t cur_ms, uint64_t all_pkts)
{
uint64_t delta_ms = 0;
if (cur_ms > stat->last_pkt_ts_ms)
{
delta_ms = cur_ms - stat->last_pkt_ts_ms;
}
if (delta_ms > g_sf_conf.interactive_latency_ms)
{
stat->interactive_pulse_num++;
session_flags_calculate_interactive(stat, all_pkts);
}
}
static void session_flags_calculate_bound(struct session_flags_stat *stat, uint64_t all_pkts)
{
if (stat == NULL || stat->c2s.pkts == 0 || stat->s2c.pkts == 0)
{
return;
}
if (!(stat->result.flags & SESSION_FLAGS_INBOUND) && !(stat->result.flags & SESSION_FLAGS_OUTBOUND))
{
if (stat->result.flags & SESSION_FLAGS_LOCAL_CLIENT)
{
if (stat->main_dir == FLOW_TYPE_C2S)
{
stat->result.flags |= SESSION_FLAGS_OUTBOUND;
stat->result.identify[session_flags_outbound_mask] = all_pkts;
}
else
{
stat->result.flags |= SESSION_FLAGS_INBOUND;
stat->result.identify[session_flags_inbound_mask] = all_pkts;
}
}
else
{
if (stat->main_dir == FLOW_TYPE_C2S)
{
stat->result.flags |= SESSION_FLAGS_INBOUND;
stat->result.identify[session_flags_inbound_mask] = all_pkts;
}
else
{
stat->result.flags |= SESSION_FLAGS_OUTBOUND;
stat->result.identify[session_flags_outbound_mask] = all_pkts;
}
}
}
}
static void session_flags_calculate_dir(struct session_flags_stat *stat, uint64_t all_pkts)
{
if (stat->c2s.pkts != 0 && !(stat->result.flags & SESSION_FLAGS_C2S))
{
stat->result.flags |= SESSION_FLAGS_C2S;
stat->result.identify[session_flags_c2s_mask] = all_pkts;
}
if (stat->s2c.pkts != 0 && !(stat->result.flags & SESSION_FLAGS_S2C))
{
stat->result.flags |= SESSION_FLAGS_S2C;
stat->result.identify[session_flags_s2c_mask] = all_pkts;
}
}
static void session_flags_calculate_bidirectional(struct session_flags_stat *stat, uint64_t all_pkts)
{
if (stat->result.flags & SESSION_FLAGS_BIDIRECTIONAL)
{
return;
}
float rate_ratio = stat->c2s.rate / stat->s2c.rate;
if (stat->iter.bidirectional == 0)
{
stat->iter.bidirectional = rate_ratio;
}
else
{//EWMA
stat->iter.bidirectional = SESSION_EWMA_FACTOR * stat->iter.bidirectional + (1 - SESSION_EWMA_FACTOR) * rate_ratio;
}
if (stat->iter.iter_cnt >= SESSION_EWMA_ITER_CNT_MIN)
{
if (stat->iter.bidirectional > SESSION_BIDIRECTIONAL_THRESHORD_MIN && stat->iter.bidirectional < SESSION_BIDIRECTIONAL_THRESHORD_MAX)
{
stat->result.flags |= SESSION_FLAGS_BIDIRECTIONAL;
stat->result.identify[session_flags_bidirectional_mask] = all_pkts;
}
}
return;
}
static void session_flags_calculate_randomness_by_fet(struct session_flags_stat *stat, size_t payload_len, const char *payload, uint64_t all_pkts)
{
if (stat->random_looking_stat.has_judged_fet)
{
return;
}
stat->random_looking_stat.has_judged_fet = 1;
if (g_sf_conf.fet_enabled)
{
struct fet_detail detail;
int is_fet = is_data_fet((unsigned char *)payload, payload_len, &detail);
stat->result.is_tls = detail.is_tls;
if (is_fet)
{//if payload is fet data, then it is definitely random looking
stat->result.flags |= SESSION_FLAGS_RANDOM_LOOKING;
stat->result.identify[session_flags_random_looking_mask] = all_pkts;
}
}
return;
}
static void session_flags_calculate_randomness_by_sts(struct session_flags_plugin_info *sf_plugin_info, struct session *session, struct session_flags_stat *stat, size_t payload_len, const char *payload, uint64_t all_pkts)
{
if (stat->random_looking_stat.has_judged_sts || sts_random_switch == 0)
{
return;
}
if (payload_len < SESSION_RANDOM_LOOKING_PAYLOAD_LEN_MIN)
{
return;
}
stat->random_looking_stat.has_judged_sts = 1;
struct sts_result result;
uint32_t random_flags_count = 0;
memset(&result, 0, sizeof(result));
mesa_statistical_test_suite((void*)payload, payload_len, &result, sts_random_switch);
if (result.frequency)
{
stat->result.random_looking_flags |= SESSION_FLAGS_FREQUENCY;
random_flags_count++;
}
if (result.block_frequency)
{
stat->result.random_looking_flags |= SESSION_FLAGS_BLOCK_FREQUENCY;
random_flags_count++;
}
if (result.cumulative_sums)
{
stat->result.random_looking_flags |= SESSION_FLAGS_CUMULATIVE_SUMS;
random_flags_count++;
}
if (result.runs)
{
stat->result.random_looking_flags |= SESSION_FLAGS_RUNS;
random_flags_count++;
}
if (result.longest_run)
{
stat->result.random_looking_flags |= SESSION_FLAGS_LONGEST_RUN;
random_flags_count++;
}
if (result.rank)
{
stat->result.random_looking_flags |= SESSION_FLAGS_RANK;
random_flags_count++;
}
if (result.non_overlapping_template_matching)
{
stat->result.random_looking_flags |= SESSION_FLAGS_NON_OVERLAPPING_TEMPLATE_MATCHING;
random_flags_count++;
}
if (result.overlapping_template_matching)
{
stat->result.random_looking_flags |= SESSION_FLAGS_OVERLAPPING_TEMPLATE_MATCHING;
random_flags_count++;
}
if (result.universal)
{
stat->result.random_looking_flags |= SESSION_FLAGS_UNIVERSAL;
random_flags_count++;
}
if (result.random_excursions)
{
stat->result.random_looking_flags |= SESSION_FLAGS_RANDOM_EXCURSIONS;
random_flags_count++;
}
if (result.random_excursions_variant)
{
stat->result.random_looking_flags |= SESSION_FLAGS_RANDOM_EXCURSIONS_VARIANT;
random_flags_count++;
}
if (result.poker_detect)
{
stat->result.random_looking_flags |= SESSION_FLAGS_POKER_DETECT;
random_flags_count++;
}
if (result.runs_distribution)
{
stat->result.random_looking_flags |= SESSION_FLAGS_RUNS_DISTRIBUTION;
random_flags_count++;
}
if (result.self_correlation)
{
stat->result.random_looking_flags |= SESSION_FLAGS_SELF_CORRELATION;
random_flags_count++;
}
if (result.binary_derivative)
{
stat->result.random_looking_flags |= SESSION_FLAGS_BINARY_DERIVATIVE;
random_flags_count++;
}
if (random_flags_count > (g_sf_conf.random_judge_flags_cnt / 2))
{
stat->result.flags |= SESSION_FLAGS_RANDOM_LOOKING;
stat->result.identify[session_flags_random_looking_mask] = all_pkts;
}
STELLAR_LOG_DEBUG(sf_plugin_info->log_handle, SESSION_FLAGS_LOG_MODULE, "[%s] calculate random looking flags, flags:0x%x, pkts_num:%d", session_get0_readable_addr(session), stat->result.random_looking_flags, all_pkts);
}
static void session_flags_calculate_random_looking(struct session_flags_plugin_info *sf_plugin_info, struct session_flags_stat *stat, struct session *session, int topic_id, uint64_t all_pkts)
{
if (stat->result.flags & SESSION_FLAGS_RANDOM_LOOKING)
{
return;
}
int udp_topic_id = sf_plugin_info->udp_topic_id;
const struct packet *pkt = session_get0_current_packet(session);
size_t payload_len = packet_get_payload_len(pkt);
const char *payload = packet_get_payload(pkt);
if ((topic_id == udp_topic_id) && g_sf_conf.random_looking_udp_ignore_pkts < 0)// disable random looking udp when random_looking_udp_ignore_pkts<0
{
return;
}
if (payload_len == 0 || payload == NULL)
{
return;
}
stat->random_looking_stat.payload_pkt_num++;
if ((topic_id == udp_topic_id) && stat->random_looking_stat.payload_pkt_num <= g_sf_conf.random_looking_udp_ignore_pkts)
{
return;
}
session_flags_calculate_randomness_by_fet(stat, payload_len, payload, all_pkts);
if (stat->result.flags & SESSION_FLAGS_RANDOM_LOOKING)
{
return;
}
session_flags_calculate_randomness_by_sts(sf_plugin_info, session, stat, payload_len, payload, all_pkts);
return;
}
static void session_flags_reset_delta(struct session_flags_stat *stat)
{
stat->c2s.delta_bytes = 0;
stat->c2s.delta_pkts = 0;
stat->c2s.delta_large_pkts = 0;
stat->c2s.delta_payload_pkts = 0;
stat->s2c.delta_bytes = 0;
stat->s2c.delta_pkts = 0;
stat->s2c.delta_large_pkts = 0;
stat->s2c.delta_payload_pkts = 0;
return;
}
static void session_flags_calculate_rate(struct session_flags_stat *stat, uint64_t delta_ms)
{
stat->c2s.rate = stat->c2s.delta_bytes * 1.f / delta_ms;
stat->s2c.rate = stat->s2c.delta_bytes * 1.f / delta_ms;
return;
}
static void session_flags_update_large_pkt_size(struct session_flags_plugin_info *sf_plugin_info, uint32_t pkt_len, uint64_t ms)
{
if (pkt_len > 1500)
{
return;
}
OnlineMean_Update(&g_large_pkt_omean, pkt_len);
if (g_large_pkt_size_update_ms == 0)
{
g_large_pkt_size_update_ms = ms;
g_large_pkt_size = g_sf_conf.large_ptks_init_size;
return;
}
if (ms - g_large_pkt_size_update_ms >= LARGE_PKT_SIZE_UPDATE_INTERVAL_MS && g_large_pkt_omean.count >= LARGE_PKT_SIZE_UPDATE_COUNT_MIN)
{
g_large_pkt_size_update_ms = ms;
g_large_pkt_size = (uint32_t)(0.84f * OnlineMean_GetStd(&g_large_pkt_omean) + OnlineMean_GetMean(&g_large_pkt_omean));//计算公式 0.84 = (g_large_pkt_size - mean) / std, 0.84为正态分布表中80%的概率对应的z值
if (g_large_pkt_size < LARGE_PKT_SIZE_MIN)
{
g_large_pkt_size = LARGE_PKT_SIZE_MIN;
}
else if (g_large_pkt_size > LARGE_PKT_SIZE_MAX)
{
g_large_pkt_size = LARGE_PKT_SIZE_MAX;
}
STELLAR_LOG_DEBUG(sf_plugin_info->log_handle, SESSION_FLAGS_LOG_MODULE, "session_flags thread %ld update large_pkt_size %d", pthread_self(), g_large_pkt_size);
}
return;
}
struct session_flags_result *session_flags(struct session_flags_plugin_info *sf_plugin_info, struct session_flags_ctx *ctx, struct session *session, int topic_id, uint32_t bytes, enum flow_type flow_type, uint64_t ms)
{
struct session_flags_stat *stat = &ctx->stat;
if (stat == NULL || bytes == 0)
{
return NULL;
}
session_flags_update_large_pkt_size(sf_plugin_info, bytes, ms);
uint64_t delta_ms = 0;
if(stat->session_start_time_ms == 0)
{
stat->session_start_time_ms = ms;
}
stat->stream_live_time_ms = ms - stat->session_start_time_ms;
if (stat->last_iter_ts_ms == 0)
{
stat->last_iter_ts_ms = ms;
}
if (flow_type == FLOW_TYPE_C2S)
{
flow_stat_update(session, &stat->c2s, bytes);
}
else
{
flow_stat_update(session, &stat->s2c, bytes);
}
uint64_t all_pkts = stat->c2s.pkts + stat->s2c.pkts;
session_flags_calculate_dir(stat, all_pkts);
session_flags_calculate_random_looking(sf_plugin_info, stat, session, topic_id, all_pkts);
const struct packet *pkt = session_get0_current_packet(session);
size_t payload_len = packet_get_payload_len(pkt);
if (g_sf_conf.tunneling_enabled && payload_len > 0 && (topic_id == sf_plugin_info->tcp_topic_id))// detect tunneling on tcp only
{
tunneling_scan_sequence(sf_plugin_info, session, ctx, payload_len, flow_type, all_pkts);
}
if (stat->stream_live_time_ms >= START_JUDGE_TIME_MS)
{
if (all_pkts > g_sf_conf.main_dir_front_n_pkts)
{
session_flags_calculate_main_dir(stat);
}
}
if (stat->c2s.pkts == 0 || stat->s2c.pkts == 0)
{
goto END;
}
if (stat->main_dir != MAIN_DIR_UNKONWN)
{
session_flags_calculate_bound(stat, all_pkts);
session_flags_calculate_unidirection(stat, all_pkts);
}
delta_ms = ms - stat->last_iter_ts_ms;
if (delta_ms >= SESSION_ITER_INTERVAL_MS)
{
session_flags_calculate_rate(stat, delta_ms);
session_flags_calculate_bidirectional(stat, all_pkts);
session_flags_calculate_CBR(stat, all_pkts);
session_flags_calculate_download(stat, all_pkts);
session_flags_calculate_bulky(stat, all_pkts);
session_flags_calculate_pseudo_unidirection(stat, all_pkts);
session_flags_calculate_streaming(stat, all_pkts);
stat->iter.iter_cnt++;
stat->last_iter_ts_ms = ms;
session_flags_reset_delta(stat);
}
session_flags_calculate_interactive_pulse(stat, ms, all_pkts);
END:
stat->last_pkt_ts_ms = ms;
return &stat->result;
}
struct session_flags_result *session_flags_get_flags(struct session_flags_stat *stat)
{
if (stat == NULL)
return NULL;
return &stat->result;
}
struct session_flags_message *session_flags_generate_firewall_message(uint64_t flags, const uint32_t identify[session_flags_all_mask])
{
int flag_num = 0;
uint32_t temp_identify[session_flags_all_mask] = {0};
struct session_flags_message *flags_msg = (struct session_flags_message *)calloc(1, sizeof(struct session_flags_message));
flags_msg->magic= MESSAGE_MAGIC;
flags_msg->flags = flags;
for (int i = 0; i < session_flags_all_mask; i++)
{
if (flags & (SESSION_FLAGS_START << i))
{
temp_identify[flag_num] = identify[i];
flag_num++;
}
}
flags_msg->packet_sequence_array = (uint32_t *)calloc(flag_num, sizeof(uint32_t));
for (int i = 0; i < flag_num; i++)
{
flags_msg->packet_sequence_array[i] = temp_identify[i];
}
flags_msg->array_num = flag_num;
return flags_msg;
}

View File

@@ -0,0 +1,153 @@
#pragma once
#include <stdint.h>
#include "onlinemean.h"
#include "tunneling.h"
#include "hs/hs_runtime.h"
#include "stellar/session.h"
#include "stellar/session_flags.h"
#include "toml/toml.h"
#define SESSION_FLAGS_LOG_MODULE "SESSION_FLAGS"
enum random_looking_flags
{
session_flags_frequency_mask = 0,
session_flags_block_frequency_mask,
session_flags_cumulative_sums_mask,
session_flags_runs_mask,
session_flags_longest_run_mask,
session_flags_rank_mask,
session_flags_non_overlapping_template_matching_mask,
session_flags_overlapping_template_matching_mask,
session_flags_universal_mask,
session_flags_random_excursions_mask,
session_flags_random_excursions_variant_mask,
session_flags_poker_detect_mask,
session_flags_runs_distribution_mask,
session_flags_self_correlation_mask,
session_flags_binary_derivative_mask,
};
#define SESSION_FLAGS_FREQUENCY (0x0000000000000001)
#define SESSION_FLAGS_BLOCK_FREQUENCY (SESSION_FLAGS_FREQUENCY << session_flags_block_frequency_mask)
#define SESSION_FLAGS_CUMULATIVE_SUMS (SESSION_FLAGS_FREQUENCY << session_flags_cumulative_sums_mask)
#define SESSION_FLAGS_RUNS (SESSION_FLAGS_FREQUENCY << session_flags_runs_mask)
#define SESSION_FLAGS_LONGEST_RUN (SESSION_FLAGS_FREQUENCY << session_flags_longest_run_mask)
#define SESSION_FLAGS_RANK (SESSION_FLAGS_FREQUENCY << session_flags_rank_mask)
#define SESSION_FLAGS_NON_OVERLAPPING_TEMPLATE_MATCHING (SESSION_FLAGS_FREQUENCY << session_flags_non_overlapping_template_matching_mask)
#define SESSION_FLAGS_OVERLAPPING_TEMPLATE_MATCHING (SESSION_FLAGS_FREQUENCY << session_flags_overlapping_template_matching_mask)
#define SESSION_FLAGS_UNIVERSAL (SESSION_FLAGS_FREQUENCY << session_flags_universal_mask)
#define SESSION_FLAGS_RANDOM_EXCURSIONS (SESSION_FLAGS_FREQUENCY << session_flags_random_excursions_mask)
#define SESSION_FLAGS_RANDOM_EXCURSIONS_VARIANT (SESSION_FLAGS_FREQUENCY << session_flags_random_excursions_variant_mask)
#define SESSION_FLAGS_POKER_DETECT (SESSION_FLAGS_FREQUENCY << session_flags_poker_detect_mask)
#define SESSION_FLAGS_RUNS_DISTRIBUTION (SESSION_FLAGS_FREQUENCY << session_flags_runs_distribution_mask)
#define SESSION_FLAGS_SELF_CORRELATION (SESSION_FLAGS_FREQUENCY << session_flags_self_correlation_mask)
#define SESSION_FLAGS_BINARY_DERIVATIVE (SESSION_FLAGS_FREQUENCY << session_flags_binary_derivative_mask)
#define MAIN_DIR_UNKONWN -1
#define START_JUDGE_TIME_MS 5000
struct session_flags_result {
uint64_t flags;
uint64_t random_looking_flags;
uint32_t identify[session_flags_all_mask];
bool is_tls;
};
struct session_flags_init_conf{
uint32_t interactive_starttime_ms;
uint32_t interactive_pulse_num;
uint32_t main_dir_front_n_pkts;
uint64_t interactive_latency_ms;
uint32_t large_ptks_init_size;
uint32_t random_judge_flags_cnt;
uint32_t session_max_process_time_ms;
uint32_t fet_enabled;
uint32_t tunneling_enabled;
int32_t random_looking_udp_ignore_pkts;
uint32_t tunneling_tls_ignore_pkts;
uint32_t tunneling_max_scan_pkts;
char tunneling_pcre_list[2048];
char random_looking_judge_list[2048];
};
struct session_flags_plugin_info{
int plugin_id;
int sess_ctx_exdata_idx;
struct stellar *st;
struct logger *log_handle;
int session_flags_topic_id;
int tcp_topic_id;
int udp_topic_id;
hs_database_t *tunneling_hs_db;
};
struct session_flags_iter_values
{
float bulky;
float CBR;
float download;
float interactive;
float pseudo_unidirectional;
float streaming;
OnlineMean_t omean;
};
struct session_flags_iter
{
uint32_t iter_cnt;
float bidirectional;
struct session_flags_iter_values c2s;
struct session_flags_iter_values s2c;
};
struct flow_stat
{
uint64_t bytes;
uint64_t pkts;
uint64_t payload_pkts;
uint64_t large_pkts;
uint32_t delta_pkts;
uint32_t delta_large_pkts;
uint32_t delta_payload_pkts;
uint32_t delta_bytes;
float rate;
};
struct random_looking_stat_info
{
uint8_t has_judged_sts;
uint8_t has_judged_fet;
uint8_t payload_pkt_num;
};
struct session_flags_stat
{
struct flow_stat c2s, s2c;
uint64_t last_pkt_ts_ms;
uint64_t interactive_pulse_num;
uint64_t session_start_time_ms;
uint64_t stream_live_time_ms;
uint64_t last_iter_ts_ms;
int main_dir;
struct random_looking_stat_info random_looking_stat;
struct tunneling_stat_info tunneling_stat;
struct session_flags_iter iter;
struct session_flags_result result;
};
struct session_flags_ctx
{
struct session_flags_stat stat;
hs_stream_t *tunneling_hs_stream;
uint64_t history_flags;
};
void session_flags_stat_init(struct session_flags_stat *stat, enum session_direction session_dir);
struct session_flags_result *session_flags(struct session_flags_plugin_info *sf_plugin_info, struct session_flags_ctx *ctx, struct session *session, int etopic_id, uint32_t bytes, enum flow_type flow_type, uint64_t ms);
struct session_flags_result *session_flags_get_flags(struct session_flags_stat *session_flags);
struct session_flags_message *session_flags_generate_firewall_message(uint64_t flags, const uint32_t identify[session_flags_all_mask]);
float session_flags_calculate_CV(OnlineMean_t * omean);

View File

@@ -0,0 +1,404 @@
#include <stdio.h>
#include <string.h>
#include <time.h>
#include "mesa_sts.h"
#include "cJSON.h"
#include "stellar/stellar.h"
#include "stellar/session.h"
#include "stellar/stellar_mq.h"
#include "stellar/stellar_exdata.h"
#include "stellar/log.h"
#include "session_flags_internal.h"
#define _MAX_STR_LEN 64
#define UNUSED(x) (void)(x)
const char *CFG_FILE_PATH="./etc/session_flags/session_flags.toml";
uint32_t sts_random_switch = 0;
struct session_flags_init_conf g_sf_conf;
static const char* random_looking_judge_table[] = {
"frequency",
"block_frequency",
"cumulative_sums",
"runs",
"longest_run",
"rank",
"non_overlapping_template_matching",
"overlapping_template_matching",
"universal",
"random_excursions",
"random_excursions_variant",
"poker_detect",
"runs_distribution",
"self_correlation",
"binary_derivative"
};
static void session_flags_topic_free_cb(void *msg, void *msg_free_arg)
{
UNUSED(msg_free_arg);
struct session_flags_message *flags = (struct session_flags_message *)msg;
if (flags)
{
if (flags->packet_sequence_array)
{
free(flags->packet_sequence_array);
}
free(flags);
}
return;
}
static void session_flags_exdata_free_cb(int idx, void *ex_ptr, void *arg)
{
UNUSED(idx);
UNUSED(arg);
if (ex_ptr == NULL)
{
return;
}
struct session_flags_ctx *ctx = (struct session_flags_ctx *)ex_ptr;
tunneling_hs_stream_free(ctx);
free(ex_ptr);
}
void session_flags_entry(struct session *session, int topic_id, const void *msg, void *per_session_ctx, void *plugin_env)
{
UNUSED(per_session_ctx);
if (msg == NULL)
{
return;
}
const struct packet *pkt = (const struct packet *)msg;
struct session_flags_plugin_info *sf_plugin_info = (struct session_flags_plugin_info *)plugin_env;
struct session_flags_ctx *ctx = (struct session_flags_ctx *)session_exdata_get(session, sf_plugin_info->sess_ctx_exdata_idx);
if (ctx == NULL)
{
ctx = (struct session_flags_ctx *)calloc(1, sizeof(struct session_flags_ctx));
session_exdata_set(session, sf_plugin_info->sess_ctx_exdata_idx, ctx);
session_flags_stat_init(&ctx->stat, session_get_direction(session));
if (g_sf_conf.tunneling_enabled)
{
tunneling_hs_stream_init(sf_plugin_info, ctx);
}
}
struct session_flags_stat *stat = &ctx->stat;
session_flags_result *flags_result = NULL;
size_t pktlen = 0;
pktlen = packet_get_raw_len(pkt);
uint64_t curr_time_ms = 0;
const struct timeval *tv;
tv = packet_get_timeval(pkt);
if (tv != NULL)
{
curr_time_ms = tv->tv_sec * 1000 + tv->tv_usec / 1000;
}
flags_result = session_flags(sf_plugin_info, ctx, session, topic_id, pktlen, session_get_flow_type(session), curr_time_ms);
if ((stat->stream_live_time_ms > g_sf_conf.session_max_process_time_ms))
{
stellar_session_plugin_dettach_current_session(session);
}
uint32_t pkts_num = stat->c2s.pkts + stat->s2c.pkts;
if (flags_result != NULL)
{
if (flags_result->flags != ctx->history_flags)
{
struct session_flags_message *flags_msg = session_flags_generate_firewall_message(flags_result->flags, flags_result->identify);
if (session_mq_publish_message(session, sf_plugin_info->session_flags_topic_id, flags_msg) < 0)
{
session_flags_topic_free_cb(flags_msg, NULL);
STELLAR_LOG_FATAL(sf_plugin_info->log_handle, SESSION_FLAGS_LOG_MODULE, "[%s] publish session flags message failed, flags:0x%x, pkts_num:%d", session_get0_readable_addr(session), flags_result->flags, pkts_num);
return;
}
ctx->history_flags = flags_result->flags;
STELLAR_LOG_DEBUG(sf_plugin_info->log_handle, SESSION_FLAGS_LOG_MODULE,
"[%s] flags:0x%x, pkts_num:%d\n \
c2s_iter: bulky: %f, CBR: %f, download: %f, interactive: %f, pseudo_unidirectional: %f, streaming: %f, CBR_CV: %f\n \
s2c_iter: bulky: %f, CBR: %f, download: %f, interactive: %f, pseudo_unidirectional: %f, streaming: %f, CBR_CV: %f\n \
iter_cnt: %d, bidirectional: %f\n", session_get0_readable_addr(session), ctx->history_flags, pkts_num,
stat->iter.c2s.bulky, stat->iter.c2s.CBR, stat->iter.c2s.download, stat->iter.c2s.interactive, stat->iter.c2s.pseudo_unidirectional, stat->iter.c2s.streaming, session_flags_calculate_CV(&stat->iter.c2s.omean),
stat->iter.s2c.bulky, stat->iter.s2c.CBR, stat->iter.s2c.download, stat->iter.s2c.interactive, stat->iter.s2c.pseudo_unidirectional, stat->iter.s2c.streaming, session_flags_calculate_CV(&stat->iter.s2c.omean),
stat->iter.iter_cnt, stat->iter.bidirectional);
}
}
return;
}
static void session_flags_load_config(struct session_flags_plugin_info *sf_plugin_info, const char *cfg_file, struct session_flags_init_conf *g_sf_conf)
{
char errbuf[256] = {0};
FILE *fp = fopen(cfg_file, "r");
if (NULL == fp)
{
STELLAR_LOG_FATAL(sf_plugin_info->log_handle, SESSION_FLAGS_LOG_MODULE, "Can't open config file:%s", cfg_file);
return;
}
toml_table_t *toml_root = toml_parse_file(fp, errbuf, sizeof(errbuf));
fclose(fp);
toml_table_t *cfg_tbl = toml_table_in(toml_root, "SESSION_FLAGS");
if (NULL == cfg_tbl)
{
STELLAR_LOG_FATAL(sf_plugin_info->log_handle, SESSION_FLAGS_LOG_MODULE, "config file:%s has no key: [SESSION_FLAGS]", cfg_file);
toml_free(toml_root);
return;
}
toml_datum_t toml_val = toml_int_in(cfg_tbl, "INTERACTIVE_STARTTIME_MS");
if (toml_val.ok)
{
g_sf_conf->interactive_starttime_ms = toml_val.u.i;
}
else
{
g_sf_conf->interactive_starttime_ms = 15000;
}
toml_val = toml_int_in(cfg_tbl, "INTERACTIVE_PULSE_NUM");
if (toml_val.ok)
{
g_sf_conf->interactive_pulse_num = toml_val.u.i;
}
else
{
g_sf_conf->interactive_pulse_num = 4;
}
toml_val = toml_int_in(cfg_tbl, "INTERACTIVE_LATENCY_MS");
if (toml_val.ok)
{
g_sf_conf->interactive_latency_ms = toml_val.u.i;
}
else
{
g_sf_conf->interactive_latency_ms = 1000;
}
toml_val = toml_int_in(cfg_tbl, "MAIN_DIR_FRONT_N_PKTS");
if (toml_val.ok)
{
g_sf_conf->main_dir_front_n_pkts = toml_val.u.i;
}
else
{
g_sf_conf->main_dir_front_n_pkts = 100;
}
toml_val = toml_int_in(cfg_tbl, "LARGE_PKTS_INIT_SIZE");
if (toml_val.ok)
{
g_sf_conf->large_ptks_init_size = toml_val.u.i;
}
else
{
g_sf_conf->large_ptks_init_size = 1000;
}
toml_val = toml_int_in(cfg_tbl, "SESSION_MAX_PROCESS_TIME_MS");
if (toml_val.ok)
{
g_sf_conf->session_max_process_time_ms = toml_val.u.i;
}
else
{
g_sf_conf->session_max_process_time_ms = 30000;
}
toml_val = toml_int_in(cfg_tbl, "FET_ENABLED");
if (toml_val.ok)
{
g_sf_conf->fet_enabled = toml_val.u.b;
}
else
{
g_sf_conf->fet_enabled = 1;
}
toml_val = toml_int_in(cfg_tbl, "RANDOM_LOOKING_UDP_IGNORE_PKTS");
if (toml_val.ok)
{
g_sf_conf->random_looking_udp_ignore_pkts = toml_val.u.i;
}
else
{
g_sf_conf->random_looking_udp_ignore_pkts = 3;
}
toml_val = toml_int_in(cfg_tbl, "TUNNELING_TLS_IGNORE_PKTS");
if (toml_val.ok)
{
g_sf_conf->tunneling_tls_ignore_pkts = toml_val.u.i;
}
else
{
g_sf_conf->tunneling_tls_ignore_pkts = 4;
}
toml_val = toml_int_in(cfg_tbl, "TUNNELING_MAX_SCAN_PKTS");
if (toml_val.ok)
{
g_sf_conf->tunneling_max_scan_pkts = toml_val.u.i;
}
else
{
g_sf_conf->tunneling_max_scan_pkts = 15;
}
toml_val = toml_string_in(cfg_tbl, "TUNNELING_PCRE_LIST");
if (toml_val.ok)
{
strncpy(g_sf_conf->tunneling_pcre_list, toml_val.u.s, sizeof(g_sf_conf->tunneling_pcre_list) - 1);
}
else
{
strncpy(g_sf_conf->tunneling_pcre_list, "{\"tunneling_pcre_list\":[]}", sizeof(g_sf_conf->tunneling_pcre_list) - 1);
}
toml_val = toml_string_in(cfg_tbl, "RANDOM_LOOKING_JUDGE_LIST");
if (toml_val.ok)
{
strncpy(g_sf_conf->random_looking_judge_list, toml_val.u.s, sizeof(g_sf_conf->random_looking_judge_list) - 1);
}
else
{
strncpy(g_sf_conf->random_looking_judge_list, "{\"random_looking_judge_list\":[]}", sizeof(g_sf_conf->random_looking_judge_list) - 1);
}
}
extern "C" void *session_flags_plugin_init(struct stellar *st)
{
char random_looking_list_str[2048] = {0};
struct session_flags_plugin_info *sf_plugin_info = (struct session_flags_plugin_info *)calloc(1, sizeof(struct session_flags_plugin_info));
cJSON *json = NULL, *item = NULL;
int array_num;
sf_plugin_info->st = st;
sf_plugin_info->sess_ctx_exdata_idx = stellar_exdata_new_index(st, "SESSION_FLAGS_SESS_CTX", session_flags_exdata_free_cb, NULL);
sf_plugin_info->log_handle = stellar_get_logger(st);
if(sf_plugin_info->log_handle==NULL)
{
printf("stellar_get_logger object failed ...\n");
goto ERROR;
}
memset(&g_sf_conf, 0, sizeof(g_sf_conf));
session_flags_load_config(sf_plugin_info, CFG_FILE_PATH, &g_sf_conf);
tunneling_hyperscan_engine_init(sf_plugin_info, &g_sf_conf);
json = cJSON_Parse(g_sf_conf.random_looking_judge_list);
if (json == NULL)
{
STELLAR_LOG_FATAL(sf_plugin_info->log_handle, SESSION_FLAGS_LOG_MODULE, "cJSON_Parse failed, random_looking_list_str:%s", random_looking_list_str);
goto ERROR;
}
item = cJSON_GetObjectItem(json, "random_looking_judge_list");
if (item == NULL)
{
STELLAR_LOG_FATAL(sf_plugin_info->log_handle, SESSION_FLAGS_LOG_MODULE, "cJSON_GetObjectItem failed, random_looking_list_str:%s", random_looking_list_str);
goto ERROR;
}
array_num = cJSON_GetArraySize(item);
if (array_num > STS_RANDOM_JUDGE_NUM || array_num < 0)
{
STELLAR_LOG_FATAL(sf_plugin_info->log_handle, SESSION_FLAGS_LOG_MODULE, "array size error, array_num:%d", array_num);
goto ERROR;
}
for (int i = 0; i < array_num; i++)
{
for (int j = 0; j < STS_RANDOM_JUDGE_NUM; j++)
{
if (strcmp(cJSON_GetArrayItem(item, i)->valuestring, random_looking_judge_table[j]) == 0)
{
STS_SET_FLAG(sts_random_switch, j);
g_sf_conf.random_judge_flags_cnt++;
break;
}
}
}
cJSON_Delete(json);
sf_plugin_info->plugin_id = stellar_session_plugin_register(st, NULL, NULL, sf_plugin_info);
if (sf_plugin_info->plugin_id < 0)
{
STELLAR_LOG_FATAL(sf_plugin_info->log_handle, SESSION_FLAGS_LOG_MODULE, "stellar_session_plugin_register failed");
goto ERROR;
}
sf_plugin_info->session_flags_topic_id = stellar_mq_create_topic(st, SESSION_FLAGS_MESSAGE_TOPIC, session_flags_topic_free_cb, NULL);
if (sf_plugin_info->session_flags_topic_id < 0)
{
STELLAR_LOG_FATAL(sf_plugin_info->log_handle, SESSION_FLAGS_LOG_MODULE, "stellar_session_mq_create_topic failed");
goto ERROR;
}
sf_plugin_info->tcp_topic_id = stellar_mq_get_topic_id(st, TOPIC_TCP_INPUT);
sf_plugin_info->udp_topic_id = stellar_mq_get_topic_id(st, TOPIC_UDP_INPUT);
if (sf_plugin_info->tcp_topic_id < 0 || sf_plugin_info->udp_topic_id < 0)
{
STELLAR_LOG_FATAL(sf_plugin_info->log_handle, SESSION_FLAGS_LOG_MODULE, "stellar_session_mq_get_topic_id failed");
goto ERROR;
}
stellar_session_mq_subscribe(st, sf_plugin_info->tcp_topic_id, session_flags_entry, sf_plugin_info->plugin_id);
stellar_session_mq_subscribe(st, sf_plugin_info->udp_topic_id, session_flags_entry, sf_plugin_info->plugin_id);
return sf_plugin_info;
ERROR:
if (sf_plugin_info != NULL)
{
free(sf_plugin_info);
}
if (json != NULL)
{
cJSON_Delete(json);
}
perror("session_flags init failed");
exit(-1);
}
extern "C" void session_flags_plugin_exit(void *plugin_ctx)
{
if (plugin_ctx == NULL)
{
return;
}
struct session_flags_plugin_info *sf_plugin_info = (struct session_flags_plugin_info *)plugin_ctx;
tunneling_hyperscan_engine_exit(sf_plugin_info->tunneling_hs_db);
free(plugin_ctx);
return;
}

View File

@@ -0,0 +1,217 @@
#include <cctype>
#include <stdlib.h>
#include <stdio.h>
#include "cJSON.h"
#include "session_flags_internal.h"
#include "tunneling.h"
#include "stellar/log.h"
#define UNUSED(x) (void)(x)
thread_local hs_scratch_t *hs_scratch = NULL;
extern struct session_flags_init_conf g_sf_conf;
static char tunneling_length_to_character(enum flow_type flow_type, size_t len)
{
char ret;
switch(len)
{
case 1 ... 200:
ret = 'A';
break;
case 201 ... 600:
ret = 'B';
break;
case 601 ... 1000:
ret = 'C';
break;
case 1001 ... 1460:
ret = 'D';
break;
default:
ret = 'Z';
break;
}
if (flow_type == FLOW_TYPE_C2S)
{
return ret;
}
else
{
return tolower(ret);
}
}
static int tunneling_match_event_handler(unsigned int id, unsigned long long from, unsigned long long to, unsigned int flags, void *context) {
UNUSED(id);
UNUSED(from);
UNUSED(to);
UNUSED(flags);
struct session_flags_ctx *ctx = (struct session_flags_ctx *)context;
ctx->stat.result.flags |= SESSION_FLAGS_TUNNELING;
return 0;
}
int tunneling_scan_sequence(struct session_flags_plugin_info *sf_plugin_info, struct session *session, struct session_flags_ctx *ctx, size_t payload_len, enum flow_type flow_type, uint64_t pkts_cnt)
{
if (ctx->stat.result.flags & SESSION_FLAGS_TUNNELING)
{
return 0;
}
ctx->stat.tunneling_stat.payload_pkt_num++;
if (ctx->stat.result.is_tls && ctx->stat.tunneling_stat.payload_pkt_num <= g_sf_conf.tunneling_tls_ignore_pkts)
{
return 0;
}
if((ctx->stat.result.is_tls==0) && (ctx->stat.tunneling_stat.payload_pkt_num > g_sf_conf.tunneling_max_scan_pkts))
{
return 0;
}
if((ctx->stat.result.is_tls) && (ctx->stat.tunneling_stat.payload_pkt_num > g_sf_conf.tunneling_max_scan_pkts+g_sf_conf.tunneling_tls_ignore_pkts))
{
return 0;
}
if (hs_scratch == NULL)
{
hs_error_t err = hs_alloc_scratch(sf_plugin_info->tunneling_hs_db, &hs_scratch);
if (err != HS_SUCCESS)
{
STELLAR_LOG_FATAL(sf_plugin_info->log_handle, SESSION_FLAGS_LOG_MODULE, "hs_alloc_scratch failed, err:%d", err);
return -1;
}
}
char tunneling_seq_char = tunneling_length_to_character(flow_type, payload_len);
STELLAR_LOG_DEBUG(sf_plugin_info->log_handle, SESSION_FLAGS_LOG_MODULE, "session: %s, is tls:%s, total_num: %d, payload_pkt_num: %d, tunneling_seq_char:%c, payload_len:%d",
session_get0_readable_addr(session), ctx->stat.result.is_tls == true ? "yes":"no", pkts_cnt, ctx->stat.tunneling_stat.payload_pkt_num, tunneling_seq_char, payload_len);
hs_error_t err = hs_scan_stream(ctx->tunneling_hs_stream, &tunneling_seq_char, 1, 0, hs_scratch, tunneling_match_event_handler, ctx);
if (err != HS_SUCCESS)
{
STELLAR_LOG_FATAL(sf_plugin_info->log_handle, SESSION_FLAGS_LOG_MODULE, "hs_scan_stream failed, err:%d", err);
return -1;
}
if (ctx->stat.result.flags & SESSION_FLAGS_TUNNELING)
{
ctx->stat.result.identify[session_flags_tunneling_mask] = pkts_cnt;
}
return 0;
}
void tunneling_hs_stream_init(struct session_flags_plugin_info *sf_plugin_info, struct session_flags_ctx *ctx)
{
hs_error_t err = hs_open_stream(sf_plugin_info->tunneling_hs_db, 0, &ctx->tunneling_hs_stream);
if (err != HS_SUCCESS)
{
STELLAR_LOG_FATAL(sf_plugin_info->log_handle, SESSION_FLAGS_LOG_MODULE, "hs_open_stream failed, err:%d", err);
return;
}
}
void tunneling_hs_stream_free(struct session_flags_ctx *ctx)
{
if (ctx->tunneling_hs_stream == NULL)
{
return;
}
hs_close_stream(ctx->tunneling_hs_stream, hs_scratch, NULL, NULL);
}
int tunneling_hyperscan_engine_init(struct session_flags_plugin_info *sf_plugin_info, struct session_flags_init_conf *g_sf_conf)
{
cJSON *json = NULL, *item = NULL;
int array_num;
char **pcre = NULL;
hs_compile_error_t *compile_err;
hs_error_t err;
unsigned int *flags = NULL;
unsigned int *ids = NULL;
int ret = 0;
g_sf_conf->tunneling_enabled = 0;
json = cJSON_Parse(g_sf_conf->tunneling_pcre_list);
if (json == NULL)
{
STELLAR_LOG_FATAL(sf_plugin_info->log_handle, SESSION_FLAGS_LOG_MODULE, "cJSON_Parse failed, tunneling_pcre_list:%s", g_sf_conf->tunneling_pcre_list);
goto END;
}
item = cJSON_GetObjectItem(json, "tunneling_pcre_list");
if (item == NULL)
{
STELLAR_LOG_FATAL(sf_plugin_info->log_handle, SESSION_FLAGS_LOG_MODULE, "cJSON_GetObjectItem failed, tunneling_pcre_list:%s", g_sf_conf->tunneling_pcre_list);
goto END;
}
array_num = cJSON_GetArraySize(item);
if (array_num < 0)
{
STELLAR_LOG_FATAL(sf_plugin_info->log_handle, SESSION_FLAGS_LOG_MODULE, "array size error, array_num:%d", array_num);
goto END;
}
if (array_num == 0)
{
goto END;
}
g_sf_conf->tunneling_enabled = 1;
pcre = (char **)calloc(array_num, sizeof(char *));
for (int i = 0; i < array_num; i++)
{
pcre[i] = cJSON_GetArrayItem(item, i)->valuestring;
}
flags = (unsigned int *)calloc(array_num, sizeof(unsigned int));
ids = (unsigned int *)calloc(array_num, sizeof(unsigned int));
for (int i = 0; i < array_num; i++)
{
flags[i] = HS_FLAG_DOTALL;
ids[i] = i;
}
err = hs_compile_multi(pcre, flags, ids, array_num, HS_MODE_STREAM, NULL, &sf_plugin_info->tunneling_hs_db, &compile_err);
if (err != HS_SUCCESS)
{
STELLAR_LOG_FATAL(sf_plugin_info->log_handle, SESSION_FLAGS_LOG_MODULE, "hs_compile_multi failed, err:%d, pattern id: %d, err_msg: %s, pattern: %s", err, compile_err->expression, compile_err->message, pcre[compile_err->expression]);
cJSON_Delete(json);
free(pcre);
ret = -1;
goto END;
}
END:
if (json != NULL)
{
cJSON_Delete(json);
}
if (pcre != NULL)
{
free(pcre);
}
if (flags != NULL)
{
free(flags);
}
if (ids != NULL)
{
free(ids);
}
return ret;
}
void tunneling_hyperscan_engine_exit(hs_database_t *tunneling_hs_db)
{
if (tunneling_hs_db != NULL)
{
hs_free_database(tunneling_hs_db);
}
}

View File

@@ -0,0 +1,18 @@
#pragma once
#include <cstdint>
#include <stdlib.h>
#include <hs/hs_common.h>
#include <hs/hs.h>
#include "stellar/session.h"
struct tunneling_stat_info
{
uint8_t payload_pkt_num;
};
int tunneling_scan_sequence(struct session_flags_plugin_info *sf_plugin_info, struct session *session, struct session_flags_ctx *ctx, size_t payload_len, flow_type flow_type, uint64_t pkts_cnt);
void tunneling_hs_stream_init(struct session_flags_plugin_info *sf_plugin_info, struct session_flags_ctx *ctx);
void tunneling_hs_stream_free(struct session_flags_ctx *ctx);
int tunneling_hyperscan_engine_init(struct session_flags_plugin_info *sf_plugin_info, struct session_flags_init_conf *g_sf_conf);
void tunneling_hyperscan_engine_exit(hs_database_t *tunneling_hs_db);

View File

@@ -0,0 +1,13 @@
add_definitions(-fPIC)
set(SOCKS_SRC socks_decoder.cpp)
add_library(socks STATIC ${SOCKS_SRC})
add_library(socks_dyn SHARED ${SOCKS_SRC})
set_target_properties(socks PROPERTIES LINK_FLAGS "-Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/version.map")
target_include_directories(socks PUBLIC ${CMAKE_SOURCE_DIR}/deps/)
target_link_libraries(socks toml)
set_target_properties(socks PROPERTIES PREFIX "")
set_target_properties(socks_dyn PROPERTIES PREFIX "")
target_link_libraries(socks_dyn toml)

View File

@@ -0,0 +1,527 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
extern "C" {
#include "stellar/stellar.h"
#include "stellar/session.h"
#include "stellar/stellar_mq.h"
#include "stellar/stellar_exdata.h"
}
#include "socks_decoder_internal.h"
#include "stellar/log.h"
#define UNUSED(x) (void)(x)
static void socks_decoder_session_exdata_free(int idx, void *ex_ptr, void *arg)
{
UNUSED(idx);
UNUSED(arg);
if (ex_ptr == NULL)
{
return;
}
free(ex_ptr);
return;
}
//packet format refer to https://zh.wikipedia.org/wiki/SOCKS
static int socks_rough_rec(const char *payload, size_t payload_len)
{
//for socks4
if (payload_len < SOCKS5_REQUEST_METHOD_MIN_LEN)
{
return -1;
}
if (payload[0] == SOCKS_FIELD_VER_4 && payload[payload_len-1] == 0)
{
if (payload_len >= 9)
{
return 0;
}
}
if (payload[0] == SOCKS_FIELD_VER_5)
{
if (2 + (unsigned int)payload[1] == payload_len)
{
return 0;
}
}
return -1;
}
static int socks5_method_request(const char *payload, size_t payload_len)
{
if (payload_len < SOCKS5_REQUEST_METHOD_MIN_LEN)
{
return -1;
}
if (payload[0] != SOCKS_FIELD_VER_5)
{
return -1;
}
if ((size_t)(2 + payload[1]) != payload_len)
{
return -1;
}
return 0;
}
static int socks4_request(struct socks_tunnel_stream *stream, const char *payload, size_t payload_len)
{
if (payload_len < 9)
return -1;
if (payload[0] != SOCKS_FIELD_VER_4 || payload[payload_len-1] != 0)
return -1;
struct socks_addr *addr = &(stream->info.dst_addr);
memcpy(&(addr->port), payload + 2, 2);
memcpy(&(addr->ipv4), payload + 4, 4);
if (addr->ipv4 & 0x00FFFFFF)
{
addr->type = SOCKS_ADDR_IPV4;
return 0;
}
else if (addr->ipv4 & 0xFF000000)//socks4a hostname
{
size_t pos = 8;
while (pos < payload_len - 2 && payload[pos] != 0)
{
pos++;
}
if (payload[pos] == 0)
{
if (payload_len - 1 - pos < 2)
return -1;
addr->fqdn.iov_len = payload_len - 1 - pos - 1;
addr->fqdn.iov_base = (unsigned char *)calloc(1, addr->fqdn.iov_len + 1);
memcpy(addr->fqdn.iov_base, payload+pos+1, addr->fqdn.iov_len);
addr->type = SOCKS_ADDR_FQDN;
return 0;
}
else
{
return -1;
}
}
return -1;
}
static int socks5_request(struct socks_tunnel_stream *stream, const char *payload, size_t payload_len)
{
unsigned int port_offset = 0;
struct socks_addr *addr = &(stream->info.dst_addr);
if (payload_len < SOCKS5_REQUEST_MIN_LEN)
{
return -1;
}
if (payload[0] != SOCKS_FIELD_VER_5)
{
return -1;
}
if (payload[1] != SOCKS_CMD_CONNECT && payload[1] != SOCKS_CMD_BIND)
{
return -1;
}
if (payload[2] != SOCKS5_RSV_DEFAULT)
{
return -1;
}
switch (payload[3])
{
case SOCKS_ATYPE_IP4:
{
if (payload_len != 10)
{
return -1;
}
addr->type = SOCKS_ADDR_IPV4;
memcpy(&(addr->ipv4), payload+4, 4);
port_offset = 8;
break;
}
//should be processed
case SOCKS_ATYPE_IP6:
{
if(payload_len != 22)
{
return -1;
}
addr->type = SOCKS_ADDR_IPV6;
memcpy(addr->ipv6, payload+4, 16);
port_offset = 20;
break;
}
case SOCKS_ATYPE_FQDN:
{
if (payload[4] < 0 || payload_len != (size_t)(7 + payload[4]))
{
return -1;
}
addr->type = SOCKS_ADDR_FQDN;
addr->fqdn.iov_len = payload[4];
addr->fqdn.iov_base = (char *)calloc(1, addr->fqdn.iov_len + 1);
memcpy(addr->fqdn.iov_base, payload+5, payload[4]);
port_offset = 5 + payload[4];
}
break;
default:
break;
}
memcpy(&(addr->port), payload+port_offset, 2);
return 0;
}
static int socks5_pass_request(struct socks_tunnel_stream *stream, const char *payload, size_t payload_len)
{
unsigned char *ubuf = (unsigned char*)payload;
unsigned char *cur;
struct socks_info *info = &stream->info;
if (ubuf[0]!=1)
{
return -1;
}
if (payload_len < 2 || payload_len < (size_t)(3+ubuf[1]) || payload_len != (size_t)(3+ubuf[1]+ubuf[2+ubuf[1]]))
{
return -1;
}
info->user_name.iov_len = ubuf[1];
info->user_name.iov_base = (char *)calloc(1, info->user_name.iov_len + 1);
memcpy(info->user_name.iov_base, ubuf+2, info->user_name.iov_len);
info->password.iov_len = ubuf[2+ubuf[1]];
info->password.iov_base = (char *)calloc(1, info->password.iov_len + 1);
cur = ubuf + 2 + info->user_name.iov_len + 1;
memcpy(info->password.iov_base, cur, info->password.iov_len);
return 0;
}
static void c2s_handler(struct socks_tunnel_stream *stream, const char *payload, size_t payload_len)
{
switch (stream->client_state)
{
case SS_BEGIN:
if (socks5_method_request(payload, payload_len) == 0)
{
stream->client_state = SS_SUB;
stream->info.version = SOCKS_VERSION_5;
}
else if (socks4_request(stream, payload, payload_len) == 0)
{
stream->client_state = SS_END;
stream->info.version = SOCKS_VERSION_4;
}
else
{
stream->client_state = SS_FAILED;
}
break;
case SS_SUB:
if (socks5_request(stream, payload, payload_len) == 0)
{
stream->client_state = SS_END;
}
else if (socks5_pass_request(stream, payload, payload_len) != 0)
{
stream->client_state = SS_FAILED;
}
break;
default:
break;
}
}
static int socks5_method_replay(const char *payload, size_t payload_len)
{
if (payload_len != 2)
{
return -1;
}
if (payload[0] != SOCKS_FIELD_VER_5)
{
return -1;
}
if (payload[1] != 0 && payload[1]!=2)
{
return -1;
}
////printf("socks5 method replay!\n");
return 0;
}
static int socks4_replay(const char *payload, size_t payload_len)
{
if (payload_len != 8)
return -1;
if (payload[0] != 0 || payload[1] < 90 || payload[1] > 93)
return -1;
return 0;
}
static int socks5_replay(const char *payload, size_t payload_len)
{
if (payload_len < 6)
{
return -1;
}
if (payload[0] != SOCKS_FIELD_VER_5)
{
return -1;
}
if (payload[1] != 0)
{
return -1;
}
if (payload[2] != 0)
{
return -1;
}
switch(payload[3])
{
case SOCKS_ATYPE_IP4:
if (payload_len < 10)
{
return -1;
}
break;
case SOCKS_ATYPE_IP6:
if (payload_len != 22)
{
return -1;
}
break;
case SOCKS_ATYPE_FQDN:
if (payload[4] < 0 || payload_len < (size_t)(7 + payload[4]))
{
return -1;
}
break;
default:
return -1;
}
return 0;
}
static int socks5_pass_reply(const char *payload, size_t payload_len)
{
if (payload_len != 2)
return -1;
if (payload[0] != 1 || payload[1] != 0)
return -1;
return 0;
}
static void s2c_handler(struct socks_tunnel_stream *stream, const char *payload, size_t payload_len)
{
switch (stream->server_state)
{
case SS_BEGIN:
if (stream->info.version == SOCKS_VERSION_5 && socks5_method_replay(payload, payload_len) == 0)
{
stream->server_state = SS_SUB;
}
else if (stream->info.version == SOCKS_VERSION_4 && socks4_replay(payload, payload_len) == 0)
{
stream->server_state = SS_END;
}
else
{
stream->server_state = SS_FAILED;
//printf("socks error, s2c beign\n");
}
break;
case SS_SUB:
if (socks5_replay(payload, payload_len) == 0)
{
stream->server_state = SS_END;
}
else if (socks5_pass_reply(payload, payload_len) != 0)
{
stream->server_state = SS_FAILED;
//printf("socks error, s2c sub\n");
}
break;
default:
//error!
break;
}
}
int socks_process(struct socks_decoder_info *socks_decoder_info, struct session *sess, struct socks_tunnel_stream *stream, const char *payload, size_t payload_len)
{
if (payload_len == 0)
{
return 0;
}
switch(stream->state)
{
case STATE_INIT:
if (socks_rough_rec(payload, payload_len) < 0)
{
stream->state = STATE_FAILED;
return -1;
}
stream->state = STATE_OPENING;
[[fallthrough]];//continue execute STATE_OPENING
case STATE_OPENING:
switch (session_get_flow_type(sess))
{
case FLOW_TYPE_C2S:
c2s_handler(stream, payload, payload_len);
break;
case FLOW_TYPE_S2C:
s2c_handler(stream, payload, payload_len);
break;
default:
break;
}
if (stream->client_state == SS_END && stream->server_state == SS_END)
{
if (session_mq_publish_message(sess, socks_decoder_info->socks_decoder_topic_id, &stream->info) < 0)
{
STELLAR_LOG_FATAL(socks_decoder_info->log_handle, SOCKS_LOG_MOUDLE, "session_mq_publish_message OPENING failed");
}
stellar_session_plugin_dettach_current_session(sess);
}
else if (stream->client_state == SS_FAILED || stream->server_state == SS_FAILED)
{
//not a socks proxy
stream->state = STATE_FAILED;
return -1;
}
break;
default:
return -1;
}
return 0;
}
void socks_decoder_on_message(struct session *sess, int topic_id, const void *msg, void *per_session_ctx, void *plugin_env)
{
UNUSED(per_session_ctx);
UNUSED(topic_id);
UNUSED(msg);
struct socks_decoder_info *socks_decoder_info = (struct socks_decoder_info *)plugin_env;
struct socks_tunnel_stream *socks_tunel_stream = (struct socks_tunnel_stream *)session_exdata_get(sess, socks_decoder_info->sess_exdata_idx);
const char *payload = NULL;
size_t payload_len = 0;
const struct packet *pkt = NULL;
if (socks_tunel_stream == NULL)
{
socks_tunel_stream = (struct socks_tunnel_stream *)calloc(1, sizeof(struct socks_tunnel_stream));
session_exdata_set(sess, socks_decoder_info->sess_exdata_idx, socks_tunel_stream);
}
pkt = session_get0_current_packet(sess);
payload = packet_get_payload(pkt);
payload_len = packet_get_payload_len(pkt);
if (socks_process(socks_decoder_info, sess, socks_tunel_stream, payload, payload_len) < 0)
{
stellar_session_plugin_dettach_current_session(sess);
}
}
extern "C" void *socks_decoder_init(struct stellar *st)
{
struct socks_decoder_info *socks_decoder_info = (struct socks_decoder_info *)calloc(1, sizeof(struct socks_decoder_info));
socks_decoder_info->sess_exdata_idx= stellar_exdata_new_index(st, "SOCKS_DECODER_SESS_CTX", socks_decoder_session_exdata_free, NULL);
socks_decoder_info->st = st;
socks_decoder_info->log_handle = stellar_get_logger(st);
socks_decoder_info->plugin_id = stellar_session_plugin_register(st, NULL, NULL, socks_decoder_info);
if (socks_decoder_info->plugin_id < 0)
{
STELLAR_LOG_FATAL(socks_decoder_info->log_handle, SOCKS_LOG_MOUDLE, "stellar_session_plugin_register failed");
goto ERROR;
}
socks_decoder_info->socks_decoder_topic_id = stellar_mq_create_topic(st, SOCKS_MESSAGE_TOPIC, NULL, NULL);
if (socks_decoder_info->socks_decoder_topic_id < 0)
{
STELLAR_LOG_FATAL(socks_decoder_info->log_handle, SOCKS_LOG_MOUDLE, "stellar_session_mq_create_topic failed");
goto ERROR;
}
socks_decoder_info->tcp_topic_id = stellar_mq_get_topic_id(st, TOPIC_TCP_STREAM);
if (socks_decoder_info->tcp_topic_id < 0)
{
STELLAR_LOG_FATAL(socks_decoder_info->log_handle, SOCKS_LOG_MOUDLE, "stellar_session_mq_get_topic_id failed");
goto ERROR;
}
if (stellar_session_mq_subscribe(st, socks_decoder_info->tcp_topic_id, socks_decoder_on_message, socks_decoder_info->plugin_id) < 0)
{
STELLAR_LOG_FATAL(socks_decoder_info->log_handle, SOCKS_LOG_MOUDLE, "stellar_session_mq_subscribe tcp_topic_id failed");
goto ERROR;
}
return socks_decoder_info;
ERROR:
if (socks_decoder_info != NULL)
{
free(socks_decoder_info);
}
perror("socks_decoder init failed");
exit(-1);
}
extern "C" void socks_decoder_exit(void *plugin_env)
{
struct socks_decoder_info *socks_decoder_info = (struct socks_decoder_info *)plugin_env;
if (socks_decoder_info != NULL)
{
free(socks_decoder_info);
}
return;
}

View File

@@ -0,0 +1,56 @@
#include "stellar/socks_decoder.h"
#define SOCKS_FIELD_VER_4 4
#define SOCKS_FIELD_VER_5 5
#define SOCKS5_REQUEST_METHOD_MIN_LEN 3
#define SOCKS5_REQUEST_MIN_LEN 6
#define SOCKS_VERSION_TYPE_SOCKS4 4
#define SOCKS_VERSION_TYPE_SOCKS5 5
#define SOCKS_CMD_CONNECT 0x01
#define SOCKS_CMD_BIND 0x02
#define SOCKS_CMD_UDP 0x03
#define SOCKS5_RSV_DEFAULT 0
#define SOCKS_ATYPE_IP4 1
#define SOCKS_ATYPE_IP6 4
#define SOCKS_ATYPE_FQDN 3
#define SOCKS5_AUTH_NONE 0x00
#define SOCKS5_AUTH_PASS 0x02
#define SOCKS_LOG_MOUDLE "SOCKS_DECODER"
struct socks_decoder_info
{
int plugin_id;
int sess_exdata_idx;
struct stellar *st;
struct logger *log_handle;
int socks_decoder_topic_id;
int tcp_topic_id;
};
enum socks_establish_state
{
SS_BEGIN = 0,
SS_SUB,
SS_END,
SS_FAILED
};
enum socks_internal_state
{
STATE_INIT,
STATE_OPENING,
STATE_FAILED
};
struct socks_tunnel_stream
{
enum socks_internal_state state;
enum socks_establish_state client_state;
enum socks_establish_state server_state;
struct socks_info info;
};

View File

@@ -0,0 +1,14 @@
add_definitions(-fPIC)
include_directories(${CMAKE_SOURCE_DIR}/deps)
include_directories(${CMAKE_BINARY_DIR}/vendors/cjson/src/cjson/include)
set(STRATUM_SRC stratum_decoder.cpp)
add_library(stratum STATIC ${STRATUM_SRC})
add_library(stratum_dyn SHARED ${STRATUM_SRC})
set_target_properties(stratum PROPERTIES LINK_FLAGS "-Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/version.map")
set_target_properties(stratum PROPERTIES PREFIX "")
target_link_libraries(stratum_dyn)
set_target_properties(stratum_dyn PROPERTIES PREFIX "")

View File

@@ -0,0 +1,311 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "cJSON.h"
#include "stellar/stellar.h"
#include "stellar/session.h"
#include "stellar/stellar_mq.h"
#include "stellar/stellar_exdata.h"
#include "stellar/stratum_decoder.h"
#include "stellar/log.h"
#define unused(x) ((void)(x))
#define STRATUM_LOG_MOUDLE "STRATUM_DECODER"
//字段内容宏
#define METHOD_STR "method"
#define WORKER_STR "worker"
#define PARAMS_STR "params"
#define AGENT_STR "agent"
enum stratum_field_type
{
CRYPTOCURRENCY_FLAG = 1,
MINING_POOL_FLAG,
MINING_PROGRAM_FLAG,
MINING_SUBSCRIBE_FLAG,
};
struct stratum_decoder_info
{
int plugin_id;
struct stellar *st;
struct logger *log_handle;
int tcp_topic_id;
int stratum_decoder_topic_id;
};
void free_stratum_filed(struct stratum_field *stratum_field)
{
if(stratum_field!=NULL){
if(stratum_field->mining_program.iov_base != NULL){
free(stratum_field->mining_program.iov_base);
stratum_field->mining_program.iov_len = 0;
}
if(stratum_field->mining_pools.iov_base != NULL){
free(stratum_field->mining_pools.iov_base);
stratum_field->mining_pools.iov_len = 0;
}
if(stratum_field->mining_subscribe.iov_base != NULL){
free(stratum_field->mining_subscribe.iov_base);
stratum_field->mining_subscribe.iov_len = 0;
}
free(stratum_field);
}
return;
}
void stratum_decoder_session_msg_free_cb(void *msg, void *msg_free_arg)
{
unused(msg_free_arg);
struct stratum_field *stratum_field = (struct stratum_field *)msg;
free_stratum_filed(stratum_field);
return;
}
int stratum_field_assign(char *content, struct stratum_field* stratum_field,int field_range)
{
switch (field_range)
{
case MINING_POOL_FLAG:
stratum_field->mining_pools.iov_len=strlen(content);
stratum_field->mining_pools.iov_base=(char*)malloc(stratum_field->mining_pools.iov_len+1);
memcpy(stratum_field->mining_pools.iov_base, content, stratum_field->mining_pools.iov_len);
((char*)stratum_field->mining_pools.iov_base)[stratum_field->mining_pools.iov_len]='\0';
break;
case MINING_PROGRAM_FLAG:
stratum_field->mining_program.iov_len=strlen(content);
stratum_field->mining_program.iov_base=(char*)malloc(stratum_field->mining_program.iov_len+1);
memcpy(stratum_field->mining_program.iov_base, content, stratum_field->mining_program.iov_len);
((char*)stratum_field->mining_program.iov_base)[stratum_field->mining_program.iov_len]='\0';
break;
case MINING_SUBSCRIBE_FLAG:
stratum_field->mining_subscribe.iov_len=strlen(content);
stratum_field->mining_subscribe.iov_base=(char*)malloc(stratum_field->mining_subscribe.iov_len+1);
memcpy(stratum_field->mining_subscribe.iov_base, content,stratum_field->mining_subscribe.iov_len);
((char*)stratum_field->mining_subscribe.iov_base)[stratum_field->mining_subscribe.iov_len]='\0';
break;
default:
return -1;
}
return 0;
}
struct stratum_field *stratum_json_decode(struct stratum_decoder_info *stratum_decoder_info, char *raw_json_str)
{
if(raw_json_str==NULL){
STELLAR_LOG_INFO(stratum_decoder_info->log_handle, STRATUM_LOG_MOUDLE, "json_decode error!:raw_json_str is null! ");
return NULL;
}
cJSON *root = cJSON_Parse(raw_json_str);
if (root == NULL){
STELLAR_LOG_INFO(stratum_decoder_info->log_handle, STRATUM_LOG_MOUDLE, "json_decode error!:root_json is null,error: %s ",cJSON_GetErrorPtr());
return NULL;
}
cJSON *method_item = cJSON_GetObjectItem(root, METHOD_STR);
if(method_item==NULL){
STELLAR_LOG_INFO(stratum_decoder_info->log_handle, STRATUM_LOG_MOUDLE, "json_decode error!:not_found '%s' in raw_json_str ", METHOD_STR);
cJSON_Delete(root);
return NULL;
}
struct stratum_field *stratum_field = (struct stratum_field *)calloc(1, sizeof(struct stratum_field));
int field_range = 0;
if(cJSON_IsString(method_item)){
int assign_ret = 0;
STELLAR_LOG_DEBUG(stratum_decoder_info->log_handle, STRATUM_LOG_MOUDLE, "json_decode,find '%s':%s\n", METHOD_STR, method_item->valuestring);
if((strncasecmp("mining.subscribe", method_item->valuestring,strlen("mining.subscribe")) == 0)
||(strncasecmp("login", method_item->valuestring,strlen("login")) == 0)){
field_range = MINING_SUBSCRIBE_FLAG;
assign_ret = stratum_field_assign(raw_json_str, stratum_field, field_range);
cJSON *paras_item = cJSON_GetObjectItem(root, PARAMS_STR);
if(paras_item == NULL){
STELLAR_LOG_INFO(stratum_decoder_info->log_handle, STRATUM_LOG_MOUDLE, "json_decode:error!not_found '%s' in raw_json_str ", PARAMS_STR);
goto err_ret;
}
if(cJSON_IsArray(paras_item)){
int asize = cJSON_GetArraySize(paras_item);
stratum_field->type = OTHER;
cJSON *array_item = cJSON_GetArrayItem(paras_item, 0);
if(cJSON_IsString(array_item)){
field_range = MINING_PROGRAM_FLAG;
assign_ret = stratum_field_assign(array_item->valuestring, stratum_field, field_range);
}
if(asize>2){
array_item = cJSON_GetArrayItem(paras_item, 2);
if(cJSON_IsString(array_item)){
field_range = MINING_POOL_FLAG;
assign_ret = stratum_field_assign(array_item->valuestring, stratum_field, field_range);
}
}
}else if(cJSON_IsObject(paras_item) || cJSON_IsRaw(paras_item)){
cJSON *agent_item = cJSON_GetObjectItem(paras_item, AGENT_STR);
if(agent_item == NULL){
STELLAR_LOG_INFO(stratum_decoder_info->log_handle, STRATUM_LOG_MOUDLE, "json_decode:error!not_found '%s' in raw_json_str ", AGENT_STR);
goto err_ret;
}
if(cJSON_IsString(agent_item)){
field_range = MINING_PROGRAM_FLAG;
stratum_field->type = OTHER;
assign_ret = stratum_field_assign(agent_item->valuestring, stratum_field, field_range);
}
}else{
STELLAR_LOG_INFO(stratum_decoder_info->log_handle, STRATUM_LOG_MOUDLE, "json_decode:error!found '%s',json_value_type:%d\n ", PARAMS_STR, paras_item->type);
goto err_ret;
}
}else if(strncasecmp("eth_submitLogin", method_item->valuestring, strlen("eth_submitLogin")) == 0){
field_range = MINING_SUBSCRIBE_FLAG;
assign_ret = stratum_field_assign(raw_json_str, stratum_field, field_range);
cJSON *worker_item = cJSON_GetObjectItem(root, WORKER_STR);
if(worker_item == NULL){
STELLAR_LOG_INFO(stratum_decoder_info->log_handle, STRATUM_LOG_MOUDLE, "json_decode:error!not_found '%s' in raw_json_str ", WORKER_STR);
goto err_ret;
}
if(cJSON_IsString(worker_item)){
field_range = MINING_PROGRAM_FLAG;
stratum_field->type = ETH;
assign_ret = stratum_field_assign(worker_item->valuestring, stratum_field, field_range);
}else{
STELLAR_LOG_INFO(stratum_decoder_info->log_handle, STRATUM_LOG_MOUDLE, "json_decode:error!found '%s',json_value_type:%d\n ", WORKER_STR, worker_item->type);
goto err_ret;
}
}else{
STELLAR_LOG_INFO(stratum_decoder_info->log_handle, STRATUM_LOG_MOUDLE, "json_decode:error!found '%s',json_value_type:%d\n ", METHOD_STR, method_item->type);
goto err_ret;
}
if(assign_ret<0){
STELLAR_LOG_INFO(stratum_decoder_info->log_handle, STRATUM_LOG_MOUDLE, "field_assign_error:raw_json_str:%s\n ", raw_json_str);
goto err_ret;
}
cJSON_Delete(root);
return stratum_field;
}else{
STELLAR_LOG_INFO(stratum_decoder_info->log_handle, STRATUM_LOG_MOUDLE, "json_decode:error!found '%s',json_value_type:%d\n ", METHOD_STR, method_item->type);
goto err_ret;
}
err_ret:
cJSON_Delete(root);
free_stratum_filed(stratum_field);
return NULL;
}
struct stratum_field *stratum_data_process(struct stratum_decoder_info *stratum_decoder_info, const char *tcpdata, size_t datalen)
{
if(tcpdata == NULL || datalen == 0)
{
return NULL;
}
char *tcp_json=(char*)malloc(datalen+1);
memcpy(tcp_json, tcpdata, datalen);
tcp_json[datalen]='\0';
struct stratum_field *stratum_field=stratum_json_decode(stratum_decoder_info, tcp_json);
if(stratum_field==NULL)
{
STELLAR_LOG_DEBUG(stratum_decoder_info->log_handle, STRATUM_LOG_MOUDLE, "payload_decode failed!stratum_field is null");
}
free(tcp_json);
tcp_json=NULL;
return stratum_field;
}
void stratum_decoder_tcp_on_msg_cb(struct session *sess, int topic_id, const void *msg, void *per_session_ctx, void *plugin_env)
{
unused(topic_id);
unused(per_session_ctx);
unused(msg);
struct stratum_decoder_info *stratum_decoder_info = (struct stratum_decoder_info *)plugin_env;
const struct packet *pkt = session_get0_current_packet(sess);
const char *payload = packet_get_payload(pkt);
size_t payload_len = packet_get_payload_len(pkt);
struct stratum_field *stratum_field = stratum_data_process(stratum_decoder_info, payload, payload_len);
if (stratum_field != NULL)
{
if (session_mq_publish_message(sess, stratum_decoder_info->stratum_decoder_topic_id, stratum_field) < 0)
{
STELLAR_LOG_FATAL(stratum_decoder_info->log_handle, STRATUM_LOG_MOUDLE, "stratum_decoder_tcp_on_msg_cb:session_mq_publish_message failed");
free_stratum_filed(stratum_field);
}
stellar_session_plugin_dettach_current_session(sess);
}
return;
}
extern "C" void *stratum_decoder_init(struct stellar *st)
{
struct stratum_decoder_info *stratum_decoder_info = (struct stratum_decoder_info *)malloc(sizeof(struct stratum_decoder_info));
stratum_decoder_info->st = st;
stratum_decoder_info->log_handle = stellar_get_logger(st);
stratum_decoder_info->plugin_id = stellar_session_plugin_register(st, NULL, NULL, stratum_decoder_info);
if (stratum_decoder_info->plugin_id < 0)
{
STELLAR_LOG_FATAL(stratum_decoder_info->log_handle, STRATUM_LOG_MOUDLE, "stellar_session_plugin_register failed");
goto ERROR;
}
stratum_decoder_info->stratum_decoder_topic_id = stellar_mq_create_topic(st, STRATUM_MESSAGE_TOPIC, stratum_decoder_session_msg_free_cb, NULL);
if (stratum_decoder_info->stratum_decoder_topic_id < 0)
{
STELLAR_LOG_FATAL(stratum_decoder_info->log_handle, STRATUM_LOG_MOUDLE, "stellar_session_mq_create_topic failed");
goto ERROR;
}
stratum_decoder_info->tcp_topic_id = stellar_mq_get_topic_id(st, TOPIC_TCP_STREAM);
if (stratum_decoder_info->tcp_topic_id < 0)
{
STELLAR_LOG_FATAL(stratum_decoder_info->log_handle, STRATUM_LOG_MOUDLE, "stellar_session_mq_get_topic_id failed");
goto ERROR;
}
if (stellar_session_mq_subscribe(st, stratum_decoder_info->tcp_topic_id, stratum_decoder_tcp_on_msg_cb, stratum_decoder_info->plugin_id) < 0)
{
STELLAR_LOG_FATAL(stratum_decoder_info->log_handle, STRATUM_LOG_MOUDLE, "stellar_session_mq_subscribe failed");
goto ERROR;
}
return stratum_decoder_info;
ERROR:
if (stratum_decoder_info)
{
free(stratum_decoder_info);
}
return NULL;
}
extern "C" void stratum_decoder_exit(void *plugin_env)
{
struct stratum_decoder_info *stratum_decoder_info = (struct stratum_decoder_info *)plugin_env;
if (stratum_decoder_info != NULL)
{
free(stratum_decoder_info);
}
return;
}

View File

@@ -0,0 +1,55 @@
#pragma once
#include <stddef.h>
#include <stdint.h>
#define MESSAGE_MAGIC 0x12345678
#define SESSION_FLAGS_MESSAGE_TOPIC "TOPIC_SESSION_FLAGS"
enum
{
session_flags_bulky_mask = 1,
session_flags_cbr_mask,
session_flags_local_client_mask,
session_flags_local_server_mask,
session_flags_download_mask,
session_flags_interactive_mask,
session_flags_inbound_mask,
session_flags_outbound_mask,
session_flags_pseudo_unidirectional_mask,
session_flags_streaming_mask,
session_flags_unidirectional_mask,
session_flags_random_looking_mask,
session_flags_c2s_mask,
session_flags_s2c_mask,
session_flags_bidirectional_mask,
session_flags_tunneling_mask,
session_flags_all_mask
};
#define SESSION_FLAGS_START (0x0000000000000001)
#define SESSION_FLAGS_BULKY (SESSION_FLAGS_START << session_flags_bulky_mask)
#define SESSION_FLAGS_CBR (SESSION_FLAGS_START << session_flags_cbr_mask)
#define SESSION_FLAGS_LOCAL_CLIENT (SESSION_FLAGS_START << session_flags_local_client_mask)
#define SESSION_FLAGS_LOCAL_SERVER (SESSION_FLAGS_START << session_flags_local_server_mask)
#define SESSION_FLAGS_DOWNLOAD (SESSION_FLAGS_START << session_flags_download_mask)
#define SESSION_FLAGS_INTERACTIVE (SESSION_FLAGS_START << session_flags_interactive_mask)
#define SESSION_FLAGS_INBOUND (SESSION_FLAGS_START << session_flags_inbound_mask)
#define SESSION_FLAGS_OUTBOUND (SESSION_FLAGS_START << session_flags_outbound_mask)
#define SESSION_FLAGS_PSEUDO_UNIDIRECTIONAL (SESSION_FLAGS_START << session_flags_pseudo_unidirectional_mask)
#define SESSION_FLAGS_STREAMING (SESSION_FLAGS_START << session_flags_streaming_mask)
#define SESSION_FLAGS_UNIDIRECTIONAL (SESSION_FLAGS_START << session_flags_unidirectional_mask)
#define SESSION_FLAGS_RANDOM_LOOKING (SESSION_FLAGS_START << session_flags_random_looking_mask)
#define SESSION_FLAGS_C2S (SESSION_FLAGS_START << session_flags_c2s_mask)
#define SESSION_FLAGS_S2C (SESSION_FLAGS_START << session_flags_s2c_mask)
#define SESSION_FLAGS_BIDIRECTIONAL (SESSION_FLAGS_START << session_flags_bidirectional_mask)
#define SESSION_FLAGS_TUNNELING (SESSION_FLAGS_START << session_flags_tunneling_mask)
struct session_flags_message
{
int magic;
uint64_t flags;
uint32_t array_num;
uint32_t *packet_sequence_array;
};

View File

@@ -0,0 +1,44 @@
#include <sys/uio.h>
#include <netinet/in.h>
#ifndef IPV6_ADDR_LEN
#define IPV6_ADDR_LEN (sizeof(struct in6_addr))
#endif
#define SOCKS_MESSAGE_TOPIC "TOPIC_SOCKS"
enum socks_addr_type
{
SOCKS_ADDR_IPV4,
SOCKS_ADDR_IPV6,
SOCKS_ADDR_FQDN
};
struct socks_addr
{
enum socks_addr_type type;
union
{
uint32_t ipv4; /* network order */
uint8_t ipv6[IPV6_ADDR_LEN] ;
struct iovec fqdn;
};
uint16_t port; /* network order */
};
enum socks_version
{
SOCKS_VERSION_4,
SOCKS_VERSION_5
};
struct socks_info
{
enum socks_version version;
struct socks_addr dst_addr;
struct iovec user_name;
struct iovec password;
};//message data

View File

@@ -0,0 +1,18 @@
#include <sys/uio.h>
#define STRATUM_MESSAGE_TOPIC "TOPIC_STRATUM"
enum cryptocurrency_type
{
ETH=1,
OTHER=2
};
struct stratum_field
{
enum cryptocurrency_type type;
struct iovec mining_pools;
struct iovec mining_program;
struct iovec mining_subscribe;
};//message data

View File

@@ -3,3 +3,6 @@ add_subdirectory(packet_tool)
add_subdirectory(debug_plugin)
add_subdirectory(lpi_plugin)
add_subdirectory(decoders/http)
add_subdirectory(decoders/socks)
add_subdirectory(decoders/stratum)
add_subdirectory(decoders/session_flags)

View File

@@ -0,0 +1,56 @@
set(DECODER_NAME session_flags)
add_library(${DECODER_NAME}_test SHARED session_flags_test_plugin.cpp)
add_dependencies(${DECODER_NAME}_test ${DECODER_NAME})
set_target_properties(${DECODER_NAME}_test PROPERTIES PREFIX "")
set(TEST_RUN_DIR ${CMAKE_BINARY_DIR}/testing)
include_directories(${CMAKE_SOURCE_DIR}/include)
include_directories(${CMAKE_SOURCE_DIR}/src)
include_directories(${CMAKE_BINARY_DIR}/vendors/cjson/src/cjson/include)
include_directories(${PROJECT_SOURCE_DIR}/decoders/session_flags)
include_directories(${PROJECT_SOURCE_DIR}/include/stellar)
add_executable(gtest_session_flags_pcap session_flags_pcap_test.cpp
dummy.c
${PROJECT_SOURCE_DIR}/decoders/session_flags/fet.cpp
${PROJECT_SOURCE_DIR}/decoders/session_flags/onlinemean.c
${PROJECT_SOURCE_DIR}/decoders/session_flags/session_flags_plugin.cpp
${PROJECT_SOURCE_DIR}/decoders/session_flags/session_flags.cpp
${PROJECT_SOURCE_DIR}/decoders/session_flags/tunneling.cpp)
target_link_libraries(gtest_session_flags_pcap gtest pcap hyperscan_static hyperscan_runtime_static logger cjson-static libmesa_sts)
add_executable(gtest_session_flags_static session_flags_static_test.cpp
dummy.c
${PROJECT_SOURCE_DIR}/decoders/session_flags/fet.cpp
${PROJECT_SOURCE_DIR}/decoders/session_flags/onlinemean.c
${PROJECT_SOURCE_DIR}/decoders/session_flags/session_flags_plugin.cpp
${PROJECT_SOURCE_DIR}/decoders/session_flags/session_flags.cpp
${PROJECT_SOURCE_DIR}/decoders/session_flags/tunneling.cpp)
target_link_libraries(gtest_session_flags_static gtest pcap hyperscan_static hyperscan_runtime_static logger cjson-static libmesa_sts)
add_executable(session_flags_test_main plugin_test_main.cpp)
set_target_properties(session_flags_test_main
PROPERTIES
LINK_OPTIONS
"-rdynamic"
)
set_target_properties(session_flags_test_main
PROPERTIES
LINK_FLAGS
"-rdynamic"
)
set(LINK_FLAGS "-rdynamic")
target_link_libraries(session_flags_test_main PUBLIC gtest cjson-static stellar_lib -Wl,--whole-archive packet_parser -Wl,--no-whole-archive)
add_subdirectory(test_based_on_stellar)
#copy pcap file folder to build directory
file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/pcap DESTINATION ${CMAKE_BINARY_DIR}/test/decoders/session_flags)
file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/test_based_on_stellar/env/session_flags.toml DESTINATION ${CMAKE_BINARY_DIR}/test/decoders/session_flags/etc/session_flags/)
include(GoogleTest)
gtest_discover_tests(gtest_session_flags_pcap)
gtest_discover_tests(gtest_session_flags_static)

View File

@@ -0,0 +1,167 @@
#include <stdlib.h>
#include <string.h>
#include "dummy.h"
#define UNUSED(x) (void)(x)
struct session g_sess;
void session_set_current_payload(struct session *sess, char *payload, int payload_len)
{
UNUSED(sess);
g_sess.payload_len = payload_len;
g_sess.payload = payload;
}
int session_exdata_set(struct session *sess, int idx, void *ex_ptr)
{
UNUSED(sess);
UNUSED(idx);
UNUSED(ex_ptr);
return 0;
}
struct logger *stellar_get_logger(struct stellar *st)
{
UNUSED(st);
return (struct logger *)1;
}
void *session_exdata_get(struct session *sess, int idx)
{
UNUSED(sess);
UNUSED(idx);
return NULL;
}
const struct packet *session_get0_current_packet(const struct session *sess)
{
UNUSED(sess);
return NULL;
}
uint16_t packet_get_payload_len(const struct packet *pkt)
{
UNUSED(pkt);
return g_sess.payload_len;
}
const char *packet_get_payload(const struct packet *pkt)
{
UNUSED(pkt);
return g_sess.payload;
}
enum session_direction session_get_direction(const struct session *sess)
{
UNUSED(sess);
return SESSION_DIRECTION_OUTBOUND;
}
enum flow_type session_get_flow_type(const struct session *sess)
{
UNUSED(sess);
return FLOW_TYPE_C2S;
}
const char *session_get0_readable_addr(const struct session *sess)
{
UNUSED(sess);
return NULL;
}
uint16_t packet_get_raw_len(const struct packet *pkt)
{
UNUSED(pkt);
return 0;
}
const struct timeval *packet_get_timeval(const struct packet *pkt)
{
UNUSED(pkt);
return NULL;
}
void stellar_session_plugin_dettach_current_session(struct session *sess)
{
UNUSED(sess);
}
int session_mq_publish_message(struct session *sess, int topic_id, void *msg)
{
UNUSED(sess);
UNUSED(topic_id);
UNUSED(msg);
return 0;
}
int stellar_exdata_new_index(struct stellar *st, const char *name, stellar_exdata_free *free_func,void *arg)
{
UNUSED(st);
UNUSED(name);
UNUSED(free_func);
UNUSED(arg);
return 0;
}
int stellar_mq_create_topic(struct stellar *st, const char *topic_name, stellar_msg_free_cb_func *msg_free_cb, void *msg_free_arg)
{
UNUSED(st);
UNUSED(topic_name);
UNUSED(msg_free_cb);
UNUSED(msg_free_arg);
return 0;
}
int stellar_mq_get_topic_id(struct stellar *st, const char *topic_name)
{
UNUSED(st);
if (strcmp(topic_name, TOPIC_TCP_INPUT) == 0)
{
return DUMMY_TCP_TOPIC_ID;
}
else if (strcmp(topic_name, TOPIC_UDP_INPUT) == 0)
{
return DUMMY_UDP_TOPIC_ID;
}
else
{
return -1;
}
}
int stellar_session_mq_subscribe(struct stellar *st, int topic_id, on_session_msg_cb_func *plugin_on_msg_cb, int plugin_id)
{
UNUSED(st);
UNUSED(topic_id);
UNUSED(plugin_on_msg_cb);
UNUSED(plugin_id);
return 0;
}
int stellar_session_plugin_register(struct stellar *st, session_ctx_new_func session_ctx_new, session_ctx_free_func session_ctx_free, void *plugin_env)
{
UNUSED(st);
UNUSED(session_ctx_new);
UNUSED(session_ctx_free);
UNUSED(plugin_env);
return 0;
}

View File

@@ -0,0 +1,18 @@
#include "stellar/stellar.h"
#include "stellar/session.h"
#include "stellar/stellar_mq.h"
#include "stellar/stellar_exdata.h"
#define DUMMY_TCP_TOPIC_ID 1
#define DUMMY_UDP_TOPIC_ID 2
struct session //stub just for test
{
int payload_len;
char *payload;
};
void session_set_current_payload(struct session *sess, char *payload, int payload_len);
void *session_flags_plugin_init(struct stellar *st);
void session_flags_plugin_exit(void *arg);

View File

@@ -0,0 +1,20 @@
[
{
"common_flags_0": 8200,
"common_flags_str_0": "[Client is Local]",
"common_flags_identify_info_0": "{\"Client is Local\":1,\"C2S\":1}",
"common_flags_1": 24584,
"common_flags_str_1": "[Client is Local]",
"common_flags_identify_info_1": "{\"Client is Local\":1,\"C2S\":1,\"S2C\":4}",
"common_flags_2": 2123980808,
"common_flags_str_2": "[Client is Local]",
"common_flags_identify_info_2": "{\"Client is Local\":1,\"C2S\":1,\"S2C\":4,\"frequency\":6,\"runs\":6,\"longest_run\":6,\"overlapping_template_matching\":6,\"random_excursions\":6,\"random_excursions_variant\":6,\"poker_detect\":6,\"runs_distribution\":6,\"self_correlation\":6,\"binary_derivative\":6}",
"common_flags_3": 2123980936,
"common_flags_str_3": "[Client is Local,Inbound]",
"common_flags_identify_info_3": "{\"Client is Local\":1,\"Inbound\":21,\"C2S\":1,\"S2C\":4,\"frequency\":6,\"runs\":6,\"longest_run\":6,\"overlapping_template_matching\":6,\"random_excursions\":6,\"random_excursions_variant\":6,\"poker_detect\":6,\"runs_distribution\":6,\"self_correlation\":6,\"binary_derivative\":6}",
"common_flags_4": 2123981960,
"common_flags_str_4": "[Client is Local,Inbound,Streaming]",
"common_flags_identify_info_4": "{\"Client is Local\":1,\"Inbound\":21,\"Streaming\":100,\"C2S\":1,\"S2C\":4,\"frequency\":6,\"runs\":6,\"longest_run\":6,\"overlapping_template_matching\":6,\"random_excursions\":6,\"random_excursions_variant\":6,\"poker_detect\":6,\"runs_distribution\":6,\"self_correlation\":6,\"binary_derivative\":6}",
"name": "base_0"
}
]

View File

@@ -0,0 +1,17 @@
[
{
"common_flags_0": 8200,
"common_flags_str_0": "[Client is Local]",
"common_flags_identify_info_0": "{\"Client is Local\":1,\"C2S\":1}",
"common_flags_1": 24584,
"common_flags_str_1": "[Client is Local]",
"common_flags_identify_info_1": "{\"Client is Local\":1,\"C2S\":1,\"S2C\":2}",
"common_flags_2": 1185898504,
"common_flags_str_2": "[Client is Local]",
"common_flags_identify_info_2": "{\"Client is Local\":1,\"C2S\":1,\"S2C\":2,\"frequency\":4,\"block_frequency\":4,\"cumulative_sums\":4,\"runs\":4,\"rank\":4,\"overlapping_template_matching\":4,\"random_excursions\":4,\"random_excursions_variant\":4,\"binary_derivative\":4}",
"common_flags_3": 1185898632,
"common_flags_str_3": "[Client is Local,Inbound]",
"common_flags_identify_info_3": "{\"Client is Local\":1,\"Inbound\":34,\"C2S\":1,\"S2C\":2,\"frequency\":4,\"block_frequency\":4,\"cumulative_sums\":4,\"runs\":4,\"rank\":4,\"overlapping_template_matching\":4,\"random_excursions\":4,\"random_excursions_variant\":4,\"binary_derivative\":4}",
"name": "base_0"
}
]

View File

@@ -0,0 +1,14 @@
[
{
"common_flags_0": 8200,
"common_flags_str_0": "[Client is Local]",
"common_flags_identify_info_0": "{\"Client is Local\":1,\"C2S\":1}",
"common_flags_1": 1453269000,
"common_flags_str_1": "[Client is Local]",
"common_flags_identify_info_1": "{\"Client is Local\":1,\"C2S\":1,\"frequency\":3,\"block_frequency\":3,\"cumulative_sums\":3,\"runs\":3,\"longest_run\":3,\"overlapping_template_matching\":3,\"random_excursions\":3,\"random_excursions_variant\":3,\"runs_distribution\":3,\"binary_derivative\":3}",
"common_flags_2": 1453269001,
"common_flags_str_2": "[Asymmetric,Client is Local]",
"common_flags_identify_info_2": "{\"Asymmetric\":10,\"Client is Local\":1,\"C2S\":1,\"frequency\":3,\"block_frequency\":3,\"cumulative_sums\":3,\"runs\":3,\"longest_run\":3,\"overlapping_template_matching\":3,\"random_excursions\":3,\"random_excursions_variant\":3,\"runs_distribution\":3,\"binary_derivative\":3}",
"name": "base_0"
}
]

View File

@@ -0,0 +1,14 @@
[
{
"common_flags_0": 8200,
"common_flags_str_0": "[Client is Local]",
"common_flags_identify_info_0": "{\"Client is Local\":1,\"C2S\":1}",
"common_flags_1": 2126340104,
"common_flags_str_1": "[Client is Local]",
"common_flags_identify_info_1": "{\"Client is Local\":1,\"C2S\":1,\"S2C\":2,\"frequency\":2,\"cumulative_sums\":2,\"runs\":2,\"longest_run\":2,\"rank\":2,\"overlapping_template_matching\":2,\"random_excursions\":2,\"random_excursions_variant\":2,\"poker_detect\":2,\"runs_distribution\":2,\"self_correlation\":2,\"binary_derivative\":2}",
"common_flags_2": 2126340232,
"common_flags_str_2": "[Client is Local,Inbound]",
"common_flags_identify_info_2": "{\"Client is Local\":1,\"Inbound\":18,\"C2S\":1,\"S2C\":2,\"frequency\":2,\"cumulative_sums\":2,\"runs\":2,\"longest_run\":2,\"rank\":2,\"overlapping_template_matching\":2,\"random_excursions\":2,\"random_excursions_variant\":2,\"poker_detect\":2,\"runs_distribution\":2,\"self_correlation\":2,\"binary_derivative\":2}",
"name": "base_0"
}
]

View File

@@ -0,0 +1,11 @@
[
{
"common_flags_0": 8208,
"common_flags_str_0": "[Server is Local,C2S]",
"common_flags_identify_info_0": "1,1,",
"common_flags_1": 24592,
"common_flags_str_1": "[Server is Local,C2S,S2C]",
"common_flags_identify_info_1": "1,1,2,",
"name": "session_flags_test"
}
]

Binary file not shown.

View File

@@ -0,0 +1,23 @@
[
{
"common_flags_0": 16392,
"common_flags_str_0": "[Client is Local]",
"common_flags_identify_info_0": "{\"Client is Local\":1,\"S2C\":1}",
"common_flags_1": 24584,
"common_flags_str_1": "[Client is Local]",
"common_flags_identify_info_1": "{\"Client is Local\":1,\"C2S\":2,\"S2C\":1}",
"common_flags_2": 1585602568,
"common_flags_str_2": "[Client is Local]",
"common_flags_identify_info_2": "{\"Client is Local\":1,\"C2S\":2,\"S2C\":1,\"block_frequency\":5,\"overlapping_template_matching\":5,\"random_excursions\":5,\"random_excursions_variant\":5,\"poker_detect\":5,\"runs_distribution\":5,\"binary_derivative\":5}",
"common_flags_3": 1585602696,
"common_flags_str_3": "[Client is Local,Inbound]",
"common_flags_identify_info_3": "{\"Client is Local\":1,\"Inbound\":25,\"C2S\":2,\"S2C\":1,\"block_frequency\":5,\"overlapping_template_matching\":5,\"random_excursions\":5,\"random_excursions_variant\":5,\"poker_detect\":5,\"runs_distribution\":5,\"binary_derivative\":5}",
"common_flags_4": 1585603720,
"common_flags_str_4": "[Client is Local,Inbound,Streaming]",
"common_flags_identify_info_4": "{\"Client is Local\":1,\"Inbound\":25,\"Streaming\":186,\"C2S\":2,\"S2C\":1,\"block_frequency\":5,\"overlapping_template_matching\":5,\"random_excursions\":5,\"random_excursions_variant\":5,\"poker_detect\":5,\"runs_distribution\":5,\"binary_derivative\":5}",
"common_flags_5": 1585636488,
"common_flags_str_5": "[Client is Local,Inbound,Streaming,Bidirectional]",
"common_flags_identify_info_5": "{\"Client is Local\":1,\"Inbound\":25,\"Streaming\":186,\"C2S\":2,\"S2C\":1,\"Bidirectional\":8551,\"block_frequency\":5,\"overlapping_template_matching\":5,\"random_excursions\":5,\"random_excursions_variant\":5,\"poker_detect\":5,\"runs_distribution\":5,\"binary_derivative\":5}",
"name": "base_0"
}
]

View File

@@ -0,0 +1,14 @@
[
{
"common_flags_0": 8208,
"common_flags_str_0": "[Server is Local]",
"common_flags_identify_info_0": "{\"Server is Local\":1,\"C2S\":1}",
"common_flags_1": 8209,
"common_flags_str_1": "[Asymmetric,Server is Local]",
"common_flags_identify_info_1": "{\"Asymmetric\":10,\"Server is Local\":1,\"C2S\":1}",
"common_flags_2": 24593,
"common_flags_str_2": "[Asymmetric,Server is Local]",
"common_flags_identify_info_2": "{\"Asymmetric\":10,\"Server is Local\":1,\"C2S\":1,\"S2C\":12}",
"name": "base_0"
}
]

Binary file not shown.

View File

@@ -0,0 +1,20 @@
[
{
"common_flags_0": 8200,
"common_flags_str_0": "[Client is Local]",
"common_flags_identify_info_0": "{\"Client is Local\":1,\"C2S\":1}",
"common_flags_1": 24584,
"common_flags_str_1": "[Client is Local]",
"common_flags_identify_info_1": "{\"Client is Local\":1,\"C2S\":1,\"S2C\":2}",
"common_flags_2": 2124242952,
"common_flags_str_2": "[Client is Local]",
"common_flags_identify_info_2": "{\"Client is Local\":1,\"C2S\":1,\"S2C\":2,\"frequency\":4,\"cumulative_sums\":4,\"runs\":4,\"longest_run\":4,\"overlapping_template_matching\":4,\"random_excursions\":4,\"random_excursions_variant\":4,\"poker_detect\":4,\"runs_distribution\":4,\"self_correlation\":4,\"binary_derivative\":4}",
"common_flags_3": 2124244104,
"common_flags_str_3": "[Client is Local,Inbound,Streaming]",
"common_flags_identify_info_3": "{\"Client is Local\":1,\"Inbound\":6036,\"Streaming\":6036,\"C2S\":1,\"S2C\":2,\"frequency\":4,\"cumulative_sums\":4,\"runs\":4,\"longest_run\":4,\"overlapping_template_matching\":4,\"random_excursions\":4,\"random_excursions_variant\":4,\"poker_detect\":4,\"runs_distribution\":4,\"self_correlation\":4,\"binary_derivative\":4}",
"common_flags_4": 2124244650,
"common_flags_str_4": "[Bulky,Client is Local,Download,Inbound,Pseudo Unidirectional,Streaming]",
"common_flags_identify_info_4": "{\"Bulky\":6042,\"Client is Local\":1,\"Download\":6042,\"Inbound\":6036,\"Pseudo Unidirectional\":6042,\"Streaming\":6036,\"C2S\":1,\"S2C\":2,\"frequency\":4,\"cumulative_sums\":4,\"runs\":4,\"longest_run\":4,\"overlapping_template_matching\":4,\"random_excursions\":4,\"random_excursions_variant\":4,\"poker_detect\":4,\"runs_distribution\":4,\"self_correlation\":4,\"binary_derivative\":4}",
"name": "base_0"
}
]

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,26 @@
[{
"common_flags_0": 8200,
"common_flags_str_0": "[Client is Local,C2S]",
"common_flags_identify_info_0": "1,1,",
"common_flags_1": 24584,
"common_flags_str_1": "[Client is Local,C2S,S2C]",
"common_flags_identify_info_1": "1,1,2,",
"common_flags_2": 28680,
"common_flags_str_2": "[Client is Local,Random Looking,C2S,S2C]",
"common_flags_identify_info_2": "1,4,1,2,",
"common_flags_3": 28808,
"common_flags_str_3": "[Client is Local,Inbound,Random Looking,C2S,S2C]",
"common_flags_identify_info_3": "1,1188,4,1,2,",
"common_flags_4": 29832,
"common_flags_str_4": "[Client is Local,Inbound,Streaming,Random Looking,C2S,S2C]",
"common_flags_identify_info_4": "1,1188,1662,4,1,2,",
"common_flags_5": 30344,
"common_flags_str_5": "[Client is Local,Inbound,Pseudo Unidirectional,Streaming,Random Looking,C2S,S2C]",
"common_flags_identify_info_5": "1,1188,3546,1662,4,1,2,",
"common_flags_6": 30346,
"common_flags_str_6": "[Bulky,Client is Local,Inbound,Pseudo Unidirectional,Streaming,Random Looking,C2S,S2C]",
"common_flags_identify_info_6": "4095,1,1188,3546,1662,4,1,2,",
"common_flags_7": 30378,
"common_flags_str_7": "[Bulky,Client is Local,Download,Inbound,Pseudo Unidirectional,Streaming,Random Looking,C2S,S2C]",
"common_flags_identify_info_7": "4095,1,4201,1188,3546,1662,4,1,2,"
}]

Binary file not shown.

View File

@@ -0,0 +1,65 @@
[
{
"common_flags_0": 8200,
"common_flags_str_0": "[Client is Local]",
"common_flags_identify_info_0": "{\"Client is Local\":1,\"C2S\":1}",
"common_flags_1": 24584,
"common_flags_str_1": "[Client is Local]",
"common_flags_identify_info_1": "{\"Client is Local\":1,\"C2S\":1,\"S2C\":2}",
"common_flags_2": 109076488,
"common_flags_str_2": "[Client is Local]",
"common_flags_identify_info_2": "{\"Client is Local\":1,\"C2S\":1,\"S2C\":2,\"overlapping_template_matching\":4,\"random_excursions\":4,\"random_excursions_variant\":4}",
"common_flags_3": 109078186,
"common_flags_str_3": "[Bulky,Client is Local,Download,Inbound,Pseudo Unidirectional,Streaming]",
"common_flags_identify_info_3": "{\"Bulky\":2250,\"Client is Local\":1,\"Download\":2250,\"Inbound\":2250,\"Pseudo Unidirectional\":2250,\"Streaming\":2250,\"C2S\":1,\"S2C\":2,\"overlapping_template_matching\":4,\"random_excursions\":4,\"random_excursions_variant\":4}",
"name": "base_0"
},
{
"common_flags_0": 8200,
"common_flags_str_0": "[Client is Local]",
"common_flags_identify_info_0": "{\"Client is Local\":1,\"C2S\":1}",
"common_flags_1": 1451237384,
"common_flags_str_1": "[Client is Local]",
"common_flags_identify_info_1": "{\"Client is Local\":1,\"C2S\":1,\"overlapping_template_matching\":10,\"random_excursions\":10,\"random_excursions_variant\":10,\"runs_distribution\":10,\"binary_derivative\":10}",
"common_flags_2": 1451237385,
"common_flags_str_2": "[Asymmetric,Client is Local]",
"common_flags_identify_info_2": "{\"Asymmetric\":4168,\"Client is Local\":1,\"C2S\":1,\"overlapping_template_matching\":10,\"random_excursions\":10,\"random_excursions_variant\":10,\"runs_distribution\":10,\"binary_derivative\":10}",
"name": "base_1"
},
{
"common_flags_0": 8200,
"common_flags_str_0": "[Client is Local]",
"common_flags_identify_info_0": "{\"Client is Local\":1,\"C2S\":1}",
"common_flags_1": 2126323720,
"common_flags_str_1": "[Client is Local]",
"common_flags_identify_info_1": "{\"Client is Local\":1,\"C2S\":1,\"frequency\":2,\"cumulative_sums\":2,\"runs\":2,\"longest_run\":2,\"rank\":2,\"overlapping_template_matching\":2,\"random_excursions\":2,\"random_excursions_variant\":2,\"poker_detect\":2,\"runs_distribution\":2,\"self_correlation\":2,\"binary_derivative\":2}",
"common_flags_2": 2126340104,
"common_flags_str_2": "[Client is Local]",
"common_flags_identify_info_2": "{\"Client is Local\":1,\"C2S\":1,\"S2C\":6,\"frequency\":2,\"cumulative_sums\":2,\"runs\":2,\"longest_run\":2,\"rank\":2,\"overlapping_template_matching\":2,\"random_excursions\":2,\"random_excursions_variant\":2,\"poker_detect\":2,\"runs_distribution\":2,\"self_correlation\":2,\"binary_derivative\":2}",
"common_flags_3": 2126340232,
"common_flags_str_3": "[Client is Local,Inbound]",
"common_flags_identify_info_3": "{\"Client is Local\":1,\"Inbound\":29,\"C2S\":1,\"S2C\":6,\"frequency\":2,\"cumulative_sums\":2,\"runs\":2,\"longest_run\":2,\"rank\":2,\"overlapping_template_matching\":2,\"random_excursions\":2,\"random_excursions_variant\":2,\"poker_detect\":2,\"runs_distribution\":2,\"self_correlation\":2,\"binary_derivative\":2}",
"name": "base_2"
},
{
"common_flags_0": 8200,
"common_flags_str_0": "[Client is Local]",
"common_flags_identify_info_0": "{\"Client is Local\":1,\"C2S\":1}",
"common_flags_1": 1186291720,
"common_flags_str_1": "[Client is Local]",
"common_flags_identify_info_1": "{\"Client is Local\":1,\"C2S\":1,\"S2C\":2,\"frequency\":2,\"cumulative_sums\":2,\"longest_run\":2,\"rank\":2,\"overlapping_template_matching\":2,\"random_excursions\":2,\"random_excursions_variant\":2,\"binary_derivative\":2}",
"common_flags_2": 1186291848,
"common_flags_str_2": "[Client is Local,Inbound]",
"common_flags_identify_info_2": "{\"Client is Local\":1,\"Inbound\":21,\"C2S\":1,\"S2C\":2,\"frequency\":2,\"cumulative_sums\":2,\"longest_run\":2,\"rank\":2,\"overlapping_template_matching\":2,\"random_excursions\":2,\"random_excursions_variant\":2,\"binary_derivative\":2}",
"common_flags_3": 1186292872,
"common_flags_str_3": "[Client is Local,Inbound,Streaming]",
"common_flags_identify_info_3": "{\"Client is Local\":1,\"Inbound\":21,\"Streaming\":100,\"C2S\":1,\"S2C\":2,\"frequency\":2,\"cumulative_sums\":2,\"longest_run\":2,\"rank\":2,\"overlapping_template_matching\":2,\"random_excursions\":2,\"random_excursions_variant\":2,\"binary_derivative\":2}",
"common_flags_4": 1186292874,
"common_flags_str_4": "[Bulky,Client is Local,Inbound,Streaming]",
"common_flags_identify_info_4": "{\"Bulky\":430,\"Client is Local\":1,\"Inbound\":21,\"Streaming\":100,\"C2S\":1,\"S2C\":2,\"frequency\":2,\"cumulative_sums\":2,\"longest_run\":2,\"rank\":2,\"overlapping_template_matching\":2,\"random_excursions\":2,\"random_excursions_variant\":2,\"binary_derivative\":2}",
"common_flags_5": 1186292878,
"common_flags_str_5": "[Bulky,CBR Streaming,Client is Local,Inbound,Streaming]",
"common_flags_identify_info_5": "{\"Bulky\":430,\"CBR Streaming\":6984,\"Client is Local\":1,\"Inbound\":21,\"Streaming\":100,\"C2S\":1,\"S2C\":2,\"frequency\":2,\"cumulative_sums\":2,\"longest_run\":2,\"rank\":2,\"overlapping_template_matching\":2,\"random_excursions\":2,\"random_excursions_variant\":2,\"binary_derivative\":2}",
"name": "base_3"
}
]

View File

@@ -0,0 +1,17 @@
[
{
"common_flags_0": 8200,
"common_flags_str_0": "[Client is Local]",
"common_flags_identify_info_0": "{\"Client is Local\":1,\"C2S\":1}",
"common_flags_1": 2126323720,
"common_flags_str_1": "[Client is Local]",
"common_flags_identify_info_1": "{\"Client is Local\":1,\"C2S\":1,\"frequency\":2,\"cumulative_sums\":2,\"runs\":2,\"longest_run\":2,\"rank\":2,\"overlapping_template_matching\":2,\"random_excursions\":2,\"random_excursions_variant\":2,\"poker_detect\":2,\"runs_distribution\":2,\"self_correlation\":2,\"binary_derivative\":2}",
"common_flags_2": 2126340104,
"common_flags_str_2": "[Client is Local]",
"common_flags_identify_info_2": "{\"Client is Local\":1,\"C2S\":1,\"S2C\":14,\"frequency\":2,\"cumulative_sums\":2,\"runs\":2,\"longest_run\":2,\"rank\":2,\"overlapping_template_matching\":2,\"random_excursions\":2,\"random_excursions_variant\":2,\"poker_detect\":2,\"runs_distribution\":2,\"self_correlation\":2,\"binary_derivative\":2}",
"common_flags_3": 2126340232,
"common_flags_str_3": "[Client is Local,Inbound]",
"common_flags_identify_info_3": "{\"Client is Local\":1,\"Inbound\":84,\"C2S\":1,\"S2C\":14,\"frequency\":2,\"cumulative_sums\":2,\"runs\":2,\"longest_run\":2,\"rank\":2,\"overlapping_template_matching\":2,\"random_excursions\":2,\"random_excursions_variant\":2,\"poker_detect\":2,\"runs_distribution\":2,\"self_correlation\":2,\"binary_derivative\":2}",
"name": "base_0"
}
]

View File

@@ -0,0 +1,14 @@
[
{
"common_flags_0": 16392,
"common_flags_str_0": "[Client is Local]",
"common_flags_identify_info_0": "{\"Client is Local\":1,\"S2C\":1}",
"common_flags_1": 1452294152,
"common_flags_str_1": "[Client is Local]",
"common_flags_identify_info_1": "{\"Client is Local\":1,\"S2C\":1,\"longest_run\":2,\"overlapping_template_matching\":2,\"random_excursions\":2,\"random_excursions_variant\":2,\"runs_distribution\":2,\"binary_derivative\":2}",
"common_flags_2": 1452294153,
"common_flags_str_2": "[Asymmetric,Client is Local]",
"common_flags_identify_info_2": "{\"Asymmetric\":37,\"Client is Local\":1,\"S2C\":1,\"longest_run\":2,\"overlapping_template_matching\":2,\"random_excursions\":2,\"random_excursions_variant\":2,\"runs_distribution\":2,\"binary_derivative\":2}",
"name": "base_0"
}
]

View File

@@ -0,0 +1,26 @@
[
{
"common_flags_0": 8200,
"common_flags_str_0": "[Client is Local]",
"common_flags_identify_info_0": "{\"Client is Local\":1,\"C2S\":1}",
"common_flags_1": 2124226568,
"common_flags_str_1": "[Client is Local]",
"common_flags_identify_info_1": "{\"Client is Local\":1,\"C2S\":1,\"frequency\":3,\"cumulative_sums\":3,\"runs\":3,\"longest_run\":3,\"overlapping_template_matching\":3,\"random_excursions\":3,\"random_excursions_variant\":3,\"poker_detect\":3,\"runs_distribution\":3,\"self_correlation\":3,\"binary_derivative\":3}",
"common_flags_2": 2124242952,
"common_flags_str_2": "[Client is Local]",
"common_flags_identify_info_2": "{\"Client is Local\":1,\"C2S\":1,\"S2C\":4,\"frequency\":3,\"cumulative_sums\":3,\"runs\":3,\"longest_run\":3,\"overlapping_template_matching\":3,\"random_excursions\":3,\"random_excursions_variant\":3,\"poker_detect\":3,\"runs_distribution\":3,\"self_correlation\":3,\"binary_derivative\":3}",
"common_flags_3": 2124244104,
"common_flags_str_3": "[Client is Local,Inbound,Streaming]",
"common_flags_identify_info_3": "{\"Client is Local\":1,\"Inbound\":291,\"Streaming\":291,\"C2S\":1,\"S2C\":4,\"frequency\":3,\"cumulative_sums\":3,\"runs\":3,\"longest_run\":3,\"overlapping_template_matching\":3,\"random_excursions\":3,\"random_excursions_variant\":3,\"poker_detect\":3,\"runs_distribution\":3,\"self_correlation\":3,\"binary_derivative\":3}",
"common_flags_4": 2124244106,
"common_flags_str_4": "[Bulky,Client is Local,Inbound,Streaming]",
"common_flags_identify_info_4": "{\"Bulky\":630,\"Client is Local\":1,\"Inbound\":291,\"Streaming\":291,\"C2S\":1,\"S2C\":4,\"frequency\":3,\"cumulative_sums\":3,\"runs\":3,\"longest_run\":3,\"overlapping_template_matching\":3,\"random_excursions\":3,\"random_excursions_variant\":3,\"poker_detect\":3,\"runs_distribution\":3,\"self_correlation\":3,\"binary_derivative\":3}",
"common_flags_5": 2124276874,
"common_flags_str_5": "[Bulky,Client is Local,Inbound,Streaming,Bidirectional]",
"common_flags_identify_info_5": "{\"Bulky\":630,\"Client is Local\":1,\"Inbound\":291,\"Streaming\":291,\"C2S\":1,\"S2C\":4,\"Bidirectional\":7315,\"frequency\":3,\"cumulative_sums\":3,\"runs\":3,\"longest_run\":3,\"overlapping_template_matching\":3,\"random_excursions\":3,\"random_excursions_variant\":3,\"poker_detect\":3,\"runs_distribution\":3,\"self_correlation\":3,\"binary_derivative\":3}",
"common_flags_6": 2124276938,
"common_flags_str_6": "[Bulky,Client is Local,Interactive,Inbound,Streaming,Bidirectional]",
"common_flags_identify_info_6": "{\"Bulky\":630,\"Client is Local\":1,\"Interactive\":25786,\"Inbound\":291,\"Streaming\":291,\"C2S\":1,\"S2C\":4,\"Bidirectional\":7315,\"frequency\":3,\"cumulative_sums\":3,\"runs\":3,\"longest_run\":3,\"overlapping_template_matching\":3,\"random_excursions\":3,\"random_excursions_variant\":3,\"poker_detect\":3,\"runs_distribution\":3,\"self_correlation\":3,\"binary_derivative\":3}",
"name": "base_0"
}
]

View File

@@ -0,0 +1,29 @@
[
{
"common_flags_0": 8208,
"common_flags_str_0": "[Server is Local]",
"common_flags_identify_info_0": "{\"Server is Local\":1,\"C2S\":1}",
"common_flags_1": 24592,
"common_flags_str_1": "[Server is Local]",
"common_flags_identify_info_1": "{\"Server is Local\":1,\"C2S\":1,\"S2C\":2}",
"common_flags_2": 111173648,
"common_flags_str_2": "[Server is Local]",
"common_flags_identify_info_2": "{\"Server is Local\":1,\"C2S\":1,\"S2C\":2,\"rank\":7,\"overlapping_template_matching\":7,\"random_excursions\":7,\"random_excursions_variant\":7}",
"common_flags_3": 111173904,
"common_flags_str_3": "[Server is Local,Outbound]",
"common_flags_identify_info_3": "{\"Server is Local\":1,\"Outbound\":40,\"C2S\":1,\"S2C\":2,\"rank\":7,\"overlapping_template_matching\":7,\"random_excursions\":7,\"random_excursions_variant\":7}",
"common_flags_4": 111173968,
"common_flags_str_4": "[Server is Local,Interactive,Outbound]",
"common_flags_identify_info_4": "{\"Server is Local\":1,\"Interactive\":52,\"Outbound\":40,\"C2S\":1,\"S2C\":2,\"rank\":7,\"overlapping_template_matching\":7,\"random_excursions\":7,\"random_excursions_variant\":7}",
"name": "base_0"
},
{
"common_flags_0": 16400,
"common_flags_str_0": "[Server is Local]",
"common_flags_identify_info_0": "{\"Server is Local\":1,\"S2C\":1}",
"common_flags_1": 16401,
"common_flags_str_1": "[Asymmetric,Server is Local]",
"common_flags_identify_info_1": "{\"Asymmetric\":2,\"Server is Local\":1,\"S2C\":1}",
"name": "base_1"
}
]

Some files were not shown because too many files have changed in this diff Show More