Merge branch 'v1.2.0_dev' into 'master'

V1.2.0 dev

See merge request ZNJK/vcpe!5
This commit is contained in:
黄昕 2023-04-10 10:49:52 +08:00
commit 3eb2e9111e
82 changed files with 6062 additions and 454 deletions

View File

@ -1,29 +1,30 @@
CMAKE_MINIMUM_REQUIRED(VERSION 3.10 FATAL_ERROR)
INCLUDE(CMakeDependentOption)
OPTION(VCPE_AGENT "Enable vCPE agent test application" OFF)
OPTION(VCPE_PPPOE "Enable vCPE work befof PPPoE mode" OFF)
OPTION(USED_OPENDHCPD "DHCP server for vCPE" OFF)
OPTION(USED_OPENDHCPDDNS "DHCP And DNS server for vCPE" OFF)
OPTION(USED_USER_VNI "Support pass user vni id from console command line" OFF)
OPTION(USED_JSON_VALIDATE "Support json protocol field validate" OFF)
OPTION(BUILD_TESTING "Enable tests" OFF)
#
OPTION(USED_REDIS "Add redis database support for vCPE" OFF)
OPTION(USED_MYSQL "Add mysql database support for vCPE" OFF)
OPTION(USED_SQLITE "Add sqlite3 database support for vCPE" OFF)
CMAKE_DEPENDENT_OPTION(USED_HTTP_SVR "Build-in http(s) server support" ON "USED_OPENDHCPD OR USED_OPENDHCPDDNS" OFF)
CMAKE_DEPENDENT_OPTION(USED_LWIP "PPPoE of LWIP support for vCPE" ON "VCPE_PPPOE" OFF)
CMAKE_DEPENDENT_OPTION(USED_ZMQ "ZeroMQ support for vCPE" ON "VCPE_PPPOE" OFF)
LIST(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/depend)
IF (BUILD_TESTING)
INCLUDE(doctest_framework)
ENDIF ()
INCLUDE(system_libs)
SET(VCPE_VERSION "1.0.1")
SET(VCPE_VERSION "1.2.0")
PROJECT(vCPE VERSION "${VCPE_VERSION}")
OPTION(VCPE_AGENT "Enable vCPE agent test application" OFF)
OPTION(USED_LWIP "PPPoE of LWIP support for vCPE" OFF)
OPTION(USED_OPENDHCPD "DHCP server for vCPE" OFF)
OPTION(USED_OPENDHCPDDNS "DHCP And DNS server for vCPE" OFF)
OPTION(USED_USER_VNI "Support pass user vni id from console command line" OFF)
OPTION(BUILD_TESTING "Enable tests" OFF)
CMAKE_DEPENDENT_OPTION(USED_HTTP_SVR "Build-in http(s) server support" ON "USED_OPENDHCPD OR USED_OPENDHCPDDNS" OFF)
#
OPTION(USED_REDIS "Add redis database support for vCPE" OFF)
OPTION(USED_MYSQL "Add mysql database support for vCPE" OFF)
OPTION(USED_SQLITE "Add sqlite3 database support for vCPE" OFF)
SET(ENV{PKG_CONFIG_PATH} "$ENV{PKG_CONFIG_PATH}:/usr/local/lib/pkgconfig")
SET(URI_HOME "${CMAKE_SOURCE_DIR}/libs")
@ -82,6 +83,10 @@ SET(COMMON_LIBS "")
INCLUDE(./depend/third_libs.cmake)
IF (USED_JSON_VALIDATE)
LIST(APPEND COMMON_DEFINE "-DJSON_SCHEMA_ON")
ENDIF ()
IF (USED_USER_VNI)
LIST(APPEND COMMON_DEFINE "-DUSERVNI_ON")
MESSAGE("Select Option USED_USER_VNI")
@ -92,6 +97,16 @@ IF (USED_HTTP_SVR)
MESSAGE("Select Option USED_HTTP_SVR")
ENDIF ()
IF (USED_ZMQ)
LIST(APPEND COMMON_DEFINE "-DZEROMQ_ON")
MESSAGE("Select Option USED_ZMQ")
ENDIF ()
IF (VCPE_PPPOE)
LIST(APPEND COMMON_DEFINE "-DPPPOE_ON")
MESSAGE("Select Option VCPE_PPPOE")
ENDIF ()
IF (USED_LWIP)
LIST(APPEND COMMON_DEFINE "-DLWIP_ON")
MESSAGE("Select Option USED_LWIP")

View File

@ -14,7 +14,7 @@ application:
agent: {
iptv_report_url = "http://10.0.0.1:50012/vcpe/dhcp/info"; # IPTV 设备上报接口
moniter_rep_url = "http://10.0.0.1:50012/vcpe/dhcp/restart"; # vCPE设备上下线接口
moniter_rep_url = ""; # vCPE设备上下线接口
};
# 硬件监控相关配置内容
@ -24,11 +24,6 @@ application:
memory = true; # 是否开启内存监控
disk = true; # 是否开启磁盘空间占用监控
sensor = true; # 是否开启传感器状态监控
cpu_refresh = 1; # CPU 状态刷新频率(秒)
mem_refresh = 10; # 内存状态刷新频率(秒)
disk_refresh = 10; # 磁盘状态刷新频率(秒)
sensor_refresh = 10; # 传感器状态刷新频率(秒)
};
# 数据库相关配置

View File

@ -9,7 +9,7 @@ buffer max = 2MB
rotate lock file = self
default format = "%d(%F %T.%l) %-6V (%c:%f:%L) %m%n"
file perms = 600
file perms = 644
fsync period = 1K
[levels]
@ -22,8 +22,8 @@ normal = "[%d(%F %T).%ms][%-6V][%c][%f:%L] %m"
[rules]
*.* >stdout; normal
*.INFO "./log/%c.log", \
1MB * 12 ~ "%E(HOME)/log/%c.%D(%F) #2r #3s.log"; \
*.INFO "/var/log/vcpe/%M(vni)_vcpe.log", \
1MB * 12 ~ "/var/log/vcpe/%M(vni)_vcpe_.%D(%F) #2r #3s.log"; \
normal

BIN
depend/json-c-0.16.tar.gz Normal file

Binary file not shown.

View File

@ -1,10 +1,36 @@
CMAKE_MINIMUM_REQUIRED(VERSION 3.14 FATAL_ERROR)
INCLUDE(FetchContent)
PKG_SEARCH_MODULE(LIBCURL QUIET libcurl)
PKG_SEARCH_MODULE(LIBSSL QUIET libssl)
PKG_SEARCH_MODULE(LIBCRYPTO QUIET libcrypto)
IF (USED_ZMQ)
PKG_SEARCH_MODULE(LIBZMQ QUIET libzmq)
IF (NOT LIBZMQ_FOUND)
LINUX_INSTALL_SYSTEM_PACKAGE()
ENDIF ()
ENDIF ()
IF ((NOT LIBCRYPTO_FOUND) OR (NOT LIBSSL_FOUND) OR (NOT LIBCURL_FOUND))
LINUX_INSTALL_SYSTEM_PACKAGE()
ENDIF ()
LIST(APPEND COMMON_LIBS "${LIBCURL_LDFLAGS} ${LIBSSL_LDFLAGS} ${LIBCRYPTO_LDFLAGS}")
LIST(APPEND COMMON_LIBS "${LIBZMQ_LDFLAGS}")
LIST(APPEND COMMON_LIBS "-lm -lpthread")
PKG_SEARCH_MODULE(LIBUV QUIET libuv)
PKG_SEARCH_MODULE(LIBCONFIG QUIET libconfig)
FIND_LIBRARY(LIBZLOG zlog PATHS "/usr/local/lib")
IF (USED_JSON_VALIDATE)
PKG_CHECK_MODULES(LIBJSON-C QUIET json-c>=0.13)
IF (NOT LIBJSON-C_FOUND)
FETCHCONTENT_DECLARE(libjson-c
URL file://${CMAKE_SOURCE_DIR}/depend/json-c-0.16.tar.gz
URL_MD5 a549a833f886d427148fb5710c3e613e
)
ENDIF ()
ENDIF ()
IF (NOT LIBUV_FOUND)
FETCHCONTENT_DECLARE(libuv
URL file://${CMAKE_SOURCE_DIR}/depend/libuv-v1.44.2.tar.gz
@ -35,6 +61,11 @@ IF (LIBZLOG STREQUAL "LIBZLOG-NOTFOUND")
FETCHCONTENT_MAKEAVAILABLE(zlog)
ENDIF ()
IF (USED_JSON_VALIDATE)
IF (NOT LIBJSON-C_FOUND)
FETCHCONTENT_MAKEAVAILABLE(libjson-c)
ENDIF ()
ENDIF ()
IF (NOT LIBUV_FOUND)
MESSAGE(STATUS "libuv not found, will be used source code to build it ...")
FETCHCONTENT_GETPROPERTIES(libuv)
@ -75,4 +106,24 @@ IF (LIBZLOG STREQUAL "LIBZLOG-NOTFOUND")
ELSE ()
MESSAGE(STATUS "zlog found of ${LIBZLOG}")
LIST(APPEND COMMON_LIBS "${LIBZLOG}")
ENDIF ()
IF (USED_JSON_VALIDATE)
IF (NOT LIBJSON-C_FOUND)
MESSAGE(STATUS "json-c not found, will be used source code to build it ...")
FETCHCONTENT_GETPROPERTIES(libjson-c)
IF (NOT libjson-c_POPULATED)
FETCHCONTENT_POPULATE(libjson-c)
ADD_SUBDIRECTORY(${libjson-c_SOURCE_DIR} ${libjson-c_BINARY_DIR})
ENDIF ()
EXECUTE_PROCESS(COMMAND ${CMAKE_COMMAND} -E make_directory "json-c"
COMMAND ${CMAKE_COMMAND} -E copy_if_different "${libjson-c_BINARY_DIR}/json.h" "./json-c/"
COMMAND ${CMAKE_COMMAND} -E copy_if_different "${libjson-c_BINARY_DIR}/json_config.h" "."
WORKING_DIRECTORY ${libjson-c_SOURCE_DIR})
INCLUDE_DIRECTORIES(${libjson-c_SOURCE_DIR})
LIST(APPEND COMMON_LIBS "json-c")
ELSE ()
MESSAGE(STATUS "json-c found ${LIBJSON-C_VERSION} at ${LIBJSON-C_LIBRARY_DIRS}")
LIST(APPEND COMMON_LIBS "${LIBJSON-C_LDFLAGS}")
ENDIF ()
ENDIF ()

View File

@ -6,19 +6,6 @@ ENDIF ()
PROJECT(${PROJECT_TARGET})
PKG_SEARCH_MODULE(LIBCURL QUIET libcurl)
PKG_SEARCH_MODULE(LIBSSL QUIET libssl)
PKG_SEARCH_MODULE(LIBCRYPTO QUIET libcrypto)
PKG_SEARCH_MODULE(LIBZMQ QUIET libzmq)
IF ((NOT LIBZMQ_FOUND) OR (NOT LIBCRYPTO_FOUND) OR (NOT LIBSSL_FOUND) OR (NOT LIBCURL_FOUND))
LINUX_INSTALL_SYSTEM_PACKAGE()
ENDIF ()
LIST(APPEND COMMON_LIBS "${LIBCURL_LDFLAGS} ${LIBSSL_LDFLAGS} ${LIBCRYPTO_LDFLAGS}")
LIST(APPEND COMMON_LIBS "${LIBZMQ_LDFLAGS}")
LIST(APPEND COMMON_LIBS "-lm -lpthread")
ADD_DEFINITIONS(${COMMON_DEFINE})
INCLUDE_DIRECTORIES(include ./ ./include ./libs/include ./lwip/src/include ./lwip/src/arch_linux/include
@ -29,7 +16,7 @@ SET(CMAKE_C_STANDARD 99)
FILE(GLOB VCPE_HEADS include/*.h include/uthash/*.h include/s2j/*.h
./httpserver/include/*.h ./httpserver/src/haywire/*.h ./httpserver/src/haywire/configuration/*.h)
IF (USED_LWIP)
IF (VCPE_PPPOE)
AUX_SOURCE_DIRECTORY(pppoe VCPE_SRC)
AUX_SOURCE_DIRECTORY(user VCPE_SRC)
ENDIF ()

View File

@ -17,13 +17,20 @@ AUX_SOURCE_DIRECTORY(banner C_SRC)
AUX_SOURCE_DIRECTORY(configure C_SRC)
AUX_SOURCE_DIRECTORY(network C_SRC)
AUX_SOURCE_DIRECTORY(task C_SRC)
AUX_SOURCE_DIRECTORY(mq C_SRC)
IF (USED_ZMQ)
AUX_SOURCE_DIRECTORY(mq C_SRC)
ENDIF ()
AUX_SOURCE_DIRECTORY(cmdline C_SRC)
AUX_SOURCE_DIRECTORY(crypto C_SRC)
AUX_SOURCE_DIRECTORY(hardware C_SRC)
AUX_SOURCE_DIRECTORY(protocol C_SRC)
AUX_SOURCE_DIRECTORY(fs_watch C_SRC)
AUX_SOURCE_DIRECTORY(zlog_module C_SRC)
IF (USED_JSON_VALIDATE)
ADD_SUBDIRECTORY(./json/json_schema)
ENDIF ()
IF (USED_HTTP_SVR)
AUX_SOURCE_DIRECTORY(mongoose C_SRC)
ENDIF ()
@ -62,6 +69,10 @@ ADD_LIBRARY(${LIB_PROJECT_TARGET} ${C_SRC} ${C_HEADS})
TARGET_LINK_LIBRARIES(${LIB_PROJECT_TARGET} ${COMMON_LIBS})
IF (USED_JSON_VALIDATE)
TARGET_LINK_LIBRARIES(${LIB_PROJECT_TARGET} jsoncdac)
ENDIF ()
IF (USED_OPENDHCPD)
TARGET_LINK_LIBRARIES(${LIB_PROJECT_TARGET} opendhcpd)
ENDIF ()

View File

@ -186,8 +186,11 @@ static int on_cmd2(void *pTbl[], const char *pName, void *pInfo) {
}
pJsonStr = cJSON_PrintUnformatted(pJsonObj);
ret = mq_cmd_run(pSvr, pJsonStr);
#ifdef ZEROMQ_ON
ret = mq_cmd_run(pSvr, pJsonStr);
#else
ret = ERR_SUCCESS;
#endif
cJSON_Delete(pJsonObj);
free((void *)pJsonStr);

View File

@ -73,11 +73,6 @@ static CFG_ITEM g_cfgItem[] = {
DEF_CFG_ITEM(CFG_WATCH_MEMORY, "watch_params.memory", VAL_BOOL, "1", "Monitor memory information"),
DEF_CFG_ITEM(CFG_WATCH_DISK, "watch_params.disk", VAL_BOOL, "1", "Monitor disk partition information"),
DEF_CFG_ITEM(CFG_WATCH_SENSOR, "watch_params.sensor", VAL_BOOL, "1", "Sensor information refresh frequency"),
/* 系统监控设备刷频率 */
DEF_CFG_ITEM(CFG_CPU_REFRESH, "watch_params.cpu_refresh", VAL_INT, "10", "CPU information refresh frequency"),
DEF_CFG_ITEM(CFG_MEM_REFRESH, "watch_params.mem_refresh", VAL_INT, "10", "Memory information refresh frequency"),
DEF_CFG_ITEM(CFG_DISK_REFRESH, "watch_params.disk_refresh", VAL_INT, "10", "Disk information refresh frequency"),
DEF_CFG_ITEM(CFG_SENSOR_REFRESH, "watch_params.sensor_refresh", VAL_INT, "10", "Sensor information refresh frequency"),
/* 数据库相配置 */
/* Redis配置 */
#ifdef USED_REDIS
@ -98,10 +93,12 @@ static CFG_ITEM g_cfgItem[] = {
DEF_CFG_ITEM(CFG_DB_SQLITE_DB_NAME, "database.sqlite_dbname", VAL_STR, "", "SQLite3 database file name"),
DEF_CFG_ITEM(CFG_DB_SQLITE_PASSWD, "database.sqlite_passwd", VAL_STR, ".main", "SQLite3 database password"),
#endif
#ifdef ZEROMQ_ON
/* 消息队列相配置 */
/* ZeroMq配置 */
DEF_CFG_ITEM(CFG_MQ_SVR_PORT, "zero_mq.svr_port", VAL_INT, "6278", "ZeroMQ server port"),
DEF_CFG_ITEM(CFG_MQ_DATA_PATH, "zero_mq.agent_addr", VAL_STR, "ipc:///tmp/msg_fifo0", "ZeroMQ Agent data path"),
#endif
/* vxLan 隧道配置 */
DEF_CFG_ITEM(CFG_VXLAN_NIC_NAME, "vxlan_wan.nic", VAL_STR, "", "Network card name to send data"),
DEF_CFG_ITEM(CFG_VXLAN_SUPPORT, "vxlan_wan.enable", VAL_BOOL, "1", "Is support vxLan tune"),

View File

@ -121,22 +121,6 @@ int cfg_get_watch_sensor() {
return cfg_get_bool_value(CFG_WATCH_SENSOR);
}
unsigned int cfg_get_cpu_refresh_period() {
return cfg_get_integral_value(CFG_CPU_REFRESH);
}
unsigned int cfg_get_mem_refresh_period() {
return cfg_get_integral_value(CFG_MEM_REFRESH);
}
unsigned int cfg_get_disk_refresh_period() {
return cfg_get_integral_value(CFG_DISK_REFRESH);
}
unsigned int cfg_get_sensor_refresh_period() {
return cfg_get_integral_value(CFG_SENSOR_REFRESH);
}
#ifdef USED_SQLITE
const char *cfg_get_sqlite_db_name() {
return cfg_get_string_value(CFG_DB_SQLITE_DB_NAME);
@ -183,10 +167,12 @@ const char *cfg_get_mysql_database() {
}
#endif
#ifdef ZEROMQ_ON
int cfg_get_zero_mq_port() {
return (unsigned short)cfg_get_integral_value(CFG_MQ_SVR_PORT);
}
const char *cfg_get_zero_mq_data_path() {
return cfg_get_string_value(CFG_MQ_DATA_PATH);
}
}
#endif

View File

@ -68,7 +68,7 @@ static int sha1prng_for_aes_key(const char *pKey, unsigned char *pShaPrng16) {
case AES128_ECB_PKCS7PADDING_SHA1PRNG: \
if (sha1prng_for_aes_key(pKey, keyBuf) != ERR_SUCCESS) { \
EVP_CIPHER_CTX_cleanup(pCtx); \
return -ERR_AES128_KEYGEN; \
return -ERR_AES_KEYGEN; \
} \
pCipher = EVP_aes_128_ecb(); \
break; \
@ -165,8 +165,8 @@ int symmetric_decrypto(AES_TYPE algorithmType,
return -ERR_EVP_UPDATE;
}
*pOutBuf = pAesBuf;
pAesBuf += enBytes;
*pOutBuf = pAesBuf;
pAesBuf += enBytes;
*pOutSize += enBytes;
if (EVP_DecryptFinal_ex(pCtx, pAesBuf, &enBytes) == 0) {
@ -239,8 +239,8 @@ int symmetric_encrypto(AES_TYPE algorithmType,
return -ERR_EVP_UPDATE;
}
*pOutBuf = pAesBuf;
pAesBuf += enBytes;
*pOutBuf = pAesBuf;
pAesBuf += enBytes;
*pOutSize += enBytes;
if (EVP_EncryptFinal_ex(pCtx, pAesBuf, &enBytes) == 0) {

View File

@ -0,0 +1,130 @@
# json-c d'accord library (libjsoncdac)
jsonc-daccord is a lightweight JSON Schema validation library written in C, and is taking advantage of the libjson-c library.
## Design Goals
The goal is to have a lightweight JSON Schema validation implementation in C using json-c. json-c is popular in OpenWRT communities. Initially I just wanted it to support a small subset of JSON Schema to suit a need to validate simple json files. See the minimum build supports below. However to suit a broader audience, supporting more JSON Schema is important.
Currently the footprint of libjsoncdac.so is 8KB. The keep the footprint from bloating out, new features should be selectable using CMake options.
Minimal build supports:
- all: type, enum, required, properties, const.
- objects:
- strings: minLength, maxLength.
- integers and doubles: minimum, maximum.
- arrays: minItems, maxItems, uniqeItems, items.
## Example Use
Public headers:
See [jsoncdaccord.h](include/jsoncdaccord.h)
```C
int jdac_validate_file(const char *jsonfile, const char *jsonschemafile);
int jdac_validate(json_object *jobj, json_object *jschema);
int jdac_ref_set_localpath(const char *_localpath);
const char* jdac_errorstr(unsigned int jdac_errors);
```
Link your binary to: `-ljsoncdac -ljson-c`
Use the #include header: `#include <jsoncdaccord.h>`
Example C code:
```C
#include <stdio.h>
#include <json-c/json.h>
#include <jsoncdaccord.h>
int main(int argc, char *argv[])
{
char *json_file = "test.json";
char *schema_file = "schema.json";
// optional: load referenced schema files from filesystem
char *localpath = "/my/path/to_json_files/";
jdac_ref_set_localpath(localpath);
printf("validating %s with %s\n", json_file, schema_file);
int err = jdac_validate_file(json_file, schema_file);
if (err==JDAC_ERR_VALID) {
printf("validation ok\n");
} else {
printf("validate failed %d: %s\n", err, jdac_errorstr(err));
}
return err;
}
```
See [jdac-cli.c](libjsoncdac/jdac-cli.c) as well.
## Install
Building from source:
Install json-c and libcmocka-dev (used in the debug builds).
- Release version:
```
git clone --branch libjsoncdac-0.2 https://github.com/domoslabs/jsonc-daccord &&\
cd jsonc-daccord && mkdir build && cd build &&\
cmake .. -DCMAKE_BUILD_TYPE=Release && make && sudo make install
```
- Debug version:
```
git clone --branch libjsoncdac-0.2 https://github.com/domoslabs/jsonc-daccord &&\
cd jsonc-daccord && mkdir build && cd build &&\
cmake .. -DCMAKE_BUILD_TYPE=Debug && make && sudo make install
```
Note: After install you might need to run `sudo ldconfig`.
## CMake Options
build options:
| option | description |
| :------------------------- | :------------------------------------------------------- |
| CMAKE_BUILD_TYPE | Build as Release or Debug. Default: Release. |
| RUN_TEST_SUITE | Run JSON Schema test suite (CMAKE_BUILD_TYPE=Debug Only) |
| BUILD_PATTERN | Support *pattern*. |
| BUILD_PATTERNPROPERTIES | Support *patternProperties* |
| BUILD_ADDITIONALPROPERTIES | Support *additionalProperties* |
| BUILD_PROPERTYNAMES | Support *propertyNames* |
| BUILD_SUBSCHEMALOGIC | Support *allOf*, *anyOf*, *oneOf*, *not*, *if-then-else* |
| BUILD_CONTAINS | Support *contains*, *minContains*, and *maxContains* |
| BUILD_DOWNLOAD | Support downloading referenced schema files |
| BUILD_STORE | Support build a list of schema uri, id, and anchors |
| BUILD_REF | Support *$ref* keyword. load schemas by file. |
Note: All BUILD_* options are selected by default
## Run tests
For debug builds:
```
ctest
ctest -V # to see output of tests
```
Running test suites are currently optional, and are select with `RUN_TEST_SUITE=ON` in the cmake options.
## Command Line Interface
You can try the library with the jdac-cli command.
```/tmp/domos/domosqos-sta_statistics_json
jdac-cli -h
```
## To do
- prevent infinite recursion
## Related links
- https://json-schema.org/specification.html
- https://github.com/json-schema-org/JSON-Schema-Test-Suite
- https://github.com/json-c/json-c

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,6 @@
{
"botenanna": "botenannna",
"boten": "boten",
"wuhu": "wublah",
"nullobject": null
}

View File

@ -0,0 +1,7 @@
{
"empty": {},
"botenanna": {
"annaaaa": "boten"
},
"nonobject": null
}

View File

@ -0,0 +1,35 @@
{
"test-int": {
"id": 123
},
"test-double": {
"id": 1.23
},
"test-string": {
"id": "1234"
},
"test-boolean": {
"id": true
},
"test-array": [
123,
"1234"
],
"test-array2": [
123,
{}
],
"test-array": {
"anna": [
{
"id": 1
},
{
"id": 2
},
{
"id": 3
}
]
}
}

View File

@ -0,0 +1,10 @@
{
"teststring1": "one",
"teststring2": "two",
"teststring3": "three",
"teststring4": "four",
"testinteger1": 1,
"testinteger2": 2,
"testinteger3": 3,
"testinteger4": 4
}

View File

@ -0,0 +1,53 @@
{
"test1": {
"flowarray": [
{
"key1": 5,
"key2": "hanz"
}
]
},
"wrongtype": {
"flowarray": [
{
"key1": "5",
"key2": "hanz"
}
]
},
"missingkey": {
"flowarray": [
{
"key2": "hanz"
}
]
},
"nestedarray": {
"flowarray": [
{
"key1": "hanz",
"key2": [
1,
2,
3,
4,
5
]
}
]
},
"nestedarrayofstrings": {
"flowarray": [
{
"key1": "hanz",
"key2": [
"1",
"2",
"3",
"4",
"5"
]
}
]
}
}

View File

@ -0,0 +1,7 @@
{
"array-1": [1],
"array-2": [1,2],
"array-3": [1,2,3],
"array-4": [1,2,3,4],
"array-5": [1,2,3,4,5]
}

View File

@ -0,0 +1,57 @@
{
"emptyobject": {},
"testjson": {
"computer": "banana",
"phone": 12345678,
"switch": true
},
"testjsontrue": {
"computer": "banana",
"phone": 12345678,
"switch": true,
"object": {"object":123},
"list": [1,2,3]
},
"testjsonfalse": {
"computer": 12345678,
"phone": "banana",
"switch": [1,2,3],
"object": true,
"list": {"object":123}
},
"testjsonstring-all": {
"computer1": "hansihansi",
"computer2": "hans",
"computer3": "ha",
"computer4": "han"
},
"testjsonstring-all-fail": {
"computer1": "hansihansi",
"computer2": "hansi",
"computer3": "han",
"computer4": "hans"
},
"testjsonstring2": {
"computer4": "ha"
},
"testjsonstring3": {
"computer4": "han"
},
"testjsonstring4": {
"computer4": "hans"
},
"testjsonstring5": {
"computer4": "hansp"
}
}

View File

@ -0,0 +1,36 @@
{
"alltrue": {
"person": {
"name": "Anna",
"husbands": 1
}
},
"nametooshort": {
"person": {
"name": "Ann",
"husbands": 1
}
},
"wrongtype": {
"person": {
"name": "Anna",
"husbands": "1"
}
},
"husbandmissing": {
"person": {
"name": "Anna"
}
},
"namemissing": {
"person": {
}
},
"empty": {
}
}

View File

@ -0,0 +1,11 @@
{
"test-emptyjson": {},
"test-keywords-abc": {"a":"a", "b":"b", "c":"c"},
"test-keywords-bc": {"b":"b", "c":"c"},
"test-keywords-ac": {"a":"a", "c":"c"},
"test-keywords-ab": {"a":"a", "b":"b"},
"test-keywords-a": {"a":"a"},
"test-keywords-b": {"b":"b"},
"test-keywords-c": {"c":"c"},
"test-wrongtype": 123
}

View File

@ -0,0 +1,8 @@
{
"test-object" : {"1":"2"},
"test-array" : [1,2,3],
"test-string" : "101",
"test-integer" : 101,
"test-double" : 101.1,
"test-boolean" : true
}

View File

@ -0,0 +1,10 @@
{
"array-empty": [],
"array-unique1": [1,2,3,4,5,6],
"array-unique2": ["one","two","three"],
"array-notunique1": [1,2,3,3,5,6],
"array-notunique2": [1,2,3,4,5,5],
"array-notunique3": [1,1,3,4,5,6],
"array-notunique4": [1,1,1,4,5,6],
"array-notunique5": ["one", "two", "two"]
}

View File

@ -0,0 +1,106 @@
{
"truejson":
{
"ID": "lcss_vectors",
"Version": "v01",
"Services": [
{
"Service": "slitherio",
"NetifyName": "gaming.slitherio",
"max_diff": 1,
"max_length": 10,
"ValidPorts": [ [444,445] ],
"vectors": [
{
"ID": "v0",
"CT": 0,
"TT": 0,
"ignore_indices": [0,1],
"proto": "tcp",
"confidence": 10,
"vector": [1,2,3,4,5,6,7,8,9]
}
]
}
]
},
"validport_toohigh":
{
"ID": "lcss_vectors",
"Version": "v01",
"Services": [
{
"Service": "slitherio",
"NetifyName": "gaming.slitherio",
"max_diff": 1,
"max_length": 10,
"ValidPorts": [ [444,445], [50000,100000] ],
"vectors": [
{
"ID": "v0",
"CT": 0,
"TT": 0,
"ignore_indices": [0,1],
"proto": "tcp",
"confidence": 10,
"vector": [1,2,3,4,5,6,7,8,9]
}
]
}
]
},
"ignore_indices_index_too_high":
{
"ID": "lcss_vectors",
"Version": "v01",
"Services": [
{
"Service": "slitherio",
"NetifyName": "gaming.slitherio",
"max_diff": 1,
"max_length": 10,
"ValidPorts": [ [444,445] ],
"vectors": [
{
"ID": "v0",
"CT": 0,
"TT": 0,
"ignore_indices": [0,20],
"proto": "tcp",
"confidence": 10,
"vector": [1,2,3,4,5,6,7,8,9]
}
]
}
]
},
"too_many_vector_elements":
{
"ID": "lcss_vectors",
"Version": "v01",
"Services": [
{
"Service": "slitherio",
"NetifyName": "gaming.slitherio",
"max_diff": 1,
"max_length": 10,
"ValidPorts": [ [444,445] ],
"vectors": [
{
"ID": "v0",
"CT": 0,
"TT": 0,
"ignore_indices": [0,1],
"proto": "tcp",
"confidence": 10,
"vector": [0,1,2,3,4,5,6,7,8,9,10]
}
]
}
]
}
}

View File

@ -0,0 +1,760 @@
{
"ID": "lcss_vectors",
"Version": "v01",
"Services": [
{
"Service": "slitherio",
"NetifyName": "gaming.slitherio",
"ValidPorts": [
[
444,
444
]
],
"vectors": [
{
"ID": "v0",
"CT": 0,
"TT": 0,
"ignore_indices": [
0,
1
],
"proto": "tcp",
"confidence": 10,
"vector": [
0,
0
]
}
]
},
{
"Service": "steamworks",
"NetifyName": "gaming.steamworks",
"ValidPorts": [
[
4380,
4380
],
[
27000,
27100
]
],
"vectors": [
{
"ID": "v0",
"CT": 2,
"TT": 20,
"ignore_indices": [],
"proto": "udp",
"confidence": 10,
"vector": [
1300,
-214
]
},
{
"ID": "v1",
"CT": 2,
"TT": 0,
"ignore_indices": [],
"proto": "udp",
"confidence": 10,
"vector": [
1300,
1300
]
}
]
},
{
"Service": "leagueoflegends",
"NetifyName": "gaming.leagueoflegends",
"ValidPorts": [
[
5000,
5500
]
],
"vectors": [
{
"ID": "v0",
"CT": 2,
"TT": 0,
"ignore_indices": [],
"proto": "udp",
"confidence": 10,
"vector": [
515,
-107
]
},
{
"ID": "v1",
"CT": 2,
"TT": 0,
"ignore_indices": [],
"proto": "udp",
"confidence": 10,
"vector": [
515,
515
]
}
]
},
{
"Service": "apex",
"NetifyName": "gaming.apex",
"ValidPorts": [
[
1024,
1124
],
[
18000,
18000
],
[
29900,
29900
],
[
37000,
40000
]
],
"vectors": [
{
"ID": "v0",
"CT": 2,
"TT": 0,
"ignore_indices": [],
"proto": "udp",
"confidence": 10,
"vector": [
50,
-58
]
},
{
"ID": "v1",
"CT": 2,
"TT": 0,
"ignore_indices": [],
"proto": "udp",
"confidence": 10,
"vector": [
50,
50
]
}
]
},
{
"Service": "rainbow6",
"NetifyName": "gaming.rainbow6",
"ValidPorts": [
[
3074,
3074
],
[
4380,
4380
],
[
6015,
6015
],
[
10000,
10099
]
],
"vectors": [
{
"ID": "v0",
"CT": 2,
"TT": 0,
"ignore_indices": [],
"proto": "udp",
"confidence": 10,
"vector": [
139,
139
]
},
{
"ID": "v1",
"CT": 2,
"TT": 0,
"ignore_indices": [],
"proto": "udp",
"confidence": 10,
"vector": [
139,
-131
]
}
]
},
{
"Service": "iperf3",
"NetifyName": "domos.iperf3",
"ValidPorts": [
[
5201,
5201
]
],
"vectors": [
{
"ID": "v2",
"ignore_indices": [],
"CT": 2,
"TT": 0,
"proto": "udp",
"confidence": 10,
"vector": [
4,
-4
]
}
]
},
{
"Service": "flent",
"NetifyName": "domos.flent",
"ValidPorts": [
[
2116,
2116
]
],
"vectors": [
{
"ID": "v2",
"ignore_indices": [],
"CT": 0,
"TT": 0,
"proto": "udp",
"confidence": 10,
"vector": [
4,
-4
]
}
]
},
{
"Service": "unrealengine4",
"NetifyName": "gaming.unrealengine4",
"ValidPorts": [
[
12000,
65535
]
],
"vectors": [
{
"ID": "v0",
"ignore_indices": [],
"CT": 2,
"TT": 0,
"proto": "udp",
"confidence": 10,
"vector": [
29,
-29
]
},
{
"ID": "v1",
"ignore_indices": [],
"CT": 2,
"TT": 0,
"proto": "udp",
"confidence": 10,
"vector": [
29,
29
]
}
]
},
{
"Service": "overwatch",
"NetifyName": "gaming.overwatch",
"ValidPorts": [
[
26400,
27000
]
],
"vectors": [
{
"ID": "v0",
"ignore_indices": [],
"CT": 2,
"TT": 0,
"proto": "udp",
"confidence": 10,
"vector": [
34,
-34
]
},
{
"ID": "v1",
"ignore_indices": [],
"CT": 2,
"TT": 0,
"proto": "udp",
"confidence": 10,
"vector": [
34,
34
]
}
]
},
{
"Service": "valorant",
"NetifyName": "gaming.valorant",
"ValidPorts": [
[
7000,
7500
]
],
"vectors": [
{
"ID": "v0",
"ignore_indices": [],
"CT": 2,
"TT": 0,
"proto": "udp",
"confidence": 10,
"vector": [
53,
-33
]
},
{
"ID": "v1",
"ignore_indices": [],
"CT": 2,
"TT": 0,
"proto": "udp",
"confidence": 10,
"vector": [
53,
53
]
}
]
},
{
"Service": "seaofthieves",
"NetifyName": "gaming.seaofthieves",
"ValidPorts": [
[
30000,
32000
]
],
"vectors": [
{
"ID": "v0",
"ignore_indices": [],
"CT": 2,
"TT": 0,
"proto": "udp",
"confidence": 10,
"vector": [
51,
-88
]
},
{
"ID": "v1",
"ignore_indices": [],
"CT": 2,
"TT": 0,
"proto": "udp",
"confidence": 10,
"vector": [
51,
51
]
},
{
"ID": "v1",
"ignore_indices": [],
"CT": 2,
"TT": 0,
"proto": "udp",
"confidence": 10,
"vector": [
272,
60
]
}
]
},
{
"Service": "rust",
"NetifyName": "gaming.rust",
"ValidPorts": [
[
28015,
28015
],
[
28225,
28225
]
],
"vectors": [
{
"ID": "v0",
"ignore_indices": [],
"CT": 2,
"TT": 0,
"proto": "udp",
"confidence": 10,
"vector": [
1372,
-28
]
},
{
"ID": "v1",
"ignore_indices": [],
"CT": 2,
"TT": 0,
"proto": "udp",
"confidence": 10,
"vector": [
1372,
1372
]
}
]
},
{
"Service": "minecraft",
"NetifyName": "gaming.minecraft",
"ValidPorts": [
[
19132,
19133
],
[
19000,
20000
]
],
"vectors": [
{
"ID": "v0",
"ignore_indices": [],
"CT": 2,
"TT": 0,
"proto": "udp",
"confidence": 10,
"vector": [
33,
1464
]
},
{
"ID": "v1",
"ignore_indices": [],
"CT": 2,
"TT": 0,
"proto": "udp",
"confidence": 10,
"vector": [
33,
33
]
}
]
},
{
"Service": "gta5",
"NetifyName": "gaming.gta5",
"ValidPorts": [
[
6672,
6672
],
[
61455,
61458
]
],
"vectors": [
{
"ID": "v0",
"ignore_indices": [
1
],
"CT": 2,
"TT": 0,
"proto": "udp",
"confidence": 10,
"vector": [
221,
0
]
},
{
"ID": "v1",
"ignore_indices": [],
"CT": 2,
"TT": 0,
"proto": "udp",
"confidence": 10,
"vector": [
221,
-221
]
},
{
"ID": "v3",
"ignore_indices": [
1
],
"CT": 2,
"TT": 0,
"proto": "udp",
"confidence": 10,
"vector": [
237,
0
]
},
{
"ID": "v3",
"ignore_indices": [
1
],
"CT": 2,
"TT": 0,
"proto": "udp",
"confidence": 10,
"vector": [
205,
0
]
},
{
"ID": "v3",
"ignore_indices": [
1
],
"CT": 2,
"TT": 0,
"proto": "udp",
"confidence": 10,
"vector": [
141,
205
]
}
]
},
{
"Service": "starcraft2",
"NetifyName": "gaming.starcraft2",
"ValidPorts": [
[
3724,
3724
]
],
"vectors": [
{
"ID": "v0",
"CT": 2,
"TT": 0,
"ignore_indices": [],
"proto": "udp",
"confidence": 10,
"vector": [
20,
-20
]
},
{
"ID": "v0",
"CT": 2,
"TT": 0,
"ignore_indices": [],
"proto": "udp",
"confidence": 10,
"vector": [
20,
20
]
}
]
},
{
"Service": "video-conferencing",
"NetifyName": "video-conferencing.video-conf",
"ValidPorts": [
[
3478,
3478
]
],
"vectors": [
{
"ID": "v0",
"CT": 0,
"TT": 0,
"ignore_indices": [],
"proto": "udp",
"confidence": 4,
"vector": []
}
]
},
{
"Service": "slack",
"NetifyName": "video-conferencing.slack",
"ValidPorts": [
[
22466,
22466
]
],
"vectors": [
{
"ID": "v0",
"CT": 0,
"TT": 0,
"ignore_indices": [],
"proto": "udp",
"confidence": 6,
"vector": []
}
]
},
{
"Service": "webex",
"NetifyName": "video-conferencing.webex",
"ValidPorts": [
[
9000,
9000
]
],
"vectors": [
{
"ID": "v0",
"CT": 0,
"TT": 0,
"ignore_indices": [],
"proto": "udp",
"confidence": 6,
"vector": []
}
]
},
{
"Service": "meet",
"NetifyName": "video-conferencing.meet",
"ValidPorts": [
[
19302,
19309
]
],
"vectors": [
{
"ID": "v0",
"CT": 0,
"TT": 0,
"ignore_indices": [],
"proto": "udp",
"confidence": 6,
"vector": []
}
]
},
{
"Service": "zoom",
"NetifyName": "video-conferencing.zoom",
"ValidPorts": [
[
3478,
3479
],
[
8801,
8802
]
],
"vectors": [
{
"ID": "v0",
"CT": 0,
"TT": 0,
"ignore_indices": [],
"proto": "udp",
"confidence": 6,
"vector": []
}
]
},
{
"Service": "bluejeans",
"NetifyName": "video-conferencing.bluejeans",
"ValidPorts": [
[
5000,
5000
]
],
"vectors": [
{
"ID": "v0",
"CT": 0,
"TT": 0,
"ignore_indices": [],
"proto": "udp",
"confidence": 6,
"vector": []
}
]
},
{
"Service": "teams/skype",
"NetifyName": "video-conferencing.teams/skype",
"ValidPorts": [
[
3478,
3481
]
],
"vectors": [
{
"ID": "v0",
"CT": 0,
"TT": 0,
"ignore_indices": [],
"proto": "udp",
"confidence": 6,
"vector": []
}
]
}
]
}

View File

@ -0,0 +1,769 @@
{
"ID": "lcss_vectors",
"Version": "v01",
"Services": [
{
"Service": "slitherio",
"NetifyName": "gaming.slitherio",
"max_diff": 1,
"max_length": 10,
"ValidPorts": [
[
444,
444
]
],
"vectors": [
{
"ID": "v0",
"TT": 0,
"ignore_indices": [
0,
1
],
"proto": "tcp",
"confidence": 10,
"vector": [
0,
0
]
}
]
},
{
"Service": "steamworks",
"NetifyName": "gaming.steamworks",
"max_diff": 1,
"max_length": 10,
"ValidPorts": [
[
4380,
4380
],
[
27000,
27100
]
],
"vectors": [
{
"ID": "v0",
"CT": 2,
"TT": 20,
"ignore_indices": [],
"proto": "udp",
"confidence": 10,
"vector": [
1300,
-214
]
},
{
"ID": "v1",
"CT": 2,
"TT": 0,
"ignore_indices": [],
"proto": "udp",
"confidence": 10,
"vector": [
1300,
1300
]
}
]
},
{
"Service": "leagueoflegends",
"NetifyName": "gaming.leagueoflegends",
"max_diff": 1,
"max_length": 10,
"ValidPorts": [
[
5000,
5500
]
],
"vectors": [
{
"ID": "v0",
"CT": 2,
"TT": 0,
"ignore_indices": [],
"proto": "udp",
"confidence": 10,
"vector": [
515,
-107
]
},
{
"ID": "v1",
"CT": 2,
"TT": 0,
"ignore_indices": [],
"proto": "udp",
"confidence": 10,
"vector": [
515,
515
]
}
]
},
{
"Service": "apex",
"NetifyName": "gaming.apex",
"max_diff": 1,
"max_length": 10,
"ValidPorts": [
[
1024,
1124
],
[
18000,
18000
],
[
29900,
29900
],
[
37000,
40000
]
],
"vectors": [
{
"ID": "v0",
"CT": 2,
"TT": 0,
"ignore_indices": [],
"proto": "udp",
"confidence": 10,
"vector": [
50,
-58
]
},
{
"ID": "v1",
"CT": 2,
"TT": 0,
"ignore_indices": [],
"proto": "udp",
"confidence": 10,
"vector": [
50,
50
]
}
]
},
{
"Service": "rainbow6",
"NetifyName": "gaming.rainbow6",
"max_diff": 1,
"max_length": 10,
"ValidPorts": [
[
3074,
3074
],
[
4380,
4380
],
[
6015,
6015
],
[
10000,
10099
]
],
"vectors": [
{
"ID": "v0",
"CT": 2,
"TT": 0,
"ignore_indices": [],
"proto": "udp",
"confidence": 10,
"vector": [
139,
139
]
},
{
"ID": "v1",
"CT": 2,
"TT": 0,
"ignore_indices": [],
"proto": "udp",
"confidence": 10,
"vector": [
139,
-131
]
}
]
},
{
"Service": "iperf3",
"NetifyName": "domos.iperf3",
"ValidPorts": [
[
5201,
5201
]
],
"vectors": [
{
"ID": "v2",
"ignore_indices": [],
"CT": 2,
"TT": 0,
"proto": "udp",
"confidence": 10,
"vector": [
4,
-4
]
}
]
},
{
"Service": "flent",
"NetifyName": "domos.flent",
"ValidPorts": [
[
2116,
2116
]
],
"vectors": [
{
"ID": "v2",
"ignore_indices": [],
"CT": 0,
"TT": 0,
"proto": "udp",
"confidence": 10,
"vector": [
4,
-4
]
}
]
},
{
"Service": "unrealengine4",
"NetifyName": "gaming.unrealengine4",
"ValidPorts": [
[
12000,
65535
]
],
"vectors": [
{
"ID": "v0",
"ignore_indices": [],
"CT": 2,
"TT": 0,
"proto": "udp",
"confidence": 10,
"vector": [
29,
-29
]
},
{
"ID": "v1",
"ignore_indices": [],
"CT": 2,
"TT": 0,
"proto": "udp",
"confidence": 10,
"vector": [
29,
29
]
}
]
},
{
"Service": "overwatch",
"NetifyName": "gaming.overwatch",
"ValidPorts": [
[
26400,
27000
]
],
"vectors": [
{
"ID": "v0",
"ignore_indices": [],
"CT": 2,
"TT": 0,
"proto": "udp",
"confidence": 10,
"vector": [
34,
-34
]
},
{
"ID": "v1",
"ignore_indices": [],
"CT": 2,
"TT": 0,
"proto": "udp",
"confidence": 10,
"vector": [
34,
34
]
}
]
},
{
"Service": "valorant",
"NetifyName": "gaming.valorant",
"ValidPorts": [
[
7000,
7500
]
],
"vectors": [
{
"ID": "v0",
"ignore_indices": [],
"CT": 2,
"TT": 0,
"proto": "udp",
"confidence": 10,
"vector": [
53,
-33
]
},
{
"ID": "v1",
"ignore_indices": [],
"CT": 2,
"TT": 0,
"proto": "udp",
"confidence": 10,
"vector": [
53,
53
]
}
]
},
{
"Service": "seaofthieves",
"NetifyName": "gaming.seaofthieves",
"ValidPorts": [
[
30000,
32000
]
],
"vectors": [
{
"ID": "v0",
"ignore_indices": [],
"CT": 2,
"TT": 0,
"proto": "udp",
"confidence": 10,
"vector": [
51,
-88
]
},
{
"ID": "v1",
"ignore_indices": [],
"CT": 2,
"TT": 0,
"proto": "udp",
"confidence": 10,
"vector": [
51,
51
]
},
{
"ID": "v1",
"ignore_indices": [],
"CT": 2,
"TT": 0,
"proto": "udp",
"confidence": 10,
"vector": [
272,
60
]
}
]
},
{
"Service": "rust",
"NetifyName": "gaming.rust",
"ValidPorts": [
[
28015,
28015
],
[
28225,
28225
]
],
"vectors": [
{
"ID": "v0",
"ignore_indices": [],
"CT": 2,
"TT": 0,
"proto": "udp",
"confidence": 10,
"vector": [
1372,
-28
]
},
{
"ID": "v1",
"ignore_indices": [],
"CT": 2,
"TT": 0,
"proto": "udp",
"confidence": 10,
"vector": [
1372,
1372
]
}
]
},
{
"Service": "minecraft",
"NetifyName": "gaming.minecraft",
"ValidPorts": [
[
19132,
19133
],
[
19000,
20000
]
],
"vectors": [
{
"ID": "v0",
"ignore_indices": [],
"CT": 2,
"TT": 0,
"proto": "udp",
"confidence": 10,
"vector": [
33,
1464
]
},
{
"ID": "v1",
"ignore_indices": [],
"CT": 2,
"TT": 0,
"proto": "udp",
"confidence": 10,
"vector": [
33,
33
]
}
]
},
{
"Service": "gta5",
"NetifyName": "gaming.gta5",
"ValidPorts": [
[
6672,
6672
],
[
61455,
61458
]
],
"vectors": [
{
"ID": "v0",
"ignore_indices": [
1
],
"CT": 2,
"TT": 0,
"proto": "udp",
"confidence": 10,
"vector": [
221,
0
]
},
{
"ID": "v1",
"ignore_indices": [],
"CT": 2,
"TT": 0,
"proto": "udp",
"confidence": 10,
"vector": [
221,
-221
]
},
{
"ID": "v3",
"ignore_indices": [
1
],
"CT": 2,
"TT": 0,
"proto": "udp",
"confidence": 10,
"vector": [
237,
0
]
},
{
"ID": "v3",
"ignore_indices": [
1
],
"CT": 2,
"TT": 0,
"proto": "udp",
"confidence": 10,
"vector": [
205,
0
]
},
{
"ID": "v3",
"ignore_indices": [
1
],
"CT": 2,
"TT": 0,
"proto": "udp",
"confidence": 10,
"vector": [
141,
205
]
}
]
},
{
"Service": "starcraft2",
"NetifyName": "gaming.starcraft2",
"ValidPorts": [
[
3724,
3724
]
],
"vectors": [
{
"ID": "v0",
"CT": 2,
"TT": 0,
"ignore_indices": [],
"proto": "udp",
"confidence": 10,
"vector": [
20,
-20
]
},
{
"ID": "v0",
"CT": 2,
"TT": 0,
"ignore_indices": [],
"proto": "udp",
"confidence": 10,
"vector": [
20,
20
]
}
]
},
{
"Service": "video-conferencing",
"NetifyName": "video-conferencing.video-conf",
"ValidPorts": [
[
3478,
3478
]
],
"vectors": [
{
"ID": "v0",
"CT": 0,
"TT": 0,
"ignore_indices": [],
"proto": "udp",
"confidence": 4,
"vector": []
}
]
},
{
"Service": "slack",
"NetifyName": "video-conferencing.slack",
"ValidPorts": [
[
22466,
22466
]
],
"vectors": [
{
"ID": "v0",
"CT": 0,
"TT": 0,
"ignore_indices": [],
"proto": "udp",
"confidence": 6,
"vector": []
}
]
},
{
"Service": "webex",
"NetifyName": "video-conferencing.webex",
"ValidPorts": [
[
9000,
9000
]
],
"vectors": [
{
"ID": "v0",
"CT": 0,
"TT": 0,
"ignore_indices": [],
"proto": "udp",
"confidence": 6,
"vector": []
}
]
},
{
"Service": "meet",
"NetifyName": "video-conferencing.meet",
"ValidPorts": [
[
19302,
19309
]
],
"vectors": [
{
"ID": "v0",
"CT": 0,
"TT": 0,
"ignore_indices": [],
"proto": "udp",
"confidence": 6,
"vector": []
}
]
},
{
"Service": "zoom",
"NetifyName": "video-conferencing.zoom",
"ValidPorts": [
[
3478,
3479
],
[
8801,
8802
]
],
"vectors": [
{
"ID": "v0",
"CT": 0,
"TT": 0,
"ignore_indices": [],
"proto": "udp",
"confidence": 6,
"vector": []
}
]
},
{
"Service": "bluejeans",
"NetifyName": "video-conferencing.bluejeans",
"ValidPorts": [
[
5000,
5000
]
],
"vectors": [
{
"ID": "v0",
"CT": 0,
"TT": 0,
"ignore_indices": [],
"proto": "udp",
"confidence": 6,
"vector": []
}
]
},
{
"Service": "teams/skype",
"NetifyName": "video-conferencing.teams/skype",
"ValidPorts": [
[
3478,
3481
]
],
"vectors": [
{
"ID": "v0",
"CT": 0,
"TT": 0,
"ignore_indices": [],
"proto": "udp",
"confidence": 6,
"vector": []
}
]
}
]
}

View File

@ -0,0 +1 @@
{}

View File

@ -0,0 +1,68 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"description": "Represents a collection of flows. For testing ref defs",
"type": "object",
"properties": {
"flows": {
"type": "array",
"items": {
"$ref": "#/$defs/flow"
}
}
},
"required": [
"flows"
],
"$defs": {
"flow": {
"type": "object",
"properties": {
"flow_id": {
"type": "string"
},
"service_name": {
"type": "string"
},
"master_protocol": {
"type": "string"
},
"sport": {
"type": "integer"
},
"dport": {
"type": "integer"
},
"src": {
"type": "string"
},
"dst": {
"type": "string"
},
"proto": {
"type": "string"
},
"alive": {
"type": "string"
},
"active": {
"type": "boolean"
},
"extrakeythatdoesnotexist": {
"type": "string"
}
},
"required": [
"flow_id",
"service_name",
"master_protocol",
"sport",
"dport",
"src",
"dst",
"proto",
"alive",
"active"
]
}
}
}

View File

@ -0,0 +1,12 @@
{
"description": "string pattern side tests",
"schema-non-object": {
"pattern": true
},
"schema-invalid-regex": {
"pattern": "^[a-zA-Z0-9]*@[a-zA-Z0-9-_.]*[.]*?"
},
"schema-valid": {
"pattern": "boten*"
}
}

View File

@ -0,0 +1,23 @@
{
"description": "patternProperties side tests",
"schema-non-object": {
"patternProperties": true
},
"schema-invalid-regex": {
"patternProperties": {
"^[a-zA-Z0-9]*@[a-zA-Z0-9-_.]*[.]*?": {
"type": "object"
}
}
},
"schema-valid": {
"patternProperties": {
"boten*": {
"type": "string"
},
"anna.*": {
"type": "string"
}
}
}
}

View File

@ -0,0 +1,51 @@
{
"acceptstringandinteger": {
"$schema": "https://json-schema.org/draft/2019-09/schema",
"type": "object",
"anyOf": [
{
"properties": {
"id": {
"type": "integer"
}
}
},
{
"properties": {
"id": {
"type": "string"
}
}
}
],
"required": [
"id"
]
},
"inarray": {
"$schema": "https://json-schema.org/draft/2019-09/schema",
"type": "object",
"properties": {
"anna": {
"type": "array",
"items": {
"anyOf": [
{
"type": "object",
"required": [
"id"
]
}
]
}
}
}
},
"anyOfSchemaError": {
"$schema": "https://json-schema.org/draft/2019-09/schema",
"type": "object",
"anyOf": [
"type"
]
}
}

View File

@ -0,0 +1,22 @@
{
"enum-string": {
"type": "string",
"enum": [
"one",
"two",
"three"
]
},
"enum-integer": {
"type": "integer",
"enum": [
1,
2,
3
]
},
"enum-schemaerror": {
"type": "integer",
"enum": "1,2,3"
}
}

View File

@ -0,0 +1,51 @@
{
"test1": {
"type": "object",
"properties": {
"flowarray": {
"type": "array",
"items": {
"type": "object",
"required": [
"key1",
"key2"
],
"properties": {
"key1": {
"type": "integer"
},
"key2": {
"type": "string"
},
}
}
}
}
},
"nested": {
"type": "object",
"properties": {
"flowarray": {
"type": "array",
"items": {
"type": "object",
"required": [
"key1",
"key2"
],
"properties": {
"key1": {
"type": "string"
},
"key2": {
"type": "array",
"items": {
"type": "integer"
}
},
}
}
}
}
}
}

View File

@ -0,0 +1,7 @@
{
"schema-2-3": {
"type": "array",
"maxItems": 3,
"minItems": 2
}
}

View File

@ -0,0 +1,80 @@
{
"noproperties":
{
"type": "object"
},
"emptyproperties":
{
"type": "object",
"properties": {}
},
"typetests":
{
"type": "object",
"properties": {
"computer": {
"type": "string"
},
"phone": {
"type": "integer"
},
"switch": {
"type": "boolean"
},
"object": {
"type": "object"
},
"list": {
"type": "array"
}
}
},
"typetests2":
{
"type": "object",
"properties": {
"computer": {
"type": "string"
},
"phone": {
"type": "integer"
},
"switch": {
"type": "boolean"
},
"object": {
"type": "object"
},
"list": {
"type": "array"
}
}
},
"string-properties":
{
"type": "object",
"properties": {
"computer1": {
"type": "string"
},
"computer2": {
"type": "string",
"maxLength": 4
},
"computer3": {
"type": "string",
"minLength": 2,
"maxLength": 2
},
"computer4": {
"type": "string",
"minLength": 3,
"maxLength": 4
}
}
}
}

View File

@ -0,0 +1,14 @@
{
"type": "object",
"properties": {
"person": {
"type": "object",
"properties": {
"name": {"type": "string", "minLength": 4},
"husbands": {"type": "integer"}
},
"required": ["name"]
}
},
"required": ["person"]
}

View File

@ -0,0 +1,12 @@
{
"test-emptyschema": {},
"test-norequired": {"type": "object"},
"test-required-empty": {"type": "object", "required": []},
"test-require-abc": {"type": "object", "required": ["a","b","c"]},
"test-require-bc": {"type": "object", "required": ["b","c"]},
"test-require-ac": {"type": "object", "required": ["a","c"]},
"test-require-ab": {"type": "object", "required": ["a","b"]},
"test-require-a": {"type": "object", "required": ["a"]},
"test-require-b": {"type": "object", "required": ["b"]},
"test-require-c": {"type": "object", "required": ["c"]}
}

View File

@ -0,0 +1,12 @@
{
"test-object" : {"type": "object"},
"test-array" : {"type": "array"},
"test-string" : {"type": "string"},
"test-integer" : {"type": "integer"},
"test-double" : {"type": "double"},
"test-boolean" : {"type": "boolean"},
"test-nonsense" : {"type": "nonsense"},
"test-nonstring" : {"type": 1 },
"test-nonstring2" : {"type": {"type": "yes" } }
}

View File

@ -0,0 +1,14 @@
{
"unique": {
"type": "array",
"uniqueItems": true
},
"notunique": {
"type": "array",
"uniqueItems": false
},
"schemaerror": {
"type": "array",
"uniqueItems": 1
}
}

View File

@ -0,0 +1,127 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"required": [
"ID",
"Version",
"Services"
],
"properties": {
"ID": {
"type": "string",
"enum": [
"lcss_vectors"
]
},
"Version": {
"type": "string",
"minLength": 2
},
"Services": {
"type": "array",
"minItems": 1,
"items": {
"type": "object",
"required": [
"Service",
"NetifyName",
"ValidPorts",
"vectors"
],
"properties": {
"Service": {
"type": "string",
"minLength": 4
},
"NetifyName": {
"type": "string",
"minLength": 4
},
"max_diff": {
"type": "integer"
},
"max_length": {
"type": "integer"
},
"ValidPorts": {
"type": "array",
"minItems": 1,
"items": {
"type": "array",
"minItems": 2,
"maxItems": 2,
"items": {
"type": "integer",
"minimum": 1,
"maximum": 65535
}
}
},
"vectors": {
"type": "array",
"minItems": 1,
"items": {
"type": "object",
"required": [
"ID",
"CT",
"TT",
"ignore_indices",
"proto",
"confidence",
"vector"
],
"properties": {
"ID": {
"type": "string",
"enum": [
"v0",
"v1",
"v2",
"v3"
]
},
"CT": {
"type": "integer",
"minimum": 0
},
"TT": {
"type": "integer",
"minimum": 0
},
"ignore_indices": {
"type": "array",
"maxItems": 10,
"items": {
"type": "integer",
"minimum": 0,
"maximum": 9
}
},
"proto": {
"type": "string",
"enum": [
"tcp",
"udp"
]
},
"confidence": {
"type": "integer"
},
"vector": {
"type": "array",
"maxItems": 10,
"items": {
"type": "integer",
"minimum": -1500,
"maximum": 1500
}
}
}
}
}
}
}
}
}
}

View File

@ -20,7 +20,7 @@ typedef struct {
#define CMD_CPU_CORE ("cat /proc/cpuinfo| grep \"cpu cores\" | uniq | awk \'{print $4}\'")
#define CMP_CPU_LOGIC_CORE ("cat /proc/cpuinfo| grep \"cpu cores\" | wc -l")
#define SUM_CPU_TIME(x) ((x).user + (x).nice + (x).sys + (x).idle + (x).irq)
#define SUM_CPU_TIME(x) ((x).user + (x).nice + (x).sys + (x).idle + (x).irq)
static int g_isInit = FALSE;
static CPU_INFO g_cpuInfo;
@ -103,7 +103,7 @@ static int get_cpu_time_info(unsigned long *pTotal, unsigned long *pIdle) {
*pTotal = *pIdle = 0;
for (i = 0; i < nCpu; i++) {
*pIdle += pCpu[i].cpu_times.idle;
*pIdle += pCpu[i].cpu_times.idle;
*pTotal += SUM_CPU_TIME(pCpu[i].cpu_times);
}
@ -135,25 +135,7 @@ static void cpuUsedRefresh() {
}
}
_Noreturn void cpuCalcCb(void *UNUSED(pArg)) {
do {
unsigned int period = cfg_get_cpu_refresh_period();
if (cfg_get_watch_cpu()) {
cpuUsedRefresh();
}
if (period < REFRESH_MAX_PERIOD && period >= 1) {
uv_sleep(1000 * period);
} else {
uv_sleep(1000);
}
} while (TRUE);
}
int cpu_watch_init() {
static uv_thread_t uvThread;
memset(&g_cpuInfo, 0, sizeof(CPU_INFO));
g_cpuInfo.nCpus = get_cpu_number();
@ -163,9 +145,6 @@ int cpu_watch_init() {
get_cpu_desc(&g_cpuInfo.cpuCoreDesc);
g_isInit = TRUE;
uv_thread_create(&uvThread, cpuCalcCb, NULL);
return ERR_SUCCESS;
}
@ -184,6 +163,8 @@ int get_cpu_info(PCPU_INFO pInfo) {
get_cpu_desc(&g_cpuInfo.cpuCoreDesc);
g_isInit = TRUE;
} else if (cfg_get_watch_cpu()) {
cpuUsedRefresh();
}
memcpy(pInfo, &g_cpuInfo, sizeof(CPU_INFO));

View File

@ -12,7 +12,7 @@
#include "uthash/uthash.h"
#include "config.h"
#define MAX_SIZE_LEN (16)
#define MAX_SIZE_LEN (16)
//#define CMD_DISK_FILESYSTEM ("df -h | awk \'{if (NR > 1){print $0}}\'")
#define CMD_DISK_FILESYSTEM ("df -h | awk \'{if (NR > 1){print $1\"|\"$2\"|\"$3\"|\"$4\"|\"$5\"|\"$6}}\'")
@ -105,6 +105,10 @@ int get_disk_info(PDISK_INFO pInfo) {
return -ERR_INPUT_PARAMS;
}
if (cfg_get_watch_disk()) {
disk_info_refresh();
}
uv_rwlock_rdlock(&g_uvLock);
pInfo->nItems = HASH_COUNT(g_diskPartInfo);
pInfo->timestamp = time(NULL);
@ -122,32 +126,12 @@ int get_disk_info(PDISK_INFO pInfo) {
return ERR_SUCCESS;
}
_Noreturn void diskRefreshCb(void *UNUSED(pArg)) {
do {
unsigned int period = cfg_get_disk_refresh_period();
if (cfg_get_watch_disk()) {
disk_info_refresh();
}
if (period < REFRESH_MAX_PERIOD && period >= 1) {
uv_sleep(1000 * period);
} else {
uv_sleep(1000);
}
} while (TRUE);
}
int disk_watch_info() {
static uv_thread_t uvThread;
uv_rwlock_init(&g_uvLock);
if (disk_info_refresh() != ERR_SUCCESS) {
return -ERR_SYS_DISK_GET_INFO;
}
uv_thread_create(&uvThread, diskRefreshCb, NULL);
return ERR_SUCCESS;
}

View File

@ -9,51 +9,48 @@
#include "user_errno.h"
#include "config.h"
#include "misc.h"
#include "task_manager.h"
static HARDWARE_INFO g_hardwareInfo;
_Noreturn void hardwareRefreshCb(void *UNUSED(pArg)) {
do {
unsigned int period = cfg_get_hardware_refresh_period();
void hardwareRefreshCb(uv_timer_t *UNUSED(pArg)) {
if (cfg_get_watch_sensor()) {
get_sensor_info(&g_hardwareInfo.sensorInfo);
}
if (cfg_get_watch_disk()) {
get_disk_info(&g_hardwareInfo.diskInfo);
}
if (cfg_get_watch_cpu()) {
get_cpu_info(&g_hardwareInfo.cpuInfo);
}
if (cfg_get_watch_memory()) {
get_memory_info(&g_hardwareInfo.memInfo);
}
if (cfg_get_watch_sensor()) {
get_sensor_info(&g_hardwareInfo.sensorInfo);
}
if (cfg_get_watch_disk()) {
get_disk_info(&g_hardwareInfo.diskInfo);
}
if (cfg_get_watch_cpu()) {
get_cpu_info(&g_hardwareInfo.cpuInfo);
}
if (cfg_get_watch_memory()) {
get_memory_info(&g_hardwareInfo.memInfo);
}
if (period < REFRESH_MAX_PERIOD && period >= 1) {
uv_sleep(1000 * period);
} else {
uv_sleep(1000);
}
uv_sleep(1000);
} while (TRUE);
//printf("%s\n", get_hardware_json());
}
int init_hardware() {
static uv_thread_t uvThread;
static uv_timer_t uvTm;
unsigned int period = cfg_get_hardware_refresh_period();
if (period >= REFRESH_MAX_PERIOD) {
period = 10000;
} else {
period *= 1000;
}
uv_timer_init(get_task_manager(), &uvTm);
memset(&g_hardwareInfo, 0, sizeof(HARDWARE_INFO));
uv_thread_create(&uvThread, hardwareRefreshCb, NULL);
cpu_watch_init();
memory_watch_init();
disk_watch_info();
sensor_watch_init();
uv_timer_start(&uvTm, hardwareRefreshCb, period, period);
return ERR_SUCCESS;
}

View File

@ -12,10 +12,11 @@
#include "misc.h"
#include "config.h"
#define MAX_SENSOR_STR (32)
#define MAX_SENSOR_STR (32)
//#define CMD_SENSOR_INFO ("ipmitool sensor | awk '{gsub(/\|/, \"\"); print $0}'")
#define CMD_SENSOR_INFO ("ipmitool sensor")
#define CMD_SENSOR_INFO ("ipmitool sensor")
#define CMD_IPMITOOL_ENABLE ("whereis ipmitool | awk '{print $2}'")
typedef struct {
char name[MAX_SENSOR_STR]; ///< 传感器名称
@ -42,9 +43,16 @@ static int sensor_info_refresh() {
int errCode = ERR_SUCCESS;
FILE *fp;
char buf[1024];
char *pRet = NULL;
if (shell_with_output(CMD_IPMITOOL_ENABLE, &pRet) != ERR_SUCCESS || pRet == NULL || strlen(pRet) == 0) {
if (pRet) {
free(pRet);
}
return -ERR_ITEM_UNEXISTS;
}
fp = popen(CMD_SENSOR_INFO, "r");
if (fp == NULL) {
return -ERR_OPEN_FILE;
}
@ -132,6 +140,10 @@ int get_sensor_info(PSENSOR_INFO pInfo) {
return -ERR_INPUT_PARAMS;
}
if (cfg_get_watch_sensor()) {
sensor_info_refresh();
}
uv_rwlock_rdlock(&g_uvLock);
pInfo->nItems = HASH_COUNT(g_pSensorInfo);
pInfo->timestamp = time(NULL);
@ -149,27 +161,9 @@ int get_sensor_info(PSENSOR_INFO pInfo) {
return ERR_SUCCESS;
}
_Noreturn void sensorRefreshCb(void *UNUSED(pArg)) {
do {
unsigned int period = cfg_get_sensor_refresh_period();
if (cfg_get_watch_sensor()) {
sensor_info_refresh();
}
if (period < REFRESH_MAX_PERIOD && period >= 1) {
uv_sleep(1000 * period);
} else {
uv_sleep(1000);
}
} while (TRUE);
}
int sensor_watch_init() {
static uv_thread_t uvThread;
int i, devOk = FALSE;
int n = ARRAY_SIZE(g_ipmiDev);
int i, devOk = FALSE;
int n = ARRAY_SIZE(g_ipmiDev);
uv_rwlock_init(&g_uvLock);
@ -188,7 +182,5 @@ int sensor_watch_init() {
return -ERR_SYS_SENSOR_GET_INFO;
}
uv_thread_create(&uvThread, sensorRefreshCb, NULL);
return ERR_SUCCESS;
}

View File

@ -14,11 +14,11 @@
#define CMD_MEMORY_INFO ("cat /proc/meminfo | awk \'{print $1\"|\"$2\"|\"$3}\'")
#define M_SIZE (1024 * 1024)
#define M_SIZE (1024 * 1024)
#define KEY_NAME (32)
#define KEY_VALUE (32)
#define VALUE_UNIT (8)
#define KEY_NAME (32)
#define KEY_VALUE (32)
#define VALUE_UNIT (8)
typedef struct {
char itemName[KEY_NAME];
@ -95,33 +95,13 @@ static int memory_info_refresh() {
return errCode;
}
_Noreturn void memRefreshCb(void *UNUSED(pArg)) {
do {
unsigned int period = cfg_get_mem_refresh_period();
if (cfg_get_watch_memory()) {
memory_info_refresh();
}
if (period < REFRESH_MAX_PERIOD && period >= 1) {
uv_sleep(1000 * period);
} else {
uv_sleep(1000);
}
} while (TRUE);
}
int memory_watch_init() {
static uv_thread_t uvThread;
uv_rwlock_init(&g_uvLock);
if (memory_info_refresh() != ERR_SUCCESS) {
return -ERR_SYS_DISK_GET_INFO;
}
uv_thread_create(&uvThread, memRefreshCb, NULL);
return ERR_SUCCESS;
}
@ -142,6 +122,10 @@ int get_memory_info(PMEMORY_INFO pInfo) {
return -ERR_INPUT_PARAMS;
}
if (cfg_get_watch_memory()) {
memory_info_refresh();
}
uv_rwlock_rdlock(&g_uvLock);
for (i = 0; i < n; i++) {

View File

@ -41,10 +41,6 @@ typedef enum {
CFG_WATCH_MEMORY,
CFG_WATCH_DISK,
CFG_WATCH_SENSOR,
CFG_CPU_REFRESH,
CFG_MEM_REFRESH,
CFG_DISK_REFRESH,
CFG_SENSOR_REFRESH,
#ifdef USED_REDIS
CFG_DB_REDIS_SERVER,
CFG_DB_REDIS_PORT,
@ -61,8 +57,10 @@ typedef enum {
CFG_DB_SQLITE_DB_NAME,
CFG_DB_SQLITE_PASSWD,
#endif
#ifdef ZEROMQ_ON
CFG_MQ_SVR_PORT,
CFG_MQ_DATA_PATH,
#endif
CFG_VXLAN_NIC_NAME,
CFG_VXLAN_SUPPORT,
CFG_VXLAN_PEER_IP,
@ -92,10 +90,6 @@ int cfg_get_watch_cpu();
int cfg_get_watch_memory();
int cfg_get_watch_disk();
int cfg_get_watch_sensor();
unsigned int cfg_get_cpu_refresh_period();
unsigned int cfg_get_mem_refresh_period();
unsigned int cfg_get_disk_refresh_period();
unsigned int cfg_get_sensor_refresh_period();
#ifdef USED_REDIS
const char *cfg_get_redis_server();
int cfg_get_redis_port();
@ -112,8 +106,10 @@ const char *cfg_get_mysql_database();
const char *cfg_get_sqlite_db_name();
const char *cfg_get_sqlite_passwd();
#endif
#ifdef ZEROMQ_ON
int cfg_get_zero_mq_port();
const char *cfg_get_zero_mq_data_path();
#endif
const char *cfg_get_string_value(CONFIG_ITEM_ID id);
c_vector cfg_get_vector(CONFIG_ITEM_ID id);

View File

@ -0,0 +1,26 @@
#ifndef __INTERNAL_H
#define __INTERNAL_H
#include <json-c/json.h>
int _jdac_load(const char *jsonfile, const char *jsonschema);
int __jdac_inspect_type(json_object *jobj, const char *type);
int _jdac_check_type (json_object *jobj, json_object *jschema);
int _jdac_check_required (json_object *jobj, json_object *jschema);
int _jdac_check_properties (json_object *jobj, json_object *jschema);
int _jdac_check_prefixItems_and_items (json_object *jobj, json_object *jschema);
int _jdac_value_is_equal (json_object *jobj1, json_object *jobj2);
int _jdac_check_const (json_object *jobj, json_object *jschema);
int _jdac_check_enums (json_object *jobj, json_object *jschema);
int _jdac_check_uniqueItems (json_object *jobj, json_object *jschema);
int _jdac_check_maxmin_items (json_object *jobj, json_object *jschema);
int _jdac_validate_array (json_object *jobj, json_object *jschema);
int _jdac_validate_object (json_object *jobj, json_object *jschema);
int _jdac_validate_string (json_object *jobj, json_object *jschema);
int _jdac_validate_integer (json_object *jobj, json_object *jschema);
int _jdac_validate_double (json_object *jobj, json_object *jschema);
int _jdac_validate_number (json_object *jobj, json_object *jschema, double value);
int _jdac_validate_boolean (json_object *jobj, json_object *jschema);
int _jdac_validate_instance (json_object *jobj, json_object *jschema);
#endif // __INTERNAL_H

View File

@ -0,0 +1,40 @@
#ifndef __JSONCDACCORD_H
#define __JSONCDACCORD_H
#include <json-c/json.h>
enum jdac_errors {
JDAC_ERR_VALID = 0,
JDAC_ERR_GENERAL_ERROR,
JDAC_ERR_JSON_NOT_FOUND,
JDAC_ERR_SCHEMA_NOT_FOUND,
JDAC_ERR_WRONG_ARGS,
JDAC_ERR_SCHEMA_ERROR,
JDAC_ERR_INVALID,
JDAC_ERR_INVALID_TYPE,
JDAC_ERR_INVALID_REQUIRED,
JDAC_ERR_INVALID_SUBSCHEMALOGIC,
JDAC_ERR_INVALID_CONST,
JDAC_ERR_INVALID_ENUMS,
JDAC_ERR_INVALID_STRLEN,
JDAC_ERR_INVALID_UNIQUEITEMS,
JDAC_ERR_INVALID_PREFIXITEMS,
JDAC_ERR_INVALID_ITEMS,
JDAC_ERR_INVALID_CONTAINS,
JDAC_ERR_INVALID_ARRAYLEN,
JDAC_ERR_INVALID_NUMBER,
JDAC_ERR_INVALID_PATTERNMATCH,
JDAC_ERR_INVALID_REF,
JDAC_REGEX_MISMATCH,
JDAC_REGEX_MATCH,
JDAC_REGEX_COMPILE_FAILED,
JDAC_ERR_MAX
};
int jdac_validate_file(const char *jsonfile, const char *jsonschemafile);
int jdac_validate(json_object *jobj, json_object *jschema);
int jdac_ref_set_localpath(const char *_localpath);
const char *jdac_errorstr(unsigned int jdac_errors);
#endif //__JSONCDACCORD_H

View File

@ -0,0 +1,36 @@
#ifndef __OPTIONAL_H
#define __OPTIONAL_H
#include <json-c/json.h>
typedef struct storage_node {
char JSONPtrURI[128];
char id[128];
char anchor[32];
char dynamicAnchor[32];
json_object *json_instance_ptr;
json_object *json_schema_ptr;
int is_root;
struct storage_node *next;
} storage_node;
int _jdac_match_string_with_regex(const char* regex_pattern, const char* value);
int _jdac_check_pattern(json_object *jobj, json_object *jschema);
int _jdac_check_patternproperties(json_object *jobj, json_object *jschema);
int _jdac_check_additionalproperties(json_object *jobj, json_object *jschema);
int _jdac_check_propertynames(json_object *jobj, json_object *jschema);
int _jdac_check_subschemalogic(json_object *jobj, json_object *jschema);
int _jdac_check_contains_and_minmaxcontains(json_object *jobj, json_object *jschema);
char* _jdac_download_schema(const char *url);
const char* _jdac_download_resolve(const char *uri);
int _jdac_store_traverse_json(storage_node **head, json_object *jschema, char *pathbuffer);
void _jdac_store_free(storage_node **head);
void _jdac_store_print(storage_node *head);
json_object* _jdac_store_resolve(storage_node *list, const char *uri);
storage_node* _jdac_store_get_root_node(storage_node *head);
int _jdac_check_ref(json_object *jobj, json_object *jschema, storage_node *storage_list);
#endif // __OPTIONAL_H

View File

@ -61,6 +61,8 @@ int get_nic_info(const char *pName,
unsigned char *pMac);
int str_to_ipaddr(const char *pIp, unsigned int *ipAddr);
unsigned long long get_current_time_ms();
int process_lock_pidfile(char *pFilePath);
void process_unlock_pidfile();
#ifdef __cplusplus
}
#endif

View File

@ -18,8 +18,9 @@ typedef enum {
CRYPTO_AES256 = 4,
} PROTO_CRYPTO_TYPE;
const char *proto_msg_validation(const char *pJsonStr, const char *msgJson, const char *errMsg);
const char *proto_create_new(cJSON *pMsgCtx, int httpCode);
const char *proto_decode_context(const char *pString, unsigned int *pVer, unsigned long long *pTm);
const char *proto_decode_context(const char *pString, unsigned int *pVer, unsigned long long *pTm, int *pErrCode);
#ifdef __cplusplus
}
#endif

View File

@ -8,8 +8,6 @@
extern "C" {
#endif
#define USED_USER_ERRNO
#define DEF_ERR_CODE(ERR_CODE) \
ERR_CODE(ERR_SUCCESS, 0, "成功") \
ERR_CODE(ERR_INPUT_PARAMS, 1, "输入参数错误") \
@ -21,48 +19,49 @@ extern "C" {
ERR_CODE(ERR_OPEN_FILE, 7, "打开文件失败") \
ERR_CODE(ERR_READ_FILE, 8, "读取文件失败") \
ERR_CODE(ERR_FILE_NOT_EXISTS, 9, "文件不存在") \
ERR_CODE(ERR_GET_FILE_SIZE, 10, "获取文件大小失败") \
ERR_CODE(ERR_COPY_FILE, 11, "复制文件失败") \
ERR_CODE(ERR_MALLOC_MEMORY, 12, "分配内存失败") \
ERR_CODE(ERR_EVP_KEY_SIZE, 13, "秘钥大小不正确") \
ERR_CODE(ERR_UNSUP_EVP_TYPE, 14, "不支持的加解密算法") \
ERR_CODE(ERR_EVP_INIT_KEY, 15, "初始化秘钥失败") \
ERR_CODE(ERR_EVP_UPDATE, 16, "加解密数据失败") \
ERR_CODE(ERR_EVP_FINALE, 17, "错误的加解密结果") \
ERR_CODE(ERR_EVP_CREATE_CTX, 18, "初始化加解密失败") \
ERR_CODE(ERR_AES128_KEYGEN, 19, "AES128秘钥失败") \
ERR_CODE(ERR_EVP_ENCRYPTION, 20, "加密失败") \
ERR_CODE(ERR_EVP_DECRYPTION, 21, "解密失败") \
ERR_CODE(ERR_CONFIG_INIT, 22, "配置文件初始化失败") \
ERR_CODE(ERR_UNCOMPATIBILITY_TYPE, 23, "未兼容的类型") \
ERR_CODE(ERR_STRING_TO_NUMBER, 24, "字符串转数字失败") \
ERR_CODE(ERR_UNKNOWN_CFG_ID, 25, "未识别的配置项") \
ERR_CODE(ERR_ZLOG_INIT, 26, "日志系统初始化失败") \
ERR_CODE(ERR_SYS_GET_CPU_INFO, 27, "获取CPU信息失败") \
ERR_CODE(ERR_SYS_NOT_FOUND_CPU, 28, "找不到CPU信息") \
ERR_CODE(ERR_SYS_DISK_GET_INFO, 29, "获取磁盘空间占用信息失败") \
ERR_CODE(ERR_SYS_IPMI_UNSUP, 30, "服务器IPMI接口不支持") \
ERR_CODE(ERR_SYS_SENSOR_GET_INFO, 31, "获取传感器信息失败") \
ERR_CODE(ERR_DB_CONNECT, 32, "数据库连接失败") \
ERR_CODE(ERR_MQ_CREATE_MQ, 33, "创建消息队列失败") \
ERR_CODE(ERR_MQ_CREATE_REP, 34, "创建REP消息队列失败") \
ERR_CODE(ERR_MQ_BIND_SOCKET, 35, "消息队列BIND Socket失败") \
ERR_CODE(ERR_MQ_CONN_SERVER, 36, "消息队列连接服务器失败") \
ERR_CODE(ERR_MQ_SEND_MSG, 37, "消息队列发送消息失败") \
ERR_CODE(ERR_JSON_CREAT_OBJ, 38, "创建JSON对象失败") \
ERR_CODE(ERR_JSON_PRASE_OBJ, 39, "解析JSON对象失败") \
ERR_CODE(ERR_CREATE_NETIF, 40, "创建网络接口失败") \
ERR_CODE(ERR_CREATE_PPPOE_NETIF, 41, "创建PPPoE网络接口失败") \
ERR_CODE(ERR_CREATE_PPP_SESSION, 42, "创建PPP连接失败") \
ERR_CODE(ERR_MISC_GET_IPADDR, 43, "获取网卡IP地址失败") \
ERR_CODE(ERR_MISC_GET_NETMASK, 44, "获取网卡子网掩码失败") \
ERR_CODE(ERR_MISC_GET_GATEWAY, 45, "获取网卡网关地址失败") \
ERR_CODE(ERR_MISC_GET_MACADDR, 46, "获取网卡MAC地址失败") \
ERR_CODE(ERR_MENU_EXIT, 47, "菜单执行完后自动退出") \
ERR_CODE(ERR_HTTP_UNSUP_METHOD, 48, "不支持的 HTTP 请求方法") \
ERR_CODE(ERR_HTTP_UNSUP_PAGE, 49, "找不到 HTTP 服务") \
ERR_CODE(ERR_PROTO_DECODE, 50, "HTTP 协议解析失败")
ERR_CODE(ERR_FILE_LOCKED, 10, "文件被锁定") \
ERR_CODE(ERR_GET_FILE_SIZE, 11, "获取文件大小失败") \
ERR_CODE(ERR_COPY_FILE, 12, "复制文件失败") \
ERR_CODE(ERR_MALLOC_MEMORY, 13, "分配内存失败") \
ERR_CODE(ERR_EVP_KEY_SIZE, 14, "秘钥大小不正确") \
ERR_CODE(ERR_UNSUP_EVP_TYPE, 15, "不支持的加解密算法") \
ERR_CODE(ERR_EVP_INIT_KEY, 16, "初始化秘钥失败") \
ERR_CODE(ERR_EVP_UPDATE, 17, "加解密数据失败") \
ERR_CODE(ERR_EVP_FINALE, 18, "错误的加解密结果") \
ERR_CODE(ERR_EVP_CREATE_CTX, 19, "初始化加解密失败") \
ERR_CODE(ERR_AES_KEYGEN, 20, "AES秘钥失败") \
ERR_CODE(ERR_EVP_ENCRYPTION, 21, "加密失败") \
ERR_CODE(ERR_EVP_DECRYPTION, 22, "解密失败") \
ERR_CODE(ERR_CONFIG_INIT, 23, "配置文件初始化失败") \
ERR_CODE(ERR_UNCOMPATIBILITY_TYPE, 24, "未兼容的类型") \
ERR_CODE(ERR_STRING_TO_NUMBER, 25, "字符串转数字失败") \
ERR_CODE(ERR_UNKNOWN_CFG_ID, 26, "未识别的配置项") \
ERR_CODE(ERR_ZLOG_INIT, 27, "日志系统初始化失败") \
ERR_CODE(ERR_SYS_GET_CPU_INFO, 28, "获取CPU信息失败") \
ERR_CODE(ERR_SYS_NOT_FOUND_CPU, 29, "找不到CPU信息") \
ERR_CODE(ERR_SYS_DISK_GET_INFO, 30, "获取磁盘空间占用信息失败") \
ERR_CODE(ERR_SYS_IPMI_UNSUP, 31, "服务器IPMI接口不支持") \
ERR_CODE(ERR_SYS_SENSOR_GET_INFO, 32, "获取传感器信息失败") \
ERR_CODE(ERR_DB_CONNECT, 33, "数据库连接失败") \
ERR_CODE(ERR_MQ_CREATE_MQ, 34, "创建消息队列失败") \
ERR_CODE(ERR_MQ_CREATE_REP, 35, "创建REP消息队列失败") \
ERR_CODE(ERR_MQ_BIND_SOCKET, 36, "消息队列BIND Socket失败") \
ERR_CODE(ERR_MQ_CONN_SERVER, 37, "消息队列连接服务器失败") \
ERR_CODE(ERR_MQ_SEND_MSG, 38, "消息队列发送消息失败") \
ERR_CODE(ERR_JSON_CREAT_OBJ, 39, "创建JSON对象失败") \
ERR_CODE(ERR_JSON_PARSE_OBJ, 40, "解析JSON对象失败") \
ERR_CODE(ERR_JSON_VALID_SCH, 41, "JSON数据验证失败") \
ERR_CODE(ERR_CREATE_NETIF, 42, "创建网络接口失败") \
ERR_CODE(ERR_CREATE_PPPOE_NETIF, 43, "创建PPPoE网络接口失败") \
ERR_CODE(ERR_CREATE_PPP_SESSION, 44, "创建PPP连接失败") \
ERR_CODE(ERR_MISC_GET_IPADDR, 45, "获取网卡IP地址失败") \
ERR_CODE(ERR_MISC_GET_NETMASK, 46, "获取网卡子网掩码失败") \
ERR_CODE(ERR_MISC_GET_GATEWAY, 47, "获取网卡网关地址失败") \
ERR_CODE(ERR_MISC_GET_MACADDR, 48, "获取网卡MAC地址失败") \
ERR_CODE(ERR_MENU_EXIT, 49, "菜单执行完后自动退出") \
ERR_CODE(ERR_HTTP_UNSUP_METHOD, 50, "不支持的 HTTP 请求方法") \
ERR_CODE(ERR_HTTP_UNSUP_PAGE, 51, "找不到 HTTP 服务") \
ERR_CODE(ERR_PROTO_DECODE, 52, "HTTP 协议解析失败")
#define GENERATE_ENUM(ENUM, no, x) ENUM,
typedef enum {

View File

@ -34,7 +34,8 @@ typedef enum {
ZLOG_MOD(ZLOG_MOD_CRYPTO, ZLOG_LEVEL_DEBUG, "CRYPTO") \
ZLOG_MOD(ZLOG_MOD_MQ, ZLOG_LEVEL_DEBUG, "MQ") \
ZLOG_MOD(ZLOG_MOD_PROTO, ZLOG_LEVEL_DEBUG, "PROTO") \
ZLOG_MOD(ZLOG_MOD_HTTPD, ZLOG_LEVEL_INFO, "HTTPD") \
ZLOG_MOD(ZLOG_MOD_HTTPD, ZLOG_LEVEL_INFO, "HTTPD") \
ZLOG_MOD(ZLOG_MOD_JSCHEM, ZLOG_LEVEL_INFO, "JSCHEM") \
ZLOG_MOD(ZLOG_MOD_USER, ZLOG_LEVEL_DEBUG, "USER") \
ZLOG_MOD(ZLOG_MOD_PPPOE, ZLOG_LEVEL_DEBUG, "PPPOE") \
ZLOG_MOD(ZLOG_MOD_VXLAN, ZLOG_LEVEL_DEBUG, "VXLAN") \
@ -64,6 +65,9 @@ typedef enum {
#define LOG_MOD(level, mod, format, ...) \
do { \
if (zlog_verify_level(level, mod)) { \
if (zlog_vni_tag_get()) { \
zlog_put_mdc("vni", zlog_vni_tag_get()); \
} \
zlog_##level(zlog_get_mod_cat((mod)), format, ##__VA_ARGS__); \
} \
} while (0)
@ -71,12 +75,16 @@ typedef enum {
#define LOG_MOD_HEX(level, mod, format, ...) \
do { \
if (zlog_verify_level(level, mod)) { \
if (zlog_vni_tag_get()) { \
zlog_put_mdc("vni", zlog_vni_tag_get()); \
} \
hzlog_##level(zlog_get_mod_cat((mod)), format, ##__VA_ARGS__); \
} \
} while (0)
zlog_category_t *zlog_get_mod_cat(ZLOG_MOD_NAME logMod);
int zlog_verify_level(int level, ZLOG_MOD_NAME logMod);
const char *zlog_vni_tag_get();
#ifdef __cplusplus
}
#endif

View File

@ -14,11 +14,13 @@
#include "inet_misc.h"
#include "crypto.h"
#include "hardware.h"
#include "msg_queue.h"
#include "http_svr.h"
#include "lib_config.h"
#include "prj_config.h"
#include "zlog_module.h"
#ifdef ZEROMQ_ON
#include "msg_queue.h"
#endif
#define DEFAULT_CONFIG_FILE ("vcpe.cfg")
#define DEFAULT_CONFIG_DIR ("config")
@ -40,6 +42,7 @@ int user_init(const char *pAppCfgFile, const char *pCfgDirectory, const char *pK
UT_string *pPath;
char bufCfgFile[MAX_PATH];
char bufCfgDir[MAX_PATH];
char pidfile[MAX_PATH];
g_pid = uv_os_getpid();
@ -112,6 +115,17 @@ int user_init(const char *pAppCfgFile, const char *pCfgDirectory, const char *pK
LOG_MOD(info, ZLOG_MOD_INIT, "Application build configure: [%s]\n", VCPE_BUILD_CONFIG);
#ifdef USERVNI_ON
sprintf(pidfile, "/tmp/%d_vcpe.pid", cfg_get_user_vni_id());
#else
sprintf(pidfile, "/tmp/vcpe.pid");
#endif
if (process_lock_pidfile(pidfile) == -ERR_FILE_LOCKED) {
LOG_MOD(error, ZLOG_MOD_INIT, "!!!Another same process is running!!!, system exit......\n");
exit(-ERR_FILE_LOCKED);
}
if (cfg_get_banner_enable()) {
banner_show();
}
@ -122,7 +136,7 @@ int user_init(const char *pAppCfgFile, const char *pCfgDirectory, const char *pK
if (cfg_get_hardware_watch_enable()) {
init_hardware();
}
#ifdef ZEROMQ_ON
if ((ret = mq_init()) != ERR_SUCCESS) {
LOG_MOD(error, ZLOG_MOD_INIT, "Message queue init error: %d\n", ret);
}
@ -130,6 +144,7 @@ int user_init(const char *pAppCfgFile, const char *pCfgDirectory, const char *pK
if ((ret = mq_data_init()) != ERR_SUCCESS) {
LOG_MOD(error, ZLOG_MOD_INIT, "Message queue init error: %d\n", ret);
}
#endif
#ifdef HTTPSERVER_ON
http_svr_init();
#endif
@ -144,9 +159,12 @@ void user_uninit() {
#ifdef HTTPSERVER_ON
http_svr_uinit();
#endif
#ifdef ZEROMQ_ON
mq_uninit();
#endif
zlog_fini();
uninit_config_system();
uv_loop_close(get_task_manager());
process_unlock_pidfile();
}
}

View File

@ -0,0 +1,42 @@
INCLUDE_DIRECTORIES(../../include/json_schema)
SET(jsoncdac_SOURCES validate.c)
LIST(APPEND OPTIONAL
pattern patternproperties additionalproperties propertynames subschemalogic
contains store ref)
FOREACH (src ${OPTIONAL})
STRING(TOUPPER ${src} srcupper)
OPTION(BUILD_${srcupper} "${src} option" ON)
IF (BUILD_${srcupper})
LIST(APPEND SUPPORTED_OPTIONAL ${src})
SET(jsoncdac_SOURCES ${jsoncdac_SOURCES} ${src}.c)
ADD_DEFINITIONS(-DJDAC_${srcupper})
ENDIF ()
ENDFOREACH ()
IF (BUILD_PATTERNPROPERTIES OR BUILD_PATTERN)
SET(jsoncdac_SOURCES ${jsoncdac_SOURCES} regex_match.c)
#set(EXTRA_LIBS regex)
ENDIF ()
# always supported
LIST(APPEND SUPPORTED_BASE type enum required properties anyOf minLength maxLength minimum maximum const)
LIST(APPEND SUPPORTED_BASE minItems maxItems uniqueItems items)
STRING(REPLACE ";" "," SUPPORTED_BASE_STR "${SUPPORTED_BASE}")
STRING(REPLACE ";" "," SUPPORTED_OPTIONAL_STR "${SUPPORTED_OPTIONAL}")
ADD_LIBRARY(jsoncdac STATIC ${jsoncdac_SOURCES})
TARGET_COMPILE_DEFINITIONS(jsoncdac PRIVATE "SUPPORTED_KEYWORDS_BASE=\"${SUPPORTED_BASE_STR}\"" "SUPPORTED_KEYWORDS_OPTIONAL=\"${SUPPORTED_OPTIONAL_STR}\"")
TARGET_LINK_LIBRARIES(jsoncdac ${EXTRA_LIBS})
SET_TARGET_PROPERTIES(
jsoncdac
PROPERTIES
OUTPUT_NAME jsoncdac
PUBLIC_HEADER "${HEADER_FILES}"
VERSION 0.0.2
SOVERSION 1
)

View File

@ -0,0 +1,58 @@
#include "jsoncdaccord.h"
#include "internal.h"
#include "optional.h"
int _jdac_check_additionalproperties(json_object *jobj, json_object *jschema) {
json_object *jaddprops = json_object_object_get(jschema, "additionalProperties");
if (!jaddprops) {
return JDAC_ERR_VALID;
}
if (!json_object_is_type(jaddprops, json_type_object) && !json_object_is_type(jaddprops, json_type_boolean)) {
return JDAC_ERR_SCHEMA_ERROR;
}
json_object *jprops = json_object_object_get(jschema, "properties");
#ifdef JDAC_PATTERNPROPERTIES
json_object *jpatprops = json_object_object_get(jschema, "patternProperties");
#endif
json_object_object_foreach(jobj, jobj_key, jobj_val) {
// if an instance key is found in properties, it is not an additional property
if (jprops) {
json_object *jprop = json_object_object_get(jprops, jobj_key);
if (jprop) {
continue; // ignore properties
}
}
// if an instance key has a match in patternProperties, it is not an additional property
#ifdef JDAC_PATTERNPROPERTIES
int foundpatternproperty = 0;
if (jpatprops) {
if (json_object_is_type(jpatprops, json_type_object)) {
json_object_object_foreach(jpatprops, jpat_key, jpat_val) {
int ret = _jdac_match_string_with_regex(jpat_key, jobj_key);
if (ret == JDAC_REGEX_MATCH) {
foundpatternproperty = 1;
break;
}
}
}
if (foundpatternproperty) {
continue;
}
}
#endif
// by this point we consider the instance to be an additional property
int err = _jdac_validate_instance(jobj_val, jaddprops);
if (err) {
return err;
}
}
return JDAC_ERR_VALID;
}

View File

@ -0,0 +1,53 @@
#include "jsoncdaccord.h"
#include "internal.h"
#include "optional.h"
int _jdac_check_contains_and_minmaxcontains(json_object *jobj, json_object *jschema) {
int err;
json_object *jcontains = json_object_object_get(jschema, "contains");
if (!jcontains) {
return JDAC_ERR_VALID;
}
if (!json_object_is_type(jcontains, json_type_object) && !json_object_is_type(jcontains, json_type_boolean)) {
return JDAC_ERR_SCHEMA_ERROR;
}
int arraylen = json_object_array_length(jobj);
int match_count = 0;
for (int i = 0; i < arraylen; i++) {
json_object *iobj = json_object_array_get_idx(jobj, i);
err = _jdac_validate_instance(iobj, jcontains);
if (err == JDAC_ERR_VALID) {
match_count++;
} else if (err == JDAC_ERR_SCHEMA_ERROR) {
return JDAC_ERR_SCHEMA_ERROR;
}
}
json_object *jmaxcontains = json_object_object_get(jschema, "maxContains");
if (jmaxcontains) {
int max = json_object_get_int(jmaxcontains);
if (match_count > max) {
return JDAC_ERR_INVALID_CONTAINS;
}
}
json_object *jmincontains = json_object_object_get(jschema, "minContains");
if (jmincontains) {
int min = json_object_get_int(jmincontains);
if (min == 0) {
return JDAC_ERR_VALID;
} else if (match_count < min) {
return JDAC_ERR_INVALID_CONTAINS;
}
}
if (match_count == 0) {
return JDAC_ERR_INVALID_CONTAINS;
}
return JDAC_ERR_VALID;
}

View File

@ -0,0 +1,55 @@
#include <stdio.h>
#include <string.h>
#include <json-c/json.h>
#include <curl/curl.h>
#include "jsoncdaccord.h"
#include "internal.h"
#include "optional.h"
struct curlmemory {
char *response;
size_t size;
};
static size_t cb(void *data, size_t size, size_t nmemb, void *userp) {
size_t realsize = size * nmemb;
struct curlmemory *mem = (struct curlmemory *)userp;
char *ptr = realloc(mem->response, mem->size + realsize + 1);
if (ptr == NULL) {
return 0; /* out of memory! */
}
mem->response = ptr;
memcpy(&(mem->response[mem->size]), data, realsize);
mem->size += realsize;
mem->response[mem->size] = 0;
return realsize;
}
char *_jdac_download_schema(const char *url) {
struct curlmemory chunk = {0};
CURL *curl = curl_easy_init();
if (curl) {
CURLcode res;
curl_easy_setopt(curl, CURLOPT_URL, url);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, cb);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&chunk);
res = curl_easy_perform(curl);
if (res != CURLE_OK) {
fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
}
curl_easy_cleanup(curl);
}
return chunk.response;
}
const char *_jdac_download_resolve(const char *uri) {
int len = strlen(uri);
if (len > 8 && strncmp(uri, "http", 4) == 0) {
return uri;
}
return NULL;
}

View File

@ -0,0 +1,27 @@
#include "jsoncdaccord.h"
#include "internal.h"
#include "optional.h"
int _jdac_check_pattern(json_object *jobj, json_object *jschema) {
json_object *jpat = json_object_object_get(jschema, "pattern");
if (jpat) {
if (!json_object_is_type(jpat, json_type_string)) {
return JDAC_ERR_SCHEMA_ERROR;
}
const char *pattern = json_object_get_string(jpat);
const char *istr = json_object_get_string(jobj);
if (istr) {
int ret = _jdac_match_string_with_regex(pattern, istr);
if (ret == JDAC_REGEX_COMPILE_FAILED) {
return JDAC_ERR_SCHEMA_ERROR;
} else if (ret == JDAC_REGEX_MATCH) {
return JDAC_ERR_VALID;
} else if (ret == JDAC_REGEX_MISMATCH) {
return JDAC_ERR_INVALID_PATTERNMATCH;
}
}
}
return JDAC_ERR_VALID;
}

View File

@ -0,0 +1,32 @@
#include "jsoncdaccord.h"
#include "internal.h"
#include "optional.h"
int _jdac_check_patternproperties(json_object *jobj, json_object *jschema) {
//LOG_MOD(debug, ZLOG_MOD_JSCHEM, "%s\n", __func__);
// check jobj non object is already checked
json_object *jpatprops = json_object_object_get(jschema, "patternProperties");
if (jpatprops) {
if (!json_object_is_type(jpatprops, json_type_object)) {
return JDAC_ERR_SCHEMA_ERROR;
}
json_object_object_foreach(jpatprops, jprop_key, jprop_val) {
json_object_object_foreach(jobj, jobj_key, jobj_val) {
int ret = _jdac_match_string_with_regex(jprop_key, jobj_key);
if (ret == JDAC_REGEX_COMPILE_FAILED) {
return JDAC_ERR_SCHEMA_ERROR;
} else if (ret == JDAC_REGEX_MATCH) {
int err = _jdac_validate_instance(jobj_val, jprop_val);
if (err) {
return err;
}
} else if (ret == JDAC_REGEX_MISMATCH) {
//
}
}
}
}
return JDAC_ERR_VALID;
}

View File

@ -0,0 +1,26 @@
#include "jsoncdaccord.h"
#include "internal.h"
#include "optional.h"
int _jdac_check_propertynames(json_object *jobj, json_object *jschema) {
json_object *jpropnames_schema = json_object_object_get(jschema, "propertyNames");
if (!jpropnames_schema) {
return JDAC_ERR_VALID;
}
if (!json_object_is_type(jpropnames_schema, json_type_object) &&
!json_object_is_type(jpropnames_schema, json_type_boolean)) {
return JDAC_ERR_SCHEMA_ERROR;
}
json_object_object_foreach(jobj, jprop_key, jprop_val) {
json_object *jprop = json_object_new_string(jprop_key);
int err = _jdac_validate_instance(jprop, jpropnames_schema);
json_object_put(jprop);
if (err) {
return err;
}
}
return JDAC_ERR_VALID;
}

View File

@ -0,0 +1,89 @@
#include <string.h>
#include <stdio.h>
#include "jsoncdaccord.h"
#include "internal.h"
#include "optional.h"
#include "../../include/zlog_module.h"
char localpath[256] = {0};
int jdac_ref_set_localpath(const char *_localpath) {
strcpy(localpath, _localpath);
return JDAC_ERR_VALID;
}
const char *_jdac_uri_get_path(const char *uri) {
const char *ptr = uri;
char *schemaseparator = strstr(uri, "://");
if (!schemaseparator) {
//no schema
} else {
//has schema
ptr = schemaseparator + 3;
char *path = strstr(ptr, "/");
if (path) {
return path;
}
}
return NULL;
}
int _jdac_check_ref(json_object *jobj, json_object *jschema, storage_node *storage_list) {
// #ifdef JDAC_STORE
json_object *jref = json_object_object_get(jschema, "$ref");
if (jref) {
const char *refstr = json_object_get_string(jref);
LOG_MOD(trace, ZLOG_MOD_JSCHEM, "ref is %s\n", refstr);
storage_node *rootnode = _jdac_store_get_root_node(storage_list);
// if there is a rootnode id, compare it to the ref
if (rootnode) {
const char *path_ref = _jdac_uri_get_path(refstr);
const char *path_id = _jdac_uri_get_path(rootnode->id);
if (!path_ref) {
return JDAC_ERR_VALID;
}
if (!path_id) {
char filepath[512];
snprintf(filepath, sizeof(filepath) - 1, "%s.%s", localpath, path_ref);
LOG_MOD(trace, ZLOG_MOD_JSCHEM, "filepath is %s\n", filepath);
json_object *jschemafromfile = json_object_from_file(filepath);
if (!jschemafromfile) {
return JDAC_ERR_JSON_NOT_FOUND;
}
int err = _jdac_validate_instance(jobj, jschemafromfile);
json_object_put(jschemafromfile);
return err;
}
if (strcmp(path_ref, path_id) != 0 && strlen(localpath) > 0) {
LOG_MOD(trace, ZLOG_MOD_JSCHEM, "yep\n");
char filepath[512];
snprintf(filepath, sizeof(filepath) - 1, "%s.%s", localpath, path_ref);
LOG_MOD(trace, ZLOG_MOD_JSCHEM, "filepath is %s\n", filepath);
json_object *jschemafromfile = json_object_from_file(filepath);
if (!jschemafromfile) {
return JDAC_ERR_JSON_NOT_FOUND;
}
int err = _jdac_validate_instance(jobj, jschemafromfile);
json_object_put(jschemafromfile);
return err;
} else if (strcmp(path_ref, path_id) == 0) {
int err = _jdac_validate_instance(jobj, rootnode->json_schema_ptr);
return err;
}
}
// if (refstr) {
// json_object *jschema_from_resolved_uri = _jdac_store_resolve(storage_list, refstr);
// if (!jschema_from_resolved_uri)
// return JDAC_ERR_INVALID_REF;
// int err = _jdac_validate_instance(jobj, jschema_from_resolved_uri);
// return err;
// }
}
// #endif
return JDAC_ERR_VALID;
}

View File

@ -0,0 +1,20 @@
#include <regex.h>
#include <stdio.h>
#include <string.h>
#include "jsoncdaccord.h"
#include "../../include/zlog_module.h"
int _jdac_match_string_with_regex(const char *regex_pattern, const char *value) {
regex_t regex;
int reti = regcomp(&regex, regex_pattern, REG_EXTENDED);
if (reti) {
LOG_MOD(error, ZLOG_MOD_JSCHEM, "Could not compile regex\n");
return JDAC_REGEX_COMPILE_FAILED;
}
reti = regexec(&regex, value, 0, NULL, 0);
regfree(&regex);
if (reti == 0) {
return JDAC_REGEX_MATCH;
}
return JDAC_REGEX_MISMATCH;
}

View File

@ -0,0 +1,135 @@
#include <string.h>
#include <stdio.h>
#include "jsoncdaccord.h"
#include "optional.h"
#include "../../include/zlog_module.h"
void _jdac_store_append(storage_node **head, storage_node *ref) {
storage_node *new_node = malloc(sizeof(storage_node));
memcpy(new_node, ref, sizeof(storage_node));
new_node->next = *head;
*head = new_node;
}
void _jdac_store_free(storage_node **head) {
while (*head) {
// if ((*head)->is_root==1 && (*head)->json_instance_ptr!=NULL)
// json_object_put((*head)->json_instance_ptr);
storage_node *el = *head;
*head = (*head)->next;
free(el);
}
*head = NULL;
}
int _jdac_store_traverse_json(storage_node **head, json_object *jschema, char *pathbuffer) {
char pathbuf[256];
pathbuf[0] = 0;
storage_node node = {0};
if (pathbuffer == NULL) {
strcpy(pathbuf, "#/");
node.is_root = 1;
} else {
strcpy(pathbuf, pathbuffer);
node.is_root = 0;
}
node.json_instance_ptr = jschema;
json_object *jid = json_object_object_get(jschema, "$id");
json_object *janchor = json_object_object_get(jschema, "$anchor");
json_object *jdynamicanchor = json_object_object_get(jschema, "$dynamicAnchor");
if (jid) {
strcpy(node.id, json_object_get_string(jid));
}
if (janchor) {
strcpy(node.anchor, json_object_get_string(janchor));
}
if (jdynamicanchor) {
strcpy(node.dynamicAnchor, json_object_get_string(jdynamicanchor));
}
// if (jid || janchor || jdynamicanchor || node.is_root==1) {
strcpy(node.JSONPtrURI, pathbuf);
node.json_schema_ptr = jschema;
_jdac_store_append(head, &node);
// }
json_object_object_foreach(jschema, jkey, jval) {
if (json_object_is_type(jval, json_type_object)) {
if (strcmp(jkey, "const") == 0) {
continue;
}
if (pathbuffer == NULL) {
sprintf(pathbuf, "#/%s", jkey);
} else {
sprintf(pathbuf, "%s/%s", pathbuffer, jkey);
}
//LOG_MOD(debug, ZLOG_MOD_JSCHEM, "%s\n", pathbuf);
_jdac_store_traverse_json(head, jval, pathbuf);
}
}
return JDAC_ERR_VALID;
}
void _jdac_store_print(storage_node *head) {
storage_node *list = head;
LOG_MOD(trace,
ZLOG_MOD_JSCHEM,
"%-*s %-*s %-*s %-*s\n",
32,
"JSONPtr",
16,
"anchor",
16,
"dynamicAnchor",
32,
"id");
while (list) {
LOG_MOD(trace,
ZLOG_MOD_JSCHEM,
"%-*s %-*s %-*s %-*s\n",
32,
list->JSONPtrURI,
16,
list->anchor,
16,
list->dynamicAnchor,
32,
list->id);
list = list->next;
}
}
storage_node *_jdac_store_get_root_node(storage_node *head) {
// spool to start of list
storage_node *list = head;
//LOG_MOD(trace, ZLOG_MOD_JSCHEM, "%-*s %-*s %-*s %-*s\n", 32, "JSONPtr", 16, "anchor", 16, "dynamicAnchor", 32, "id");
while (list) {
//LOG_MOD(trace, ZLOG_MOD_JSCHEM, "%-*s %-*s %-*s %-*s\n", 32, list->JSONPtrURI, 16, list->anchor, 16, list->dynamicAnchor, 32, list->id);
if (list->next == NULL) {
return list;
}
list = list->next;
}
return NULL;
}
json_object *_jdac_store_resolve(storage_node *list, const char *uri) {
while (list) {
if (strcmp(list->id, uri) == 0) {
return list->json_instance_ptr;
}
if (strcmp(list->JSONPtrURI, uri) == 0) {
return list->json_instance_ptr;
}
list = list->next;
}
return NULL;
}

View File

@ -0,0 +1,116 @@
#include "jsoncdaccord.h"
#include "internal.h"
#include "optional.h"
enum subschematype {
JDAC_ALLOF = 0,
JDAC_ANYOF,
JDAC_ONEOF
};
// shall return valid or invalid based on subschema type
int _jdac_test_subschema_array(json_object *jobj, json_object *jsubschema_array, enum subschematype type) {
if (jsubschema_array == NULL) {
return JDAC_ERR_VALID;
}
// MUST be a non-empty array
if (!json_object_is_type(jsubschema_array, json_type_array)) {
return JDAC_ERR_SCHEMA_ERROR;
}
int arraylen = (int)json_object_array_length(jsubschema_array);
if (arraylen == 0) {
return JDAC_ERR_SCHEMA_ERROR;
}
int number_of_valid_schemas = 0;
for (int i = 0; i < arraylen; i++) {
json_object *jsubschema = json_object_array_get_idx(jsubschema_array, i);
if (!json_object_is_type(jsubschema, json_type_object) && !json_object_is_type(jsubschema, json_type_boolean)) {
return JDAC_ERR_SCHEMA_ERROR;
}
int err = _jdac_validate_instance(jobj, jsubschema);
if (err == JDAC_ERR_VALID) {
number_of_valid_schemas++;
} else if (err == JDAC_ERR_SCHEMA_ERROR) {
return JDAC_ERR_SCHEMA_ERROR;
} else {
// continue
}
}
if (type == JDAC_ALLOF) {
if (number_of_valid_schemas == arraylen) {
return JDAC_ERR_VALID;
}
} else if (type == JDAC_ANYOF) {
if (number_of_valid_schemas > 0) {
return JDAC_ERR_VALID;
}
} else if (type == JDAC_ONEOF) {
if (number_of_valid_schemas == 1) {
return JDAC_ERR_VALID;
}
}
return JDAC_ERR_INVALID_SUBSCHEMALOGIC;
}
int _jdac_check_subschemalogic(json_object *jobj, json_object *jschema) {
int err;
json_object *jarray;
jarray = json_object_object_get(jschema, "allOf");
err = _jdac_test_subschema_array(jobj, jarray, JDAC_ALLOF);
if (err) {
return JDAC_ERR_INVALID_SUBSCHEMALOGIC;
}
jarray = json_object_object_get(jschema, "anyOf");
err = _jdac_test_subschema_array(jobj, jarray, JDAC_ANYOF);
if (err) {
return JDAC_ERR_INVALID_SUBSCHEMALOGIC;
}
jarray = json_object_object_get(jschema, "oneOf");
err = _jdac_test_subschema_array(jobj, jarray, JDAC_ONEOF);
if (err) {
return JDAC_ERR_INVALID_SUBSCHEMALOGIC;
}
json_object *jnot = json_object_object_get(jschema, "not");
if (jnot) {
// "not" is special, and MUST be a json object
if (json_object_is_type(jnot, json_type_object) || json_object_is_type(jnot, json_type_boolean)) {
err = _jdac_validate_instance(jobj, jnot);
if (err == JDAC_ERR_VALID) {
return JDAC_ERR_INVALID_SUBSCHEMALOGIC;
} else if (err == JDAC_ERR_SCHEMA_ERROR) {
return JDAC_ERR_SCHEMA_ERROR;
} else {
return JDAC_ERR_VALID;
}
} else {
return JDAC_ERR_SCHEMA_ERROR;
}
}
json_object *if_schema = json_object_object_get(jschema, "if");
json_object *then_schema = json_object_object_get(jschema, "then");
json_object *else_schema = json_object_object_get(jschema, "else");
if (if_schema) {
err = _jdac_validate_instance(jobj, if_schema);
if (err == JDAC_ERR_VALID && then_schema) {
err = _jdac_validate_instance(jobj, then_schema);
return err;
} else if (err != JDAC_ERR_VALID && else_schema) {
err = _jdac_validate_instance(jobj, else_schema);
return err;
}
}
return JDAC_ERR_VALID;
}

View File

@ -0,0 +1,649 @@
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <json-c/json.h>
#include "jsoncdaccord.h"
#include "internal.h"
#include "optional.h"
#include "../../include/zlog_module.h"
json_object *json = NULL;
json_object *schema = NULL;
json_object *defs = NULL;
#ifdef JDAC_STORE
static storage_node *storagelist_head = NULL;
#endif
static char *jdacerrstr[JDAC_ERR_MAX] = {"VALID",
"GENERAL ERROR",
"JSON FILE NOT FOUND",
"SCHEMA FILE NOT FOUND",
"WRONG ARGUEMNTS GIVEN",
"SCHEMA ERROR",
"INVALID",
"INVALID TYPE",
"INVALID REQUIRED",
"INVALID SUBSCHEMA LOGIC (allOf, anyOf, oneOf, or not)",
"INVALID CONST",
"INVALID ENUMS",
"INVALID STRING LENGTH",
"INVALID UNIQUE ITEMS",
"INVALID UNIQUE CONTAINS",
"INVALID PREFIXITEMS",
"INVALID ITEMS",
"INVALID ARRAY LENGTH",
"INVALID NUMBER",
"INVALID REFERENCE",
"PATTERN NO MATCH",
"REGEX MISMATCH",
"REGEX MATCH",
"REGEX COMPILE FAILED"};
const char *jdac_errorstr(unsigned int jdac_errors) {
if (jdac_errors < JDAC_ERR_MAX) {
return jdacerrstr[jdac_errors];
}
return NULL;
}
int _jdac_load(const char *jsonfile, const char *jsonschema) {
json = json_object_from_file(jsonfile);
if (json == NULL) {
return JDAC_ERR_JSON_NOT_FOUND;
}
schema = json_object_from_file(jsonschema);
if (schema == NULL) {
json_object_put(json);
return JDAC_ERR_SCHEMA_NOT_FOUND;
}
return JDAC_ERR_VALID;
}
int __jdac_inspect_type(json_object *jobj, const char *type) {
if (strcmp(type, "object") == 0) {
if (json_object_is_type(jobj, json_type_object)) {
return JDAC_ERR_VALID;
}
} else if (strcmp(type, "array") == 0) {
if (json_object_is_type(jobj, json_type_array)) {
return JDAC_ERR_VALID;
}
} else if (strcmp(type, "string") == 0) {
if (json_object_is_type(jobj, json_type_string)) {
return JDAC_ERR_VALID;
}
} else if (strcmp(type, "integer") == 0) {
if (json_object_is_type(jobj, json_type_int)) {
return JDAC_ERR_VALID;
}
if (json_object_is_type(jobj, json_type_double)) {
double value = json_object_get_double(jobj);
if (value == round(value)) { // "zero fractional part is an integer"
return JDAC_ERR_VALID;
}
}
} else if (strcmp(type, "double") == 0) {
if (json_object_is_type(jobj, json_type_double)) {
return JDAC_ERR_VALID;
}
} else if (strcmp(type, "number") == 0) {
if (json_object_is_type(jobj, json_type_double) || json_object_is_type(jobj, json_type_int)) {
return JDAC_ERR_VALID;
}
} else if (strcmp(type, "boolean") == 0) {
if (json_object_is_type(jobj, json_type_boolean)) {
return JDAC_ERR_VALID;
}
} else if (strcmp(type, "null") == 0) {
if (json_object_is_type(jobj, json_type_null)) {
return JDAC_ERR_VALID;
}
} else {
LOG_MOD(warn, ZLOG_MOD_JSCHEM, "WARN unknown type in check type %s\n", type);
return JDAC_ERR_SCHEMA_ERROR;
}
return JDAC_ERR_INVALID_TYPE;
}
int _jdac_check_type(json_object *jobj, json_object *jschema) {
json_object *jtype = json_object_object_get(jschema, "type");
if (jtype == NULL) {
return JDAC_ERR_VALID;
} else if (json_object_is_type(jtype, json_type_string)) {
const char *type = json_object_get_string(jtype);
return __jdac_inspect_type(jobj, type);
} else if (json_object_is_type(jtype, json_type_array)) {
int arraylen = json_object_array_length(jtype);
for (int i = 0; i < arraylen; i++) {
json_object *iobj = json_object_array_get_idx(jtype, i);
if (!json_object_is_type(iobj, json_type_string)) {
return JDAC_ERR_SCHEMA_ERROR;
}
const char *type = json_object_get_string(iobj);
int err = __jdac_inspect_type(jobj, type);
if (err == JDAC_ERR_VALID) {
return JDAC_ERR_VALID;
}
}
return JDAC_ERR_INVALID_TYPE;
} else {
return JDAC_ERR_SCHEMA_ERROR;
}
}
int _jdac_check_required(json_object *jobj, json_object *jschema) {
//LOG_MOD(debug, ZLOG_MOD_JSCHEM, "%s\n%s\n", __func__, json_object_to_json_string(jobj));
json_object *jarray = json_object_object_get(jschema, "required");
int missing_required_key = 0;
if (jarray) {
int arraylen = json_object_array_length(jarray);
for (int i = 0; i < arraylen; i++) {
json_object *iobj = json_object_array_get_idx(jarray, i);
const char *key = json_object_get_string(iobj);
if (key) {
//LOG_MOD(debug, ZLOG_MOD_JSCHEM, "%s\n", key);
// use json_object_object_get_ex becuase of json_type_null types
json_object *required_object = NULL;
int err = json_object_object_get_ex(jobj, key, &required_object);
if (err == 0) {
LOG_MOD(debug, ZLOG_MOD_JSCHEM, "required key missing: %s\n", key);
missing_required_key = 1;
}
}
}
}
if (missing_required_key) {
return JDAC_ERR_INVALID_REQUIRED;
} else {
return JDAC_ERR_VALID;
}
}
int _jdac_check_properties(json_object *jobj, json_object *jschema) {
// LOG_MOD(debug, ZLOG_MOD_JSCHEM, "%s\n", __func__);
json_object *jprops = json_object_object_get(jschema, "properties");
if (jprops) {
json_object_object_foreach(jprops, jprop_key, jprop_val) {
// LOG_MOD(debug, ZLOG_MOD_JSCHEM, "key of prop is %s\n", jprop_key);
json_object *iobj = json_object_object_get(jobj, jprop_key);
//LOG_MOD(debug, ZLOG_MOD_JSCHEM, "iobj %s type %d\nkey %s\nval %s\n", json_object_get_string(iobj), json_object_get_type(iobj), jprop_key, json_object_get_string(jprop_val));
if (iobj) {
int err = _jdac_validate_instance(iobj, jprop_val);
if (err) {
return err;
}
}
}
}
return JDAC_ERR_VALID;
}
int _jdac_check_prefixItems_and_items(json_object *jobj, json_object *jschema) {
json_object *jprefixitems = json_object_object_get(jschema, "prefixItems");
json_object *jitems = json_object_object_get(jschema, "items");
int jobj_arraylen = json_object_array_length(jobj);
int prefixitems_arraylen = 0;
if (jprefixitems) {
if (!json_object_is_type(jprefixitems, json_type_array)) {
return JDAC_ERR_SCHEMA_ERROR;
}
prefixitems_arraylen = json_object_array_length(jprefixitems);
for (int i = 0; i < jobj_arraylen && i < prefixitems_arraylen; i++) {
//LOG_MOD(debug, ZLOG_MOD_JSCHEM, "i=%d prefixitems\n", i);
json_object *iobj = json_object_array_get_idx(jobj, i);
json_object *ischema = json_object_array_get_idx(jprefixitems, i);
int err = _jdac_validate_instance(iobj, ischema);
if (err) {
return JDAC_ERR_INVALID_PREFIXITEMS;
}
}
}
if (jitems) {
if (!json_object_is_type(jitems, json_type_object) && !json_object_is_type(jitems, json_type_boolean)) {
return JDAC_ERR_SCHEMA_ERROR;
}
for (int i = prefixitems_arraylen; i < jobj_arraylen; i++) {
//LOG_MOD(debug, ZLOG_MOD_JSCHEM, "i=%d items\n", i);
json_object *iobj = json_object_array_get_idx(jobj, i);
int err = _jdac_validate_instance(iobj, jitems);
if (err) {
return JDAC_ERR_INVALID_ITEMS;
}
}
}
return JDAC_ERR_VALID;
}
json_object *_jdac_get_defs_from_ref(json_object *ref) {
char key[128];
if (!json_object_is_type(ref, json_type_string)) {
return NULL;
}
const char *refstr = json_object_get_string(ref);
if (sscanf(refstr, "#/$defs/%s", key) == 1) {
return json_object_object_get(defs, key);
}
return NULL;
}
int _jdac_value_is_equal(json_object *jobj1, json_object *jobj2) {
if (json_object_equal(jobj1, jobj2)) {
return JDAC_ERR_VALID;
}
if (json_object_is_type(jobj1, json_type_double) && json_object_is_type(jobj2, json_type_int)) {
double value = json_object_get_double(jobj1);
double value2 = json_object_get_int64(jobj2);
if (value == round(value) && value == value2) {
return JDAC_ERR_VALID;
}
}
if (json_object_is_type(jobj1, json_type_int) && json_object_is_type(jobj2, json_type_double)) {
double value = json_object_get_double(jobj2);
double value2 = json_object_get_int64(jobj1);
if (value == round(value) && value == value2) {
return JDAC_ERR_VALID;
}
}
return JDAC_ERR_INVALID;
}
int _jdac_check_const(json_object *jobj, json_object *jschema) {
json_object *jconst;
int err = json_object_object_get_ex(jschema, "const", &jconst);
if (err == 0) {
return JDAC_ERR_VALID;
}
err = _jdac_value_is_equal(jobj, jconst);
if (err == JDAC_ERR_VALID) {
return JDAC_ERR_VALID;
}
return JDAC_ERR_INVALID_CONST;
}
int _jdac_check_enums(json_object *jobj, json_object *jschema) {
json_object *jenum_array = json_object_object_get(jschema, "enum");
if (!jenum_array) {
return JDAC_ERR_VALID;
}
if (!json_object_is_type(jenum_array, json_type_array)) {
return JDAC_ERR_SCHEMA_ERROR;
}
int arraylen = json_object_array_length(jenum_array);
for (int i = 0; i < arraylen; i++) {
json_object *ienum = json_object_array_get_idx(jenum_array, i);
int err = _jdac_value_is_equal(jobj, ienum);
if (err == JDAC_ERR_VALID) {
return JDAC_ERR_VALID;
}
}
LOG_MOD(error, ZLOG_MOD_JSCHEM, "ERROR: enum check failed (%s not in enum)\n", json_object_to_json_string(jobj));
return JDAC_ERR_INVALID_ENUMS;
}
int _jdac_check_uniqueItems(json_object *jobj, json_object *jschema) {
json_object *juniq = json_object_object_get(jschema, "uniqueItems");
if (juniq) {
if (!json_object_is_type(juniq, json_type_boolean)) {
return JDAC_ERR_SCHEMA_ERROR;
}
if (json_object_get_boolean(juniq) == 0) {
return JDAC_ERR_VALID;
}
int arraylen = json_object_array_length(jobj);
for (int i = 0; i < arraylen - 1; i++) {
json_object *iobj = json_object_array_get_idx(jobj, i);
for (int j = i + 1; j < arraylen; j++) {
json_object *uobj = json_object_array_get_idx(jobj, j);
if (json_object_equal(iobj, uobj) == 1) {
return JDAC_ERR_INVALID_UNIQUEITEMS;
}
}
}
}
return JDAC_ERR_VALID;
}
int _jdac_check_maxmin_items(json_object *jobj, json_object *jschema) {
int err = JDAC_ERR_VALID;
json_object *jmax = json_object_object_get(jschema, "maxItems");
json_object *jmin = json_object_object_get(jschema, "minItems");
int arraylen = json_object_array_length(jobj);
if (jmax) {
if (json_object_is_type(jmax, json_type_int) || json_object_is_type(jmax, json_type_double)) {
int maxitems = json_object_get_double(jmax);
if (arraylen > maxitems) {
err = JDAC_ERR_INVALID_ARRAYLEN;
}
}
}
if (jmin) {
if (json_object_is_type(jmin, json_type_int) || json_object_is_type(jmin, json_type_double)) {
int minitems = json_object_get_double(jmin);
if (arraylen < minitems) {
err = JDAC_ERR_INVALID_ARRAYLEN;
}
}
}
if (err) {
LOG_MOD(error, ZLOG_MOD_JSCHEM, "ERROR: failed at maxItems or minItems check\n");
}
return err;
}
int _jdac_validate_array(json_object *jobj, json_object *jschema) {
int err;
err = _jdac_check_prefixItems_and_items(jobj, jschema);
if (err) {
return err;
}
err = _jdac_check_uniqueItems(jobj, jschema);
if (err) {
return err;
}
err = _jdac_check_maxmin_items(jobj, jschema);
if (err) {
return err;
}
#ifdef JDAC_CONTAINS
err = _jdac_check_contains_and_minmaxcontains(jobj, jschema);
if (err) {
return err;
}
#endif
return JDAC_ERR_VALID;
}
int _jdac_validate_object(json_object *jobj, json_object *jschema) {
int err;
if (defs == NULL) {
defs = json_object_object_get(jschema, "$defs");
}
err = _jdac_check_required(jobj, jschema);
if (err) {
return err;
}
err = _jdac_check_properties(jobj, jschema);
if (err) {
return err;
}
#ifdef JDAC_PROPERTYNAMES
err = _jdac_check_propertynames(jobj, jschema);
if (err) {
return err;
}
#endif
#ifdef JDAC_PATTERNPROPERTIES
err = _jdac_check_patternproperties(jobj, jschema);
if (err) {
return err;
}
#endif
#ifdef JDAC_ADDITIONALPROPERTIES
err = _jdac_check_additionalproperties(jobj, jschema);
if (err) {
return err;
}
#endif
return JDAC_ERR_VALID;
}
int utf8_length(const char *str) {
const char *pointer = str;
int len = 0;
while (pointer[0]) {
if ((pointer[0] & 0xC0) != 0x80) {
len++;
}
pointer++;
}
return len;
}
int _jdac_validate_string(json_object *jobj, json_object *jschema) {
const char *str = json_object_get_string(jobj);
//LOG_MOD(debug, ZLOG_MOD_JSCHEM, "strlen of %s %ld %d %d\n", str, strlen(str), json_object_get_string_len(jobj), utf8_length(str));
json_object *jminlen = json_object_object_get(jschema, "minLength");
if (jminlen) {
int minlen = json_object_get_int64(jminlen);
if (utf8_length(str) < minlen) {
return JDAC_ERR_INVALID_STRLEN;
}
}
json_object *jmaxlen = json_object_object_get(jschema, "maxLength");
if (jmaxlen) {
int maxlen = json_object_get_int64(jmaxlen);
if (utf8_length(str) > maxlen) {
return JDAC_ERR_INVALID_STRLEN;
}
}
int err = _jdac_check_enums(jobj, jschema);
if (err) {
return err;
}
#ifdef JDAC_PATTERN
err = _jdac_check_pattern(jobj, jschema);
if (err) {
return err;
}
#endif
return JDAC_ERR_VALID;
}
int _jdac_validate_integer(json_object *jobj, json_object *jschema) {
double value = (double)json_object_get_int64(jobj);
int err = _jdac_validate_number(jobj, jschema, value);
return err;
}
int _jdac_validate_double(json_object *jobj, json_object *jschema) {
double value = json_object_get_double(jobj);
int err = _jdac_validate_number(jobj, jschema, value);
return err;
}
int _jdac_validate_number(json_object *jobj, json_object *jschema, double value) {
json_object *jmult = json_object_object_get(jschema, "multipleOf");
if (jmult) {
double multipland = (double)json_object_get_double(jmult);
if (multipland == 0.0) {
return JDAC_ERR_SCHEMA_ERROR;
}
double divided = value / multipland;
if (isinf(divided) != 0) {
return JDAC_ERR_INVALID_NUMBER;
}
if (divided != round(divided)) {
return JDAC_ERR_INVALID_NUMBER;
}
}
json_object *jmin = json_object_object_get(jschema, "minimum");
if (jmin) {
double min = (double)json_object_get_double(jmin);
if (value < min) {
return JDAC_ERR_INVALID_NUMBER;
}
}
json_object *jexclmin = json_object_object_get(jschema, "exclusiveMinimum");
if (jexclmin) {
double min = (double)json_object_get_double(jexclmin);
if (value <= min) {
return JDAC_ERR_INVALID_NUMBER;
}
}
json_object *jmax = json_object_object_get(jschema, "maximum");
if (jmax) {
double max = (double)json_object_get_double(jmax);
if (value > max) {
return JDAC_ERR_INVALID_NUMBER;
}
}
json_object *jexclmax = json_object_object_get(jschema, "exclusiveMaximum");
if (jexclmax) {
double max = (double)json_object_get_double(jexclmax);
if (value >= max) {
return JDAC_ERR_INVALID_NUMBER;
}
}
return JDAC_ERR_VALID;
}
int _jdac_validate_boolean(json_object *jobj, json_object *jschema) {
// LOG_MOD(debug, ZLOG_MOD_JSCHEM, "%s\n", __func__);
return JDAC_ERR_VALID;
}
int _jdac_validate_instance(json_object *jobj, json_object *jschema) {
int err;
// LOG_MOD(debug, ZLOG_MOD_JSCHEM, "--validate instance--\n");
// LOG_MOD(debug, ZLOG_MOD_JSCHEM, "%s\n", json_object_get_string(jobj));
// LOG_MOD(debug, ZLOG_MOD_JSCHEM, "%s\n", json_object_get_string(jschema));
#ifdef JDAC_REF
err = _jdac_check_ref(jobj, jschema, storagelist_head);
if (err) {
return err;
}
#endif
// check if jschema is a bool, true or false
if (json_object_is_type(jschema, json_type_boolean)) {
json_bool value = json_object_get_boolean(jschema);
if (value == 0) {
return JDAC_ERR_INVALID;
}
if (value == 1) {
return JDAC_ERR_VALID;
}
}
err = _jdac_check_type(jobj, jschema);
if (err) {
return err;
}
err = _jdac_check_const(jobj, jschema);
if (err) {
return err;
}
err = _jdac_check_enums(jobj, jschema);
if (err) {
return err;
}
// if (!json_object_is_type(jobj, json_type_null))
// LOG_MOD(debug, ZLOG_MOD_JSCHEM, "%s\n", json_object_get_string(jobj));
// else
// LOG_MOD(debug, ZLOG_MOD_JSCHEM, "jobj was null\n");
// if (!json_object_is_type(jschema, json_type_null))
// LOG_MOD(debug, ZLOG_MOD_JSCHEM, "%s\n", json_object_get_string(jschema));
// else
// LOG_MOD(debug, ZLOG_MOD_JSCHEM, "jschema was null\n");
#ifdef JDAC_SUBSCHEMALOGIC
err = _jdac_check_subschemalogic(jobj, jschema);
if (err) {
return err;
}
#endif
json_type type = json_object_get_type(jobj);
if (type == json_type_object) {
return _jdac_validate_object(jobj, jschema);
} else if (type == json_type_array) {
return _jdac_validate_array(jobj, jschema);
} else if (type == json_type_string) {
return _jdac_validate_string(jobj, jschema);
} else if (type == json_type_boolean) {
return _jdac_validate_boolean(jobj, jschema);
} else if (type == json_type_int) {
return _jdac_validate_integer(jobj, jschema);
} else if (type == json_type_double) {
return _jdac_validate_double(jobj, jschema);
} else if (type == json_type_null) {
return JDAC_ERR_VALID;
} else {
LOG_MOD(warn, ZLOG_MOD_JSCHEM, "WARN: type %d not handled\n", type);
}
return JDAC_ERR_VALID;
}
int jdac_validate(json_object *jobj, json_object *jschema) {
#ifdef JDAC_STORE
_jdac_store_traverse_json(&storagelist_head, jschema, NULL);
_jdac_store_print(storagelist_head);
#endif
int err = _jdac_validate_instance(jobj, jschema);
#ifdef JDAC_STORE
_jdac_store_free(&storagelist_head);
#endif
return err;
}
int jdac_validate_file(const char *jsonfile, const char *jsonschemafile) {
int err = _jdac_load(jsonfile, jsonschemafile);
if (err) {
return err;
}
err = jdac_validate(json, schema);
json_object_put(json);
json_object_put(schema);
json = NULL;
schema = NULL;
defs = NULL;
return err;
}

View File

@ -0,0 +1,33 @@
//
// Created by xajhuang on 2023/3/2.
//
#include <fcntl.h>
#include <sys/file.h>
#include <errno.h>
#include <unistd.h>
#include <string.h>
#include "user_errno.h"
#include "misc.h"
static int g_lockfd = -1;
static char g_pidPath[MAX_PATH] = {0};
int process_lock_pidfile(char *pFilePath) {
if (pFilePath == NULL || strlen(pFilePath) == 0) {
return ERR_SUCCESS;
}
strcpy(g_pidPath, pFilePath);
g_lockfd = open(pFilePath, O_CREAT | O_RDWR, 0666); // open file
int rc = flock(g_lockfd, LOCK_EX | LOCK_NB); // lock access to open file
if (rc && EWOULDBLOCK == errno) { // check lock success
return -ERR_FILE_LOCKED; // another instance is running
}
return ERR_SUCCESS;
}
void process_unlock_pidfile() {
close(g_lockfd);
unlink(g_pidPath);
}

View File

@ -10,7 +10,9 @@
#include "crypto.h"
#include "user_errno.h"
#include "zlog_module.h"
#ifdef JSON_SCHEMA_ON
#include "json_schema/jsoncdaccord.h"
#endif
#define CURRENT_PROTOCOL_VERSION (1)
typedef struct {
@ -21,14 +23,121 @@ typedef struct {
cJSON *msgContend;
} PROTOCOL_WARP, *PPROTOCOL_WARP;
const char *proto_decode_context(const char *pString, unsigned int *pVer, unsigned long long *pTm) {
#ifdef JSON_SCHEMA_ON
typedef struct {
const char *pSchJson;
const char *pErrMsg;
} JSON_SCHEMA_CTX, *PJSON_SCHEMA_CTX;
static JSON_SCHEMA_CTX g_json_sch[] = {
{"{\"type\":\"object\",\"required\":[\"ver\"]}", "Missing required field [ver]" },
{"{\"type\":\"object\",\"required\":[\"cryptoType\"]}", "Missing required field [cryptoType]" },
{"{\"type\":\"object\",\"required\":[\"timeStamp\"]}", "Missing required field [timeStamp]" },
{"{\"type\":\"object\",\"required\":[\"msgContent\"]}", "Missing required field [msgContent]" },
{"{\"properties\":{\"ver\":{\"type\":\"integer\"}}}", "[ver] should be an integer value" },
{"{\"properties\":{\"cryptoType\":{\"type\":\"integer\"}}}", "[cryptoType] should be an integer value"},
{"{\"properties\":{\"cryptoType\":{\"minimum\":0,\"maximum\":4}}}", "Undefined type in field [cryptoType]" },
{"{\"properties\":{\"timeStamp\":{\"type\":\"integer\"}}}", "[timeStamp] should be an integer value" },
};
const char *proto_schema_validation(const char *pJsonStr) {
int i;
json_object *pJs = json_tokener_parse(pJsonStr);
if (!pJs) {
cJSON *pRspRoot = cJSON_CreateObject();
cJSON_AddNumberToObject(pRspRoot, "status", ERR_JSON_PARSE_OBJ);
cJSON_AddStringToObject(pRspRoot, "message", getErrorEnumDesc(ERR_JSON_PARSE_OBJ));
return proto_create_new(pRspRoot, 200);
}
for (i = 0; i < ARRAY_SIZE(g_json_sch); i++) {
json_object *pSc = json_tokener_parse(g_json_sch[i].pSchJson);
if (!pSc) {
LOG_MOD(error, ZLOG_MOD_PROTO, "Json schema format error: [%s]\n", g_json_sch[i].pSchJson);
continue;
}
if (jdac_validate(pJs, pSc) != JDAC_ERR_VALID) {
cJSON *pRspRoot = cJSON_CreateObject();
cJSON_AddNumberToObject(pRspRoot, "status", ERR_JSON_VALID_SCH);
cJSON_AddStringToObject(pRspRoot, "message", getErrorEnumDesc(ERR_JSON_VALID_SCH));
cJSON_AddStringToObject(pRspRoot, "details", g_json_sch[i].pErrMsg);
json_object_put(pSc);
json_object_put(pJs);
return proto_create_new(pRspRoot, 200);
}
json_object_put(pSc);
}
json_object_put(pJs);
return NULL;
}
const char *proto_msg_validation(const char *pJsonStr, const char *msgJson, const char *errMsg) {
json_object *pJs = json_tokener_parse(pJsonStr);
if (!pJs) {
cJSON *pRspRoot = cJSON_CreateObject();
cJSON_AddNumberToObject(pRspRoot, "status", ERR_JSON_PARSE_OBJ);
cJSON_AddStringToObject(pRspRoot, "message", getErrorEnumDesc(ERR_JSON_PARSE_OBJ));
return proto_create_new(pRspRoot, 200);
}
json_object *pSc = json_tokener_parse(msgJson);
if (!pSc) {
LOG_MOD(error, ZLOG_MOD_PROTO, "Json schema format error: [%s]\n", msgJson);
}
if (jdac_validate(pJs, pSc) != JDAC_ERR_VALID) {
cJSON *pRspRoot = cJSON_CreateObject();
cJSON_AddNumberToObject(pRspRoot, "status", ERR_JSON_VALID_SCH);
cJSON_AddStringToObject(pRspRoot, "message", getErrorEnumDesc(ERR_JSON_VALID_SCH));
cJSON_AddStringToObject(pRspRoot, "details", errMsg);
json_object_put(pSc);
json_object_put(pJs);
return proto_create_new(pRspRoot, 200);
}
json_object_put(pSc);
json_object_put(pJs);
return NULL;
}
#endif
const char *proto_decode_context(const char *pString, unsigned int *pVer, unsigned long long *pTm, int *pErrCode) {
cJSON *pMsgCtx;
unsigned char *pBase64;
int decodeSize;
unsigned int outSize = 0;
char *pMsgContent = NULL;
cJSON *pRoot = cJSON_Parse(pString);
cJSON *pRoot;
#ifdef JSON_SCHEMA_ON
const char *pSchJson;
#endif
if (pErrCode == NULL) {
return NULL;
}
if (pString == NULL || strlen(pString) == 0) {
*pErrCode = ERR_INPUT_PARAMS;
return NULL;
}
LOG_MOD(debug, ZLOG_MOD_PROTO, "Request: %s\n", pString);
#ifdef JSON_SCHEMA_ON
pSchJson = proto_schema_validation(pString);
if (pSchJson != NULL && strlen(pSchJson) > 0) {
*pErrCode = ERR_JSON_VALID_SCH;
return pSchJson;
}
#endif
pRoot = cJSON_Parse(pString);
if (!pRoot) {
return NULL;
}
@ -201,7 +310,7 @@ const char *proto_create_new(cJSON *pMsgCtx, int httpCode) {
}
pStrProto = cJSON_PrintUnformatted(pRoot);
LOG_MOD(trace, ZLOG_MOD_PROTO, "Create: \n%s\n", pStrProto);
LOG_MOD(debug, ZLOG_MOD_PROTO, "Create: %s\n", pStrProto);
cJSON_Delete(pRoot);

View File

@ -4,6 +4,7 @@
#include <string.h>
#include "zlog_module.h"
#include "misc.h"
#include "config.h"
#define MAX_ZLOG_MOD_LEN (8)
@ -20,6 +21,22 @@ static ZLOG_MODULE g_zlogModule[] = {
DEF_ZLOG_MOD(GENERATE_ENUM_ARRAY) {-1, ZLOG_LEVEL_FATAL, NULL, "UNKNOWN"}
};
#ifdef USERVNI_ON
static char g_vni_str[64] = {0};
const char *zlog_vni_tag_get() {
if (strlen(g_vni_str) == 0) {
sprintf(g_vni_str, "%u", cfg_get_user_vni_id());
}
return (const char *)g_vni_str;
}
#else
const char *zlog_vni_tag_get() {
return "main";
}
#endif
zlog_category_t *zlog_get_mod_cat(ZLOG_MOD_NAME logMod) {
if (logMod >= ARRAY_SIZE(g_zlogModule) || logMod < 0) {
logMod = ARRAY_SIZE(g_zlogModule) - 1;

View File

@ -1904,18 +1904,33 @@ MYDWORD sdmess(data9 *req) {
req->dhcpp.header.bp_op = BOOTP_REPLY;
errno = 0;
#if DISCOVER_RSP_NOT_BOARDCAST
sockaddr_in cliAddr = get_cliAddr(nicif, tempbuff, req);
#endif
if (req->req_type == DHCP_MESS_DISCOVER && !req->remote.sin_addr.s_addr) {
req->bytes = (int)sendto(network.dhcpConn[req->sockInd].sock,
req->raw,
packSize,
MSG_DONTROUTE,
#if DISCOVER_RSP_NOT_BOARDCAST
(sockaddr *)&cliAddr,
sizeof(cliAddr));
#else
(sockaddr *)&req->remote,
sizeof(req->remote));
#endif
} else {
req->bytes = (int)
sendto(network.dhcpConn[req->sockInd].sock, req->raw, packSize, 0, (sockaddr *)&cliAddr, sizeof(cliAddr));
req->bytes = (int)sendto(network.dhcpConn[req->sockInd].sock,
req->raw,
packSize,
0,
#if DISCOVER_RSP_NOT_BOARDCAST
(sockaddr *)&cliAddr,
sizeof(cliAddr));
#else
(sockaddr *)&req->remote,
sizeof(req->remote));
#endif
}
if (errno || req->bytes <= 0) {

View File

@ -39,7 +39,7 @@
#endif
#ifndef SIOCGIFCONF
#include <sys/sockio.h>
#include <sys/ioctl.h>
#endif
#ifndef _UIO_H_
@ -70,19 +70,21 @@ typedef struct in_pktinfo IN_PKTINFO;
#define IFF_DYNAMIC 0x8000
#endif
#define MYWORD unsigned short
#define MYBYTE unsigned char
#define MYDWORD unsigned int
#define SOCKET_ERROR -1
#define INVALID_SOCKET -1
#define SOCKADDR_IN sockaddr_in
#define SOCKADDR sockaddr
#define SOCKET int
#define BOOL bool
#define LPSOCKADDR sockaddr *
#define closesocket close
#define MYWORD unsigned short
#define MYBYTE unsigned char
#define MYDWORD unsigned int
#define SOCKET_ERROR -1
#define INVALID_SOCKET -1
#define SOCKADDR_IN sockaddr_in
#define SOCKADDR sockaddr
#define SOCKET int
#define BOOL bool
#define LPSOCKADDR sockaddr *
#define closesocket close
#define STR2INT(val) ((int)strtol((val), nullptr, 10))
#define STR2INT(val) ((int)strtol((val), nullptr, 10))
#define DISCOVER_RSP_NOT_BOARDCAST (0)
#define logDHCPMess(logBuff, logLevel) \
do { \
@ -705,75 +707,77 @@ struct data15 {
};
//Function Prototypes
bool checkIP(data9 *req, data17 *rangeData, MYDWORD ip);
bool checkMask(MYDWORD);
bool checkRange(data17 *, char);
bool detectChange();
bool getSection(const char *, char *, MYBYTE, char *);
bool isInt(char *);
bool isIP(char *);
FILE *openSection(const char *, MYBYTE);
MYBYTE pIP(void *, MYDWORD);
MYBYTE pUInt(void *raw, MYDWORD data);
MYBYTE pUShort(void *, MYWORD);
MYBYTE addServer(MYDWORD *, MYBYTE, MYDWORD);
int getRangeInd(MYDWORD);
char *myTrim(char *, char *);
char *myGetToken(char *, MYBYTE);
char *cloneString(char *);
char *getHexValue(MYBYTE *, char *, MYBYTE *);
char *genHostName(char *, const MYBYTE *, MYBYTE);
char *hex2String(char *, const MYBYTE *, MYBYTE);
char *IP2String(char *, MYDWORD);
char *myUpper(char *string);
char *myLower(char *string);
char *readSection(char *, FILE *);
data7 *findDHCPEntry(char *);
data7 *createCache(data71 *pLump);
MYDWORD alad(data9 *);
MYDWORD resad(data9 *);
MYDWORD sdmess(data9 *);
MYDWORD sendRepl(data9 *req);
MYDWORD *findServer(MYDWORD *, MYBYTE, MYDWORD);
int getIndex(char, MYDWORD);
int addDHCPRange(char *dp);
void addVendClass(MYBYTE rangeSetInd, char *vendClass, MYBYTE vendClassSize);
void addUserClass(MYBYTE rangeSetInd, char *userClass, MYBYTE userClassSize);
void addMacRange(MYBYTE rangeSetInd, char *macRange);
void addOptions(data9 *req);
void calcRangeLimits(MYDWORD, MYDWORD, MYDWORD *, MYDWORD *);
void closeConn();
bool getInterfaces(data1 *pNetwork);
void *init(void *);
void lockOptions(FILE *);
void loadOptions(FILE *, const char *, data20 *);
void mySplit(char *, char *, const char *, char);
void *sendHTTP(void *);
void procHTTP(data19 *);
void pvdata(data9 *, data3 *);
void recvRepl(data9 *);
void lockIP(MYDWORD);
void sendStatus(data19 *req);
void setTempLease(data7 *);
void setLeaseExpiry(data7 *);
void setLeaseExpiry(data7 *, MYDWORD);
void *updateStateFile(void *);
MYWORD fUShort(void *);
MYWORD gdmess(data9 *, MYBYTE);
MYWORD myTokenize(char *, char *, const char *, bool);
MYDWORD fIP(void *raw);
MYDWORD fUInt(void *raw);
int prepareUserHtmlRespStatus(const char **pRsp);
bool checkIP(data9 *req, data17 *rangeData, MYDWORD ip);
bool checkMask(MYDWORD);
bool checkRange(data17 *, char);
bool detectChange();
bool getSection(const char *, char *, MYBYTE, char *);
bool isInt(char *);
bool isIP(char *);
FILE *openSection(const char *, MYBYTE);
MYBYTE pIP(void *, MYDWORD);
MYBYTE pUInt(void *raw, MYDWORD data);
MYBYTE pUShort(void *, MYWORD);
MYBYTE addServer(MYDWORD *, MYBYTE, MYDWORD);
int getRangeInd(MYDWORD);
char *myTrim(char *, char *);
char *myGetToken(char *, MYBYTE);
char *cloneString(char *);
char *getHexValue(MYBYTE *, char *, MYBYTE *);
char *genHostName(char *, const MYBYTE *, MYBYTE);
char *hex2String(char *, const MYBYTE *, MYBYTE);
char *IP2String(char *, MYDWORD);
char *myUpper(char *string);
char *myLower(char *string);
char *readSection(char *, FILE *);
data7 *findDHCPEntry(char *);
data7 *createCache(data71 *pLump);
MYDWORD alad(data9 *);
MYDWORD resad(data9 *);
MYDWORD sdmess(data9 *);
MYDWORD sendRepl(data9 *req);
MYDWORD *findServer(MYDWORD *, MYBYTE, MYDWORD);
int getIndex(char, MYDWORD);
int addDHCPRange(char *dp);
void addVendClass(MYBYTE rangeSetInd, char *vendClass, MYBYTE vendClassSize);
void addUserClass(MYBYTE rangeSetInd, char *userClass, MYBYTE userClassSize);
void addMacRange(MYBYTE rangeSetInd, char *macRange);
void addOptions(data9 *req);
void calcRangeLimits(MYDWORD, MYDWORD, MYDWORD *, MYDWORD *);
void closeConn();
bool getInterfaces(data1 *pNetwork);
void *init(void *);
void lockOptions(FILE *);
void loadOptions(FILE *, const char *, data20 *);
void mySplit(char *, char *, const char *, char);
void *sendHTTP(void *);
void procHTTP(data19 *);
void pvdata(data9 *, data3 *);
void recvRepl(data9 *);
void lockIP(MYDWORD);
void sendStatus(data19 *req);
void setTempLease(data7 *);
void setLeaseExpiry(data7 *);
void setLeaseExpiry(data7 *, MYDWORD);
void *updateStateFile(void *);
MYWORD fUShort(void *);
MYWORD gdmess(data9 *, MYBYTE);
MYWORD myTokenize(char *, char *, const char *, bool);
MYDWORD fIP(void *raw);
MYDWORD fUInt(void *raw);
int prepareUserHtmlRespStatus(const char **pRsp);
#ifdef HTTPSERVER_ON
void opendhcp_init_http_server();
void opendhcp_init_http_server();
#endif
void opendhcp_set_replication_svr();
void opendhcp_add_ip_pool_set();
void opendhcp_add_mac_filter();
int process_iptv_multicast(const unsigned char *p, int size, const char *mac);
int opendhcp_add_listener();
unsigned int opendhcp_set_lease_time();
int getHwAddr(char *buff, char *mac);
int arpSet(const char *ifname, char *ipStr, char *mac);
#if DISCOVER_RSP_NOT_BOARDCAST
sockaddr_in get_cliAddr(char *nicif, char *tempbuff, data9 *req);
#endif
void opendhcp_set_replication_svr();
void opendhcp_add_ip_pool_set();
void opendhcp_add_mac_filter();
int process_iptv_multicast(const unsigned char *p, int size, const char *mac);
int opendhcp_add_listener();
unsigned int opendhcp_set_lease_time();
int getHwAddr(char *buff, char *mac);
int arpSet(const char *ifname, char *ipStr, char *mac);
sockaddr_in get_cliAddr(char *nicif, char *tempbuff, data9 *req);
#pragma clang diagnostic pop

View File

@ -5,18 +5,14 @@
#include <map>
using namespace std;
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <net/if.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <memory.h>
#include <cstdlib>
#include "opendhcpd.h"
#include "s2j/cJSON.h"
#include "misc.h"
#include <net/if_arp.h>
#include <uv.h>
#include "config.h"
#include "proto.h"
@ -25,6 +21,13 @@ using namespace std;
#include "sds/sds.h"
#include "inet_misc.h"
#include "http_svr.h"
#include "task_manager.h"
#if DISCOVER_RSP_NOT_BOARDCAST
#include <sys/socket.h>
#include <unistd.h>
#include <net/if_arp.h>
#endif
extern data2 cfig;
extern bool kRunning;
@ -43,38 +46,90 @@ static PIPTV_DEV_SET g_iptvNewDevs = nullptr;
static PIPTV_DEV_SET g_iptvCacheDevs = nullptr;
static uv_rwlock_t g_uvCacheLock;
#ifdef JSON_SCHEMA_ON
// clang-format off
typedef struct {
const char *pSchJson;
const char *pErrMsg;
} JSON_POST_CTX;
static JSON_POST_CTX g_add_msg[] = {
{R"({"type":"object","required":["rangeSet"]})", "Missing required field [rangeSet]"},
{R"({"properties":{"rangeSet":{"type":"array","minItems":1}}})", "No content in array [rangeSet]"},
{R"({"properties":{"rangeSet":{"items":{"type":"object","required":["dhcpRange"]}}}})", "Missing required field [dhcpRange]"},
{R"({"properties":{"rangeSet":{"items":{"properties":{"netmask":{"type":"string"}}}}}})", "[netmask] should be a string value"},
{R"({"properties":{"rangeSet":{"items":{"properties":{"domainServer":{"type":"string"}}}}}})", "[domainServer] should be a string value"},
{R"({"properties":{"rangeSet":{"items":{"properties":{"gateway":{"type":"string"}}}}}})", "[gateway] should be a string value"},
{R"({"properties":{"rangeSet":{"items":{"properties":{"leaseTime":{"type":"integer"}}}}}})", "[leaseTime] should be an integer value"},
// {R"({"properties":{"rangeSet":{"items":{"properties":{"dhcpRange":{"type":"string","minLength":15}}}}}})", "Error in field [dhcpRange]"}
};
static JSON_POST_CTX g_del_msg[] = {
{R"({"type":"object","required":["dhcpRange"]})", "Missing required field [dhcpRange]"},
{R"({"properties":{"dhcpRange":{"type":"array","minItems":1}}})", "No content in field [dhcpRange]"},
// {R"({"properties":{"dhcpRange":{"items":{"type":"string","minLength":15}}}})", "Error in field [dhcpRange]"}
};
static JSON_POST_CTX g_que_msg[] = {
{R"({"type":"object","required":["userMac"]})", "Missing required field [userMac]"},
{R"({"properties":{"userMac":{"type":"array","minItems":1}}})", "No content in field [userMac]"},
// {R"({"properties":{"userMac":{"items":{"type":"string","minLength":17,"maxLength":17}}}})", "Error in field [userMac]"}
};
// clang-format on
#endif
static int dhcp_get_user_info(const char **pRsp, const char *pRequest) {
char logBuff[512];
const char *pStrContent;
int k;
int errCode = 0;
dhcpMap::iterator p;
if (pRequest == nullptr || strlen(pRequest) == 0) {
sprintf(logBuff, "Requeset Json");
sprintf(logBuff, "Request Json");
logDHCPMess(logBuff, 1);
return ERR_INPUT_PARAMS;
}
pStrContent = proto_decode_context(pRequest, nullptr, nullptr);
pStrContent = proto_decode_context(pRequest, nullptr, nullptr, &errCode);
if (pStrContent == nullptr) {
sprintf(logBuff, "Requeset Json error %s", pRequest);
sprintf(logBuff, "Request Json error %s", pRequest);
logDHCPMess(logBuff, 1);
free((void *)pStrContent);
return ERR_PROTO_DECODE;
}
#ifdef JSON_SCHEMA_ON
if (errCode == ERR_JSON_VALID_SCH) {
*pRsp = pStrContent;
return ERR_SUCCESS;
}
const char *pSchJson;
for(auto i : g_que_msg) {
pSchJson = proto_msg_validation(pStrContent, i.pSchJson, i.pErrMsg);
if (pSchJson != nullptr && strlen(pSchJson) > 0) {
*pRsp = pSchJson;
free((void *)pStrContent);
return ERR_SUCCESS;
}
}
free((void *)pSchJson);
#endif
cJSON *pRoot = cJSON_Parse(pStrContent);
free((void *)pStrContent);
if (!pRoot) {
return ERR_JSON_PRASE_OBJ;
return ERR_JSON_PARSE_OBJ;
}
cJSON *pUserMac = cJSON_GetObjectItem(pRoot, "userMac");
if (!pUserMac) {
cJSON_Delete(pRoot);
return ERR_JSON_PRASE_OBJ;
return ERR_JSON_PARSE_OBJ;
}
cJSON *pRspMsg = cJSON_CreateObject();
@ -318,26 +373,46 @@ static int add_dhcpd_rangeset(const char **pRsp, const char *pRequest) {
OBJ_DHCP_RNG range;
cJSON *pRspRoot;
cJSON *pExpandArray;
int errCode = 0;
if (pRequest == nullptr || strlen(pRequest) == 0) {
sprintf(logBuff, "Requeset Json");
sprintf(logBuff, "Request Json");
logDHCPMess(logBuff, 1);
return ERR_INPUT_PARAMS;
}
pStrContent = proto_decode_context(pRequest, nullptr, nullptr);
pStrContent = proto_decode_context(pRequest, nullptr, nullptr, &errCode);
if (pStrContent == nullptr) {
sprintf(logBuff, "Requeset Json error %s", pRequest);
sprintf(logBuff, "Request Json error %s", pRequest);
logDHCPMess(logBuff, 1);
free((void *)pStrContent);
return ERR_PROTO_DECODE;
}
#ifdef JSON_SCHEMA_ON
if (errCode == ERR_JSON_VALID_SCH) {
*pRsp = pStrContent;
return ERR_SUCCESS;
}
const char *pSchJson;
for(auto i : g_add_msg) {
pSchJson = proto_msg_validation(pStrContent, i.pSchJson, i.pErrMsg);
if (pSchJson != nullptr && strlen(pSchJson) > 0) {
*pRsp = pSchJson;
free((void *)pStrContent);
return ERR_SUCCESS;
}
}
free((void *)pSchJson);
#endif
cJSON *pRoot = cJSON_Parse(pStrContent);
free((void *)pStrContent);
if (!pRoot) {
return ERR_JSON_PRASE_OBJ;
return ERR_JSON_PARSE_OBJ;
}
cJSON *prange_set = cJSON_GetObjectItem(pRoot, "rangeSet");
@ -417,24 +492,44 @@ static int delete_dhcpd_rangeset(const char **pRsp, const char *pRequest) {
data13 dhcpRanges[MAX_DHCP_RANGES];
PHASH_MAP delMap = nullptr;
int resCount = 0;
int errCode = 0;
if (pRequest == nullptr || strlen(pRequest) == 0) {
sprintf(logBuff, "Requeset Json");
sprintf(logBuff, "Request Json");
logDHCPMess(logBuff, 1);
return ERR_INPUT_PARAMS;
}
pStrContent = proto_decode_context(pRequest, nullptr, nullptr);
pStrContent = proto_decode_context(pRequest, nullptr, nullptr, &errCode);
if (pStrContent == nullptr) {
sprintf(logBuff, "Requeset Json error %s", pRequest);
sprintf(logBuff, "Request Json error %s", pRequest);
logDHCPMess(logBuff, 1);
free((void*)pStrContent);
return ERR_PROTO_DECODE;
}
#ifdef JSON_SCHEMA_ON
if (errCode == ERR_JSON_VALID_SCH) {
*pRsp = pStrContent;
return ERR_SUCCESS;
}
const char *pSchJson;
for(auto i : g_del_msg) {
pSchJson = proto_msg_validation(pStrContent, i.pSchJson, i.pErrMsg);
if (pSchJson != nullptr && strlen(pSchJson) > 0) {
*pRsp = pSchJson;
free((void*)pStrContent);
return ERR_SUCCESS;
}
}
free((void*)pSchJson);
#endif
cJSON *pRoot = cJSON_Parse(pStrContent);
free((void *)pStrContent);
if (!pRoot) {
return ERR_JSON_PRASE_OBJ;
return ERR_JSON_PARSE_OBJ;
}
cJSON *pdhcp_range = cJSON_GetObjectItem(pRoot, "dhcpRange");
@ -443,11 +538,11 @@ static int delete_dhcpd_rangeset(const char **pRsp, const char *pRequest) {
pdelArray = cJSON_CreateArray();
cJSON_AddItemToObject(pRspRoot, "rangeSet", pdelArray);
char start[128];
char end[128];
char del_range[256];
for (int i = 0; i < cJSON_GetArraySize(pdhcp_range); i++) {
cJSON *pdel_Item = cJSON_CreateObject();
cJSON *pdelRange = cJSON_GetArrayItem(pdhcp_range, i);
char del_range[256];
auto *delItem = (PHASH_MAP)malloc(sizeof(HASH_MAP));
if (!pdelRange) {
continue;
@ -457,42 +552,40 @@ static int delete_dhcpd_rangeset(const char **pRsp, const char *pRequest) {
MYDWORD st_addr;
MYDWORD en_addr;
char start[128];
char end[128];
mySplit(start, end, del_range, '-');
st_addr = htonl(inet_addr(start));
en_addr = htonl(inet_addr(end));
if (en_addr == 0) {
cJSON_AddStringToObject(pdel_Item, "dhcpRange", del_range);
if(isIP(start) && isIP(end)) {
st_addr = htonl(inet_addr(start));
en_addr = htonl(inet_addr(end));
PHASH_MAP s;
HASH_FIND_INT(delMap, &st_addr, s);
if (s == nullptr) {
s = (PHASH_MAP)malloc(sizeof(HASH_MAP));
s->key = st_addr;
s->value = en_addr;
HASH_ADD_INT(delMap, key, s);
}
} else {
cJSON *pdel_Item = cJSON_CreateObject();
cJSON_AddStringToObject(pdel_Item, "dhcpRange", del_range);
cJSON_AddNumberToObject(pdel_Item, "status", ERR_INPUT_PARAMS);
cJSON_AddStringToObject(pdel_Item, "message", getErrorEnumDesc(ERR_INPUT_PARAMS));
cJSON_AddItemToArray(pdelArray, pdel_Item);
}
HASH_FIND_INT(delMap, &st_addr, delItem);
if (delItem == nullptr) {
auto *s = (PHASH_MAP)malloc(sizeof(HASH_MAP));
s->key = st_addr;
s->value = en_addr;
HASH_ADD_INT(delMap, key, s);
}
}
for (int i = 0; i < cfig.rangeCount; i++) {
cJSON *pdel_Item = cJSON_CreateObject();
PHASH_MAP delRange;
char del_range[256];
char saddr[128];
char eaddr[128];
memset(del_range, 0, 256);
HASH_FIND_INT(delMap, &cfig.dhcpRanges[i].rangeStart, delRange);
if (delRange != nullptr) {
IP2String(saddr, ntohl(delRange->key));
IP2String(eaddr, ntohl(delRange->value));
IP2String(start, ntohl(delRange->key));
IP2String(end, ntohl(delRange->value));
sprintf(del_range, "%s-%s", saddr, eaddr);
sprintf(del_range, "%s-%s", start, end);
cJSON_AddStringToObject(pdel_Item, "dhcpRange", del_range);
//Determine whether the input is correct or not
if (delRange->value == cfig.dhcpRanges[i].rangeEnd) {
@ -500,6 +593,9 @@ static int delete_dhcpd_rangeset(const char **pRsp, const char *pRequest) {
cJSON_AddStringToObject(pdel_Item, "message", getErrorEnumDesc(ERR_SUCCESS));
cJSON_AddItemToArray(pdelArray, pdel_Item);
free(cfig.dhcpRanges[i].options);
free(cfig.dhcpRanges[i].expiry);
free(cfig.dhcpRanges[i].dhcpEntry);
} else {
memcpy(&dhcpRanges[resCount], &cfig.dhcpRanges[i], sizeof(struct data13));
resCount++;
@ -509,32 +605,32 @@ static int delete_dhcpd_rangeset(const char **pRsp, const char *pRequest) {
}
HASH_DEL(delMap, delRange);
free(delRange);
} else {
memcpy(&dhcpRanges[resCount], &cfig.dhcpRanges[i], sizeof(struct data13));
resCount++;
cJSON_Delete(pdel_Item);
}
}
//The input parameter does not exist
if (resCount > cfig.rangeCount - cJSON_GetArraySize(pdhcp_range)) {
auto *s = (PHASH_MAP)malloc(sizeof(HASH_MAP));
PHASH_MAP tmp;
char saddr[128];
char eaddr[128];
char del_range[256];
memset(del_range, 0, 256);
PHASH_MAP s;
PHASH_MAP tmp;
memset(del_range, 0, 256);
HASH_ITER(hh, delMap, s, tmp) HASH_ITER(hh, delMap, s, tmp) {
cJSON *pdel_Item = cJSON_CreateObject();
IP2String(start, ntohl(s->key));
IP2String(end, ntohl(s->value));
HASH_ITER(hh, delMap, s, tmp) {
cJSON *pdel_Item = cJSON_CreateObject();
IP2String(saddr, ntohl(s->key));
IP2String(eaddr, ntohl(s->value));
sprintf(del_range, "%s-%s", start, end);
cJSON_AddStringToObject(pdel_Item, "dhcpRange", del_range);
sprintf(del_range, "%s-%s", saddr, eaddr);
cJSON_AddStringToObject(pdel_Item, "dhcpRange", del_range);
cJSON_AddNumberToObject(pdel_Item, "status", ERR_ITEM_UNEXISTS);
cJSON_AddStringToObject(pdel_Item, "message", getErrorEnumDesc(ERR_ITEM_UNEXISTS));
cJSON_AddItemToArray(pdelArray, pdel_Item);
cJSON_AddNumberToObject(pdel_Item, "status", ERR_ITEM_UNEXISTS);
cJSON_AddStringToObject(pdel_Item, "message", getErrorEnumDesc(ERR_ITEM_UNEXISTS));
cJSON_AddItemToArray(pdelArray, pdel_Item);
}
HASH_DEL(delMap, s);
free(s);
}
//Rewrite cfig.dhcpRanges
@ -658,6 +754,7 @@ int getHwAddr(char *buff, char *mac) {
#pragma clang diagnostic pop
#if DISCOVER_RSP_NOT_BOARDCAST
int arpSet(const char *ifname, char *ipStr, char *mac) {
if (ifname == nullptr || ipStr == nullptr || mac == nullptr) {
LOG_MOD(error, ZLOG_MOD_OPENDHCPD, "para is null.\n");
@ -707,6 +804,7 @@ sockaddr_in get_cliAddr(char *nicif, char *tempbuff, data9 *req) {
cliAddr.sin_addr.s_addr = inet_addr(IP2String(tempbuff, req->dhcpp.header.bp_yiaddr));
return cliAddr;
}
#endif
unsigned int opendhcp_set_lease_time() {
return config_get_dhcp_server_lease_time();
@ -749,60 +847,63 @@ static void on_http_response_cb(void *pData,
free(pUserData);
}
void iptvCacheCb(void *UNUSED(pArg)) {
do {
bool isReport = false;
const char *pUrl = config_get_agent_iptv_report_url();
PIPTV_DEV_SET report = nullptr;
PIPTV_DEV_SET pDev, pTmp = nullptr;
uv_rwlock_wrlock(&g_uvCacheLock);
HASH_ITER(hh, g_iptvNewDevs, pDev, pTmp) {
PIPTV_DEV_SET pTemp;
const char *pDevMac = strdup(pDev->iptvMAC);
HASH_FIND_STR(g_iptvCacheDevs, pDevMac, pTemp);
// 新发现设备没有被上报过
if (!pTemp) {
auto pCacheDev = (PIPTV_DEV_SET)malloc(sizeof(IPTV_DEV_SET));
memcpy(pCacheDev, pDev, sizeof(IPTV_DEV_SET));
HASH_ADD_STR(report, iptvMAC, pCacheDev);
void iptvCacheCb(uv_timer_t *UNUSED(pArg)) {
bool isReport = false;
const char *pUrl = config_get_agent_iptv_report_url();
PIPTV_DEV_SET report = nullptr;
PIPTV_DEV_SET pDev, pTmp = nullptr;
uv_rwlock_wrlock(&g_uvCacheLock);
HASH_ITER(hh, g_iptvNewDevs, pDev, pTmp) uv_sleep(10);
HASH_ITER(hh, report, pDev, pTmp) {
HASH_DEL(report, pDev);
free(pDev);
}
HASH_ITER(hh, report, pDev, pTmp) if (isReport && pUrl && strlen(pUrl) > 0) {
cJSON *pRspMsg = cJSON_CreateObject();
cJSON *pMsgArray = cJSON_CreateArray();
cJSON_AddItemToObject(pRspMsg, "iptvDevs", pMsgArray);
isReport = true;
// 添加到缓存列表供后续查询
HASH_ADD_STR(g_iptvCacheDevs, iptvMAC, pCacheDev);
LOG_MOD(debug,
ZLOG_MOD_OPENDHCPD,
"Add IPTV device %s vni %d to cache\n",
pCacheDev->iptvMAC,
pCacheDev->vni);
}
HASH_DEL(g_iptvNewDevs, pDev);
free(pDev);
free((void *)pDevMac);
}
uv_rwlock_wrunlock(&g_uvCacheLock);
if (isReport && pUrl && strlen(pUrl) > 0) {
cJSON *pRspMsg = cJSON_CreateObject();
cJSON *pMsgArray = cJSON_CreateArray();
cJSON_AddItemToObject(pRspMsg, "iptvDevs", pMsgArray);
HASH_ITER(hh, report, pDev, pTmp) {
cJSON *pRspItem = cJSON_CreateObject();
cJSON_AddStringToObject(pRspItem, "mac", pDev->iptvMAC);
cJSON_AddNumberToObject(pRspItem, "vni", pDev->vni);
pDev->isReport = 1;
cJSON_AddItemToArray(pMsgArray, pRspItem);
}
const char *pStrPro = proto_create_new(pRspMsg, 200);
// Report new IPTV device MAC
inet_http_post_async(pUrl, pStrPro, on_http_response_cb, (void *)pStrPro);
HASH_ITER(hh, report, pDev, pTmp) {
cJSON *pRspItem = cJSON_CreateObject();
cJSON_AddStringToObject(pRspItem, "mac", pDev->iptvMAC);
cJSON_AddNumberToObject(pRspItem, "vni", pDev->vni);
pDev->isReport = 1;
cJSON_AddItemToArray(pMsgArray, pRspItem);
}
uv_sleep(10);
} while (true);
const char *pStrPro = proto_create_new(pRspMsg, 200);
// Report new IPTV device MAC
inet_http_post_async(pUrl, pStrPro, on_http_response_cb, (void *)pStrPro);
}
uv_rwlock_wrunlock(&g_uvCacheLock);
HASH_ITER(hh, g_iptvNewDevs, pDev, pTmp) {
PIPTV_DEV_SET pTemp;
const char *pDevMac = strdup(pDev->iptvMAC);
HASH_FIND_STR(g_iptvCacheDevs, pDevMac, pTemp);
// 新发现设备没有被上报过
if (!pTemp) {
auto pCacheDev = (PIPTV_DEV_SET)malloc(sizeof(IPTV_DEV_SET));
auto pRepDev = (PIPTV_DEV_SET)malloc(sizeof(IPTV_DEV_SET));
memcpy(pCacheDev, pDev, sizeof(IPTV_DEV_SET));
memcpy(pRepDev, pDev, sizeof(IPTV_DEV_SET));
HASH_ADD_STR(report, iptvMAC, pRepDev);
isReport = true;
// 添加到缓存列表供后续查询
HASH_ADD_STR(g_iptvCacheDevs, iptvMAC, pCacheDev);
LOG_MOD(debug,
ZLOG_MOD_OPENDHCPD,
"Add IPTV device %s vni %d to cache\n",
pCacheDev->iptvMAC,
pCacheDev->vni);
}
HASH_DEL(g_iptvNewDevs, pDev);
free(pDev);
free((void *)pDevMac);
}
}
/**
@ -924,12 +1025,13 @@ static HTTP_ROUTE_INFO g_routeTable[] = {
};
void opendhcp_init_http_server() {
static int added = FALSE;
static uv_thread_t uvThread;
static int added = FALSE;
static uv_timer_t uvTm;
if (!added) {
uv_rwlock_init(&g_uvCacheLock);
uv_thread_create(&uvThread, iptvCacheCb, nullptr);
uv_timer_init(get_task_manager(), &uvTm);
uv_timer_start(&uvTm, iptvCacheCb, 1000, 1000);
for (auto &i : g_routeTable) {
PHTTP_ROUTE_INFO p = &i;
http_add_route(p->routeName, p->method, p->priority, p->cb, p->pUserData);

View File

@ -4,6 +4,7 @@
#include <uv.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include "cmdline.h"
#include "task_manager.h"
#include "init.h"
@ -76,7 +77,9 @@ static void on_http_response_cb(void *pData,
}
int main(int argc, char **argv) {
int ret;
int ret;
const char *pRspUrl;
#ifdef OPENDHCPDDNS_ON
return dual_server_main(argc, argv);
#else
@ -103,12 +106,19 @@ int main(int argc, char **argv) {
pppoe_session_init();
#endif
const char *pStrSetup = proto_create_new(create_app_process_status(1), 200);
inet_http_post_async(config_get_agent_moniter_report_url(), pStrSetup, on_http_response_cb, (void *)pStrSetup);
pRspUrl = config_get_agent_moniter_report_url();
if (pRspUrl && strlen(pRspUrl) > 0) {
const char *pStrSetup = proto_create_new(create_app_process_status(1), 200);
inet_http_post_async(config_get_agent_moniter_report_url(), pStrSetup, on_http_response_cb, (void *)pStrSetup);
}
task_manager_run();
const char *pStrExit = proto_create_new(create_app_process_status(0), 200);
inet_http_post_async(config_get_agent_moniter_report_url(), pStrSetup, on_http_response_cb, (void *)pStrExit);
if (pRspUrl && strlen(pRspUrl) > 0) {
const char *pStrExit = proto_create_new(create_app_process_status(0), 200);
inet_http_post_async(config_get_agent_moniter_report_url(), pStrExit, on_http_response_cb, (void *)pStrExit);
}
while (!is_system_cleanup()) {
sleep(1);

View File

@ -8,7 +8,7 @@ ADD_DEFINITIONS(-DPROJECT_NAME="${PROJECT_NAME}")
ADD_EXECUTABLE(${PROJECT_NAME} ${UTEST_SRC})
TARGET_LINK_LIBRARIES(${PROJECT_NAME} common)
TARGET_LINK_LIBRARIES(${PROJECT_NAME} common ${COMMON_LIBS})
#INCLUDE(CTest)
#INCLUDE(doctest)

View File

@ -0,0 +1,47 @@
//
// Created by dongwenzhe on 2023/3/14.
//
#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN
#include "doctest.h"
#include "crypto.h"
TEST_SUITE("Crypto functions") {
TEST_CASE("BASE64") {
auto *pSrc = (unsigned char *)"HELLOWORLD";
const char *encode;
encode = base64_encode(pSrc, 16);
INFO("BASE64_ENCODING:", encode);
unsigned char *decode;
unsigned int outputSize = 0;
decode = base64_decode(encode, &outputSize);
INFO("BASE64_DECODING:", decode);
for(int i = 0; i<outputSize; i++) {
CHECK_EQ(decode[i], pSrc[i]);
}
free((void *)encode);
free((void *)decode);
}
TEST_CASE("AES") {
AES_TYPE algoType = DES3_CBC_PKCS7PADDING;
const char *data = "hello world";
const char *key = "NmmW4zO4FCrhpugLaoBgjA==";
unsigned char *out;
unsigned char *res;
int outputSize = 0;
int resSize = 0;
symmetric_encrypto(algoType, (unsigned char *)data, strlen(data), &out, &outputSize, key);
CHECK_NE(out, nullptr);
symmetric_decrypto(algoType, out, outputSize, &res, &resSize, key);
CHECK_NE(res, nullptr);
REQUIRE_MESSAGE((strlen(data) == resSize), "the decrypted message:", res);
free((void *)out);
free((void *)res);
}
}

View File

@ -0,0 +1,20 @@
//
// Created by dongwenzhe on 2023/3/16.
//
#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN
#include "hardware.h"
#include "doctest.h"
TEST_SUITE("Hardware functions") {
TEST_CASE("CPU") {
PCPU_INFO cpuInfo;
memset(&cpuInfo, 0, sizeof(PCPU_INFO));
cpu_watch_init();
get_cpu_info(cpuInfo);
CHECK_NE(cpuInfo->nCores, 0);
CHECK_NE(cpuInfo->cpuUsed, 0);
CHECK_NE(cpuInfo->cpuCoreDesc.cpuName, nullptr);
}
}

View File

@ -0,0 +1,54 @@
//
// Created by xajhuang on 2023/2/23.
//
#include "doctest.h"
#ifdef __cplusplus
extern "C" {
#endif
#include "json_schema/jsoncdaccord.h"
#ifdef __cplusplus
}
#endif
TEST_SUITE("Json schema validator functions") {
TEST_CASE("JSONCDAC VALIDATOR") {
const char *json =
"{\n"
" \"ver\": 3,\n"
" \"cryptoType\": 0,\n"
" \"timeStamp\": 1599187216753,\n"
" \"msgContent\": {\n"
" \"rangeSet\": [\n"
" {\n"
" \"dhcpRange\": \"192.168.30.50-192.168.30.60\",\n"
" \"netmask\": \"255.255.255.0\",\n"
" \"domainServer\": \"114.114.114.114, 8.8.8.8\",\n"
" \"gateway\": \"192.168.30.1\",\n"
" \"leaseTime\": 420\n"
" }\n"
" ]\n"
" }\n"
"}";
const char *sch =
"{\n"
"\t\"type\": \"object\",\n"
"\t\"properties\": {\n"
"\t\t\"ver\": {\n"
"\t\t\t\"type\": \"string\"\t\t\t\n"
"\t\t}\n"
"\t},\n"
"\t\"required\": [\n"
" \"ver\"\n"
" ]\n"
"}";
json_object *pJs = json_tokener_parse(json);
json_object *pSc = json_tokener_parse(sch);
CHECK_NE(pJs, nullptr);
CHECK_NE(pSc, nullptr);
int ret = jdac_validate(pJs, pSc);
CHECK_EQ(JDAC_ERR_VALID, ret);
}
}

View File

@ -0,0 +1,58 @@
//
// Created by dongwenzhe on 2023/3/17.
//
#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN
#include "doctest.h"
#include "s2j/s2j.h"
typedef struct {
char info[16];
} Message;
typedef struct {
int id;
char name[16];
Message msg;
} Service;
TEST_SUITE("S2J_TEST") {
TEST_CASE("S2J") {
Service origin_Server;
origin_Server.id = 3;
strcpy(origin_Server.name, "dhcpServer");
strcpy(origin_Server.msg.info, "opendhcpd");
Service *pServer = &origin_Server;
s2j_create_json_obj(testServer);
s2j_json_set_basic_element(testServer, pServer, int, id);
s2j_json_set_basic_element(testServer, pServer, string, name);
s2j_json_set_struct_element(testInfo, testServer, pMsg, pServer, Message, msg);
s2j_json_set_basic_element(testInfo, pMsg, string, info);
int i;
CHECK_EQ(testServer->child->valueint, 3);
for(i = 0; i < strlen(origin_Server.name); i++) {
CHECK_EQ(origin_Server.name[i], testServer->child->next->valuestring[i]);
}
for(i = 0; i < strlen(origin_Server.msg.info); i++) {
CHECK_EQ(origin_Server.msg.info[i], testServer->child->next->next->child->valuestring[i]);
}
cJSON_Delete(testServer);
}
TEST_CASE("J2S") {
char originServer[] = R"({"id":3, "name":"dhcpServer", "message":{"info":"opendhcpd"}})";
cJSON *testServer = cJSON_Parse(originServer);
s2j_create_struct_obj(pServer, Service);
s2j_struct_get_basic_element(pServer, testServer, int, id);
s2j_struct_get_basic_element(pServer, testServer, string, name);
s2j_struct_get_struct_element(pMsg, pServer, testInfo, testServer, Message, msg);
s2j_struct_get_basic_element(pMsg, testInfo, string, info);
CHECK_EQ(pServer->id, 3);
cJSON_Delete(testServer);
free(pServer);
}
}

View File

@ -0,0 +1,51 @@
//
// Created by dongwenzhe on 2023/3/21.
//
#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN
#include "uthash/utarray.h"
#include "doctest.h"
typedef struct {
int a;
char *b;
} COMBO,*PCOMBO;
UT_icd ut_combo_icd = {sizeof(COMBO), nullptr, nullptr, nullptr};
TEST_SUITE("UTArray") {
UT_array *nums;
COMBO t_combo;
TEST_CASE("PUSH") {
PCOMBO p_combo;
memset(&p_combo, 0, sizeof(PCOMBO));
utarray_new(nums, &ut_combo_icd);
t_combo.a = 1;
t_combo.b = "hello ";
utarray_push_back(nums, &t_combo);
t_combo.a = 2;
t_combo.b = "world";
utarray_push_back(nums, &t_combo);
while((PCOMBO)utarray_next(nums, p_combo) != nullptr) {
p_combo = (PCOMBO)utarray_next(nums, p_combo);
MESSAGE("COMBO:", p_combo->a);
MESSAGE(doctest::String(p_combo->b));
}
}
TEST_CASE("POP") {
PCOMBO p_combo;
memset(&p_combo, 0, sizeof(PCOMBO));
MESSAGE("original len: ", utarray_len(nums));
while(utarray_len(nums) != 0) {
p_combo = (PCOMBO)utarray_next(nums, p_combo);
utarray_pop_back(nums);
MESSAGE("len: ", utarray_len(nums));
}
utarray_free(nums);
}
}

View File

@ -0,0 +1,46 @@
//
// Created by dongwenzhe on 2023/3/21.
//
//#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN
#include "uthash/utstring.h"
#include "doctest.h"
TEST_SUITE("UTString") {
TEST_CASE("Append") {
UT_string *s;
UT_string *t;
utstring_new(s);
utstring_new(t);
utstring_printf(s, "hello ");
utstring_printf(t, "world");
utstring_concat(s, t);
char *body = utstring_body(s);
MESSAGE(doctest::String(body));
CHECK(doctest::String(body) == "hello world");
utstring_free(s);
utstring_free(t);
}
TEST_CASE("Binary") {
UT_string *s;
utstring_new(s);
utstring_printf(s, "hello world");
MESSAGE(utstring_len(s));
char binary[] = "\xff\xff";
utstring_bincpy(s, binary, sizeof(binary));
MESSAGE(utstring_len(s));
char *body = utstring_body(s);
MESSAGE(doctest::String(body));
utstring_clear(s);
utstring_free(s);
}
}