Compare commits

...

13 Commits

Author SHA1 Message Date
qazmko1029
3d206b130a
Merge e46039adb9 into d0efd9ef7b 2024-02-20 13:47:22 +08:00
Simon Goldschmidt
d0efd9ef7b tcpip: fix that TCPIP_CORE_LOCK is not released for LWIP_TIMERS==0
See bug #65328

Signed-off-by: Simon Goldschmidt <goldsimon@gmx.de>
2024-02-19 21:44:18 +01:00
Krzysztof Mazur
e799c266fa makefsdata: extend file type matching with .shtml and .shtm
[Problem]
When using makefsdata perl script to convert shtml files with SSI tags
the shtml files get generated with text/plain content type, making
browsers not render them correctly

[Solution]
Extend the regex to generate text/html content type for any of:
.htm, .html, .shtm, .shtml extensions
2024-02-19 20:58:58 +01:00
Brian
cb511019b0 Update codeql-buildscript.sh
Adding install dependencies step
2024-02-19 20:03:32 +01:00
Brian
9004e7bd77 Add CodeQL Workflow for Code Security Analysis
Add CodeQL Workflow for Code Security Analysis

This pull request introduces a CodeQL workflow to enhance the security analysis of our repository. CodeQL is a powerful static analysis tool that helps identify and mitigate security vulnerabilities in our codebase. By integrating this workflow into our GitHub Actions, we can proactively identify and address potential issues before they become security threats.

We added a new CodeQL workflow file (.github/workflows/codeql.yml) that
- Runs on every pull request (functionality to run on every push to main branches is included as a comment for convenience).
- Runs daily.
- Excludes queries with a high false positive rate or low-severity findings.
- Does not display results for git submodules, focusing only on our own codebase.

Testing:
To validate the functionality of this workflow, we have run several test scans on the codebase and reviewed the results. The workflow successfully compiles the project, identifies issues, and provides actionable insights while reducing noise by excluding certain queries and third-party code.

Deployment:
Once this pull request is merged, the CodeQL workflow will be active and automatically run on every push and pull request to the main branch. To view the results of these code scans, please follow these steps:
1. Under the repository name, click on the Security tab.
2. In the left sidebar, click Code scanning alerts.

Additional Information:
- You can further customize the workflow to adapt to your specific needs by modifying the workflow file.
- For more information on CodeQL and how to interpret its results, refer to the GitHub documentation and the CodeQL documentation (https://codeql.github.com/ and https://codeql.github.com/docs/).

Signed-off-by: Brian <bayuan@purdue.edu>
2024-02-19 20:03:32 +01:00
Brian
17b1f5d382 Add CodeQL Workflow for Code Security Analysis
Add CodeQL Workflow for Code Security Analysis

This pull request introduces a CodeQL workflow to enhance the security analysis of our repository. CodeQL is a powerful static analysis tool that helps identify and mitigate security vulnerabilities in our codebase. By integrating this workflow into our GitHub Actions, we can proactively identify and address potential issues before they become security threats.

We added a new CodeQL workflow file (.github/workflows/codeql.yml) that
- Runs on every pull request (functionality to run on every push to main branches is included as a comment for convenience).
- Runs daily.
- Excludes queries with a high false positive rate or low-severity findings.
- Does not display results for git submodules, focusing only on our own codebase.

Testing:
To validate the functionality of this workflow, we have run several test scans on the codebase and reviewed the results. The workflow successfully compiles the project, identifies issues, and provides actionable insights while reducing noise by excluding certain queries and third-party code.

Deployment:
Once this pull request is merged, the CodeQL workflow will be active and automatically run on every push and pull request to the main branch. To view the results of these code scans, please follow these steps:
1. Under the repository name, click on the Security tab.
2. In the left sidebar, click Code scanning alerts.

Additional Information:
- You can further customize the workflow to adapt to your specific needs by modifying the workflow file.
- For more information on CodeQL and how to interpret its results, refer to the GitHub documentation and the CodeQL documentation (https://codeql.github.com/ and https://codeql.github.com/docs/).

Signed-off-by: Brian <bayuan@purdue.edu>
2024-02-19 20:03:32 +01:00
Brian
10dc9b7eb3 Add CodeQL Workflow for Code Security Analysis
Add CodeQL Workflow for Code Security Analysis

This pull request introduces a CodeQL workflow to enhance the security analysis of our repository. CodeQL is a powerful static analysis tool that helps identify and mitigate security vulnerabilities in our codebase. By integrating this workflow into our GitHub Actions, we can proactively identify and address potential issues before they become security threats.

We added a new CodeQL workflow file (.github/workflows/codeql.yml) that
- Runs on every pull request (functionality to run on every push to main branches is included as a comment for convenience).
- Runs daily.
- Excludes queries with a high false positive rate or low-severity findings.
- Does not display results for git submodules, focusing only on our own codebase.

Testing:
To validate the functionality of this workflow, we have run several test scans on the codebase and reviewed the results. The workflow successfully compiles the project, identifies issues, and provides actionable insights while reducing noise by excluding certain queries and third-party code.

Deployment:
Once this pull request is merged, the CodeQL workflow will be active and automatically run on every push and pull request to the main branch. To view the results of these code scans, please follow these steps:
1. Under the repository name, click on the Security tab.
2. In the left sidebar, click Code scanning alerts.

Additional Information:
- You can further customize the workflow to adapt to your specific needs by modifying the workflow file.
- For more information on CodeQL and how to interpret its results, refer to the GitHub documentation and the CodeQL documentation (https://codeql.github.com/ and https://codeql.github.com/docs/).

Signed-off-by: Brian <bayuan@purdue.edu>
2024-02-19 20:03:32 +01:00
Brian
c3d6fe9d72 Add CodeQL Workflow for Code Security Analysis
Add CodeQL Workflow for Code Security Analysis

This pull request introduces a CodeQL workflow to enhance the security analysis of our repository. CodeQL is a powerful static analysis tool that helps identify and mitigate security vulnerabilities in our codebase. By integrating this workflow into our GitHub Actions, we can proactively identify and address potential issues before they become security threats.

We added a new CodeQL workflow file (.github/workflows/codeql.yml) that
- Runs on every push and pull request to the main branch.
- Excludes queries with a high false positive rate or low-severity findings.
- Does not display results for third-party code, focusing only on our own codebase.

Testing:
To validate the functionality of this workflow, we have run several test scans on the codebase and reviewed the results. The workflow successfully compiles the project, identifies issues, and provides actionable insights while reducing noise by excluding certain queries and third-party code.

Deployment:
Once this pull request is merged, the CodeQL workflow will be active and automatically run on every push and pull request to the main branch. To view the results of these code scans, please follow these steps:
1. Under the repository name, click on the Security tab.
2. In the left sidebar, click Code scanning alerts.

Additional Information:
- You can further customize the workflow to adapt to your specific needs by modifying the workflow file.
- For more information on CodeQL and how to interpret its results, refer to the GitHub documentation and the CodeQL documentation.

Signed-off-by: Brian <bayuan@purdue.edu>
2024-02-19 20:03:32 +01:00
Kirill Lokotkov
93821fc437 Fixed netdb.c when LWIP_SOCKET_HAVE_SA_LEN == 0
Fields sin6_len and sin_len are always used in the file but not all implementations of sockaddr_in or sockaddr_in6 have this fields (including Linux implementation).
Added #if-check to avoid compilation errors in such cases.
2024-02-19 18:13:28 +01:00
Kirill Lokotkov
7c494b3829 Added "lwip/errno.h" to netdb.c includes
Defines EINVAL and ERANGE are used in the file but not included directly. When I try to use <sys/socket.h> and <arpa/inet.h> as LWIP_SOCKET_EXTERNAL_HEADERS it causes errors with this defines.
2024-02-19 18:13:28 +01:00
qazmko1029
e46039adb9 snmp: forgot to change OID length 2023-12-30 23:30:06 +08:00
qazmko1029
5c8a07cd87 LwipMibCompiler: compile read-create object as read-write in generated C code 2023-12-30 23:19:59 +08:00
qazmko1029
53c3e8165a snmp: fix SNMPv2 generic trap ID and special varbinds OID to send according to rfc3584 2023-12-30 23:15:52 +08:00
8 changed files with 198 additions and 18 deletions

View File

@ -0,0 +1,6 @@
#!/usr/bin/env bash
sudo apt-get install check ninja-build doxygen
cp contrib/examples/example_app/lwipcfg.h.ci contrib/examples/example_app/lwipcfg.h
make -C contrib/ports/unix/check
mkdir build && cd build && cmake .. -G Ninja && cmake --build .

126
.github/workflows/codeql.yml vendored Normal file
View File

@ -0,0 +1,126 @@
# For most projects, this workflow file will not need changing; you simply need
# to commit it to your repository.
#
# You may wish to alter this file to override the set of languages analyzed,
# or to provide custom queries or build logic.
#
# ******** NOTE ********
# We have attempted to detect the languages in your repository. Please check
# the `language` matrix defined below to confirm you have the correct set of
# supported CodeQL languages.
#
name: "CodeQL"
on:
# push:
# branches: [ "main", "master" ]
schedule:
- cron: '0 0 * * *'
pull_request:
branches: '*'
jobs:
analyze:
name: Analyze
# Runner size impacts CodeQL analysis time. To learn more, please see:
# - https://gh.io/recommended-hardware-resources-for-running-codeql
# - https://gh.io/supported-runners-and-hardware-resources
# - https://gh.io/using-larger-runners
# Consider using larger runners for possible analysis time improvements.
runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-20.04' }}
timeout-minutes: ${{ (matrix.language == 'swift' && 120) || 360 }}
permissions:
actions: read
contents: read
security-events: write
strategy:
fail-fast: false
matrix:
language: [ 'cpp' ]
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby', 'swift' ]
# Use only 'java' to analyze code written in Java, Kotlin or both
# Use only 'javascript' to analyze code written in JavaScript, TypeScript or both
# Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support
steps:
- name: Checkout repository
uses: actions/checkout@v3
with:
submodules: recursive
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.
# For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
# queries: security-extended,security-and-quality
queries: security-and-quality
# Autobuild attempts to build any compiled languages (C/C++, C#, Go, Java, or Swift).
# If this step fails, then you should remove it and run the build manually (see below)
#- name: Autobuild
# uses: github/codeql-action/autobuild@v2
# Command-line programs to run using the OS shell.
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
# If the Autobuild fails above, remove it and uncomment the following three lines.
# modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.
- run: |
./.github/workflows/codeql-buildscript.sh
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
with:
category: "/language:${{matrix.language}}"
upload: false
id: step1
# Filter out rules with low severity or high false positve rate
# Also filter out warnings in third-party code
- name: Filter out unwanted errors and warnings
uses: advanced-security/filter-sarif@v1
with:
patterns: |
-**:cpp/path-injection
-**:cpp/world-writable-file-creation
-**:cpp/poorly-documented-function
-**:cpp/potentially-dangerous-function
-**:cpp/use-of-goto
-**:cpp/integer-multiplication-cast-to-long
-**:cpp/comparison-with-wider-type
-**:cpp/leap-year/*
-**:cpp/ambiguously-signed-bit-field
-**:cpp/suspicious-pointer-scaling
-**:cpp/suspicious-pointer-scaling-void
-**:cpp/unsigned-comparison-zero
-**/cmake*/Modules/**
input: ${{ steps.step1.outputs.sarif-output }}/cpp.sarif
output: ${{ steps.step1.outputs.sarif-output }}/cpp.sarif
- name: Upload CodeQL results to code scanning
uses: github/codeql-action/upload-sarif@v2
with:
sarif_file: ${{ steps.step1.outputs.sarif-output }}
category: "/language:${{matrix.language}}"
- name: Upload CodeQL results as an artifact
if: success() || failure()
uses: actions/upload-artifact@v3
with:
name: codeql-results
path: ${{ steps.step1.outputs.sarif-output }}
retention-days: 5
- name: Fail if an error is found
run: |
./.github/workflows/fail_on_error.py \
${{ steps.step1.outputs.sarif-output }}/cpp.sarif

34
.github/workflows/fail_on_error.py vendored Executable file
View File

@ -0,0 +1,34 @@
#!/usr/bin/env python3
import json
import sys
# Return whether SARIF file contains error-level results
def codeql_sarif_contain_error(filename):
with open(filename, 'r') as f:
s = json.load(f)
for run in s.get('runs', []):
rules_metadata = run['tool']['driver']['rules']
if not rules_metadata:
rules_metadata = run['tool']['extensions'][0]['rules']
for res in run.get('results', []):
if 'ruleIndex' in res:
rule_index = res['ruleIndex']
elif 'rule' in res and 'index' in res['rule']:
rule_index = res['rule']['index']
else:
continue
try:
rule_level = rules_metadata[rule_index]['defaultConfiguration']['level']
except IndexError as e:
print(e, rule_index, len(rules_metadata))
else:
if rule_level == 'error':
return True
return False
if __name__ == "__main__":
if codeql_sarif_contain_error(sys.argv[1]):
sys.exit(1)

View File

@ -74,7 +74,7 @@ namespace LwipMibCompiler
string mibFileName = Path.GetFileNameWithoutExtension(mibFile).ToLowerInvariant(); string mibFileName = Path.GetFileNameWithoutExtension(mibFile).ToLowerInvariant();
destFile = Path.Combine(destFile, mibFileName + ".c"); destFile = Path.Combine(destFile, mibFileName + ".c");
} }
string destFileExt = Path.GetExtension(destFile); string destFileExt = Path.GetExtension(destFile);
if (!String.IsNullOrEmpty(destFileExt)) if (!String.IsNullOrEmpty(destFileExt))
{ {
@ -94,10 +94,10 @@ namespace LwipMibCompiler
} }
} }
// read and resolve MIB // read and resolve MIB
Console.WriteLine(" Reading MIB file..."); Console.WriteLine(" Reading MIB file...");
MibDocument md = new MibDocument(mibFile); MibDocument md = new MibDocument(mibFile);
MibTypesResolver.ResolveTypes(md.Modules[0]); MibTypesResolver.ResolveTypes(md.Modules[0]);
MibTree mt = new MibTree(md.Modules[0] as MibModule); MibTree mt = new MibTree(md.Modules[0] as MibModule);
@ -335,7 +335,7 @@ namespace LwipMibCompiler
{ {
Console.WriteLine(String.Format("Unsupported BaseType: Module='{0}', Name='{1}'!", mibType.Module, mibType.Name)); Console.WriteLine(String.Format("Unsupported BaseType: Module='{0}', Name='{1}'!", mibType.Module, mibType.Name));
} }
return null; return null;
} }
} }
@ -353,7 +353,7 @@ namespace LwipMibCompiler
} }
else if (ote.Access == MaxAccess.readCreate) else if (ote.Access == MaxAccess.readCreate)
{ {
result.AccessMode = SnmpAccessMode.ReadOnly; result.AccessMode = SnmpAccessMode.ReadWrite;
} }
else if (ignoreAccessibleFlag && (ote.Access == MaxAccess.notAccessible)) else if (ignoreAccessibleFlag && (ote.Access == MaxAccess.notAccessible))
{ {
@ -426,7 +426,7 @@ namespace LwipMibCompiler
} }
MibTreeNode rowNode = mibTreeNode.ChildNodes[0]; MibTreeNode rowNode = mibTreeNode.ChildNodes[0];
ObjectType rot = rowNode.Entity as ObjectType; ObjectType rot = rowNode.Entity as ObjectType;
if (rot != null) if (rot != null)
{ {

View File

@ -40,6 +40,7 @@
#if LWIP_DNS && LWIP_SOCKET #if LWIP_DNS && LWIP_SOCKET
#include "lwip/err.h" #include "lwip/err.h"
#include "lwip/errno.h"
#include "lwip/mem.h" #include "lwip/mem.h"
#include "lwip/memp.h" #include "lwip/memp.h"
#include "lwip/ip_addr.h" #include "lwip/ip_addr.h"
@ -382,7 +383,9 @@ lwip_getaddrinfo(const char *nodename, const char *servname,
/* set up sockaddr */ /* set up sockaddr */
inet6_addr_from_ip6addr(&sa6->sin6_addr, ip_2_ip6(&addr)); inet6_addr_from_ip6addr(&sa6->sin6_addr, ip_2_ip6(&addr));
sa6->sin6_family = AF_INET6; sa6->sin6_family = AF_INET6;
#if LWIP_SOCKET_HAVE_SA_LEN
sa6->sin6_len = sizeof(struct sockaddr_in6); sa6->sin6_len = sizeof(struct sockaddr_in6);
#endif /* LWIP_SOCKET_HAVE_SA_LEN */
sa6->sin6_port = lwip_htons((u16_t)port_nr); sa6->sin6_port = lwip_htons((u16_t)port_nr);
sa6->sin6_scope_id = ip6_addr_zone(ip_2_ip6(&addr)); sa6->sin6_scope_id = ip6_addr_zone(ip_2_ip6(&addr));
ai->ai_family = AF_INET6; ai->ai_family = AF_INET6;
@ -393,7 +396,9 @@ lwip_getaddrinfo(const char *nodename, const char *servname,
/* set up sockaddr */ /* set up sockaddr */
inet_addr_from_ip4addr(&sa4->sin_addr, ip_2_ip4(&addr)); inet_addr_from_ip4addr(&sa4->sin_addr, ip_2_ip4(&addr));
sa4->sin_family = AF_INET; sa4->sin_family = AF_INET;
#if LWIP_SOCKET_HAVE_SA_LEN
sa4->sin_len = sizeof(struct sockaddr_in); sa4->sin_len = sizeof(struct sockaddr_in);
#endif /* LWIP_SOCKET_HAVE_SA_LEN */
sa4->sin_port = lwip_htons((u16_t)port_nr); sa4->sin_port = lwip_htons((u16_t)port_nr);
ai->ai_family = AF_INET; ai->ai_family = AF_INET;
#endif /* LWIP_IPV4 */ #endif /* LWIP_IPV4 */

View File

@ -68,11 +68,20 @@ sys_mutex_t lock_tcpip_core;
static void tcpip_thread_handle_msg(struct tcpip_msg *msg); static void tcpip_thread_handle_msg(struct tcpip_msg *msg);
#if !LWIP_TIMERS #if !LWIP_TIMERS
/* wait for a message with timers disabled (e.g. pass a timer-check trigger into tcpip_thread) */
#define TCPIP_MBOX_FETCH(mbox, msg) sys_mbox_fetch(mbox, msg) /** Wait for a message with timers disabled (e.g. pass a timer-check trigger into tcpip_thread) */
static void
tcpip_mbox_fetch(sys_mbox_t* mbox, void** msg)
{
LWIP_ASSERT_CORE_LOCKED();
UNLOCK_TCPIP_CORE();
sys_mbox_fetch(mbox, msg);
LOCK_TCPIP_CORE();
}
#else /* !LWIP_TIMERS */ #else /* !LWIP_TIMERS */
/* wait for a message, timeouts are processed while waiting */
#define TCPIP_MBOX_FETCH(mbox, msg) tcpip_timeouts_mbox_fetch(mbox, msg)
/** /**
* Wait (forever) for a message to arrive in an mbox. * Wait (forever) for a message to arrive in an mbox.
* While waiting, timeouts are processed. * While waiting, timeouts are processed.
@ -81,7 +90,7 @@ static void tcpip_thread_handle_msg(struct tcpip_msg *msg);
* @param msg the place to store the message * @param msg the place to store the message
*/ */
static void static void
tcpip_timeouts_mbox_fetch(sys_mbox_t *mbox, void **msg) tcpip_mbox_fetch(sys_mbox_t *mbox, void **msg)
{ {
u32_t sleeptime, res; u32_t sleeptime, res;
@ -139,7 +148,7 @@ tcpip_thread(void *arg)
while (1) { /* MAIN Loop */ while (1) { /* MAIN Loop */
LWIP_TCPIP_THREAD_ALIVE(); LWIP_TCPIP_THREAD_ALIVE();
/* wait for a message, timeouts are processed while waiting */ /* wait for a message, timeouts are processed while waiting */
TCPIP_MBOX_FETCH(&tcpip_mbox, (void **)&msg); tcpip_mbox_fetch(&tcpip_mbox, (void **)&msg);
if (msg == NULL) { if (msg == NULL) {
LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: invalid message: NULL\n")); LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: invalid message: NULL\n"));
LWIP_ASSERT("tcpip_thread: invalid message", 0); LWIP_ASSERT("tcpip_thread: invalid message", 0);

View File

@ -21,7 +21,7 @@ while($file = <FILES>) {
print(HEADER "HTTP/1.0 200 OK\r\n"); print(HEADER "HTTP/1.0 200 OK\r\n");
} }
print(HEADER "Server: lwIP/pre-0.6 (http://www.sics.se/~adam/lwip/)\r\n"); print(HEADER "Server: lwIP/pre-0.6 (http://www.sics.se/~adam/lwip/)\r\n");
if($file =~ /\.html$/) { if($file =~ /\.s?html?$/) {
print(HEADER "Content-type: text/html\r\n"); print(HEADER "Content-type: text/html\r\n");
} elsif($file =~ /\.gif$/) { } elsif($file =~ /\.gif$/) {
print(HEADER "Content-type: image/gif\r\n"); print(HEADER "Content-type: image/gif\r\n");

View File

@ -256,7 +256,7 @@ snmp_prepare_trap_oid(struct snmp_obj_id *dest_snmp_trap_oid, const struct snmp_
if (sizeof(dest_snmp_trap_oid->id) >= sizeof(snmpTrapOID)) { if (sizeof(dest_snmp_trap_oid->id) >= sizeof(snmpTrapOID)) {
MEMCPY(&dest_snmp_trap_oid->id, snmpTrapOID , sizeof(snmpTrapOID)); MEMCPY(&dest_snmp_trap_oid->id, snmpTrapOID , sizeof(snmpTrapOID));
dest_snmp_trap_oid->len = LWIP_ARRAYSIZE(snmpTrapOID); dest_snmp_trap_oid->len = LWIP_ARRAYSIZE(snmpTrapOID);
dest_snmp_trap_oid->id[dest_snmp_trap_oid->len++] = specific_trap + 1; dest_snmp_trap_oid->id[dest_snmp_trap_oid->len++] = generic_trap + 1;
} else { } else {
err = ERR_MEM; err = ERR_MEM;
} }
@ -359,8 +359,8 @@ snmp_send_trap_or_notification_or_inform_generic(struct snmp_msg_trap *trap_msg,
NULL, /* *next */ NULL, /* *next */
NULL, /* *prev */ NULL, /* *prev */
{ /* oid */ { /* oid */
8, /* oid len */ 9, /* oid len */
{1, 3, 6, 1, 2, 1, 1, 3} /* oid for sysUpTime */ {1, 3, 6, 1, 2, 1, 1, 3, 0} /* oid for sysUpTime.0 */
}, },
SNMP_ASN1_TYPE_TIMETICKS, /* type */ SNMP_ASN1_TYPE_TIMETICKS, /* type */
sizeof(u32_t), /* value_len */ sizeof(u32_t), /* value_len */
@ -371,8 +371,8 @@ snmp_send_trap_or_notification_or_inform_generic(struct snmp_msg_trap *trap_msg,
NULL, /* *next */ NULL, /* *next */
NULL, /* *prev */ NULL, /* *prev */
{ /* oid */ { /* oid */
10, /* oid len */ 11, /* oid len */
{1, 3, 6, 1, 6, 3, 1, 1, 4, 1} /* oid for snmpTrapOID */ {1, 3, 6, 1, 6, 3, 1, 1, 4, 1, 0} /* oid for snmpTrapOID.0 */
}, },
SNMP_ASN1_TYPE_OBJECT_ID, /* type */ SNMP_ASN1_TYPE_OBJECT_ID, /* type */
0, /* value_len */ 0, /* value_len */