mirror of
https://github.com/drasko/open-ameba.git
synced 2024-11-25 15:34:18 +00:00
update
This commit is contained in:
parent
629e5fdc28
commit
bd42ffa334
212 changed files with 35447 additions and 223 deletions
BIN
RTL00_SDKV35a/component/common/api/at_cmd/atcmd_sys.zip
Normal file
BIN
RTL00_SDKV35a/component/common/api/at_cmd/atcmd_sys.zip
Normal file
Binary file not shown.
|
@ -90,7 +90,7 @@
|
||||||
#define printf DiagPrintfPatch
|
#define printf DiagPrintfPatch
|
||||||
#define sprintf DiagSPrintfPatch
|
#define sprintf DiagSPrintfPatch
|
||||||
#define snprintf DiagSnPrintfPatch
|
#define snprintf DiagSnPrintfPatch
|
||||||
#define strstr(a, b) DiagStrstrPatch((char *)(a), (char *)(b))
|
#define strstr(a, b) DiagStrstrPatch((char *)(a), (char *)(b))
|
||||||
#define strtok DiagStrtokPatch
|
#define strtok DiagStrtokPatch
|
||||||
#else
|
#else
|
||||||
#define printf DiagPrintf
|
#define printf DiagPrintf
|
||||||
|
|
|
@ -44,6 +44,10 @@ typedef signed short int s16;
|
||||||
typedef unsigned char bool;
|
typedef unsigned char bool;
|
||||||
|
|
||||||
|
|
||||||
|
extern u8 txt0123456789ABCDEF[16];
|
||||||
|
#define tab0123456789ABCDEF txt0123456789ABCDEF // = "0123456789ABCDEF"
|
||||||
|
|
||||||
|
|
||||||
#define in_range(c, lo, up) ((u8)c >= lo && (u8)c <= up)
|
#define in_range(c, lo, up) ((u8)c >= lo && (u8)c <= up)
|
||||||
#define isprint(c) in_range(c, 0x20, 0x7f)
|
#define isprint(c) in_range(c, 0x20, 0x7f)
|
||||||
#define isdigit(c) in_range(c, '0', '9')
|
#define isdigit(c) in_range(c, '0', '9')
|
||||||
|
@ -644,7 +648,7 @@ int DiagSnPrintfPatch(char *buf, size_t size, const char *fmt, ...)
|
||||||
shift = (hex_count - 1)*4;
|
shift = (hex_count - 1)*4;
|
||||||
|
|
||||||
for(; shift >= 0; shift -= 4)
|
for(; shift >= 0; shift -= 4)
|
||||||
*q++ = "0123456789ABCDEF"[(h >> shift) & 0xF] | ncase;
|
*q++ = tab0123456789ABCDEF[(h >> shift) & 0xF] | ncase;
|
||||||
}
|
}
|
||||||
else if(*fmt == 'd') {
|
else if(*fmt == 'd') {
|
||||||
int i = *dp++;
|
int i = *dp++;
|
||||||
|
@ -825,7 +829,7 @@ static int VSprintfPatch(char *buf, const char *fmt, const int *dp)
|
||||||
|
|
||||||
for(; shift >= 0; shift -= 4) {
|
for(; shift >= 0; shift -= 4) {
|
||||||
|
|
||||||
*q++ = "0123456789ABCDEF"[(h >> shift) & 0xF] | ncase;
|
*q++ = tab0123456789ABCDEF[(h >> shift) & 0xF] | ncase;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,7 +35,7 @@ const unsigned char *eap_client_cert = NULL;
|
||||||
const unsigned char *eap_client_key = NULL;
|
const unsigned char *eap_client_key = NULL;
|
||||||
char *eap_client_key_pwd = NULL;
|
char *eap_client_key_pwd = NULL;
|
||||||
|
|
||||||
//int max_buf_bio_size = SSL_BUFFER_LEN;
|
//int max_buf_bio_size = SSL_BUFFER_LEN; // ?pvvx?
|
||||||
|
|
||||||
#ifdef CONFIG_ENABLE_EAP
|
#ifdef CONFIG_ENABLE_EAP
|
||||||
void eap_eapol_recvd_hdl(char *buf, int buf_len, int flags, void* handler_user_data);
|
void eap_eapol_recvd_hdl(char *buf, int buf_len, int flags, void* handler_user_data);
|
||||||
|
|
|
@ -978,7 +978,7 @@ u8 OTU_check_gpio(void)
|
||||||
GPIO_Pin.pin_name = HAL_GPIO_GetIPPinName_8195a(0x21); //pin PC_1
|
GPIO_Pin.pin_name = HAL_GPIO_GetIPPinName_8195a(0x21); //pin PC_1
|
||||||
GPIO_Pin.pin_mode = DIN_PULL_HIGH;
|
GPIO_Pin.pin_mode = DIN_PULL_HIGH;
|
||||||
|
|
||||||
_pHAL_Gpio_Adapter = &gBoot_Gpio_Adapter;
|
// _pHAL_Gpio_Adapter = &gBoot_Gpio_Adapter;
|
||||||
|
|
||||||
HAL_GPIO_Init_8195a(&GPIO_Pin);
|
HAL_GPIO_Init_8195a(&GPIO_Pin);
|
||||||
if (HAL_GPIO_ReadPin_8195a(&GPIO_Pin) == GPIO_PIN_LOW) {
|
if (HAL_GPIO_ReadPin_8195a(&GPIO_Pin) == GPIO_PIN_LOW) {
|
||||||
|
@ -989,7 +989,7 @@ u8 OTU_check_gpio(void)
|
||||||
}
|
}
|
||||||
HAL_GPIO_DeInit_8195a(&GPIO_Pin);
|
HAL_GPIO_DeInit_8195a(&GPIO_Pin);
|
||||||
|
|
||||||
_pHAL_Gpio_Adapter = NULL;
|
// _pHAL_Gpio_Adapter = NULL;
|
||||||
return enter_update;
|
return enter_update;
|
||||||
#else
|
#else
|
||||||
return 0;
|
return 0;
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,174 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||||
|
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||||
|
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
|
* OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* This file is part of the lwIP TCP/IP stack.
|
||||||
|
*
|
||||||
|
* Author: Adam Dunkels <adam@sics.se>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "lwip/apps/httpd_opts.h"
|
||||||
|
#include "lwip/def.h"
|
||||||
|
#include "lwip/apps/fs.h"
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
|
||||||
|
#include HTTPD_FSDATA_FILE
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if LWIP_HTTPD_CUSTOM_FILES
|
||||||
|
int fs_open_custom(struct fs_file *file, const char *name);
|
||||||
|
void fs_close_custom(struct fs_file *file);
|
||||||
|
#if LWIP_HTTPD_FS_ASYNC_READ
|
||||||
|
u8_t fs_canread_custom(struct fs_file *file);
|
||||||
|
u8_t fs_wait_read_custom(struct fs_file *file, fs_wait_cb callback_fn, void *callback_arg);
|
||||||
|
int fs_read_async_custom(struct fs_file *file, char *buffer, int count, fs_wait_cb callback_fn, void *callback_arg);
|
||||||
|
#else /* LWIP_HTTPD_FS_ASYNC_READ */
|
||||||
|
int fs_read_custom(struct fs_file *file, char *buffer, int count);
|
||||||
|
#endif /* LWIP_HTTPD_FS_ASYNC_READ */
|
||||||
|
#endif /* LWIP_HTTPD_CUSTOM_FILES */
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
err_t
|
||||||
|
fs_open(struct fs_file *file, const char *name)
|
||||||
|
{
|
||||||
|
const struct fsdata_file *f;
|
||||||
|
|
||||||
|
if ((file == NULL) || (name == NULL)) {
|
||||||
|
return ERR_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if LWIP_HTTPD_CUSTOM_FILES
|
||||||
|
if (fs_open_custom(file, name)) {
|
||||||
|
file->is_custom_file = 1;
|
||||||
|
return ERR_OK;
|
||||||
|
}
|
||||||
|
file->is_custom_file = 0;
|
||||||
|
#endif /* LWIP_HTTPD_CUSTOM_FILES */
|
||||||
|
|
||||||
|
for (f = FS_ROOT; f != NULL; f = f->next) {
|
||||||
|
if (!strcmp(name, (const char *)f->name)) {
|
||||||
|
file->data = (const char *)f->data;
|
||||||
|
file->len = f->len;
|
||||||
|
file->index = f->len;
|
||||||
|
file->pextension = NULL;
|
||||||
|
file->flags = f->flags;
|
||||||
|
#if HTTPD_PRECALCULATED_CHECKSUM
|
||||||
|
file->chksum_count = f->chksum_count;
|
||||||
|
file->chksum = f->chksum;
|
||||||
|
#endif /* HTTPD_PRECALCULATED_CHECKSUM */
|
||||||
|
#if LWIP_HTTPD_FILE_STATE
|
||||||
|
file->state = fs_state_init(file, name);
|
||||||
|
#endif /* #if LWIP_HTTPD_FILE_STATE */
|
||||||
|
return ERR_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* file not found */
|
||||||
|
return ERR_VAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
void
|
||||||
|
fs_close(struct fs_file *file)
|
||||||
|
{
|
||||||
|
#if LWIP_HTTPD_CUSTOM_FILES
|
||||||
|
if (file->is_custom_file) {
|
||||||
|
fs_close_custom(file);
|
||||||
|
}
|
||||||
|
#endif /* LWIP_HTTPD_CUSTOM_FILES */
|
||||||
|
#if LWIP_HTTPD_FILE_STATE
|
||||||
|
fs_state_free(file, file->state);
|
||||||
|
#endif /* #if LWIP_HTTPD_FILE_STATE */
|
||||||
|
LWIP_UNUSED_ARG(file);
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
#if LWIP_HTTPD_DYNAMIC_FILE_READ
|
||||||
|
#if LWIP_HTTPD_FS_ASYNC_READ
|
||||||
|
int
|
||||||
|
fs_read_async(struct fs_file *file, char *buffer, int count, fs_wait_cb callback_fn, void *callback_arg)
|
||||||
|
#else /* LWIP_HTTPD_FS_ASYNC_READ */
|
||||||
|
int
|
||||||
|
fs_read(struct fs_file *file, char *buffer, int count)
|
||||||
|
#endif /* LWIP_HTTPD_FS_ASYNC_READ */
|
||||||
|
{
|
||||||
|
int read;
|
||||||
|
if(file->index == file->len) {
|
||||||
|
return FS_READ_EOF;
|
||||||
|
}
|
||||||
|
#if LWIP_HTTPD_FS_ASYNC_READ
|
||||||
|
LWIP_UNUSED_ARG(callback_fn);
|
||||||
|
LWIP_UNUSED_ARG(callback_arg);
|
||||||
|
#endif /* LWIP_HTTPD_FS_ASYNC_READ */
|
||||||
|
#if LWIP_HTTPD_CUSTOM_FILES
|
||||||
|
if (file->is_custom_file) {
|
||||||
|
#if LWIP_HTTPD_FS_ASYNC_READ
|
||||||
|
return fs_read_async_custom(file, buffer, count, callback_fn, callback_arg);
|
||||||
|
#else /* LWIP_HTTPD_FS_ASYNC_READ */
|
||||||
|
return fs_read_custom(file, buffer, count);
|
||||||
|
#endif /* LWIP_HTTPD_FS_ASYNC_READ */
|
||||||
|
}
|
||||||
|
#endif /* LWIP_HTTPD_CUSTOM_FILES */
|
||||||
|
|
||||||
|
read = file->len - file->index;
|
||||||
|
if(read > count) {
|
||||||
|
read = count;
|
||||||
|
}
|
||||||
|
|
||||||
|
MEMCPY(buffer, (file->data + file->index), read);
|
||||||
|
file->index += read;
|
||||||
|
|
||||||
|
return(read);
|
||||||
|
}
|
||||||
|
#endif /* LWIP_HTTPD_DYNAMIC_FILE_READ */
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
#if LWIP_HTTPD_FS_ASYNC_READ
|
||||||
|
int
|
||||||
|
fs_is_file_ready(struct fs_file *file, fs_wait_cb callback_fn, void *callback_arg)
|
||||||
|
{
|
||||||
|
if (file != NULL) {
|
||||||
|
#if LWIP_HTTPD_FS_ASYNC_READ
|
||||||
|
#if LWIP_HTTPD_CUSTOM_FILES
|
||||||
|
if (!fs_canread_custom(file)) {
|
||||||
|
if (fs_wait_read_custom(file, callback_fn, callback_arg)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else /* LWIP_HTTPD_CUSTOM_FILES */
|
||||||
|
LWIP_UNUSED_ARG(callback_fn);
|
||||||
|
LWIP_UNUSED_ARG(callback_arg);
|
||||||
|
#endif /* LWIP_HTTPD_CUSTOM_FILES */
|
||||||
|
#endif /* LWIP_HTTPD_FS_ASYNC_READ */
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
#endif /* LWIP_HTTPD_FS_ASYNC_READ */
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
int
|
||||||
|
fs_bytes_left(struct fs_file *file)
|
||||||
|
{
|
||||||
|
return file->len - file->index;
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
<html>
|
||||||
|
<head><title>lwIP - A Lightweight TCP/IP Stack</title></head>
|
||||||
|
<body bgcolor="white" text="black">
|
||||||
|
|
||||||
|
<table width="100%">
|
||||||
|
<tr valign="top"><td width="80">
|
||||||
|
<a href="http://www.sics.se/"><img src="/img/sics.gif"
|
||||||
|
border="0" alt="SICS logo" title="SICS logo"></a>
|
||||||
|
</td><td width="500">
|
||||||
|
<h1>lwIP - A Lightweight TCP/IP Stack</h1>
|
||||||
|
<h2>404 - Page not found</h2>
|
||||||
|
<p>
|
||||||
|
Sorry, the page you are requesting was not found on this
|
||||||
|
server.
|
||||||
|
</p>
|
||||||
|
</td><td>
|
||||||
|
|
||||||
|
</td></tr>
|
||||||
|
</table>
|
||||||
|
</body>
|
||||||
|
</html>
|
Binary file not shown.
After Width: | Height: | Size: 724 B |
|
@ -0,0 +1,47 @@
|
||||||
|
<html>
|
||||||
|
<head><title>lwIP - A Lightweight TCP/IP Stack</title></head>
|
||||||
|
<body bgcolor="white" text="black">
|
||||||
|
|
||||||
|
<table width="100%">
|
||||||
|
<tr valign="top"><td width="80">
|
||||||
|
<a href="http://www.sics.se/"><img src="/img/sics.gif"
|
||||||
|
border="0" alt="SICS logo" title="SICS logo"></a>
|
||||||
|
</td><td width="500">
|
||||||
|
<h1>lwIP - A Lightweight TCP/IP Stack</h1>
|
||||||
|
<p>
|
||||||
|
The web page you are watching was served by a simple web
|
||||||
|
server running on top of the lightweight TCP/IP stack <a
|
||||||
|
href="http://www.sics.se/~adam/lwip/">lwIP</a>.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
lwIP is an open source implementation of the TCP/IP
|
||||||
|
protocol suite that was originally written by <a
|
||||||
|
href="http://www.sics.se/~adam/lwip/">Adam Dunkels
|
||||||
|
of the Swedish Institute of Computer Science</a> but now is
|
||||||
|
being actively developed by a team of developers
|
||||||
|
distributed world-wide. Since it's release, lwIP has
|
||||||
|
spurred a lot of interest and has been ported to several
|
||||||
|
platforms and operating systems. lwIP can be used either
|
||||||
|
with or without an underlying OS.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
The focus of the lwIP TCP/IP implementation is to reduce
|
||||||
|
the RAM usage while still having a full scale TCP. This
|
||||||
|
makes lwIP suitable for use in embedded systems with tens
|
||||||
|
of kilobytes of free RAM and room for around 40 kilobytes
|
||||||
|
of code ROM.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
More information about lwIP can be found at the lwIP
|
||||||
|
homepage at <a
|
||||||
|
href="http://savannah.nongnu.org/projects/lwip/">http://savannah.nongnu.org/projects/lwip/</a>
|
||||||
|
or at the lwIP wiki at <a
|
||||||
|
href="http://lwip.wikia.com/">http://lwip.wikia.com/</a>.
|
||||||
|
</p>
|
||||||
|
</td><td>
|
||||||
|
|
||||||
|
</td></tr>
|
||||||
|
</table>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
|
@ -0,0 +1,297 @@
|
||||||
|
#include "lwip/apps/fs.h"
|
||||||
|
#include "lwip/def.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define file_NULL (struct fsdata_file *) NULL
|
||||||
|
|
||||||
|
|
||||||
|
static const unsigned int dummy_align__img_sics_gif = 0;
|
||||||
|
static const unsigned char data__img_sics_gif[] = {
|
||||||
|
/* /img/sics.gif (14 chars) */
|
||||||
|
0x2f,0x69,0x6d,0x67,0x2f,0x73,0x69,0x63,0x73,0x2e,0x67,0x69,0x66,0x00,0x00,0x00,
|
||||||
|
|
||||||
|
/* HTTP header */
|
||||||
|
/* "HTTP/1.0 200 OK
|
||||||
|
" (17 bytes) */
|
||||||
|
0x48,0x54,0x54,0x50,0x2f,0x31,0x2e,0x30,0x20,0x32,0x30,0x30,0x20,0x4f,0x4b,0x0d,
|
||||||
|
0x0a,
|
||||||
|
/* "Server: lwIP/1.3.1 (http://savannah.nongnu.org/projects/lwip)
|
||||||
|
" (63 bytes) */
|
||||||
|
0x53,0x65,0x72,0x76,0x65,0x72,0x3a,0x20,0x6c,0x77,0x49,0x50,0x2f,0x31,0x2e,0x33,
|
||||||
|
0x2e,0x31,0x20,0x28,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x73,0x61,0x76,0x61,0x6e,
|
||||||
|
0x6e,0x61,0x68,0x2e,0x6e,0x6f,0x6e,0x67,0x6e,0x75,0x2e,0x6f,0x72,0x67,0x2f,0x70,
|
||||||
|
0x72,0x6f,0x6a,0x65,0x63,0x74,0x73,0x2f,0x6c,0x77,0x69,0x70,0x29,0x0d,0x0a,
|
||||||
|
/* "Content-type: image/gif
|
||||||
|
|
||||||
|
" (27 bytes) */
|
||||||
|
0x43,0x6f,0x6e,0x74,0x65,0x6e,0x74,0x2d,0x74,0x79,0x70,0x65,0x3a,0x20,0x69,0x6d,
|
||||||
|
0x61,0x67,0x65,0x2f,0x67,0x69,0x66,0x0d,0x0a,0x0d,0x0a,
|
||||||
|
/* raw file data (724 bytes) */
|
||||||
|
0x47,0x49,0x46,0x38,0x39,0x61,0x46,0x00,0x22,0x00,0xa5,0x00,0x00,0xd9,0x2b,0x39,
|
||||||
|
0x6a,0x6a,0x6a,0xbf,0xbf,0xbf,0x93,0x93,0x93,0x0f,0x0f,0x0f,0xb0,0xb0,0xb0,0xa6,
|
||||||
|
0xa6,0xa6,0x80,0x80,0x80,0x76,0x76,0x76,0x1e,0x1e,0x1e,0x9d,0x9d,0x9d,0x2e,0x2e,
|
||||||
|
0x2e,0x49,0x49,0x49,0x54,0x54,0x54,0x8a,0x8a,0x8a,0x60,0x60,0x60,0xc6,0xa6,0x99,
|
||||||
|
0xbd,0xb5,0xb2,0xc2,0xab,0xa1,0xd9,0x41,0x40,0xd5,0x67,0x55,0xc0,0xb0,0xaa,0xd5,
|
||||||
|
0x5e,0x4e,0xd6,0x50,0x45,0xcc,0x93,0x7d,0xc8,0xa1,0x90,0xce,0x8b,0x76,0xd2,0x7b,
|
||||||
|
0x65,0xd1,0x84,0x6d,0xc9,0x99,0x86,0x3a,0x3a,0x3a,0x00,0x00,0x00,0xb8,0xb8,0xb8,
|
||||||
|
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||||
|
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||||
|
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||||
|
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||||
|
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||||
|
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x2c,0x00,0x00,
|
||||||
|
0x00,0x00,0x46,0x00,0x22,0x00,0x00,0x06,0xfe,0x40,0x90,0x70,0x48,0x2c,0x1a,0x8f,
|
||||||
|
0xc8,0xa4,0x72,0xc9,0x6c,0x3a,0x9f,0xd0,0xa8,0x74,0x4a,0xad,0x5a,0xaf,0xd8,0xac,
|
||||||
|
0x76,0xa9,0x40,0x04,0xbe,0x83,0xe2,0x60,0x3c,0x50,0x20,0x0d,0x8e,0x6f,0x00,0x31,
|
||||||
|
0x28,0x1c,0x0d,0x07,0xb5,0xc3,0x60,0x75,0x24,0x3e,0xf8,0xfc,0x87,0x11,0x06,0xe9,
|
||||||
|
0x3d,0x46,0x07,0x0b,0x7a,0x7a,0x7c,0x43,0x06,0x1e,0x84,0x78,0x0b,0x07,0x6e,0x51,
|
||||||
|
0x01,0x8a,0x84,0x08,0x7e,0x79,0x80,0x87,0x89,0x91,0x7a,0x93,0x0a,0x04,0x99,0x78,
|
||||||
|
0x96,0x4f,0x03,0x9e,0x79,0x01,0x94,0x9f,0x43,0x9c,0xa3,0xa4,0x05,0x77,0xa3,0xa0,
|
||||||
|
0x4e,0x98,0x79,0x0b,0x1e,0x83,0xa4,0xa6,0x1f,0x96,0x05,0x9d,0xaa,0x78,0x01,0x07,
|
||||||
|
0x84,0x04,0x1e,0x1e,0xbb,0xb8,0x51,0x84,0x0e,0x43,0x05,0x07,0x77,0xa5,0x7f,0x42,
|
||||||
|
0xb1,0xb2,0x01,0x63,0x08,0x0d,0xbb,0x01,0x0c,0x7a,0x0d,0x44,0x0e,0xd8,0xaf,0x4c,
|
||||||
|
0x05,0x7a,0x04,0x47,0x07,0x07,0xb7,0x80,0xa2,0xe1,0x7d,0x44,0x05,0x01,0x04,0x01,
|
||||||
|
0xd0,0xea,0x87,0x93,0x4f,0xe0,0x9a,0x49,0xce,0xd8,0x79,0x04,0x66,0x20,0x15,0x10,
|
||||||
|
0x10,0x11,0x92,0x29,0x80,0xb6,0xc0,0x91,0x15,0x45,0x1e,0x90,0x19,0x71,0x46,0xa8,
|
||||||
|
0x5c,0x04,0x0e,0x00,0x22,0x4e,0xe8,0x40,0x24,0x9f,0x3e,0x04,0x06,0xa7,0x58,0xd4,
|
||||||
|
0x93,0xa0,0x1c,0x91,0x3f,0xe8,0xf0,0x88,0x03,0xb1,0x21,0xa2,0x49,0x00,0x19,0x86,
|
||||||
|
0xfc,0x52,0x44,0xe0,0x01,0x9d,0x29,0x21,0x15,0x25,0x50,0xf7,0x67,0x25,0x1e,0x06,
|
||||||
|
0xfd,0x4e,0x9a,0xb4,0x90,0xac,0x15,0xfa,0xcb,0x52,0x53,0x1e,0x8c,0xf2,0xf8,0x07,
|
||||||
|
0x92,0x2d,0x08,0x3a,0x4d,0x12,0x49,0x95,0x49,0xdb,0x14,0x04,0xc4,0x14,0x85,0x29,
|
||||||
|
0xaa,0xe7,0x01,0x08,0xa4,0x49,0x01,0x14,0x51,0xe0,0x53,0x91,0xd5,0x29,0x06,0x1a,
|
||||||
|
0x64,0x02,0xf4,0xc7,0x81,0x9e,0x05,0x20,0x22,0x64,0xa5,0x30,0xae,0xab,0x9e,0x97,
|
||||||
|
0x53,0xd8,0xb9,0xfd,0x50,0xef,0x93,0x02,0x42,0x74,0x34,0xe8,0x9c,0x20,0x21,0xc9,
|
||||||
|
0x01,0x68,0x78,0xe6,0x55,0x29,0x20,0x56,0x4f,0x4c,0x40,0x51,0x71,0x82,0xc0,0x70,
|
||||||
|
0x21,0x22,0x85,0xbe,0x4b,0x1c,0x44,0x05,0xea,0xa4,0x01,0xbf,0x22,0xb5,0xf0,0x1c,
|
||||||
|
0x06,0x51,0x38,0x8f,0xe0,0x22,0xec,0x18,0xac,0x39,0x22,0xd4,0xd6,0x93,0x44,0x01,
|
||||||
|
0x32,0x82,0xc8,0xfc,0x61,0xb3,0x01,0x45,0x0c,0x2e,0x83,0x30,0xd0,0x0e,0x17,0x24,
|
||||||
|
0x0f,0x70,0x85,0x94,0xee,0x05,0x05,0x53,0x4b,0x32,0x1b,0x3f,0x98,0xd3,0x1d,0x29,
|
||||||
|
0x81,0xb0,0xae,0x1e,0x8c,0x7e,0x68,0xe0,0x60,0x5a,0x54,0x8f,0xb0,0x78,0x69,0x73,
|
||||||
|
0x06,0xa2,0x00,0x6b,0x57,0xca,0x3d,0x11,0x50,0xbd,0x04,0x30,0x4b,0x3a,0xd4,0xab,
|
||||||
|
0x5f,0x1f,0x9b,0x3d,0x13,0x74,0x27,0x88,0x3c,0x25,0xe0,0x17,0xbe,0x7a,0x79,0x45,
|
||||||
|
0x0d,0x0c,0xb0,0x8b,0xda,0x90,0xca,0x80,0x06,0x5d,0x17,0x60,0x1c,0x22,0x4c,0xd8,
|
||||||
|
0x57,0x22,0x06,0x20,0x00,0x98,0x07,0x08,0xe4,0x56,0x80,0x80,0x1c,0xc5,0xb7,0xc5,
|
||||||
|
0x82,0x0c,0x36,0xe8,0xe0,0x83,0x10,0x46,0x28,0xe1,0x84,0x14,0x56,0x68,0xa1,0x10,
|
||||||
|
0x41,0x00,0x00,0x3b,};
|
||||||
|
|
||||||
|
static const unsigned int dummy_align__404_html = 1;
|
||||||
|
static const unsigned char data__404_html[] = {
|
||||||
|
/* /404.html (10 chars) */
|
||||||
|
0x2f,0x34,0x30,0x34,0x2e,0x68,0x74,0x6d,0x6c,0x00,0x00,0x00,
|
||||||
|
|
||||||
|
/* HTTP header */
|
||||||
|
/* "HTTP/1.0 404 File not found
|
||||||
|
" (29 bytes) */
|
||||||
|
0x48,0x54,0x54,0x50,0x2f,0x31,0x2e,0x30,0x20,0x34,0x30,0x34,0x20,0x46,0x69,0x6c,
|
||||||
|
0x65,0x20,0x6e,0x6f,0x74,0x20,0x66,0x6f,0x75,0x6e,0x64,0x0d,0x0a,
|
||||||
|
/* "Server: lwIP/1.3.1 (http://savannah.nongnu.org/projects/lwip)
|
||||||
|
" (63 bytes) */
|
||||||
|
0x53,0x65,0x72,0x76,0x65,0x72,0x3a,0x20,0x6c,0x77,0x49,0x50,0x2f,0x31,0x2e,0x33,
|
||||||
|
0x2e,0x31,0x20,0x28,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x73,0x61,0x76,0x61,0x6e,
|
||||||
|
0x6e,0x61,0x68,0x2e,0x6e,0x6f,0x6e,0x67,0x6e,0x75,0x2e,0x6f,0x72,0x67,0x2f,0x70,
|
||||||
|
0x72,0x6f,0x6a,0x65,0x63,0x74,0x73,0x2f,0x6c,0x77,0x69,0x70,0x29,0x0d,0x0a,
|
||||||
|
/* "Content-type: text/html
|
||||||
|
|
||||||
|
" (27 bytes) */
|
||||||
|
0x43,0x6f,0x6e,0x74,0x65,0x6e,0x74,0x2d,0x74,0x79,0x70,0x65,0x3a,0x20,0x74,0x65,
|
||||||
|
0x78,0x74,0x2f,0x68,0x74,0x6d,0x6c,0x0d,0x0a,0x0d,0x0a,
|
||||||
|
/* raw file data (565 bytes) */
|
||||||
|
0x3c,0x68,0x74,0x6d,0x6c,0x3e,0x0d,0x0a,0x3c,0x68,0x65,0x61,0x64,0x3e,0x3c,0x74,
|
||||||
|
0x69,0x74,0x6c,0x65,0x3e,0x6c,0x77,0x49,0x50,0x20,0x2d,0x20,0x41,0x20,0x4c,0x69,
|
||||||
|
0x67,0x68,0x74,0x77,0x65,0x69,0x67,0x68,0x74,0x20,0x54,0x43,0x50,0x2f,0x49,0x50,
|
||||||
|
0x20,0x53,0x74,0x61,0x63,0x6b,0x3c,0x2f,0x74,0x69,0x74,0x6c,0x65,0x3e,0x3c,0x2f,
|
||||||
|
0x68,0x65,0x61,0x64,0x3e,0x0d,0x0a,0x3c,0x62,0x6f,0x64,0x79,0x20,0x62,0x67,0x63,
|
||||||
|
0x6f,0x6c,0x6f,0x72,0x3d,0x22,0x77,0x68,0x69,0x74,0x65,0x22,0x20,0x74,0x65,0x78,
|
||||||
|
0x74,0x3d,0x22,0x62,0x6c,0x61,0x63,0x6b,0x22,0x3e,0x0d,0x0a,0x0d,0x0a,0x20,0x20,
|
||||||
|
0x20,0x20,0x3c,0x74,0x61,0x62,0x6c,0x65,0x20,0x77,0x69,0x64,0x74,0x68,0x3d,0x22,
|
||||||
|
0x31,0x30,0x30,0x25,0x22,0x3e,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x3c,0x74,
|
||||||
|
0x72,0x20,0x76,0x61,0x6c,0x69,0x67,0x6e,0x3d,0x22,0x74,0x6f,0x70,0x22,0x3e,0x3c,
|
||||||
|
0x74,0x64,0x20,0x77,0x69,0x64,0x74,0x68,0x3d,0x22,0x38,0x30,0x22,0x3e,0x09,0x20,
|
||||||
|
0x20,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x61,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x68,
|
||||||
|
0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x73,0x69,0x63,0x73,0x2e,0x73,
|
||||||
|
0x65,0x2f,0x22,0x3e,0x3c,0x69,0x6d,0x67,0x20,0x73,0x72,0x63,0x3d,0x22,0x2f,0x69,
|
||||||
|
0x6d,0x67,0x2f,0x73,0x69,0x63,0x73,0x2e,0x67,0x69,0x66,0x22,0x0d,0x0a,0x09,0x20,
|
||||||
|
0x20,0x62,0x6f,0x72,0x64,0x65,0x72,0x3d,0x22,0x30,0x22,0x20,0x61,0x6c,0x74,0x3d,
|
||||||
|
0x22,0x53,0x49,0x43,0x53,0x20,0x6c,0x6f,0x67,0x6f,0x22,0x20,0x74,0x69,0x74,0x6c,
|
||||||
|
0x65,0x3d,0x22,0x53,0x49,0x43,0x53,0x20,0x6c,0x6f,0x67,0x6f,0x22,0x3e,0x3c,0x2f,
|
||||||
|
0x61,0x3e,0x0d,0x0a,0x09,0x3c,0x2f,0x74,0x64,0x3e,0x3c,0x74,0x64,0x20,0x77,0x69,
|
||||||
|
0x64,0x74,0x68,0x3d,0x22,0x35,0x30,0x30,0x22,0x3e,0x09,0x20,0x20,0x0d,0x0a,0x09,
|
||||||
|
0x20,0x20,0x3c,0x68,0x31,0x3e,0x6c,0x77,0x49,0x50,0x20,0x2d,0x20,0x41,0x20,0x4c,
|
||||||
|
0x69,0x67,0x68,0x74,0x77,0x65,0x69,0x67,0x68,0x74,0x20,0x54,0x43,0x50,0x2f,0x49,
|
||||||
|
0x50,0x20,0x53,0x74,0x61,0x63,0x6b,0x3c,0x2f,0x68,0x31,0x3e,0x0d,0x0a,0x09,0x20,
|
||||||
|
0x20,0x3c,0x68,0x32,0x3e,0x34,0x30,0x34,0x20,0x2d,0x20,0x50,0x61,0x67,0x65,0x20,
|
||||||
|
0x6e,0x6f,0x74,0x20,0x66,0x6f,0x75,0x6e,0x64,0x3c,0x2f,0x68,0x32,0x3e,0x0d,0x0a,
|
||||||
|
0x09,0x20,0x20,0x3c,0x70,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x53,0x6f,0x72,
|
||||||
|
0x72,0x79,0x2c,0x20,0x74,0x68,0x65,0x20,0x70,0x61,0x67,0x65,0x20,0x79,0x6f,0x75,
|
||||||
|
0x20,0x61,0x72,0x65,0x20,0x72,0x65,0x71,0x75,0x65,0x73,0x74,0x69,0x6e,0x67,0x20,
|
||||||
|
0x77,0x61,0x73,0x20,0x6e,0x6f,0x74,0x20,0x66,0x6f,0x75,0x6e,0x64,0x20,0x6f,0x6e,
|
||||||
|
0x20,0x74,0x68,0x69,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x73,0x65,0x72,0x76,
|
||||||
|
0x65,0x72,0x2e,0x20,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x2f,0x70,0x3e,0x0d,0x0a,0x09,
|
||||||
|
0x3c,0x2f,0x74,0x64,0x3e,0x3c,0x74,0x64,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x26,0x6e,
|
||||||
|
0x62,0x73,0x70,0x3b,0x0d,0x0a,0x09,0x3c,0x2f,0x74,0x64,0x3e,0x3c,0x2f,0x74,0x72,
|
||||||
|
0x3e,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x3c,0x2f,0x74,0x61,0x62,0x6c,0x65,
|
||||||
|
0x3e,0x0d,0x0a,0x3c,0x2f,0x62,0x6f,0x64,0x79,0x3e,0x0d,0x0a,0x3c,0x2f,0x68,0x74,
|
||||||
|
0x6d,0x6c,0x3e,0x0d,0x0a,};
|
||||||
|
|
||||||
|
static const unsigned int dummy_align__index_html = 2;
|
||||||
|
static const unsigned char data__index_html[] = {
|
||||||
|
/* /index.html (12 chars) */
|
||||||
|
0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x68,0x74,0x6d,0x6c,0x00,
|
||||||
|
|
||||||
|
/* HTTP header */
|
||||||
|
/* "HTTP/1.0 200 OK
|
||||||
|
" (17 bytes) */
|
||||||
|
0x48,0x54,0x54,0x50,0x2f,0x31,0x2e,0x30,0x20,0x32,0x30,0x30,0x20,0x4f,0x4b,0x0d,
|
||||||
|
0x0a,
|
||||||
|
/* "Server: lwIP/1.3.1 (http://savannah.nongnu.org/projects/lwip)
|
||||||
|
" (63 bytes) */
|
||||||
|
0x53,0x65,0x72,0x76,0x65,0x72,0x3a,0x20,0x6c,0x77,0x49,0x50,0x2f,0x31,0x2e,0x33,
|
||||||
|
0x2e,0x31,0x20,0x28,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x73,0x61,0x76,0x61,0x6e,
|
||||||
|
0x6e,0x61,0x68,0x2e,0x6e,0x6f,0x6e,0x67,0x6e,0x75,0x2e,0x6f,0x72,0x67,0x2f,0x70,
|
||||||
|
0x72,0x6f,0x6a,0x65,0x63,0x74,0x73,0x2f,0x6c,0x77,0x69,0x70,0x29,0x0d,0x0a,
|
||||||
|
/* "Content-type: text/html
|
||||||
|
|
||||||
|
" (27 bytes) */
|
||||||
|
0x43,0x6f,0x6e,0x74,0x65,0x6e,0x74,0x2d,0x74,0x79,0x70,0x65,0x3a,0x20,0x74,0x65,
|
||||||
|
0x78,0x74,0x2f,0x68,0x74,0x6d,0x6c,0x0d,0x0a,0x0d,0x0a,
|
||||||
|
/* raw file data (1751 bytes) */
|
||||||
|
0x3c,0x68,0x74,0x6d,0x6c,0x3e,0x0d,0x0a,0x3c,0x68,0x65,0x61,0x64,0x3e,0x3c,0x74,
|
||||||
|
0x69,0x74,0x6c,0x65,0x3e,0x6c,0x77,0x49,0x50,0x20,0x2d,0x20,0x41,0x20,0x4c,0x69,
|
||||||
|
0x67,0x68,0x74,0x77,0x65,0x69,0x67,0x68,0x74,0x20,0x54,0x43,0x50,0x2f,0x49,0x50,
|
||||||
|
0x20,0x53,0x74,0x61,0x63,0x6b,0x3c,0x2f,0x74,0x69,0x74,0x6c,0x65,0x3e,0x3c,0x2f,
|
||||||
|
0x68,0x65,0x61,0x64,0x3e,0x0d,0x0a,0x3c,0x62,0x6f,0x64,0x79,0x20,0x62,0x67,0x63,
|
||||||
|
0x6f,0x6c,0x6f,0x72,0x3d,0x22,0x77,0x68,0x69,0x74,0x65,0x22,0x20,0x74,0x65,0x78,
|
||||||
|
0x74,0x3d,0x22,0x62,0x6c,0x61,0x63,0x6b,0x22,0x3e,0x0d,0x0a,0x0d,0x0a,0x20,0x20,
|
||||||
|
0x20,0x20,0x3c,0x74,0x61,0x62,0x6c,0x65,0x20,0x77,0x69,0x64,0x74,0x68,0x3d,0x22,
|
||||||
|
0x31,0x30,0x30,0x25,0x22,0x3e,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x3c,0x74,
|
||||||
|
0x72,0x20,0x76,0x61,0x6c,0x69,0x67,0x6e,0x3d,0x22,0x74,0x6f,0x70,0x22,0x3e,0x3c,
|
||||||
|
0x74,0x64,0x20,0x77,0x69,0x64,0x74,0x68,0x3d,0x22,0x38,0x30,0x22,0x3e,0x09,0x20,
|
||||||
|
0x20,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x61,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x68,
|
||||||
|
0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x73,0x69,0x63,0x73,0x2e,0x73,
|
||||||
|
0x65,0x2f,0x22,0x3e,0x3c,0x69,0x6d,0x67,0x20,0x73,0x72,0x63,0x3d,0x22,0x2f,0x69,
|
||||||
|
0x6d,0x67,0x2f,0x73,0x69,0x63,0x73,0x2e,0x67,0x69,0x66,0x22,0x0d,0x0a,0x09,0x20,
|
||||||
|
0x20,0x62,0x6f,0x72,0x64,0x65,0x72,0x3d,0x22,0x30,0x22,0x20,0x61,0x6c,0x74,0x3d,
|
||||||
|
0x22,0x53,0x49,0x43,0x53,0x20,0x6c,0x6f,0x67,0x6f,0x22,0x20,0x74,0x69,0x74,0x6c,
|
||||||
|
0x65,0x3d,0x22,0x53,0x49,0x43,0x53,0x20,0x6c,0x6f,0x67,0x6f,0x22,0x3e,0x3c,0x2f,
|
||||||
|
0x61,0x3e,0x0d,0x0a,0x09,0x3c,0x2f,0x74,0x64,0x3e,0x3c,0x74,0x64,0x20,0x77,0x69,
|
||||||
|
0x64,0x74,0x68,0x3d,0x22,0x35,0x30,0x30,0x22,0x3e,0x09,0x20,0x20,0x0d,0x0a,0x09,
|
||||||
|
0x20,0x20,0x3c,0x68,0x31,0x3e,0x6c,0x77,0x49,0x50,0x20,0x2d,0x20,0x41,0x20,0x4c,
|
||||||
|
0x69,0x67,0x68,0x74,0x77,0x65,0x69,0x67,0x68,0x74,0x20,0x54,0x43,0x50,0x2f,0x49,
|
||||||
|
0x50,0x20,0x53,0x74,0x61,0x63,0x6b,0x3c,0x2f,0x68,0x31,0x3e,0x0d,0x0a,0x09,0x20,
|
||||||
|
0x20,0x3c,0x70,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x54,0x68,0x65,0x20,0x77,
|
||||||
|
0x65,0x62,0x20,0x70,0x61,0x67,0x65,0x20,0x79,0x6f,0x75,0x20,0x61,0x72,0x65,0x20,
|
||||||
|
0x77,0x61,0x74,0x63,0x68,0x69,0x6e,0x67,0x20,0x77,0x61,0x73,0x20,0x73,0x65,0x72,
|
||||||
|
0x76,0x65,0x64,0x20,0x62,0x79,0x20,0x61,0x20,0x73,0x69,0x6d,0x70,0x6c,0x65,0x20,
|
||||||
|
0x77,0x65,0x62,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x73,0x65,0x72,0x76,0x65,0x72,
|
||||||
|
0x20,0x72,0x75,0x6e,0x6e,0x69,0x6e,0x67,0x20,0x6f,0x6e,0x20,0x74,0x6f,0x70,0x20,
|
||||||
|
0x6f,0x66,0x20,0x74,0x68,0x65,0x20,0x6c,0x69,0x67,0x68,0x74,0x77,0x65,0x69,0x67,
|
||||||
|
0x68,0x74,0x20,0x54,0x43,0x50,0x2f,0x49,0x50,0x20,0x73,0x74,0x61,0x63,0x6b,0x20,
|
||||||
|
0x3c,0x61,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x68,
|
||||||
|
0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x73,0x69,0x63,0x73,0x2e,0x73,
|
||||||
|
0x65,0x2f,0x7e,0x61,0x64,0x61,0x6d,0x2f,0x6c,0x77,0x69,0x70,0x2f,0x22,0x3e,0x6c,
|
||||||
|
0x77,0x49,0x50,0x3c,0x2f,0x61,0x3e,0x2e,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x2f,0x70,
|
||||||
|
0x3e,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x70,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,
|
||||||
|
0x6c,0x77,0x49,0x50,0x20,0x69,0x73,0x20,0x61,0x6e,0x20,0x6f,0x70,0x65,0x6e,0x20,
|
||||||
|
0x73,0x6f,0x75,0x72,0x63,0x65,0x20,0x69,0x6d,0x70,0x6c,0x65,0x6d,0x65,0x6e,0x74,
|
||||||
|
0x61,0x74,0x69,0x6f,0x6e,0x20,0x6f,0x66,0x20,0x74,0x68,0x65,0x20,0x54,0x43,0x50,
|
||||||
|
0x2f,0x49,0x50,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x70,0x72,0x6f,0x74,0x6f,0x63,
|
||||||
|
0x6f,0x6c,0x20,0x73,0x75,0x69,0x74,0x65,0x20,0x74,0x68,0x61,0x74,0x20,0x77,0x61,
|
||||||
|
0x73,0x20,0x6f,0x72,0x69,0x67,0x69,0x6e,0x61,0x6c,0x6c,0x79,0x20,0x77,0x72,0x69,
|
||||||
|
0x74,0x74,0x65,0x6e,0x20,0x62,0x79,0x20,0x3c,0x61,0x0d,0x0a,0x09,0x20,0x20,0x20,
|
||||||
|
0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x77,
|
||||||
|
0x77,0x2e,0x73,0x69,0x63,0x73,0x2e,0x73,0x65,0x2f,0x7e,0x61,0x64,0x61,0x6d,0x2f,
|
||||||
|
0x6c,0x77,0x69,0x70,0x2f,0x22,0x3e,0x41,0x64,0x61,0x6d,0x20,0x44,0x75,0x6e,0x6b,
|
||||||
|
0x65,0x6c,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x6f,0x66,0x20,0x74,0x68,0x65,
|
||||||
|
0x20,0x53,0x77,0x65,0x64,0x69,0x73,0x68,0x20,0x49,0x6e,0x73,0x74,0x69,0x74,0x75,
|
||||||
|
0x74,0x65,0x20,0x6f,0x66,0x20,0x43,0x6f,0x6d,0x70,0x75,0x74,0x65,0x72,0x20,0x53,
|
||||||
|
0x63,0x69,0x65,0x6e,0x63,0x65,0x3c,0x2f,0x61,0x3e,0x20,0x62,0x75,0x74,0x20,0x6e,
|
||||||
|
0x6f,0x77,0x20,0x69,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x62,0x65,0x69,0x6e,
|
||||||
|
0x67,0x20,0x61,0x63,0x74,0x69,0x76,0x65,0x6c,0x79,0x20,0x64,0x65,0x76,0x65,0x6c,
|
||||||
|
0x6f,0x70,0x65,0x64,0x20,0x62,0x79,0x20,0x61,0x20,0x74,0x65,0x61,0x6d,0x20,0x6f,
|
||||||
|
0x66,0x20,0x64,0x65,0x76,0x65,0x6c,0x6f,0x70,0x65,0x72,0x73,0x0d,0x0a,0x09,0x20,
|
||||||
|
0x20,0x20,0x20,0x64,0x69,0x73,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x64,0x20,0x77,
|
||||||
|
0x6f,0x72,0x6c,0x64,0x2d,0x77,0x69,0x64,0x65,0x2e,0x20,0x53,0x69,0x6e,0x63,0x65,
|
||||||
|
0x20,0x69,0x74,0x27,0x73,0x20,0x72,0x65,0x6c,0x65,0x61,0x73,0x65,0x2c,0x20,0x6c,
|
||||||
|
0x77,0x49,0x50,0x20,0x68,0x61,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x73,0x70,
|
||||||
|
0x75,0x72,0x72,0x65,0x64,0x20,0x61,0x20,0x6c,0x6f,0x74,0x20,0x6f,0x66,0x20,0x69,
|
||||||
|
0x6e,0x74,0x65,0x72,0x65,0x73,0x74,0x20,0x61,0x6e,0x64,0x20,0x68,0x61,0x73,0x20,
|
||||||
|
0x62,0x65,0x65,0x6e,0x20,0x70,0x6f,0x72,0x74,0x65,0x64,0x20,0x74,0x6f,0x20,0x73,
|
||||||
|
0x65,0x76,0x65,0x72,0x61,0x6c,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x70,0x6c,0x61,
|
||||||
|
0x74,0x66,0x6f,0x72,0x6d,0x73,0x20,0x61,0x6e,0x64,0x20,0x6f,0x70,0x65,0x72,0x61,
|
||||||
|
0x74,0x69,0x6e,0x67,0x20,0x73,0x79,0x73,0x74,0x65,0x6d,0x73,0x2e,0x20,0x6c,0x77,
|
||||||
|
0x49,0x50,0x20,0x63,0x61,0x6e,0x20,0x62,0x65,0x20,0x75,0x73,0x65,0x64,0x20,0x65,
|
||||||
|
0x69,0x74,0x68,0x65,0x72,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x77,0x69,0x74,0x68,
|
||||||
|
0x20,0x6f,0x72,0x20,0x77,0x69,0x74,0x68,0x6f,0x75,0x74,0x20,0x61,0x6e,0x20,0x75,
|
||||||
|
0x6e,0x64,0x65,0x72,0x6c,0x79,0x69,0x6e,0x67,0x20,0x4f,0x53,0x2e,0x0d,0x0a,0x09,
|
||||||
|
0x20,0x20,0x3c,0x2f,0x70,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x70,0x3e,0x0d,0x0a,
|
||||||
|
0x09,0x20,0x20,0x20,0x20,0x54,0x68,0x65,0x20,0x66,0x6f,0x63,0x75,0x73,0x20,0x6f,
|
||||||
|
0x66,0x20,0x74,0x68,0x65,0x20,0x6c,0x77,0x49,0x50,0x20,0x54,0x43,0x50,0x2f,0x49,
|
||||||
|
0x50,0x20,0x69,0x6d,0x70,0x6c,0x65,0x6d,0x65,0x6e,0x74,0x61,0x74,0x69,0x6f,0x6e,
|
||||||
|
0x20,0x69,0x73,0x20,0x74,0x6f,0x20,0x72,0x65,0x64,0x75,0x63,0x65,0x0d,0x0a,0x09,
|
||||||
|
0x20,0x20,0x20,0x20,0x74,0x68,0x65,0x20,0x52,0x41,0x4d,0x20,0x75,0x73,0x61,0x67,
|
||||||
|
0x65,0x20,0x77,0x68,0x69,0x6c,0x65,0x20,0x73,0x74,0x69,0x6c,0x6c,0x20,0x68,0x61,
|
||||||
|
0x76,0x69,0x6e,0x67,0x20,0x61,0x20,0x66,0x75,0x6c,0x6c,0x20,0x73,0x63,0x61,0x6c,
|
||||||
|
0x65,0x20,0x54,0x43,0x50,0x2e,0x20,0x54,0x68,0x69,0x73,0x0d,0x0a,0x09,0x20,0x20,
|
||||||
|
0x20,0x20,0x6d,0x61,0x6b,0x65,0x73,0x20,0x6c,0x77,0x49,0x50,0x20,0x73,0x75,0x69,
|
||||||
|
0x74,0x61,0x62,0x6c,0x65,0x20,0x66,0x6f,0x72,0x20,0x75,0x73,0x65,0x20,0x69,0x6e,
|
||||||
|
0x20,0x65,0x6d,0x62,0x65,0x64,0x64,0x65,0x64,0x20,0x73,0x79,0x73,0x74,0x65,0x6d,
|
||||||
|
0x73,0x20,0x77,0x69,0x74,0x68,0x20,0x74,0x65,0x6e,0x73,0x0d,0x0a,0x09,0x20,0x20,
|
||||||
|
0x20,0x20,0x6f,0x66,0x20,0x6b,0x69,0x6c,0x6f,0x62,0x79,0x74,0x65,0x73,0x20,0x6f,
|
||||||
|
0x66,0x20,0x66,0x72,0x65,0x65,0x20,0x52,0x41,0x4d,0x20,0x61,0x6e,0x64,0x20,0x72,
|
||||||
|
0x6f,0x6f,0x6d,0x20,0x66,0x6f,0x72,0x20,0x61,0x72,0x6f,0x75,0x6e,0x64,0x20,0x34,
|
||||||
|
0x30,0x20,0x6b,0x69,0x6c,0x6f,0x62,0x79,0x74,0x65,0x73,0x0d,0x0a,0x09,0x20,0x20,
|
||||||
|
0x20,0x20,0x6f,0x66,0x20,0x63,0x6f,0x64,0x65,0x20,0x52,0x4f,0x4d,0x2e,0x0d,0x0a,
|
||||||
|
0x09,0x20,0x20,0x3c,0x2f,0x70,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x70,0x3e,0x0d,
|
||||||
|
0x0a,0x09,0x20,0x20,0x20,0x20,0x4d,0x6f,0x72,0x65,0x20,0x69,0x6e,0x66,0x6f,0x72,
|
||||||
|
0x6d,0x61,0x74,0x69,0x6f,0x6e,0x20,0x61,0x62,0x6f,0x75,0x74,0x20,0x6c,0x77,0x49,
|
||||||
|
0x50,0x20,0x63,0x61,0x6e,0x20,0x62,0x65,0x20,0x66,0x6f,0x75,0x6e,0x64,0x20,0x61,
|
||||||
|
0x74,0x20,0x74,0x68,0x65,0x20,0x6c,0x77,0x49,0x50,0x0d,0x0a,0x09,0x20,0x20,0x20,
|
||||||
|
0x20,0x68,0x6f,0x6d,0x65,0x70,0x61,0x67,0x65,0x20,0x61,0x74,0x20,0x3c,0x61,0x0d,
|
||||||
|
0x0a,0x09,0x20,0x20,0x20,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x68,0x74,0x74,0x70,
|
||||||
|
0x3a,0x2f,0x2f,0x73,0x61,0x76,0x61,0x6e,0x6e,0x61,0x68,0x2e,0x6e,0x6f,0x6e,0x67,
|
||||||
|
0x6e,0x75,0x2e,0x6f,0x72,0x67,0x2f,0x70,0x72,0x6f,0x6a,0x65,0x63,0x74,0x73,0x2f,
|
||||||
|
0x6c,0x77,0x69,0x70,0x2f,0x22,0x3e,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x73,0x61,
|
||||||
|
0x76,0x61,0x6e,0x6e,0x61,0x68,0x2e,0x6e,0x6f,0x6e,0x67,0x6e,0x75,0x2e,0x6f,0x72,
|
||||||
|
0x67,0x2f,0x70,0x72,0x6f,0x6a,0x65,0x63,0x74,0x73,0x2f,0x6c,0x77,0x69,0x70,0x2f,
|
||||||
|
0x3c,0x2f,0x61,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x6f,0x72,0x20,0x61,0x74,
|
||||||
|
0x20,0x74,0x68,0x65,0x20,0x6c,0x77,0x49,0x50,0x20,0x77,0x69,0x6b,0x69,0x20,0x61,
|
||||||
|
0x74,0x20,0x3c,0x61,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x68,0x72,0x65,0x66,0x3d,
|
||||||
|
0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x6c,0x77,0x69,0x70,0x2e,0x77,0x69,0x6b,
|
||||||
|
0x69,0x61,0x2e,0x63,0x6f,0x6d,0x2f,0x22,0x3e,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,
|
||||||
|
0x6c,0x77,0x69,0x70,0x2e,0x77,0x69,0x6b,0x69,0x61,0x2e,0x63,0x6f,0x6d,0x2f,0x3c,
|
||||||
|
0x2f,0x61,0x3e,0x2e,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x2f,0x70,0x3e,0x0d,0x0a,0x09,
|
||||||
|
0x3c,0x2f,0x74,0x64,0x3e,0x3c,0x74,0x64,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x26,0x6e,
|
||||||
|
0x62,0x73,0x70,0x3b,0x0d,0x0a,0x09,0x3c,0x2f,0x74,0x64,0x3e,0x3c,0x2f,0x74,0x72,
|
||||||
|
0x3e,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x3c,0x2f,0x74,0x61,0x62,0x6c,0x65,
|
||||||
|
0x3e,0x0d,0x0a,0x3c,0x2f,0x62,0x6f,0x64,0x79,0x3e,0x0d,0x0a,0x3c,0x2f,0x68,0x74,
|
||||||
|
0x6d,0x6c,0x3e,0x0d,0x0a,0x0d,0x0a,};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const struct fsdata_file file__img_sics_gif[] = { {
|
||||||
|
file_NULL,
|
||||||
|
data__img_sics_gif,
|
||||||
|
data__img_sics_gif + 16,
|
||||||
|
sizeof(data__img_sics_gif) - 16,
|
||||||
|
1,
|
||||||
|
}};
|
||||||
|
|
||||||
|
const struct fsdata_file file__404_html[] = { {
|
||||||
|
file__img_sics_gif,
|
||||||
|
data__404_html,
|
||||||
|
data__404_html + 12,
|
||||||
|
sizeof(data__404_html) - 12,
|
||||||
|
1,
|
||||||
|
}};
|
||||||
|
|
||||||
|
const struct fsdata_file file__index_html[] = { {
|
||||||
|
file__404_html,
|
||||||
|
data__index_html,
|
||||||
|
data__index_html + 12,
|
||||||
|
sizeof(data__index_html) - 12,
|
||||||
|
1,
|
||||||
|
}};
|
||||||
|
|
||||||
|
#define FS_ROOT file__index_html
|
||||||
|
#define FS_NUMFILES 3
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||||
|
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||||
|
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
|
* OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* This file is part of the lwIP TCP/IP stack.
|
||||||
|
*
|
||||||
|
* Author: Adam Dunkels <adam@sics.se>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef LWIP_FSDATA_H
|
||||||
|
#define LWIP_FSDATA_H
|
||||||
|
|
||||||
|
#include "lwip/apps/httpd_opts.h"
|
||||||
|
#include "lwip/apps/fs.h"
|
||||||
|
|
||||||
|
/* THIS FILE IS DEPRECATED AND WILL BE REMOVED IN THE FUTURE */
|
||||||
|
/* content was moved to fs.h to simplify #include structure */
|
||||||
|
|
||||||
|
#endif /* LWIP_FSDATA_H */
|
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,114 @@
|
||||||
|
#ifndef LWIP_HTTPD_STRUCTS_H
|
||||||
|
#define LWIP_HTTPD_STRUCTS_H
|
||||||
|
|
||||||
|
#include "lwip/apps/httpd.h"
|
||||||
|
|
||||||
|
#if LWIP_HTTPD_DYNAMIC_HEADERS
|
||||||
|
/** This struct is used for a list of HTTP header strings for various
|
||||||
|
* filename extensions. */
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
const char *extension;
|
||||||
|
const char *content_type;
|
||||||
|
} tHTTPHeader;
|
||||||
|
|
||||||
|
/** A list of strings used in HTTP headers (see RFC 1945 HTTP/1.0 and
|
||||||
|
* RFC 2616 HTTP/1.1 for header field definitions) */
|
||||||
|
static const char * const g_psHTTPHeaderStrings[] =
|
||||||
|
{
|
||||||
|
"HTTP/1.0 200 OK\r\n",
|
||||||
|
"HTTP/1.0 404 File not found\r\n",
|
||||||
|
"HTTP/1.0 400 Bad Request\r\n",
|
||||||
|
"HTTP/1.0 501 Not Implemented\r\n",
|
||||||
|
"HTTP/1.1 200 OK\r\n",
|
||||||
|
"HTTP/1.1 404 File not found\r\n",
|
||||||
|
"HTTP/1.1 400 Bad Request\r\n",
|
||||||
|
"HTTP/1.1 501 Not Implemented\r\n",
|
||||||
|
"Content-Length: ",
|
||||||
|
"Connection: Close\r\n",
|
||||||
|
"Connection: keep-alive\r\n",
|
||||||
|
"Connection: keep-alive\r\nContent-Length: ",
|
||||||
|
"Server: "HTTPD_SERVER_AGENT"\r\n",
|
||||||
|
"\r\n<html><body><h2>404: The requested file cannot be found.</h2></body></html>\r\n"
|
||||||
|
#if LWIP_HTTPD_SUPPORT_11_KEEPALIVE
|
||||||
|
,"Connection: keep-alive\r\nContent-Length: 77\r\n\r\n<html><body><h2>404: The requested file cannot be found.</h2></body></html>\r\n"
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Indexes into the g_psHTTPHeaderStrings array */
|
||||||
|
#define HTTP_HDR_OK 0 /* 200 OK */
|
||||||
|
#define HTTP_HDR_NOT_FOUND 1 /* 404 File not found */
|
||||||
|
#define HTTP_HDR_BAD_REQUEST 2 /* 400 Bad request */
|
||||||
|
#define HTTP_HDR_NOT_IMPL 3 /* 501 Not Implemented */
|
||||||
|
#define HTTP_HDR_OK_11 4 /* 200 OK */
|
||||||
|
#define HTTP_HDR_NOT_FOUND_11 5 /* 404 File not found */
|
||||||
|
#define HTTP_HDR_BAD_REQUEST_11 6 /* 400 Bad request */
|
||||||
|
#define HTTP_HDR_NOT_IMPL_11 7 /* 501 Not Implemented */
|
||||||
|
#define HTTP_HDR_CONTENT_LENGTH 8 /* Content-Length: (HTTP 1.0)*/
|
||||||
|
#define HTTP_HDR_CONN_CLOSE 9 /* Connection: Close (HTTP 1.1) */
|
||||||
|
#define HTTP_HDR_CONN_KEEPALIVE 10 /* Connection: keep-alive (HTTP 1.1) */
|
||||||
|
#define HTTP_HDR_KEEPALIVE_LEN 11 /* Connection: keep-alive + Content-Length: (HTTP 1.1)*/
|
||||||
|
#define HTTP_HDR_SERVER 12 /* Server: HTTPD_SERVER_AGENT */
|
||||||
|
#define DEFAULT_404_HTML 13 /* default 404 body */
|
||||||
|
#if LWIP_HTTPD_SUPPORT_11_KEEPALIVE
|
||||||
|
#define DEFAULT_404_HTML_PERSISTENT 14 /* default 404 body, but including Connection: keep-alive */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#define HTTP_HDR_HTML "Content-type: text/html\r\n\r\n"
|
||||||
|
#define HTTP_HDR_SSI "Content-type: text/html\r\nExpires: Fri, 10 Apr 2008 14:00:00 GMT\r\nPragma: no-cache\r\n\r\n"
|
||||||
|
#define HTTP_HDR_GIF "Content-type: image/gif\r\n\r\n"
|
||||||
|
#define HTTP_HDR_PNG "Content-type: image/png\r\n\r\n"
|
||||||
|
#define HTTP_HDR_JPG "Content-type: image/jpeg\r\n\r\n"
|
||||||
|
#define HTTP_HDR_BMP "Content-type: image/bmp\r\n\r\n"
|
||||||
|
#define HTTP_HDR_ICO "Content-type: image/x-icon\r\n\r\n"
|
||||||
|
#define HTTP_HDR_APP "Content-type: application/octet-stream\r\n\r\n"
|
||||||
|
#define HTTP_HDR_JS "Content-type: application/javascript\r\n\r\n"
|
||||||
|
#define HTTP_HDR_RA "Content-type: application/javascript\r\n\r\n"
|
||||||
|
#define HTTP_HDR_CSS "Content-type: text/css\r\n\r\n"
|
||||||
|
#define HTTP_HDR_SWF "Content-type: application/x-shockwave-flash\r\n\r\n"
|
||||||
|
#define HTTP_HDR_XML "Content-type: text/xml\r\n\r\n"
|
||||||
|
#define HTTP_HDR_PDF "Content-type: application/pdf\r\n\r\n"
|
||||||
|
#define HTTP_HDR_JSON "Content-type: application/json\r\n\r\n"
|
||||||
|
|
||||||
|
#define HTTP_HDR_DEFAULT_TYPE "Content-type: text/plain\r\n\r\n"
|
||||||
|
|
||||||
|
/** A list of extension-to-HTTP header strings (see outdated RFC 1700 MEDIA TYPES
|
||||||
|
* and http://www.iana.org/assignments/media-types for registered content types
|
||||||
|
* and subtypes) */
|
||||||
|
static const tHTTPHeader g_psHTTPHeaders[] =
|
||||||
|
{
|
||||||
|
{ "html", HTTP_HDR_HTML},
|
||||||
|
{ "htm", HTTP_HDR_HTML},
|
||||||
|
{ "shtml",HTTP_HDR_SSI},
|
||||||
|
{ "shtm", HTTP_HDR_SSI},
|
||||||
|
{ "ssi", HTTP_HDR_SSI},
|
||||||
|
{ "gif", HTTP_HDR_GIF},
|
||||||
|
{ "png", HTTP_HDR_PNG},
|
||||||
|
{ "jpg", HTTP_HDR_JPG},
|
||||||
|
{ "bmp", HTTP_HDR_BMP},
|
||||||
|
{ "ico", HTTP_HDR_ICO},
|
||||||
|
{ "class",HTTP_HDR_APP},
|
||||||
|
{ "cls", HTTP_HDR_APP},
|
||||||
|
{ "js", HTTP_HDR_JS},
|
||||||
|
{ "ram", HTTP_HDR_RA},
|
||||||
|
{ "css", HTTP_HDR_CSS},
|
||||||
|
{ "swf", HTTP_HDR_SWF},
|
||||||
|
{ "xml", HTTP_HDR_XML},
|
||||||
|
{ "xsl", HTTP_HDR_XML},
|
||||||
|
{ "pdf", HTTP_HDR_PDF},
|
||||||
|
{ "json", HTTP_HDR_JSON}
|
||||||
|
};
|
||||||
|
|
||||||
|
#define NUM_HTTP_HEADERS (sizeof(g_psHTTPHeaders) / sizeof(tHTTPHeader))
|
||||||
|
|
||||||
|
#endif /* LWIP_HTTPD_DYNAMIC_HEADERS */
|
||||||
|
|
||||||
|
#if LWIP_HTTPD_SSI
|
||||||
|
static const char * const g_pcSSIExtensions[] = {
|
||||||
|
".shtml", ".shtm", ".ssi", ".xml"
|
||||||
|
};
|
||||||
|
#define NUM_SHTML_EXTENSIONS (sizeof(g_pcSSIExtensions) / sizeof(const char *))
|
||||||
|
#endif /* LWIP_HTTPD_SSI */
|
||||||
|
|
||||||
|
#endif /* LWIP_HTTPD_STRUCTS_H */
|
|
@ -0,0 +1,97 @@
|
||||||
|
#!/usr/bin/perl
|
||||||
|
|
||||||
|
open(OUTPUT, "> fsdata.c");
|
||||||
|
|
||||||
|
chdir("fs");
|
||||||
|
open(FILES, "find . -type f |");
|
||||||
|
|
||||||
|
while($file = <FILES>) {
|
||||||
|
|
||||||
|
# Do not include files in CVS directories nor backup files.
|
||||||
|
if($file =~ /(CVS|~)/) {
|
||||||
|
next;
|
||||||
|
}
|
||||||
|
|
||||||
|
chop($file);
|
||||||
|
|
||||||
|
open(HEADER, "> /tmp/header") || die $!;
|
||||||
|
if($file =~ /404/) {
|
||||||
|
print(HEADER "HTTP/1.0 404 File not found\r\n");
|
||||||
|
} else {
|
||||||
|
print(HEADER "HTTP/1.0 200 OK\r\n");
|
||||||
|
}
|
||||||
|
print(HEADER "Server: lwIP/pre-0.6 (http://www.sics.se/~adam/lwip/)\r\n");
|
||||||
|
if($file =~ /\.html$/) {
|
||||||
|
print(HEADER "Content-type: text/html\r\n");
|
||||||
|
} elsif($file =~ /\.gif$/) {
|
||||||
|
print(HEADER "Content-type: image/gif\r\n");
|
||||||
|
} elsif($file =~ /\.png$/) {
|
||||||
|
print(HEADER "Content-type: image/png\r\n");
|
||||||
|
} elsif($file =~ /\.jpg$/) {
|
||||||
|
print(HEADER "Content-type: image/jpeg\r\n");
|
||||||
|
} elsif($file =~ /\.class$/) {
|
||||||
|
print(HEADER "Content-type: application/octet-stream\r\n");
|
||||||
|
} elsif($file =~ /\.ram$/) {
|
||||||
|
print(HEADER "Content-type: audio/x-pn-realaudio\r\n");
|
||||||
|
} else {
|
||||||
|
print(HEADER "Content-type: text/plain\r\n");
|
||||||
|
}
|
||||||
|
print(HEADER "\r\n");
|
||||||
|
close(HEADER);
|
||||||
|
|
||||||
|
unless($file =~ /\.plain$/ || $file =~ /cgi/) {
|
||||||
|
system("cat /tmp/header $file > /tmp/file");
|
||||||
|
} else {
|
||||||
|
system("cp $file /tmp/file");
|
||||||
|
}
|
||||||
|
|
||||||
|
open(FILE, "/tmp/file");
|
||||||
|
unlink("/tmp/file");
|
||||||
|
unlink("/tmp/header");
|
||||||
|
|
||||||
|
$file =~ s/\.//;
|
||||||
|
$fvar = $file;
|
||||||
|
$fvar =~ s-/-_-g;
|
||||||
|
$fvar =~ s-\.-_-g;
|
||||||
|
print(OUTPUT "static const unsigned char data".$fvar."[] = {\n");
|
||||||
|
print(OUTPUT "\t/* $file */\n\t");
|
||||||
|
for($j = 0; $j < length($file); $j++) {
|
||||||
|
printf(OUTPUT "%#02x, ", unpack("C", substr($file, $j, 1)));
|
||||||
|
}
|
||||||
|
printf(OUTPUT "0,\n");
|
||||||
|
|
||||||
|
|
||||||
|
$i = 0;
|
||||||
|
while(read(FILE, $data, 1)) {
|
||||||
|
if($i == 0) {
|
||||||
|
print(OUTPUT "\t");
|
||||||
|
}
|
||||||
|
printf(OUTPUT "%#02x, ", unpack("C", $data));
|
||||||
|
$i++;
|
||||||
|
if($i == 10) {
|
||||||
|
print(OUTPUT "\n");
|
||||||
|
$i = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
print(OUTPUT "};\n\n");
|
||||||
|
close(FILE);
|
||||||
|
push(@fvars, $fvar);
|
||||||
|
push(@files, $file);
|
||||||
|
}
|
||||||
|
|
||||||
|
for($i = 0; $i < @fvars; $i++) {
|
||||||
|
$file = $files[$i];
|
||||||
|
$fvar = $fvars[$i];
|
||||||
|
|
||||||
|
if($i == 0) {
|
||||||
|
$prevfile = "NULL";
|
||||||
|
} else {
|
||||||
|
$prevfile = "file" . $fvars[$i - 1];
|
||||||
|
}
|
||||||
|
print(OUTPUT "const struct fsdata_file file".$fvar."[] = {{$prevfile, data$fvar, ");
|
||||||
|
print(OUTPUT "data$fvar + ". (length($file) + 1) .", ");
|
||||||
|
print(OUTPUT "sizeof(data$fvar) - ". (length($file) + 1) ."}};\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
print(OUTPUT "#define FS_ROOT file$fvars[$i - 1]\n\n");
|
||||||
|
print(OUTPUT "#define FS_NUMFILES $i\n");
|
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,13 @@
|
||||||
|
This directory contains a script ('makefsdata') to create C code suitable for
|
||||||
|
httpd for given html pages (or other files) in a directory.
|
||||||
|
|
||||||
|
There is also a plain C console application doing the same and extended a bit.
|
||||||
|
|
||||||
|
Usage: htmlgen [targetdir] [-s] [-i]s
|
||||||
|
targetdir: relative or absolute path to files to convert
|
||||||
|
switch -s: toggle processing of subdirectories (default is on)
|
||||||
|
switch -e: exclude HTTP header from file (header is created at runtime, default is on)
|
||||||
|
switch -11: include HTTP 1.1 header (1.0 is default)
|
||||||
|
|
||||||
|
if targetdir not specified, makefsdata will attempt to
|
||||||
|
process files in subdirectory 'fs'.
|
|
@ -0,0 +1,661 @@
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* lwIP iPerf server implementation
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @defgroup iperf Iperf server
|
||||||
|
* @ingroup apps
|
||||||
|
*
|
||||||
|
* This is a simple performance measuring server to check your bandwith using
|
||||||
|
* iPerf2 on a PC as client.
|
||||||
|
* It is currently a minimal implementation providing an IPv4 TCP server only.
|
||||||
|
*
|
||||||
|
* @todo: implement UDP mode and IPv6
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2014 Simon Goldschmidt
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||||
|
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||||
|
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
|
* OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* This file is part of the lwIP TCP/IP stack.
|
||||||
|
*
|
||||||
|
* Author: Simon Goldschmidt
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "lwip/apps/lwiperf.h"
|
||||||
|
|
||||||
|
#include "lwip/tcp.h"
|
||||||
|
#include "lwip/sys.h"
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
/* Currently, only TCP-over-IPv4 is implemented (does iperf support IPv6 anyway?) */
|
||||||
|
#if LWIP_IPV4 && LWIP_TCP
|
||||||
|
|
||||||
|
/** Specify the idle timeout (in seconds) after that the test fails */
|
||||||
|
#ifndef LWIPERF_TCP_MAX_IDLE_SEC
|
||||||
|
#define LWIPERF_TCP_MAX_IDLE_SEC 10U
|
||||||
|
#endif
|
||||||
|
#if LWIPERF_TCP_MAX_IDLE_SEC > 255
|
||||||
|
#error LWIPERF_TCP_MAX_IDLE_SEC must fit into an u8_t
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* File internal memory allocation (struct lwiperf_*): this defaults to
|
||||||
|
the heap */
|
||||||
|
#ifndef LWIPERF_ALLOC
|
||||||
|
#define LWIPERF_ALLOC(type) mem_malloc(sizeof(type))
|
||||||
|
#define LWIPERF_FREE(type, item) mem_free(item)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** If this is 1, check that received data has the correct format */
|
||||||
|
#ifndef LWIPERF_CHECK_RX_DATA
|
||||||
|
#define LWIPERF_CHECK_RX_DATA 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** This is the Iperf settings struct sent from the client */
|
||||||
|
typedef struct _lwiperf_settings {
|
||||||
|
#define LWIPERF_FLAGS_ANSWER_TEST 0x80000000
|
||||||
|
#define LWIPERF_FLAGS_ANSWER_NOW 0x00000001
|
||||||
|
u32_t flags;
|
||||||
|
u32_t num_threads; /* unused for now */
|
||||||
|
u32_t remote_port;
|
||||||
|
u32_t buffer_len; /* unused for now */
|
||||||
|
u32_t win_band; /* TCP window / UDP rate: unused for now */
|
||||||
|
u32_t amount; /* pos. value: bytes?; neg. values: time (unit is 10ms: 1/100 second) */
|
||||||
|
} lwiperf_settings_t;
|
||||||
|
|
||||||
|
/** Basic connection handle */
|
||||||
|
struct _lwiperf_state_base;
|
||||||
|
typedef struct _lwiperf_state_base lwiperf_state_base_t;
|
||||||
|
struct _lwiperf_state_base {
|
||||||
|
/* 1=tcp, 0=udp */
|
||||||
|
u8_t tcp;
|
||||||
|
/* 1=server, 0=client */
|
||||||
|
u8_t server;
|
||||||
|
lwiperf_state_base_t* next;
|
||||||
|
lwiperf_state_base_t* related_server_state;
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Connection handle for a TCP iperf session */
|
||||||
|
typedef struct _lwiperf_state_tcp {
|
||||||
|
lwiperf_state_base_t base;
|
||||||
|
struct tcp_pcb* server_pcb;
|
||||||
|
struct tcp_pcb* conn_pcb;
|
||||||
|
u32_t time_started;
|
||||||
|
lwiperf_report_fn report_fn;
|
||||||
|
void* report_arg;
|
||||||
|
u8_t poll_count;
|
||||||
|
u8_t next_num;
|
||||||
|
u32_t bytes_transferred;
|
||||||
|
lwiperf_settings_t settings;
|
||||||
|
u8_t have_settings_buf;
|
||||||
|
} lwiperf_state_tcp_t;
|
||||||
|
|
||||||
|
/** List of active iperf sessions */
|
||||||
|
static lwiperf_state_base_t* lwiperf_all_connections;
|
||||||
|
/** A const buffer to send from: we want to measure sending, not copying! */
|
||||||
|
static const u8_t lwiperf_txbuf_const[1600] = {
|
||||||
|
'0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9',
|
||||||
|
'0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9',
|
||||||
|
'0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9',
|
||||||
|
'0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9',
|
||||||
|
'0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9',
|
||||||
|
'0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9',
|
||||||
|
'0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9',
|
||||||
|
'0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9',
|
||||||
|
'0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9',
|
||||||
|
'0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9',
|
||||||
|
'0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9',
|
||||||
|
'0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9',
|
||||||
|
'0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9',
|
||||||
|
'0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9',
|
||||||
|
'0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9',
|
||||||
|
'0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9',
|
||||||
|
'0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9',
|
||||||
|
'0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9',
|
||||||
|
'0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9',
|
||||||
|
'0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9',
|
||||||
|
'0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9',
|
||||||
|
'0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9',
|
||||||
|
'0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9',
|
||||||
|
'0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9',
|
||||||
|
'0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9',
|
||||||
|
'0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9',
|
||||||
|
'0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9',
|
||||||
|
'0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9',
|
||||||
|
'0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9',
|
||||||
|
'0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9',
|
||||||
|
'0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9',
|
||||||
|
'0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9',
|
||||||
|
'0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9',
|
||||||
|
'0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9',
|
||||||
|
'0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9',
|
||||||
|
'0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9',
|
||||||
|
'0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9',
|
||||||
|
'0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9',
|
||||||
|
'0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9',
|
||||||
|
'0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9',
|
||||||
|
};
|
||||||
|
|
||||||
|
static err_t lwiperf_tcp_poll(void *arg, struct tcp_pcb *tpcb);
|
||||||
|
static void lwiperf_tcp_err(void *arg, err_t err);
|
||||||
|
|
||||||
|
/** Add an iperf session to the 'active' list */
|
||||||
|
static void
|
||||||
|
lwiperf_list_add(lwiperf_state_base_t* item)
|
||||||
|
{
|
||||||
|
if (lwiperf_all_connections == NULL) {
|
||||||
|
lwiperf_all_connections = item;
|
||||||
|
} else {
|
||||||
|
item = lwiperf_all_connections;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Remove an iperf session from the 'active' list */
|
||||||
|
static void
|
||||||
|
lwiperf_list_remove(lwiperf_state_base_t* item)
|
||||||
|
{
|
||||||
|
lwiperf_state_base_t* prev = NULL;
|
||||||
|
lwiperf_state_base_t* iter;
|
||||||
|
for (iter = lwiperf_all_connections; iter != NULL; prev = iter, iter = iter->next) {
|
||||||
|
if (iter == item) {
|
||||||
|
if (prev == NULL) {
|
||||||
|
lwiperf_all_connections = iter->next;
|
||||||
|
} else {
|
||||||
|
prev->next = item;
|
||||||
|
}
|
||||||
|
/* @debug: ensure this item is listed only once */
|
||||||
|
for (iter = iter->next; iter != NULL; iter = iter->next) {
|
||||||
|
LWIP_ASSERT("duplicate entry", iter != item);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Call the report function of an iperf tcp session */
|
||||||
|
static void
|
||||||
|
lwip_tcp_conn_report(lwiperf_state_tcp_t* conn, enum lwiperf_report_type report_type)
|
||||||
|
{
|
||||||
|
if ((conn != NULL) && (conn->report_fn != NULL)) {
|
||||||
|
u32_t now, duration_ms, bandwidth_kbitpsec;
|
||||||
|
now = sys_now();
|
||||||
|
duration_ms = now - conn->time_started;
|
||||||
|
if (duration_ms == 0) {
|
||||||
|
bandwidth_kbitpsec = 0;
|
||||||
|
} else {
|
||||||
|
bandwidth_kbitpsec = (conn->bytes_transferred / duration_ms) * 8U;
|
||||||
|
}
|
||||||
|
conn->report_fn(conn->report_arg, report_type,
|
||||||
|
&conn->conn_pcb->local_ip, conn->conn_pcb->local_port,
|
||||||
|
&conn->conn_pcb->remote_ip, conn->conn_pcb->remote_port,
|
||||||
|
conn->bytes_transferred, duration_ms, bandwidth_kbitpsec);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Close an iperf tcp session */
|
||||||
|
static void
|
||||||
|
lwiperf_tcp_close(lwiperf_state_tcp_t* conn, enum lwiperf_report_type report_type)
|
||||||
|
{
|
||||||
|
err_t err;
|
||||||
|
|
||||||
|
lwip_tcp_conn_report(conn, report_type);
|
||||||
|
lwiperf_list_remove(&conn->base);
|
||||||
|
if (conn->conn_pcb != NULL) {
|
||||||
|
tcp_arg(conn->conn_pcb, NULL);
|
||||||
|
tcp_poll(conn->conn_pcb, NULL, 0);
|
||||||
|
tcp_sent(conn->conn_pcb, NULL);
|
||||||
|
tcp_recv(conn->conn_pcb, NULL);
|
||||||
|
tcp_err(conn->conn_pcb, NULL);
|
||||||
|
err = tcp_close(conn->conn_pcb);
|
||||||
|
if (err != ERR_OK) {
|
||||||
|
/* don't want to wait for free memory here... */
|
||||||
|
tcp_abort(conn->conn_pcb);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* no conn pcb, this is the server pcb */
|
||||||
|
err = tcp_close(conn->server_pcb);
|
||||||
|
LWIP_ASSERT("error", err != ERR_OK);
|
||||||
|
}
|
||||||
|
LWIPERF_FREE(lwiperf_state_tcp_t, conn);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Try to send more data on an iperf tcp session */
|
||||||
|
static err_t
|
||||||
|
lwiperf_tcp_client_send_more(lwiperf_state_tcp_t* conn)
|
||||||
|
{
|
||||||
|
int send_more;
|
||||||
|
err_t err;
|
||||||
|
u16_t txlen;
|
||||||
|
u16_t txlen_max;
|
||||||
|
void* txptr;
|
||||||
|
u8_t apiflags;
|
||||||
|
|
||||||
|
LWIP_ASSERT("conn invalid", (conn != NULL) && conn->base.tcp && (conn->base.server == 0));
|
||||||
|
|
||||||
|
do {
|
||||||
|
send_more = 0;
|
||||||
|
if (conn->settings.amount & PP_HTONL(0x80000000)) {
|
||||||
|
/* this session is time-limited */
|
||||||
|
u32_t now = sys_now();
|
||||||
|
u32_t diff_ms = now - conn->time_started;
|
||||||
|
u32_t time = (u32_t)-(s32_t)lwip_htonl(conn->settings.amount);
|
||||||
|
u32_t time_ms = time * 10;
|
||||||
|
if (diff_ms >= time_ms) {
|
||||||
|
/* time specified by the client is over -> close the connection */
|
||||||
|
lwiperf_tcp_close(conn, LWIPERF_TCP_DONE_CLIENT);
|
||||||
|
return ERR_OK;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* this session is byte-limited */
|
||||||
|
u32_t amount_bytes = lwip_htonl(conn->settings.amount);
|
||||||
|
/* @todo: this can send up to 1*MSS more than requested... */
|
||||||
|
if (amount_bytes >= conn->bytes_transferred) {
|
||||||
|
/* all requested bytes transferred -> close the connection */
|
||||||
|
lwiperf_tcp_close(conn, LWIPERF_TCP_DONE_CLIENT);
|
||||||
|
return ERR_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (conn->bytes_transferred < 24) {
|
||||||
|
/* transmit the settings a first time */
|
||||||
|
txptr = &((u8_t*)&conn->settings)[conn->bytes_transferred];
|
||||||
|
txlen_max = (u16_t)(24 - conn->bytes_transferred);
|
||||||
|
apiflags = TCP_WRITE_FLAG_COPY;
|
||||||
|
} else if (conn->bytes_transferred < 48) {
|
||||||
|
/* transmit the settings a second time */
|
||||||
|
txptr = &((u8_t*)&conn->settings)[conn->bytes_transferred - 24];
|
||||||
|
txlen_max = (u16_t)(48 - conn->bytes_transferred);
|
||||||
|
apiflags = TCP_WRITE_FLAG_COPY | TCP_WRITE_FLAG_MORE;
|
||||||
|
send_more = 1;
|
||||||
|
} else {
|
||||||
|
/* transmit data */
|
||||||
|
/* @todo: every x bytes, transmit the settings again */
|
||||||
|
txptr = LWIP_CONST_CAST(void*, &lwiperf_txbuf_const[conn->bytes_transferred % 10]);
|
||||||
|
txlen_max = TCP_MSS;
|
||||||
|
if (conn->bytes_transferred == 48) { /* @todo: fix this for intermediate settings, too */
|
||||||
|
txlen_max = TCP_MSS - 24;
|
||||||
|
}
|
||||||
|
apiflags = 0; /* no copying needed */
|
||||||
|
send_more = 1;
|
||||||
|
}
|
||||||
|
txlen = txlen_max;
|
||||||
|
do {
|
||||||
|
err = tcp_write(conn->conn_pcb, txptr, txlen, apiflags);
|
||||||
|
if (err == ERR_MEM) {
|
||||||
|
txlen /= 2;
|
||||||
|
}
|
||||||
|
} while ((err == ERR_MEM) && (txlen >= (TCP_MSS/2)));
|
||||||
|
|
||||||
|
if (err == ERR_OK) {
|
||||||
|
conn->bytes_transferred += txlen;
|
||||||
|
} else {
|
||||||
|
send_more = 0;
|
||||||
|
}
|
||||||
|
} while(send_more);
|
||||||
|
|
||||||
|
tcp_output(conn->conn_pcb);
|
||||||
|
return ERR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** TCP sent callback, try to send more data */
|
||||||
|
static err_t
|
||||||
|
lwiperf_tcp_client_sent(void *arg, struct tcp_pcb *tpcb, u16_t len)
|
||||||
|
{
|
||||||
|
lwiperf_state_tcp_t* conn = (lwiperf_state_tcp_t*)arg;
|
||||||
|
/* @todo: check 'len' (e.g. to time ACK of all data)? for now, we just send more... */
|
||||||
|
LWIP_ASSERT("invalid conn", conn->conn_pcb == tpcb);
|
||||||
|
LWIP_UNUSED_ARG(tpcb);
|
||||||
|
LWIP_UNUSED_ARG(len);
|
||||||
|
|
||||||
|
conn->poll_count = 0;
|
||||||
|
|
||||||
|
return lwiperf_tcp_client_send_more(conn);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** TCP connected callback (active connection), send data now */
|
||||||
|
static err_t
|
||||||
|
lwiperf_tcp_client_connected(void *arg, struct tcp_pcb *tpcb, err_t err)
|
||||||
|
{
|
||||||
|
lwiperf_state_tcp_t* conn = (lwiperf_state_tcp_t*)arg;
|
||||||
|
LWIP_ASSERT("invalid conn", conn->conn_pcb == tpcb);
|
||||||
|
LWIP_UNUSED_ARG(tpcb);
|
||||||
|
if (err != ERR_OK) {
|
||||||
|
lwiperf_tcp_close(conn, LWIPERF_TCP_ABORTED_REMOTE);
|
||||||
|
return ERR_OK;
|
||||||
|
}
|
||||||
|
conn->poll_count = 0;
|
||||||
|
conn->time_started = sys_now();
|
||||||
|
return lwiperf_tcp_client_send_more(conn);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Start TCP connection back to the client (either parallel or after the
|
||||||
|
* receive test has finished.
|
||||||
|
*/
|
||||||
|
static err_t
|
||||||
|
lwiperf_tx_start(lwiperf_state_tcp_t* conn)
|
||||||
|
{
|
||||||
|
err_t err;
|
||||||
|
lwiperf_state_tcp_t* client_conn;
|
||||||
|
struct tcp_pcb* newpcb;
|
||||||
|
ip_addr_t remote_addr;
|
||||||
|
u16_t remote_port;
|
||||||
|
|
||||||
|
client_conn = (lwiperf_state_tcp_t*)LWIPERF_ALLOC(lwiperf_state_tcp_t);
|
||||||
|
if (client_conn == NULL) {
|
||||||
|
return ERR_MEM;
|
||||||
|
}
|
||||||
|
newpcb = tcp_new();
|
||||||
|
if (newpcb == NULL) {
|
||||||
|
LWIPERF_FREE(lwiperf_state_tcp_t, client_conn);
|
||||||
|
return ERR_MEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
MEMCPY(client_conn, conn, sizeof(lwiperf_state_tcp_t));
|
||||||
|
client_conn->base.server = 0;
|
||||||
|
client_conn->server_pcb = NULL;
|
||||||
|
client_conn->conn_pcb = newpcb;
|
||||||
|
client_conn->time_started = sys_now(); /* @todo: set this again on 'connected' */
|
||||||
|
client_conn->poll_count = 0;
|
||||||
|
client_conn->next_num = 4; /* initial nr is '4' since the header has 24 byte */
|
||||||
|
client_conn->bytes_transferred = 0;
|
||||||
|
client_conn->settings.flags = 0; /* prevent the remote side starting back as client again */
|
||||||
|
|
||||||
|
tcp_arg(newpcb, client_conn);
|
||||||
|
tcp_sent(newpcb, lwiperf_tcp_client_sent);
|
||||||
|
tcp_poll(newpcb, lwiperf_tcp_poll, 2U);
|
||||||
|
tcp_err(newpcb, lwiperf_tcp_err);
|
||||||
|
|
||||||
|
ip_addr_copy(remote_addr, conn->conn_pcb->remote_ip);
|
||||||
|
remote_port = (u16_t)lwip_htonl(client_conn->settings.remote_port);
|
||||||
|
|
||||||
|
err = tcp_connect(newpcb, &remote_addr, remote_port, lwiperf_tcp_client_connected);
|
||||||
|
if (err != ERR_OK) {
|
||||||
|
lwiperf_tcp_close(client_conn, LWIPERF_TCP_ABORTED_LOCAL);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
lwiperf_list_add(&client_conn->base);
|
||||||
|
return ERR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Receive data on an iperf tcp session */
|
||||||
|
static err_t
|
||||||
|
lwiperf_tcp_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err)
|
||||||
|
{
|
||||||
|
u8_t tmp;
|
||||||
|
u16_t tot_len;
|
||||||
|
u32_t packet_idx;
|
||||||
|
struct pbuf* q;
|
||||||
|
lwiperf_state_tcp_t* conn = (lwiperf_state_tcp_t*)arg;
|
||||||
|
|
||||||
|
LWIP_ASSERT("pcb mismatch", conn->conn_pcb == tpcb);
|
||||||
|
LWIP_UNUSED_ARG(tpcb);
|
||||||
|
|
||||||
|
if (err != ERR_OK) {
|
||||||
|
lwiperf_tcp_close(conn, LWIPERF_TCP_ABORTED_REMOTE);
|
||||||
|
return ERR_OK;
|
||||||
|
}
|
||||||
|
if (p == NULL) {
|
||||||
|
/* connection closed -> test done */
|
||||||
|
if ((conn->settings.flags & PP_HTONL(LWIPERF_FLAGS_ANSWER_TEST|LWIPERF_FLAGS_ANSWER_NOW)) ==
|
||||||
|
PP_HTONL(LWIPERF_FLAGS_ANSWER_TEST)) {
|
||||||
|
/* client requested transmission after end of test */
|
||||||
|
lwiperf_tx_start(conn);
|
||||||
|
}
|
||||||
|
lwiperf_tcp_close(conn, LWIPERF_TCP_DONE_SERVER);
|
||||||
|
return ERR_OK;
|
||||||
|
}
|
||||||
|
tot_len = p->tot_len;
|
||||||
|
|
||||||
|
conn->poll_count = 0;
|
||||||
|
|
||||||
|
if ((!conn->have_settings_buf) || ((conn->bytes_transferred -24) % (1024*128) == 0)) {
|
||||||
|
/* wait for 24-byte header */
|
||||||
|
if (p->tot_len < sizeof(lwiperf_settings_t)) {
|
||||||
|
lwiperf_tcp_close(conn, LWIPERF_TCP_ABORTED_LOCAL_DATAERROR);
|
||||||
|
pbuf_free(p);
|
||||||
|
return ERR_VAL;
|
||||||
|
}
|
||||||
|
if (!conn->have_settings_buf) {
|
||||||
|
if (pbuf_copy_partial(p, &conn->settings, sizeof(lwiperf_settings_t), 0) != sizeof(lwiperf_settings_t)) {
|
||||||
|
lwiperf_tcp_close(conn, LWIPERF_TCP_ABORTED_LOCAL);
|
||||||
|
pbuf_free(p);
|
||||||
|
return ERR_VAL;
|
||||||
|
}
|
||||||
|
conn->have_settings_buf = 1;
|
||||||
|
if ((conn->settings.flags & PP_HTONL(LWIPERF_FLAGS_ANSWER_TEST|LWIPERF_FLAGS_ANSWER_NOW)) ==
|
||||||
|
PP_HTONL(LWIPERF_FLAGS_ANSWER_TEST|LWIPERF_FLAGS_ANSWER_NOW)) {
|
||||||
|
/* client requested parallel transmission test */
|
||||||
|
err_t err2 = lwiperf_tx_start(conn);
|
||||||
|
if (err2 != ERR_OK) {
|
||||||
|
lwiperf_tcp_close(conn, LWIPERF_TCP_ABORTED_LOCAL_TXERROR);
|
||||||
|
pbuf_free(p);
|
||||||
|
return err2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (pbuf_memcmp(p, 0, &conn->settings, sizeof(lwiperf_settings_t)) != 0) {
|
||||||
|
lwiperf_tcp_close(conn, LWIPERF_TCP_ABORTED_LOCAL_DATAERROR);
|
||||||
|
pbuf_free(p);
|
||||||
|
return ERR_VAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
conn->bytes_transferred += sizeof(lwiperf_settings_t);
|
||||||
|
if (conn->bytes_transferred <= 24) {
|
||||||
|
conn->time_started = sys_now();
|
||||||
|
tcp_recved(tpcb, p->tot_len);
|
||||||
|
pbuf_free(p);
|
||||||
|
return ERR_OK;
|
||||||
|
}
|
||||||
|
conn->next_num = 4; /* 24 bytes received... */
|
||||||
|
tmp = pbuf_header(p, -24);
|
||||||
|
LWIP_ASSERT("pbuf_header failed", tmp == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
packet_idx = 0;
|
||||||
|
for (q = p; q != NULL; q = q->next) {
|
||||||
|
#if LWIPERF_CHECK_RX_DATA
|
||||||
|
const u8_t* payload = (const u8_t*)q->payload;
|
||||||
|
u16_t i;
|
||||||
|
for (i = 0; i < q->len; i++) {
|
||||||
|
u8_t val = payload[i];
|
||||||
|
u8_t num = val - '0';
|
||||||
|
if (num == conn->next_num) {
|
||||||
|
conn->next_num++;
|
||||||
|
if (conn->next_num == 10) {
|
||||||
|
conn->next_num = 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
lwiperf_tcp_close(conn, LWIPERF_TCP_ABORTED_LOCAL_DATAERROR);
|
||||||
|
pbuf_free(p);
|
||||||
|
return ERR_VAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
packet_idx += q->len;
|
||||||
|
}
|
||||||
|
LWIP_ASSERT("count mismatch", packet_idx == p->tot_len);
|
||||||
|
conn->bytes_transferred += packet_idx;
|
||||||
|
tcp_recved(tpcb, tot_len);
|
||||||
|
pbuf_free(p);
|
||||||
|
return ERR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Error callback, iperf tcp session aborted */
|
||||||
|
static void
|
||||||
|
lwiperf_tcp_err(void *arg, err_t err)
|
||||||
|
{
|
||||||
|
lwiperf_state_tcp_t* conn = (lwiperf_state_tcp_t*)arg;
|
||||||
|
LWIP_UNUSED_ARG(err);
|
||||||
|
lwiperf_tcp_close(conn, LWIPERF_TCP_ABORTED_REMOTE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** TCP poll callback, try to send more data */
|
||||||
|
static err_t
|
||||||
|
lwiperf_tcp_poll(void *arg, struct tcp_pcb *tpcb)
|
||||||
|
{
|
||||||
|
lwiperf_state_tcp_t* conn = (lwiperf_state_tcp_t*)arg;
|
||||||
|
LWIP_ASSERT("pcb mismatch", conn->conn_pcb == tpcb);
|
||||||
|
LWIP_UNUSED_ARG(tpcb);
|
||||||
|
if (++conn->poll_count >= LWIPERF_TCP_MAX_IDLE_SEC) {
|
||||||
|
lwiperf_tcp_close(conn, LWIPERF_TCP_ABORTED_LOCAL);
|
||||||
|
return ERR_OK; /* lwiperf_tcp_close frees conn */
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!conn->base.server) {
|
||||||
|
lwiperf_tcp_client_send_more(conn);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ERR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** This is called when a new client connects for an iperf tcp session */
|
||||||
|
static err_t
|
||||||
|
lwiperf_tcp_accept(void *arg, struct tcp_pcb *newpcb, err_t err)
|
||||||
|
{
|
||||||
|
lwiperf_state_tcp_t *s, *conn;
|
||||||
|
if ((err != ERR_OK) || (newpcb == NULL) || (arg == NULL)) {
|
||||||
|
return ERR_VAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
s = (lwiperf_state_tcp_t*)arg;
|
||||||
|
conn = (lwiperf_state_tcp_t*)LWIPERF_ALLOC(lwiperf_state_tcp_t);
|
||||||
|
if (conn == NULL) {
|
||||||
|
return ERR_MEM;
|
||||||
|
}
|
||||||
|
memset(conn, 0, sizeof(lwiperf_state_tcp_t));
|
||||||
|
conn->base.tcp = 1;
|
||||||
|
conn->base.server = 1;
|
||||||
|
conn->base.related_server_state = &s->base;
|
||||||
|
conn->server_pcb = s->server_pcb;
|
||||||
|
conn->conn_pcb = newpcb;
|
||||||
|
conn->time_started = sys_now();
|
||||||
|
conn->report_fn = s->report_fn;
|
||||||
|
conn->report_arg = s->report_arg;
|
||||||
|
|
||||||
|
/* setup the tcp rx connection */
|
||||||
|
tcp_arg(newpcb, conn);
|
||||||
|
tcp_recv(newpcb, lwiperf_tcp_recv);
|
||||||
|
tcp_poll(newpcb, lwiperf_tcp_poll, 2U);
|
||||||
|
tcp_err(conn->conn_pcb, lwiperf_tcp_err);
|
||||||
|
|
||||||
|
lwiperf_list_add(&conn->base);
|
||||||
|
return ERR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup iperf
|
||||||
|
* Start a TCP iperf server on the default TCP port (5001) and listen for
|
||||||
|
* incoming connections from iperf clients.
|
||||||
|
*
|
||||||
|
* @returns a connection handle that can be used to abort the server
|
||||||
|
* by calling @ref lwiperf_abort()
|
||||||
|
*/
|
||||||
|
void*
|
||||||
|
lwiperf_start_tcp_server_default(lwiperf_report_fn report_fn, void* report_arg)
|
||||||
|
{
|
||||||
|
return lwiperf_start_tcp_server(IP_ADDR_ANY, LWIPERF_TCP_PORT_DEFAULT,
|
||||||
|
report_fn, report_arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup iperf
|
||||||
|
* Start a TCP iperf server on a specific IP address and port and listen for
|
||||||
|
* incoming connections from iperf clients.
|
||||||
|
*
|
||||||
|
* @returns a connection handle that can be used to abort the server
|
||||||
|
* by calling @ref lwiperf_abort()
|
||||||
|
*/
|
||||||
|
void*
|
||||||
|
lwiperf_start_tcp_server(const ip_addr_t* local_addr, u16_t local_port,
|
||||||
|
lwiperf_report_fn report_fn, void* report_arg)
|
||||||
|
{
|
||||||
|
err_t err;
|
||||||
|
struct tcp_pcb* pcb;
|
||||||
|
lwiperf_state_tcp_t* s;
|
||||||
|
|
||||||
|
if (local_addr == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
s = (lwiperf_state_tcp_t*)LWIPERF_ALLOC(lwiperf_state_tcp_t);
|
||||||
|
if (s == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
memset(s, 0, sizeof(lwiperf_state_tcp_t));
|
||||||
|
s->base.tcp = 1;
|
||||||
|
s->base.server = 1;
|
||||||
|
s->report_fn = report_fn;
|
||||||
|
s->report_arg = report_arg;
|
||||||
|
|
||||||
|
pcb = tcp_new();
|
||||||
|
if (pcb != NULL) {
|
||||||
|
err = tcp_bind(pcb, local_addr, local_port);
|
||||||
|
if (err == ERR_OK) {
|
||||||
|
s->server_pcb = tcp_listen_with_backlog(pcb, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (s->server_pcb == NULL) {
|
||||||
|
if (pcb != NULL) {
|
||||||
|
tcp_close(pcb);
|
||||||
|
}
|
||||||
|
LWIPERF_FREE(lwiperf_state_tcp_t, s);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
pcb = NULL;
|
||||||
|
|
||||||
|
tcp_arg(s->server_pcb, s);
|
||||||
|
tcp_accept(s->server_pcb, lwiperf_tcp_accept);
|
||||||
|
|
||||||
|
lwiperf_list_add(&s->base);
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup iperf
|
||||||
|
* Abort an iperf session (handle returned by lwiperf_start_tcp_server*())
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
lwiperf_abort(void* lwiperf_session)
|
||||||
|
{
|
||||||
|
lwiperf_state_base_t* i, *dealloc, *last = NULL;
|
||||||
|
|
||||||
|
for (i = lwiperf_all_connections; i != NULL; ) {
|
||||||
|
if ((i == lwiperf_session) || (i->related_server_state == lwiperf_session)) {
|
||||||
|
dealloc = i;
|
||||||
|
i = i->next;
|
||||||
|
if (last != NULL) {
|
||||||
|
last->next = i;
|
||||||
|
}
|
||||||
|
LWIPERF_FREE(lwiperf_state_tcp_t, dealloc); /* @todo: type? */
|
||||||
|
} else {
|
||||||
|
last = i;
|
||||||
|
i = i->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* LWIP_IPV4 && LWIP_TCP */
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,367 @@
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* NetBIOS name service responder
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @defgroup netbiosns NETBIOS responder
|
||||||
|
* @ingroup apps
|
||||||
|
*
|
||||||
|
* This is an example implementation of a NetBIOS name server.
|
||||||
|
* It responds to name queries for a configurable name.
|
||||||
|
* Name resolving is not supported.
|
||||||
|
*
|
||||||
|
* Note that the device doesn't broadcast it's own name so can't
|
||||||
|
* detect duplicate names!
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||||
|
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||||
|
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
|
* OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* This file is part of the lwIP TCP/IP stack.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "lwip/apps/netbiosns.h"
|
||||||
|
|
||||||
|
#if LWIP_IPV4 && LWIP_UDP /* don't build if not configured for use in lwipopts.h */
|
||||||
|
|
||||||
|
#include "lwip/def.h"
|
||||||
|
#include "lwip/udp.h"
|
||||||
|
#include "lwip/netif.h"
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
/** default port number for "NetBIOS Name service */
|
||||||
|
#define NETBIOS_PORT 137
|
||||||
|
|
||||||
|
/** size of a NetBIOS name */
|
||||||
|
#define NETBIOS_NAME_LEN 16
|
||||||
|
|
||||||
|
/** The Time-To-Live for NetBIOS name responds (in seconds)
|
||||||
|
* Default is 300000 seconds (3 days, 11 hours, 20 minutes) */
|
||||||
|
#define NETBIOS_NAME_TTL 300000u
|
||||||
|
|
||||||
|
/** NetBIOS header flags */
|
||||||
|
#define NETB_HFLAG_RESPONSE 0x8000U
|
||||||
|
#define NETB_HFLAG_OPCODE 0x7800U
|
||||||
|
#define NETB_HFLAG_OPCODE_NAME_QUERY 0x0000U
|
||||||
|
#define NETB_HFLAG_AUTHORATIVE 0x0400U
|
||||||
|
#define NETB_HFLAG_TRUNCATED 0x0200U
|
||||||
|
#define NETB_HFLAG_RECURS_DESIRED 0x0100U
|
||||||
|
#define NETB_HFLAG_RECURS_AVAILABLE 0x0080U
|
||||||
|
#define NETB_HFLAG_BROADCAST 0x0010U
|
||||||
|
#define NETB_HFLAG_REPLYCODE 0x0008U
|
||||||
|
#define NETB_HFLAG_REPLYCODE_NOERROR 0x0000U
|
||||||
|
|
||||||
|
/** NetBIOS name flags */
|
||||||
|
#define NETB_NFLAG_UNIQUE 0x8000U
|
||||||
|
#define NETB_NFLAG_NODETYPE 0x6000U
|
||||||
|
#define NETB_NFLAG_NODETYPE_HNODE 0x6000U
|
||||||
|
#define NETB_NFLAG_NODETYPE_MNODE 0x4000U
|
||||||
|
#define NETB_NFLAG_NODETYPE_PNODE 0x2000U
|
||||||
|
#define NETB_NFLAG_NODETYPE_BNODE 0x0000U
|
||||||
|
|
||||||
|
/** NetBIOS message header */
|
||||||
|
#ifdef PACK_STRUCT_USE_INCLUDES
|
||||||
|
# include "arch/bpstruct.h"
|
||||||
|
#endif
|
||||||
|
PACK_STRUCT_BEGIN
|
||||||
|
struct netbios_hdr {
|
||||||
|
PACK_STRUCT_FIELD(u16_t trans_id);
|
||||||
|
PACK_STRUCT_FIELD(u16_t flags);
|
||||||
|
PACK_STRUCT_FIELD(u16_t questions);
|
||||||
|
PACK_STRUCT_FIELD(u16_t answerRRs);
|
||||||
|
PACK_STRUCT_FIELD(u16_t authorityRRs);
|
||||||
|
PACK_STRUCT_FIELD(u16_t additionalRRs);
|
||||||
|
} PACK_STRUCT_STRUCT;
|
||||||
|
PACK_STRUCT_END
|
||||||
|
#ifdef PACK_STRUCT_USE_INCLUDES
|
||||||
|
# include "arch/epstruct.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** NetBIOS message name part */
|
||||||
|
#ifdef PACK_STRUCT_USE_INCLUDES
|
||||||
|
# include "arch/bpstruct.h"
|
||||||
|
#endif
|
||||||
|
PACK_STRUCT_BEGIN
|
||||||
|
struct netbios_name_hdr {
|
||||||
|
PACK_STRUCT_FLD_8(u8_t nametype);
|
||||||
|
PACK_STRUCT_FLD_8(u8_t encname[(NETBIOS_NAME_LEN*2)+1]);
|
||||||
|
PACK_STRUCT_FIELD(u16_t type);
|
||||||
|
PACK_STRUCT_FIELD(u16_t cls);
|
||||||
|
PACK_STRUCT_FIELD(u32_t ttl);
|
||||||
|
PACK_STRUCT_FIELD(u16_t datalen);
|
||||||
|
PACK_STRUCT_FIELD(u16_t flags);
|
||||||
|
PACK_STRUCT_FLD_S(ip4_addr_p_t addr);
|
||||||
|
} PACK_STRUCT_STRUCT;
|
||||||
|
PACK_STRUCT_END
|
||||||
|
#ifdef PACK_STRUCT_USE_INCLUDES
|
||||||
|
# include "arch/epstruct.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** NetBIOS message */
|
||||||
|
#ifdef PACK_STRUCT_USE_INCLUDES
|
||||||
|
# include "arch/bpstruct.h"
|
||||||
|
#endif
|
||||||
|
PACK_STRUCT_BEGIN
|
||||||
|
struct netbios_resp
|
||||||
|
{
|
||||||
|
struct netbios_hdr resp_hdr;
|
||||||
|
struct netbios_name_hdr resp_name;
|
||||||
|
} PACK_STRUCT_STRUCT;
|
||||||
|
PACK_STRUCT_END
|
||||||
|
#ifdef PACK_STRUCT_USE_INCLUDES
|
||||||
|
# include "arch/epstruct.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef NETBIOS_LWIP_NAME
|
||||||
|
#define NETBIOS_LOCAL_NAME NETBIOS_LWIP_NAME
|
||||||
|
#else
|
||||||
|
static char netbiosns_local_name[NETBIOS_NAME_LEN];
|
||||||
|
#define NETBIOS_LOCAL_NAME netbiosns_local_name
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct udp_pcb *netbiosns_pcb;
|
||||||
|
|
||||||
|
/** Decode a NetBIOS name (from packet to string) */
|
||||||
|
static int
|
||||||
|
netbiosns_name_decode(char *name_enc, char *name_dec, int name_dec_len)
|
||||||
|
{
|
||||||
|
char *pname;
|
||||||
|
char cname;
|
||||||
|
char cnbname;
|
||||||
|
int idx = 0;
|
||||||
|
|
||||||
|
LWIP_UNUSED_ARG(name_dec_len);
|
||||||
|
|
||||||
|
/* Start decoding netbios name. */
|
||||||
|
pname = name_enc;
|
||||||
|
for (;;) {
|
||||||
|
/* Every two characters of the first level-encoded name
|
||||||
|
* turn into one character in the decoded name. */
|
||||||
|
cname = *pname;
|
||||||
|
if (cname == '\0')
|
||||||
|
break; /* no more characters */
|
||||||
|
if (cname == '.')
|
||||||
|
break; /* scope ID follows */
|
||||||
|
if (cname < 'A' || cname > 'Z') {
|
||||||
|
/* Not legal. */
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
cname -= 'A';
|
||||||
|
cnbname = cname << 4;
|
||||||
|
pname++;
|
||||||
|
|
||||||
|
cname = *pname;
|
||||||
|
if (cname == '\0' || cname == '.') {
|
||||||
|
/* No more characters in the name - but we're in
|
||||||
|
* the middle of a pair. Not legal. */
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (cname < 'A' || cname > 'Z') {
|
||||||
|
/* Not legal. */
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
cname -= 'A';
|
||||||
|
cnbname |= cname;
|
||||||
|
pname++;
|
||||||
|
|
||||||
|
/* Do we have room to store the character? */
|
||||||
|
if (idx < NETBIOS_NAME_LEN) {
|
||||||
|
/* Yes - store the character. */
|
||||||
|
name_dec[idx++] = (cnbname!=' '?cnbname:'\0');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0 /* function currently unused */
|
||||||
|
/** Encode a NetBIOS name (from string to packet) - currently unused because
|
||||||
|
we don't ask for names. */
|
||||||
|
static int
|
||||||
|
netbiosns_name_encode(char *name_enc, char *name_dec, int name_dec_len)
|
||||||
|
{
|
||||||
|
char *pname;
|
||||||
|
char cname;
|
||||||
|
unsigned char ucname;
|
||||||
|
int idx = 0;
|
||||||
|
|
||||||
|
/* Start encoding netbios name. */
|
||||||
|
pname = name_enc;
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
/* Every two characters of the first level-encoded name
|
||||||
|
* turn into one character in the decoded name. */
|
||||||
|
cname = *pname;
|
||||||
|
if (cname == '\0')
|
||||||
|
break; /* no more characters */
|
||||||
|
if (cname == '.')
|
||||||
|
break; /* scope ID follows */
|
||||||
|
if ((cname < 'A' || cname > 'Z') && (cname < '0' || cname > '9')) {
|
||||||
|
/* Not legal. */
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Do we have room to store the character? */
|
||||||
|
if (idx >= name_dec_len) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Yes - store the character. */
|
||||||
|
ucname = cname;
|
||||||
|
name_dec[idx++] = ('A'+((ucname>>4) & 0x0F));
|
||||||
|
name_dec[idx++] = ('A'+( ucname & 0x0F));
|
||||||
|
pname++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fill with "space" coding */
|
||||||
|
for (;idx < name_dec_len - 1;) {
|
||||||
|
name_dec[idx++] = 'C';
|
||||||
|
name_dec[idx++] = 'A';
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Terminate string */
|
||||||
|
name_dec[idx] = '\0';
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif /* 0 */
|
||||||
|
|
||||||
|
/** NetBIOS Name service recv callback */
|
||||||
|
static void
|
||||||
|
netbiosns_recv(void *arg, struct udp_pcb *upcb, struct pbuf *p, const ip_addr_t *addr, u16_t port)
|
||||||
|
{
|
||||||
|
LWIP_UNUSED_ARG(arg);
|
||||||
|
|
||||||
|
/* if packet is valid */
|
||||||
|
if (p != NULL) {
|
||||||
|
char netbios_name[NETBIOS_NAME_LEN+1];
|
||||||
|
struct netbios_hdr* netbios_hdr = (struct netbios_hdr*)p->payload;
|
||||||
|
struct netbios_name_hdr* netbios_name_hdr = (struct netbios_name_hdr*)(netbios_hdr+1);
|
||||||
|
|
||||||
|
/* we only answer if we got a default interface */
|
||||||
|
if (netif_default != NULL) {
|
||||||
|
/* @todo: do we need to check answerRRs/authorityRRs/additionalRRs? */
|
||||||
|
/* if the packet is a NetBIOS name query question */
|
||||||
|
if (((netbios_hdr->flags & PP_NTOHS(NETB_HFLAG_OPCODE)) == PP_NTOHS(NETB_HFLAG_OPCODE_NAME_QUERY)) &&
|
||||||
|
((netbios_hdr->flags & PP_NTOHS(NETB_HFLAG_RESPONSE)) == 0) &&
|
||||||
|
(netbios_hdr->questions == PP_NTOHS(1))) {
|
||||||
|
/* decode the NetBIOS name */
|
||||||
|
netbiosns_name_decode((char*)(netbios_name_hdr->encname), netbios_name, sizeof(netbios_name));
|
||||||
|
/* if the packet is for us */
|
||||||
|
if (lwip_strnicmp(netbios_name, NETBIOS_LOCAL_NAME, sizeof(NETBIOS_LOCAL_NAME)) == 0) {
|
||||||
|
struct pbuf *q;
|
||||||
|
struct netbios_resp *resp;
|
||||||
|
|
||||||
|
q = pbuf_alloc(PBUF_TRANSPORT, sizeof(struct netbios_resp), PBUF_RAM);
|
||||||
|
if (q != NULL) {
|
||||||
|
resp = (struct netbios_resp*)q->payload;
|
||||||
|
|
||||||
|
/* prepare NetBIOS header response */
|
||||||
|
resp->resp_hdr.trans_id = netbios_hdr->trans_id;
|
||||||
|
resp->resp_hdr.flags = PP_HTONS(NETB_HFLAG_RESPONSE |
|
||||||
|
NETB_HFLAG_OPCODE_NAME_QUERY |
|
||||||
|
NETB_HFLAG_AUTHORATIVE |
|
||||||
|
NETB_HFLAG_RECURS_DESIRED);
|
||||||
|
resp->resp_hdr.questions = 0;
|
||||||
|
resp->resp_hdr.answerRRs = PP_HTONS(1);
|
||||||
|
resp->resp_hdr.authorityRRs = 0;
|
||||||
|
resp->resp_hdr.additionalRRs = 0;
|
||||||
|
|
||||||
|
/* prepare NetBIOS header datas */
|
||||||
|
MEMCPY( resp->resp_name.encname, netbios_name_hdr->encname, sizeof(netbios_name_hdr->encname));
|
||||||
|
resp->resp_name.nametype = netbios_name_hdr->nametype;
|
||||||
|
resp->resp_name.type = netbios_name_hdr->type;
|
||||||
|
resp->resp_name.cls = netbios_name_hdr->cls;
|
||||||
|
resp->resp_name.ttl = PP_HTONL(NETBIOS_NAME_TTL);
|
||||||
|
resp->resp_name.datalen = PP_HTONS(sizeof(resp->resp_name.flags)+sizeof(resp->resp_name.addr));
|
||||||
|
resp->resp_name.flags = PP_HTONS(NETB_NFLAG_NODETYPE_BNODE);
|
||||||
|
ip4_addr_copy(resp->resp_name.addr, *netif_ip4_addr(netif_default));
|
||||||
|
|
||||||
|
/* send the NetBIOS response */
|
||||||
|
udp_sendto(upcb, q, addr, port);
|
||||||
|
|
||||||
|
/* free the "reference" pbuf */
|
||||||
|
pbuf_free(q);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* free the pbuf */
|
||||||
|
pbuf_free(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup netbiosns
|
||||||
|
* Init netbios responder
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
netbiosns_init(void)
|
||||||
|
{
|
||||||
|
#ifdef NETBIOS_LWIP_NAME
|
||||||
|
LWIP_ASSERT("NetBIOS name is too long!", strlen(NETBIOS_LWIP_NAME) < NETBIOS_NAME_LEN);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
netbiosns_pcb = udp_new_ip_type(IPADDR_TYPE_ANY);
|
||||||
|
if (netbiosns_pcb != NULL) {
|
||||||
|
/* we have to be allowed to send broadcast packets! */
|
||||||
|
ip_set_option(netbiosns_pcb, SOF_BROADCAST);
|
||||||
|
udp_bind(netbiosns_pcb, IP_ANY_TYPE, NETBIOS_PORT);
|
||||||
|
udp_recv(netbiosns_pcb, netbiosns_recv, netbiosns_pcb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef NETBIOS_LWIP_NAME
|
||||||
|
/**
|
||||||
|
* @ingroup netbiosns
|
||||||
|
* Set netbios name. ATTENTION: the hostname must be less than 15 characters!
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
netbiosns_set_name(const char* hostname)
|
||||||
|
{
|
||||||
|
size_t copy_len = strlen(hostname);
|
||||||
|
LWIP_ASSERT("NetBIOS name is too long!", copy_len < NETBIOS_NAME_LEN);
|
||||||
|
if (copy_len >= NETBIOS_NAME_LEN) {
|
||||||
|
copy_len = NETBIOS_NAME_LEN - 1;
|
||||||
|
}
|
||||||
|
MEMCPY(netbiosns_local_name, hostname, copy_len + 1);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup netbiosns
|
||||||
|
* Stop netbios responder
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
netbiosns_stop(void)
|
||||||
|
{
|
||||||
|
if (netbiosns_pcb != NULL) {
|
||||||
|
udp_remove(netbiosns_pcb);
|
||||||
|
netbiosns_pcb = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* LWIP_IPV4 && LWIP_UDP */
|
|
@ -0,0 +1,749 @@
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* Abstract Syntax Notation One (ISO 8824, 8825) encoding
|
||||||
|
*
|
||||||
|
* @todo not optimised (yet), favor correctness over speed, favor speed over size
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006 Axon Digital Design B.V., The Netherlands.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||||
|
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||||
|
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
|
* OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* Author: Christiaan Simons <christiaan.simons@axon.tv>
|
||||||
|
* Martin Hentschel <info@cl-soft.de>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "lwip/apps/snmp_opts.h"
|
||||||
|
|
||||||
|
#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */
|
||||||
|
|
||||||
|
#include "snmp_asn1.h"
|
||||||
|
|
||||||
|
#define PBUF_OP_EXEC(code) \
|
||||||
|
if ((code) != ERR_OK) { \
|
||||||
|
return ERR_BUF; \
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encodes a TLV into a pbuf stream.
|
||||||
|
*
|
||||||
|
* @param pbuf_stream points to a pbuf stream
|
||||||
|
* @param tlv TLV to encode
|
||||||
|
* @return ERR_OK if successful, ERR_ARG if we can't (or won't) encode
|
||||||
|
*/
|
||||||
|
err_t
|
||||||
|
snmp_ans1_enc_tlv(struct snmp_pbuf_stream* pbuf_stream, struct snmp_asn1_tlv* tlv)
|
||||||
|
{
|
||||||
|
u8_t data;
|
||||||
|
u8_t length_bytes_required;
|
||||||
|
|
||||||
|
/* write type */
|
||||||
|
if ((tlv->type & SNMP_ASN1_DATATYPE_MASK) == SNMP_ASN1_DATATYPE_EXTENDED) {
|
||||||
|
/* extended format is not used by SNMP so we do not accept those values */
|
||||||
|
return ERR_ARG;
|
||||||
|
}
|
||||||
|
if (tlv->type_len != 0) {
|
||||||
|
/* any other value as auto is not accepted for type (we always use one byte because extended syntax is prohibited) */
|
||||||
|
return ERR_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
PBUF_OP_EXEC(snmp_pbuf_stream_write(pbuf_stream, tlv->type));
|
||||||
|
tlv->type_len = 1;
|
||||||
|
|
||||||
|
/* write length */
|
||||||
|
if (tlv->value_len <= 127) {
|
||||||
|
length_bytes_required = 1;
|
||||||
|
} else if (tlv->value_len <= 255) {
|
||||||
|
length_bytes_required = 2;
|
||||||
|
} else {
|
||||||
|
length_bytes_required = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check for forced min length */
|
||||||
|
if (tlv->length_len > 0) {
|
||||||
|
if (tlv->length_len < length_bytes_required) {
|
||||||
|
/* unable to code requested length in requested number of bytes */
|
||||||
|
return ERR_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
length_bytes_required = tlv->length_len;
|
||||||
|
} else {
|
||||||
|
tlv->length_len = length_bytes_required;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (length_bytes_required > 1) {
|
||||||
|
/* multi byte representation required */
|
||||||
|
length_bytes_required--;
|
||||||
|
data = 0x80 | length_bytes_required; /* extended length definition, 1 length byte follows */
|
||||||
|
|
||||||
|
PBUF_OP_EXEC(snmp_pbuf_stream_write(pbuf_stream, data));
|
||||||
|
|
||||||
|
while (length_bytes_required > 1) {
|
||||||
|
if (length_bytes_required == 2) {
|
||||||
|
/* append high byte */
|
||||||
|
data = (u8_t)(tlv->value_len >> 8);
|
||||||
|
} else {
|
||||||
|
/* append leading 0x00 */
|
||||||
|
data = 0x00;
|
||||||
|
}
|
||||||
|
|
||||||
|
PBUF_OP_EXEC(snmp_pbuf_stream_write(pbuf_stream, data));
|
||||||
|
length_bytes_required--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* append low byte */
|
||||||
|
data = (u8_t)(tlv->value_len & 0xFF);
|
||||||
|
PBUF_OP_EXEC(snmp_pbuf_stream_write(pbuf_stream, data));
|
||||||
|
|
||||||
|
return ERR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encodes raw data (octet string, opaque) into a pbuf chained ASN1 msg.
|
||||||
|
*
|
||||||
|
* @param pbuf_stream points to a pbuf stream
|
||||||
|
* @param raw_len raw data length
|
||||||
|
* @param raw points raw data
|
||||||
|
* @return ERR_OK if successful, ERR_ARG if we can't (or won't) encode
|
||||||
|
*/
|
||||||
|
err_t
|
||||||
|
snmp_asn1_enc_raw(struct snmp_pbuf_stream* pbuf_stream, const u8_t *raw, u16_t raw_len)
|
||||||
|
{
|
||||||
|
PBUF_OP_EXEC(snmp_pbuf_stream_writebuf(pbuf_stream, raw, raw_len));
|
||||||
|
|
||||||
|
return ERR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encodes u32_t (counter, gauge, timeticks) into a pbuf chained ASN1 msg.
|
||||||
|
*
|
||||||
|
* @param pbuf_stream points to a pbuf stream
|
||||||
|
* @param octets_needed encoding length (from snmp_asn1_enc_u32t_cnt())
|
||||||
|
* @param value is the host order u32_t value to be encoded
|
||||||
|
* @return ERR_OK if successful, ERR_ARG if we can't (or won't) encode
|
||||||
|
*
|
||||||
|
* @see snmp_asn1_enc_u32t_cnt()
|
||||||
|
*/
|
||||||
|
err_t
|
||||||
|
snmp_asn1_enc_u32t(struct snmp_pbuf_stream* pbuf_stream, u16_t octets_needed, u32_t value)
|
||||||
|
{
|
||||||
|
if (octets_needed > 5) {
|
||||||
|
return ERR_ARG;
|
||||||
|
}
|
||||||
|
if (octets_needed == 5) {
|
||||||
|
/* not enough bits in 'value' add leading 0x00 */
|
||||||
|
PBUF_OP_EXEC(snmp_pbuf_stream_write(pbuf_stream, 0x00));
|
||||||
|
octets_needed--;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (octets_needed > 1) {
|
||||||
|
octets_needed--;
|
||||||
|
PBUF_OP_EXEC(snmp_pbuf_stream_write(pbuf_stream, (u8_t)(value >> (octets_needed << 3))));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (only) one least significant octet */
|
||||||
|
PBUF_OP_EXEC(snmp_pbuf_stream_write(pbuf_stream, (u8_t)value));
|
||||||
|
|
||||||
|
return ERR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encodes u64_t (counter64) into a pbuf chained ASN1 msg.
|
||||||
|
*
|
||||||
|
* @param pbuf_stream points to a pbuf stream
|
||||||
|
* @param octets_needed encoding length (from snmp_asn1_enc_u32t_cnt())
|
||||||
|
* @param value is the host order u32_t value to be encoded
|
||||||
|
* @return ERR_OK if successful, ERR_ARG if we can't (or won't) encode
|
||||||
|
*
|
||||||
|
* @see snmp_asn1_enc_u64t_cnt()
|
||||||
|
*/
|
||||||
|
err_t
|
||||||
|
snmp_asn1_enc_u64t(struct snmp_pbuf_stream* pbuf_stream, u16_t octets_needed, const u32_t* value)
|
||||||
|
{
|
||||||
|
if (octets_needed > 9) {
|
||||||
|
return ERR_ARG;
|
||||||
|
}
|
||||||
|
if (octets_needed == 9) {
|
||||||
|
/* not enough bits in 'value' add leading 0x00 */
|
||||||
|
PBUF_OP_EXEC(snmp_pbuf_stream_write(pbuf_stream, 0x00));
|
||||||
|
octets_needed--;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (octets_needed > 4) {
|
||||||
|
octets_needed--;
|
||||||
|
PBUF_OP_EXEC(snmp_pbuf_stream_write(pbuf_stream, (u8_t)(*value >> ((octets_needed-4) << 3))));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* skip to low u32 */
|
||||||
|
value++;
|
||||||
|
|
||||||
|
while (octets_needed > 1) {
|
||||||
|
octets_needed--;
|
||||||
|
PBUF_OP_EXEC(snmp_pbuf_stream_write(pbuf_stream, (u8_t)(*value >> (octets_needed << 3))));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* always write at least one octet (also in case of value == 0) */
|
||||||
|
PBUF_OP_EXEC(snmp_pbuf_stream_write(pbuf_stream, (u8_t)(*value)));
|
||||||
|
|
||||||
|
return ERR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encodes s32_t integer into a pbuf chained ASN1 msg.
|
||||||
|
*
|
||||||
|
* @param pbuf_stream points to a pbuf stream
|
||||||
|
* @param octets_needed encoding length (from snmp_asn1_enc_s32t_cnt())
|
||||||
|
* @param value is the host order s32_t value to be encoded
|
||||||
|
* @return ERR_OK if successful, ERR_ARG if we can't (or won't) encode
|
||||||
|
*
|
||||||
|
* @see snmp_asn1_enc_s32t_cnt()
|
||||||
|
*/
|
||||||
|
err_t
|
||||||
|
snmp_asn1_enc_s32t(struct snmp_pbuf_stream* pbuf_stream, u16_t octets_needed, s32_t value)
|
||||||
|
{
|
||||||
|
while (octets_needed > 1) {
|
||||||
|
octets_needed--;
|
||||||
|
|
||||||
|
PBUF_OP_EXEC(snmp_pbuf_stream_write(pbuf_stream, (u8_t)(value >> (octets_needed << 3))));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (only) one least significant octet */
|
||||||
|
PBUF_OP_EXEC(snmp_pbuf_stream_write(pbuf_stream, (u8_t)value));
|
||||||
|
|
||||||
|
return ERR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encodes object identifier into a pbuf chained ASN1 msg.
|
||||||
|
*
|
||||||
|
* @param pbuf_stream points to a pbuf stream
|
||||||
|
* @param oid points to object identifier array
|
||||||
|
* @param oid_len object identifier array length
|
||||||
|
* @return ERR_OK if successful, ERR_ARG if we can't (or won't) encode
|
||||||
|
*/
|
||||||
|
err_t
|
||||||
|
snmp_asn1_enc_oid(struct snmp_pbuf_stream* pbuf_stream, const u32_t *oid, u16_t oid_len)
|
||||||
|
{
|
||||||
|
if (oid_len > 1) {
|
||||||
|
/* write compressed first two sub id's */
|
||||||
|
u32_t compressed_byte = ((oid[0] * 40) + oid[1]);
|
||||||
|
PBUF_OP_EXEC(snmp_pbuf_stream_write(pbuf_stream, (u8_t)compressed_byte));
|
||||||
|
oid_len -= 2;
|
||||||
|
oid += 2;
|
||||||
|
} else {
|
||||||
|
/* @bug: allow empty varbinds for symmetry (we must decode them for getnext), allow partial compression?? */
|
||||||
|
/* ident_len <= 1, at least we need zeroDotZero (0.0) (ident_len == 2) */
|
||||||
|
return ERR_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (oid_len > 0) {
|
||||||
|
u32_t sub_id;
|
||||||
|
u8_t shift, tail;
|
||||||
|
|
||||||
|
oid_len--;
|
||||||
|
sub_id = *oid;
|
||||||
|
tail = 0;
|
||||||
|
shift = 28;
|
||||||
|
while (shift > 0) {
|
||||||
|
u8_t code;
|
||||||
|
|
||||||
|
code = (u8_t)(sub_id >> shift);
|
||||||
|
if ((code != 0) || (tail != 0)) {
|
||||||
|
tail = 1;
|
||||||
|
PBUF_OP_EXEC(snmp_pbuf_stream_write(pbuf_stream, code | 0x80));
|
||||||
|
}
|
||||||
|
shift -= 7;
|
||||||
|
}
|
||||||
|
PBUF_OP_EXEC(snmp_pbuf_stream_write(pbuf_stream, (u8_t)sub_id & 0x7F));
|
||||||
|
|
||||||
|
/* proceed to next sub-identifier */
|
||||||
|
oid++;
|
||||||
|
}
|
||||||
|
return ERR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns octet count for length.
|
||||||
|
*
|
||||||
|
* @param length parameter length
|
||||||
|
* @param octets_needed points to the return value
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
snmp_asn1_enc_length_cnt(u16_t length, u8_t *octets_needed)
|
||||||
|
{
|
||||||
|
if (length < 0x80U) {
|
||||||
|
*octets_needed = 1;
|
||||||
|
} else if (length < 0x100U) {
|
||||||
|
*octets_needed = 2;
|
||||||
|
} else {
|
||||||
|
*octets_needed = 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns octet count for an u32_t.
|
||||||
|
*
|
||||||
|
* @param value value to be encoded
|
||||||
|
* @param octets_needed points to the return value
|
||||||
|
*
|
||||||
|
* @note ASN coded integers are _always_ signed. E.g. +0xFFFF is coded
|
||||||
|
* as 0x00,0xFF,0xFF. Note the leading sign octet. A positive value
|
||||||
|
* of 0xFFFFFFFF is preceded with 0x00 and the length is 5 octets!!
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
snmp_asn1_enc_u32t_cnt(u32_t value, u16_t *octets_needed)
|
||||||
|
{
|
||||||
|
if (value < 0x80UL) {
|
||||||
|
*octets_needed = 1;
|
||||||
|
} else if (value < 0x8000UL) {
|
||||||
|
*octets_needed = 2;
|
||||||
|
} else if (value < 0x800000UL) {
|
||||||
|
*octets_needed = 3;
|
||||||
|
} else if (value < 0x80000000UL) {
|
||||||
|
*octets_needed = 4;
|
||||||
|
} else {
|
||||||
|
*octets_needed = 5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns octet count for an u64_t.
|
||||||
|
*
|
||||||
|
* @param value value to be encoded
|
||||||
|
* @param octets_needed points to the return value
|
||||||
|
*
|
||||||
|
* @note ASN coded integers are _always_ signed. E.g. +0xFFFF is coded
|
||||||
|
* as 0x00,0xFF,0xFF. Note the leading sign octet. A positive value
|
||||||
|
* of 0xFFFFFFFF is preceded with 0x00 and the length is 5 octets!!
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
snmp_asn1_enc_u64t_cnt(const u32_t *value, u16_t *octets_needed)
|
||||||
|
{
|
||||||
|
/* check if high u32 is 0 */
|
||||||
|
if (*value == 0x00) {
|
||||||
|
/* only low u32 is important */
|
||||||
|
value++;
|
||||||
|
snmp_asn1_enc_u32t_cnt(*value, octets_needed);
|
||||||
|
} else {
|
||||||
|
/* low u32 does not matter for length determination */
|
||||||
|
snmp_asn1_enc_u32t_cnt(*value, octets_needed);
|
||||||
|
*octets_needed = *octets_needed + 4; /* add the 4 bytes of low u32 */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns octet count for an s32_t.
|
||||||
|
*
|
||||||
|
* @param value value to be encoded
|
||||||
|
* @param octets_needed points to the return value
|
||||||
|
*
|
||||||
|
* @note ASN coded integers are _always_ signed.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
snmp_asn1_enc_s32t_cnt(s32_t value, u16_t *octets_needed)
|
||||||
|
{
|
||||||
|
if (value < 0) {
|
||||||
|
value = ~value;
|
||||||
|
}
|
||||||
|
if (value < 0x80L) {
|
||||||
|
*octets_needed = 1;
|
||||||
|
} else if (value < 0x8000L) {
|
||||||
|
*octets_needed = 2;
|
||||||
|
} else if (value < 0x800000L) {
|
||||||
|
*octets_needed = 3;
|
||||||
|
} else {
|
||||||
|
*octets_needed = 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns octet count for an object identifier.
|
||||||
|
*
|
||||||
|
* @param oid points to object identifier array
|
||||||
|
* @param oid_len object identifier array length
|
||||||
|
* @param octets_needed points to the return value
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
snmp_asn1_enc_oid_cnt(const u32_t *oid, u16_t oid_len, u16_t *octets_needed)
|
||||||
|
{
|
||||||
|
u32_t sub_id;
|
||||||
|
|
||||||
|
*octets_needed = 0;
|
||||||
|
if (oid_len > 1) {
|
||||||
|
/* compressed prefix in one octet */
|
||||||
|
(*octets_needed)++;
|
||||||
|
oid_len -= 2;
|
||||||
|
oid += 2;
|
||||||
|
}
|
||||||
|
while (oid_len > 0) {
|
||||||
|
oid_len--;
|
||||||
|
sub_id = *oid;
|
||||||
|
|
||||||
|
sub_id >>= 7;
|
||||||
|
(*octets_needed)++;
|
||||||
|
while (sub_id > 0) {
|
||||||
|
sub_id >>= 7;
|
||||||
|
(*octets_needed)++;
|
||||||
|
}
|
||||||
|
oid++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decodes a TLV from a pbuf stream.
|
||||||
|
*
|
||||||
|
* @param pbuf_stream points to a pbuf stream
|
||||||
|
* @param tlv returns decoded TLV
|
||||||
|
* @return ERR_OK if successful, ERR_VAL if we can't decode
|
||||||
|
*/
|
||||||
|
err_t
|
||||||
|
snmp_asn1_dec_tlv(struct snmp_pbuf_stream* pbuf_stream, struct snmp_asn1_tlv* tlv)
|
||||||
|
{
|
||||||
|
u8_t data;
|
||||||
|
|
||||||
|
/* decode type first */
|
||||||
|
PBUF_OP_EXEC(snmp_pbuf_stream_read(pbuf_stream, &data));
|
||||||
|
tlv->type = data;
|
||||||
|
|
||||||
|
if ((tlv->type & SNMP_ASN1_DATATYPE_MASK) == SNMP_ASN1_DATATYPE_EXTENDED) {
|
||||||
|
/* extended format is not used by SNMP so we do not accept those values */
|
||||||
|
return ERR_VAL;
|
||||||
|
}
|
||||||
|
tlv->type_len = 1;
|
||||||
|
|
||||||
|
/* now, decode length */
|
||||||
|
PBUF_OP_EXEC(snmp_pbuf_stream_read(pbuf_stream, &data));
|
||||||
|
|
||||||
|
if (data < 0x80) { /* short form */
|
||||||
|
tlv->length_len = 1;
|
||||||
|
tlv->value_len = data;
|
||||||
|
} else if (data > 0x80) { /* long form */
|
||||||
|
u8_t length_bytes = data - 0x80;
|
||||||
|
tlv->length_len = length_bytes + 1; /* this byte + defined number of length bytes following */
|
||||||
|
tlv->value_len = 0;
|
||||||
|
|
||||||
|
while (length_bytes > 0) {
|
||||||
|
/* we only support up to u16.maxvalue-1 (2 bytes) but have to accept leading zero bytes */
|
||||||
|
if (tlv->value_len > 0xFF) {
|
||||||
|
return ERR_VAL;
|
||||||
|
}
|
||||||
|
PBUF_OP_EXEC(snmp_pbuf_stream_read(pbuf_stream, &data));
|
||||||
|
tlv->value_len <<= 8;
|
||||||
|
tlv->value_len |= data;
|
||||||
|
|
||||||
|
/* take care for special value used for indefinite length */
|
||||||
|
if (tlv->value_len == 0xFFFF) {
|
||||||
|
return ERR_VAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
length_bytes--;
|
||||||
|
}
|
||||||
|
} else { /* data == 0x80 indefinite length form */
|
||||||
|
/* (not allowed for SNMP; RFC 1157, 3.2.2) */
|
||||||
|
return ERR_VAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ERR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decodes positive integer (counter, gauge, timeticks) into u32_t.
|
||||||
|
*
|
||||||
|
* @param pbuf_stream points to a pbuf stream
|
||||||
|
* @param len length of the coded integer field
|
||||||
|
* @param value return host order integer
|
||||||
|
* @return ERR_OK if successful, ERR_ARG if we can't (or won't) decode
|
||||||
|
*
|
||||||
|
* @note ASN coded integers are _always_ signed. E.g. +0xFFFF is coded
|
||||||
|
* as 0x00,0xFF,0xFF. Note the leading sign octet. A positive value
|
||||||
|
* of 0xFFFFFFFF is preceded with 0x00 and the length is 5 octets!!
|
||||||
|
*/
|
||||||
|
err_t
|
||||||
|
snmp_asn1_dec_u32t(struct snmp_pbuf_stream *pbuf_stream, u16_t len, u32_t *value)
|
||||||
|
{
|
||||||
|
u8_t data;
|
||||||
|
|
||||||
|
if ((len > 0) && (len <= 5)) {
|
||||||
|
PBUF_OP_EXEC(snmp_pbuf_stream_read(pbuf_stream, &data));
|
||||||
|
|
||||||
|
/* expecting sign bit to be zero, only unsigned please! */
|
||||||
|
if (((len == 5) && (data == 0x00)) || ((len < 5) && ((data & 0x80) == 0))) {
|
||||||
|
*value = data;
|
||||||
|
len--;
|
||||||
|
|
||||||
|
while (len > 0) {
|
||||||
|
PBUF_OP_EXEC(snmp_pbuf_stream_read(pbuf_stream, &data));
|
||||||
|
len--;
|
||||||
|
|
||||||
|
*value <<= 8;
|
||||||
|
*value |= data;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ERR_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ERR_VAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decodes large positive integer (counter64) into 2x u32_t.
|
||||||
|
*
|
||||||
|
* @param pbuf_stream points to a pbuf stream
|
||||||
|
* @param len length of the coded integer field
|
||||||
|
* @param value return host order integer
|
||||||
|
* @return ERR_OK if successful, ERR_ARG if we can't (or won't) decode
|
||||||
|
*
|
||||||
|
* @note ASN coded integers are _always_ signed. E.g. +0xFFFF is coded
|
||||||
|
* as 0x00,0xFF,0xFF. Note the leading sign octet. A positive value
|
||||||
|
* of 0xFFFFFFFF is preceded with 0x00 and the length is 5 octets!!
|
||||||
|
*/
|
||||||
|
err_t
|
||||||
|
snmp_asn1_dec_u64t(struct snmp_pbuf_stream *pbuf_stream, u16_t len, u32_t *value)
|
||||||
|
{
|
||||||
|
u8_t data;
|
||||||
|
|
||||||
|
if (len <= 4) {
|
||||||
|
/* high u32 is 0 */
|
||||||
|
*value = 0;
|
||||||
|
/* directly skip to low u32 */
|
||||||
|
value++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((len > 0) && (len <= 9)) {
|
||||||
|
PBUF_OP_EXEC(snmp_pbuf_stream_read(pbuf_stream, &data));
|
||||||
|
|
||||||
|
/* expecting sign bit to be zero, only unsigned please! */
|
||||||
|
if (((len == 9) && (data == 0x00)) || ((len < 9) && ((data & 0x80) == 0))) {
|
||||||
|
*value = data;
|
||||||
|
len--;
|
||||||
|
|
||||||
|
while (len > 0) {
|
||||||
|
PBUF_OP_EXEC(snmp_pbuf_stream_read(pbuf_stream, &data));
|
||||||
|
|
||||||
|
if (len == 4) {
|
||||||
|
/* skip to low u32 */
|
||||||
|
value++;
|
||||||
|
*value = 0;
|
||||||
|
} else {
|
||||||
|
*value <<= 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
*value |= data;
|
||||||
|
len--;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ERR_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ERR_VAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decodes integer into s32_t.
|
||||||
|
*
|
||||||
|
* @param pbuf_stream points to a pbuf stream
|
||||||
|
* @param len length of the coded integer field
|
||||||
|
* @param value return host order integer
|
||||||
|
* @return ERR_OK if successful, ERR_ARG if we can't (or won't) decode
|
||||||
|
*
|
||||||
|
* @note ASN coded integers are _always_ signed!
|
||||||
|
*/
|
||||||
|
err_t
|
||||||
|
snmp_asn1_dec_s32t(struct snmp_pbuf_stream *pbuf_stream, u16_t len, s32_t *value)
|
||||||
|
{
|
||||||
|
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||||
|
u8_t *lsb_ptr = (u8_t*)value;
|
||||||
|
#endif
|
||||||
|
#if BYTE_ORDER == BIG_ENDIAN
|
||||||
|
u8_t *lsb_ptr = (u8_t*)value + sizeof(s32_t) - 1;
|
||||||
|
#endif
|
||||||
|
u8_t sign;
|
||||||
|
u8_t data;
|
||||||
|
|
||||||
|
if ((len > 0) && (len < 5)) {
|
||||||
|
PBUF_OP_EXEC(snmp_pbuf_stream_read(pbuf_stream, &data));
|
||||||
|
len--;
|
||||||
|
|
||||||
|
if (data & 0x80) {
|
||||||
|
/* negative, start from -1 */
|
||||||
|
*value = -1;
|
||||||
|
sign = 1;
|
||||||
|
*lsb_ptr &= data;
|
||||||
|
} else {
|
||||||
|
/* positive, start from 0 */
|
||||||
|
*value = 0;
|
||||||
|
sign = 0;
|
||||||
|
*lsb_ptr |= data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* OR/AND octets with value */
|
||||||
|
while (len > 0) {
|
||||||
|
PBUF_OP_EXEC(snmp_pbuf_stream_read(pbuf_stream, &data));
|
||||||
|
len--;
|
||||||
|
|
||||||
|
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||||
|
*value <<= 8;
|
||||||
|
#endif
|
||||||
|
#if BYTE_ORDER == BIG_ENDIAN
|
||||||
|
*value >>= 8;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (sign) {
|
||||||
|
*lsb_ptr |= 255;
|
||||||
|
*lsb_ptr &= data;
|
||||||
|
} else {
|
||||||
|
*lsb_ptr |= data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ERR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ERR_VAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decodes object identifier from incoming message into array of u32_t.
|
||||||
|
*
|
||||||
|
* @param pbuf_stream points to a pbuf stream
|
||||||
|
* @param len length of the coded object identifier
|
||||||
|
* @param oid return decoded object identifier
|
||||||
|
* @param oid_len return decoded object identifier length
|
||||||
|
* @param oid_max_len size of oid buffer
|
||||||
|
* @return ERR_OK if successful, ERR_ARG if we can't (or won't) decode
|
||||||
|
*/
|
||||||
|
err_t
|
||||||
|
snmp_asn1_dec_oid(struct snmp_pbuf_stream *pbuf_stream, u16_t len, u32_t* oid, u8_t* oid_len, u8_t oid_max_len)
|
||||||
|
{
|
||||||
|
u32_t *oid_ptr;
|
||||||
|
u8_t data;
|
||||||
|
|
||||||
|
*oid_len = 0;
|
||||||
|
oid_ptr = oid;
|
||||||
|
if (len > 0) {
|
||||||
|
if (oid_max_len < 2) {
|
||||||
|
return ERR_MEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
PBUF_OP_EXEC(snmp_pbuf_stream_read(pbuf_stream, &data));
|
||||||
|
len--;
|
||||||
|
|
||||||
|
/* first compressed octet */
|
||||||
|
if (data == 0x2B) {
|
||||||
|
/* (most) common case 1.3 (iso.org) */
|
||||||
|
*oid_ptr = 1;
|
||||||
|
oid_ptr++;
|
||||||
|
*oid_ptr = 3;
|
||||||
|
oid_ptr++;
|
||||||
|
} else if (data < 40) {
|
||||||
|
*oid_ptr = 0;
|
||||||
|
oid_ptr++;
|
||||||
|
*oid_ptr = data;
|
||||||
|
oid_ptr++;
|
||||||
|
} else if (data < 80) {
|
||||||
|
*oid_ptr = 1;
|
||||||
|
oid_ptr++;
|
||||||
|
*oid_ptr = data - 40;
|
||||||
|
oid_ptr++;
|
||||||
|
} else {
|
||||||
|
*oid_ptr = 2;
|
||||||
|
oid_ptr++;
|
||||||
|
*oid_ptr = data - 80;
|
||||||
|
oid_ptr++;
|
||||||
|
}
|
||||||
|
*oid_len = 2;
|
||||||
|
} else {
|
||||||
|
/* accepting zero length identifiers e.g. for getnext operation. uncommon but valid */
|
||||||
|
return ERR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
while ((len > 0) && (*oid_len < oid_max_len)) {
|
||||||
|
PBUF_OP_EXEC(snmp_pbuf_stream_read(pbuf_stream, &data));
|
||||||
|
len--;
|
||||||
|
|
||||||
|
if ((data & 0x80) == 0x00) {
|
||||||
|
/* sub-identifier uses single octet */
|
||||||
|
*oid_ptr = data;
|
||||||
|
} else {
|
||||||
|
/* sub-identifier uses multiple octets */
|
||||||
|
u32_t sub_id = (data & ~0x80);
|
||||||
|
while ((len > 0) && ((data & 0x80) != 0)) {
|
||||||
|
PBUF_OP_EXEC(snmp_pbuf_stream_read(pbuf_stream, &data));
|
||||||
|
len--;
|
||||||
|
|
||||||
|
sub_id = (sub_id << 7) + (data & ~0x80);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((data & 0x80) != 0) {
|
||||||
|
/* "more bytes following" bit still set at end of len */
|
||||||
|
return ERR_VAL;
|
||||||
|
}
|
||||||
|
*oid_ptr = sub_id;
|
||||||
|
}
|
||||||
|
oid_ptr++;
|
||||||
|
(*oid_len)++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (len > 0) {
|
||||||
|
/* OID to long to fit in our buffer */
|
||||||
|
return ERR_MEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ERR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decodes (copies) raw data (ip-addresses, octet strings, opaque encoding)
|
||||||
|
* from incoming message into array.
|
||||||
|
*
|
||||||
|
* @param pbuf_stream points to a pbuf stream
|
||||||
|
* @param len length of the coded raw data (zero is valid, e.g. empty string!)
|
||||||
|
* @param buf return raw bytes
|
||||||
|
* @param buf_len returns length of the raw return value
|
||||||
|
* @param buf_max_len buffer size
|
||||||
|
* @return ERR_OK if successful, ERR_ARG if we can't (or won't) decode
|
||||||
|
*/
|
||||||
|
err_t
|
||||||
|
snmp_asn1_dec_raw(struct snmp_pbuf_stream *pbuf_stream, u16_t len, u8_t *buf, u16_t* buf_len, u16_t buf_max_len)
|
||||||
|
{
|
||||||
|
if (len > buf_max_len) {
|
||||||
|
/* not enough dst space */
|
||||||
|
return ERR_MEM;
|
||||||
|
}
|
||||||
|
*buf_len = len;
|
||||||
|
|
||||||
|
while (len > 0) {
|
||||||
|
PBUF_OP_EXEC(snmp_pbuf_stream_read(pbuf_stream, buf));
|
||||||
|
buf++;
|
||||||
|
len--;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ERR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* LWIP_SNMP */
|
|
@ -0,0 +1,108 @@
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* Abstract Syntax Notation One (ISO 8824, 8825) codec.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006 Axon Digital Design B.V., The Netherlands.
|
||||||
|
* Copyright (c) 2016 Elias Oenal.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||||
|
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||||
|
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
|
* OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* Author: Christiaan Simons <christiaan.simons@axon.tv>
|
||||||
|
* Martin Hentschel <info@cl-soft.de>
|
||||||
|
* Elias Oenal <lwip@eliasoenal.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef LWIP_HDR_APPS_SNMP_ASN1_H
|
||||||
|
#define LWIP_HDR_APPS_SNMP_ASN1_H
|
||||||
|
|
||||||
|
#include "lwip/apps/snmp_opts.h"
|
||||||
|
|
||||||
|
#if LWIP_SNMP
|
||||||
|
|
||||||
|
#include "lwip/err.h"
|
||||||
|
#include "lwip/apps/snmp_core.h"
|
||||||
|
#include "snmp_pbuf_stream.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define SNMP_ASN1_TLV_INDEFINITE_LENGTH 0x80
|
||||||
|
|
||||||
|
#define SNMP_ASN1_CLASS_MASK 0xC0
|
||||||
|
#define SNMP_ASN1_CONTENTTYPE_MASK 0x20
|
||||||
|
#define SNMP_ASN1_DATATYPE_MASK 0x1F
|
||||||
|
#define SNMP_ASN1_DATATYPE_EXTENDED 0x1F /* DataType indicating that datatype is encoded in following bytes */
|
||||||
|
|
||||||
|
/* context specific (SNMP) tags (from SNMP spec. RFC1157) */
|
||||||
|
#define SNMP_ASN1_CONTEXT_PDU_GET_REQ 0
|
||||||
|
#define SNMP_ASN1_CONTEXT_PDU_GET_NEXT_REQ 1
|
||||||
|
#define SNMP_ASN1_CONTEXT_PDU_GET_RESP 2
|
||||||
|
#define SNMP_ASN1_CONTEXT_PDU_SET_REQ 3
|
||||||
|
#define SNMP_ASN1_CONTEXT_PDU_TRAP 4
|
||||||
|
#define SNMP_ASN1_CONTEXT_PDU_GET_BULK_REQ 5
|
||||||
|
|
||||||
|
#define SNMP_ASN1_CONTEXT_VARBIND_NO_SUCH_OBJECT 0
|
||||||
|
#define SNMP_ASN1_CONTEXT_VARBIND_END_OF_MIB_VIEW 2
|
||||||
|
|
||||||
|
struct snmp_asn1_tlv
|
||||||
|
{
|
||||||
|
u8_t type; /* only U8 because extended types are not specified by SNMP */
|
||||||
|
u8_t type_len; /* encoded length of 'type' field (normally 1) */
|
||||||
|
u8_t length_len; /* indicates how many bytes are required to encode the 'value_len' field */
|
||||||
|
u16_t value_len; /* encoded length of the value */
|
||||||
|
};
|
||||||
|
#define SNMP_ASN1_TLV_HDR_LENGTH(tlv) ((tlv).type_len + (tlv).length_len)
|
||||||
|
#define SNMP_ASN1_TLV_LENGTH(tlv) ((tlv).type_len + (tlv).length_len + (tlv).value_len)
|
||||||
|
#define SNMP_ASN1_SET_TLV_PARAMS(tlv, type_, length_len_, value_len_) do { (tlv).type = (type_); (tlv).type_len = 0; (tlv).length_len = (length_len_); (tlv).value_len = (value_len_); } while (0);
|
||||||
|
|
||||||
|
err_t snmp_asn1_dec_tlv(struct snmp_pbuf_stream* pbuf_stream, struct snmp_asn1_tlv* tlv);
|
||||||
|
err_t snmp_asn1_dec_u32t(struct snmp_pbuf_stream *pbuf_stream, u16_t len, u32_t *value);
|
||||||
|
err_t snmp_asn1_dec_u64t(struct snmp_pbuf_stream *pbuf_stream, u16_t len, u32_t *value);
|
||||||
|
err_t snmp_asn1_dec_s32t(struct snmp_pbuf_stream *pbuf_stream, u16_t len, s32_t *value);
|
||||||
|
err_t snmp_asn1_dec_oid(struct snmp_pbuf_stream *pbuf_stream, u16_t len, u32_t* oid, u8_t* oid_len, u8_t oid_max_len);
|
||||||
|
err_t snmp_asn1_dec_raw(struct snmp_pbuf_stream *pbuf_stream, u16_t len, u8_t *buf, u16_t* buf_len, u16_t buf_max_len);
|
||||||
|
|
||||||
|
err_t snmp_ans1_enc_tlv(struct snmp_pbuf_stream* pbuf_stream, struct snmp_asn1_tlv* tlv);
|
||||||
|
|
||||||
|
void snmp_asn1_enc_length_cnt(u16_t length, u8_t *octets_needed);
|
||||||
|
void snmp_asn1_enc_u32t_cnt(u32_t value, u16_t *octets_needed);
|
||||||
|
void snmp_asn1_enc_u64t_cnt(const u32_t *value, u16_t *octets_needed);
|
||||||
|
void snmp_asn1_enc_s32t_cnt(s32_t value, u16_t *octets_needed);
|
||||||
|
void snmp_asn1_enc_oid_cnt(const u32_t *oid, u16_t oid_len, u16_t *octets_needed);
|
||||||
|
err_t snmp_asn1_enc_oid(struct snmp_pbuf_stream* pbuf_stream, const u32_t *oid, u16_t oid_len);
|
||||||
|
err_t snmp_asn1_enc_s32t(struct snmp_pbuf_stream* pbuf_stream, u16_t octets_needed, s32_t value);
|
||||||
|
err_t snmp_asn1_enc_u32t(struct snmp_pbuf_stream* pbuf_stream, u16_t octets_needed, u32_t value);
|
||||||
|
err_t snmp_asn1_enc_u64t(struct snmp_pbuf_stream* pbuf_stream, u16_t octets_needed, const u32_t* value);
|
||||||
|
err_t snmp_asn1_enc_raw(struct snmp_pbuf_stream* pbuf_stream, const u8_t *raw, u16_t raw_len);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* LWIP_SNMP */
|
||||||
|
|
||||||
|
#endif /* LWIP_HDR_APPS_SNMP_ASN1_H */
|
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,76 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||||
|
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||||
|
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
|
* OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* This file is part of the lwIP TCP/IP stack.
|
||||||
|
*
|
||||||
|
* Author: Martin Hentschel <info@cl-soft.de>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef LWIP_HDR_APPS_SNMP_CORE_PRIV_H
|
||||||
|
#define LWIP_HDR_APPS_SNMP_CORE_PRIV_H
|
||||||
|
|
||||||
|
#include "lwip/apps/snmp_opts.h"
|
||||||
|
|
||||||
|
#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */
|
||||||
|
|
||||||
|
#include "lwip/apps/snmp_core.h"
|
||||||
|
#include "snmp_asn1.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* (outdated) SNMPv1 error codes
|
||||||
|
* shall not be used by MIBS anymore, nevertheless required from core for properly answering a v1 request
|
||||||
|
*/
|
||||||
|
#define SNMP_ERR_NOSUCHNAME 2
|
||||||
|
#define SNMP_ERR_BADVALUE 3
|
||||||
|
#define SNMP_ERR_READONLY 4
|
||||||
|
/* error codes which are internal and shall not be used by MIBS
|
||||||
|
* shall not be used by MIBS anymore, nevertheless required from core for properly answering a v1 request
|
||||||
|
*/
|
||||||
|
#define SNMP_ERR_TOOBIG 1
|
||||||
|
#define SNMP_ERR_AUTHORIZATIONERROR 16
|
||||||
|
#define SNMP_ERR_NOSUCHOBJECT SNMP_VARBIND_EXCEPTION_OFFSET + SNMP_ASN1_CONTEXT_VARBIND_NO_SUCH_OBJECT
|
||||||
|
#define SNMP_ERR_ENDOFMIBVIEW SNMP_VARBIND_EXCEPTION_OFFSET + SNMP_ASN1_CONTEXT_VARBIND_END_OF_MIB_VIEW
|
||||||
|
|
||||||
|
|
||||||
|
const struct snmp_node* snmp_mib_tree_resolve_exact(const struct snmp_mib *mib, const u32_t *oid, u8_t oid_len, u8_t* oid_instance_len);
|
||||||
|
const struct snmp_node* snmp_mib_tree_resolve_next(const struct snmp_mib *mib, const u32_t *oid, u8_t oid_len, struct snmp_obj_id* oidret);
|
||||||
|
|
||||||
|
typedef u8_t (*snmp_validate_node_instance_method)(struct snmp_node_instance*, void*);
|
||||||
|
|
||||||
|
u8_t snmp_get_node_instance_from_oid(const u32_t *oid, u8_t oid_len, struct snmp_node_instance* node_instance);
|
||||||
|
u8_t snmp_get_next_node_instance_from_oid(const u32_t *oid, u8_t oid_len, snmp_validate_node_instance_method validate_node_instance_method, void* validate_node_instance_arg, struct snmp_obj_id* node_oid, struct snmp_node_instance* node_instance);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* LWIP_SNMP */
|
||||||
|
|
||||||
|
#endif /* LWIP_HDR_APPS_SNMP_CORE_PRIV_H */
|
|
@ -0,0 +1,116 @@
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* Management Information Base II (RFC1213) objects and functions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006 Axon Digital Design B.V., The Netherlands.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||||
|
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||||
|
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
|
* OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* Author: Dirk Ziegelmeier <dziegel@gmx.de>
|
||||||
|
* Christiaan Simons <christiaan.simons@axon.tv>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @defgroup snmp_mib2 MIB2
|
||||||
|
* @ingroup snmp
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "lwip/apps/snmp_opts.h"
|
||||||
|
|
||||||
|
#if LWIP_SNMP && SNMP_LWIP_MIB2 /* don't build if not configured for use in lwipopts.h */
|
||||||
|
|
||||||
|
#if !LWIP_STATS
|
||||||
|
#error LWIP_SNMP MIB2 needs LWIP_STATS (for MIB2)
|
||||||
|
#endif
|
||||||
|
#if !MIB2_STATS
|
||||||
|
#error LWIP_SNMP MIB2 needs MIB2_STATS (for MIB2)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "lwip/snmp.h"
|
||||||
|
#include "lwip/apps/snmp.h"
|
||||||
|
#include "lwip/apps/snmp_core.h"
|
||||||
|
#include "lwip/apps/snmp_mib2.h"
|
||||||
|
#include "lwip/apps/snmp_scalar.h"
|
||||||
|
|
||||||
|
#if SNMP_USE_NETCONN
|
||||||
|
#include "lwip/tcpip.h"
|
||||||
|
#include "lwip/priv/tcpip_priv.h"
|
||||||
|
void
|
||||||
|
snmp_mib2_lwip_synchronizer(snmp_threadsync_called_fn fn, void* arg)
|
||||||
|
{
|
||||||
|
#if LWIP_TCPIP_CORE_LOCKING
|
||||||
|
LOCK_TCPIP_CORE();
|
||||||
|
fn(arg);
|
||||||
|
UNLOCK_TCPIP_CORE();
|
||||||
|
#else
|
||||||
|
tcpip_callback(fn, arg);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
struct snmp_threadsync_instance snmp_mib2_lwip_locks;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* dot3 and EtherLike MIB not planned. (transmission .1.3.6.1.2.1.10) */
|
||||||
|
/* historical (some say hysterical). (cmot .1.3.6.1.2.1.9) */
|
||||||
|
/* lwIP has no EGP, thus may not implement it. (egp .1.3.6.1.2.1.8) */
|
||||||
|
|
||||||
|
/* --- mib-2 .1.3.6.1.2.1 ----------------------------------------------------- */
|
||||||
|
extern const struct snmp_scalar_array_node snmp_mib2_snmp_root;
|
||||||
|
extern const struct snmp_tree_node snmp_mib2_udp_root;
|
||||||
|
extern const struct snmp_tree_node snmp_mib2_tcp_root;
|
||||||
|
extern const struct snmp_scalar_array_node snmp_mib2_icmp_root;
|
||||||
|
extern const struct snmp_tree_node snmp_mib2_interface_root;
|
||||||
|
extern const struct snmp_scalar_array_node snmp_mib2_system_node;
|
||||||
|
extern const struct snmp_tree_node snmp_mib2_at_root;
|
||||||
|
extern const struct snmp_tree_node snmp_mib2_ip_root;
|
||||||
|
|
||||||
|
static const struct snmp_node* const mib2_nodes[] = {
|
||||||
|
&snmp_mib2_system_node.node.node,
|
||||||
|
&snmp_mib2_interface_root.node,
|
||||||
|
#if LWIP_ARP && LWIP_IPV4
|
||||||
|
&snmp_mib2_at_root.node,
|
||||||
|
#endif /* LWIP_ARP && LWIP_IPV4 */
|
||||||
|
#if LWIP_IPV4
|
||||||
|
&snmp_mib2_ip_root.node,
|
||||||
|
#endif /* LWIP_IPV4 */
|
||||||
|
#if LWIP_ICMP
|
||||||
|
&snmp_mib2_icmp_root.node.node,
|
||||||
|
#endif /* LWIP_ICMP */
|
||||||
|
#if LWIP_TCP
|
||||||
|
&snmp_mib2_tcp_root.node,
|
||||||
|
#endif /* LWIP_TCP */
|
||||||
|
#if LWIP_UDP
|
||||||
|
&snmp_mib2_udp_root.node,
|
||||||
|
#endif /* LWIP_UDP */
|
||||||
|
&snmp_mib2_snmp_root.node.node
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct snmp_tree_node mib2_root = SNMP_CREATE_TREE_NODE(1, mib2_nodes);
|
||||||
|
|
||||||
|
static const u32_t mib2_base_oid_arr[] = { 1,3,6,1,2,1 };
|
||||||
|
const struct snmp_mib mib2 = SNMP_MIB_CREATE(mib2_base_oid_arr, &mib2_root.node);
|
||||||
|
|
||||||
|
#endif /* LWIP_SNMP && SNMP_LWIP_MIB2 */
|
|
@ -0,0 +1,182 @@
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* Management Information Base II (RFC1213) ICMP objects and functions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006 Axon Digital Design B.V., The Netherlands.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||||
|
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||||
|
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
|
* OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* Author: Dirk Ziegelmeier <dziegel@gmx.de>
|
||||||
|
* Christiaan Simons <christiaan.simons@axon.tv>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "lwip/snmp.h"
|
||||||
|
#include "lwip/apps/snmp.h"
|
||||||
|
#include "lwip/apps/snmp_core.h"
|
||||||
|
#include "lwip/apps/snmp_mib2.h"
|
||||||
|
#include "lwip/apps/snmp_table.h"
|
||||||
|
#include "lwip/apps/snmp_scalar.h"
|
||||||
|
#include "lwip/icmp.h"
|
||||||
|
#include "lwip/stats.h"
|
||||||
|
|
||||||
|
#if LWIP_SNMP && SNMP_LWIP_MIB2 && LWIP_ICMP
|
||||||
|
|
||||||
|
#if SNMP_USE_NETCONN
|
||||||
|
#define SYNC_NODE_NAME(node_name) node_name ## _synced
|
||||||
|
#define CREATE_LWIP_SYNC_NODE(oid, node_name) \
|
||||||
|
static const struct snmp_threadsync_node node_name ## _synced = SNMP_CREATE_THREAD_SYNC_NODE(oid, &node_name.node, &snmp_mib2_lwip_locks);
|
||||||
|
#else
|
||||||
|
#define SYNC_NODE_NAME(node_name) node_name
|
||||||
|
#define CREATE_LWIP_SYNC_NODE(oid, node_name)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* --- icmp .1.3.6.1.2.1.5 ----------------------------------------------------- */
|
||||||
|
|
||||||
|
static s16_t
|
||||||
|
icmp_get_value(const struct snmp_scalar_array_node_def *node, void *value)
|
||||||
|
{
|
||||||
|
u32_t *uint_ptr = (u32_t*)value;
|
||||||
|
|
||||||
|
switch (node->oid) {
|
||||||
|
case 1: /* icmpInMsgs */
|
||||||
|
*uint_ptr = STATS_GET(mib2.icmpinmsgs);
|
||||||
|
return sizeof(*uint_ptr);
|
||||||
|
case 2: /* icmpInErrors */
|
||||||
|
*uint_ptr = STATS_GET(mib2.icmpinerrors);
|
||||||
|
return sizeof(*uint_ptr);
|
||||||
|
case 3: /* icmpInDestUnreachs */
|
||||||
|
*uint_ptr = STATS_GET(mib2.icmpindestunreachs);
|
||||||
|
return sizeof(*uint_ptr);
|
||||||
|
case 4: /* icmpInTimeExcds */
|
||||||
|
*uint_ptr = STATS_GET(mib2.icmpintimeexcds);
|
||||||
|
return sizeof(*uint_ptr);
|
||||||
|
case 5: /* icmpInParmProbs */
|
||||||
|
*uint_ptr = STATS_GET(mib2.icmpinparmprobs);
|
||||||
|
return sizeof(*uint_ptr);
|
||||||
|
case 6: /* icmpInSrcQuenchs */
|
||||||
|
*uint_ptr = STATS_GET(mib2.icmpinsrcquenchs);
|
||||||
|
return sizeof(*uint_ptr);
|
||||||
|
case 7: /* icmpInRedirects */
|
||||||
|
*uint_ptr = STATS_GET(mib2.icmpinredirects);
|
||||||
|
return sizeof(*uint_ptr);
|
||||||
|
case 8: /* icmpInEchos */
|
||||||
|
*uint_ptr = STATS_GET(mib2.icmpinechos);
|
||||||
|
return sizeof(*uint_ptr);
|
||||||
|
case 9: /* icmpInEchoReps */
|
||||||
|
*uint_ptr = STATS_GET(mib2.icmpinechoreps);
|
||||||
|
return sizeof(*uint_ptr);
|
||||||
|
case 10: /* icmpInTimestamps */
|
||||||
|
*uint_ptr = STATS_GET(mib2.icmpintimestamps);
|
||||||
|
return sizeof(*uint_ptr);
|
||||||
|
case 11: /* icmpInTimestampReps */
|
||||||
|
*uint_ptr = STATS_GET(mib2.icmpintimestampreps);
|
||||||
|
return sizeof(*uint_ptr);
|
||||||
|
case 12: /* icmpInAddrMasks */
|
||||||
|
*uint_ptr = STATS_GET(mib2.icmpinaddrmasks);
|
||||||
|
return sizeof(*uint_ptr);
|
||||||
|
case 13: /* icmpInAddrMaskReps */
|
||||||
|
*uint_ptr = STATS_GET(mib2.icmpinaddrmaskreps);
|
||||||
|
return sizeof(*uint_ptr);
|
||||||
|
case 14: /* icmpOutMsgs */
|
||||||
|
*uint_ptr = STATS_GET(mib2.icmpoutmsgs);
|
||||||
|
return sizeof(*uint_ptr);
|
||||||
|
case 15: /* icmpOutErrors */
|
||||||
|
*uint_ptr = STATS_GET(mib2.icmpouterrors);
|
||||||
|
return sizeof(*uint_ptr);
|
||||||
|
case 16: /* icmpOutDestUnreachs */
|
||||||
|
*uint_ptr = STATS_GET(mib2.icmpoutdestunreachs);
|
||||||
|
return sizeof(*uint_ptr);
|
||||||
|
case 17: /* icmpOutTimeExcds */
|
||||||
|
*uint_ptr = STATS_GET(mib2.icmpouttimeexcds);
|
||||||
|
return sizeof(*uint_ptr);
|
||||||
|
case 18: /* icmpOutParmProbs: not supported -> always 0 */
|
||||||
|
*uint_ptr = 0;
|
||||||
|
return sizeof(*uint_ptr);
|
||||||
|
case 19: /* icmpOutSrcQuenchs: not supported -> always 0 */
|
||||||
|
*uint_ptr = 0;
|
||||||
|
return sizeof(*uint_ptr);
|
||||||
|
case 20: /* icmpOutRedirects: not supported -> always 0 */
|
||||||
|
*uint_ptr = 0;
|
||||||
|
return sizeof(*uint_ptr);
|
||||||
|
case 21: /* icmpOutEchos */
|
||||||
|
*uint_ptr = STATS_GET(mib2.icmpoutechos);
|
||||||
|
return sizeof(*uint_ptr);
|
||||||
|
case 22: /* icmpOutEchoReps */
|
||||||
|
*uint_ptr = STATS_GET(mib2.icmpoutechoreps);
|
||||||
|
return sizeof(*uint_ptr);
|
||||||
|
case 23: /* icmpOutTimestamps: not supported -> always 0 */
|
||||||
|
*uint_ptr = 0;
|
||||||
|
return sizeof(*uint_ptr);
|
||||||
|
case 24: /* icmpOutTimestampReps: not supported -> always 0 */
|
||||||
|
*uint_ptr = 0;
|
||||||
|
return sizeof(*uint_ptr);
|
||||||
|
case 25: /* icmpOutAddrMasks: not supported -> always 0 */
|
||||||
|
*uint_ptr = 0;
|
||||||
|
return sizeof(*uint_ptr);
|
||||||
|
case 26: /* icmpOutAddrMaskReps: not supported -> always 0 */
|
||||||
|
*uint_ptr = 0;
|
||||||
|
return sizeof(*uint_ptr);
|
||||||
|
default:
|
||||||
|
LWIP_DEBUGF(SNMP_MIB_DEBUG,("icmp_get_value(): unknown id: %"S32_F"\n", node->oid));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static const struct snmp_scalar_array_node_def icmp_nodes[] = {
|
||||||
|
{ 1, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY},
|
||||||
|
{ 2, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY},
|
||||||
|
{ 3, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY},
|
||||||
|
{ 4, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY},
|
||||||
|
{ 5, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY},
|
||||||
|
{ 6, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY},
|
||||||
|
{ 7, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY},
|
||||||
|
{ 8, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY},
|
||||||
|
{ 9, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY},
|
||||||
|
{10, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY},
|
||||||
|
{11, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY},
|
||||||
|
{12, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY},
|
||||||
|
{13, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY},
|
||||||
|
{14, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY},
|
||||||
|
{15, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY},
|
||||||
|
{16, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY},
|
||||||
|
{17, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY},
|
||||||
|
{18, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY},
|
||||||
|
{19, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY},
|
||||||
|
{20, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY},
|
||||||
|
{21, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY},
|
||||||
|
{22, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY},
|
||||||
|
{23, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY},
|
||||||
|
{24, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY},
|
||||||
|
{25, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY},
|
||||||
|
{26, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}
|
||||||
|
};
|
||||||
|
|
||||||
|
const struct snmp_scalar_array_node snmp_mib2_icmp_root = SNMP_SCALAR_CREATE_ARRAY_NODE(5, icmp_nodes, icmp_get_value, NULL, NULL);
|
||||||
|
|
||||||
|
#endif /* LWIP_SNMP && SNMP_LWIP_MIB2 && LWIP_ICMP */
|
|
@ -0,0 +1,375 @@
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* Management Information Base II (RFC1213) INTERFACES objects and functions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006 Axon Digital Design B.V., The Netherlands.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||||
|
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||||
|
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
|
* OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* Author: Dirk Ziegelmeier <dziegel@gmx.de>
|
||||||
|
* Christiaan Simons <christiaan.simons@axon.tv>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "lwip/snmp.h"
|
||||||
|
#include "lwip/apps/snmp.h"
|
||||||
|
#include "lwip/apps/snmp_core.h"
|
||||||
|
#include "lwip/apps/snmp_mib2.h"
|
||||||
|
#include "lwip/apps/snmp_table.h"
|
||||||
|
#include "lwip/apps/snmp_scalar.h"
|
||||||
|
#include "lwip/netif.h"
|
||||||
|
#include "lwip/stats.h"
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#if LWIP_SNMP && SNMP_LWIP_MIB2
|
||||||
|
|
||||||
|
#if SNMP_USE_NETCONN
|
||||||
|
#define SYNC_NODE_NAME(node_name) node_name ## _synced
|
||||||
|
#define CREATE_LWIP_SYNC_NODE(oid, node_name) \
|
||||||
|
static const struct snmp_threadsync_node node_name ## _synced = SNMP_CREATE_THREAD_SYNC_NODE(oid, &node_name.node, &snmp_mib2_lwip_locks);
|
||||||
|
#else
|
||||||
|
#define SYNC_NODE_NAME(node_name) node_name
|
||||||
|
#define CREATE_LWIP_SYNC_NODE(oid, node_name)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* --- interfaces .1.3.6.1.2.1.2 ----------------------------------------------------- */
|
||||||
|
|
||||||
|
static s16_t
|
||||||
|
interfaces_get_value(struct snmp_node_instance* instance, void* value)
|
||||||
|
{
|
||||||
|
if (instance->node->oid == 1) {
|
||||||
|
s32_t *sint_ptr = (s32_t*)value;
|
||||||
|
s32_t num_netifs = 0;
|
||||||
|
|
||||||
|
struct netif *netif = netif_list;
|
||||||
|
while (netif != NULL) {
|
||||||
|
num_netifs++;
|
||||||
|
netif = netif->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
*sint_ptr = num_netifs;
|
||||||
|
return sizeof(*sint_ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* list of allowed value ranges for incoming OID */
|
||||||
|
static const struct snmp_oid_range interfaces_Table_oid_ranges[] = {
|
||||||
|
{ 1, 0xff } /* netif->num is u8_t */
|
||||||
|
};
|
||||||
|
|
||||||
|
static const u8_t iftable_ifOutQLen = 0;
|
||||||
|
|
||||||
|
static const u8_t iftable_ifOperStatus_up = 1;
|
||||||
|
static const u8_t iftable_ifOperStatus_down = 2;
|
||||||
|
|
||||||
|
static const u8_t iftable_ifAdminStatus_up = 1;
|
||||||
|
static const u8_t iftable_ifAdminStatus_lowerLayerDown = 7;
|
||||||
|
static const u8_t iftable_ifAdminStatus_down = 2;
|
||||||
|
|
||||||
|
static snmp_err_t
|
||||||
|
interfaces_Table_get_cell_instance(const u32_t* column, const u32_t* row_oid, u8_t row_oid_len, struct snmp_node_instance* cell_instance)
|
||||||
|
{
|
||||||
|
u32_t ifIndex;
|
||||||
|
struct netif *netif;
|
||||||
|
|
||||||
|
LWIP_UNUSED_ARG(column);
|
||||||
|
|
||||||
|
/* check if incoming OID length and if values are in plausible range */
|
||||||
|
if (!snmp_oid_in_range(row_oid, row_oid_len, interfaces_Table_oid_ranges, LWIP_ARRAYSIZE(interfaces_Table_oid_ranges))) {
|
||||||
|
return SNMP_ERR_NOSUCHINSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get netif index from incoming OID */
|
||||||
|
ifIndex = row_oid[0];
|
||||||
|
|
||||||
|
/* find netif with index */
|
||||||
|
netif = netif_list;
|
||||||
|
while (netif != NULL) {
|
||||||
|
if (netif_to_num(netif) == ifIndex) {
|
||||||
|
/* store netif pointer for subsequent operations (get/test/set) */
|
||||||
|
cell_instance->reference.ptr = netif;
|
||||||
|
return SNMP_ERR_NOERROR;
|
||||||
|
}
|
||||||
|
netif = netif->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* not found */
|
||||||
|
return SNMP_ERR_NOSUCHINSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static snmp_err_t
|
||||||
|
interfaces_Table_get_next_cell_instance(const u32_t* column, struct snmp_obj_id* row_oid, struct snmp_node_instance* cell_instance)
|
||||||
|
{
|
||||||
|
struct netif *netif;
|
||||||
|
struct snmp_next_oid_state state;
|
||||||
|
u32_t result_temp[LWIP_ARRAYSIZE(interfaces_Table_oid_ranges)];
|
||||||
|
|
||||||
|
LWIP_UNUSED_ARG(column);
|
||||||
|
|
||||||
|
/* init struct to search next oid */
|
||||||
|
snmp_next_oid_init(&state, row_oid->id, row_oid->len, result_temp, LWIP_ARRAYSIZE(interfaces_Table_oid_ranges));
|
||||||
|
|
||||||
|
/* iterate over all possible OIDs to find the next one */
|
||||||
|
netif = netif_list;
|
||||||
|
while (netif != NULL) {
|
||||||
|
u32_t test_oid[LWIP_ARRAYSIZE(interfaces_Table_oid_ranges)];
|
||||||
|
test_oid[0] = netif_to_num(netif);
|
||||||
|
|
||||||
|
/* check generated OID: is it a candidate for the next one? */
|
||||||
|
snmp_next_oid_check(&state, test_oid, LWIP_ARRAYSIZE(interfaces_Table_oid_ranges), netif);
|
||||||
|
|
||||||
|
netif = netif->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* did we find a next one? */
|
||||||
|
if (state.status == SNMP_NEXT_OID_STATUS_SUCCESS) {
|
||||||
|
snmp_oid_assign(row_oid, state.next_oid, state.next_oid_len);
|
||||||
|
/* store netif pointer for subsequent operations (get/test/set) */
|
||||||
|
cell_instance->reference.ptr = /* (struct netif*) */state.reference;
|
||||||
|
return SNMP_ERR_NOERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* not found */
|
||||||
|
return SNMP_ERR_NOSUCHINSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static s16_t
|
||||||
|
interfaces_Table_get_value(struct snmp_node_instance* instance, void* value)
|
||||||
|
{
|
||||||
|
struct netif *netif = (struct netif*)instance->reference.ptr;
|
||||||
|
u32_t* value_u32 = (u32_t*)value;
|
||||||
|
s32_t* value_s32 = (s32_t*)value;
|
||||||
|
u16_t value_len;
|
||||||
|
|
||||||
|
switch (SNMP_TABLE_GET_COLUMN_FROM_OID(instance->instance_oid.id))
|
||||||
|
{
|
||||||
|
case 1: /* ifIndex */
|
||||||
|
*value_s32 = netif_to_num(netif);
|
||||||
|
value_len = sizeof(*value_s32);
|
||||||
|
break;
|
||||||
|
case 2: /* ifDescr */
|
||||||
|
value_len = sizeof(netif->name);
|
||||||
|
MEMCPY(value, netif->name, value_len);
|
||||||
|
break;
|
||||||
|
case 3: /* ifType */
|
||||||
|
*value_s32 = netif->link_type;
|
||||||
|
value_len = sizeof(*value_s32);
|
||||||
|
break;
|
||||||
|
case 4: /* ifMtu */
|
||||||
|
*value_s32 = netif->mtu;
|
||||||
|
value_len = sizeof(*value_s32);
|
||||||
|
break;
|
||||||
|
case 5: /* ifSpeed */
|
||||||
|
*value_u32 = netif->link_speed;
|
||||||
|
value_len = sizeof(*value_u32);
|
||||||
|
break;
|
||||||
|
case 6: /* ifPhysAddress */
|
||||||
|
value_len = sizeof(netif->hwaddr);
|
||||||
|
MEMCPY(value, &netif->hwaddr, value_len);
|
||||||
|
break;
|
||||||
|
case 7: /* ifAdminStatus */
|
||||||
|
if (netif_is_up(netif)) {
|
||||||
|
*value_s32 = iftable_ifOperStatus_up;
|
||||||
|
} else {
|
||||||
|
*value_s32 = iftable_ifOperStatus_down;
|
||||||
|
}
|
||||||
|
value_len = sizeof(*value_s32);
|
||||||
|
break;
|
||||||
|
case 8: /* ifOperStatus */
|
||||||
|
if (netif_is_up(netif)) {
|
||||||
|
if (netif_is_link_up(netif)) {
|
||||||
|
*value_s32 = iftable_ifAdminStatus_up;
|
||||||
|
} else {
|
||||||
|
*value_s32 = iftable_ifAdminStatus_lowerLayerDown;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
*value_s32 = iftable_ifAdminStatus_down;
|
||||||
|
}
|
||||||
|
value_len = sizeof(*value_s32);
|
||||||
|
break;
|
||||||
|
case 9: /* ifLastChange */
|
||||||
|
*value_u32 = netif->ts;
|
||||||
|
value_len = sizeof(*value_u32);
|
||||||
|
break;
|
||||||
|
case 10: /* ifInOctets */
|
||||||
|
*value_u32 = netif->mib2_counters.ifinoctets;
|
||||||
|
value_len = sizeof(*value_u32);
|
||||||
|
break;
|
||||||
|
case 11: /* ifInUcastPkts */
|
||||||
|
*value_u32 = netif->mib2_counters.ifinucastpkts;
|
||||||
|
value_len = sizeof(*value_u32);
|
||||||
|
break;
|
||||||
|
case 12: /* ifInNUcastPkts */
|
||||||
|
*value_u32 = netif->mib2_counters.ifinnucastpkts;
|
||||||
|
value_len = sizeof(*value_u32);
|
||||||
|
break;
|
||||||
|
case 13: /* ifInDiscards */
|
||||||
|
*value_u32 = netif->mib2_counters.ifindiscards;
|
||||||
|
value_len = sizeof(*value_u32);
|
||||||
|
break;
|
||||||
|
case 14: /* ifInErrors */
|
||||||
|
*value_u32 = netif->mib2_counters.ifinerrors;
|
||||||
|
value_len = sizeof(*value_u32);
|
||||||
|
break;
|
||||||
|
case 15: /* ifInUnkownProtos */
|
||||||
|
*value_u32 = netif->mib2_counters.ifinunknownprotos;
|
||||||
|
value_len = sizeof(*value_u32);
|
||||||
|
break;
|
||||||
|
case 16: /* ifOutOctets */
|
||||||
|
*value_u32 = netif->mib2_counters.ifoutoctets;
|
||||||
|
value_len = sizeof(*value_u32);
|
||||||
|
break;
|
||||||
|
case 17: /* ifOutUcastPkts */
|
||||||
|
*value_u32 = netif->mib2_counters.ifoutucastpkts;
|
||||||
|
value_len = sizeof(*value_u32);
|
||||||
|
break;
|
||||||
|
case 18: /* ifOutNUcastPkts */
|
||||||
|
*value_u32 = netif->mib2_counters.ifoutnucastpkts;
|
||||||
|
value_len = sizeof(*value_u32);
|
||||||
|
break;
|
||||||
|
case 19: /* ifOutDiscarts */
|
||||||
|
*value_u32 = netif->mib2_counters.ifoutdiscards;
|
||||||
|
value_len = sizeof(*value_u32);
|
||||||
|
break;
|
||||||
|
case 20: /* ifOutErrors */
|
||||||
|
*value_u32 = netif->mib2_counters.ifouterrors;
|
||||||
|
value_len = sizeof(*value_u32);
|
||||||
|
break;
|
||||||
|
case 21: /* ifOutQLen */
|
||||||
|
*value_u32 = iftable_ifOutQLen;
|
||||||
|
value_len = sizeof(*value_u32);
|
||||||
|
break;
|
||||||
|
/** @note returning zeroDotZero (0.0) no media specific MIB support */
|
||||||
|
case 22: /* ifSpecific */
|
||||||
|
value_len = snmp_zero_dot_zero.len * sizeof(u32_t);
|
||||||
|
MEMCPY(value, snmp_zero_dot_zero.id, value_len);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return value_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if !SNMP_SAFE_REQUESTS
|
||||||
|
|
||||||
|
static snmp_err_t
|
||||||
|
interfaces_Table_set_test(struct snmp_node_instance* instance, u16_t len, void *value)
|
||||||
|
{
|
||||||
|
s32_t *sint_ptr = (s32_t*)value;
|
||||||
|
|
||||||
|
/* stack should never call this method for another column,
|
||||||
|
because all other columns are set to readonly */
|
||||||
|
LWIP_ASSERT("Invalid column", (SNMP_TABLE_GET_COLUMN_FROM_OID(instance->instance_oid.id) == 7));
|
||||||
|
LWIP_UNUSED_ARG(len);
|
||||||
|
|
||||||
|
if (*sint_ptr == 1 || *sint_ptr == 2) {
|
||||||
|
return SNMP_ERR_NOERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return SNMP_ERR_WRONGVALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static snmp_err_t
|
||||||
|
interfaces_Table_set_value(struct snmp_node_instance* instance, u16_t len, void *value)
|
||||||
|
{
|
||||||
|
struct netif *netif = (struct netif*)instance->reference.ptr;
|
||||||
|
s32_t *sint_ptr = (s32_t*)value;
|
||||||
|
|
||||||
|
/* stack should never call this method for another column,
|
||||||
|
because all other columns are set to readonly */
|
||||||
|
LWIP_ASSERT("Invalid column", (SNMP_TABLE_GET_COLUMN_FROM_OID(instance->instance_oid.id) == 7));
|
||||||
|
LWIP_UNUSED_ARG(len);
|
||||||
|
|
||||||
|
if (*sint_ptr == 1) {
|
||||||
|
netif_set_up(netif);
|
||||||
|
} else if (*sint_ptr == 2) {
|
||||||
|
netif_set_down(netif);
|
||||||
|
}
|
||||||
|
|
||||||
|
return SNMP_ERR_NOERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* SNMP_SAFE_REQUESTS */
|
||||||
|
|
||||||
|
static const struct snmp_scalar_node interfaces_Number = SNMP_SCALAR_CREATE_NODE_READONLY(1, SNMP_ASN1_TYPE_INTEGER, interfaces_get_value);
|
||||||
|
|
||||||
|
static const struct snmp_table_col_def interfaces_Table_columns[] = {
|
||||||
|
{ 1, SNMP_ASN1_TYPE_INTEGER, SNMP_NODE_INSTANCE_READ_ONLY }, /* ifIndex */
|
||||||
|
{ 2, SNMP_ASN1_TYPE_OCTET_STRING, SNMP_NODE_INSTANCE_READ_ONLY }, /* ifDescr */
|
||||||
|
{ 3, SNMP_ASN1_TYPE_INTEGER, SNMP_NODE_INSTANCE_READ_ONLY }, /* ifType */
|
||||||
|
{ 4, SNMP_ASN1_TYPE_INTEGER, SNMP_NODE_INSTANCE_READ_ONLY }, /* ifMtu */
|
||||||
|
{ 5, SNMP_ASN1_TYPE_GAUGE, SNMP_NODE_INSTANCE_READ_ONLY }, /* ifSpeed */
|
||||||
|
{ 6, SNMP_ASN1_TYPE_OCTET_STRING, SNMP_NODE_INSTANCE_READ_ONLY }, /* ifPhysAddress */
|
||||||
|
#if !SNMP_SAFE_REQUESTS
|
||||||
|
{ 7, SNMP_ASN1_TYPE_INTEGER, SNMP_NODE_INSTANCE_READ_WRITE }, /* ifAdminStatus */
|
||||||
|
#else
|
||||||
|
{ 7, SNMP_ASN1_TYPE_INTEGER, SNMP_NODE_INSTANCE_READ_ONLY }, /* ifAdminStatus */
|
||||||
|
#endif
|
||||||
|
{ 8, SNMP_ASN1_TYPE_INTEGER, SNMP_NODE_INSTANCE_READ_ONLY }, /* ifOperStatus */
|
||||||
|
{ 9, SNMP_ASN1_TYPE_TIMETICKS, SNMP_NODE_INSTANCE_READ_ONLY }, /* ifLastChange */
|
||||||
|
{ 10, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY }, /* ifInOctets */
|
||||||
|
{ 11, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY }, /* ifInUcastPkts */
|
||||||
|
{ 12, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY }, /* ifInNUcastPkts */
|
||||||
|
{ 13, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY }, /* ifInDiscarts */
|
||||||
|
{ 14, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY }, /* ifInErrors */
|
||||||
|
{ 15, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY }, /* ifInUnkownProtos */
|
||||||
|
{ 16, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY }, /* ifOutOctets */
|
||||||
|
{ 17, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY }, /* ifOutUcastPkts */
|
||||||
|
{ 18, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY }, /* ifOutNUcastPkts */
|
||||||
|
{ 19, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY }, /* ifOutDiscarts */
|
||||||
|
{ 20, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY }, /* ifOutErrors */
|
||||||
|
{ 21, SNMP_ASN1_TYPE_GAUGE, SNMP_NODE_INSTANCE_READ_ONLY }, /* ifOutQLen */
|
||||||
|
{ 22, SNMP_ASN1_TYPE_OBJECT_ID, SNMP_NODE_INSTANCE_READ_ONLY } /* ifSpecific */
|
||||||
|
};
|
||||||
|
|
||||||
|
#if !SNMP_SAFE_REQUESTS
|
||||||
|
static const struct snmp_table_node interfaces_Table = SNMP_TABLE_CREATE(
|
||||||
|
2, interfaces_Table_columns,
|
||||||
|
interfaces_Table_get_cell_instance, interfaces_Table_get_next_cell_instance,
|
||||||
|
interfaces_Table_get_value, interfaces_Table_set_test, interfaces_Table_set_value);
|
||||||
|
#else
|
||||||
|
static const struct snmp_table_node interfaces_Table = SNMP_TABLE_CREATE(
|
||||||
|
2, interfaces_Table_columns,
|
||||||
|
interfaces_Table_get_cell_instance, interfaces_Table_get_next_cell_instance,
|
||||||
|
interfaces_Table_get_value, NULL, NULL);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* the following nodes access variables in LWIP stack from SNMP worker thread and must therefore be synced to LWIP (TCPIP) thread */
|
||||||
|
CREATE_LWIP_SYNC_NODE(1, interfaces_Number)
|
||||||
|
CREATE_LWIP_SYNC_NODE(2, interfaces_Table)
|
||||||
|
|
||||||
|
static const struct snmp_node* const interface_nodes[] = {
|
||||||
|
&SYNC_NODE_NAME(interfaces_Number).node.node,
|
||||||
|
&SYNC_NODE_NAME(interfaces_Table).node.node
|
||||||
|
};
|
||||||
|
|
||||||
|
const struct snmp_tree_node snmp_mib2_interface_root = SNMP_CREATE_TREE_NODE(2, interface_nodes);
|
||||||
|
|
||||||
|
#endif /* LWIP_SNMP && SNMP_LWIP_MIB2 */
|
|
@ -0,0 +1,743 @@
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* Management Information Base II (RFC1213) IP objects and functions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006 Axon Digital Design B.V., The Netherlands.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||||
|
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||||
|
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
|
* OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* Author: Dirk Ziegelmeier <dziegel@gmx.de>
|
||||||
|
* Christiaan Simons <christiaan.simons@axon.tv>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "lwip/snmp.h"
|
||||||
|
#include "lwip/apps/snmp.h"
|
||||||
|
#include "lwip/apps/snmp_core.h"
|
||||||
|
#include "lwip/apps/snmp_mib2.h"
|
||||||
|
#include "lwip/apps/snmp_table.h"
|
||||||
|
#include "lwip/apps/snmp_scalar.h"
|
||||||
|
#include "lwip/stats.h"
|
||||||
|
#include "lwip/netif.h"
|
||||||
|
#include "lwip/ip.h"
|
||||||
|
#include "lwip/etharp.h"
|
||||||
|
|
||||||
|
#if LWIP_SNMP && SNMP_LWIP_MIB2
|
||||||
|
|
||||||
|
#if SNMP_USE_NETCONN
|
||||||
|
#define SYNC_NODE_NAME(node_name) node_name ## _synced
|
||||||
|
#define CREATE_LWIP_SYNC_NODE(oid, node_name) \
|
||||||
|
static const struct snmp_threadsync_node node_name ## _synced = SNMP_CREATE_THREAD_SYNC_NODE(oid, &node_name.node, &snmp_mib2_lwip_locks);
|
||||||
|
#else
|
||||||
|
#define SYNC_NODE_NAME(node_name) node_name
|
||||||
|
#define CREATE_LWIP_SYNC_NODE(oid, node_name)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if LWIP_IPV4
|
||||||
|
/* --- ip .1.3.6.1.2.1.4 ----------------------------------------------------- */
|
||||||
|
|
||||||
|
static s16_t
|
||||||
|
ip_get_value(struct snmp_node_instance* instance, void* value)
|
||||||
|
{
|
||||||
|
s32_t* sint_ptr = (s32_t*)value;
|
||||||
|
u32_t* uint_ptr = (u32_t*)value;
|
||||||
|
|
||||||
|
switch (instance->node->oid) {
|
||||||
|
case 1: /* ipForwarding */
|
||||||
|
#if IP_FORWARD
|
||||||
|
/* forwarding */
|
||||||
|
*sint_ptr = 1;
|
||||||
|
#else
|
||||||
|
/* not-forwarding */
|
||||||
|
*sint_ptr = 2;
|
||||||
|
#endif
|
||||||
|
return sizeof(*sint_ptr);
|
||||||
|
case 2: /* ipDefaultTTL */
|
||||||
|
*sint_ptr = IP_DEFAULT_TTL;
|
||||||
|
return sizeof(*sint_ptr);
|
||||||
|
case 3: /* ipInReceives */
|
||||||
|
*uint_ptr = STATS_GET(mib2.ipinreceives);
|
||||||
|
return sizeof(*uint_ptr);
|
||||||
|
case 4: /* ipInHdrErrors */
|
||||||
|
*uint_ptr = STATS_GET(mib2.ipinhdrerrors);
|
||||||
|
return sizeof(*uint_ptr);
|
||||||
|
case 5: /* ipInAddrErrors */
|
||||||
|
*uint_ptr = STATS_GET(mib2.ipinaddrerrors);
|
||||||
|
return sizeof(*uint_ptr);
|
||||||
|
case 6: /* ipForwDatagrams */
|
||||||
|
*uint_ptr = STATS_GET(mib2.ipforwdatagrams);
|
||||||
|
return sizeof(*uint_ptr);
|
||||||
|
case 7: /* ipInUnknownProtos */
|
||||||
|
*uint_ptr = STATS_GET(mib2.ipinunknownprotos);
|
||||||
|
return sizeof(*uint_ptr);
|
||||||
|
case 8: /* ipInDiscards */
|
||||||
|
*uint_ptr = STATS_GET(mib2.ipindiscards);
|
||||||
|
return sizeof(*uint_ptr);
|
||||||
|
case 9: /* ipInDelivers */
|
||||||
|
*uint_ptr = STATS_GET(mib2.ipindelivers);
|
||||||
|
return sizeof(*uint_ptr);
|
||||||
|
case 10: /* ipOutRequests */
|
||||||
|
*uint_ptr = STATS_GET(mib2.ipoutrequests);
|
||||||
|
return sizeof(*uint_ptr);
|
||||||
|
case 11: /* ipOutDiscards */
|
||||||
|
*uint_ptr = STATS_GET(mib2.ipoutdiscards);
|
||||||
|
return sizeof(*uint_ptr);
|
||||||
|
case 12: /* ipOutNoRoutes */
|
||||||
|
*uint_ptr = STATS_GET(mib2.ipoutnoroutes);
|
||||||
|
return sizeof(*uint_ptr);
|
||||||
|
case 13: /* ipReasmTimeout */
|
||||||
|
#if IP_REASSEMBLY
|
||||||
|
*sint_ptr = IP_REASS_MAXAGE;
|
||||||
|
#else
|
||||||
|
*sint_ptr = 0;
|
||||||
|
#endif
|
||||||
|
return sizeof(*sint_ptr);
|
||||||
|
case 14: /* ipReasmReqds */
|
||||||
|
*uint_ptr = STATS_GET(mib2.ipreasmreqds);
|
||||||
|
return sizeof(*uint_ptr);
|
||||||
|
case 15: /* ipReasmOKs */
|
||||||
|
*uint_ptr = STATS_GET(mib2.ipreasmoks);
|
||||||
|
return sizeof(*uint_ptr);
|
||||||
|
case 16: /* ipReasmFails */
|
||||||
|
*uint_ptr = STATS_GET(mib2.ipreasmfails);
|
||||||
|
return sizeof(*uint_ptr);
|
||||||
|
case 17: /* ipFragOKs */
|
||||||
|
*uint_ptr = STATS_GET(mib2.ipfragoks);
|
||||||
|
return sizeof(*uint_ptr);
|
||||||
|
case 18: /* ipFragFails */
|
||||||
|
*uint_ptr = STATS_GET(mib2.ipfragfails);
|
||||||
|
return sizeof(*uint_ptr);
|
||||||
|
case 19: /* ipFragCreates */
|
||||||
|
*uint_ptr = STATS_GET(mib2.ipfragcreates);
|
||||||
|
return sizeof(*uint_ptr);
|
||||||
|
case 23: /* ipRoutingDiscards: not supported -> always 0 */
|
||||||
|
*uint_ptr = 0;
|
||||||
|
return sizeof(*uint_ptr);
|
||||||
|
default:
|
||||||
|
LWIP_DEBUGF(SNMP_MIB_DEBUG,("ip_get_value(): unknown id: %"S32_F"\n", instance->node->oid));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test ip object value before setting.
|
||||||
|
*
|
||||||
|
* @param instance node instance
|
||||||
|
* @param len return value space (in bytes)
|
||||||
|
* @param value points to (varbind) space to copy value from.
|
||||||
|
*
|
||||||
|
* @note we allow set if the value matches the hardwired value,
|
||||||
|
* otherwise return badvalue.
|
||||||
|
*/
|
||||||
|
static snmp_err_t
|
||||||
|
ip_set_test(struct snmp_node_instance* instance, u16_t len, void *value)
|
||||||
|
{
|
||||||
|
snmp_err_t ret = SNMP_ERR_WRONGVALUE;
|
||||||
|
s32_t *sint_ptr = (s32_t*)value;
|
||||||
|
|
||||||
|
LWIP_UNUSED_ARG(len);
|
||||||
|
switch (instance->node->oid) {
|
||||||
|
case 1: /* ipForwarding */
|
||||||
|
#if IP_FORWARD
|
||||||
|
/* forwarding */
|
||||||
|
if (*sint_ptr == 1)
|
||||||
|
#else
|
||||||
|
/* not-forwarding */
|
||||||
|
if (*sint_ptr == 2)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
ret = SNMP_ERR_NOERROR;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 2: /* ipDefaultTTL */
|
||||||
|
if (*sint_ptr == IP_DEFAULT_TTL) {
|
||||||
|
ret = SNMP_ERR_NOERROR;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
LWIP_DEBUGF(SNMP_MIB_DEBUG,("ip_set_test(): unknown id: %"S32_F"\n", instance->node->oid));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static snmp_err_t
|
||||||
|
ip_set_value(struct snmp_node_instance* instance, u16_t len, void *value)
|
||||||
|
{
|
||||||
|
LWIP_UNUSED_ARG(instance);
|
||||||
|
LWIP_UNUSED_ARG(len);
|
||||||
|
LWIP_UNUSED_ARG(value);
|
||||||
|
/* nothing to do here because in set_test we only accept values being the same as our own stored value -> no need to store anything */
|
||||||
|
return SNMP_ERR_NOERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --- ipAddrTable --- */
|
||||||
|
|
||||||
|
/* list of allowed value ranges for incoming OID */
|
||||||
|
static const struct snmp_oid_range ip_AddrTable_oid_ranges[] = {
|
||||||
|
{ 0, 0xff }, /* IP A */
|
||||||
|
{ 0, 0xff }, /* IP B */
|
||||||
|
{ 0, 0xff }, /* IP C */
|
||||||
|
{ 0, 0xff } /* IP D */
|
||||||
|
};
|
||||||
|
|
||||||
|
static snmp_err_t
|
||||||
|
ip_AddrTable_get_cell_value_core(struct netif *netif, const u32_t* column, union snmp_variant_value* value, u32_t* value_len)
|
||||||
|
{
|
||||||
|
LWIP_UNUSED_ARG(value_len);
|
||||||
|
|
||||||
|
switch (*column) {
|
||||||
|
case 1: /* ipAdEntAddr */
|
||||||
|
value->u32 = netif_ip4_addr(netif)->addr;
|
||||||
|
break;
|
||||||
|
case 2: /* ipAdEntIfIndex */
|
||||||
|
value->u32 = netif_to_num(netif);
|
||||||
|
break;
|
||||||
|
case 3: /* ipAdEntNetMask */
|
||||||
|
value->u32 = netif_ip4_netmask(netif)->addr;
|
||||||
|
break;
|
||||||
|
case 4: /* ipAdEntBcastAddr */
|
||||||
|
/* lwIP oddity, there's no broadcast
|
||||||
|
address in the netif we can rely on */
|
||||||
|
value->u32 = IPADDR_BROADCAST & 1;
|
||||||
|
break;
|
||||||
|
case 5: /* ipAdEntReasmMaxSize */
|
||||||
|
#if IP_REASSEMBLY
|
||||||
|
/* @todo The theoretical maximum is IP_REASS_MAX_PBUFS * size of the pbufs,
|
||||||
|
* but only if receiving one fragmented packet at a time.
|
||||||
|
* The current solution is to calculate for 2 simultaneous packets...
|
||||||
|
*/
|
||||||
|
value->u32 = (IP_HLEN + ((IP_REASS_MAX_PBUFS/2) *
|
||||||
|
(PBUF_POOL_BUFSIZE - PBUF_LINK_ENCAPSULATION_HLEN - PBUF_LINK_HLEN - IP_HLEN)));
|
||||||
|
#else
|
||||||
|
/** @todo returning MTU would be a bad thing and
|
||||||
|
returning a wild guess like '576' isn't good either */
|
||||||
|
value->u32 = 0;
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return SNMP_ERR_NOSUCHINSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return SNMP_ERR_NOERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
static snmp_err_t
|
||||||
|
ip_AddrTable_get_cell_value(const u32_t* column, const u32_t* row_oid, u8_t row_oid_len, union snmp_variant_value* value, u32_t* value_len)
|
||||||
|
{
|
||||||
|
ip4_addr_t ip;
|
||||||
|
struct netif *netif;
|
||||||
|
|
||||||
|
/* check if incoming OID length and if values are in plausible range */
|
||||||
|
if (!snmp_oid_in_range(row_oid, row_oid_len, ip_AddrTable_oid_ranges, LWIP_ARRAYSIZE(ip_AddrTable_oid_ranges))) {
|
||||||
|
return SNMP_ERR_NOSUCHINSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get IP from incoming OID */
|
||||||
|
snmp_oid_to_ip4(&row_oid[0], &ip); /* we know it succeeds because of oid_in_range check above */
|
||||||
|
|
||||||
|
/* find netif with requested ip */
|
||||||
|
netif = netif_list;
|
||||||
|
while (netif != NULL) {
|
||||||
|
if (ip4_addr_cmp(&ip, netif_ip4_addr(netif))) {
|
||||||
|
/* fill in object properties */
|
||||||
|
return ip_AddrTable_get_cell_value_core(netif, column, value, value_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
netif = netif->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* not found */
|
||||||
|
return SNMP_ERR_NOSUCHINSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static snmp_err_t
|
||||||
|
ip_AddrTable_get_next_cell_instance_and_value(const u32_t* column, struct snmp_obj_id* row_oid, union snmp_variant_value* value, u32_t* value_len)
|
||||||
|
{
|
||||||
|
struct netif *netif;
|
||||||
|
struct snmp_next_oid_state state;
|
||||||
|
u32_t result_temp[LWIP_ARRAYSIZE(ip_AddrTable_oid_ranges)];
|
||||||
|
|
||||||
|
/* init struct to search next oid */
|
||||||
|
snmp_next_oid_init(&state, row_oid->id, row_oid->len, result_temp, LWIP_ARRAYSIZE(ip_AddrTable_oid_ranges));
|
||||||
|
|
||||||
|
/* iterate over all possible OIDs to find the next one */
|
||||||
|
netif = netif_list;
|
||||||
|
while (netif != NULL) {
|
||||||
|
u32_t test_oid[LWIP_ARRAYSIZE(ip_AddrTable_oid_ranges)];
|
||||||
|
snmp_ip4_to_oid(netif_ip4_addr(netif), &test_oid[0]);
|
||||||
|
|
||||||
|
/* check generated OID: is it a candidate for the next one? */
|
||||||
|
snmp_next_oid_check(&state, test_oid, LWIP_ARRAYSIZE(ip_AddrTable_oid_ranges), netif);
|
||||||
|
|
||||||
|
netif = netif->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* did we find a next one? */
|
||||||
|
if (state.status == SNMP_NEXT_OID_STATUS_SUCCESS) {
|
||||||
|
snmp_oid_assign(row_oid, state.next_oid, state.next_oid_len);
|
||||||
|
/* fill in object properties */
|
||||||
|
return ip_AddrTable_get_cell_value_core((struct netif*)state.reference, column, value, value_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* not found */
|
||||||
|
return SNMP_ERR_NOSUCHINSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --- ipRouteTable --- */
|
||||||
|
|
||||||
|
/* list of allowed value ranges for incoming OID */
|
||||||
|
static const struct snmp_oid_range ip_RouteTable_oid_ranges[] = {
|
||||||
|
{ 0, 0xff }, /* IP A */
|
||||||
|
{ 0, 0xff }, /* IP B */
|
||||||
|
{ 0, 0xff }, /* IP C */
|
||||||
|
{ 0, 0xff }, /* IP D */
|
||||||
|
};
|
||||||
|
|
||||||
|
static snmp_err_t
|
||||||
|
ip_RouteTable_get_cell_value_core(struct netif *netif, u8_t default_route, const u32_t* column, union snmp_variant_value* value, u32_t* value_len)
|
||||||
|
{
|
||||||
|
switch (*column) {
|
||||||
|
case 1: /* ipRouteDest */
|
||||||
|
if (default_route) {
|
||||||
|
/* default rte has 0.0.0.0 dest */
|
||||||
|
value->u32 = IP4_ADDR_ANY4->addr;
|
||||||
|
} else {
|
||||||
|
/* netifs have netaddress dest */
|
||||||
|
ip4_addr_t tmp;
|
||||||
|
ip4_addr_get_network(&tmp, netif_ip4_addr(netif), netif_ip4_netmask(netif));
|
||||||
|
value->u32 = tmp.addr;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 2: /* ipRouteIfIndex */
|
||||||
|
value->u32 = netif_to_num(netif);
|
||||||
|
break;
|
||||||
|
case 3: /* ipRouteMetric1 */
|
||||||
|
if (default_route) {
|
||||||
|
value->s32 = 1; /* default */
|
||||||
|
} else {
|
||||||
|
value->s32 = 0; /* normal */
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 4: /* ipRouteMetric2 */
|
||||||
|
case 5: /* ipRouteMetric3 */
|
||||||
|
case 6: /* ipRouteMetric4 */
|
||||||
|
value->s32 = -1; /* none */
|
||||||
|
break;
|
||||||
|
case 7: /* ipRouteNextHop */
|
||||||
|
if (default_route) {
|
||||||
|
/* default rte: gateway */
|
||||||
|
value->u32 = netif_ip4_gw(netif)->addr;
|
||||||
|
} else {
|
||||||
|
/* other rtes: netif ip_addr */
|
||||||
|
value->u32 = netif_ip4_addr(netif)->addr;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 8: /* ipRouteType */
|
||||||
|
if (default_route) {
|
||||||
|
/* default rte is indirect */
|
||||||
|
value->u32 = 4; /* indirect */
|
||||||
|
} else {
|
||||||
|
/* other rtes are direct */
|
||||||
|
value->u32 = 3; /* direct */
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 9: /* ipRouteProto */
|
||||||
|
/* locally defined routes */
|
||||||
|
value->u32 = 2; /* local */
|
||||||
|
break;
|
||||||
|
case 10: /* ipRouteAge */
|
||||||
|
/* @todo (sysuptime - timestamp last change) / 100 */
|
||||||
|
value->u32 = 0;
|
||||||
|
break;
|
||||||
|
case 11: /* ipRouteMask */
|
||||||
|
if (default_route) {
|
||||||
|
/* default rte use 0.0.0.0 mask */
|
||||||
|
value->u32 = IP4_ADDR_ANY4->addr;
|
||||||
|
} else {
|
||||||
|
/* other rtes use netmask */
|
||||||
|
value->u32 = netif_ip4_netmask(netif)->addr;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 12: /* ipRouteMetric5 */
|
||||||
|
value->s32 = -1; /* none */
|
||||||
|
break;
|
||||||
|
case 13: /* ipRouteInfo */
|
||||||
|
value->const_ptr = snmp_zero_dot_zero.id;
|
||||||
|
*value_len = snmp_zero_dot_zero.len * sizeof(u32_t);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return SNMP_ERR_NOSUCHINSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return SNMP_ERR_NOERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
static snmp_err_t
|
||||||
|
ip_RouteTable_get_cell_value(const u32_t* column, const u32_t* row_oid, u8_t row_oid_len, union snmp_variant_value* value, u32_t* value_len)
|
||||||
|
{
|
||||||
|
ip4_addr_t test_ip;
|
||||||
|
struct netif *netif;
|
||||||
|
|
||||||
|
/* check if incoming OID length and if values are in plausible range */
|
||||||
|
if (!snmp_oid_in_range(row_oid, row_oid_len, ip_RouteTable_oid_ranges, LWIP_ARRAYSIZE(ip_RouteTable_oid_ranges))) {
|
||||||
|
return SNMP_ERR_NOSUCHINSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get IP and port from incoming OID */
|
||||||
|
snmp_oid_to_ip4(&row_oid[0], &test_ip); /* we know it succeeds because of oid_in_range check above */
|
||||||
|
|
||||||
|
/* default route is on default netif */
|
||||||
|
if (ip4_addr_isany_val(test_ip) && (netif_default != NULL)) {
|
||||||
|
/* fill in object properties */
|
||||||
|
return ip_RouteTable_get_cell_value_core(netif_default, 1, column, value, value_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* find netif with requested route */
|
||||||
|
netif = netif_list;
|
||||||
|
while (netif != NULL) {
|
||||||
|
ip4_addr_t dst;
|
||||||
|
ip4_addr_get_network(&dst, netif_ip4_addr(netif), netif_ip4_netmask(netif));
|
||||||
|
|
||||||
|
if (ip4_addr_cmp(&dst, &test_ip)) {
|
||||||
|
/* fill in object properties */
|
||||||
|
return ip_RouteTable_get_cell_value_core(netif, 0, column, value, value_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
netif = netif->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* not found */
|
||||||
|
return SNMP_ERR_NOSUCHINSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static snmp_err_t
|
||||||
|
ip_RouteTable_get_next_cell_instance_and_value(const u32_t* column, struct snmp_obj_id* row_oid, union snmp_variant_value* value, u32_t* value_len)
|
||||||
|
{
|
||||||
|
struct netif *netif;
|
||||||
|
struct snmp_next_oid_state state;
|
||||||
|
u32_t result_temp[LWIP_ARRAYSIZE(ip_RouteTable_oid_ranges)];
|
||||||
|
u32_t test_oid[LWIP_ARRAYSIZE(ip_RouteTable_oid_ranges)];
|
||||||
|
|
||||||
|
/* init struct to search next oid */
|
||||||
|
snmp_next_oid_init(&state, row_oid->id, row_oid->len, result_temp, LWIP_ARRAYSIZE(ip_RouteTable_oid_ranges));
|
||||||
|
|
||||||
|
/* check default route */
|
||||||
|
if (netif_default != NULL) {
|
||||||
|
snmp_ip4_to_oid(IP4_ADDR_ANY4, &test_oid[0]);
|
||||||
|
snmp_next_oid_check(&state, test_oid, LWIP_ARRAYSIZE(ip_RouteTable_oid_ranges), netif_default);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* iterate over all possible OIDs to find the next one */
|
||||||
|
netif = netif_list;
|
||||||
|
while (netif != NULL) {
|
||||||
|
ip4_addr_t dst;
|
||||||
|
ip4_addr_get_network(&dst, netif_ip4_addr(netif), netif_ip4_netmask(netif));
|
||||||
|
|
||||||
|
/* check generated OID: is it a candidate for the next one? */
|
||||||
|
if (!ip4_addr_isany_val(dst)) {
|
||||||
|
snmp_ip4_to_oid(&dst, &test_oid[0]);
|
||||||
|
snmp_next_oid_check(&state, test_oid, LWIP_ARRAYSIZE(ip_RouteTable_oid_ranges), netif);
|
||||||
|
}
|
||||||
|
|
||||||
|
netif = netif->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* did we find a next one? */
|
||||||
|
if (state.status == SNMP_NEXT_OID_STATUS_SUCCESS) {
|
||||||
|
ip4_addr_t dst;
|
||||||
|
snmp_oid_to_ip4(&result_temp[0], &dst);
|
||||||
|
snmp_oid_assign(row_oid, state.next_oid, state.next_oid_len);
|
||||||
|
/* fill in object properties */
|
||||||
|
return ip_RouteTable_get_cell_value_core((struct netif*)state.reference, ip4_addr_isany_val(dst), column, value, value_len);
|
||||||
|
} else {
|
||||||
|
/* not found */
|
||||||
|
return SNMP_ERR_NOSUCHINSTANCE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if LWIP_ARP && LWIP_IPV4
|
||||||
|
/* --- ipNetToMediaTable --- */
|
||||||
|
|
||||||
|
/* list of allowed value ranges for incoming OID */
|
||||||
|
static const struct snmp_oid_range ip_NetToMediaTable_oid_ranges[] = {
|
||||||
|
{ 1, 0xff }, /* IfIndex */
|
||||||
|
{ 0, 0xff }, /* IP A */
|
||||||
|
{ 0, 0xff }, /* IP B */
|
||||||
|
{ 0, 0xff }, /* IP C */
|
||||||
|
{ 0, 0xff } /* IP D */
|
||||||
|
};
|
||||||
|
|
||||||
|
static snmp_err_t
|
||||||
|
ip_NetToMediaTable_get_cell_value_core(u8_t arp_table_index, const u32_t* column, union snmp_variant_value* value, u32_t* value_len)
|
||||||
|
{
|
||||||
|
ip4_addr_t *ip;
|
||||||
|
struct netif *netif;
|
||||||
|
struct eth_addr *ethaddr;
|
||||||
|
|
||||||
|
etharp_get_entry(arp_table_index, &ip, &netif, ðaddr);
|
||||||
|
|
||||||
|
/* value */
|
||||||
|
switch (*column) {
|
||||||
|
case 1: /* atIfIndex / ipNetToMediaIfIndex */
|
||||||
|
value->u32 = netif_to_num(netif);
|
||||||
|
break;
|
||||||
|
case 2: /* atPhysAddress / ipNetToMediaPhysAddress */
|
||||||
|
value->ptr = ethaddr;
|
||||||
|
*value_len = sizeof(*ethaddr);
|
||||||
|
break;
|
||||||
|
case 3: /* atNetAddress / ipNetToMediaNetAddress */
|
||||||
|
value->u32 = ip->addr;
|
||||||
|
break;
|
||||||
|
case 4: /* ipNetToMediaType */
|
||||||
|
value->u32 = 3; /* dynamic*/
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return SNMP_ERR_NOSUCHINSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return SNMP_ERR_NOERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
static snmp_err_t
|
||||||
|
ip_NetToMediaTable_get_cell_value(const u32_t* column, const u32_t* row_oid, u8_t row_oid_len, union snmp_variant_value* value, u32_t* value_len)
|
||||||
|
{
|
||||||
|
ip4_addr_t ip_in;
|
||||||
|
u8_t netif_index;
|
||||||
|
u8_t i;
|
||||||
|
|
||||||
|
/* check if incoming OID length and if values are in plausible range */
|
||||||
|
if (!snmp_oid_in_range(row_oid, row_oid_len, ip_NetToMediaTable_oid_ranges, LWIP_ARRAYSIZE(ip_NetToMediaTable_oid_ranges))) {
|
||||||
|
return SNMP_ERR_NOSUCHINSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get IP from incoming OID */
|
||||||
|
netif_index = (u8_t)row_oid[0];
|
||||||
|
snmp_oid_to_ip4(&row_oid[1], &ip_in); /* we know it succeeds because of oid_in_range check above */
|
||||||
|
|
||||||
|
/* find requested entry */
|
||||||
|
for (i=0; i<ARP_TABLE_SIZE; i++) {
|
||||||
|
ip4_addr_t *ip;
|
||||||
|
struct netif *netif;
|
||||||
|
struct eth_addr *ethaddr;
|
||||||
|
|
||||||
|
if (etharp_get_entry(i, &ip, &netif, ðaddr)) {
|
||||||
|
if ((netif_index == netif_to_num(netif)) && ip4_addr_cmp(&ip_in, ip)) {
|
||||||
|
/* fill in object properties */
|
||||||
|
return ip_NetToMediaTable_get_cell_value_core(i, column, value, value_len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* not found */
|
||||||
|
return SNMP_ERR_NOSUCHINSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static snmp_err_t
|
||||||
|
ip_NetToMediaTable_get_next_cell_instance_and_value(const u32_t* column, struct snmp_obj_id* row_oid, union snmp_variant_value* value, u32_t* value_len)
|
||||||
|
{
|
||||||
|
u8_t i;
|
||||||
|
struct snmp_next_oid_state state;
|
||||||
|
u32_t result_temp[LWIP_ARRAYSIZE(ip_NetToMediaTable_oid_ranges)];
|
||||||
|
|
||||||
|
/* init struct to search next oid */
|
||||||
|
snmp_next_oid_init(&state, row_oid->id, row_oid->len, result_temp, LWIP_ARRAYSIZE(ip_NetToMediaTable_oid_ranges));
|
||||||
|
|
||||||
|
/* iterate over all possible OIDs to find the next one */
|
||||||
|
for (i=0; i<ARP_TABLE_SIZE; i++) {
|
||||||
|
ip4_addr_t *ip;
|
||||||
|
struct netif *netif;
|
||||||
|
struct eth_addr *ethaddr;
|
||||||
|
|
||||||
|
if (etharp_get_entry(i, &ip, &netif, ðaddr)) {
|
||||||
|
u32_t test_oid[LWIP_ARRAYSIZE(ip_NetToMediaTable_oid_ranges)];
|
||||||
|
|
||||||
|
test_oid[0] = netif_to_num(netif);
|
||||||
|
snmp_ip4_to_oid(ip, &test_oid[1]);
|
||||||
|
|
||||||
|
/* check generated OID: is it a candidate for the next one? */
|
||||||
|
snmp_next_oid_check(&state, test_oid, LWIP_ARRAYSIZE(ip_NetToMediaTable_oid_ranges), LWIP_PTR_NUMERIC_CAST(void*, i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* did we find a next one? */
|
||||||
|
if (state.status == SNMP_NEXT_OID_STATUS_SUCCESS) {
|
||||||
|
snmp_oid_assign(row_oid, state.next_oid, state.next_oid_len);
|
||||||
|
/* fill in object properties */
|
||||||
|
return ip_NetToMediaTable_get_cell_value_core(LWIP_PTR_NUMERIC_CAST(u8_t, state.reference), column, value, value_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* not found */
|
||||||
|
return SNMP_ERR_NOSUCHINSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* LWIP_ARP && LWIP_IPV4 */
|
||||||
|
|
||||||
|
static const struct snmp_scalar_node ip_Forwarding = SNMP_SCALAR_CREATE_NODE(1, SNMP_NODE_INSTANCE_READ_WRITE, SNMP_ASN1_TYPE_INTEGER, ip_get_value, ip_set_test, ip_set_value);
|
||||||
|
static const struct snmp_scalar_node ip_DefaultTTL = SNMP_SCALAR_CREATE_NODE(2, SNMP_NODE_INSTANCE_READ_WRITE, SNMP_ASN1_TYPE_INTEGER, ip_get_value, ip_set_test, ip_set_value);
|
||||||
|
static const struct snmp_scalar_node ip_InReceives = SNMP_SCALAR_CREATE_NODE_READONLY(3, SNMP_ASN1_TYPE_COUNTER, ip_get_value);
|
||||||
|
static const struct snmp_scalar_node ip_InHdrErrors = SNMP_SCALAR_CREATE_NODE_READONLY(4, SNMP_ASN1_TYPE_COUNTER, ip_get_value);
|
||||||
|
static const struct snmp_scalar_node ip_InAddrErrors = SNMP_SCALAR_CREATE_NODE_READONLY(5, SNMP_ASN1_TYPE_COUNTER, ip_get_value);
|
||||||
|
static const struct snmp_scalar_node ip_ForwDatagrams = SNMP_SCALAR_CREATE_NODE_READONLY(6, SNMP_ASN1_TYPE_COUNTER, ip_get_value);
|
||||||
|
static const struct snmp_scalar_node ip_InUnknownProtos = SNMP_SCALAR_CREATE_NODE_READONLY(7, SNMP_ASN1_TYPE_COUNTER, ip_get_value);
|
||||||
|
static const struct snmp_scalar_node ip_InDiscards = SNMP_SCALAR_CREATE_NODE_READONLY(8, SNMP_ASN1_TYPE_COUNTER, ip_get_value);
|
||||||
|
static const struct snmp_scalar_node ip_InDelivers = SNMP_SCALAR_CREATE_NODE_READONLY(9, SNMP_ASN1_TYPE_COUNTER, ip_get_value);
|
||||||
|
static const struct snmp_scalar_node ip_OutRequests = SNMP_SCALAR_CREATE_NODE_READONLY(10, SNMP_ASN1_TYPE_COUNTER, ip_get_value);
|
||||||
|
static const struct snmp_scalar_node ip_OutDiscards = SNMP_SCALAR_CREATE_NODE_READONLY(11, SNMP_ASN1_TYPE_COUNTER, ip_get_value);
|
||||||
|
static const struct snmp_scalar_node ip_OutNoRoutes = SNMP_SCALAR_CREATE_NODE_READONLY(12, SNMP_ASN1_TYPE_COUNTER, ip_get_value);
|
||||||
|
static const struct snmp_scalar_node ip_ReasmTimeout = SNMP_SCALAR_CREATE_NODE_READONLY(13, SNMP_ASN1_TYPE_INTEGER, ip_get_value);
|
||||||
|
static const struct snmp_scalar_node ip_ReasmReqds = SNMP_SCALAR_CREATE_NODE_READONLY(14, SNMP_ASN1_TYPE_COUNTER, ip_get_value);
|
||||||
|
static const struct snmp_scalar_node ip_ReasmOKs = SNMP_SCALAR_CREATE_NODE_READONLY(15, SNMP_ASN1_TYPE_COUNTER, ip_get_value);
|
||||||
|
static const struct snmp_scalar_node ip_ReasmFails = SNMP_SCALAR_CREATE_NODE_READONLY(16, SNMP_ASN1_TYPE_COUNTER, ip_get_value);
|
||||||
|
static const struct snmp_scalar_node ip_FragOKs = SNMP_SCALAR_CREATE_NODE_READONLY(17, SNMP_ASN1_TYPE_COUNTER, ip_get_value);
|
||||||
|
static const struct snmp_scalar_node ip_FragFails = SNMP_SCALAR_CREATE_NODE_READONLY(18, SNMP_ASN1_TYPE_COUNTER, ip_get_value);
|
||||||
|
static const struct snmp_scalar_node ip_FragCreates = SNMP_SCALAR_CREATE_NODE_READONLY(19, SNMP_ASN1_TYPE_COUNTER, ip_get_value);
|
||||||
|
static const struct snmp_scalar_node ip_RoutingDiscards = SNMP_SCALAR_CREATE_NODE_READONLY(23, SNMP_ASN1_TYPE_COUNTER, ip_get_value);
|
||||||
|
|
||||||
|
static const struct snmp_table_simple_col_def ip_AddrTable_columns[] = {
|
||||||
|
{ 1, SNMP_ASN1_TYPE_IPADDR, SNMP_VARIANT_VALUE_TYPE_U32 }, /* ipAdEntAddr */
|
||||||
|
{ 2, SNMP_ASN1_TYPE_INTEGER, SNMP_VARIANT_VALUE_TYPE_U32 }, /* ipAdEntIfIndex */
|
||||||
|
{ 3, SNMP_ASN1_TYPE_IPADDR, SNMP_VARIANT_VALUE_TYPE_U32 }, /* ipAdEntNetMask */
|
||||||
|
{ 4, SNMP_ASN1_TYPE_INTEGER, SNMP_VARIANT_VALUE_TYPE_U32 }, /* ipAdEntBcastAddr */
|
||||||
|
{ 5, SNMP_ASN1_TYPE_INTEGER, SNMP_VARIANT_VALUE_TYPE_U32 } /* ipAdEntReasmMaxSize */
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct snmp_table_simple_node ip_AddrTable = SNMP_TABLE_CREATE_SIMPLE(20, ip_AddrTable_columns, ip_AddrTable_get_cell_value, ip_AddrTable_get_next_cell_instance_and_value);
|
||||||
|
|
||||||
|
static const struct snmp_table_simple_col_def ip_RouteTable_columns[] = {
|
||||||
|
{ 1, SNMP_ASN1_TYPE_IPADDR, SNMP_VARIANT_VALUE_TYPE_U32 }, /* ipRouteDest */
|
||||||
|
{ 2, SNMP_ASN1_TYPE_INTEGER, SNMP_VARIANT_VALUE_TYPE_U32 }, /* ipRouteIfIndex */
|
||||||
|
{ 3, SNMP_ASN1_TYPE_INTEGER, SNMP_VARIANT_VALUE_TYPE_S32 }, /* ipRouteMetric1 */
|
||||||
|
{ 4, SNMP_ASN1_TYPE_INTEGER, SNMP_VARIANT_VALUE_TYPE_S32 }, /* ipRouteMetric2 */
|
||||||
|
{ 5, SNMP_ASN1_TYPE_INTEGER, SNMP_VARIANT_VALUE_TYPE_S32 }, /* ipRouteMetric3 */
|
||||||
|
{ 6, SNMP_ASN1_TYPE_INTEGER, SNMP_VARIANT_VALUE_TYPE_S32 }, /* ipRouteMetric4 */
|
||||||
|
{ 7, SNMP_ASN1_TYPE_IPADDR, SNMP_VARIANT_VALUE_TYPE_U32 }, /* ipRouteNextHop */
|
||||||
|
{ 8, SNMP_ASN1_TYPE_INTEGER, SNMP_VARIANT_VALUE_TYPE_U32 }, /* ipRouteType */
|
||||||
|
{ 9, SNMP_ASN1_TYPE_INTEGER, SNMP_VARIANT_VALUE_TYPE_U32 }, /* ipRouteProto */
|
||||||
|
{ 10, SNMP_ASN1_TYPE_INTEGER, SNMP_VARIANT_VALUE_TYPE_U32 }, /* ipRouteAge */
|
||||||
|
{ 11, SNMP_ASN1_TYPE_IPADDR, SNMP_VARIANT_VALUE_TYPE_U32 }, /* ipRouteMask */
|
||||||
|
{ 12, SNMP_ASN1_TYPE_INTEGER, SNMP_VARIANT_VALUE_TYPE_S32 }, /* ipRouteMetric5 */
|
||||||
|
{ 13, SNMP_ASN1_TYPE_OBJECT_ID, SNMP_VARIANT_VALUE_TYPE_PTR } /* ipRouteInfo */
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct snmp_table_simple_node ip_RouteTable = SNMP_TABLE_CREATE_SIMPLE(21, ip_RouteTable_columns, ip_RouteTable_get_cell_value, ip_RouteTable_get_next_cell_instance_and_value);
|
||||||
|
#endif /* LWIP_IPV4 */
|
||||||
|
|
||||||
|
#if LWIP_ARP && LWIP_IPV4
|
||||||
|
static const struct snmp_table_simple_col_def ip_NetToMediaTable_columns[] = {
|
||||||
|
{ 1, SNMP_ASN1_TYPE_INTEGER, SNMP_VARIANT_VALUE_TYPE_U32 }, /* ipNetToMediaIfIndex */
|
||||||
|
{ 2, SNMP_ASN1_TYPE_OCTET_STRING, SNMP_VARIANT_VALUE_TYPE_PTR }, /* ipNetToMediaPhysAddress */
|
||||||
|
{ 3, SNMP_ASN1_TYPE_IPADDR, SNMP_VARIANT_VALUE_TYPE_U32 }, /* ipNetToMediaNetAddress */
|
||||||
|
{ 4, SNMP_ASN1_TYPE_INTEGER, SNMP_VARIANT_VALUE_TYPE_U32 } /* ipNetToMediaType */
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct snmp_table_simple_node ip_NetToMediaTable = SNMP_TABLE_CREATE_SIMPLE(22, ip_NetToMediaTable_columns, ip_NetToMediaTable_get_cell_value, ip_NetToMediaTable_get_next_cell_instance_and_value);
|
||||||
|
#endif /* LWIP_ARP && LWIP_IPV4 */
|
||||||
|
|
||||||
|
#if LWIP_IPV4
|
||||||
|
/* the following nodes access variables in LWIP stack from SNMP worker thread and must therefore be synced to LWIP (TCPIP) thread */
|
||||||
|
CREATE_LWIP_SYNC_NODE( 1, ip_Forwarding)
|
||||||
|
CREATE_LWIP_SYNC_NODE( 2, ip_DefaultTTL)
|
||||||
|
CREATE_LWIP_SYNC_NODE( 3, ip_InReceives)
|
||||||
|
CREATE_LWIP_SYNC_NODE( 4, ip_InHdrErrors)
|
||||||
|
CREATE_LWIP_SYNC_NODE( 5, ip_InAddrErrors)
|
||||||
|
CREATE_LWIP_SYNC_NODE( 6, ip_ForwDatagrams)
|
||||||
|
CREATE_LWIP_SYNC_NODE( 7, ip_InUnknownProtos)
|
||||||
|
CREATE_LWIP_SYNC_NODE( 8, ip_InDiscards)
|
||||||
|
CREATE_LWIP_SYNC_NODE( 9, ip_InDelivers)
|
||||||
|
CREATE_LWIP_SYNC_NODE(10, ip_OutRequests)
|
||||||
|
CREATE_LWIP_SYNC_NODE(11, ip_OutDiscards)
|
||||||
|
CREATE_LWIP_SYNC_NODE(12, ip_OutNoRoutes)
|
||||||
|
CREATE_LWIP_SYNC_NODE(13, ip_ReasmTimeout)
|
||||||
|
CREATE_LWIP_SYNC_NODE(14, ip_ReasmReqds)
|
||||||
|
CREATE_LWIP_SYNC_NODE(15, ip_ReasmOKs)
|
||||||
|
CREATE_LWIP_SYNC_NODE(15, ip_ReasmFails)
|
||||||
|
CREATE_LWIP_SYNC_NODE(17, ip_FragOKs)
|
||||||
|
CREATE_LWIP_SYNC_NODE(18, ip_FragFails)
|
||||||
|
CREATE_LWIP_SYNC_NODE(19, ip_FragCreates)
|
||||||
|
CREATE_LWIP_SYNC_NODE(20, ip_AddrTable)
|
||||||
|
CREATE_LWIP_SYNC_NODE(21, ip_RouteTable)
|
||||||
|
#if LWIP_ARP
|
||||||
|
CREATE_LWIP_SYNC_NODE(22, ip_NetToMediaTable)
|
||||||
|
#endif /* LWIP_ARP */
|
||||||
|
CREATE_LWIP_SYNC_NODE(23, ip_RoutingDiscards)
|
||||||
|
|
||||||
|
static const struct snmp_node* const ip_nodes[] = {
|
||||||
|
&SYNC_NODE_NAME(ip_Forwarding).node.node,
|
||||||
|
&SYNC_NODE_NAME(ip_DefaultTTL).node.node,
|
||||||
|
&SYNC_NODE_NAME(ip_InReceives).node.node,
|
||||||
|
&SYNC_NODE_NAME(ip_InHdrErrors).node.node,
|
||||||
|
&SYNC_NODE_NAME(ip_InAddrErrors).node.node,
|
||||||
|
&SYNC_NODE_NAME(ip_ForwDatagrams).node.node,
|
||||||
|
&SYNC_NODE_NAME(ip_InUnknownProtos).node.node,
|
||||||
|
&SYNC_NODE_NAME(ip_InDiscards).node.node,
|
||||||
|
&SYNC_NODE_NAME(ip_InDelivers).node.node,
|
||||||
|
&SYNC_NODE_NAME(ip_OutRequests).node.node,
|
||||||
|
&SYNC_NODE_NAME(ip_OutDiscards).node.node,
|
||||||
|
&SYNC_NODE_NAME(ip_OutNoRoutes).node.node,
|
||||||
|
&SYNC_NODE_NAME(ip_ReasmTimeout).node.node,
|
||||||
|
&SYNC_NODE_NAME(ip_ReasmReqds).node.node,
|
||||||
|
&SYNC_NODE_NAME(ip_ReasmOKs).node.node,
|
||||||
|
&SYNC_NODE_NAME(ip_ReasmFails).node.node,
|
||||||
|
&SYNC_NODE_NAME(ip_FragOKs).node.node,
|
||||||
|
&SYNC_NODE_NAME(ip_FragFails).node.node,
|
||||||
|
&SYNC_NODE_NAME(ip_FragCreates).node.node,
|
||||||
|
&SYNC_NODE_NAME(ip_AddrTable).node.node,
|
||||||
|
&SYNC_NODE_NAME(ip_RouteTable).node.node,
|
||||||
|
#if LWIP_ARP
|
||||||
|
&SYNC_NODE_NAME(ip_NetToMediaTable).node.node,
|
||||||
|
#endif /* LWIP_ARP */
|
||||||
|
&SYNC_NODE_NAME(ip_RoutingDiscards).node.node
|
||||||
|
};
|
||||||
|
|
||||||
|
const struct snmp_tree_node snmp_mib2_ip_root = SNMP_CREATE_TREE_NODE(4, ip_nodes);
|
||||||
|
#endif /* LWIP_IPV4 */
|
||||||
|
|
||||||
|
/* --- at .1.3.6.1.2.1.3 ----------------------------------------------------- */
|
||||||
|
|
||||||
|
#if LWIP_ARP && LWIP_IPV4
|
||||||
|
/* at node table is a subset of ip_nettomedia table (same rows but less columns) */
|
||||||
|
static const struct snmp_table_simple_col_def at_Table_columns[] = {
|
||||||
|
{ 1, SNMP_ASN1_TYPE_INTEGER, SNMP_VARIANT_VALUE_TYPE_U32 }, /* atIfIndex */
|
||||||
|
{ 2, SNMP_ASN1_TYPE_OCTET_STRING, SNMP_VARIANT_VALUE_TYPE_PTR }, /* atPhysAddress */
|
||||||
|
{ 3, SNMP_ASN1_TYPE_IPADDR, SNMP_VARIANT_VALUE_TYPE_U32 } /* atNetAddress */
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct snmp_table_simple_node at_Table = SNMP_TABLE_CREATE_SIMPLE(1, at_Table_columns, ip_NetToMediaTable_get_cell_value, ip_NetToMediaTable_get_next_cell_instance_and_value);
|
||||||
|
|
||||||
|
/* the following nodes access variables in LWIP stack from SNMP worker thread and must therefore be synced to LWIP (TCPIP) thread */
|
||||||
|
CREATE_LWIP_SYNC_NODE(1, at_Table)
|
||||||
|
|
||||||
|
static const struct snmp_node* const at_nodes[] = {
|
||||||
|
&SYNC_NODE_NAME(at_Table).node.node
|
||||||
|
};
|
||||||
|
|
||||||
|
const struct snmp_tree_node snmp_mib2_at_root = SNMP_CREATE_TREE_NODE(3, at_nodes);
|
||||||
|
#endif /* LWIP_ARP && LWIP_IPV4 */
|
||||||
|
|
||||||
|
#endif /* LWIP_SNMP && SNMP_LWIP_MIB2 */
|
|
@ -0,0 +1,227 @@
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* Management Information Base II (RFC1213) SNMP objects and functions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006 Axon Digital Design B.V., The Netherlands.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||||
|
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||||
|
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
|
* OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* Author: Dirk Ziegelmeier <dziegel@gmx.de>
|
||||||
|
* Christiaan Simons <christiaan.simons@axon.tv>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "lwip/snmp.h"
|
||||||
|
#include "lwip/apps/snmp.h"
|
||||||
|
#include "lwip/apps/snmp_core.h"
|
||||||
|
#include "lwip/apps/snmp_mib2.h"
|
||||||
|
#include "lwip/apps/snmp_scalar.h"
|
||||||
|
|
||||||
|
#if LWIP_SNMP && SNMP_LWIP_MIB2
|
||||||
|
|
||||||
|
#define MIB2_AUTH_TRAPS_ENABLED 1
|
||||||
|
#define MIB2_AUTH_TRAPS_DISABLED 2
|
||||||
|
|
||||||
|
/* --- snmp .1.3.6.1.2.1.11 ----------------------------------------------------- */
|
||||||
|
static s16_t
|
||||||
|
snmp_get_value(const struct snmp_scalar_array_node_def *node, void *value)
|
||||||
|
{
|
||||||
|
u32_t *uint_ptr = (u32_t*)value;
|
||||||
|
switch (node->oid) {
|
||||||
|
case 1: /* snmpInPkts */
|
||||||
|
*uint_ptr = snmp_stats.inpkts;
|
||||||
|
break;
|
||||||
|
case 2: /* snmpOutPkts */
|
||||||
|
*uint_ptr = snmp_stats.outpkts;
|
||||||
|
break;
|
||||||
|
case 3: /* snmpInBadVersions */
|
||||||
|
*uint_ptr = snmp_stats.inbadversions;
|
||||||
|
break;
|
||||||
|
case 4: /* snmpInBadCommunityNames */
|
||||||
|
*uint_ptr = snmp_stats.inbadcommunitynames;
|
||||||
|
break;
|
||||||
|
case 5: /* snmpInBadCommunityUses */
|
||||||
|
*uint_ptr = snmp_stats.inbadcommunityuses;
|
||||||
|
break;
|
||||||
|
case 6: /* snmpInASNParseErrs */
|
||||||
|
*uint_ptr = snmp_stats.inasnparseerrs;
|
||||||
|
break;
|
||||||
|
case 8: /* snmpInTooBigs */
|
||||||
|
*uint_ptr = snmp_stats.intoobigs;
|
||||||
|
break;
|
||||||
|
case 9: /* snmpInNoSuchNames */
|
||||||
|
*uint_ptr = snmp_stats.innosuchnames;
|
||||||
|
break;
|
||||||
|
case 10: /* snmpInBadValues */
|
||||||
|
*uint_ptr = snmp_stats.inbadvalues;
|
||||||
|
break;
|
||||||
|
case 11: /* snmpInReadOnlys */
|
||||||
|
*uint_ptr = snmp_stats.inreadonlys;
|
||||||
|
break;
|
||||||
|
case 12: /* snmpInGenErrs */
|
||||||
|
*uint_ptr = snmp_stats.ingenerrs;
|
||||||
|
break;
|
||||||
|
case 13: /* snmpInTotalReqVars */
|
||||||
|
*uint_ptr = snmp_stats.intotalreqvars;
|
||||||
|
break;
|
||||||
|
case 14: /* snmpInTotalSetVars */
|
||||||
|
*uint_ptr = snmp_stats.intotalsetvars;
|
||||||
|
break;
|
||||||
|
case 15: /* snmpInGetRequests */
|
||||||
|
*uint_ptr = snmp_stats.ingetrequests;
|
||||||
|
break;
|
||||||
|
case 16: /* snmpInGetNexts */
|
||||||
|
*uint_ptr = snmp_stats.ingetnexts;
|
||||||
|
break;
|
||||||
|
case 17: /* snmpInSetRequests */
|
||||||
|
*uint_ptr = snmp_stats.insetrequests;
|
||||||
|
break;
|
||||||
|
case 18: /* snmpInGetResponses */
|
||||||
|
*uint_ptr = snmp_stats.ingetresponses;
|
||||||
|
break;
|
||||||
|
case 19: /* snmpInTraps */
|
||||||
|
*uint_ptr = snmp_stats.intraps;
|
||||||
|
break;
|
||||||
|
case 20: /* snmpOutTooBigs */
|
||||||
|
*uint_ptr = snmp_stats.outtoobigs;
|
||||||
|
break;
|
||||||
|
case 21: /* snmpOutNoSuchNames */
|
||||||
|
*uint_ptr = snmp_stats.outnosuchnames;
|
||||||
|
break;
|
||||||
|
case 22: /* snmpOutBadValues */
|
||||||
|
*uint_ptr = snmp_stats.outbadvalues;
|
||||||
|
break;
|
||||||
|
case 24: /* snmpOutGenErrs */
|
||||||
|
*uint_ptr = snmp_stats.outgenerrs;
|
||||||
|
break;
|
||||||
|
case 25: /* snmpOutGetRequests */
|
||||||
|
*uint_ptr = snmp_stats.outgetrequests;
|
||||||
|
break;
|
||||||
|
case 26: /* snmpOutGetNexts */
|
||||||
|
*uint_ptr = snmp_stats.outgetnexts;
|
||||||
|
break;
|
||||||
|
case 27: /* snmpOutSetRequests */
|
||||||
|
*uint_ptr = snmp_stats.outsetrequests;
|
||||||
|
break;
|
||||||
|
case 28: /* snmpOutGetResponses */
|
||||||
|
*uint_ptr = snmp_stats.outgetresponses;
|
||||||
|
break;
|
||||||
|
case 29: /* snmpOutTraps */
|
||||||
|
*uint_ptr = snmp_stats.outtraps;
|
||||||
|
break;
|
||||||
|
case 30: /* snmpEnableAuthenTraps */
|
||||||
|
if (snmp_get_auth_traps_enabled() == SNMP_AUTH_TRAPS_DISABLED) {
|
||||||
|
*uint_ptr = MIB2_AUTH_TRAPS_DISABLED;
|
||||||
|
} else {
|
||||||
|
*uint_ptr = MIB2_AUTH_TRAPS_ENABLED;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 31: /* snmpSilentDrops */
|
||||||
|
*uint_ptr = 0; /* not supported */
|
||||||
|
break;
|
||||||
|
case 32: /* snmpProxyDrops */
|
||||||
|
*uint_ptr = 0; /* not supported */
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
LWIP_DEBUGF(SNMP_MIB_DEBUG,("snmp_get_value(): unknown id: %"S32_F"\n", node->oid));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return sizeof(*uint_ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
static snmp_err_t
|
||||||
|
snmp_set_test(const struct snmp_scalar_array_node_def *node, u16_t len, void *value)
|
||||||
|
{
|
||||||
|
snmp_err_t ret = SNMP_ERR_WRONGVALUE;
|
||||||
|
LWIP_UNUSED_ARG(len);
|
||||||
|
|
||||||
|
if (node->oid == 30) {
|
||||||
|
/* snmpEnableAuthenTraps */
|
||||||
|
s32_t *sint_ptr = (s32_t*)value;
|
||||||
|
|
||||||
|
/* we should have writable non-volatile mem here */
|
||||||
|
if ((*sint_ptr == MIB2_AUTH_TRAPS_DISABLED) || (*sint_ptr == MIB2_AUTH_TRAPS_ENABLED)) {
|
||||||
|
ret = SNMP_ERR_NOERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static snmp_err_t
|
||||||
|
snmp_set_value(const struct snmp_scalar_array_node_def *node, u16_t len, void *value)
|
||||||
|
{
|
||||||
|
LWIP_UNUSED_ARG(len);
|
||||||
|
|
||||||
|
if (node->oid == 30) {
|
||||||
|
/* snmpEnableAuthenTraps */
|
||||||
|
s32_t *sint_ptr = (s32_t*)value;
|
||||||
|
if (*sint_ptr == MIB2_AUTH_TRAPS_DISABLED) {
|
||||||
|
snmp_set_auth_traps_enabled(SNMP_AUTH_TRAPS_DISABLED);
|
||||||
|
} else {
|
||||||
|
snmp_set_auth_traps_enabled(SNMP_AUTH_TRAPS_ENABLED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return SNMP_ERR_NOERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* the following nodes access variables in SNMP stack (snmp_stats) from SNMP worker thread -> OK, no sync needed */
|
||||||
|
static const struct snmp_scalar_array_node_def snmp_nodes[] = {
|
||||||
|
{ 1, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, /* snmpInPkts */
|
||||||
|
{ 2, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, /* snmpOutPkts */
|
||||||
|
{ 3, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, /* snmpInBadVersions */
|
||||||
|
{ 4, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, /* snmpInBadCommunityNames */
|
||||||
|
{ 5, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, /* snmpInBadCommunityUses */
|
||||||
|
{ 6, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, /* snmpInASNParseErrs */
|
||||||
|
{ 8, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, /* snmpInTooBigs */
|
||||||
|
{ 9, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, /* snmpInNoSuchNames */
|
||||||
|
{10, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, /* snmpInBadValues */
|
||||||
|
{11, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, /* snmpInReadOnlys */
|
||||||
|
{12, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, /* snmpInGenErrs */
|
||||||
|
{13, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, /* snmpInTotalReqVars */
|
||||||
|
{14, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, /* snmpInTotalSetVars */
|
||||||
|
{15, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, /* snmpInGetRequests */
|
||||||
|
{16, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, /* snmpInGetNexts */
|
||||||
|
{17, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, /* snmpInSetRequests */
|
||||||
|
{18, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, /* snmpInGetResponses */
|
||||||
|
{19, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, /* snmpInTraps */
|
||||||
|
{20, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, /* snmpOutTooBigs */
|
||||||
|
{21, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, /* snmpOutNoSuchNames */
|
||||||
|
{22, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, /* snmpOutBadValues */
|
||||||
|
{24, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, /* snmpOutGenErrs */
|
||||||
|
{25, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, /* snmpOutGetRequests */
|
||||||
|
{26, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, /* snmpOutGetNexts */
|
||||||
|
{27, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, /* snmpOutSetRequests */
|
||||||
|
{28, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, /* snmpOutGetResponses */
|
||||||
|
{29, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, /* snmpOutTraps */
|
||||||
|
{30, SNMP_ASN1_TYPE_INTEGER, SNMP_NODE_INSTANCE_READ_WRITE}, /* snmpEnableAuthenTraps */
|
||||||
|
{31, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, /* snmpSilentDrops */
|
||||||
|
{32, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY} /* snmpProxyDrops */
|
||||||
|
};
|
||||||
|
|
||||||
|
const struct snmp_scalar_array_node snmp_mib2_snmp_root = SNMP_SCALAR_CREATE_ARRAY_NODE(11, snmp_nodes, snmp_get_value, snmp_set_test, snmp_set_value);
|
||||||
|
|
||||||
|
#endif /* LWIP_SNMP && SNMP_LWIP_MIB2 */
|
|
@ -0,0 +1,377 @@
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* Management Information Base II (RFC1213) SYSTEM objects and functions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006 Axon Digital Design B.V., The Netherlands.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||||
|
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||||
|
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
|
* OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* Author: Dirk Ziegelmeier <dziegel@gmx.de>
|
||||||
|
* Christiaan Simons <christiaan.simons@axon.tv>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "lwip/snmp.h"
|
||||||
|
#include "lwip/apps/snmp.h"
|
||||||
|
#include "lwip/apps/snmp_core.h"
|
||||||
|
#include "lwip/apps/snmp_mib2.h"
|
||||||
|
#include "lwip/apps/snmp_table.h"
|
||||||
|
#include "lwip/apps/snmp_scalar.h"
|
||||||
|
#include "lwip/sys.h"
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#if LWIP_SNMP && SNMP_LWIP_MIB2
|
||||||
|
|
||||||
|
#if SNMP_USE_NETCONN
|
||||||
|
#define SYNC_NODE_NAME(node_name) node_name ## _synced
|
||||||
|
#define CREATE_LWIP_SYNC_NODE(oid, node_name) \
|
||||||
|
static const struct snmp_threadsync_node node_name ## _synced = SNMP_CREATE_THREAD_SYNC_NODE(oid, &node_name.node, &snmp_mib2_lwip_locks);
|
||||||
|
#else
|
||||||
|
#define SYNC_NODE_NAME(node_name) node_name
|
||||||
|
#define CREATE_LWIP_SYNC_NODE(oid, node_name)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* --- system .1.3.6.1.2.1.1 ----------------------------------------------------- */
|
||||||
|
|
||||||
|
/** mib-2.system.sysDescr */
|
||||||
|
static const u8_t sysdescr_default[] = SNMP_LWIP_MIB2_SYSDESC;
|
||||||
|
static const u8_t* sysdescr = sysdescr_default;
|
||||||
|
static const u16_t* sysdescr_len = NULL; /* use strlen for determining len */
|
||||||
|
|
||||||
|
/** mib-2.system.sysContact */
|
||||||
|
static const u8_t syscontact_default[] = SNMP_LWIP_MIB2_SYSCONTACT;
|
||||||
|
static const u8_t* syscontact = syscontact_default;
|
||||||
|
static const u16_t* syscontact_len = NULL; /* use strlen for determining len */
|
||||||
|
static u8_t* syscontact_wr = NULL; /* if writable, points to the same buffer as syscontact (required for correct constness) */
|
||||||
|
static u16_t* syscontact_wr_len = NULL; /* if writable, points to the same buffer as syscontact_len (required for correct constness) */
|
||||||
|
static u16_t syscontact_bufsize = 0; /* 0=not writable */
|
||||||
|
|
||||||
|
/** mib-2.system.sysName */
|
||||||
|
static const u8_t sysname_default[] = SNMP_LWIP_MIB2_SYSNAME;
|
||||||
|
static const u8_t* sysname = sysname_default;
|
||||||
|
static const u16_t* sysname_len = NULL; /* use strlen for determining len */
|
||||||
|
static u8_t* sysname_wr = NULL; /* if writable, points to the same buffer as sysname (required for correct constness) */
|
||||||
|
static u16_t* sysname_wr_len = NULL; /* if writable, points to the same buffer as sysname_len (required for correct constness) */
|
||||||
|
static u16_t sysname_bufsize = 0; /* 0=not writable */
|
||||||
|
|
||||||
|
/** mib-2.system.sysLocation */
|
||||||
|
static const u8_t syslocation_default[] = SNMP_LWIP_MIB2_SYSLOCATION;
|
||||||
|
static const u8_t* syslocation = syslocation_default;
|
||||||
|
static const u16_t* syslocation_len = NULL; /* use strlen for determining len */
|
||||||
|
static u8_t* syslocation_wr = NULL; /* if writable, points to the same buffer as syslocation (required for correct constness) */
|
||||||
|
static u16_t* syslocation_wr_len = NULL; /* if writable, points to the same buffer as syslocation_len (required for correct constness) */
|
||||||
|
static u16_t syslocation_bufsize = 0; /* 0=not writable */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup snmp_mib2
|
||||||
|
* Initializes sysDescr pointers.
|
||||||
|
*
|
||||||
|
* @param str if non-NULL then copy str pointer
|
||||||
|
* @param len points to string length, excluding zero terminator
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
snmp_mib2_set_sysdescr(const u8_t *str, const u16_t *len)
|
||||||
|
{
|
||||||
|
if (str != NULL) {
|
||||||
|
sysdescr = str;
|
||||||
|
sysdescr_len = len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup snmp_mib2
|
||||||
|
* Initializes sysContact pointers
|
||||||
|
*
|
||||||
|
* @param ocstr if non-NULL then copy str pointer
|
||||||
|
* @param ocstrlen points to string length, excluding zero terminator.
|
||||||
|
* if set to NULL it is assumed that ocstr is NULL-terminated.
|
||||||
|
* @param bufsize size of the buffer in bytes.
|
||||||
|
* (this is required because the buffer can be overwritten by snmp-set)
|
||||||
|
* if ocstrlen is NULL buffer needs space for terminating 0 byte.
|
||||||
|
* otherwise complete buffer is used for string.
|
||||||
|
* if bufsize is set to 0, the value is regarded as read-only.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
snmp_mib2_set_syscontact(u8_t *ocstr, u16_t *ocstrlen, u16_t bufsize)
|
||||||
|
{
|
||||||
|
if (ocstr != NULL) {
|
||||||
|
syscontact = ocstr;
|
||||||
|
syscontact_wr = ocstr;
|
||||||
|
syscontact_len = ocstrlen;
|
||||||
|
syscontact_wr_len = ocstrlen;
|
||||||
|
syscontact_bufsize = bufsize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup snmp_mib2
|
||||||
|
* see \ref snmp_mib2_set_syscontact but set pointer to readonly memory
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
snmp_mib2_set_syscontact_readonly(const u8_t *ocstr, const u16_t *ocstrlen)
|
||||||
|
{
|
||||||
|
if (ocstr != NULL) {
|
||||||
|
syscontact = ocstr;
|
||||||
|
syscontact_len = ocstrlen;
|
||||||
|
syscontact_wr = NULL;
|
||||||
|
syscontact_wr_len = NULL;
|
||||||
|
syscontact_bufsize = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup snmp_mib2
|
||||||
|
* Initializes sysName pointers
|
||||||
|
*
|
||||||
|
* @param ocstr if non-NULL then copy str pointer
|
||||||
|
* @param ocstrlen points to string length, excluding zero terminator.
|
||||||
|
* if set to NULL it is assumed that ocstr is NULL-terminated.
|
||||||
|
* @param bufsize size of the buffer in bytes.
|
||||||
|
* (this is required because the buffer can be overwritten by snmp-set)
|
||||||
|
* if ocstrlen is NULL buffer needs space for terminating 0 byte.
|
||||||
|
* otherwise complete buffer is used for string.
|
||||||
|
* if bufsize is set to 0, the value is regarded as read-only.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
snmp_mib2_set_sysname(u8_t *ocstr, u16_t *ocstrlen, u16_t bufsize)
|
||||||
|
{
|
||||||
|
if (ocstr != NULL) {
|
||||||
|
sysname = ocstr;
|
||||||
|
sysname_wr = ocstr;
|
||||||
|
sysname_len = ocstrlen;
|
||||||
|
sysname_wr_len = ocstrlen;
|
||||||
|
sysname_bufsize = bufsize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup snmp_mib2
|
||||||
|
* see \ref snmp_mib2_set_sysname but set pointer to readonly memory
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
snmp_mib2_set_sysname_readonly(const u8_t *ocstr, const u16_t *ocstrlen)
|
||||||
|
{
|
||||||
|
if (ocstr != NULL) {
|
||||||
|
sysname = ocstr;
|
||||||
|
sysname_len = ocstrlen;
|
||||||
|
sysname_wr = NULL;
|
||||||
|
sysname_wr_len = NULL;
|
||||||
|
sysname_bufsize = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup snmp_mib2
|
||||||
|
* Initializes sysLocation pointers
|
||||||
|
*
|
||||||
|
* @param ocstr if non-NULL then copy str pointer
|
||||||
|
* @param ocstrlen points to string length, excluding zero terminator.
|
||||||
|
* if set to NULL it is assumed that ocstr is NULL-terminated.
|
||||||
|
* @param bufsize size of the buffer in bytes.
|
||||||
|
* (this is required because the buffer can be overwritten by snmp-set)
|
||||||
|
* if ocstrlen is NULL buffer needs space for terminating 0 byte.
|
||||||
|
* otherwise complete buffer is used for string.
|
||||||
|
* if bufsize is set to 0, the value is regarded as read-only.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
snmp_mib2_set_syslocation(u8_t *ocstr, u16_t *ocstrlen, u16_t bufsize)
|
||||||
|
{
|
||||||
|
if (ocstr != NULL) {
|
||||||
|
syslocation = ocstr;
|
||||||
|
syslocation_wr = ocstr;
|
||||||
|
syslocation_len = ocstrlen;
|
||||||
|
syslocation_wr_len = ocstrlen;
|
||||||
|
syslocation_bufsize = bufsize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup snmp_mib2
|
||||||
|
* see \ref snmp_mib2_set_syslocation but set pointer to readonly memory
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
snmp_mib2_set_syslocation_readonly(const u8_t *ocstr, const u16_t *ocstrlen)
|
||||||
|
{
|
||||||
|
if (ocstr != NULL) {
|
||||||
|
syslocation = ocstr;
|
||||||
|
syslocation_len = ocstrlen;
|
||||||
|
syslocation_wr = NULL;
|
||||||
|
syslocation_wr_len = NULL;
|
||||||
|
syslocation_bufsize = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static s16_t
|
||||||
|
system_get_value(const struct snmp_scalar_array_node_def *node, void *value)
|
||||||
|
{
|
||||||
|
const u8_t* var = NULL;
|
||||||
|
const s16_t* var_len;
|
||||||
|
u16_t result;
|
||||||
|
|
||||||
|
switch (node->oid) {
|
||||||
|
case 1: /* sysDescr */
|
||||||
|
var = sysdescr;
|
||||||
|
var_len = (const s16_t*)sysdescr_len;
|
||||||
|
break;
|
||||||
|
case 2: /* sysObjectID */
|
||||||
|
{
|
||||||
|
const struct snmp_obj_id* dev_enterprise_oid = snmp_get_device_enterprise_oid();
|
||||||
|
MEMCPY(value, dev_enterprise_oid->id, dev_enterprise_oid->len * sizeof(u32_t));
|
||||||
|
return dev_enterprise_oid->len * sizeof(u32_t);
|
||||||
|
}
|
||||||
|
case 3: /* sysUpTime */
|
||||||
|
MIB2_COPY_SYSUPTIME_TO((u32_t*)value);
|
||||||
|
return sizeof(u32_t);
|
||||||
|
case 4: /* sysContact */
|
||||||
|
var = syscontact;
|
||||||
|
var_len = (const s16_t*)syscontact_len;
|
||||||
|
break;
|
||||||
|
case 5: /* sysName */
|
||||||
|
var = sysname;
|
||||||
|
var_len = (const s16_t*)sysname_len;
|
||||||
|
break;
|
||||||
|
case 6: /* sysLocation */
|
||||||
|
var = syslocation;
|
||||||
|
var_len = (const s16_t*)syslocation_len;
|
||||||
|
break;
|
||||||
|
case 7: /* sysServices */
|
||||||
|
*(s32_t*)value = SNMP_SYSSERVICES;
|
||||||
|
return sizeof(s32_t);
|
||||||
|
default:
|
||||||
|
LWIP_DEBUGF(SNMP_MIB_DEBUG,("system_get_value(): unknown id: %"S32_F"\n", node->oid));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* handle string values (OID 1,4,5 and 6) */
|
||||||
|
LWIP_ASSERT("", (value != NULL));
|
||||||
|
if (var_len == NULL) {
|
||||||
|
result = (s16_t)strlen((const char*)var);
|
||||||
|
} else {
|
||||||
|
result = *var_len;
|
||||||
|
}
|
||||||
|
MEMCPY(value, var, result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static snmp_err_t
|
||||||
|
system_set_test(const struct snmp_scalar_array_node_def *node, u16_t len, void *value)
|
||||||
|
{
|
||||||
|
snmp_err_t ret = SNMP_ERR_WRONGVALUE;
|
||||||
|
const u16_t* var_bufsize = NULL;
|
||||||
|
const u16_t* var_wr_len;
|
||||||
|
|
||||||
|
LWIP_UNUSED_ARG(value);
|
||||||
|
|
||||||
|
switch (node->oid) {
|
||||||
|
case 4: /* sysContact */
|
||||||
|
var_bufsize = &syscontact_bufsize;
|
||||||
|
var_wr_len = syscontact_wr_len;
|
||||||
|
break;
|
||||||
|
case 5: /* sysName */
|
||||||
|
var_bufsize = &sysname_bufsize;
|
||||||
|
var_wr_len = sysname_wr_len;
|
||||||
|
break;
|
||||||
|
case 6: /* sysLocation */
|
||||||
|
var_bufsize = &syslocation_bufsize;
|
||||||
|
var_wr_len = syslocation_wr_len;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
LWIP_DEBUGF(SNMP_MIB_DEBUG,("system_set_test(): unknown id: %"S32_F"\n", node->oid));
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check if value is writable at all */
|
||||||
|
if (*var_bufsize > 0) {
|
||||||
|
if (var_wr_len == NULL) {
|
||||||
|
/* we have to take the terminating 0 into account */
|
||||||
|
if (len < *var_bufsize) {
|
||||||
|
ret = SNMP_ERR_NOERROR;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (len <= *var_bufsize) {
|
||||||
|
ret = SNMP_ERR_NOERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ret = SNMP_ERR_NOTWRITABLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static snmp_err_t
|
||||||
|
system_set_value(const struct snmp_scalar_array_node_def *node, u16_t len, void *value)
|
||||||
|
{
|
||||||
|
u8_t* var_wr = NULL;
|
||||||
|
u16_t* var_wr_len;
|
||||||
|
|
||||||
|
switch (node->oid) {
|
||||||
|
case 4: /* sysContact */
|
||||||
|
var_wr = syscontact_wr;
|
||||||
|
var_wr_len = syscontact_wr_len;
|
||||||
|
break;
|
||||||
|
case 5: /* sysName */
|
||||||
|
var_wr = sysname_wr;
|
||||||
|
var_wr_len = sysname_wr_len;
|
||||||
|
break;
|
||||||
|
case 6: /* sysLocation */
|
||||||
|
var_wr = syslocation_wr;
|
||||||
|
var_wr_len = syslocation_wr_len;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
LWIP_DEBUGF(SNMP_MIB_DEBUG,("system_set_value(): unknown id: %"S32_F"\n", node->oid));
|
||||||
|
return SNMP_ERR_GENERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* no need to check size of target buffer, this was already done in set_test method */
|
||||||
|
LWIP_ASSERT("", var_wr != NULL);
|
||||||
|
MEMCPY(var_wr, value, len);
|
||||||
|
|
||||||
|
if (var_wr_len == NULL) {
|
||||||
|
/* add terminating 0 */
|
||||||
|
var_wr[len] = 0;
|
||||||
|
} else {
|
||||||
|
*var_wr_len = len;
|
||||||
|
}
|
||||||
|
|
||||||
|
return SNMP_ERR_NOERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct snmp_scalar_array_node_def system_nodes[] = {
|
||||||
|
{1, SNMP_ASN1_TYPE_OCTET_STRING, SNMP_NODE_INSTANCE_READ_ONLY}, /* sysDescr */
|
||||||
|
{2, SNMP_ASN1_TYPE_OBJECT_ID, SNMP_NODE_INSTANCE_READ_ONLY}, /* sysObjectID */
|
||||||
|
{3, SNMP_ASN1_TYPE_TIMETICKS, SNMP_NODE_INSTANCE_READ_ONLY}, /* sysUpTime */
|
||||||
|
{4, SNMP_ASN1_TYPE_OCTET_STRING, SNMP_NODE_INSTANCE_READ_WRITE}, /* sysContact */
|
||||||
|
{5, SNMP_ASN1_TYPE_OCTET_STRING, SNMP_NODE_INSTANCE_READ_WRITE}, /* sysName */
|
||||||
|
{6, SNMP_ASN1_TYPE_OCTET_STRING, SNMP_NODE_INSTANCE_READ_WRITE}, /* sysLocation */
|
||||||
|
{7, SNMP_ASN1_TYPE_INTEGER, SNMP_NODE_INSTANCE_READ_ONLY} /* sysServices */
|
||||||
|
};
|
||||||
|
|
||||||
|
const struct snmp_scalar_array_node snmp_mib2_system_node = SNMP_SCALAR_CREATE_ARRAY_NODE(1, system_nodes, system_get_value, system_set_test, system_set_value);
|
||||||
|
|
||||||
|
#endif /* LWIP_SNMP && SNMP_LWIP_MIB2 */
|
|
@ -0,0 +1,594 @@
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* Management Information Base II (RFC1213) TCP objects and functions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006 Axon Digital Design B.V., The Netherlands.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||||
|
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||||
|
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
|
* OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* Author: Dirk Ziegelmeier <dziegel@gmx.de>
|
||||||
|
* Christiaan Simons <christiaan.simons@axon.tv>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "lwip/snmp.h"
|
||||||
|
#include "lwip/apps/snmp.h"
|
||||||
|
#include "lwip/apps/snmp_core.h"
|
||||||
|
#include "lwip/apps/snmp_mib2.h"
|
||||||
|
#include "lwip/apps/snmp_table.h"
|
||||||
|
#include "lwip/apps/snmp_scalar.h"
|
||||||
|
#include "lwip/tcp.h"
|
||||||
|
#include "lwip/priv/tcp_priv.h"
|
||||||
|
#include "lwip/stats.h"
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#if LWIP_SNMP && SNMP_LWIP_MIB2 && LWIP_TCP
|
||||||
|
|
||||||
|
#if SNMP_USE_NETCONN
|
||||||
|
#define SYNC_NODE_NAME(node_name) node_name ## _synced
|
||||||
|
#define CREATE_LWIP_SYNC_NODE(oid, node_name) \
|
||||||
|
static const struct snmp_threadsync_node node_name ## _synced = SNMP_CREATE_THREAD_SYNC_NODE(oid, &node_name.node, &snmp_mib2_lwip_locks);
|
||||||
|
#else
|
||||||
|
#define SYNC_NODE_NAME(node_name) node_name
|
||||||
|
#define CREATE_LWIP_SYNC_NODE(oid, node_name)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* --- tcp .1.3.6.1.2.1.6 ----------------------------------------------------- */
|
||||||
|
|
||||||
|
static s16_t
|
||||||
|
tcp_get_value(struct snmp_node_instance* instance, void* value)
|
||||||
|
{
|
||||||
|
u32_t *uint_ptr = (u32_t*)value;
|
||||||
|
s32_t *sint_ptr = (s32_t*)value;
|
||||||
|
|
||||||
|
switch (instance->node->oid) {
|
||||||
|
case 1: /* tcpRtoAlgorithm, vanj(4) */
|
||||||
|
*sint_ptr = 4;
|
||||||
|
return sizeof(*sint_ptr);
|
||||||
|
case 2: /* tcpRtoMin */
|
||||||
|
/* @todo not the actual value, a guess,
|
||||||
|
needs to be calculated */
|
||||||
|
*sint_ptr = 1000;
|
||||||
|
return sizeof(*sint_ptr);
|
||||||
|
case 3: /* tcpRtoMax */
|
||||||
|
/* @todo not the actual value, a guess,
|
||||||
|
needs to be calculated */
|
||||||
|
*sint_ptr = 60000;
|
||||||
|
return sizeof(*sint_ptr);
|
||||||
|
case 4: /* tcpMaxConn */
|
||||||
|
*sint_ptr = MEMP_NUM_TCP_PCB;
|
||||||
|
return sizeof(*sint_ptr);
|
||||||
|
case 5: /* tcpActiveOpens */
|
||||||
|
*uint_ptr = STATS_GET(mib2.tcpactiveopens);
|
||||||
|
return sizeof(*uint_ptr);
|
||||||
|
case 6: /* tcpPassiveOpens */
|
||||||
|
*uint_ptr = STATS_GET(mib2.tcppassiveopens);
|
||||||
|
return sizeof(*uint_ptr);
|
||||||
|
case 7: /* tcpAttemptFails */
|
||||||
|
*uint_ptr = STATS_GET(mib2.tcpattemptfails);
|
||||||
|
return sizeof(*uint_ptr);
|
||||||
|
case 8: /* tcpEstabResets */
|
||||||
|
*uint_ptr = STATS_GET(mib2.tcpestabresets);
|
||||||
|
return sizeof(*uint_ptr);
|
||||||
|
case 9: /* tcpCurrEstab */
|
||||||
|
{
|
||||||
|
u16_t tcpcurrestab = 0;
|
||||||
|
struct tcp_pcb *pcb = tcp_active_pcbs;
|
||||||
|
while (pcb != NULL) {
|
||||||
|
if ((pcb->state == ESTABLISHED) ||
|
||||||
|
(pcb->state == CLOSE_WAIT)) {
|
||||||
|
tcpcurrestab++;
|
||||||
|
}
|
||||||
|
pcb = pcb->next;
|
||||||
|
}
|
||||||
|
*uint_ptr = tcpcurrestab;
|
||||||
|
}
|
||||||
|
return sizeof(*uint_ptr);
|
||||||
|
case 10: /* tcpInSegs */
|
||||||
|
*uint_ptr = STATS_GET(mib2.tcpinsegs);
|
||||||
|
return sizeof(*uint_ptr);
|
||||||
|
case 11: /* tcpOutSegs */
|
||||||
|
*uint_ptr = STATS_GET(mib2.tcpoutsegs);
|
||||||
|
return sizeof(*uint_ptr);
|
||||||
|
case 12: /* tcpRetransSegs */
|
||||||
|
*uint_ptr = STATS_GET(mib2.tcpretranssegs);
|
||||||
|
return sizeof(*uint_ptr);
|
||||||
|
case 14: /* tcpInErrs */
|
||||||
|
*uint_ptr = STATS_GET(mib2.tcpinerrs);
|
||||||
|
return sizeof(*uint_ptr);
|
||||||
|
case 15: /* tcpOutRsts */
|
||||||
|
*uint_ptr = STATS_GET(mib2.tcpoutrsts);
|
||||||
|
return sizeof(*uint_ptr);
|
||||||
|
case 17: /* tcpHCInSegs */
|
||||||
|
memset(value, 0, 2*sizeof(u32_t)); /* not supported */
|
||||||
|
return 2*sizeof(u32_t);
|
||||||
|
case 18: /* tcpHCOutSegs */
|
||||||
|
memset(value, 0, 2*sizeof(u32_t)); /* not supported */
|
||||||
|
return 2*sizeof(u32_t);
|
||||||
|
default:
|
||||||
|
LWIP_DEBUGF(SNMP_MIB_DEBUG,("tcp_get_value(): unknown id: %"S32_F"\n", instance->node->oid));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --- tcpConnTable --- */
|
||||||
|
|
||||||
|
#if LWIP_IPV4
|
||||||
|
|
||||||
|
/* list of allowed value ranges for incoming OID */
|
||||||
|
static const struct snmp_oid_range tcp_ConnTable_oid_ranges[] = {
|
||||||
|
{ 0, 0xff }, /* IP A */
|
||||||
|
{ 0, 0xff }, /* IP B */
|
||||||
|
{ 0, 0xff }, /* IP C */
|
||||||
|
{ 0, 0xff }, /* IP D */
|
||||||
|
{ 0, 0xffff }, /* Port */
|
||||||
|
{ 0, 0xff }, /* IP A */
|
||||||
|
{ 0, 0xff }, /* IP B */
|
||||||
|
{ 0, 0xff }, /* IP C */
|
||||||
|
{ 0, 0xff }, /* IP D */
|
||||||
|
{ 0, 0xffff } /* Port */
|
||||||
|
};
|
||||||
|
|
||||||
|
static snmp_err_t
|
||||||
|
tcp_ConnTable_get_cell_value_core(struct tcp_pcb *pcb, const u32_t* column, union snmp_variant_value* value, u32_t* value_len)
|
||||||
|
{
|
||||||
|
LWIP_UNUSED_ARG(value_len);
|
||||||
|
|
||||||
|
/* value */
|
||||||
|
switch (*column) {
|
||||||
|
case 1: /* tcpConnState */
|
||||||
|
value->u32 = pcb->state + 1;
|
||||||
|
break;
|
||||||
|
case 2: /* tcpConnLocalAddress */
|
||||||
|
value->u32 = ip_2_ip4(&pcb->local_ip)->addr;
|
||||||
|
break;
|
||||||
|
case 3: /* tcpConnLocalPort */
|
||||||
|
value->u32 = pcb->local_port;
|
||||||
|
break;
|
||||||
|
case 4: /* tcpConnRemAddress */
|
||||||
|
if (pcb->state == LISTEN) {
|
||||||
|
value->u32 = IP4_ADDR_ANY4->addr;
|
||||||
|
} else {
|
||||||
|
value->u32 = ip_2_ip4(&pcb->remote_ip)->addr;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 5: /* tcpConnRemPort */
|
||||||
|
if (pcb->state == LISTEN) {
|
||||||
|
value->u32 = 0;
|
||||||
|
} else {
|
||||||
|
value->u32 = pcb->remote_port;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
LWIP_ASSERT("invalid id", 0);
|
||||||
|
return SNMP_ERR_NOSUCHINSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return SNMP_ERR_NOERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
static snmp_err_t
|
||||||
|
tcp_ConnTable_get_cell_value(const u32_t* column, const u32_t* row_oid, u8_t row_oid_len, union snmp_variant_value* value, u32_t* value_len)
|
||||||
|
{
|
||||||
|
u8_t i;
|
||||||
|
ip4_addr_t local_ip;
|
||||||
|
ip4_addr_t remote_ip;
|
||||||
|
u16_t local_port;
|
||||||
|
u16_t remote_port;
|
||||||
|
struct tcp_pcb *pcb;
|
||||||
|
|
||||||
|
/* check if incoming OID length and if values are in plausible range */
|
||||||
|
if (!snmp_oid_in_range(row_oid, row_oid_len, tcp_ConnTable_oid_ranges, LWIP_ARRAYSIZE(tcp_ConnTable_oid_ranges))) {
|
||||||
|
return SNMP_ERR_NOSUCHINSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get IPs and ports from incoming OID */
|
||||||
|
snmp_oid_to_ip4(&row_oid[0], &local_ip); /* we know it succeeds because of oid_in_range check above */
|
||||||
|
local_port = (u16_t)row_oid[4];
|
||||||
|
snmp_oid_to_ip4(&row_oid[5], &remote_ip); /* we know it succeeds because of oid_in_range check above */
|
||||||
|
remote_port = (u16_t)row_oid[9];
|
||||||
|
|
||||||
|
/* find tcp_pcb with requested ips and ports */
|
||||||
|
for (i = 0; i < LWIP_ARRAYSIZE(tcp_pcb_lists); i++) {
|
||||||
|
pcb = *tcp_pcb_lists[i];
|
||||||
|
|
||||||
|
while (pcb != NULL) {
|
||||||
|
/* do local IP and local port match? */
|
||||||
|
if (IP_IS_V4_VAL(pcb->local_ip) &&
|
||||||
|
ip4_addr_cmp(&local_ip, ip_2_ip4(&pcb->local_ip)) && (local_port == pcb->local_port)) {
|
||||||
|
|
||||||
|
/* PCBs in state LISTEN are not connected and have no remote_ip or remote_port */
|
||||||
|
if (pcb->state == LISTEN) {
|
||||||
|
if (ip4_addr_cmp(&remote_ip, IP4_ADDR_ANY4) && (remote_port == 0)) {
|
||||||
|
/* fill in object properties */
|
||||||
|
return tcp_ConnTable_get_cell_value_core(pcb, column, value, value_len);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (IP_IS_V4_VAL(pcb->remote_ip) &&
|
||||||
|
ip4_addr_cmp(&remote_ip, ip_2_ip4(&pcb->remote_ip)) && (remote_port == pcb->remote_port)) {
|
||||||
|
/* fill in object properties */
|
||||||
|
return tcp_ConnTable_get_cell_value_core(pcb, column, value, value_len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pcb = pcb->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* not found */
|
||||||
|
return SNMP_ERR_NOSUCHINSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static snmp_err_t
|
||||||
|
tcp_ConnTable_get_next_cell_instance_and_value(const u32_t* column, struct snmp_obj_id* row_oid, union snmp_variant_value* value, u32_t* value_len)
|
||||||
|
{
|
||||||
|
u8_t i;
|
||||||
|
struct tcp_pcb *pcb;
|
||||||
|
struct snmp_next_oid_state state;
|
||||||
|
u32_t result_temp[LWIP_ARRAYSIZE(tcp_ConnTable_oid_ranges)];
|
||||||
|
|
||||||
|
/* init struct to search next oid */
|
||||||
|
snmp_next_oid_init(&state, row_oid->id, row_oid->len, result_temp, LWIP_ARRAYSIZE(tcp_ConnTable_oid_ranges));
|
||||||
|
|
||||||
|
/* iterate over all possible OIDs to find the next one */
|
||||||
|
for (i = 0; i < LWIP_ARRAYSIZE(tcp_pcb_lists); i++) {
|
||||||
|
pcb = *tcp_pcb_lists[i];
|
||||||
|
while (pcb != NULL) {
|
||||||
|
u32_t test_oid[LWIP_ARRAYSIZE(tcp_ConnTable_oid_ranges)];
|
||||||
|
|
||||||
|
if (IP_IS_V4_VAL(pcb->local_ip)) {
|
||||||
|
snmp_ip4_to_oid(ip_2_ip4(&pcb->local_ip), &test_oid[0]);
|
||||||
|
test_oid[4] = pcb->local_port;
|
||||||
|
|
||||||
|
/* PCBs in state LISTEN are not connected and have no remote_ip or remote_port */
|
||||||
|
if (pcb->state == LISTEN) {
|
||||||
|
snmp_ip4_to_oid(IP4_ADDR_ANY4, &test_oid[5]);
|
||||||
|
test_oid[9] = 0;
|
||||||
|
} else {
|
||||||
|
if (IP_IS_V6_VAL(pcb->remote_ip)) { /* should never happen */
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
snmp_ip4_to_oid(ip_2_ip4(&pcb->remote_ip), &test_oid[5]);
|
||||||
|
test_oid[9] = pcb->remote_port;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check generated OID: is it a candidate for the next one? */
|
||||||
|
snmp_next_oid_check(&state, test_oid, LWIP_ARRAYSIZE(tcp_ConnTable_oid_ranges), pcb);
|
||||||
|
}
|
||||||
|
|
||||||
|
pcb = pcb->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* did we find a next one? */
|
||||||
|
if (state.status == SNMP_NEXT_OID_STATUS_SUCCESS) {
|
||||||
|
snmp_oid_assign(row_oid, state.next_oid, state.next_oid_len);
|
||||||
|
/* fill in object properties */
|
||||||
|
return tcp_ConnTable_get_cell_value_core((struct tcp_pcb*)state.reference, column, value, value_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* not found */
|
||||||
|
return SNMP_ERR_NOSUCHINSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* LWIP_IPV4 */
|
||||||
|
|
||||||
|
/* --- tcpConnectionTable --- */
|
||||||
|
|
||||||
|
static snmp_err_t
|
||||||
|
tcp_ConnectionTable_get_cell_value_core(const u32_t* column, struct tcp_pcb *pcb, union snmp_variant_value* value)
|
||||||
|
{
|
||||||
|
/* all items except tcpConnectionState and tcpConnectionProcess are declared as not-accessible */
|
||||||
|
switch (*column) {
|
||||||
|
case 7: /* tcpConnectionState */
|
||||||
|
value->u32 = pcb->state + 1;
|
||||||
|
break;
|
||||||
|
case 8: /* tcpConnectionProcess */
|
||||||
|
value->u32 = 0; /* not supported */
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return SNMP_ERR_NOSUCHINSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return SNMP_ERR_NOERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
static snmp_err_t
|
||||||
|
tcp_ConnectionTable_get_cell_value(const u32_t* column, const u32_t* row_oid, u8_t row_oid_len, union snmp_variant_value* value, u32_t* value_len)
|
||||||
|
{
|
||||||
|
ip_addr_t local_ip, remote_ip;
|
||||||
|
u16_t local_port, remote_port;
|
||||||
|
struct tcp_pcb *pcb;
|
||||||
|
u8_t idx = 0;
|
||||||
|
u8_t i;
|
||||||
|
struct tcp_pcb ** const tcp_pcb_nonlisten_lists[] = {&tcp_bound_pcbs, &tcp_active_pcbs, &tcp_tw_pcbs};
|
||||||
|
|
||||||
|
LWIP_UNUSED_ARG(value_len);
|
||||||
|
|
||||||
|
/* tcpConnectionLocalAddressType + tcpConnectionLocalAddress + tcpConnectionLocalPort */
|
||||||
|
idx += snmp_oid_to_ip_port(&row_oid[idx], row_oid_len-idx, &local_ip, &local_port);
|
||||||
|
if (idx == 0) {
|
||||||
|
return SNMP_ERR_NOSUCHINSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* tcpConnectionRemAddressType + tcpConnectionRemAddress + tcpConnectionRemPort */
|
||||||
|
idx += snmp_oid_to_ip_port(&row_oid[idx], row_oid_len-idx, &remote_ip, &remote_port);
|
||||||
|
if (idx == 0) {
|
||||||
|
return SNMP_ERR_NOSUCHINSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* find tcp_pcb with requested ip and port*/
|
||||||
|
for (i = 0; i < LWIP_ARRAYSIZE(tcp_pcb_nonlisten_lists); i++) {
|
||||||
|
pcb = *tcp_pcb_nonlisten_lists[i];
|
||||||
|
|
||||||
|
while (pcb != NULL) {
|
||||||
|
if (ip_addr_cmp(&local_ip, &pcb->local_ip) &&
|
||||||
|
(local_port == pcb->local_port) &&
|
||||||
|
ip_addr_cmp(&remote_ip, &pcb->remote_ip) &&
|
||||||
|
(remote_port == pcb->remote_port)) {
|
||||||
|
/* fill in object properties */
|
||||||
|
return tcp_ConnectionTable_get_cell_value_core(column, pcb, value);
|
||||||
|
}
|
||||||
|
pcb = pcb->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* not found */
|
||||||
|
return SNMP_ERR_NOSUCHINSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static snmp_err_t
|
||||||
|
tcp_ConnectionTable_get_next_cell_instance_and_value(const u32_t* column, struct snmp_obj_id* row_oid, union snmp_variant_value* value, u32_t* value_len)
|
||||||
|
{
|
||||||
|
struct tcp_pcb *pcb;
|
||||||
|
struct snmp_next_oid_state state;
|
||||||
|
/* 1x tcpConnectionLocalAddressType + 1x OID len + 16x tcpConnectionLocalAddress + 1x tcpConnectionLocalPort
|
||||||
|
* 1x tcpConnectionRemAddressType + 1x OID len + 16x tcpConnectionRemAddress + 1x tcpConnectionRemPort */
|
||||||
|
u32_t result_temp[38];
|
||||||
|
u8_t i;
|
||||||
|
struct tcp_pcb ** const tcp_pcb_nonlisten_lists[] = {&tcp_bound_pcbs, &tcp_active_pcbs, &tcp_tw_pcbs};
|
||||||
|
|
||||||
|
LWIP_UNUSED_ARG(value_len);
|
||||||
|
|
||||||
|
/* init struct to search next oid */
|
||||||
|
snmp_next_oid_init(&state, row_oid->id, row_oid->len, result_temp, LWIP_ARRAYSIZE(result_temp));
|
||||||
|
|
||||||
|
/* iterate over all possible OIDs to find the next one */
|
||||||
|
for (i = 0; i < LWIP_ARRAYSIZE(tcp_pcb_nonlisten_lists); i++) {
|
||||||
|
pcb = *tcp_pcb_nonlisten_lists[i];
|
||||||
|
|
||||||
|
while (pcb != NULL) {
|
||||||
|
u8_t idx = 0;
|
||||||
|
u32_t test_oid[LWIP_ARRAYSIZE(result_temp)];
|
||||||
|
|
||||||
|
/* tcpConnectionLocalAddressType + tcpConnectionLocalAddress + tcpConnectionLocalPort */
|
||||||
|
idx += snmp_ip_port_to_oid(&pcb->local_ip, pcb->local_port, &test_oid[idx]);
|
||||||
|
|
||||||
|
/* tcpConnectionRemAddressType + tcpConnectionRemAddress + tcpConnectionRemPort */
|
||||||
|
idx += snmp_ip_port_to_oid(&pcb->remote_ip, pcb->remote_port, &test_oid[idx]);
|
||||||
|
|
||||||
|
/* check generated OID: is it a candidate for the next one? */
|
||||||
|
snmp_next_oid_check(&state, test_oid, idx, pcb);
|
||||||
|
|
||||||
|
pcb = pcb->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* did we find a next one? */
|
||||||
|
if (state.status == SNMP_NEXT_OID_STATUS_SUCCESS) {
|
||||||
|
snmp_oid_assign(row_oid, state.next_oid, state.next_oid_len);
|
||||||
|
/* fill in object properties */
|
||||||
|
return tcp_ConnectionTable_get_cell_value_core(column, (struct tcp_pcb*)state.reference, value);
|
||||||
|
} else {
|
||||||
|
/* not found */
|
||||||
|
return SNMP_ERR_NOSUCHINSTANCE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --- tcpListenerTable --- */
|
||||||
|
|
||||||
|
static snmp_err_t
|
||||||
|
tcp_ListenerTable_get_cell_value_core(const u32_t* column, union snmp_variant_value* value)
|
||||||
|
{
|
||||||
|
/* all items except tcpListenerProcess are declared as not-accessible */
|
||||||
|
switch (*column) {
|
||||||
|
case 4: /* tcpListenerProcess */
|
||||||
|
value->u32 = 0; /* not supported */
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return SNMP_ERR_NOSUCHINSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return SNMP_ERR_NOERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
static snmp_err_t
|
||||||
|
tcp_ListenerTable_get_cell_value(const u32_t* column, const u32_t* row_oid, u8_t row_oid_len, union snmp_variant_value* value, u32_t* value_len)
|
||||||
|
{
|
||||||
|
ip_addr_t local_ip;
|
||||||
|
u16_t local_port;
|
||||||
|
struct tcp_pcb_listen *pcb;
|
||||||
|
u8_t idx = 0;
|
||||||
|
|
||||||
|
LWIP_UNUSED_ARG(value_len);
|
||||||
|
|
||||||
|
/* tcpListenerLocalAddressType + tcpListenerLocalAddress + tcpListenerLocalPort */
|
||||||
|
idx += snmp_oid_to_ip_port(&row_oid[idx], row_oid_len-idx, &local_ip, &local_port);
|
||||||
|
if (idx == 0) {
|
||||||
|
return SNMP_ERR_NOSUCHINSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* find tcp_pcb with requested ip and port*/
|
||||||
|
pcb = tcp_listen_pcbs.listen_pcbs;
|
||||||
|
while (pcb != NULL) {
|
||||||
|
if (ip_addr_cmp(&local_ip, &pcb->local_ip) &&
|
||||||
|
(local_port == pcb->local_port)) {
|
||||||
|
/* fill in object properties */
|
||||||
|
return tcp_ListenerTable_get_cell_value_core(column, value);
|
||||||
|
}
|
||||||
|
pcb = pcb->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* not found */
|
||||||
|
return SNMP_ERR_NOSUCHINSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static snmp_err_t
|
||||||
|
tcp_ListenerTable_get_next_cell_instance_and_value(const u32_t* column, struct snmp_obj_id* row_oid, union snmp_variant_value* value, u32_t* value_len)
|
||||||
|
{
|
||||||
|
struct tcp_pcb_listen *pcb;
|
||||||
|
struct snmp_next_oid_state state;
|
||||||
|
/* 1x tcpListenerLocalAddressType + 1x OID len + 16x tcpListenerLocalAddress + 1x tcpListenerLocalPort */
|
||||||
|
u32_t result_temp[19];
|
||||||
|
|
||||||
|
LWIP_UNUSED_ARG(value_len);
|
||||||
|
|
||||||
|
/* init struct to search next oid */
|
||||||
|
snmp_next_oid_init(&state, row_oid->id, row_oid->len, result_temp, LWIP_ARRAYSIZE(result_temp));
|
||||||
|
|
||||||
|
/* iterate over all possible OIDs to find the next one */
|
||||||
|
pcb = tcp_listen_pcbs.listen_pcbs;
|
||||||
|
while (pcb != NULL) {
|
||||||
|
u8_t idx = 0;
|
||||||
|
u32_t test_oid[LWIP_ARRAYSIZE(result_temp)];
|
||||||
|
|
||||||
|
/* tcpListenerLocalAddressType + tcpListenerLocalAddress + tcpListenerLocalPort */
|
||||||
|
idx += snmp_ip_port_to_oid(&pcb->local_ip, pcb->local_port, &test_oid[idx]);
|
||||||
|
|
||||||
|
/* check generated OID: is it a candidate for the next one? */
|
||||||
|
snmp_next_oid_check(&state, test_oid, idx, NULL);
|
||||||
|
|
||||||
|
pcb = pcb->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* did we find a next one? */
|
||||||
|
if (state.status == SNMP_NEXT_OID_STATUS_SUCCESS) {
|
||||||
|
snmp_oid_assign(row_oid, state.next_oid, state.next_oid_len);
|
||||||
|
/* fill in object properties */
|
||||||
|
return tcp_ListenerTable_get_cell_value_core(column, value);
|
||||||
|
} else {
|
||||||
|
/* not found */
|
||||||
|
return SNMP_ERR_NOSUCHINSTANCE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct snmp_scalar_node tcp_RtoAlgorithm = SNMP_SCALAR_CREATE_NODE_READONLY(1, SNMP_ASN1_TYPE_INTEGER, tcp_get_value);
|
||||||
|
static const struct snmp_scalar_node tcp_RtoMin = SNMP_SCALAR_CREATE_NODE_READONLY(2, SNMP_ASN1_TYPE_INTEGER, tcp_get_value);
|
||||||
|
static const struct snmp_scalar_node tcp_RtoMax = SNMP_SCALAR_CREATE_NODE_READONLY(3, SNMP_ASN1_TYPE_INTEGER, tcp_get_value);
|
||||||
|
static const struct snmp_scalar_node tcp_MaxConn = SNMP_SCALAR_CREATE_NODE_READONLY(4, SNMP_ASN1_TYPE_INTEGER, tcp_get_value);
|
||||||
|
static const struct snmp_scalar_node tcp_ActiveOpens = SNMP_SCALAR_CREATE_NODE_READONLY(5, SNMP_ASN1_TYPE_COUNTER, tcp_get_value);
|
||||||
|
static const struct snmp_scalar_node tcp_PassiveOpens = SNMP_SCALAR_CREATE_NODE_READONLY(6, SNMP_ASN1_TYPE_COUNTER, tcp_get_value);
|
||||||
|
static const struct snmp_scalar_node tcp_AttemptFails = SNMP_SCALAR_CREATE_NODE_READONLY(7, SNMP_ASN1_TYPE_COUNTER, tcp_get_value);
|
||||||
|
static const struct snmp_scalar_node tcp_EstabResets = SNMP_SCALAR_CREATE_NODE_READONLY(8, SNMP_ASN1_TYPE_COUNTER, tcp_get_value);
|
||||||
|
static const struct snmp_scalar_node tcp_CurrEstab = SNMP_SCALAR_CREATE_NODE_READONLY(9, SNMP_ASN1_TYPE_GAUGE, tcp_get_value);
|
||||||
|
static const struct snmp_scalar_node tcp_InSegs = SNMP_SCALAR_CREATE_NODE_READONLY(10, SNMP_ASN1_TYPE_COUNTER, tcp_get_value);
|
||||||
|
static const struct snmp_scalar_node tcp_OutSegs = SNMP_SCALAR_CREATE_NODE_READONLY(11, SNMP_ASN1_TYPE_COUNTER, tcp_get_value);
|
||||||
|
static const struct snmp_scalar_node tcp_RetransSegs = SNMP_SCALAR_CREATE_NODE_READONLY(12, SNMP_ASN1_TYPE_COUNTER, tcp_get_value);
|
||||||
|
static const struct snmp_scalar_node tcp_InErrs = SNMP_SCALAR_CREATE_NODE_READONLY(14, SNMP_ASN1_TYPE_COUNTER, tcp_get_value);
|
||||||
|
static const struct snmp_scalar_node tcp_OutRsts = SNMP_SCALAR_CREATE_NODE_READONLY(15, SNMP_ASN1_TYPE_COUNTER, tcp_get_value);
|
||||||
|
static const struct snmp_scalar_node tcp_HCInSegs = SNMP_SCALAR_CREATE_NODE_READONLY(17, SNMP_ASN1_TYPE_COUNTER64, tcp_get_value);
|
||||||
|
static const struct snmp_scalar_node tcp_HCOutSegs = SNMP_SCALAR_CREATE_NODE_READONLY(18, SNMP_ASN1_TYPE_COUNTER64, tcp_get_value);
|
||||||
|
|
||||||
|
#if LWIP_IPV4
|
||||||
|
static const struct snmp_table_simple_col_def tcp_ConnTable_columns[] = {
|
||||||
|
{ 1, SNMP_ASN1_TYPE_INTEGER, SNMP_VARIANT_VALUE_TYPE_U32 }, /* tcpConnState */
|
||||||
|
{ 2, SNMP_ASN1_TYPE_IPADDR, SNMP_VARIANT_VALUE_TYPE_U32 }, /* tcpConnLocalAddress */
|
||||||
|
{ 3, SNMP_ASN1_TYPE_INTEGER, SNMP_VARIANT_VALUE_TYPE_U32 }, /* tcpConnLocalPort */
|
||||||
|
{ 4, SNMP_ASN1_TYPE_IPADDR, SNMP_VARIANT_VALUE_TYPE_U32 }, /* tcpConnRemAddress */
|
||||||
|
{ 5, SNMP_ASN1_TYPE_INTEGER, SNMP_VARIANT_VALUE_TYPE_U32 } /* tcpConnRemPort */
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct snmp_table_simple_node tcp_ConnTable = SNMP_TABLE_CREATE_SIMPLE(13, tcp_ConnTable_columns, tcp_ConnTable_get_cell_value, tcp_ConnTable_get_next_cell_instance_and_value);
|
||||||
|
#endif /* LWIP_IPV4 */
|
||||||
|
|
||||||
|
static const struct snmp_table_simple_col_def tcp_ConnectionTable_columns[] = {
|
||||||
|
/* all items except tcpConnectionState and tcpConnectionProcess are declared as not-accessible */
|
||||||
|
{ 7, SNMP_ASN1_TYPE_INTEGER, SNMP_VARIANT_VALUE_TYPE_U32 }, /* tcpConnectionState */
|
||||||
|
{ 8, SNMP_ASN1_TYPE_UNSIGNED32, SNMP_VARIANT_VALUE_TYPE_U32 } /* tcpConnectionProcess */
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct snmp_table_simple_node tcp_ConnectionTable = SNMP_TABLE_CREATE_SIMPLE(19, tcp_ConnectionTable_columns, tcp_ConnectionTable_get_cell_value, tcp_ConnectionTable_get_next_cell_instance_and_value);
|
||||||
|
|
||||||
|
|
||||||
|
static const struct snmp_table_simple_col_def tcp_ListenerTable_columns[] = {
|
||||||
|
/* all items except tcpListenerProcess are declared as not-accessible */
|
||||||
|
{ 4, SNMP_ASN1_TYPE_UNSIGNED32, SNMP_VARIANT_VALUE_TYPE_U32 } /* tcpListenerProcess */
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct snmp_table_simple_node tcp_ListenerTable = SNMP_TABLE_CREATE_SIMPLE(20, tcp_ListenerTable_columns, tcp_ListenerTable_get_cell_value, tcp_ListenerTable_get_next_cell_instance_and_value);
|
||||||
|
|
||||||
|
/* the following nodes access variables in LWIP stack from SNMP worker thread and must therefore be synced to LWIP (TCPIP) thread */
|
||||||
|
CREATE_LWIP_SYNC_NODE( 1, tcp_RtoAlgorithm)
|
||||||
|
CREATE_LWIP_SYNC_NODE( 2, tcp_RtoMin)
|
||||||
|
CREATE_LWIP_SYNC_NODE( 3, tcp_RtoMax)
|
||||||
|
CREATE_LWIP_SYNC_NODE( 4, tcp_MaxConn)
|
||||||
|
CREATE_LWIP_SYNC_NODE( 5, tcp_ActiveOpens)
|
||||||
|
CREATE_LWIP_SYNC_NODE( 6, tcp_PassiveOpens)
|
||||||
|
CREATE_LWIP_SYNC_NODE( 7, tcp_AttemptFails)
|
||||||
|
CREATE_LWIP_SYNC_NODE( 8, tcp_EstabResets)
|
||||||
|
CREATE_LWIP_SYNC_NODE( 9, tcp_CurrEstab)
|
||||||
|
CREATE_LWIP_SYNC_NODE(10, tcp_InSegs)
|
||||||
|
CREATE_LWIP_SYNC_NODE(11, tcp_OutSegs)
|
||||||
|
CREATE_LWIP_SYNC_NODE(12, tcp_RetransSegs)
|
||||||
|
#if LWIP_IPV4
|
||||||
|
CREATE_LWIP_SYNC_NODE(13, tcp_ConnTable)
|
||||||
|
#endif /* LWIP_IPV4 */
|
||||||
|
CREATE_LWIP_SYNC_NODE(14, tcp_InErrs)
|
||||||
|
CREATE_LWIP_SYNC_NODE(15, tcp_OutRsts)
|
||||||
|
CREATE_LWIP_SYNC_NODE(17, tcp_HCInSegs)
|
||||||
|
CREATE_LWIP_SYNC_NODE(18, tcp_HCOutSegs)
|
||||||
|
CREATE_LWIP_SYNC_NODE(19, tcp_ConnectionTable)
|
||||||
|
CREATE_LWIP_SYNC_NODE(20, tcp_ListenerTable)
|
||||||
|
|
||||||
|
static const struct snmp_node* const tcp_nodes[] = {
|
||||||
|
&SYNC_NODE_NAME(tcp_RtoAlgorithm).node.node,
|
||||||
|
&SYNC_NODE_NAME(tcp_RtoMin).node.node,
|
||||||
|
&SYNC_NODE_NAME(tcp_RtoMax).node.node,
|
||||||
|
&SYNC_NODE_NAME(tcp_MaxConn).node.node,
|
||||||
|
&SYNC_NODE_NAME(tcp_ActiveOpens).node.node,
|
||||||
|
&SYNC_NODE_NAME(tcp_PassiveOpens).node.node,
|
||||||
|
&SYNC_NODE_NAME(tcp_AttemptFails).node.node,
|
||||||
|
&SYNC_NODE_NAME(tcp_EstabResets).node.node,
|
||||||
|
&SYNC_NODE_NAME(tcp_CurrEstab).node.node,
|
||||||
|
&SYNC_NODE_NAME(tcp_InSegs).node.node,
|
||||||
|
&SYNC_NODE_NAME(tcp_OutSegs).node.node,
|
||||||
|
&SYNC_NODE_NAME(tcp_RetransSegs).node.node,
|
||||||
|
#if LWIP_IPV4
|
||||||
|
&SYNC_NODE_NAME(tcp_ConnTable).node.node,
|
||||||
|
#endif /* LWIP_IPV4 */
|
||||||
|
&SYNC_NODE_NAME(tcp_InErrs).node.node,
|
||||||
|
&SYNC_NODE_NAME(tcp_OutRsts).node.node,
|
||||||
|
&SYNC_NODE_NAME(tcp_HCInSegs).node.node,
|
||||||
|
&SYNC_NODE_NAME(tcp_HCOutSegs).node.node,
|
||||||
|
&SYNC_NODE_NAME(tcp_ConnectionTable).node.node,
|
||||||
|
&SYNC_NODE_NAME(tcp_ListenerTable).node.node
|
||||||
|
};
|
||||||
|
|
||||||
|
const struct snmp_tree_node snmp_mib2_tcp_root = SNMP_CREATE_TREE_NODE(6, tcp_nodes);
|
||||||
|
#endif /* LWIP_SNMP && SNMP_LWIP_MIB2 && LWIP_TCP */
|
|
@ -0,0 +1,357 @@
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* Management Information Base II (RFC1213) UDP objects and functions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006 Axon Digital Design B.V., The Netherlands.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||||
|
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||||
|
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
|
* OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* Author: Dirk Ziegelmeier <dziegel@gmx.de>
|
||||||
|
* Christiaan Simons <christiaan.simons@axon.tv>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "lwip/snmp.h"
|
||||||
|
#include "lwip/apps/snmp.h"
|
||||||
|
#include "lwip/apps/snmp_core.h"
|
||||||
|
#include "lwip/apps/snmp_mib2.h"
|
||||||
|
#include "lwip/apps/snmp_table.h"
|
||||||
|
#include "lwip/apps/snmp_scalar.h"
|
||||||
|
#include "lwip/udp.h"
|
||||||
|
#include "lwip/stats.h"
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#if LWIP_SNMP && SNMP_LWIP_MIB2 && LWIP_UDP
|
||||||
|
|
||||||
|
#if SNMP_USE_NETCONN
|
||||||
|
#define SYNC_NODE_NAME(node_name) node_name ## _synced
|
||||||
|
#define CREATE_LWIP_SYNC_NODE(oid, node_name) \
|
||||||
|
static const struct snmp_threadsync_node node_name ## _synced = SNMP_CREATE_THREAD_SYNC_NODE(oid, &node_name.node, &snmp_mib2_lwip_locks);
|
||||||
|
#else
|
||||||
|
#define SYNC_NODE_NAME(node_name) node_name
|
||||||
|
#define CREATE_LWIP_SYNC_NODE(oid, node_name)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* --- udp .1.3.6.1.2.1.7 ----------------------------------------------------- */
|
||||||
|
|
||||||
|
static s16_t
|
||||||
|
udp_get_value(struct snmp_node_instance* instance, void* value)
|
||||||
|
{
|
||||||
|
u32_t *uint_ptr = (u32_t*)value;
|
||||||
|
|
||||||
|
switch (instance->node->oid) {
|
||||||
|
case 1: /* udpInDatagrams */
|
||||||
|
*uint_ptr = STATS_GET(mib2.udpindatagrams);
|
||||||
|
return sizeof(*uint_ptr);
|
||||||
|
case 2: /* udpNoPorts */
|
||||||
|
*uint_ptr = STATS_GET(mib2.udpnoports);
|
||||||
|
return sizeof(*uint_ptr);
|
||||||
|
case 3: /* udpInErrors */
|
||||||
|
*uint_ptr = STATS_GET(mib2.udpinerrors);
|
||||||
|
return sizeof(*uint_ptr);
|
||||||
|
case 4: /* udpOutDatagrams */
|
||||||
|
*uint_ptr = STATS_GET(mib2.udpoutdatagrams);
|
||||||
|
return sizeof(*uint_ptr);
|
||||||
|
case 8: /* udpHCInDatagrams */
|
||||||
|
memset(value, 0, 2*sizeof(u32_t)); /* not supported */
|
||||||
|
return 2*sizeof(u32_t);
|
||||||
|
case 9: /* udpHCOutDatagrams */
|
||||||
|
memset(value, 0, 2*sizeof(u32_t)); /* not supported */
|
||||||
|
return 2*sizeof(u32_t);
|
||||||
|
default:
|
||||||
|
LWIP_DEBUGF(SNMP_MIB_DEBUG,("udp_get_value(): unknown id: %"S32_F"\n", instance->node->oid));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --- udpEndpointTable --- */
|
||||||
|
|
||||||
|
static snmp_err_t
|
||||||
|
udp_endpointTable_get_cell_value_core(const u32_t* column, union snmp_variant_value* value)
|
||||||
|
{
|
||||||
|
/* all items except udpEndpointProcess are declared as not-accessible */
|
||||||
|
switch (*column) {
|
||||||
|
case 8: /* udpEndpointProcess */
|
||||||
|
value->u32 = 0; /* not supported */
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return SNMP_ERR_NOSUCHINSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return SNMP_ERR_NOERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
static snmp_err_t
|
||||||
|
udp_endpointTable_get_cell_value(const u32_t* column, const u32_t* row_oid, u8_t row_oid_len, union snmp_variant_value* value, u32_t* value_len)
|
||||||
|
{
|
||||||
|
ip_addr_t local_ip, remote_ip;
|
||||||
|
u16_t local_port, remote_port;
|
||||||
|
struct udp_pcb *pcb;
|
||||||
|
u8_t idx = 0;
|
||||||
|
|
||||||
|
LWIP_UNUSED_ARG(value_len);
|
||||||
|
|
||||||
|
/* udpEndpointLocalAddressType + udpEndpointLocalAddress + udpEndpointLocalPort */
|
||||||
|
idx += snmp_oid_to_ip_port(&row_oid[idx], row_oid_len-idx, &local_ip, &local_port);
|
||||||
|
if (idx == 0) {
|
||||||
|
return SNMP_ERR_NOSUCHINSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* udpEndpointRemoteAddressType + udpEndpointRemoteAddress + udpEndpointRemotePort */
|
||||||
|
idx += snmp_oid_to_ip_port(&row_oid[idx], row_oid_len-idx, &remote_ip, &remote_port);
|
||||||
|
if (idx == 0) {
|
||||||
|
return SNMP_ERR_NOSUCHINSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* udpEndpointInstance */
|
||||||
|
if (row_oid_len < (idx+1)) {
|
||||||
|
return SNMP_ERR_NOSUCHINSTANCE;
|
||||||
|
}
|
||||||
|
if (row_oid[idx] != 0) {
|
||||||
|
return SNMP_ERR_NOSUCHINSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* find udp_pcb with requested ip and port*/
|
||||||
|
pcb = udp_pcbs;
|
||||||
|
while (pcb != NULL) {
|
||||||
|
if (ip_addr_cmp(&local_ip, &pcb->local_ip) &&
|
||||||
|
(local_port == pcb->local_port) &&
|
||||||
|
ip_addr_cmp(&remote_ip, &pcb->remote_ip) &&
|
||||||
|
(remote_port == pcb->remote_port)) {
|
||||||
|
/* fill in object properties */
|
||||||
|
return udp_endpointTable_get_cell_value_core(column, value);
|
||||||
|
}
|
||||||
|
pcb = pcb->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* not found */
|
||||||
|
return SNMP_ERR_NOSUCHINSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static snmp_err_t
|
||||||
|
udp_endpointTable_get_next_cell_instance_and_value(const u32_t* column, struct snmp_obj_id* row_oid, union snmp_variant_value* value, u32_t* value_len)
|
||||||
|
{
|
||||||
|
struct udp_pcb *pcb;
|
||||||
|
struct snmp_next_oid_state state;
|
||||||
|
/* 1x udpEndpointLocalAddressType + 1x OID len + 16x udpEndpointLocalAddress + 1x udpEndpointLocalPort +
|
||||||
|
* 1x udpEndpointRemoteAddressType + 1x OID len + 16x udpEndpointRemoteAddress + 1x udpEndpointRemotePort +
|
||||||
|
* 1x udpEndpointInstance = 39
|
||||||
|
*/
|
||||||
|
u32_t result_temp[39];
|
||||||
|
|
||||||
|
LWIP_UNUSED_ARG(value_len);
|
||||||
|
|
||||||
|
/* init struct to search next oid */
|
||||||
|
snmp_next_oid_init(&state, row_oid->id, row_oid->len, result_temp, LWIP_ARRAYSIZE(result_temp));
|
||||||
|
|
||||||
|
/* iterate over all possible OIDs to find the next one */
|
||||||
|
pcb = udp_pcbs;
|
||||||
|
while (pcb != NULL) {
|
||||||
|
u32_t test_oid[LWIP_ARRAYSIZE(result_temp)];
|
||||||
|
u8_t idx = 0;
|
||||||
|
|
||||||
|
/* udpEndpointLocalAddressType + udpEndpointLocalAddress + udpEndpointLocalPort */
|
||||||
|
idx += snmp_ip_port_to_oid(&pcb->local_ip, pcb->local_port, &test_oid[idx]);
|
||||||
|
|
||||||
|
/* udpEndpointRemoteAddressType + udpEndpointRemoteAddress + udpEndpointRemotePort */
|
||||||
|
idx += snmp_ip_port_to_oid(&pcb->remote_ip, pcb->remote_port, &test_oid[idx]);
|
||||||
|
|
||||||
|
test_oid[idx] = 0; /* udpEndpointInstance */
|
||||||
|
idx++;
|
||||||
|
|
||||||
|
/* check generated OID: is it a candidate for the next one? */
|
||||||
|
snmp_next_oid_check(&state, test_oid, idx, NULL);
|
||||||
|
|
||||||
|
pcb = pcb->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* did we find a next one? */
|
||||||
|
if (state.status == SNMP_NEXT_OID_STATUS_SUCCESS) {
|
||||||
|
snmp_oid_assign(row_oid, state.next_oid, state.next_oid_len);
|
||||||
|
/* fill in object properties */
|
||||||
|
return udp_endpointTable_get_cell_value_core(column, value);
|
||||||
|
} else {
|
||||||
|
/* not found */
|
||||||
|
return SNMP_ERR_NOSUCHINSTANCE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --- udpTable --- */
|
||||||
|
|
||||||
|
#if LWIP_IPV4
|
||||||
|
|
||||||
|
/* list of allowed value ranges for incoming OID */
|
||||||
|
static const struct snmp_oid_range udp_Table_oid_ranges[] = {
|
||||||
|
{ 0, 0xff }, /* IP A */
|
||||||
|
{ 0, 0xff }, /* IP B */
|
||||||
|
{ 0, 0xff }, /* IP C */
|
||||||
|
{ 0, 0xff }, /* IP D */
|
||||||
|
{ 1, 0xffff } /* Port */
|
||||||
|
};
|
||||||
|
|
||||||
|
static snmp_err_t
|
||||||
|
udp_Table_get_cell_value_core(struct udp_pcb *pcb, const u32_t* column, union snmp_variant_value* value, u32_t* value_len)
|
||||||
|
{
|
||||||
|
LWIP_UNUSED_ARG(value_len);
|
||||||
|
|
||||||
|
switch (*column) {
|
||||||
|
case 1: /* udpLocalAddress */
|
||||||
|
/* set reference to PCB local IP and return a generic node that copies IP4 addresses */
|
||||||
|
value->u32 = ip_2_ip4(&pcb->local_ip)->addr;
|
||||||
|
break;
|
||||||
|
case 2: /* udpLocalPort */
|
||||||
|
/* set reference to PCB local port and return a generic node that copies u16_t values */
|
||||||
|
value->u32 = pcb->local_port;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return SNMP_ERR_NOSUCHINSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return SNMP_ERR_NOERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
static snmp_err_t
|
||||||
|
udp_Table_get_cell_value(const u32_t* column, const u32_t* row_oid, u8_t row_oid_len, union snmp_variant_value* value, u32_t* value_len)
|
||||||
|
{
|
||||||
|
ip4_addr_t ip;
|
||||||
|
u16_t port;
|
||||||
|
struct udp_pcb *pcb;
|
||||||
|
|
||||||
|
/* check if incoming OID length and if values are in plausible range */
|
||||||
|
if (!snmp_oid_in_range(row_oid, row_oid_len, udp_Table_oid_ranges, LWIP_ARRAYSIZE(udp_Table_oid_ranges))) {
|
||||||
|
return SNMP_ERR_NOSUCHINSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get IP and port from incoming OID */
|
||||||
|
snmp_oid_to_ip4(&row_oid[0], &ip); /* we know it succeeds because of oid_in_range check above */
|
||||||
|
port = (u16_t)row_oid[4];
|
||||||
|
|
||||||
|
/* find udp_pcb with requested ip and port*/
|
||||||
|
pcb = udp_pcbs;
|
||||||
|
while (pcb != NULL) {
|
||||||
|
if (IP_IS_V4_VAL(pcb->local_ip)) {
|
||||||
|
if (ip4_addr_cmp(&ip, ip_2_ip4(&pcb->local_ip)) && (port == pcb->local_port)) {
|
||||||
|
/* fill in object properties */
|
||||||
|
return udp_Table_get_cell_value_core(pcb, column, value, value_len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pcb = pcb->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* not found */
|
||||||
|
return SNMP_ERR_NOSUCHINSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static snmp_err_t
|
||||||
|
udp_Table_get_next_cell_instance_and_value(const u32_t* column, struct snmp_obj_id* row_oid, union snmp_variant_value* value, u32_t* value_len)
|
||||||
|
{
|
||||||
|
struct udp_pcb *pcb;
|
||||||
|
struct snmp_next_oid_state state;
|
||||||
|
u32_t result_temp[LWIP_ARRAYSIZE(udp_Table_oid_ranges)];
|
||||||
|
|
||||||
|
/* init struct to search next oid */
|
||||||
|
snmp_next_oid_init(&state, row_oid->id, row_oid->len, result_temp, LWIP_ARRAYSIZE(udp_Table_oid_ranges));
|
||||||
|
|
||||||
|
/* iterate over all possible OIDs to find the next one */
|
||||||
|
pcb = udp_pcbs;
|
||||||
|
while (pcb != NULL) {
|
||||||
|
u32_t test_oid[LWIP_ARRAYSIZE(udp_Table_oid_ranges)];
|
||||||
|
|
||||||
|
if (IP_IS_V4_VAL(pcb->local_ip)) {
|
||||||
|
snmp_ip4_to_oid(ip_2_ip4(&pcb->local_ip), &test_oid[0]);
|
||||||
|
test_oid[4] = pcb->local_port;
|
||||||
|
|
||||||
|
/* check generated OID: is it a candidate for the next one? */
|
||||||
|
snmp_next_oid_check(&state, test_oid, LWIP_ARRAYSIZE(udp_Table_oid_ranges), pcb);
|
||||||
|
}
|
||||||
|
|
||||||
|
pcb = pcb->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* did we find a next one? */
|
||||||
|
if (state.status == SNMP_NEXT_OID_STATUS_SUCCESS) {
|
||||||
|
snmp_oid_assign(row_oid, state.next_oid, state.next_oid_len);
|
||||||
|
/* fill in object properties */
|
||||||
|
return udp_Table_get_cell_value_core((struct udp_pcb*)state.reference, column, value, value_len);
|
||||||
|
} else {
|
||||||
|
/* not found */
|
||||||
|
return SNMP_ERR_NOSUCHINSTANCE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* LWIP_IPV4 */
|
||||||
|
|
||||||
|
static const struct snmp_scalar_node udp_inDatagrams = SNMP_SCALAR_CREATE_NODE_READONLY(1, SNMP_ASN1_TYPE_COUNTER, udp_get_value);
|
||||||
|
static const struct snmp_scalar_node udp_noPorts = SNMP_SCALAR_CREATE_NODE_READONLY(2, SNMP_ASN1_TYPE_COUNTER, udp_get_value);
|
||||||
|
static const struct snmp_scalar_node udp_inErrors = SNMP_SCALAR_CREATE_NODE_READONLY(3, SNMP_ASN1_TYPE_COUNTER, udp_get_value);
|
||||||
|
static const struct snmp_scalar_node udp_outDatagrams = SNMP_SCALAR_CREATE_NODE_READONLY(4, SNMP_ASN1_TYPE_COUNTER, udp_get_value);
|
||||||
|
static const struct snmp_scalar_node udp_HCInDatagrams = SNMP_SCALAR_CREATE_NODE_READONLY(8, SNMP_ASN1_TYPE_COUNTER64, udp_get_value);
|
||||||
|
static const struct snmp_scalar_node udp_HCOutDatagrams = SNMP_SCALAR_CREATE_NODE_READONLY(9, SNMP_ASN1_TYPE_COUNTER64, udp_get_value);
|
||||||
|
|
||||||
|
#if LWIP_IPV4
|
||||||
|
static const struct snmp_table_simple_col_def udp_Table_columns[] = {
|
||||||
|
{ 1, SNMP_ASN1_TYPE_IPADDR, SNMP_VARIANT_VALUE_TYPE_U32 }, /* udpLocalAddress */
|
||||||
|
{ 2, SNMP_ASN1_TYPE_INTEGER, SNMP_VARIANT_VALUE_TYPE_U32 } /* udpLocalPort */
|
||||||
|
};
|
||||||
|
static const struct snmp_table_simple_node udp_Table = SNMP_TABLE_CREATE_SIMPLE(5, udp_Table_columns, udp_Table_get_cell_value, udp_Table_get_next_cell_instance_and_value);
|
||||||
|
#endif /* LWIP_IPV4 */
|
||||||
|
|
||||||
|
static const struct snmp_table_simple_col_def udp_endpointTable_columns[] = {
|
||||||
|
/* all items except udpEndpointProcess are declared as not-accessible */
|
||||||
|
{ 8, SNMP_ASN1_TYPE_UNSIGNED32, SNMP_VARIANT_VALUE_TYPE_U32 } /* udpEndpointProcess */
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct snmp_table_simple_node udp_endpointTable = SNMP_TABLE_CREATE_SIMPLE(7, udp_endpointTable_columns, udp_endpointTable_get_cell_value, udp_endpointTable_get_next_cell_instance_and_value);
|
||||||
|
|
||||||
|
/* the following nodes access variables in LWIP stack from SNMP worker thread and must therefore be synced to LWIP (TCPIP) thread */
|
||||||
|
CREATE_LWIP_SYNC_NODE(1, udp_inDatagrams)
|
||||||
|
CREATE_LWIP_SYNC_NODE(2, udp_noPorts)
|
||||||
|
CREATE_LWIP_SYNC_NODE(3, udp_inErrors)
|
||||||
|
CREATE_LWIP_SYNC_NODE(4, udp_outDatagrams)
|
||||||
|
#if LWIP_IPV4
|
||||||
|
CREATE_LWIP_SYNC_NODE(5, udp_Table)
|
||||||
|
#endif /* LWIP_IPV4 */
|
||||||
|
CREATE_LWIP_SYNC_NODE(7, udp_endpointTable)
|
||||||
|
CREATE_LWIP_SYNC_NODE(8, udp_HCInDatagrams)
|
||||||
|
CREATE_LWIP_SYNC_NODE(9, udp_HCOutDatagrams)
|
||||||
|
|
||||||
|
static const struct snmp_node* const udp_nodes[] = {
|
||||||
|
&SYNC_NODE_NAME(udp_inDatagrams).node.node,
|
||||||
|
&SYNC_NODE_NAME(udp_noPorts).node.node,
|
||||||
|
&SYNC_NODE_NAME(udp_inErrors).node.node,
|
||||||
|
&SYNC_NODE_NAME(udp_outDatagrams).node.node,
|
||||||
|
#if LWIP_IPV4
|
||||||
|
&SYNC_NODE_NAME(udp_Table).node.node,
|
||||||
|
#endif /* LWIP_IPV4 */
|
||||||
|
&SYNC_NODE_NAME(udp_endpointTable).node.node,
|
||||||
|
&SYNC_NODE_NAME(udp_HCInDatagrams).node.node,
|
||||||
|
&SYNC_NODE_NAME(udp_HCOutDatagrams).node.node
|
||||||
|
};
|
||||||
|
|
||||||
|
const struct snmp_tree_node snmp_mib2_udp_root = SNMP_CREATE_TREE_NODE(7, udp_nodes);
|
||||||
|
#endif /* LWIP_SNMP && SNMP_LWIP_MIB2 && LWIP_UDP */
|
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,194 @@
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* SNMP Agent message handling structures (internal API, do not use in client code).
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006 Axon Digital Design B.V., The Netherlands.
|
||||||
|
* Copyright (c) 2016 Elias Oenal.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||||
|
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||||
|
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
|
* OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* Author: Christiaan Simons <christiaan.simons@axon.tv>
|
||||||
|
* Martin Hentschel <info@cl-soft.de>
|
||||||
|
* Elias Oenal <lwip@eliasoenal.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef LWIP_HDR_APPS_SNMP_MSG_H
|
||||||
|
#define LWIP_HDR_APPS_SNMP_MSG_H
|
||||||
|
|
||||||
|
#include "lwip/apps/snmp_opts.h"
|
||||||
|
|
||||||
|
#if LWIP_SNMP
|
||||||
|
|
||||||
|
#include "lwip/apps/snmp.h"
|
||||||
|
#include "lwip/apps/snmp_core.h"
|
||||||
|
#include "snmp_pbuf_stream.h"
|
||||||
|
#include "lwip/ip_addr.h"
|
||||||
|
#include "lwip/err.h"
|
||||||
|
|
||||||
|
#if LWIP_SNMP_V3
|
||||||
|
#include "snmpv3_priv.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* The listen port of the SNMP agent. Clients have to make their requests to
|
||||||
|
this port. Most standard clients won't work if you change this! */
|
||||||
|
#ifndef SNMP_IN_PORT
|
||||||
|
#define SNMP_IN_PORT 161
|
||||||
|
#endif
|
||||||
|
/* The remote port the SNMP agent sends traps to. Most standard trap sinks won't
|
||||||
|
work if you change this! */
|
||||||
|
#ifndef SNMP_TRAP_PORT
|
||||||
|
#define SNMP_TRAP_PORT 162
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* version defines used in PDU */
|
||||||
|
#define SNMP_VERSION_1 0
|
||||||
|
#define SNMP_VERSION_2c 1
|
||||||
|
#define SNMP_VERSION_3 3
|
||||||
|
|
||||||
|
struct snmp_varbind_enumerator
|
||||||
|
{
|
||||||
|
struct snmp_pbuf_stream pbuf_stream;
|
||||||
|
u16_t varbind_count;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
SNMP_VB_ENUMERATOR_ERR_OK = 0,
|
||||||
|
SNMP_VB_ENUMERATOR_ERR_EOVB = 1,
|
||||||
|
SNMP_VB_ENUMERATOR_ERR_ASN1ERROR = 2,
|
||||||
|
SNMP_VB_ENUMERATOR_ERR_INVALIDLENGTH = 3
|
||||||
|
} snmp_vb_enumerator_err_t;
|
||||||
|
|
||||||
|
void snmp_vb_enumerator_init(struct snmp_varbind_enumerator* enumerator, struct pbuf* p, u16_t offset, u16_t length);
|
||||||
|
snmp_vb_enumerator_err_t snmp_vb_enumerator_get_next(struct snmp_varbind_enumerator* enumerator, struct snmp_varbind* varbind);
|
||||||
|
|
||||||
|
struct snmp_request
|
||||||
|
{
|
||||||
|
/* Communication handle */
|
||||||
|
void *handle;
|
||||||
|
/* source IP address */
|
||||||
|
const ip_addr_t *source_ip;
|
||||||
|
/* source UDP port */
|
||||||
|
u16_t source_port;
|
||||||
|
/* incoming snmp version */
|
||||||
|
u8_t version;
|
||||||
|
/* community name (zero terminated) */
|
||||||
|
u8_t community[SNMP_MAX_COMMUNITY_STR_LEN + 1];
|
||||||
|
/* community string length (exclusive zero term) */
|
||||||
|
u16_t community_strlen;
|
||||||
|
/* request type */
|
||||||
|
u8_t request_type;
|
||||||
|
/* request ID */
|
||||||
|
s32_t request_id;
|
||||||
|
/* error status */
|
||||||
|
s32_t error_status;
|
||||||
|
/* error index */
|
||||||
|
s32_t error_index;
|
||||||
|
/* non-repeaters (getBulkRequest (SNMPv2c)) */
|
||||||
|
s32_t non_repeaters;
|
||||||
|
/* max-repetitions (getBulkRequest (SNMPv2c)) */
|
||||||
|
s32_t max_repetitions;
|
||||||
|
|
||||||
|
#if LWIP_SNMP_V3
|
||||||
|
s32_t msg_id;
|
||||||
|
s32_t msg_max_size;
|
||||||
|
u8_t msg_flags;
|
||||||
|
s32_t msg_security_model;
|
||||||
|
u8_t msg_authoritative_engine_id[SNMP_V3_MAX_ENGINE_ID_LENGTH];
|
||||||
|
u8_t msg_authoritative_engine_id_len;
|
||||||
|
s32_t msg_authoritative_engine_boots;
|
||||||
|
s32_t msg_authoritative_engine_time;
|
||||||
|
u8_t msg_user_name[SNMP_V3_MAX_USER_LENGTH];
|
||||||
|
u8_t msg_user_name_len;
|
||||||
|
u8_t msg_authentication_parameters[SNMP_V3_MAX_AUTH_PARAM_LENGTH];
|
||||||
|
u8_t msg_privacy_parameters[SNMP_V3_MAX_PRIV_PARAM_LENGTH];
|
||||||
|
u8_t context_engine_id[SNMP_V3_MAX_ENGINE_ID_LENGTH];
|
||||||
|
u8_t context_engine_id_len;
|
||||||
|
u8_t context_name[SNMP_V3_MAX_ENGINE_ID_LENGTH];
|
||||||
|
u8_t context_name_len;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct pbuf *inbound_pbuf;
|
||||||
|
struct snmp_varbind_enumerator inbound_varbind_enumerator;
|
||||||
|
u16_t inbound_varbind_offset;
|
||||||
|
u16_t inbound_varbind_len;
|
||||||
|
u16_t inbound_padding_len;
|
||||||
|
|
||||||
|
struct pbuf *outbound_pbuf;
|
||||||
|
struct snmp_pbuf_stream outbound_pbuf_stream;
|
||||||
|
u16_t outbound_pdu_offset;
|
||||||
|
u16_t outbound_error_status_offset;
|
||||||
|
u16_t outbound_error_index_offset;
|
||||||
|
u16_t outbound_varbind_offset;
|
||||||
|
#if LWIP_SNMP_V3
|
||||||
|
u16_t outbound_msg_global_data_offset;
|
||||||
|
u16_t outbound_msg_global_data_end;
|
||||||
|
u16_t outbound_msg_security_parameters_str_offset;
|
||||||
|
u16_t outbound_msg_security_parameters_seq_offset;
|
||||||
|
u16_t outbound_msg_security_parameters_end;
|
||||||
|
u16_t outbound_msg_authentication_parameters_offset;
|
||||||
|
u16_t outbound_scoped_pdu_seq_offset;
|
||||||
|
u16_t outbound_scoped_pdu_string_offset;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
u8_t value_buffer[SNMP_MAX_VALUE_SIZE];
|
||||||
|
};
|
||||||
|
|
||||||
|
/** A helper struct keeping length information about varbinds */
|
||||||
|
struct snmp_varbind_len
|
||||||
|
{
|
||||||
|
u8_t vb_len_len;
|
||||||
|
u16_t vb_value_len;
|
||||||
|
u8_t oid_len_len;
|
||||||
|
u16_t oid_value_len;
|
||||||
|
u8_t value_len_len;
|
||||||
|
u16_t value_value_len;
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Agent community string */
|
||||||
|
extern const char *snmp_community;
|
||||||
|
/** Agent community string for write access */
|
||||||
|
extern const char *snmp_community_write;
|
||||||
|
/** handle for sending traps */
|
||||||
|
extern void* snmp_traps_handle;
|
||||||
|
|
||||||
|
void snmp_receive(void *handle, struct pbuf *p, const ip_addr_t *source_ip, u16_t port);
|
||||||
|
err_t snmp_sendto(void *handle, struct pbuf *p, const ip_addr_t *dst, u16_t port);
|
||||||
|
u8_t snmp_get_local_ip_for_dst(void* handle, const ip_addr_t *dst, ip_addr_t *result);
|
||||||
|
err_t snmp_varbind_length(struct snmp_varbind *varbind, struct snmp_varbind_len *len);
|
||||||
|
err_t snmp_append_outbound_varbind(struct snmp_pbuf_stream *pbuf_stream, struct snmp_varbind* varbind);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* LWIP_SNMP */
|
||||||
|
|
||||||
|
#endif /* LWIP_HDR_APPS_SNMP_MSG_H */
|
|
@ -0,0 +1,121 @@
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* SNMP netconn frontend.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||||
|
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||||
|
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
|
* OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* Author: Dirk Ziegelmeier <dziegel@gmx.de>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "lwip/apps/snmp_opts.h"
|
||||||
|
|
||||||
|
#if LWIP_SNMP && SNMP_USE_NETCONN
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include "lwip/api.h"
|
||||||
|
#include "lwip/ip.h"
|
||||||
|
#include "lwip/udp.h"
|
||||||
|
#include "snmp_msg.h"
|
||||||
|
#include "lwip/sys.h"
|
||||||
|
|
||||||
|
/** SNMP netconn API worker thread */
|
||||||
|
static void
|
||||||
|
snmp_netconn_thread(void *arg)
|
||||||
|
{
|
||||||
|
struct netconn *conn;
|
||||||
|
struct netbuf *buf;
|
||||||
|
err_t err;
|
||||||
|
LWIP_UNUSED_ARG(arg);
|
||||||
|
|
||||||
|
/* Bind to SNMP port with default IP address */
|
||||||
|
#if LWIP_IPV6
|
||||||
|
conn = netconn_new(NETCONN_UDP_IPV6);
|
||||||
|
netconn_bind(conn, IP6_ADDR_ANY, SNMP_IN_PORT);
|
||||||
|
#else /* LWIP_IPV6 */
|
||||||
|
conn = netconn_new(NETCONN_UDP);
|
||||||
|
netconn_bind(conn, IP4_ADDR_ANY, SNMP_IN_PORT);
|
||||||
|
#endif /* LWIP_IPV6 */
|
||||||
|
LWIP_ERROR("snmp_netconn: invalid conn", (conn != NULL), return;);
|
||||||
|
|
||||||
|
snmp_traps_handle = conn;
|
||||||
|
|
||||||
|
do {
|
||||||
|
err = netconn_recv(conn, &buf);
|
||||||
|
|
||||||
|
if (err == ERR_OK) {
|
||||||
|
snmp_receive(conn, buf->p, &buf->addr, buf->port);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (buf != NULL) {
|
||||||
|
netbuf_delete(buf);
|
||||||
|
}
|
||||||
|
} while(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
err_t
|
||||||
|
snmp_sendto(void *handle, struct pbuf *p, const ip_addr_t *dst, u16_t port)
|
||||||
|
{
|
||||||
|
err_t result;
|
||||||
|
struct netbuf buf;
|
||||||
|
|
||||||
|
memset(&buf, 0, sizeof(buf));
|
||||||
|
buf.p = p;
|
||||||
|
result = netconn_sendto((struct netconn*)handle, &buf, dst, port);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
u8_t
|
||||||
|
snmp_get_local_ip_for_dst(void* handle, const ip_addr_t *dst, ip_addr_t *result)
|
||||||
|
{
|
||||||
|
struct netconn* conn = (struct netconn*)handle;
|
||||||
|
struct netif *dst_if;
|
||||||
|
const ip_addr_t* dst_ip;
|
||||||
|
|
||||||
|
LWIP_UNUSED_ARG(conn); /* unused in case of IPV4 only configuration */
|
||||||
|
|
||||||
|
ip_route_get_local_ip(&conn->pcb.udp->local_ip, dst, dst_if, dst_ip);
|
||||||
|
|
||||||
|
if ((dst_if != NULL) && (dst_ip != NULL)) {
|
||||||
|
ip_addr_copy(*result, *dst_ip);
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Starts SNMP Agent.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
snmp_init(void)
|
||||||
|
{
|
||||||
|
sys_thread_new("snmp_netconn", snmp_netconn_thread, NULL, SNMP_STACK_SIZE, SNMP_THREAD_PRIO);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* LWIP_SNMP && SNMP_USE_NETCONN */
|
|
@ -0,0 +1,156 @@
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* SNMP pbuf stream wrapper implementation (internal API, do not use in client code).
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||||
|
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||||
|
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
|
* OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* This file is part of the lwIP TCP/IP stack.
|
||||||
|
*
|
||||||
|
* Author: Martin Hentschel <info@cl-soft.de>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "lwip/apps/snmp_opts.h"
|
||||||
|
|
||||||
|
#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */
|
||||||
|
|
||||||
|
#include "snmp_pbuf_stream.h"
|
||||||
|
#include "lwip/def.h"
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
err_t
|
||||||
|
snmp_pbuf_stream_init(struct snmp_pbuf_stream* pbuf_stream, struct pbuf* p, u16_t offset, u16_t length)
|
||||||
|
{
|
||||||
|
pbuf_stream->offset = offset;
|
||||||
|
pbuf_stream->length = length;
|
||||||
|
pbuf_stream->pbuf = p;
|
||||||
|
|
||||||
|
return ERR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
err_t
|
||||||
|
snmp_pbuf_stream_read(struct snmp_pbuf_stream* pbuf_stream, u8_t* data)
|
||||||
|
{
|
||||||
|
if (pbuf_stream->length == 0) {
|
||||||
|
return ERR_BUF;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pbuf_copy_partial(pbuf_stream->pbuf, data, 1, pbuf_stream->offset) == 0) {
|
||||||
|
return ERR_BUF;
|
||||||
|
}
|
||||||
|
|
||||||
|
pbuf_stream->offset++;
|
||||||
|
pbuf_stream->length--;
|
||||||
|
|
||||||
|
return ERR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
err_t
|
||||||
|
snmp_pbuf_stream_write(struct snmp_pbuf_stream* pbuf_stream, u8_t data)
|
||||||
|
{
|
||||||
|
return snmp_pbuf_stream_writebuf(pbuf_stream, &data, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
err_t
|
||||||
|
snmp_pbuf_stream_writebuf(struct snmp_pbuf_stream* pbuf_stream, const void* buf, u16_t buf_len)
|
||||||
|
{
|
||||||
|
if (pbuf_stream->length < buf_len) {
|
||||||
|
return ERR_BUF;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pbuf_take_at(pbuf_stream->pbuf, buf, buf_len, pbuf_stream->offset) != ERR_OK) {
|
||||||
|
return ERR_BUF;
|
||||||
|
}
|
||||||
|
|
||||||
|
pbuf_stream->offset += buf_len;
|
||||||
|
pbuf_stream->length -= buf_len;
|
||||||
|
|
||||||
|
return ERR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
err_t
|
||||||
|
snmp_pbuf_stream_writeto(struct snmp_pbuf_stream* pbuf_stream, struct snmp_pbuf_stream* target_pbuf_stream, u16_t len)
|
||||||
|
{
|
||||||
|
|
||||||
|
if ((pbuf_stream == NULL) || (target_pbuf_stream == NULL)) {
|
||||||
|
return ERR_ARG;
|
||||||
|
}
|
||||||
|
if ((len > pbuf_stream->length) || (len > target_pbuf_stream->length)) {
|
||||||
|
return ERR_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (len == 0) {
|
||||||
|
len = LWIP_MIN(pbuf_stream->length, target_pbuf_stream->length);
|
||||||
|
}
|
||||||
|
|
||||||
|
while (len > 0) {
|
||||||
|
u16_t chunk_len;
|
||||||
|
err_t err;
|
||||||
|
u16_t target_offset;
|
||||||
|
struct pbuf* pbuf = pbuf_skip(pbuf_stream->pbuf, pbuf_stream->offset, &target_offset);
|
||||||
|
|
||||||
|
if ((pbuf == NULL) || (pbuf->len == 0)) {
|
||||||
|
return ERR_BUF;
|
||||||
|
}
|
||||||
|
|
||||||
|
chunk_len = LWIP_MIN(len, pbuf->len);
|
||||||
|
err = snmp_pbuf_stream_writebuf(target_pbuf_stream, &((u8_t*)pbuf->payload)[target_offset], chunk_len);
|
||||||
|
if (err != ERR_OK) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
pbuf_stream->offset += chunk_len;
|
||||||
|
pbuf_stream->length -= chunk_len;
|
||||||
|
len -= chunk_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ERR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
err_t
|
||||||
|
snmp_pbuf_stream_seek(struct snmp_pbuf_stream* pbuf_stream, s32_t offset)
|
||||||
|
{
|
||||||
|
if ((offset < 0) || (offset > pbuf_stream->length)) {
|
||||||
|
/* we cannot seek backwards or forward behind stream end */
|
||||||
|
return ERR_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
pbuf_stream->offset += (u16_t)offset;
|
||||||
|
pbuf_stream->length -= (u16_t)offset;
|
||||||
|
|
||||||
|
return ERR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
err_t
|
||||||
|
snmp_pbuf_stream_seek_abs(struct snmp_pbuf_stream* pbuf_stream, u32_t offset)
|
||||||
|
{
|
||||||
|
s32_t rel_offset = offset - pbuf_stream->offset;
|
||||||
|
return snmp_pbuf_stream_seek(pbuf_stream, rel_offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* LWIP_SNMP */
|
|
@ -0,0 +1,73 @@
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* SNMP pbuf stream wrapper (internal API, do not use in client code).
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||||
|
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||||
|
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
|
* OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* This file is part of the lwIP TCP/IP stack.
|
||||||
|
*
|
||||||
|
* Author: Martin Hentschel <info@cl-soft.de>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef LWIP_HDR_APPS_SNMP_PBUF_STREAM_H
|
||||||
|
#define LWIP_HDR_APPS_SNMP_PBUF_STREAM_H
|
||||||
|
|
||||||
|
#include "lwip/apps/snmp_opts.h"
|
||||||
|
|
||||||
|
#if LWIP_SNMP
|
||||||
|
|
||||||
|
#include "lwip/err.h"
|
||||||
|
#include "lwip/pbuf.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct snmp_pbuf_stream
|
||||||
|
{
|
||||||
|
struct pbuf* pbuf;
|
||||||
|
u16_t offset;
|
||||||
|
u16_t length;
|
||||||
|
};
|
||||||
|
|
||||||
|
err_t snmp_pbuf_stream_init(struct snmp_pbuf_stream* pbuf_stream, struct pbuf* p, u16_t offset, u16_t length);
|
||||||
|
err_t snmp_pbuf_stream_read(struct snmp_pbuf_stream* pbuf_stream, u8_t* data);
|
||||||
|
err_t snmp_pbuf_stream_write(struct snmp_pbuf_stream* pbuf_stream, u8_t data);
|
||||||
|
err_t snmp_pbuf_stream_writebuf(struct snmp_pbuf_stream* pbuf_stream, const void* buf, u16_t buf_len);
|
||||||
|
err_t snmp_pbuf_stream_writeto(struct snmp_pbuf_stream* pbuf_stream, struct snmp_pbuf_stream* target_pbuf_stream, u16_t len);
|
||||||
|
err_t snmp_pbuf_stream_seek(struct snmp_pbuf_stream* pbuf_stream, s32_t offset);
|
||||||
|
err_t snmp_pbuf_stream_seek_abs(struct snmp_pbuf_stream* pbuf_stream, u32_t offset);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* LWIP_SNMP */
|
||||||
|
|
||||||
|
#endif /* LWIP_HDR_APPS_SNMP_PBUF_STREAM_H */
|
|
@ -0,0 +1,100 @@
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* SNMP RAW API frontend.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||||
|
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||||
|
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
|
* OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* Author: Dirk Ziegelmeier <dziegel@gmx.de>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "lwip/apps/snmp_opts.h"
|
||||||
|
#include "lwip/ip_addr.h"
|
||||||
|
|
||||||
|
#if LWIP_SNMP && SNMP_USE_RAW
|
||||||
|
|
||||||
|
#include "lwip/udp.h"
|
||||||
|
#include "lwip/ip.h"
|
||||||
|
#include "snmp_msg.h"
|
||||||
|
|
||||||
|
/* lwIP UDP receive callback function */
|
||||||
|
static void
|
||||||
|
snmp_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr, u16_t port)
|
||||||
|
{
|
||||||
|
LWIP_UNUSED_ARG(arg);
|
||||||
|
|
||||||
|
snmp_receive(pcb, p, addr, port);
|
||||||
|
|
||||||
|
pbuf_free(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
err_t
|
||||||
|
snmp_sendto(void *handle, struct pbuf *p, const ip_addr_t *dst, u16_t port)
|
||||||
|
{
|
||||||
|
return udp_sendto((struct udp_pcb*)handle, p, dst, port);
|
||||||
|
}
|
||||||
|
|
||||||
|
u8_t
|
||||||
|
snmp_get_local_ip_for_dst(void* handle, const ip_addr_t *dst, ip_addr_t *result)
|
||||||
|
{
|
||||||
|
struct udp_pcb* udp_pcb = (struct udp_pcb*)handle;
|
||||||
|
struct netif *dst_if;
|
||||||
|
const ip_addr_t* dst_ip;
|
||||||
|
|
||||||
|
LWIP_UNUSED_ARG(udp_pcb); /* unused in case of IPV4 only configuration */
|
||||||
|
|
||||||
|
ip_route_get_local_ip(&udp_pcb->local_ip, dst, dst_if, dst_ip);
|
||||||
|
|
||||||
|
if ((dst_if != NULL) && (dst_ip != NULL)) {
|
||||||
|
ip_addr_copy(*result, *dst_ip);
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup snmp_core
|
||||||
|
* Starts SNMP Agent.
|
||||||
|
* Allocates UDP pcb and binds it to IP_ANY_TYPE port 161.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
snmp_init(void)
|
||||||
|
{
|
||||||
|
err_t err;
|
||||||
|
|
||||||
|
struct udp_pcb *snmp_pcb = udp_new_ip_type(IPADDR_TYPE_ANY);
|
||||||
|
LWIP_ERROR("snmp_raw: no PCB", (snmp_pcb != NULL), return;);
|
||||||
|
|
||||||
|
snmp_traps_handle = snmp_pcb;
|
||||||
|
|
||||||
|
udp_recv(snmp_pcb, snmp_recv, (void *)SNMP_IN_PORT);
|
||||||
|
err = udp_bind(snmp_pcb, IP_ANY_TYPE, SNMP_IN_PORT);
|
||||||
|
LWIP_ERROR("snmp_raw: Unable to bind PCB", (err == ERR_OK), return;);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* LWIP_SNMP && SNMP_USE_RAW */
|
|
@ -0,0 +1,220 @@
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* SNMP scalar node support implementation.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||||
|
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||||
|
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
|
* OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* This file is part of the lwIP TCP/IP stack.
|
||||||
|
*
|
||||||
|
* Author: Martin Hentschel <info@cl-soft.de>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "lwip/apps/snmp_opts.h"
|
||||||
|
|
||||||
|
#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */
|
||||||
|
|
||||||
|
#include "lwip/apps/snmp_scalar.h"
|
||||||
|
#include "lwip/apps/snmp_core.h"
|
||||||
|
|
||||||
|
static s16_t snmp_scalar_array_get_value(struct snmp_node_instance* instance, void* value);
|
||||||
|
static snmp_err_t snmp_scalar_array_set_test(struct snmp_node_instance* instance, u16_t value_len, void* value);
|
||||||
|
static snmp_err_t snmp_scalar_array_set_value(struct snmp_node_instance* instance, u16_t value_len, void* value);
|
||||||
|
|
||||||
|
snmp_err_t
|
||||||
|
snmp_scalar_get_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance)
|
||||||
|
{
|
||||||
|
const struct snmp_scalar_node* scalar_node = (const struct snmp_scalar_node*)(const void*)instance->node;
|
||||||
|
|
||||||
|
LWIP_UNUSED_ARG(root_oid);
|
||||||
|
LWIP_UNUSED_ARG(root_oid_len);
|
||||||
|
|
||||||
|
/* scalar only has one dedicated instance: .0 */
|
||||||
|
if ((instance->instance_oid.len != 1) || (instance->instance_oid.id[0] != 0)) {
|
||||||
|
return SNMP_ERR_NOSUCHINSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
instance->access = scalar_node->access;
|
||||||
|
instance->asn1_type = scalar_node->asn1_type;
|
||||||
|
instance->get_value = scalar_node->get_value;
|
||||||
|
instance->set_test = scalar_node->set_test;
|
||||||
|
instance->set_value = scalar_node->set_value;
|
||||||
|
return SNMP_ERR_NOERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
snmp_err_t
|
||||||
|
snmp_scalar_get_next_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance)
|
||||||
|
{
|
||||||
|
/* because our only instance is .0 we can only return a next instance if no instance oid is passed */
|
||||||
|
if (instance->instance_oid.len == 0) {
|
||||||
|
instance->instance_oid.len = 1;
|
||||||
|
instance->instance_oid.id[0] = 0;
|
||||||
|
|
||||||
|
return snmp_scalar_get_instance(root_oid, root_oid_len, instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
return SNMP_ERR_NOSUCHINSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
snmp_err_t
|
||||||
|
snmp_scalar_array_get_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance)
|
||||||
|
{
|
||||||
|
LWIP_UNUSED_ARG(root_oid);
|
||||||
|
LWIP_UNUSED_ARG(root_oid_len);
|
||||||
|
|
||||||
|
if ((instance->instance_oid.len == 2) && (instance->instance_oid.id[1] == 0)) {
|
||||||
|
const struct snmp_scalar_array_node* array_node = (const struct snmp_scalar_array_node*)(const void*)instance->node;
|
||||||
|
const struct snmp_scalar_array_node_def* array_node_def = array_node->array_nodes;
|
||||||
|
u32_t i = 0;
|
||||||
|
|
||||||
|
while (i < array_node->array_node_count) {
|
||||||
|
if (array_node_def->oid == instance->instance_oid.id[0]) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
array_node_def++;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i < array_node->array_node_count) {
|
||||||
|
instance->access = array_node_def->access;
|
||||||
|
instance->asn1_type = array_node_def->asn1_type;
|
||||||
|
instance->get_value = snmp_scalar_array_get_value;
|
||||||
|
instance->set_test = snmp_scalar_array_set_test;
|
||||||
|
instance->set_value = snmp_scalar_array_set_value;
|
||||||
|
instance->reference.const_ptr = array_node_def;
|
||||||
|
|
||||||
|
return SNMP_ERR_NOERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return SNMP_ERR_NOSUCHINSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
snmp_err_t
|
||||||
|
snmp_scalar_array_get_next_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance)
|
||||||
|
{
|
||||||
|
const struct snmp_scalar_array_node* array_node = (const struct snmp_scalar_array_node*)(const void*)instance->node;
|
||||||
|
const struct snmp_scalar_array_node_def* array_node_def = array_node->array_nodes;
|
||||||
|
const struct snmp_scalar_array_node_def* result = NULL;
|
||||||
|
|
||||||
|
LWIP_UNUSED_ARG(root_oid);
|
||||||
|
LWIP_UNUSED_ARG(root_oid_len);
|
||||||
|
|
||||||
|
if ((instance->instance_oid.len == 0) && (array_node->array_node_count > 0)) {
|
||||||
|
/* return node with lowest OID */
|
||||||
|
u16_t i = 0;
|
||||||
|
|
||||||
|
result = array_node_def;
|
||||||
|
array_node_def++;
|
||||||
|
|
||||||
|
for (i = 1; i < array_node->array_node_count; i++) {
|
||||||
|
if (array_node_def->oid < result->oid) {
|
||||||
|
result = array_node_def;
|
||||||
|
}
|
||||||
|
array_node_def++;
|
||||||
|
}
|
||||||
|
} else if (instance->instance_oid.len >= 1) {
|
||||||
|
if (instance->instance_oid.len == 1) {
|
||||||
|
/* if we have the requested OID we return its instance, otherwise we search for the next available */
|
||||||
|
u16_t i = 0;
|
||||||
|
while (i < array_node->array_node_count) {
|
||||||
|
if (array_node_def->oid == instance->instance_oid.id[0]) {
|
||||||
|
result = array_node_def;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
array_node_def++;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (result == NULL) {
|
||||||
|
u32_t oid_dist = 0xFFFFFFFFUL;
|
||||||
|
u16_t i = 0;
|
||||||
|
array_node_def = array_node->array_nodes; /* may be already at the end when if case before was executed without result -> reinitialize to start */
|
||||||
|
while (i < array_node->array_node_count) {
|
||||||
|
if ((array_node_def->oid > instance->instance_oid.id[0]) &&
|
||||||
|
((u32_t)(array_node_def->oid - instance->instance_oid.id[0]) < oid_dist)) {
|
||||||
|
result = array_node_def;
|
||||||
|
oid_dist = array_node_def->oid - instance->instance_oid.id[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
array_node_def++;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result == NULL) {
|
||||||
|
/* nothing to return */
|
||||||
|
return SNMP_ERR_NOSUCHINSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
instance->instance_oid.len = 2;
|
||||||
|
instance->instance_oid.id[0] = result->oid;
|
||||||
|
instance->instance_oid.id[1] = 0;
|
||||||
|
|
||||||
|
instance->access = result->access;
|
||||||
|
instance->asn1_type = result->asn1_type;
|
||||||
|
instance->get_value = snmp_scalar_array_get_value;
|
||||||
|
instance->set_test = snmp_scalar_array_set_test;
|
||||||
|
instance->set_value = snmp_scalar_array_set_value;
|
||||||
|
instance->reference.const_ptr = result;
|
||||||
|
|
||||||
|
return SNMP_ERR_NOERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
static s16_t
|
||||||
|
snmp_scalar_array_get_value(struct snmp_node_instance* instance, void* value)
|
||||||
|
{
|
||||||
|
const struct snmp_scalar_array_node* array_node = (const struct snmp_scalar_array_node*)(const void*)instance->node;
|
||||||
|
const struct snmp_scalar_array_node_def* array_node_def = (const struct snmp_scalar_array_node_def*)instance->reference.const_ptr;
|
||||||
|
|
||||||
|
return array_node->get_value(array_node_def, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
static snmp_err_t
|
||||||
|
snmp_scalar_array_set_test(struct snmp_node_instance* instance, u16_t value_len, void* value)
|
||||||
|
{
|
||||||
|
const struct snmp_scalar_array_node* array_node = (const struct snmp_scalar_array_node*)(const void*)instance->node;
|
||||||
|
const struct snmp_scalar_array_node_def* array_node_def = (const struct snmp_scalar_array_node_def*)instance->reference.const_ptr;
|
||||||
|
|
||||||
|
return array_node->set_test(array_node_def, value_len, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
static snmp_err_t
|
||||||
|
snmp_scalar_array_set_value(struct snmp_node_instance* instance, u16_t value_len, void* value)
|
||||||
|
{
|
||||||
|
const struct snmp_scalar_array_node* array_node = (const struct snmp_scalar_array_node*)(const void*)instance->node;
|
||||||
|
const struct snmp_scalar_array_node_def* array_node_def = (const struct snmp_scalar_array_node_def*)instance->reference.const_ptr;
|
||||||
|
|
||||||
|
return array_node->set_value(array_node_def, value_len, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* LWIP_SNMP */
|
|
@ -0,0 +1,343 @@
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* SNMP table support implementation.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||||
|
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||||
|
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
|
* OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* This file is part of the lwIP TCP/IP stack.
|
||||||
|
*
|
||||||
|
* Author: Martin Hentschel <info@cl-soft.de>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "lwip/apps/snmp_opts.h"
|
||||||
|
|
||||||
|
#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */
|
||||||
|
|
||||||
|
#include "lwip/apps/snmp_core.h"
|
||||||
|
#include "lwip/apps/snmp_table.h"
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
snmp_err_t snmp_table_get_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance)
|
||||||
|
{
|
||||||
|
snmp_err_t ret = SNMP_ERR_NOSUCHINSTANCE;
|
||||||
|
const struct snmp_table_node* table_node = (const struct snmp_table_node*)(const void*)instance->node;
|
||||||
|
|
||||||
|
LWIP_UNUSED_ARG(root_oid);
|
||||||
|
LWIP_UNUSED_ARG(root_oid_len);
|
||||||
|
|
||||||
|
/* check min. length (fixed row entry definition, column, row instance oid with at least one entry */
|
||||||
|
/* fixed row entry always has oid 1 */
|
||||||
|
if ((instance->instance_oid.len >= 3) && (instance->instance_oid.id[0] == 1)) {
|
||||||
|
/* search column */
|
||||||
|
const struct snmp_table_col_def* col_def = table_node->columns;
|
||||||
|
u16_t i = table_node->column_count;
|
||||||
|
while (i > 0) {
|
||||||
|
if (col_def->index == instance->instance_oid.id[1]) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
col_def++;
|
||||||
|
i--;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i > 0) {
|
||||||
|
/* everything may be overwritten by get_cell_instance_method() in order to implement special handling for single columns/cells */
|
||||||
|
instance->asn1_type = col_def->asn1_type;
|
||||||
|
instance->access = col_def->access;
|
||||||
|
instance->get_value = table_node->get_value;
|
||||||
|
instance->set_test = table_node->set_test;
|
||||||
|
instance->set_value = table_node->set_value;
|
||||||
|
|
||||||
|
ret = table_node->get_cell_instance(
|
||||||
|
&(instance->instance_oid.id[1]),
|
||||||
|
&(instance->instance_oid.id[2]),
|
||||||
|
instance->instance_oid.len-2,
|
||||||
|
instance);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
snmp_err_t snmp_table_get_next_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance)
|
||||||
|
{
|
||||||
|
const struct snmp_table_node* table_node = (const struct snmp_table_node*)(const void*)instance->node;
|
||||||
|
const struct snmp_table_col_def* col_def;
|
||||||
|
struct snmp_obj_id row_oid;
|
||||||
|
u32_t column = 0;
|
||||||
|
snmp_err_t result;
|
||||||
|
|
||||||
|
LWIP_UNUSED_ARG(root_oid);
|
||||||
|
LWIP_UNUSED_ARG(root_oid_len);
|
||||||
|
|
||||||
|
/* check that first part of id is 0 or 1, referencing fixed row entry */
|
||||||
|
if ((instance->instance_oid.len > 0) && (instance->instance_oid.id[0] > 1)) {
|
||||||
|
return SNMP_ERR_NOSUCHINSTANCE;
|
||||||
|
}
|
||||||
|
if (instance->instance_oid.len > 1) {
|
||||||
|
column = instance->instance_oid.id[1];
|
||||||
|
}
|
||||||
|
if (instance->instance_oid.len > 2) {
|
||||||
|
snmp_oid_assign(&row_oid, &(instance->instance_oid.id[2]), instance->instance_oid.len - 2);
|
||||||
|
} else {
|
||||||
|
row_oid.len = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
instance->get_value = table_node->get_value;
|
||||||
|
instance->set_test = table_node->set_test;
|
||||||
|
instance->set_value = table_node->set_value;
|
||||||
|
|
||||||
|
/* resolve column and value */
|
||||||
|
do {
|
||||||
|
u16_t i;
|
||||||
|
const struct snmp_table_col_def* next_col_def = NULL;
|
||||||
|
col_def = table_node->columns;
|
||||||
|
|
||||||
|
for (i = 0; i < table_node->column_count; i++) {
|
||||||
|
if (col_def->index == column) {
|
||||||
|
next_col_def = col_def;
|
||||||
|
break;
|
||||||
|
} else if ((col_def->index > column) && ((next_col_def == NULL) || (col_def->index < next_col_def->index))) {
|
||||||
|
next_col_def = col_def;
|
||||||
|
}
|
||||||
|
col_def++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (next_col_def == NULL) {
|
||||||
|
/* no further column found */
|
||||||
|
return SNMP_ERR_NOSUCHINSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
instance->asn1_type = next_col_def->asn1_type;
|
||||||
|
instance->access = next_col_def->access;
|
||||||
|
|
||||||
|
result = table_node->get_next_cell_instance(
|
||||||
|
&next_col_def->index,
|
||||||
|
&row_oid,
|
||||||
|
instance);
|
||||||
|
|
||||||
|
if (result == SNMP_ERR_NOERROR) {
|
||||||
|
col_def = next_col_def;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
row_oid.len = 0; /* reset row_oid because we switch to next column and start with the first entry there */
|
||||||
|
column = next_col_def->index + 1;
|
||||||
|
} while (1);
|
||||||
|
|
||||||
|
/* build resulting oid */
|
||||||
|
instance->instance_oid.len = 2;
|
||||||
|
instance->instance_oid.id[0] = 1;
|
||||||
|
instance->instance_oid.id[1] = col_def->index;
|
||||||
|
snmp_oid_append(&instance->instance_oid, row_oid.id, row_oid.len);
|
||||||
|
|
||||||
|
return SNMP_ERR_NOERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
snmp_err_t snmp_table_simple_get_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance)
|
||||||
|
{
|
||||||
|
snmp_err_t ret = SNMP_ERR_NOSUCHINSTANCE;
|
||||||
|
const struct snmp_table_simple_node* table_node = (const struct snmp_table_simple_node*)(const void*)instance->node;
|
||||||
|
|
||||||
|
LWIP_UNUSED_ARG(root_oid);
|
||||||
|
LWIP_UNUSED_ARG(root_oid_len);
|
||||||
|
|
||||||
|
/* check min. length (fixed row entry definition, column, row instance oid with at least one entry */
|
||||||
|
/* fixed row entry always has oid 1 */
|
||||||
|
if ((instance->instance_oid.len >= 3) && (instance->instance_oid.id[0] == 1)) {
|
||||||
|
ret = table_node->get_cell_value(
|
||||||
|
&(instance->instance_oid.id[1]),
|
||||||
|
&(instance->instance_oid.id[2]),
|
||||||
|
instance->instance_oid.len-2,
|
||||||
|
&instance->reference,
|
||||||
|
&instance->reference_len);
|
||||||
|
|
||||||
|
if (ret == SNMP_ERR_NOERROR) {
|
||||||
|
/* search column */
|
||||||
|
const struct snmp_table_simple_col_def* col_def = table_node->columns;
|
||||||
|
u32_t i = table_node->column_count;
|
||||||
|
while (i > 0) {
|
||||||
|
if (col_def->index == instance->instance_oid.id[1]) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
col_def++;
|
||||||
|
i--;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i > 0) {
|
||||||
|
instance->asn1_type = col_def->asn1_type;
|
||||||
|
instance->access = SNMP_NODE_INSTANCE_READ_ONLY;
|
||||||
|
instance->set_test = NULL;
|
||||||
|
instance->set_value = NULL;
|
||||||
|
|
||||||
|
switch (col_def->data_type) {
|
||||||
|
case SNMP_VARIANT_VALUE_TYPE_U32:
|
||||||
|
instance->get_value = snmp_table_extract_value_from_u32ref;
|
||||||
|
break;
|
||||||
|
case SNMP_VARIANT_VALUE_TYPE_S32:
|
||||||
|
instance->get_value = snmp_table_extract_value_from_s32ref;
|
||||||
|
break;
|
||||||
|
case SNMP_VARIANT_VALUE_TYPE_PTR: /* fall through */
|
||||||
|
case SNMP_VARIANT_VALUE_TYPE_CONST_PTR:
|
||||||
|
instance->get_value = snmp_table_extract_value_from_refconstptr;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
LWIP_DEBUGF(SNMP_DEBUG, ("snmp_table_simple_get_instance(): unknown column data_type: %d\n", col_def->data_type));
|
||||||
|
return SNMP_ERR_GENERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = SNMP_ERR_NOERROR;
|
||||||
|
} else {
|
||||||
|
ret = SNMP_ERR_NOSUCHINSTANCE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
snmp_err_t snmp_table_simple_get_next_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance)
|
||||||
|
{
|
||||||
|
const struct snmp_table_simple_node* table_node = (const struct snmp_table_simple_node*)(const void*)instance->node;
|
||||||
|
const struct snmp_table_simple_col_def* col_def;
|
||||||
|
struct snmp_obj_id row_oid;
|
||||||
|
u32_t column = 0;
|
||||||
|
snmp_err_t result;
|
||||||
|
|
||||||
|
LWIP_UNUSED_ARG(root_oid);
|
||||||
|
LWIP_UNUSED_ARG(root_oid_len);
|
||||||
|
|
||||||
|
/* check that first part of id is 0 or 1, referencing fixed row entry */
|
||||||
|
if ((instance->instance_oid.len > 0) && (instance->instance_oid.id[0] > 1)) {
|
||||||
|
return SNMP_ERR_NOSUCHINSTANCE;
|
||||||
|
}
|
||||||
|
if (instance->instance_oid.len > 1) {
|
||||||
|
column = instance->instance_oid.id[1];
|
||||||
|
}
|
||||||
|
if (instance->instance_oid.len > 2) {
|
||||||
|
snmp_oid_assign(&row_oid, &(instance->instance_oid.id[2]), instance->instance_oid.len - 2);
|
||||||
|
} else {
|
||||||
|
row_oid.len = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* resolve column and value */
|
||||||
|
do {
|
||||||
|
u32_t i;
|
||||||
|
const struct snmp_table_simple_col_def* next_col_def = NULL;
|
||||||
|
col_def = table_node->columns;
|
||||||
|
|
||||||
|
for (i = 0; i < table_node->column_count; i++) {
|
||||||
|
if (col_def->index == column) {
|
||||||
|
next_col_def = col_def;
|
||||||
|
break;
|
||||||
|
} else if ((col_def->index > column) && ((next_col_def == NULL) ||
|
||||||
|
(col_def->index < next_col_def->index))) {
|
||||||
|
next_col_def = col_def;
|
||||||
|
}
|
||||||
|
col_def++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (next_col_def == NULL) {
|
||||||
|
/* no further column found */
|
||||||
|
return SNMP_ERR_NOSUCHINSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = table_node->get_next_cell_instance_and_value(
|
||||||
|
&next_col_def->index,
|
||||||
|
&row_oid,
|
||||||
|
&instance->reference,
|
||||||
|
&instance->reference_len);
|
||||||
|
|
||||||
|
if (result == SNMP_ERR_NOERROR) {
|
||||||
|
col_def = next_col_def;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
row_oid.len = 0; /* reset row_oid because we switch to next column and start with the first entry there */
|
||||||
|
column = next_col_def->index + 1;
|
||||||
|
}
|
||||||
|
while (1);
|
||||||
|
|
||||||
|
instance->asn1_type = col_def->asn1_type;
|
||||||
|
instance->access = SNMP_NODE_INSTANCE_READ_ONLY;
|
||||||
|
instance->set_test = NULL;
|
||||||
|
instance->set_value = NULL;
|
||||||
|
|
||||||
|
switch (col_def->data_type) {
|
||||||
|
case SNMP_VARIANT_VALUE_TYPE_U32:
|
||||||
|
instance->get_value = snmp_table_extract_value_from_u32ref;
|
||||||
|
break;
|
||||||
|
case SNMP_VARIANT_VALUE_TYPE_S32:
|
||||||
|
instance->get_value = snmp_table_extract_value_from_s32ref;
|
||||||
|
break;
|
||||||
|
case SNMP_VARIANT_VALUE_TYPE_PTR: /* fall through */
|
||||||
|
case SNMP_VARIANT_VALUE_TYPE_CONST_PTR:
|
||||||
|
instance->get_value = snmp_table_extract_value_from_refconstptr;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
LWIP_DEBUGF(SNMP_DEBUG, ("snmp_table_simple_get_instance(): unknown column data_type: %d\n", col_def->data_type));
|
||||||
|
return SNMP_ERR_GENERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* build resulting oid */
|
||||||
|
instance->instance_oid.len = 2;
|
||||||
|
instance->instance_oid.id[0] = 1;
|
||||||
|
instance->instance_oid.id[1] = col_def->index;
|
||||||
|
snmp_oid_append(&instance->instance_oid, row_oid.id, row_oid.len);
|
||||||
|
|
||||||
|
return SNMP_ERR_NOERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
s16_t
|
||||||
|
snmp_table_extract_value_from_s32ref(struct snmp_node_instance* instance, void* value)
|
||||||
|
{
|
||||||
|
s32_t *dst = (s32_t*)value;
|
||||||
|
*dst = instance->reference.s32;
|
||||||
|
return sizeof(*dst);
|
||||||
|
}
|
||||||
|
|
||||||
|
s16_t
|
||||||
|
snmp_table_extract_value_from_u32ref(struct snmp_node_instance* instance, void* value)
|
||||||
|
{
|
||||||
|
u32_t *dst = (u32_t*)value;
|
||||||
|
*dst = instance->reference.u32;
|
||||||
|
return sizeof(*dst);
|
||||||
|
}
|
||||||
|
|
||||||
|
s16_t
|
||||||
|
snmp_table_extract_value_from_refconstptr(struct snmp_node_instance* instance, void* value)
|
||||||
|
{
|
||||||
|
MEMCPY(value, instance->reference.const_ptr, instance->reference_len);
|
||||||
|
return (u16_t)instance->reference_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* LWIP_SNMP */
|
|
@ -0,0 +1,219 @@
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* SNMP thread synchronization implementation.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||||
|
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||||
|
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
|
* OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* Author: Dirk Ziegelmeier <dziegel@gmx.de>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "lwip/apps/snmp_opts.h"
|
||||||
|
|
||||||
|
#if LWIP_SNMP && (NO_SYS == 0) /* don't build if not configured for use in lwipopts.h */
|
||||||
|
|
||||||
|
#include "lwip/apps/snmp_threadsync.h"
|
||||||
|
#include "lwip/apps/snmp_core.h"
|
||||||
|
#include "lwip/sys.h"
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
static void
|
||||||
|
call_synced_function(struct threadsync_data *call_data, snmp_threadsync_called_fn fn)
|
||||||
|
{
|
||||||
|
sys_mutex_lock(&call_data->threadsync_node->instance->sem_usage_mutex);
|
||||||
|
call_data->threadsync_node->instance->sync_fn(fn, call_data);
|
||||||
|
sys_sem_wait(&call_data->threadsync_node->instance->sem);
|
||||||
|
sys_mutex_unlock(&call_data->threadsync_node->instance->sem_usage_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
threadsync_get_value_synced(void *ctx)
|
||||||
|
{
|
||||||
|
struct threadsync_data *call_data = (struct threadsync_data*)ctx;
|
||||||
|
|
||||||
|
call_data->retval.s16 = call_data->proxy_instance.get_value(&call_data->proxy_instance, call_data->arg1.value);
|
||||||
|
|
||||||
|
sys_sem_signal(&call_data->threadsync_node->instance->sem);
|
||||||
|
}
|
||||||
|
|
||||||
|
static s16_t
|
||||||
|
threadsync_get_value(struct snmp_node_instance* instance, void* value)
|
||||||
|
{
|
||||||
|
struct threadsync_data *call_data = (struct threadsync_data*)instance->reference.ptr;
|
||||||
|
|
||||||
|
call_data->arg1.value = value;
|
||||||
|
call_synced_function(call_data, threadsync_get_value_synced);
|
||||||
|
|
||||||
|
return call_data->retval.s16;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
threadsync_set_test_synced(void *ctx)
|
||||||
|
{
|
||||||
|
struct threadsync_data *call_data = (struct threadsync_data*)ctx;
|
||||||
|
|
||||||
|
call_data->retval.err = call_data->proxy_instance.set_test(&call_data->proxy_instance, call_data->arg2.len, call_data->arg1.value);
|
||||||
|
|
||||||
|
sys_sem_signal(&call_data->threadsync_node->instance->sem);
|
||||||
|
}
|
||||||
|
|
||||||
|
static snmp_err_t
|
||||||
|
threadsync_set_test(struct snmp_node_instance* instance, u16_t len, void *value)
|
||||||
|
{
|
||||||
|
struct threadsync_data *call_data = (struct threadsync_data*)instance->reference.ptr;
|
||||||
|
|
||||||
|
call_data->arg1.value = value;
|
||||||
|
call_data->arg2.len = len;
|
||||||
|
call_synced_function(call_data, threadsync_set_test_synced);
|
||||||
|
|
||||||
|
return call_data->retval.err;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
threadsync_set_value_synced(void *ctx)
|
||||||
|
{
|
||||||
|
struct threadsync_data *call_data = (struct threadsync_data*)ctx;
|
||||||
|
|
||||||
|
call_data->retval.err = call_data->proxy_instance.set_value(&call_data->proxy_instance, call_data->arg2.len, call_data->arg1.value);
|
||||||
|
|
||||||
|
sys_sem_signal(&call_data->threadsync_node->instance->sem);
|
||||||
|
}
|
||||||
|
|
||||||
|
static snmp_err_t
|
||||||
|
threadsync_set_value(struct snmp_node_instance* instance, u16_t len, void *value)
|
||||||
|
{
|
||||||
|
struct threadsync_data *call_data = (struct threadsync_data*)instance->reference.ptr;
|
||||||
|
|
||||||
|
call_data->arg1.value = value;
|
||||||
|
call_data->arg2.len = len;
|
||||||
|
call_synced_function(call_data, threadsync_set_value_synced);
|
||||||
|
|
||||||
|
return call_data->retval.err;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
threadsync_release_instance_synced(void* ctx)
|
||||||
|
{
|
||||||
|
struct threadsync_data *call_data = (struct threadsync_data*)ctx;
|
||||||
|
|
||||||
|
call_data->proxy_instance.release_instance(&call_data->proxy_instance);
|
||||||
|
|
||||||
|
sys_sem_signal(&call_data->threadsync_node->instance->sem);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
threadsync_release_instance(struct snmp_node_instance *instance)
|
||||||
|
{
|
||||||
|
struct threadsync_data *call_data = (struct threadsync_data*)instance->reference.ptr;
|
||||||
|
|
||||||
|
if (call_data->proxy_instance.release_instance != NULL) {
|
||||||
|
call_synced_function(call_data, threadsync_release_instance_synced);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
get_instance_synced(void* ctx)
|
||||||
|
{
|
||||||
|
struct threadsync_data *call_data = (struct threadsync_data*)ctx;
|
||||||
|
const struct snmp_leaf_node *leaf = (const struct snmp_leaf_node*)(const void*)call_data->proxy_instance.node;
|
||||||
|
|
||||||
|
call_data->retval.err = leaf->get_instance(call_data->arg1.root_oid, call_data->arg2.root_oid_len, &call_data->proxy_instance);
|
||||||
|
|
||||||
|
sys_sem_signal(&call_data->threadsync_node->instance->sem);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
get_next_instance_synced(void* ctx)
|
||||||
|
{
|
||||||
|
struct threadsync_data *call_data = (struct threadsync_data*)ctx;
|
||||||
|
const struct snmp_leaf_node *leaf = (const struct snmp_leaf_node*)(const void*)call_data->proxy_instance.node;
|
||||||
|
|
||||||
|
call_data->retval.err = leaf->get_next_instance(call_data->arg1.root_oid, call_data->arg2.root_oid_len, &call_data->proxy_instance);
|
||||||
|
|
||||||
|
sys_sem_signal(&call_data->threadsync_node->instance->sem);
|
||||||
|
}
|
||||||
|
|
||||||
|
static snmp_err_t
|
||||||
|
do_sync(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance, snmp_threadsync_called_fn fn)
|
||||||
|
{
|
||||||
|
const struct snmp_threadsync_node *threadsync_node = (const struct snmp_threadsync_node*)(const void*)instance->node;
|
||||||
|
struct threadsync_data *call_data = &threadsync_node->instance->data;
|
||||||
|
|
||||||
|
if (threadsync_node->node.node.oid != threadsync_node->target->node.oid) {
|
||||||
|
LWIP_DEBUGF(SNMP_DEBUG, ("Sync node OID does not match target node OID"));
|
||||||
|
return SNMP_ERR_NOSUCHINSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(&call_data->proxy_instance, 0, sizeof(call_data->proxy_instance));
|
||||||
|
|
||||||
|
instance->reference.ptr = call_data;
|
||||||
|
snmp_oid_assign(&call_data->proxy_instance.instance_oid, instance->instance_oid.id, instance->instance_oid.len);
|
||||||
|
|
||||||
|
call_data->proxy_instance.node = &threadsync_node->target->node;
|
||||||
|
call_data->threadsync_node = threadsync_node;
|
||||||
|
|
||||||
|
call_data->arg1.root_oid = root_oid;
|
||||||
|
call_data->arg2.root_oid_len = root_oid_len;
|
||||||
|
call_synced_function(call_data, fn);
|
||||||
|
|
||||||
|
if (call_data->retval.err == SNMP_ERR_NOERROR) {
|
||||||
|
instance->access = call_data->proxy_instance.access;
|
||||||
|
instance->asn1_type = call_data->proxy_instance.asn1_type;
|
||||||
|
instance->release_instance = threadsync_release_instance;
|
||||||
|
instance->get_value = (call_data->proxy_instance.get_value != NULL)? threadsync_get_value : NULL;
|
||||||
|
instance->set_value = (call_data->proxy_instance.set_value != NULL)? threadsync_set_value : NULL;
|
||||||
|
instance->set_test = (call_data->proxy_instance.set_test != NULL)? threadsync_set_test : NULL;
|
||||||
|
snmp_oid_assign(&instance->instance_oid, call_data->proxy_instance.instance_oid.id, call_data->proxy_instance.instance_oid.len);
|
||||||
|
}
|
||||||
|
|
||||||
|
return call_data->retval.err;
|
||||||
|
}
|
||||||
|
|
||||||
|
snmp_err_t
|
||||||
|
snmp_threadsync_get_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance)
|
||||||
|
{
|
||||||
|
return do_sync(root_oid, root_oid_len, instance, get_instance_synced);
|
||||||
|
}
|
||||||
|
|
||||||
|
snmp_err_t
|
||||||
|
snmp_threadsync_get_next_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance)
|
||||||
|
{
|
||||||
|
return do_sync(root_oid, root_oid_len, instance, get_next_instance_synced);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Initializes thread synchronization instance */
|
||||||
|
void snmp_threadsync_init(struct snmp_threadsync_instance *instance, snmp_threadsync_synchronizer_fn sync_fn)
|
||||||
|
{
|
||||||
|
err_t err = sys_mutex_new(&instance->sem_usage_mutex);
|
||||||
|
LWIP_ASSERT("Failed to set up mutex", err == ERR_OK);
|
||||||
|
err = sys_sem_new(&instance->sem, 0);
|
||||||
|
LWIP_UNUSED_ARG(err); /* in case of LWIP_NOASSERT */
|
||||||
|
LWIP_ASSERT("Failed to set up semaphore", err == ERR_OK);
|
||||||
|
instance->sync_fn = sync_fn;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* LWIP_SNMP */
|
|
@ -0,0 +1,445 @@
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* SNMPv1 traps implementation.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||||
|
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||||
|
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
|
* OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* This file is part of the lwIP TCP/IP stack.
|
||||||
|
*
|
||||||
|
* Author: Martin Hentschel
|
||||||
|
* Christiaan Simons <christiaan.simons@axon.tv>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "lwip/apps/snmp_opts.h"
|
||||||
|
|
||||||
|
#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "lwip/snmp.h"
|
||||||
|
#include "lwip/sys.h"
|
||||||
|
#include "lwip/apps/snmp.h"
|
||||||
|
#include "lwip/apps/snmp_core.h"
|
||||||
|
#include "snmp_msg.h"
|
||||||
|
#include "snmp_asn1.h"
|
||||||
|
#include "snmp_core_priv.h"
|
||||||
|
|
||||||
|
struct snmp_msg_trap
|
||||||
|
{
|
||||||
|
/* source enterprise ID (sysObjectID) */
|
||||||
|
const struct snmp_obj_id *enterprise;
|
||||||
|
/* source IP address, raw network order format */
|
||||||
|
ip_addr_t sip;
|
||||||
|
/* generic trap code */
|
||||||
|
u32_t gen_trap;
|
||||||
|
/* specific trap code */
|
||||||
|
u32_t spc_trap;
|
||||||
|
/* timestamp */
|
||||||
|
u32_t ts;
|
||||||
|
/* snmp_version */
|
||||||
|
u32_t snmp_version;
|
||||||
|
|
||||||
|
/* output trap lengths used in ASN encoding */
|
||||||
|
/* encoding pdu length */
|
||||||
|
u16_t pdulen;
|
||||||
|
/* encoding community length */
|
||||||
|
u16_t comlen;
|
||||||
|
/* encoding sequence length */
|
||||||
|
u16_t seqlen;
|
||||||
|
/* encoding varbinds sequence length */
|
||||||
|
u16_t vbseqlen;
|
||||||
|
};
|
||||||
|
|
||||||
|
static u16_t snmp_trap_varbind_sum(struct snmp_msg_trap *trap, struct snmp_varbind *varbinds);
|
||||||
|
static u16_t snmp_trap_header_sum(struct snmp_msg_trap *trap, u16_t vb_len);
|
||||||
|
static void snmp_trap_header_enc(struct snmp_msg_trap *trap, struct snmp_pbuf_stream *pbuf_stream);
|
||||||
|
static void snmp_trap_varbind_enc(struct snmp_msg_trap *trap, struct snmp_pbuf_stream *pbuf_stream, struct snmp_varbind *varbinds);
|
||||||
|
|
||||||
|
/** Agent community string for sending traps */
|
||||||
|
extern const char *snmp_community_trap;
|
||||||
|
|
||||||
|
void* snmp_traps_handle;
|
||||||
|
|
||||||
|
struct snmp_trap_dst
|
||||||
|
{
|
||||||
|
/* destination IP address in network order */
|
||||||
|
ip_addr_t dip;
|
||||||
|
/* set to 0 when disabled, >0 when enabled */
|
||||||
|
u8_t enable;
|
||||||
|
};
|
||||||
|
static struct snmp_trap_dst trap_dst[SNMP_TRAP_DESTINATIONS];
|
||||||
|
|
||||||
|
static u8_t snmp_auth_traps_enabled = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup snmp_traps
|
||||||
|
* Sets enable switch for this trap destination.
|
||||||
|
* @param dst_idx index in 0 .. SNMP_TRAP_DESTINATIONS-1
|
||||||
|
* @param enable switch if 0 destination is disabled >0 enabled.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
snmp_trap_dst_enable(u8_t dst_idx, u8_t enable)
|
||||||
|
{
|
||||||
|
if (dst_idx < SNMP_TRAP_DESTINATIONS) {
|
||||||
|
trap_dst[dst_idx].enable = enable;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup snmp_traps
|
||||||
|
* Sets IPv4 address for this trap destination.
|
||||||
|
* @param dst_idx index in 0 .. SNMP_TRAP_DESTINATIONS-1
|
||||||
|
* @param dst IPv4 address in host order.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
snmp_trap_dst_ip_set(u8_t dst_idx, const ip_addr_t *dst)
|
||||||
|
{
|
||||||
|
if (dst_idx < SNMP_TRAP_DESTINATIONS) {
|
||||||
|
ip_addr_set(&trap_dst[dst_idx].dip, dst);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup snmp_traps
|
||||||
|
* Enable/disable authentication traps
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
snmp_set_auth_traps_enabled(u8_t enable)
|
||||||
|
{
|
||||||
|
snmp_auth_traps_enabled = enable;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup snmp_traps
|
||||||
|
* Get authentication traps enabled state
|
||||||
|
*/
|
||||||
|
u8_t
|
||||||
|
snmp_get_auth_traps_enabled(void)
|
||||||
|
{
|
||||||
|
return snmp_auth_traps_enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup snmp_traps
|
||||||
|
* Sends a generic or enterprise specific trap message.
|
||||||
|
*
|
||||||
|
* @param eoid points to enterprise object identifier
|
||||||
|
* @param generic_trap is the trap code
|
||||||
|
* @param specific_trap used for enterprise traps when generic_trap == 6
|
||||||
|
* @param varbinds linked list of varbinds to be sent
|
||||||
|
* @return ERR_OK when success, ERR_MEM if we're out of memory
|
||||||
|
*
|
||||||
|
* @note the use of the enterprise identifier field
|
||||||
|
* is per RFC1215.
|
||||||
|
* Use .iso.org.dod.internet.mgmt.mib-2.snmp for generic traps
|
||||||
|
* and .iso.org.dod.internet.private.enterprises.yourenterprise
|
||||||
|
* (sysObjectID) for specific traps.
|
||||||
|
*/
|
||||||
|
err_t
|
||||||
|
snmp_send_trap(const struct snmp_obj_id* eoid, s32_t generic_trap, s32_t specific_trap, struct snmp_varbind *varbinds)
|
||||||
|
{
|
||||||
|
struct snmp_msg_trap trap_msg;
|
||||||
|
struct snmp_trap_dst *td;
|
||||||
|
struct pbuf *p;
|
||||||
|
u16_t i, tot_len;
|
||||||
|
err_t err = ERR_OK;
|
||||||
|
|
||||||
|
trap_msg.snmp_version = 0;
|
||||||
|
|
||||||
|
for (i = 0, td = &trap_dst[0]; i < SNMP_TRAP_DESTINATIONS; i++, td++) {
|
||||||
|
if ((td->enable != 0) && !ip_addr_isany(&td->dip)) {
|
||||||
|
/* lookup current source address for this dst */
|
||||||
|
if (snmp_get_local_ip_for_dst(snmp_traps_handle, &td->dip, &trap_msg.sip)) {
|
||||||
|
if (eoid == NULL) {
|
||||||
|
trap_msg.enterprise = snmp_get_device_enterprise_oid();
|
||||||
|
} else {
|
||||||
|
trap_msg.enterprise = eoid;
|
||||||
|
}
|
||||||
|
|
||||||
|
trap_msg.gen_trap = generic_trap;
|
||||||
|
if (generic_trap == SNMP_GENTRAP_ENTERPRISE_SPECIFIC) {
|
||||||
|
trap_msg.spc_trap = specific_trap;
|
||||||
|
} else {
|
||||||
|
trap_msg.spc_trap = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
MIB2_COPY_SYSUPTIME_TO(&trap_msg.ts);
|
||||||
|
|
||||||
|
/* pass 0, calculate length fields */
|
||||||
|
tot_len = snmp_trap_varbind_sum(&trap_msg, varbinds);
|
||||||
|
tot_len = snmp_trap_header_sum(&trap_msg, tot_len);
|
||||||
|
|
||||||
|
/* allocate pbuf(s) */
|
||||||
|
p = pbuf_alloc(PBUF_TRANSPORT, tot_len, PBUF_RAM);
|
||||||
|
if (p != NULL) {
|
||||||
|
struct snmp_pbuf_stream pbuf_stream;
|
||||||
|
snmp_pbuf_stream_init(&pbuf_stream, p, 0, tot_len);
|
||||||
|
|
||||||
|
/* pass 1, encode packet ino the pbuf(s) */
|
||||||
|
snmp_trap_header_enc(&trap_msg, &pbuf_stream);
|
||||||
|
snmp_trap_varbind_enc(&trap_msg, &pbuf_stream, varbinds);
|
||||||
|
|
||||||
|
snmp_stats.outtraps++;
|
||||||
|
snmp_stats.outpkts++;
|
||||||
|
|
||||||
|
/** send to the TRAP destination */
|
||||||
|
snmp_sendto(snmp_traps_handle, p, &td->dip, SNMP_TRAP_PORT);
|
||||||
|
pbuf_free(p);
|
||||||
|
} else {
|
||||||
|
err = ERR_MEM;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* routing error */
|
||||||
|
err = ERR_RTE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup snmp_traps
|
||||||
|
* Send generic SNMP trap
|
||||||
|
*/
|
||||||
|
err_t
|
||||||
|
snmp_send_trap_generic(s32_t generic_trap)
|
||||||
|
{
|
||||||
|
static const struct snmp_obj_id oid = { 7, { 1, 3, 6, 1, 2, 1, 11 } };
|
||||||
|
return snmp_send_trap(&oid, generic_trap, 0, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup snmp_traps
|
||||||
|
* Send specific SNMP trap with variable bindings
|
||||||
|
*/
|
||||||
|
err_t
|
||||||
|
snmp_send_trap_specific(s32_t specific_trap, struct snmp_varbind *varbinds)
|
||||||
|
{
|
||||||
|
return snmp_send_trap(NULL, SNMP_GENTRAP_ENTERPRISE_SPECIFIC, specific_trap, varbinds);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup snmp_traps
|
||||||
|
* Send coldstart trap
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
snmp_coldstart_trap(void)
|
||||||
|
{
|
||||||
|
snmp_send_trap_generic(SNMP_GENTRAP_COLDSTART);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup snmp_traps
|
||||||
|
* Send authentication failure trap (used internally by agent)
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
snmp_authfail_trap(void)
|
||||||
|
{
|
||||||
|
if (snmp_auth_traps_enabled != 0) {
|
||||||
|
snmp_send_trap_generic(SNMP_GENTRAP_AUTH_FAILURE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static u16_t
|
||||||
|
snmp_trap_varbind_sum(struct snmp_msg_trap *trap, struct snmp_varbind *varbinds)
|
||||||
|
{
|
||||||
|
struct snmp_varbind *varbind;
|
||||||
|
u16_t tot_len;
|
||||||
|
u8_t tot_len_len;
|
||||||
|
|
||||||
|
tot_len = 0;
|
||||||
|
varbind = varbinds;
|
||||||
|
while (varbind != NULL) {
|
||||||
|
struct snmp_varbind_len len;
|
||||||
|
|
||||||
|
if (snmp_varbind_length(varbind, &len) == ERR_OK) {
|
||||||
|
tot_len += 1 + len.vb_len_len + len.vb_value_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
varbind = varbind->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
trap->vbseqlen = tot_len;
|
||||||
|
snmp_asn1_enc_length_cnt(trap->vbseqlen, &tot_len_len);
|
||||||
|
tot_len += 1 + tot_len_len;
|
||||||
|
|
||||||
|
return tot_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sums trap header field lengths from tail to head and
|
||||||
|
* returns trap_header_lengths for second encoding pass.
|
||||||
|
*
|
||||||
|
* @param trap Trap message
|
||||||
|
* @param vb_len varbind-list length
|
||||||
|
* @return the required length for encoding the trap header
|
||||||
|
*/
|
||||||
|
static u16_t
|
||||||
|
snmp_trap_header_sum(struct snmp_msg_trap *trap, u16_t vb_len)
|
||||||
|
{
|
||||||
|
u16_t tot_len;
|
||||||
|
u16_t len;
|
||||||
|
u8_t lenlen;
|
||||||
|
|
||||||
|
tot_len = vb_len;
|
||||||
|
|
||||||
|
snmp_asn1_enc_u32t_cnt(trap->ts, &len);
|
||||||
|
snmp_asn1_enc_length_cnt(len, &lenlen);
|
||||||
|
tot_len += 1 + len + lenlen;
|
||||||
|
|
||||||
|
snmp_asn1_enc_s32t_cnt(trap->spc_trap, &len);
|
||||||
|
snmp_asn1_enc_length_cnt(len, &lenlen);
|
||||||
|
tot_len += 1 + len + lenlen;
|
||||||
|
|
||||||
|
snmp_asn1_enc_s32t_cnt(trap->gen_trap, &len);
|
||||||
|
snmp_asn1_enc_length_cnt(len, &lenlen);
|
||||||
|
tot_len += 1 + len + lenlen;
|
||||||
|
|
||||||
|
if (IP_IS_V6_VAL(trap->sip)) {
|
||||||
|
#if LWIP_IPV6
|
||||||
|
len = sizeof(ip_2_ip6(&trap->sip)->addr);
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
#if LWIP_IPV4
|
||||||
|
len = sizeof(ip_2_ip4(&trap->sip)->addr);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
snmp_asn1_enc_length_cnt(len, &lenlen);
|
||||||
|
tot_len += 1 + len + lenlen;
|
||||||
|
|
||||||
|
snmp_asn1_enc_oid_cnt(trap->enterprise->id, trap->enterprise->len, &len);
|
||||||
|
snmp_asn1_enc_length_cnt(len, &lenlen);
|
||||||
|
tot_len += 1 + len + lenlen;
|
||||||
|
|
||||||
|
trap->pdulen = tot_len;
|
||||||
|
snmp_asn1_enc_length_cnt(trap->pdulen, &lenlen);
|
||||||
|
tot_len += 1 + lenlen;
|
||||||
|
|
||||||
|
trap->comlen = (u16_t)LWIP_MIN(strlen(snmp_community_trap), 0xFFFF);
|
||||||
|
snmp_asn1_enc_length_cnt(trap->comlen, &lenlen);
|
||||||
|
tot_len += 1 + lenlen + trap->comlen;
|
||||||
|
|
||||||
|
snmp_asn1_enc_s32t_cnt(trap->snmp_version, &len);
|
||||||
|
snmp_asn1_enc_length_cnt(len, &lenlen);
|
||||||
|
tot_len += 1 + len + lenlen;
|
||||||
|
|
||||||
|
trap->seqlen = tot_len;
|
||||||
|
snmp_asn1_enc_length_cnt(trap->seqlen, &lenlen);
|
||||||
|
tot_len += 1 + lenlen;
|
||||||
|
|
||||||
|
return tot_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
snmp_trap_varbind_enc(struct snmp_msg_trap *trap, struct snmp_pbuf_stream *pbuf_stream, struct snmp_varbind *varbinds)
|
||||||
|
{
|
||||||
|
struct snmp_asn1_tlv tlv;
|
||||||
|
struct snmp_varbind *varbind;
|
||||||
|
|
||||||
|
varbind = varbinds;
|
||||||
|
|
||||||
|
SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_SEQUENCE, 0, trap->vbseqlen);
|
||||||
|
snmp_ans1_enc_tlv(pbuf_stream, &tlv);
|
||||||
|
|
||||||
|
while (varbind != NULL) {
|
||||||
|
snmp_append_outbound_varbind(pbuf_stream, varbind);
|
||||||
|
|
||||||
|
varbind = varbind->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encodes trap header from head to tail.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
snmp_trap_header_enc(struct snmp_msg_trap *trap, struct snmp_pbuf_stream *pbuf_stream)
|
||||||
|
{
|
||||||
|
struct snmp_asn1_tlv tlv;
|
||||||
|
|
||||||
|
/* 'Message' sequence */
|
||||||
|
SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_SEQUENCE, 0, trap->seqlen);
|
||||||
|
snmp_ans1_enc_tlv(pbuf_stream, &tlv);
|
||||||
|
|
||||||
|
/* version */
|
||||||
|
SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_INTEGER, 0, 0);
|
||||||
|
snmp_asn1_enc_s32t_cnt(trap->snmp_version, &tlv.value_len);
|
||||||
|
snmp_ans1_enc_tlv(pbuf_stream, &tlv);
|
||||||
|
snmp_asn1_enc_s32t(pbuf_stream, tlv.value_len, trap->snmp_version);
|
||||||
|
|
||||||
|
/* community */
|
||||||
|
SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_OCTET_STRING, 0, trap->comlen);
|
||||||
|
snmp_ans1_enc_tlv(pbuf_stream, &tlv);
|
||||||
|
snmp_asn1_enc_raw(pbuf_stream, (const u8_t *)snmp_community_trap, trap->comlen);
|
||||||
|
|
||||||
|
/* 'PDU' sequence */
|
||||||
|
SNMP_ASN1_SET_TLV_PARAMS(tlv, (SNMP_ASN1_CLASS_CONTEXT | SNMP_ASN1_CONTENTTYPE_CONSTRUCTED | SNMP_ASN1_CONTEXT_PDU_TRAP), 0, trap->pdulen);
|
||||||
|
snmp_ans1_enc_tlv(pbuf_stream, &tlv);
|
||||||
|
|
||||||
|
/* object ID */
|
||||||
|
SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_OBJECT_ID, 0, 0);
|
||||||
|
snmp_asn1_enc_oid_cnt(trap->enterprise->id, trap->enterprise->len, &tlv.value_len);
|
||||||
|
snmp_ans1_enc_tlv(pbuf_stream, &tlv);
|
||||||
|
snmp_asn1_enc_oid(pbuf_stream, trap->enterprise->id, trap->enterprise->len);
|
||||||
|
|
||||||
|
/* IP addr */
|
||||||
|
if (IP_IS_V6_VAL(trap->sip)) {
|
||||||
|
#if LWIP_IPV6
|
||||||
|
SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_IPADDR, 0, sizeof(ip_2_ip6(&trap->sip)->addr));
|
||||||
|
snmp_ans1_enc_tlv(pbuf_stream, &tlv);
|
||||||
|
snmp_asn1_enc_raw(pbuf_stream, (const u8_t *)&ip_2_ip6(&trap->sip)->addr, sizeof(ip_2_ip6(&trap->sip)->addr));
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
#if LWIP_IPV4
|
||||||
|
SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_IPADDR, 0, sizeof(ip_2_ip4(&trap->sip)->addr));
|
||||||
|
snmp_ans1_enc_tlv(pbuf_stream, &tlv);
|
||||||
|
snmp_asn1_enc_raw(pbuf_stream, (const u8_t *)&ip_2_ip4(&trap->sip)->addr, sizeof(ip_2_ip4(&trap->sip)->addr));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/* trap length */
|
||||||
|
SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_INTEGER, 0, 0);
|
||||||
|
snmp_asn1_enc_s32t_cnt(trap->gen_trap, &tlv.value_len);
|
||||||
|
snmp_ans1_enc_tlv(pbuf_stream, &tlv);
|
||||||
|
snmp_asn1_enc_s32t(pbuf_stream, tlv.value_len, trap->gen_trap);
|
||||||
|
|
||||||
|
/* specific trap */
|
||||||
|
SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_INTEGER, 0, 0);
|
||||||
|
snmp_asn1_enc_s32t_cnt(trap->spc_trap, &tlv.value_len);
|
||||||
|
snmp_ans1_enc_tlv(pbuf_stream, &tlv);
|
||||||
|
snmp_asn1_enc_s32t(pbuf_stream, tlv.value_len, trap->spc_trap);
|
||||||
|
|
||||||
|
/* timestamp */
|
||||||
|
SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_TIMETICKS, 0, 0);
|
||||||
|
snmp_asn1_enc_s32t_cnt(trap->ts, &tlv.value_len);
|
||||||
|
snmp_ans1_enc_tlv(pbuf_stream, &tlv);
|
||||||
|
snmp_asn1_enc_s32t(pbuf_stream, tlv.value_len, trap->ts);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* LWIP_SNMP */
|
|
@ -0,0 +1,136 @@
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* Additional SNMPv3 functionality RFC3414 and RFC3826.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2016 Elias Oenal.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||||
|
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||||
|
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
|
* OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* Author: Elias Oenal <lwip@eliasoenal.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "snmpv3_priv.h"
|
||||||
|
#include "lwip/apps/snmpv3.h"
|
||||||
|
#include "lwip/sys.h"
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#if LWIP_SNMP && LWIP_SNMP_V3
|
||||||
|
|
||||||
|
#ifdef LWIP_SNMPV3_INCLUDE_ENGINE
|
||||||
|
#include LWIP_SNMPV3_INCLUDE_ENGINE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define SNMP_MAX_TIME_BOOT 2147483647UL
|
||||||
|
|
||||||
|
/** Call this if engine has been changed. Has to reset boots, see below */
|
||||||
|
void
|
||||||
|
snmpv3_engine_id_changed(void)
|
||||||
|
{
|
||||||
|
snmpv3_set_engine_boots(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** According to RFC3414 2.2.2.
|
||||||
|
*
|
||||||
|
* The number of times that the SNMP engine has
|
||||||
|
* (re-)initialized itself since snmpEngineID
|
||||||
|
* was last configured.
|
||||||
|
*/
|
||||||
|
u32_t
|
||||||
|
snmpv3_get_engine_boots_internal(void)
|
||||||
|
{
|
||||||
|
if (snmpv3_get_engine_boots() == 0 ||
|
||||||
|
snmpv3_get_engine_boots() < SNMP_MAX_TIME_BOOT) {
|
||||||
|
return snmpv3_get_engine_boots();
|
||||||
|
}
|
||||||
|
|
||||||
|
snmpv3_set_engine_boots(SNMP_MAX_TIME_BOOT);
|
||||||
|
return snmpv3_get_engine_boots();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** RFC3414 2.2.2.
|
||||||
|
*
|
||||||
|
* Once the timer reaches 2147483647 it gets reset to zero and the
|
||||||
|
* engine boot ups get incremented.
|
||||||
|
*/
|
||||||
|
u32_t
|
||||||
|
snmpv3_get_engine_time_internal(void)
|
||||||
|
{
|
||||||
|
if (snmpv3_get_engine_time() >= SNMP_MAX_TIME_BOOT) {
|
||||||
|
snmpv3_reset_engine_time();
|
||||||
|
|
||||||
|
if (snmpv3_get_engine_boots() < SNMP_MAX_TIME_BOOT - 1) {
|
||||||
|
snmpv3_set_engine_boots(snmpv3_get_engine_boots() + 1);
|
||||||
|
} else {
|
||||||
|
snmpv3_set_engine_boots(SNMP_MAX_TIME_BOOT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return snmpv3_get_engine_time();
|
||||||
|
}
|
||||||
|
|
||||||
|
#if LWIP_SNMP_V3_CRYPTO
|
||||||
|
|
||||||
|
/* This function ignores the byte order suggestion in RFC3414
|
||||||
|
* since it simply doesn't influence the effectiveness of an IV.
|
||||||
|
*
|
||||||
|
* Implementing RFC3826 priv param algorithm if LWIP_RAND is available.
|
||||||
|
*
|
||||||
|
* @todo: This is a potential thread safety issue.
|
||||||
|
*/
|
||||||
|
err_t
|
||||||
|
snmpv3_build_priv_param(u8_t* priv_param)
|
||||||
|
{
|
||||||
|
#ifdef LWIP_RAND /* Based on RFC3826 */
|
||||||
|
static u8_t init;
|
||||||
|
static u32_t priv1, priv2;
|
||||||
|
|
||||||
|
/* Lazy initialisation */
|
||||||
|
if (init == 0) {
|
||||||
|
init = 1;
|
||||||
|
priv1 = LWIP_RAND();
|
||||||
|
priv2 = LWIP_RAND();
|
||||||
|
}
|
||||||
|
|
||||||
|
SMEMCPY(&priv_param[0], &priv1, sizeof(priv1));
|
||||||
|
SMEMCPY(&priv_param[4], &priv2, sizeof(priv2));
|
||||||
|
|
||||||
|
/* Emulate 64bit increment */
|
||||||
|
priv1++;
|
||||||
|
if (!priv1) { /* Overflow */
|
||||||
|
priv2++;
|
||||||
|
}
|
||||||
|
#else /* Based on RFC3414 */
|
||||||
|
static u32_t ctr;
|
||||||
|
u32_t boots = LWIP_SNMPV3_GET_ENGINE_BOOTS();
|
||||||
|
SMEMCPY(&priv_param[0], &boots, 4);
|
||||||
|
SMEMCPY(&priv_param[4], &ctr, 4);
|
||||||
|
ctr++;
|
||||||
|
#endif
|
||||||
|
return ERR_OK;
|
||||||
|
}
|
||||||
|
#endif /* LWIP_SNMP_V3_CRYPTO */
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,145 @@
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* Dummy SNMPv3 functions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2016 Elias Oenal.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||||
|
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||||
|
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
|
* OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* Author: Elias Oenal <lwip@eliasoenal.com>
|
||||||
|
* Dirk Ziegelmeier <dirk@ziegelmeier.net>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "lwip/apps/snmpv3.h"
|
||||||
|
#include "snmpv3_priv.h"
|
||||||
|
#include <string.h>
|
||||||
|
#include "lwip/err.h"
|
||||||
|
|
||||||
|
#if LWIP_SNMP && LWIP_SNMP_V3
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param username is a pointer to a string.
|
||||||
|
* @param auth_algo is a pointer to u8_t. The implementation has to set this if user was found.
|
||||||
|
* @param auth_key is a pointer to a pointer to a string. Implementation has to set this if user was found.
|
||||||
|
* @param priv_algo is a pointer to u8_t. The implementation has to set this if user was found.
|
||||||
|
* @param priv_key is a pointer to a pointer to a string. Implementation has to set this if user was found.
|
||||||
|
*/
|
||||||
|
err_t
|
||||||
|
snmpv3_get_user(const char* username, u8_t *auth_algo, u8_t *auth_key, u8_t *priv_algo, u8_t *priv_key)
|
||||||
|
{
|
||||||
|
const char* engine_id;
|
||||||
|
u8_t engine_id_len;
|
||||||
|
|
||||||
|
if(strlen(username) == 0) {
|
||||||
|
return ERR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(memcmp(username, "lwip", 4) != 0) {
|
||||||
|
return ERR_VAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
snmpv3_get_engine_id(&engine_id, &engine_id_len);
|
||||||
|
|
||||||
|
if(auth_key != NULL) {
|
||||||
|
snmpv3_password_to_key_sha((const u8_t*)"maplesyrup", 10,
|
||||||
|
(const u8_t*)engine_id, engine_id_len,
|
||||||
|
auth_key);
|
||||||
|
*auth_algo = SNMP_V3_AUTH_ALGO_SHA;
|
||||||
|
}
|
||||||
|
if(priv_key != NULL) {
|
||||||
|
snmpv3_password_to_key_sha((const u8_t*)"maplesyrup", 10,
|
||||||
|
(const u8_t*)engine_id, engine_id_len,
|
||||||
|
priv_key);
|
||||||
|
*priv_algo = SNMP_V3_PRIV_ALGO_DES;
|
||||||
|
}
|
||||||
|
return ERR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get engine ID from persistence
|
||||||
|
* @param id
|
||||||
|
* @param len
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
snmpv3_get_engine_id(const char **id, u8_t *len)
|
||||||
|
{
|
||||||
|
*id = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02";
|
||||||
|
*len = 12;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store engine ID in persistence
|
||||||
|
* @param id
|
||||||
|
* @param len
|
||||||
|
*/
|
||||||
|
err_t
|
||||||
|
snmpv3_set_engine_id(const char *id, u8_t len)
|
||||||
|
{
|
||||||
|
LWIP_UNUSED_ARG(id);
|
||||||
|
LWIP_UNUSED_ARG(len);
|
||||||
|
return ERR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get engine boots from persistence. Must be increased on each boot.
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
u32_t
|
||||||
|
snmpv3_get_engine_boots(void)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store engine boots in persistence
|
||||||
|
* @param boots
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
snmpv3_set_engine_boots(u32_t boots)
|
||||||
|
{
|
||||||
|
LWIP_UNUSED_ARG(boots);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* RFC3414 2.2.2.
|
||||||
|
* Once the timer reaches 2147483647 it gets reset to zero and the
|
||||||
|
* engine boot ups get incremented.
|
||||||
|
*/
|
||||||
|
u32_t
|
||||||
|
snmpv3_get_engine_time(void)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reset current engine time to 0
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
snmpv3_reset_engine_time(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* LWIP_SNMP && LWIP_SNMP_V3 */
|
|
@ -0,0 +1,331 @@
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* SNMPv3 crypto/auth functions implemented for ARM mbedtls.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2016 Elias Oenal and Dirk Ziegelmeier.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||||
|
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||||
|
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
|
* OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* Author: Elias Oenal <lwip@eliasoenal.com>
|
||||||
|
* Dirk Ziegelmeier <dirk@ziegelmeier.net>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "lwip/apps/snmpv3.h"
|
||||||
|
#include "snmpv3_priv.h"
|
||||||
|
#include "lwip/arch.h"
|
||||||
|
#include "snmp_msg.h"
|
||||||
|
#include "lwip/sys.h"
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#if LWIP_SNMP && LWIP_SNMP_V3 && LWIP_SNMP_V3_MBEDTLS
|
||||||
|
|
||||||
|
#include "mbedtls/md.h"
|
||||||
|
#include "mbedtls/cipher.h"
|
||||||
|
|
||||||
|
#include "mbedtls/md5.h"
|
||||||
|
#include "mbedtls/sha1.h"
|
||||||
|
|
||||||
|
err_t
|
||||||
|
snmpv3_auth(struct snmp_pbuf_stream* stream, u16_t length,
|
||||||
|
const u8_t* key, u8_t algo, u8_t* hmac_out)
|
||||||
|
{
|
||||||
|
u32_t i;
|
||||||
|
u8_t key_len;
|
||||||
|
const mbedtls_md_info_t *md_info;
|
||||||
|
mbedtls_md_context_t ctx;
|
||||||
|
struct snmp_pbuf_stream read_stream;
|
||||||
|
snmp_pbuf_stream_init(&read_stream, stream->pbuf, stream->offset, stream->length);
|
||||||
|
|
||||||
|
if (algo == SNMP_V3_AUTH_ALGO_MD5) {
|
||||||
|
md_info = mbedtls_md_info_from_type(MBEDTLS_MD_MD5);
|
||||||
|
key_len = SNMP_V3_MD5_LEN;
|
||||||
|
} else if (algo == SNMP_V3_AUTH_ALGO_SHA) {
|
||||||
|
md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA1);
|
||||||
|
key_len = SNMP_V3_SHA_LEN;
|
||||||
|
} else {
|
||||||
|
return ERR_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
mbedtls_md_init(&ctx);
|
||||||
|
if(mbedtls_md_setup(&ctx, md_info, 1) != 0) {
|
||||||
|
return ERR_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mbedtls_md_hmac_starts(&ctx, key, key_len) != 0) {
|
||||||
|
goto free_md;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < length; i++) {
|
||||||
|
u8_t byte;
|
||||||
|
|
||||||
|
if (snmp_pbuf_stream_read(&read_stream, &byte)) {
|
||||||
|
goto free_md;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mbedtls_md_hmac_update(&ctx, &byte, 1) != 0) {
|
||||||
|
goto free_md;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mbedtls_md_hmac_finish(&ctx, hmac_out) != 0) {
|
||||||
|
goto free_md;
|
||||||
|
}
|
||||||
|
|
||||||
|
mbedtls_md_free(&ctx);
|
||||||
|
return ERR_OK;
|
||||||
|
|
||||||
|
free_md:
|
||||||
|
mbedtls_md_free(&ctx);
|
||||||
|
return ERR_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if LWIP_SNMP_V3_CRYPTO
|
||||||
|
|
||||||
|
err_t
|
||||||
|
snmpv3_crypt(struct snmp_pbuf_stream* stream, u16_t length,
|
||||||
|
const u8_t* key, const u8_t* priv_param, const u32_t engine_boots,
|
||||||
|
const u32_t engine_time, u8_t algo, u8_t mode)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
mbedtls_cipher_context_t ctx;
|
||||||
|
const mbedtls_cipher_info_t *cipher_info;
|
||||||
|
|
||||||
|
struct snmp_pbuf_stream read_stream;
|
||||||
|
struct snmp_pbuf_stream write_stream;
|
||||||
|
snmp_pbuf_stream_init(&read_stream, stream->pbuf, stream->offset, stream->length);
|
||||||
|
snmp_pbuf_stream_init(&write_stream, stream->pbuf, stream->offset, stream->length);
|
||||||
|
mbedtls_cipher_init(&ctx);
|
||||||
|
|
||||||
|
if (algo == SNMP_V3_PRIV_ALGO_DES) {
|
||||||
|
u8_t iv_local[8];
|
||||||
|
u8_t out_bytes[8];
|
||||||
|
size_t out_len;
|
||||||
|
|
||||||
|
/* RFC 3414 mandates padding for DES */
|
||||||
|
if ((length & 0x07) != 0) {
|
||||||
|
return ERR_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
cipher_info = mbedtls_cipher_info_from_type(MBEDTLS_CIPHER_DES_CBC);
|
||||||
|
if(mbedtls_cipher_setup(&ctx, cipher_info) != 0) {
|
||||||
|
return ERR_ARG;
|
||||||
|
}
|
||||||
|
if(mbedtls_cipher_set_padding_mode(&ctx, MBEDTLS_PADDING_NONE) != 0) {
|
||||||
|
return ERR_ARG;
|
||||||
|
}
|
||||||
|
if(mbedtls_cipher_setkey(&ctx, key, 8*8, (mode == SNMP_V3_PRIV_MODE_ENCRYPT)? MBEDTLS_ENCRYPT : MBEDTLS_DECRYPT) != 0) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Prepare IV */
|
||||||
|
for (i = 0; i < LWIP_ARRAYSIZE(iv_local); i++) {
|
||||||
|
iv_local[i] = priv_param[i] ^ key[i + 8];
|
||||||
|
}
|
||||||
|
if(mbedtls_cipher_set_iv(&ctx, iv_local, LWIP_ARRAYSIZE(iv_local)) != 0) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < length; i += 8) {
|
||||||
|
size_t j;
|
||||||
|
u8_t in_bytes[8];
|
||||||
|
out_len = LWIP_ARRAYSIZE(out_bytes) ;
|
||||||
|
|
||||||
|
for (j = 0; j < LWIP_ARRAYSIZE(in_bytes); j++) {
|
||||||
|
snmp_pbuf_stream_read(&read_stream, &in_bytes[j]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(mbedtls_cipher_update(&ctx, in_bytes, LWIP_ARRAYSIZE(in_bytes), out_bytes, &out_len) != 0) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
snmp_pbuf_stream_writebuf(&write_stream, out_bytes, out_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
out_len = LWIP_ARRAYSIZE(out_bytes);
|
||||||
|
if(mbedtls_cipher_finish(&ctx, out_bytes, &out_len) != 0) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
snmp_pbuf_stream_writebuf(&write_stream, out_bytes, out_len);
|
||||||
|
} else if (algo == SNMP_V3_PRIV_ALGO_AES) {
|
||||||
|
u8_t iv_local[16];
|
||||||
|
|
||||||
|
cipher_info = mbedtls_cipher_info_from_type(MBEDTLS_CIPHER_AES_128_CFB128);
|
||||||
|
if(mbedtls_cipher_setup(&ctx, cipher_info) != 0) {
|
||||||
|
return ERR_ARG;
|
||||||
|
}
|
||||||
|
if(mbedtls_cipher_setkey(&ctx, key, 16*8, (mode == SNMP_V3_PRIV_MODE_ENCRYPT)? MBEDTLS_ENCRYPT : MBEDTLS_DECRYPT) != 0) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* IV is the big endian concatenation of boots,
|
||||||
|
* uptime and priv param - see RFC3826.
|
||||||
|
*/
|
||||||
|
iv_local[0 + 0] = (engine_boots >> 24) & 0xFF;
|
||||||
|
iv_local[0 + 1] = (engine_boots >> 16) & 0xFF;
|
||||||
|
iv_local[0 + 2] = (engine_boots >> 8) & 0xFF;
|
||||||
|
iv_local[0 + 3] = (engine_boots >> 0) & 0xFF;
|
||||||
|
iv_local[4 + 0] = (engine_time >> 24) & 0xFF;
|
||||||
|
iv_local[4 + 1] = (engine_time >> 16) & 0xFF;
|
||||||
|
iv_local[4 + 2] = (engine_time >> 8) & 0xFF;
|
||||||
|
iv_local[4 + 3] = (engine_time >> 0) & 0xFF;
|
||||||
|
SMEMCPY(iv_local + 8, priv_param, 8);
|
||||||
|
if(mbedtls_cipher_set_iv(&ctx, iv_local, LWIP_ARRAYSIZE(iv_local)) != 0) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < length; i++) {
|
||||||
|
u8_t in_byte;
|
||||||
|
u8_t out_byte;
|
||||||
|
size_t out_len = sizeof(out_byte);
|
||||||
|
|
||||||
|
snmp_pbuf_stream_read(&read_stream, &in_byte);
|
||||||
|
if(mbedtls_cipher_update(&ctx, &in_byte, sizeof(in_byte), &out_byte, &out_len) != 0) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
snmp_pbuf_stream_write(&write_stream, out_byte);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return ERR_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
mbedtls_cipher_free(&ctx);
|
||||||
|
return ERR_OK;
|
||||||
|
|
||||||
|
error:
|
||||||
|
mbedtls_cipher_free(&ctx);
|
||||||
|
return ERR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* LWIP_SNMP_V3_CRYPTO */
|
||||||
|
|
||||||
|
/* A.2.1. Password to Key Sample Code for MD5 */
|
||||||
|
void
|
||||||
|
snmpv3_password_to_key_md5(
|
||||||
|
const u8_t *password, /* IN */
|
||||||
|
u8_t passwordlen, /* IN */
|
||||||
|
const u8_t *engineID, /* IN - pointer to snmpEngineID */
|
||||||
|
u8_t engineLength,/* IN - length of snmpEngineID */
|
||||||
|
u8_t *key) /* OUT - pointer to caller 16-octet buffer */
|
||||||
|
{
|
||||||
|
mbedtls_md5_context MD;
|
||||||
|
u8_t *cp, password_buf[64];
|
||||||
|
u32_t password_index = 0;
|
||||||
|
u8_t i;
|
||||||
|
u32_t count = 0;
|
||||||
|
|
||||||
|
mbedtls_md5_init(&MD); /* initialize MD5 */
|
||||||
|
mbedtls_md5_starts(&MD);
|
||||||
|
|
||||||
|
/**********************************************/
|
||||||
|
/* Use while loop until we've done 1 Megabyte */
|
||||||
|
/**********************************************/
|
||||||
|
while (count < 1048576) {
|
||||||
|
cp = password_buf;
|
||||||
|
for (i = 0; i < 64; i++) {
|
||||||
|
/*************************************************/
|
||||||
|
/* Take the next octet of the password, wrapping */
|
||||||
|
/* to the beginning of the password as necessary.*/
|
||||||
|
/*************************************************/
|
||||||
|
*cp++ = password[password_index++ % passwordlen];
|
||||||
|
}
|
||||||
|
mbedtls_md5_update(&MD, password_buf, 64);
|
||||||
|
count += 64;
|
||||||
|
}
|
||||||
|
mbedtls_md5_finish(&MD, key); /* tell MD5 we're done */
|
||||||
|
|
||||||
|
/*****************************************************/
|
||||||
|
/* Now localize the key with the engineID and pass */
|
||||||
|
/* through MD5 to produce final key */
|
||||||
|
/* May want to ensure that engineLength <= 32, */
|
||||||
|
/* otherwise need to use a buffer larger than 64 */
|
||||||
|
/*****************************************************/
|
||||||
|
SMEMCPY(password_buf, key, 16);
|
||||||
|
MEMCPY(password_buf + 16, engineID, engineLength);
|
||||||
|
SMEMCPY(password_buf + 16 + engineLength, key, 16);
|
||||||
|
|
||||||
|
mbedtls_md5_starts(&MD);
|
||||||
|
mbedtls_md5_update(&MD, password_buf, 32 + engineLength);
|
||||||
|
mbedtls_md5_finish(&MD, key);
|
||||||
|
|
||||||
|
mbedtls_md5_free(&MD);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* A.2.2. Password to Key Sample Code for SHA */
|
||||||
|
void
|
||||||
|
snmpv3_password_to_key_sha(
|
||||||
|
const u8_t *password, /* IN */
|
||||||
|
u8_t passwordlen, /* IN */
|
||||||
|
const u8_t *engineID, /* IN - pointer to snmpEngineID */
|
||||||
|
u8_t engineLength,/* IN - length of snmpEngineID */
|
||||||
|
u8_t *key) /* OUT - pointer to caller 20-octet buffer */
|
||||||
|
{
|
||||||
|
mbedtls_sha1_context SH;
|
||||||
|
u8_t *cp, password_buf[72];
|
||||||
|
u32_t password_index = 0;
|
||||||
|
u8_t i;
|
||||||
|
u32_t count = 0;
|
||||||
|
|
||||||
|
mbedtls_sha1_init(&SH); /* initialize SHA */
|
||||||
|
mbedtls_sha1_starts(&SH);
|
||||||
|
|
||||||
|
/**********************************************/
|
||||||
|
/* Use while loop until we've done 1 Megabyte */
|
||||||
|
/**********************************************/
|
||||||
|
while (count < 1048576) {
|
||||||
|
cp = password_buf;
|
||||||
|
for (i = 0; i < 64; i++) {
|
||||||
|
/*************************************************/
|
||||||
|
/* Take the next octet of the password, wrapping */
|
||||||
|
/* to the beginning of the password as necessary.*/
|
||||||
|
/*************************************************/
|
||||||
|
*cp++ = password[password_index++ % passwordlen];
|
||||||
|
}
|
||||||
|
mbedtls_sha1_update(&SH, password_buf, 64);
|
||||||
|
count += 64;
|
||||||
|
}
|
||||||
|
mbedtls_sha1_finish(&SH, key); /* tell SHA we're done */
|
||||||
|
|
||||||
|
/*****************************************************/
|
||||||
|
/* Now localize the key with the engineID and pass */
|
||||||
|
/* through SHA to produce final key */
|
||||||
|
/* May want to ensure that engineLength <= 32, */
|
||||||
|
/* otherwise need to use a buffer larger than 72 */
|
||||||
|
/*****************************************************/
|
||||||
|
SMEMCPY(password_buf, key, 20);
|
||||||
|
MEMCPY(password_buf + 20, engineID, engineLength);
|
||||||
|
SMEMCPY(password_buf + 20 + engineLength, key, 20);
|
||||||
|
|
||||||
|
mbedtls_sha1_starts(&SH);
|
||||||
|
mbedtls_sha1_update(&SH, password_buf, 40 + engineLength);
|
||||||
|
mbedtls_sha1_finish(&SH, key);
|
||||||
|
|
||||||
|
mbedtls_sha1_free(&SH);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* LWIP_SNMP && LWIP_SNMP_V3 && LWIP_SNMP_V3_MBEDTLS */
|
|
@ -0,0 +1,66 @@
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* Additional SNMPv3 functionality RFC3414 and RFC3826 (internal API, do not use in client code).
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2016 Elias Oenal.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||||
|
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||||
|
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
|
* OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* Author: Elias Oenal <lwip@eliasoenal.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef LWIP_HDR_APPS_SNMP_V3_PRIV_H
|
||||||
|
#define LWIP_HDR_APPS_SNMP_V3_PRIV_H
|
||||||
|
|
||||||
|
#include "lwip/apps/snmp_opts.h"
|
||||||
|
|
||||||
|
#if LWIP_SNMP && LWIP_SNMP_V3
|
||||||
|
|
||||||
|
#include "snmp_pbuf_stream.h"
|
||||||
|
|
||||||
|
/* According to RFC 3411 */
|
||||||
|
#define SNMP_V3_MAX_ENGINE_ID_LENGTH 32
|
||||||
|
#define SNMP_V3_MAX_USER_LENGTH 32
|
||||||
|
|
||||||
|
#define SNMP_V3_MAX_AUTH_PARAM_LENGTH 12
|
||||||
|
#define SNMP_V3_MAX_PRIV_PARAM_LENGTH 8
|
||||||
|
|
||||||
|
#define SNMP_V3_AUTH_FLAG 0x01
|
||||||
|
#define SNMP_V3_PRIV_FLAG 0x02
|
||||||
|
|
||||||
|
#define SNMP_V3_MD5_LEN 16
|
||||||
|
#define SNMP_V3_SHA_LEN 20
|
||||||
|
|
||||||
|
u32_t snmpv3_get_engine_boots_internal(void);
|
||||||
|
u32_t snmpv3_get_engine_time_internal(void);
|
||||||
|
err_t snmpv3_auth(struct snmp_pbuf_stream* stream, u16_t length, const u8_t* key, u8_t algo, u8_t* hmac_out);
|
||||||
|
err_t snmpv3_crypt(struct snmp_pbuf_stream* stream, u16_t length, const u8_t* key,
|
||||||
|
const u8_t* priv_param, const u32_t engine_boots, const u32_t engine_time, u8_t algo, u8_t mode);
|
||||||
|
err_t snmpv3_build_priv_param(u8_t* priv_param);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* LWIP_HDR_APPS_SNMP_V3_PRIV_H */
|
|
@ -0,0 +1,727 @@
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* SNTP client module
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2007-2009 Frédéric Bernon, Simon Goldschmidt
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||||
|
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||||
|
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
|
* OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* This file is part of the lwIP TCP/IP stack.
|
||||||
|
*
|
||||||
|
* Author: Frédéric Bernon, Simon Goldschmidt
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @defgroup sntp SNTP
|
||||||
|
* @ingroup apps
|
||||||
|
*
|
||||||
|
* This is simple "SNTP" client for the lwIP raw API.
|
||||||
|
* It is a minimal implementation of SNTPv4 as specified in RFC 4330.
|
||||||
|
*
|
||||||
|
* For a list of some public NTP servers, see this link :
|
||||||
|
* http://support.ntp.org/bin/view/Servers/NTPPoolServers
|
||||||
|
*
|
||||||
|
* @todo:
|
||||||
|
* - set/change servers at runtime
|
||||||
|
* - complete SNTP_CHECK_RESPONSE checks 3 and 4
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "lwip/apps/sntp.h"
|
||||||
|
|
||||||
|
#include "lwip/opt.h"
|
||||||
|
#include "lwip/timeouts.h"
|
||||||
|
#include "lwip/udp.h"
|
||||||
|
#include "lwip/dns.h"
|
||||||
|
#include "lwip/ip_addr.h"
|
||||||
|
#include "lwip/pbuf.h"
|
||||||
|
#include "lwip/dhcp.h"
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
#if LWIP_UDP
|
||||||
|
|
||||||
|
/* Handle support for more than one server via SNTP_MAX_SERVERS */
|
||||||
|
#if SNTP_MAX_SERVERS > 1
|
||||||
|
#define SNTP_SUPPORT_MULTIPLE_SERVERS 1
|
||||||
|
#else /* NTP_MAX_SERVERS > 1 */
|
||||||
|
#define SNTP_SUPPORT_MULTIPLE_SERVERS 0
|
||||||
|
#endif /* NTP_MAX_SERVERS > 1 */
|
||||||
|
|
||||||
|
#if (SNTP_UPDATE_DELAY < 15000) && !defined(SNTP_SUPPRESS_DELAY_CHECK)
|
||||||
|
#error "SNTPv4 RFC 4330 enforces a minimum update time of 15 seconds (define SNTP_SUPPRESS_DELAY_CHECK to disable this error)!"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Configure behaviour depending on microsecond or second precision */
|
||||||
|
#ifdef SNTP_SET_SYSTEM_TIME_US
|
||||||
|
#define SNTP_CALC_TIME_US 1
|
||||||
|
#define SNTP_RECEIVE_TIME_SIZE 2
|
||||||
|
#else
|
||||||
|
#define SNTP_SET_SYSTEM_TIME_US(sec, us)
|
||||||
|
#define SNTP_CALC_TIME_US 0
|
||||||
|
#define SNTP_RECEIVE_TIME_SIZE 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* the various debug levels for this file */
|
||||||
|
#define SNTP_DEBUG_TRACE (SNTP_DEBUG | LWIP_DBG_TRACE)
|
||||||
|
#define SNTP_DEBUG_STATE (SNTP_DEBUG | LWIP_DBG_STATE)
|
||||||
|
#define SNTP_DEBUG_WARN (SNTP_DEBUG | LWIP_DBG_LEVEL_WARNING)
|
||||||
|
#define SNTP_DEBUG_WARN_STATE (SNTP_DEBUG | LWIP_DBG_LEVEL_WARNING | LWIP_DBG_STATE)
|
||||||
|
#define SNTP_DEBUG_SERIOUS (SNTP_DEBUG | LWIP_DBG_LEVEL_SERIOUS)
|
||||||
|
|
||||||
|
#define SNTP_ERR_KOD 1
|
||||||
|
|
||||||
|
/* SNTP protocol defines */
|
||||||
|
#define SNTP_MSG_LEN 48
|
||||||
|
|
||||||
|
#define SNTP_OFFSET_LI_VN_MODE 0
|
||||||
|
#define SNTP_LI_MASK 0xC0
|
||||||
|
#define SNTP_LI_NO_WARNING 0x00
|
||||||
|
#define SNTP_LI_LAST_MINUTE_61_SEC 0x01
|
||||||
|
#define SNTP_LI_LAST_MINUTE_59_SEC 0x02
|
||||||
|
#define SNTP_LI_ALARM_CONDITION 0x03 /* (clock not synchronized) */
|
||||||
|
|
||||||
|
#define SNTP_VERSION_MASK 0x38
|
||||||
|
#define SNTP_VERSION (4/* NTP Version 4*/<<3)
|
||||||
|
|
||||||
|
#define SNTP_MODE_MASK 0x07
|
||||||
|
#define SNTP_MODE_CLIENT 0x03
|
||||||
|
#define SNTP_MODE_SERVER 0x04
|
||||||
|
#define SNTP_MODE_BROADCAST 0x05
|
||||||
|
|
||||||
|
#define SNTP_OFFSET_STRATUM 1
|
||||||
|
#define SNTP_STRATUM_KOD 0x00
|
||||||
|
|
||||||
|
#define SNTP_OFFSET_ORIGINATE_TIME 24
|
||||||
|
#define SNTP_OFFSET_RECEIVE_TIME 32
|
||||||
|
#define SNTP_OFFSET_TRANSMIT_TIME 40
|
||||||
|
|
||||||
|
/* number of seconds between 1900 and 1970 (MSB=1)*/
|
||||||
|
#define DIFF_SEC_1900_1970 (2208988800UL)
|
||||||
|
/* number of seconds between 1970 and Feb 7, 2036 (6:28:16 UTC) (MSB=0) */
|
||||||
|
#define DIFF_SEC_1970_2036 (2085978496UL)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SNTP packet format (without optional fields)
|
||||||
|
* Timestamps are coded as 64 bits:
|
||||||
|
* - 32 bits seconds since Jan 01, 1970, 00:00
|
||||||
|
* - 32 bits seconds fraction (0-padded)
|
||||||
|
* For future use, if the MSB in the seconds part is set, seconds are based
|
||||||
|
* on Feb 07, 2036, 06:28:16.
|
||||||
|
*/
|
||||||
|
#ifdef PACK_STRUCT_USE_INCLUDES
|
||||||
|
# include "arch/bpstruct.h"
|
||||||
|
#endif
|
||||||
|
PACK_STRUCT_BEGIN
|
||||||
|
struct sntp_msg {
|
||||||
|
PACK_STRUCT_FLD_8(u8_t li_vn_mode);
|
||||||
|
PACK_STRUCT_FLD_8(u8_t stratum);
|
||||||
|
PACK_STRUCT_FLD_8(u8_t poll);
|
||||||
|
PACK_STRUCT_FLD_8(u8_t precision);
|
||||||
|
PACK_STRUCT_FIELD(u32_t root_delay);
|
||||||
|
PACK_STRUCT_FIELD(u32_t root_dispersion);
|
||||||
|
PACK_STRUCT_FIELD(u32_t reference_identifier);
|
||||||
|
PACK_STRUCT_FIELD(u32_t reference_timestamp[2]);
|
||||||
|
PACK_STRUCT_FIELD(u32_t originate_timestamp[2]);
|
||||||
|
PACK_STRUCT_FIELD(u32_t receive_timestamp[2]);
|
||||||
|
PACK_STRUCT_FIELD(u32_t transmit_timestamp[2]);
|
||||||
|
} PACK_STRUCT_STRUCT;
|
||||||
|
PACK_STRUCT_END
|
||||||
|
#ifdef PACK_STRUCT_USE_INCLUDES
|
||||||
|
# include "arch/epstruct.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* function prototypes */
|
||||||
|
static void sntp_request(void *arg);
|
||||||
|
|
||||||
|
/** The operating mode */
|
||||||
|
static u8_t sntp_opmode;
|
||||||
|
|
||||||
|
/** The UDP pcb used by the SNTP client */
|
||||||
|
static struct udp_pcb* sntp_pcb;
|
||||||
|
/** Names/Addresses of servers */
|
||||||
|
struct sntp_server {
|
||||||
|
#if SNTP_SERVER_DNS
|
||||||
|
char* name;
|
||||||
|
#endif /* SNTP_SERVER_DNS */
|
||||||
|
ip_addr_t addr;
|
||||||
|
};
|
||||||
|
static struct sntp_server sntp_servers[SNTP_MAX_SERVERS];
|
||||||
|
|
||||||
|
#if SNTP_GET_SERVERS_FROM_DHCP
|
||||||
|
static u8_t sntp_set_servers_from_dhcp;
|
||||||
|
#endif /* SNTP_GET_SERVERS_FROM_DHCP */
|
||||||
|
#if SNTP_SUPPORT_MULTIPLE_SERVERS
|
||||||
|
/** The currently used server (initialized to 0) */
|
||||||
|
static u8_t sntp_current_server;
|
||||||
|
#else /* SNTP_SUPPORT_MULTIPLE_SERVERS */
|
||||||
|
#define sntp_current_server 0
|
||||||
|
#endif /* SNTP_SUPPORT_MULTIPLE_SERVERS */
|
||||||
|
|
||||||
|
#if SNTP_RETRY_TIMEOUT_EXP
|
||||||
|
#define SNTP_RESET_RETRY_TIMEOUT() sntp_retry_timeout = SNTP_RETRY_TIMEOUT
|
||||||
|
/** Retry time, initialized with SNTP_RETRY_TIMEOUT and doubled with each retry. */
|
||||||
|
static u32_t sntp_retry_timeout;
|
||||||
|
#else /* SNTP_RETRY_TIMEOUT_EXP */
|
||||||
|
#define SNTP_RESET_RETRY_TIMEOUT()
|
||||||
|
#define sntp_retry_timeout SNTP_RETRY_TIMEOUT
|
||||||
|
#endif /* SNTP_RETRY_TIMEOUT_EXP */
|
||||||
|
|
||||||
|
#if SNTP_CHECK_RESPONSE >= 1
|
||||||
|
/** Saves the last server address to compare with response */
|
||||||
|
static ip_addr_t sntp_last_server_address;
|
||||||
|
#endif /* SNTP_CHECK_RESPONSE >= 1 */
|
||||||
|
|
||||||
|
#if SNTP_CHECK_RESPONSE >= 2
|
||||||
|
/** Saves the last timestamp sent (which is sent back by the server)
|
||||||
|
* to compare against in response */
|
||||||
|
static u32_t sntp_last_timestamp_sent[2];
|
||||||
|
#endif /* SNTP_CHECK_RESPONSE >= 2 */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SNTP processing of received timestamp
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
sntp_process(u32_t *receive_timestamp)
|
||||||
|
{
|
||||||
|
/* convert SNTP time (1900-based) to unix GMT time (1970-based)
|
||||||
|
* if MSB is 0, SNTP time is 2036-based!
|
||||||
|
*/
|
||||||
|
u32_t rx_secs = lwip_ntohl(receive_timestamp[0]);
|
||||||
|
int is_1900_based = ((rx_secs & 0x80000000) != 0);
|
||||||
|
u32_t t = is_1900_based ? (rx_secs - DIFF_SEC_1900_1970) : (rx_secs + DIFF_SEC_1970_2036);
|
||||||
|
time_t tim = t;
|
||||||
|
|
||||||
|
#if SNTP_CALC_TIME_US
|
||||||
|
u32_t us = lwip_ntohl(receive_timestamp[1]) / 4295;
|
||||||
|
SNTP_SET_SYSTEM_TIME_US(t, us);
|
||||||
|
/* display local time from GMT time */
|
||||||
|
LWIP_DEBUGF(SNTP_DEBUG_TRACE, ("sntp_process: %s, %"U32_F" us", ctime(&tim), us));
|
||||||
|
|
||||||
|
#else /* SNTP_CALC_TIME_US */
|
||||||
|
|
||||||
|
/* change system time and/or the update the RTC clock */
|
||||||
|
SNTP_SET_SYSTEM_TIME(t);
|
||||||
|
/* display local time from GMT time */
|
||||||
|
LWIP_DEBUGF(SNTP_DEBUG_TRACE, ("sntp_process: %s", ctime(&tim)));
|
||||||
|
#endif /* SNTP_CALC_TIME_US */
|
||||||
|
LWIP_UNUSED_ARG(tim);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize request struct to be sent to server.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
sntp_initialize_request(struct sntp_msg *req)
|
||||||
|
{
|
||||||
|
memset(req, 0, SNTP_MSG_LEN);
|
||||||
|
req->li_vn_mode = SNTP_LI_NO_WARNING | SNTP_VERSION | SNTP_MODE_CLIENT;
|
||||||
|
|
||||||
|
#if SNTP_CHECK_RESPONSE >= 2
|
||||||
|
{
|
||||||
|
u32_t sntp_time_sec, sntp_time_us;
|
||||||
|
/* fill in transmit timestamp and save it in 'sntp_last_timestamp_sent' */
|
||||||
|
SNTP_GET_SYSTEM_TIME(sntp_time_sec, sntp_time_us);
|
||||||
|
sntp_last_timestamp_sent[0] = lwip_htonl(sntp_time_sec + DIFF_SEC_1900_1970);
|
||||||
|
req->transmit_timestamp[0] = sntp_last_timestamp_sent[0];
|
||||||
|
/* we send/save us instead of fraction to be faster... */
|
||||||
|
sntp_last_timestamp_sent[1] = lwip_htonl(sntp_time_us);
|
||||||
|
req->transmit_timestamp[1] = sntp_last_timestamp_sent[1];
|
||||||
|
}
|
||||||
|
#endif /* SNTP_CHECK_RESPONSE >= 2 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retry: send a new request (and increase retry timeout).
|
||||||
|
*
|
||||||
|
* @param arg is unused (only necessary to conform to sys_timeout)
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
sntp_retry(void* arg)
|
||||||
|
{
|
||||||
|
LWIP_UNUSED_ARG(arg);
|
||||||
|
|
||||||
|
LWIP_DEBUGF(SNTP_DEBUG_STATE, ("sntp_retry: Next request will be sent in %"U32_F" ms\n",
|
||||||
|
sntp_retry_timeout));
|
||||||
|
|
||||||
|
/* set up a timer to send a retry and increase the retry delay */
|
||||||
|
sys_timeout(sntp_retry_timeout, sntp_request, NULL);
|
||||||
|
|
||||||
|
#if SNTP_RETRY_TIMEOUT_EXP
|
||||||
|
{
|
||||||
|
u32_t new_retry_timeout;
|
||||||
|
/* increase the timeout for next retry */
|
||||||
|
new_retry_timeout = sntp_retry_timeout << 1;
|
||||||
|
/* limit to maximum timeout and prevent overflow */
|
||||||
|
if ((new_retry_timeout <= SNTP_RETRY_TIMEOUT_MAX) &&
|
||||||
|
(new_retry_timeout > sntp_retry_timeout)) {
|
||||||
|
sntp_retry_timeout = new_retry_timeout;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* SNTP_RETRY_TIMEOUT_EXP */
|
||||||
|
}
|
||||||
|
|
||||||
|
#if SNTP_SUPPORT_MULTIPLE_SERVERS
|
||||||
|
/**
|
||||||
|
* If Kiss-of-Death is received (or another packet parsing error),
|
||||||
|
* try the next server or retry the current server and increase the retry
|
||||||
|
* timeout if only one server is available.
|
||||||
|
* (implicitly, SNTP_MAX_SERVERS > 1)
|
||||||
|
*
|
||||||
|
* @param arg is unused (only necessary to conform to sys_timeout)
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
sntp_try_next_server(void* arg)
|
||||||
|
{
|
||||||
|
u8_t old_server, i;
|
||||||
|
LWIP_UNUSED_ARG(arg);
|
||||||
|
|
||||||
|
old_server = sntp_current_server;
|
||||||
|
for (i = 0; i < SNTP_MAX_SERVERS - 1; i++) {
|
||||||
|
sntp_current_server++;
|
||||||
|
if (sntp_current_server >= SNTP_MAX_SERVERS) {
|
||||||
|
sntp_current_server = 0;
|
||||||
|
}
|
||||||
|
if (!ip_addr_isany(&sntp_servers[sntp_current_server].addr)
|
||||||
|
#if SNTP_SERVER_DNS
|
||||||
|
|| (sntp_servers[sntp_current_server].name != NULL)
|
||||||
|
#endif
|
||||||
|
) {
|
||||||
|
LWIP_DEBUGF(SNTP_DEBUG_STATE, ("sntp_try_next_server: Sending request to server %"U16_F"\n",
|
||||||
|
(u16_t)sntp_current_server));
|
||||||
|
/* new server: reset retry timeout */
|
||||||
|
SNTP_RESET_RETRY_TIMEOUT();
|
||||||
|
/* instantly send a request to the next server */
|
||||||
|
sntp_request(NULL);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* no other valid server found */
|
||||||
|
sntp_current_server = old_server;
|
||||||
|
sntp_retry(NULL);
|
||||||
|
}
|
||||||
|
#else /* SNTP_SUPPORT_MULTIPLE_SERVERS */
|
||||||
|
/* Always retry on error if only one server is supported */
|
||||||
|
#define sntp_try_next_server sntp_retry
|
||||||
|
#endif /* SNTP_SUPPORT_MULTIPLE_SERVERS */
|
||||||
|
|
||||||
|
/** UDP recv callback for the sntp pcb */
|
||||||
|
static void
|
||||||
|
sntp_recv(void *arg, struct udp_pcb* pcb, struct pbuf *p, const ip_addr_t *addr, u16_t port)
|
||||||
|
{
|
||||||
|
u8_t mode;
|
||||||
|
u8_t stratum;
|
||||||
|
u32_t receive_timestamp[SNTP_RECEIVE_TIME_SIZE];
|
||||||
|
err_t err;
|
||||||
|
|
||||||
|
LWIP_UNUSED_ARG(arg);
|
||||||
|
LWIP_UNUSED_ARG(pcb);
|
||||||
|
|
||||||
|
/* packet received: stop retry timeout */
|
||||||
|
sys_untimeout(sntp_try_next_server, NULL);
|
||||||
|
sys_untimeout(sntp_request, NULL);
|
||||||
|
|
||||||
|
err = ERR_ARG;
|
||||||
|
#if SNTP_CHECK_RESPONSE >= 1
|
||||||
|
/* check server address and port */
|
||||||
|
if (((sntp_opmode != SNTP_OPMODE_POLL) || ip_addr_cmp(addr, &sntp_last_server_address)) &&
|
||||||
|
(port == SNTP_PORT))
|
||||||
|
#else /* SNTP_CHECK_RESPONSE >= 1 */
|
||||||
|
LWIP_UNUSED_ARG(addr);
|
||||||
|
LWIP_UNUSED_ARG(port);
|
||||||
|
#endif /* SNTP_CHECK_RESPONSE >= 1 */
|
||||||
|
{
|
||||||
|
/* process the response */
|
||||||
|
if (p->tot_len == SNTP_MSG_LEN) {
|
||||||
|
pbuf_copy_partial(p, &mode, 1, SNTP_OFFSET_LI_VN_MODE);
|
||||||
|
mode &= SNTP_MODE_MASK;
|
||||||
|
/* if this is a SNTP response... */
|
||||||
|
if (((sntp_opmode == SNTP_OPMODE_POLL) && (mode == SNTP_MODE_SERVER)) ||
|
||||||
|
((sntp_opmode == SNTP_OPMODE_LISTENONLY) && (mode == SNTP_MODE_BROADCAST))) {
|
||||||
|
pbuf_copy_partial(p, &stratum, 1, SNTP_OFFSET_STRATUM);
|
||||||
|
if (stratum == SNTP_STRATUM_KOD) {
|
||||||
|
/* Kiss-of-death packet. Use another server or increase UPDATE_DELAY. */
|
||||||
|
err = SNTP_ERR_KOD;
|
||||||
|
LWIP_DEBUGF(SNTP_DEBUG_STATE, ("sntp_recv: Received Kiss-of-Death\n"));
|
||||||
|
} else {
|
||||||
|
#if SNTP_CHECK_RESPONSE >= 2
|
||||||
|
/* check originate_timetamp against sntp_last_timestamp_sent */
|
||||||
|
u32_t originate_timestamp[2];
|
||||||
|
pbuf_copy_partial(p, &originate_timestamp, 8, SNTP_OFFSET_ORIGINATE_TIME);
|
||||||
|
if ((originate_timestamp[0] != sntp_last_timestamp_sent[0]) ||
|
||||||
|
(originate_timestamp[1] != sntp_last_timestamp_sent[1]))
|
||||||
|
{
|
||||||
|
LWIP_DEBUGF(SNTP_DEBUG_WARN, ("sntp_recv: Invalid originate timestamp in response\n"));
|
||||||
|
} else
|
||||||
|
#endif /* SNTP_CHECK_RESPONSE >= 2 */
|
||||||
|
/* @todo: add code for SNTP_CHECK_RESPONSE >= 3 and >= 4 here */
|
||||||
|
{
|
||||||
|
/* correct answer */
|
||||||
|
err = ERR_OK;
|
||||||
|
pbuf_copy_partial(p, &receive_timestamp, SNTP_RECEIVE_TIME_SIZE * 4, SNTP_OFFSET_TRANSMIT_TIME);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
LWIP_DEBUGF(SNTP_DEBUG_WARN, ("sntp_recv: Invalid mode in response: %"U16_F"\n", (u16_t)mode));
|
||||||
|
/* wait for correct response */
|
||||||
|
err = ERR_TIMEOUT;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
LWIP_DEBUGF(SNTP_DEBUG_WARN, ("sntp_recv: Invalid packet length: %"U16_F"\n", p->tot_len));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#if SNTP_CHECK_RESPONSE >= 1
|
||||||
|
else {
|
||||||
|
/* packet from wrong remote address or port, wait for correct response */
|
||||||
|
err = ERR_TIMEOUT;
|
||||||
|
}
|
||||||
|
#endif /* SNTP_CHECK_RESPONSE >= 1 */
|
||||||
|
pbuf_free(p);
|
||||||
|
if (err == ERR_OK) {
|
||||||
|
sntp_process(receive_timestamp);
|
||||||
|
|
||||||
|
/* Set up timeout for next request (only if poll response was received)*/
|
||||||
|
if (sntp_opmode == SNTP_OPMODE_POLL) {
|
||||||
|
/* Correct response, reset retry timeout */
|
||||||
|
SNTP_RESET_RETRY_TIMEOUT();
|
||||||
|
|
||||||
|
sys_timeout((u32_t)SNTP_UPDATE_DELAY, sntp_request, NULL);
|
||||||
|
LWIP_DEBUGF(SNTP_DEBUG_STATE, ("sntp_recv: Scheduled next time request: %"U32_F" ms\n",
|
||||||
|
(u32_t)SNTP_UPDATE_DELAY));
|
||||||
|
}
|
||||||
|
} else if (err != ERR_TIMEOUT) {
|
||||||
|
/* Errors are only processed in case of an explicit poll response */
|
||||||
|
if (sntp_opmode == SNTP_OPMODE_POLL) {
|
||||||
|
if (err == SNTP_ERR_KOD) {
|
||||||
|
/* Kiss-of-death packet. Use another server or increase UPDATE_DELAY. */
|
||||||
|
sntp_try_next_server(NULL);
|
||||||
|
} else {
|
||||||
|
/* another error, try the same server again */
|
||||||
|
sntp_retry(NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Actually send an sntp request to a server.
|
||||||
|
*
|
||||||
|
* @param server_addr resolved IP address of the SNTP server
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
sntp_send_request(const ip_addr_t *server_addr)
|
||||||
|
{
|
||||||
|
struct pbuf* p;
|
||||||
|
p = pbuf_alloc(PBUF_TRANSPORT, SNTP_MSG_LEN, PBUF_RAM);
|
||||||
|
if (p != NULL) {
|
||||||
|
struct sntp_msg *sntpmsg = (struct sntp_msg *)p->payload;
|
||||||
|
LWIP_DEBUGF(SNTP_DEBUG_STATE, ("sntp_send_request: Sending request to server\n"));
|
||||||
|
/* initialize request message */
|
||||||
|
sntp_initialize_request(sntpmsg);
|
||||||
|
/* send request */
|
||||||
|
udp_sendto(sntp_pcb, p, server_addr, SNTP_PORT);
|
||||||
|
/* free the pbuf after sending it */
|
||||||
|
pbuf_free(p);
|
||||||
|
/* set up receive timeout: try next server or retry on timeout */
|
||||||
|
sys_timeout((u32_t)SNTP_RECV_TIMEOUT, sntp_try_next_server, NULL);
|
||||||
|
#if SNTP_CHECK_RESPONSE >= 1
|
||||||
|
/* save server address to verify it in sntp_recv */
|
||||||
|
ip_addr_set(&sntp_last_server_address, server_addr);
|
||||||
|
#endif /* SNTP_CHECK_RESPONSE >= 1 */
|
||||||
|
} else {
|
||||||
|
LWIP_DEBUGF(SNTP_DEBUG_SERIOUS, ("sntp_send_request: Out of memory, trying again in %"U32_F" ms\n",
|
||||||
|
(u32_t)SNTP_RETRY_TIMEOUT));
|
||||||
|
/* out of memory: set up a timer to send a retry */
|
||||||
|
sys_timeout((u32_t)SNTP_RETRY_TIMEOUT, sntp_request, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if SNTP_SERVER_DNS
|
||||||
|
/**
|
||||||
|
* DNS found callback when using DNS names as server address.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
sntp_dns_found(const char* hostname, const ip_addr_t *ipaddr, void *arg)
|
||||||
|
{
|
||||||
|
LWIP_UNUSED_ARG(hostname);
|
||||||
|
LWIP_UNUSED_ARG(arg);
|
||||||
|
|
||||||
|
if (ipaddr != NULL) {
|
||||||
|
/* Address resolved, send request */
|
||||||
|
LWIP_DEBUGF(SNTP_DEBUG_STATE, ("sntp_dns_found: Server address resolved, sending request\n"));
|
||||||
|
sntp_send_request(ipaddr);
|
||||||
|
} else {
|
||||||
|
/* DNS resolving failed -> try another server */
|
||||||
|
LWIP_DEBUGF(SNTP_DEBUG_WARN_STATE, ("sntp_dns_found: Failed to resolve server address resolved, trying next server\n"));
|
||||||
|
sntp_try_next_server(NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* SNTP_SERVER_DNS */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send out an sntp request.
|
||||||
|
*
|
||||||
|
* @param arg is unused (only necessary to conform to sys_timeout)
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
sntp_request(void *arg)
|
||||||
|
{
|
||||||
|
ip_addr_t sntp_server_address;
|
||||||
|
err_t err;
|
||||||
|
|
||||||
|
LWIP_UNUSED_ARG(arg);
|
||||||
|
|
||||||
|
/* initialize SNTP server address */
|
||||||
|
#if SNTP_SERVER_DNS
|
||||||
|
if (sntp_servers[sntp_current_server].name) {
|
||||||
|
/* always resolve the name and rely on dns-internal caching & timeout */
|
||||||
|
ip_addr_set_zero(&sntp_servers[sntp_current_server].addr);
|
||||||
|
err = dns_gethostbyname(sntp_servers[sntp_current_server].name, &sntp_server_address,
|
||||||
|
sntp_dns_found, NULL);
|
||||||
|
if (err == ERR_INPROGRESS) {
|
||||||
|
/* DNS request sent, wait for sntp_dns_found being called */
|
||||||
|
LWIP_DEBUGF(SNTP_DEBUG_STATE, ("sntp_request: Waiting for server address to be resolved.\n"));
|
||||||
|
return;
|
||||||
|
} else if (err == ERR_OK) {
|
||||||
|
sntp_servers[sntp_current_server].addr = sntp_server_address;
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
#endif /* SNTP_SERVER_DNS */
|
||||||
|
{
|
||||||
|
sntp_server_address = sntp_servers[sntp_current_server].addr;
|
||||||
|
err = (ip_addr_isany_val(sntp_server_address)) ? ERR_ARG : ERR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (err == ERR_OK) {
|
||||||
|
LWIP_DEBUGF(SNTP_DEBUG_TRACE, ("sntp_request: current server address is %s\n",
|
||||||
|
ipaddr_ntoa(&sntp_server_address)));
|
||||||
|
sntp_send_request(&sntp_server_address);
|
||||||
|
} else {
|
||||||
|
/* address conversion failed, try another server */
|
||||||
|
LWIP_DEBUGF(SNTP_DEBUG_WARN_STATE, ("sntp_request: Invalid server address, trying next server.\n"));
|
||||||
|
sys_timeout((u32_t)SNTP_RETRY_TIMEOUT, sntp_try_next_server, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup sntp
|
||||||
|
* Initialize this module.
|
||||||
|
* Send out request instantly or after SNTP_STARTUP_DELAY(_FUNC).
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
sntp_init(void)
|
||||||
|
{
|
||||||
|
#ifdef SNTP_SERVER_ADDRESS
|
||||||
|
#if SNTP_SERVER_DNS
|
||||||
|
sntp_setservername(0, SNTP_SERVER_ADDRESS);
|
||||||
|
#else
|
||||||
|
#error SNTP_SERVER_ADDRESS string not supported SNTP_SERVER_DNS==0
|
||||||
|
#endif
|
||||||
|
#endif /* SNTP_SERVER_ADDRESS */
|
||||||
|
|
||||||
|
if (sntp_pcb == NULL) {
|
||||||
|
sntp_pcb = udp_new_ip_type(IPADDR_TYPE_ANY);
|
||||||
|
LWIP_ASSERT("Failed to allocate udp pcb for sntp client", sntp_pcb != NULL);
|
||||||
|
if (sntp_pcb != NULL) {
|
||||||
|
udp_recv(sntp_pcb, sntp_recv, NULL);
|
||||||
|
|
||||||
|
if (sntp_opmode == SNTP_OPMODE_POLL) {
|
||||||
|
SNTP_RESET_RETRY_TIMEOUT();
|
||||||
|
#if SNTP_STARTUP_DELAY
|
||||||
|
sys_timeout((u32_t)SNTP_STARTUP_DELAY_FUNC, sntp_request, NULL);
|
||||||
|
#else
|
||||||
|
sntp_request(NULL);
|
||||||
|
#endif
|
||||||
|
} else if (sntp_opmode == SNTP_OPMODE_LISTENONLY) {
|
||||||
|
ip_set_option(sntp_pcb, SOF_BROADCAST);
|
||||||
|
udp_bind(sntp_pcb, IP_ANY_TYPE, SNTP_PORT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup sntp
|
||||||
|
* Stop this module.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
sntp_stop(void)
|
||||||
|
{
|
||||||
|
if (sntp_pcb != NULL) {
|
||||||
|
sys_untimeout(sntp_request, NULL);
|
||||||
|
sys_untimeout(sntp_try_next_server, NULL);
|
||||||
|
udp_remove(sntp_pcb);
|
||||||
|
sntp_pcb = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup sntp
|
||||||
|
* Get enabled state.
|
||||||
|
*/
|
||||||
|
u8_t sntp_enabled(void)
|
||||||
|
{
|
||||||
|
return (sntp_pcb != NULL)? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup sntp
|
||||||
|
* Sets the operating mode.
|
||||||
|
* @param operating_mode one of the available operating modes
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
sntp_setoperatingmode(u8_t operating_mode)
|
||||||
|
{
|
||||||
|
LWIP_ASSERT("Invalid operating mode", operating_mode <= SNTP_OPMODE_LISTENONLY);
|
||||||
|
LWIP_ASSERT("Operating mode must not be set while SNTP client is running", sntp_pcb == NULL);
|
||||||
|
sntp_opmode = operating_mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup sntp
|
||||||
|
* Gets the operating mode.
|
||||||
|
*/
|
||||||
|
u8_t
|
||||||
|
sntp_getoperatingmode(void)
|
||||||
|
{
|
||||||
|
return sntp_opmode;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if SNTP_GET_SERVERS_FROM_DHCP
|
||||||
|
/**
|
||||||
|
* Config SNTP server handling by IP address, name, or DHCP; clear table
|
||||||
|
* @param set_servers_from_dhcp enable or disable getting server addresses from dhcp
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
sntp_servermode_dhcp(int set_servers_from_dhcp)
|
||||||
|
{
|
||||||
|
u8_t new_mode = set_servers_from_dhcp ? 1 : 0;
|
||||||
|
if (sntp_set_servers_from_dhcp != new_mode) {
|
||||||
|
sntp_set_servers_from_dhcp = new_mode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* SNTP_GET_SERVERS_FROM_DHCP */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup sntp
|
||||||
|
* Initialize one of the NTP servers by IP address
|
||||||
|
*
|
||||||
|
* @param idx the index of the NTP server to set must be < SNTP_MAX_SERVERS
|
||||||
|
* @param server IP address of the NTP server to set
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
sntp_setserver(u8_t idx, const ip_addr_t *server)
|
||||||
|
{
|
||||||
|
if (idx < SNTP_MAX_SERVERS) {
|
||||||
|
if (server != NULL) {
|
||||||
|
sntp_servers[idx].addr = (*server);
|
||||||
|
} else {
|
||||||
|
ip_addr_set_zero(&sntp_servers[idx].addr);
|
||||||
|
}
|
||||||
|
#if SNTP_SERVER_DNS
|
||||||
|
sntp_servers[idx].name = NULL;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if LWIP_DHCP && SNTP_GET_SERVERS_FROM_DHCP
|
||||||
|
/**
|
||||||
|
* Initialize one of the NTP servers by IP address, required by DHCP
|
||||||
|
*
|
||||||
|
* @param numdns the index of the NTP server to set must be < SNTP_MAX_SERVERS
|
||||||
|
* @param dnsserver IP address of the NTP server to set
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
dhcp_set_ntp_servers(u8_t num, const ip4_addr_t *server)
|
||||||
|
{
|
||||||
|
LWIP_DEBUGF(SNTP_DEBUG_TRACE, ("sntp: %s %u.%u.%u.%u as NTP server #%u via DHCP\n",
|
||||||
|
(sntp_set_servers_from_dhcp ? "Got" : "Rejected"),
|
||||||
|
ip4_addr1(server), ip4_addr2(server), ip4_addr3(server), ip4_addr4(server), num));
|
||||||
|
if (sntp_set_servers_from_dhcp && num) {
|
||||||
|
u8_t i;
|
||||||
|
for (i = 0; (i < num) && (i < SNTP_MAX_SERVERS); i++) {
|
||||||
|
ip_addr_t addr;
|
||||||
|
ip_addr_copy_from_ip4(addr, server[i]);
|
||||||
|
sntp_setserver(i, &addr);
|
||||||
|
}
|
||||||
|
for (i = num; i < SNTP_MAX_SERVERS; i++) {
|
||||||
|
sntp_setserver(i, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* LWIP_DHCP && SNTP_GET_SERVERS_FROM_DHCP */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup sntp
|
||||||
|
* Obtain one of the currently configured by IP address (or DHCP) NTP servers
|
||||||
|
*
|
||||||
|
* @param idx the index of the NTP server
|
||||||
|
* @return IP address of the indexed NTP server or "ip_addr_any" if the NTP
|
||||||
|
* server has not been configured by address (or at all).
|
||||||
|
*/
|
||||||
|
const ip_addr_t*
|
||||||
|
sntp_getserver(u8_t idx)
|
||||||
|
{
|
||||||
|
if (idx < SNTP_MAX_SERVERS) {
|
||||||
|
return &sntp_servers[idx].addr;
|
||||||
|
}
|
||||||
|
return IP_ADDR_ANY;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if SNTP_SERVER_DNS
|
||||||
|
/**
|
||||||
|
* Initialize one of the NTP servers by name
|
||||||
|
*
|
||||||
|
* @param numdns the index of the NTP server to set must be < SNTP_MAX_SERVERS
|
||||||
|
* @param dnsserver DNS name of the NTP server to set, to be resolved at contact time
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
sntp_setservername(u8_t idx, char *server)
|
||||||
|
{
|
||||||
|
if (idx < SNTP_MAX_SERVERS) {
|
||||||
|
sntp_servers[idx].name = server;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Obtain one of the currently configured by name NTP servers.
|
||||||
|
*
|
||||||
|
* @param numdns the index of the NTP server
|
||||||
|
* @return IP address of the indexed NTP server or NULL if the NTP
|
||||||
|
* server has not been configured by name (or at all)
|
||||||
|
*/
|
||||||
|
char *
|
||||||
|
sntp_getservername(u8_t idx)
|
||||||
|
{
|
||||||
|
if (idx < SNTP_MAX_SERVERS) {
|
||||||
|
return sntp_servers[idx].name;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
#endif /* SNTP_SERVER_DNS */
|
||||||
|
|
||||||
|
#endif /* LWIP_UDP */
|
|
@ -0,0 +1,417 @@
|
||||||
|
/****************************************************************//**
|
||||||
|
*
|
||||||
|
* @file tftp_server.c
|
||||||
|
*
|
||||||
|
* @author Logan Gunthorpe <logang@deltatee.com>
|
||||||
|
* Dirk Ziegelmeier <dziegel@gmx.de>
|
||||||
|
*
|
||||||
|
* @brief Trivial File Transfer Protocol (RFC 1350)
|
||||||
|
*
|
||||||
|
* Copyright (c) Deltatee Enterprises Ltd. 2013
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
********************************************************************/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification,are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||||
|
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||||
|
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||||
|
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* Author: Logan Gunthorpe <logang@deltatee.com>
|
||||||
|
* Dirk Ziegelmeier <dziegel@gmx.de>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @defgroup tftp TFTP server
|
||||||
|
* @ingroup apps
|
||||||
|
*
|
||||||
|
* This is simple TFTP server for the lwIP raw API.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "lwip/apps/tftp_server.h"
|
||||||
|
|
||||||
|
#if LWIP_UDP
|
||||||
|
|
||||||
|
#include "lwip/udp.h"
|
||||||
|
#include "lwip/timeouts.h"
|
||||||
|
#include "lwip/debug.h"
|
||||||
|
|
||||||
|
#define TFTP_MAX_PAYLOAD_SIZE 512
|
||||||
|
#define TFTP_HEADER_LENGTH 4
|
||||||
|
|
||||||
|
#define TFTP_RRQ 1
|
||||||
|
#define TFTP_WRQ 2
|
||||||
|
#define TFTP_DATA 3
|
||||||
|
#define TFTP_ACK 4
|
||||||
|
#define TFTP_ERROR 5
|
||||||
|
|
||||||
|
enum tftp_error {
|
||||||
|
TFTP_ERROR_FILE_NOT_FOUND = 1,
|
||||||
|
TFTP_ERROR_ACCESS_VIOLATION = 2,
|
||||||
|
TFTP_ERROR_DISK_FULL = 3,
|
||||||
|
TFTP_ERROR_ILLEGAL_OPERATION = 4,
|
||||||
|
TFTP_ERROR_UNKNOWN_TRFR_ID = 5,
|
||||||
|
TFTP_ERROR_FILE_EXISTS = 6,
|
||||||
|
TFTP_ERROR_NO_SUCH_USER = 7
|
||||||
|
};
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
struct tftp_state {
|
||||||
|
const struct tftp_context *ctx;
|
||||||
|
void *handle;
|
||||||
|
struct pbuf *last_data;
|
||||||
|
struct udp_pcb *upcb;
|
||||||
|
ip_addr_t addr;
|
||||||
|
u16_t port;
|
||||||
|
int timer;
|
||||||
|
int last_pkt;
|
||||||
|
u16_t blknum;
|
||||||
|
u8_t retries;
|
||||||
|
u8_t mode_write;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct tftp_state tftp_state;
|
||||||
|
|
||||||
|
static void tftp_tmr(void* arg);
|
||||||
|
|
||||||
|
static void
|
||||||
|
close_handle(void)
|
||||||
|
{
|
||||||
|
tftp_state.port = 0;
|
||||||
|
ip_addr_set_any(0, &tftp_state.addr);
|
||||||
|
|
||||||
|
if(tftp_state.last_data != NULL) {
|
||||||
|
pbuf_free(tftp_state.last_data);
|
||||||
|
tftp_state.last_data = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
sys_untimeout(tftp_tmr, NULL);
|
||||||
|
|
||||||
|
if (tftp_state.handle) {
|
||||||
|
tftp_state.ctx->close(tftp_state.handle);
|
||||||
|
tftp_state.handle = NULL;
|
||||||
|
LWIP_DEBUGF(TFTP_DEBUG | LWIP_DBG_STATE, ("tftp: closing\n"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
send_error(const ip_addr_t *addr, u16_t port, enum tftp_error code, const char *str)
|
||||||
|
{
|
||||||
|
int str_length = strlen(str);
|
||||||
|
struct pbuf* p;
|
||||||
|
u16_t* payload;
|
||||||
|
|
||||||
|
p = pbuf_alloc(PBUF_TRANSPORT, (u16_t)(TFTP_HEADER_LENGTH + str_length + 1), PBUF_RAM);
|
||||||
|
if(p == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
payload = (u16_t*) p->payload;
|
||||||
|
payload[0] = PP_HTONS(TFTP_ERROR);
|
||||||
|
payload[1] = lwip_htons(code);
|
||||||
|
MEMCPY(&payload[2], str, str_length + 1);
|
||||||
|
|
||||||
|
udp_sendto(tftp_state.upcb, p, addr, port);
|
||||||
|
pbuf_free(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
send_ack(u16_t blknum)
|
||||||
|
{
|
||||||
|
struct pbuf* p;
|
||||||
|
u16_t* payload;
|
||||||
|
|
||||||
|
p = pbuf_alloc(PBUF_TRANSPORT, TFTP_HEADER_LENGTH, PBUF_RAM);
|
||||||
|
if(p == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
payload = (u16_t*) p->payload;
|
||||||
|
|
||||||
|
payload[0] = PP_HTONS(TFTP_ACK);
|
||||||
|
payload[1] = lwip_htons(blknum);
|
||||||
|
udp_sendto(tftp_state.upcb, p, &tftp_state.addr, tftp_state.port);
|
||||||
|
pbuf_free(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
resend_data(void)
|
||||||
|
{
|
||||||
|
struct pbuf *p = pbuf_alloc(PBUF_TRANSPORT, tftp_state.last_data->len, PBUF_RAM);
|
||||||
|
if(p == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(pbuf_copy(p, tftp_state.last_data) != ERR_OK) {
|
||||||
|
pbuf_free(p);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
udp_sendto(tftp_state.upcb, p, &tftp_state.addr, tftp_state.port);
|
||||||
|
pbuf_free(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
send_data(void)
|
||||||
|
{
|
||||||
|
u16_t *payload;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if(tftp_state.last_data != NULL) {
|
||||||
|
pbuf_free(tftp_state.last_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
tftp_state.last_data = pbuf_alloc(PBUF_TRANSPORT, TFTP_HEADER_LENGTH + TFTP_MAX_PAYLOAD_SIZE, PBUF_RAM);
|
||||||
|
if(tftp_state.last_data == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
payload = (u16_t *) tftp_state.last_data->payload;
|
||||||
|
payload[0] = PP_HTONS(TFTP_DATA);
|
||||||
|
payload[1] = lwip_htons(tftp_state.blknum);
|
||||||
|
|
||||||
|
ret = tftp_state.ctx->read(tftp_state.handle, &payload[2], TFTP_MAX_PAYLOAD_SIZE);
|
||||||
|
if (ret < 0) {
|
||||||
|
send_error(&tftp_state.addr, tftp_state.port, TFTP_ERROR_ACCESS_VIOLATION, "Error occured while reading the file.");
|
||||||
|
close_handle();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
pbuf_realloc(tftp_state.last_data, (u16_t)(TFTP_HEADER_LENGTH + ret));
|
||||||
|
resend_data();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
recv(void *arg, struct udp_pcb *upcb, struct pbuf *p, const ip_addr_t *addr, u16_t port)
|
||||||
|
{
|
||||||
|
u16_t *sbuf = (u16_t *) p->payload;
|
||||||
|
int opcode;
|
||||||
|
|
||||||
|
LWIP_UNUSED_ARG(arg);
|
||||||
|
LWIP_UNUSED_ARG(upcb);
|
||||||
|
|
||||||
|
if (((tftp_state.port != 0) && (port != tftp_state.port)) ||
|
||||||
|
(!ip_addr_isany_val(tftp_state.addr) && !ip_addr_cmp(&tftp_state.addr, addr))) {
|
||||||
|
send_error(addr, port, TFTP_ERROR_ACCESS_VIOLATION, "Only one connection at a time is supported");
|
||||||
|
pbuf_free(p);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
opcode = sbuf[0];
|
||||||
|
|
||||||
|
tftp_state.last_pkt = tftp_state.timer;
|
||||||
|
tftp_state.retries = 0;
|
||||||
|
|
||||||
|
switch (opcode) {
|
||||||
|
case PP_HTONS(TFTP_RRQ): /* fall through */
|
||||||
|
case PP_HTONS(TFTP_WRQ):
|
||||||
|
{
|
||||||
|
const char tftp_null = 0;
|
||||||
|
char filename[TFTP_MAX_FILENAME_LEN];
|
||||||
|
char mode[TFTP_MAX_MODE_LEN];
|
||||||
|
u16_t filename_end_offset;
|
||||||
|
u16_t mode_end_offset;
|
||||||
|
|
||||||
|
if(tftp_state.handle != NULL) {
|
||||||
|
send_error(addr, port, TFTP_ERROR_ACCESS_VIOLATION, "Only one connection at a time is supported");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
sys_timeout(TFTP_TIMER_MSECS, tftp_tmr, NULL);
|
||||||
|
|
||||||
|
/* find \0 in pbuf -> end of filename string */
|
||||||
|
filename_end_offset = pbuf_memfind(p, &tftp_null, sizeof(tftp_null), 2);
|
||||||
|
if((u16_t)(filename_end_offset-2) > sizeof(filename)) {
|
||||||
|
send_error(addr, port, TFTP_ERROR_ACCESS_VIOLATION, "Filename too long/not NULL terminated");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
pbuf_copy_partial(p, filename, filename_end_offset-2, 2);
|
||||||
|
|
||||||
|
/* find \0 in pbuf -> end of mode string */
|
||||||
|
mode_end_offset = pbuf_memfind(p, &tftp_null, sizeof(tftp_null), filename_end_offset+1);
|
||||||
|
if((u16_t)(mode_end_offset-filename_end_offset) > sizeof(mode)) {
|
||||||
|
send_error(addr, port, TFTP_ERROR_ACCESS_VIOLATION, "Mode too long/not NULL terminated");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
pbuf_copy_partial(p, mode, mode_end_offset-filename_end_offset, filename_end_offset+1);
|
||||||
|
|
||||||
|
tftp_state.handle = tftp_state.ctx->open(filename, mode, opcode == PP_HTONS(TFTP_WRQ));
|
||||||
|
tftp_state.blknum = 1;
|
||||||
|
|
||||||
|
if (!tftp_state.handle) {
|
||||||
|
send_error(addr, port, TFTP_ERROR_FILE_NOT_FOUND, "Unable to open requested file.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
LWIP_DEBUGF(TFTP_DEBUG | LWIP_DBG_STATE, ("tftp: %s request from ", (opcode == PP_HTONS(TFTP_WRQ)) ? "write" : "read"));
|
||||||
|
ip_addr_debug_print(TFTP_DEBUG | LWIP_DBG_STATE, addr);
|
||||||
|
LWIP_DEBUGF(TFTP_DEBUG | LWIP_DBG_STATE, (" for '%s' mode '%s'\n", filename, mode));
|
||||||
|
|
||||||
|
ip_addr_copy(tftp_state.addr, *addr);
|
||||||
|
tftp_state.port = port;
|
||||||
|
|
||||||
|
if (opcode == PP_HTONS(TFTP_WRQ)) {
|
||||||
|
tftp_state.mode_write = 1;
|
||||||
|
send_ack(0);
|
||||||
|
} else {
|
||||||
|
tftp_state.mode_write = 0;
|
||||||
|
send_data();
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case PP_HTONS(TFTP_DATA):
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
u16_t blknum;
|
||||||
|
|
||||||
|
if (tftp_state.handle == NULL) {
|
||||||
|
send_error(addr, port, TFTP_ERROR_ACCESS_VIOLATION, "No connection");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tftp_state.mode_write != 1) {
|
||||||
|
send_error(addr, port, TFTP_ERROR_ACCESS_VIOLATION, "Not a write connection");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
blknum = lwip_ntohs(sbuf[1]);
|
||||||
|
pbuf_header(p, -TFTP_HEADER_LENGTH);
|
||||||
|
|
||||||
|
ret = tftp_state.ctx->write(tftp_state.handle, p);
|
||||||
|
if (ret < 0) {
|
||||||
|
send_error(addr, port, TFTP_ERROR_ACCESS_VIOLATION, "error writing file");
|
||||||
|
close_handle();
|
||||||
|
} else {
|
||||||
|
send_ack(blknum);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p->tot_len < TFTP_MAX_PAYLOAD_SIZE) {
|
||||||
|
close_handle();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case PP_HTONS(TFTP_ACK):
|
||||||
|
{
|
||||||
|
u16_t blknum;
|
||||||
|
int lastpkt;
|
||||||
|
|
||||||
|
if (tftp_state.handle == NULL) {
|
||||||
|
send_error(addr, port, TFTP_ERROR_ACCESS_VIOLATION, "No connection");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tftp_state.mode_write != 0) {
|
||||||
|
send_error(addr, port, TFTP_ERROR_ACCESS_VIOLATION, "Not a read connection");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
blknum = lwip_ntohs(sbuf[1]);
|
||||||
|
if (blknum != tftp_state.blknum) {
|
||||||
|
send_error(addr, port, TFTP_ERROR_UNKNOWN_TRFR_ID, "Wrong block number");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
lastpkt = 0;
|
||||||
|
|
||||||
|
if (tftp_state.last_data != NULL) {
|
||||||
|
lastpkt = tftp_state.last_data->tot_len != (TFTP_MAX_PAYLOAD_SIZE + TFTP_HEADER_LENGTH);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!lastpkt) {
|
||||||
|
tftp_state.blknum++;
|
||||||
|
send_data();
|
||||||
|
} else {
|
||||||
|
close_handle();
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
send_error(addr, port, TFTP_ERROR_ILLEGAL_OPERATION, "Unknown operation");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
pbuf_free(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
tftp_tmr(void* arg)
|
||||||
|
{
|
||||||
|
LWIP_UNUSED_ARG(arg);
|
||||||
|
|
||||||
|
tftp_state.timer++;
|
||||||
|
|
||||||
|
if (tftp_state.handle == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
sys_timeout(TFTP_TIMER_MSECS, tftp_tmr, NULL);
|
||||||
|
|
||||||
|
if ((tftp_state.timer - tftp_state.last_pkt) > (TFTP_TIMEOUT_MSECS / TFTP_TIMER_MSECS)) {
|
||||||
|
if ((tftp_state.last_data != NULL) && (tftp_state.retries < TFTP_MAX_RETRIES)) {
|
||||||
|
LWIP_DEBUGF(TFTP_DEBUG | LWIP_DBG_STATE, ("tftp: timeout, retrying\n"));
|
||||||
|
resend_data();
|
||||||
|
tftp_state.retries++;
|
||||||
|
} else {
|
||||||
|
LWIP_DEBUGF(TFTP_DEBUG | LWIP_DBG_STATE, ("tftp: timeout\n"));
|
||||||
|
close_handle();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @ingroup tftp
|
||||||
|
* Initialize TFTP server.
|
||||||
|
* @param ctx TFTP callback struct
|
||||||
|
*/
|
||||||
|
err_t
|
||||||
|
tftp_init(const struct tftp_context *ctx)
|
||||||
|
{
|
||||||
|
err_t ret;
|
||||||
|
|
||||||
|
struct udp_pcb *pcb = udp_new_ip_type(IPADDR_TYPE_ANY);
|
||||||
|
if (pcb == NULL) {
|
||||||
|
return ERR_MEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = udp_bind(pcb, IP_ANY_TYPE, TFTP_PORT);
|
||||||
|
if (ret != ERR_OK) {
|
||||||
|
udp_remove(pcb);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
tftp_state.handle = NULL;
|
||||||
|
tftp_state.port = 0;
|
||||||
|
tftp_state.ctx = ctx;
|
||||||
|
tftp_state.timer = 0;
|
||||||
|
tftp_state.last_data = NULL;
|
||||||
|
tftp_state.upcb = pcb;
|
||||||
|
|
||||||
|
udp_recv(pcb, recv, NULL);
|
||||||
|
|
||||||
|
return ERR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* LWIP_UDP */
|
|
@ -103,45 +103,6 @@
|
||||||
#define DNS_MAX_TTL 604800
|
#define DNS_MAX_TTL 604800
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* DNS protocol flags */
|
|
||||||
#define DNS_FLAG1_RESPONSE 0x80
|
|
||||||
#define DNS_FLAG1_OPCODE_STATUS 0x10
|
|
||||||
#define DNS_FLAG1_OPCODE_INVERSE 0x08
|
|
||||||
#define DNS_FLAG1_OPCODE_STANDARD 0x00
|
|
||||||
#define DNS_FLAG1_AUTHORATIVE 0x04
|
|
||||||
#define DNS_FLAG1_TRUNC 0x02
|
|
||||||
#define DNS_FLAG1_RD 0x01
|
|
||||||
#define DNS_FLAG2_RA 0x80
|
|
||||||
#define DNS_FLAG2_ERR_MASK 0x0f
|
|
||||||
#define DNS_FLAG2_ERR_NONE 0x00
|
|
||||||
#define DNS_FLAG2_ERR_NAME 0x03
|
|
||||||
|
|
||||||
/* DNS protocol states */
|
|
||||||
#define DNS_STATE_UNUSED 0
|
|
||||||
#define DNS_STATE_NEW 1
|
|
||||||
#define DNS_STATE_ASKING 2
|
|
||||||
#define DNS_STATE_DONE 3
|
|
||||||
|
|
||||||
#ifdef PACK_STRUCT_USE_INCLUDES
|
|
||||||
# include "arch/bpstruct.h"
|
|
||||||
#endif
|
|
||||||
PACK_STRUCT_BEGIN
|
|
||||||
/** DNS message header */
|
|
||||||
struct dns_hdr {
|
|
||||||
PACK_STRUCT_FIELD(u16_t id);
|
|
||||||
PACK_STRUCT_FIELD(u8_t flags1);
|
|
||||||
PACK_STRUCT_FIELD(u8_t flags2);
|
|
||||||
PACK_STRUCT_FIELD(u16_t numquestions);
|
|
||||||
PACK_STRUCT_FIELD(u16_t numanswers);
|
|
||||||
PACK_STRUCT_FIELD(u16_t numauthrr);
|
|
||||||
PACK_STRUCT_FIELD(u16_t numextrarr);
|
|
||||||
} PACK_STRUCT_STRUCT;
|
|
||||||
PACK_STRUCT_END
|
|
||||||
#ifdef PACK_STRUCT_USE_INCLUDES
|
|
||||||
# include "arch/epstruct.h"
|
|
||||||
#endif
|
|
||||||
#define SIZEOF_DNS_HDR 12
|
|
||||||
|
|
||||||
/** DNS query message structure.
|
/** DNS query message structure.
|
||||||
No packing needed: only used locally on the stack. */
|
No packing needed: only used locally on the stack. */
|
||||||
struct dns_query {
|
struct dns_query {
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
This directory contains application headers.
|
||||||
|
Every application shall provide one api file APP.h and optionally one options file APP_opts.h
|
|
@ -0,0 +1,115 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||||
|
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||||
|
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
|
* OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* This file is part of the lwIP TCP/IP stack.
|
||||||
|
*
|
||||||
|
* Author: Adam Dunkels <adam@sics.se>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef LWIP_HDR_APPS_FS_H
|
||||||
|
#define LWIP_HDR_APPS_FS_H
|
||||||
|
|
||||||
|
#include "httpd_opts.h"
|
||||||
|
#include "lwip/err.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define FS_READ_EOF -1
|
||||||
|
#define FS_READ_DELAYED -2
|
||||||
|
|
||||||
|
#if HTTPD_PRECALCULATED_CHECKSUM
|
||||||
|
struct fsdata_chksum {
|
||||||
|
u32_t offset;
|
||||||
|
u16_t chksum;
|
||||||
|
u16_t len;
|
||||||
|
};
|
||||||
|
#endif /* HTTPD_PRECALCULATED_CHECKSUM */
|
||||||
|
|
||||||
|
#define FS_FILE_FLAGS_HEADER_INCLUDED 0x01
|
||||||
|
#define FS_FILE_FLAGS_HEADER_PERSISTENT 0x02
|
||||||
|
|
||||||
|
struct fs_file {
|
||||||
|
const char *data;
|
||||||
|
int len;
|
||||||
|
int index;
|
||||||
|
void *pextension;
|
||||||
|
#if HTTPD_PRECALCULATED_CHECKSUM
|
||||||
|
const struct fsdata_chksum *chksum;
|
||||||
|
u16_t chksum_count;
|
||||||
|
#endif /* HTTPD_PRECALCULATED_CHECKSUM */
|
||||||
|
u8_t flags;
|
||||||
|
#if LWIP_HTTPD_CUSTOM_FILES
|
||||||
|
u8_t is_custom_file;
|
||||||
|
#endif /* LWIP_HTTPD_CUSTOM_FILES */
|
||||||
|
#if LWIP_HTTPD_FILE_STATE
|
||||||
|
void *state;
|
||||||
|
#endif /* LWIP_HTTPD_FILE_STATE */
|
||||||
|
};
|
||||||
|
|
||||||
|
#if LWIP_HTTPD_FS_ASYNC_READ
|
||||||
|
typedef void (*fs_wait_cb)(void *arg);
|
||||||
|
#endif /* LWIP_HTTPD_FS_ASYNC_READ */
|
||||||
|
|
||||||
|
err_t fs_open(struct fs_file *file, const char *name);
|
||||||
|
void fs_close(struct fs_file *file);
|
||||||
|
#if LWIP_HTTPD_DYNAMIC_FILE_READ
|
||||||
|
#if LWIP_HTTPD_FS_ASYNC_READ
|
||||||
|
int fs_read_async(struct fs_file *file, char *buffer, int count, fs_wait_cb callback_fn, void *callback_arg);
|
||||||
|
#else /* LWIP_HTTPD_FS_ASYNC_READ */
|
||||||
|
int fs_read(struct fs_file *file, char *buffer, int count);
|
||||||
|
#endif /* LWIP_HTTPD_FS_ASYNC_READ */
|
||||||
|
#endif /* LWIP_HTTPD_DYNAMIC_FILE_READ */
|
||||||
|
#if LWIP_HTTPD_FS_ASYNC_READ
|
||||||
|
int fs_is_file_ready(struct fs_file *file, fs_wait_cb callback_fn, void *callback_arg);
|
||||||
|
#endif /* LWIP_HTTPD_FS_ASYNC_READ */
|
||||||
|
int fs_bytes_left(struct fs_file *file);
|
||||||
|
|
||||||
|
#if LWIP_HTTPD_FILE_STATE
|
||||||
|
/** This user-defined function is called when a file is opened. */
|
||||||
|
void *fs_state_init(struct fs_file *file, const char *name);
|
||||||
|
/** This user-defined function is called when a file is closed. */
|
||||||
|
void fs_state_free(struct fs_file *file, void *state);
|
||||||
|
#endif /* #if LWIP_HTTPD_FILE_STATE */
|
||||||
|
|
||||||
|
struct fsdata_file {
|
||||||
|
const struct fsdata_file *next;
|
||||||
|
const unsigned char *name;
|
||||||
|
const unsigned char *data;
|
||||||
|
int len;
|
||||||
|
u8_t flags;
|
||||||
|
#if HTTPD_PRECALCULATED_CHECKSUM
|
||||||
|
u16_t chksum_count;
|
||||||
|
const struct fsdata_chksum *chksum;
|
||||||
|
#endif /* HTTPD_PRECALCULATED_CHECKSUM */
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* LWIP_HDR_APPS_FS_H */
|
|
@ -0,0 +1,236 @@
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* HTTP server
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||||
|
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||||
|
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
|
* OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* This file is part of the lwIP TCP/IP stack.
|
||||||
|
*
|
||||||
|
* Author: Adam Dunkels <adam@sics.se>
|
||||||
|
*
|
||||||
|
* This version of the file has been modified by Texas Instruments to offer
|
||||||
|
* simple server-side-include (SSI) and Common Gateway Interface (CGI)
|
||||||
|
* capability.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef LWIP_HDR_APPS_HTTPD_H
|
||||||
|
#define LWIP_HDR_APPS_HTTPD_H
|
||||||
|
|
||||||
|
#include "httpd_opts.h"
|
||||||
|
#include "lwip/err.h"
|
||||||
|
#include "lwip/pbuf.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if LWIP_HTTPD_CGI
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Function pointer for a CGI script handler.
|
||||||
|
*
|
||||||
|
* This function is called each time the HTTPD server is asked for a file
|
||||||
|
* whose name was previously registered as a CGI function using a call to
|
||||||
|
* http_set_cgi_handler. The iIndex parameter provides the index of the
|
||||||
|
* CGI within the ppcURLs array passed to http_set_cgi_handler. Parameters
|
||||||
|
* pcParam and pcValue provide access to the parameters provided along with
|
||||||
|
* the URI. iNumParams provides a count of the entries in the pcParam and
|
||||||
|
* pcValue arrays. Each entry in the pcParam array contains the name of a
|
||||||
|
* parameter with the corresponding entry in the pcValue array containing the
|
||||||
|
* value for that parameter. Note that pcParam may contain multiple elements
|
||||||
|
* with the same name if, for example, a multi-selection list control is used
|
||||||
|
* in the form generating the data.
|
||||||
|
*
|
||||||
|
* The function should return a pointer to a character string which is the
|
||||||
|
* path and filename of the response that is to be sent to the connected
|
||||||
|
* browser, for example "/thanks.htm" or "/response/error.ssi".
|
||||||
|
*
|
||||||
|
* The maximum number of parameters that will be passed to this function via
|
||||||
|
* iNumParams is defined by LWIP_HTTPD_MAX_CGI_PARAMETERS. Any parameters in the incoming
|
||||||
|
* HTTP request above this number will be discarded.
|
||||||
|
*
|
||||||
|
* Requests intended for use by this CGI mechanism must be sent using the GET
|
||||||
|
* method (which encodes all parameters within the URI rather than in a block
|
||||||
|
* later in the request). Attempts to use the POST method will result in the
|
||||||
|
* request being ignored.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
typedef const char *(*tCGIHandler)(int iIndex, int iNumParams, char *pcParam[],
|
||||||
|
char *pcValue[]);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Structure defining the base filename (URL) of a CGI and the associated
|
||||||
|
* function which is to be called when that URL is requested.
|
||||||
|
*/
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
const char *pcCGIName;
|
||||||
|
tCGIHandler pfnCGIHandler;
|
||||||
|
} tCGI;
|
||||||
|
|
||||||
|
void http_set_cgi_handlers(const tCGI *pCGIs, int iNumHandlers);
|
||||||
|
|
||||||
|
#endif /* LWIP_HTTPD_CGI */
|
||||||
|
|
||||||
|
#if LWIP_HTTPD_CGI || LWIP_HTTPD_CGI_SSI
|
||||||
|
|
||||||
|
#if LWIP_HTTPD_CGI_SSI
|
||||||
|
/** Define this generic CGI handler in your application.
|
||||||
|
* It is called once for every URI with parameters.
|
||||||
|
* The parameters can be stored to
|
||||||
|
*/
|
||||||
|
extern void httpd_cgi_handler(const char* uri, int iNumParams, char **pcParam, char **pcValue
|
||||||
|
#if defined(LWIP_HTTPD_FILE_STATE) && LWIP_HTTPD_FILE_STATE
|
||||||
|
, void *connection_state
|
||||||
|
#endif /* LWIP_HTTPD_FILE_STATE */
|
||||||
|
);
|
||||||
|
#endif /* LWIP_HTTPD_CGI_SSI */
|
||||||
|
|
||||||
|
#endif /* LWIP_HTTPD_CGI || LWIP_HTTPD_CGI_SSI */
|
||||||
|
|
||||||
|
#if LWIP_HTTPD_SSI
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Function pointer for the SSI tag handler callback.
|
||||||
|
*
|
||||||
|
* This function will be called each time the HTTPD server detects a tag of the
|
||||||
|
* form <!--#name--> in a .shtml, .ssi or .shtm file where "name" appears as
|
||||||
|
* one of the tags supplied to http_set_ssi_handler in the ppcTags array. The
|
||||||
|
* returned insert string, which will be appended after the the string
|
||||||
|
* "<!--#name-->" in file sent back to the client,should be written to pointer
|
||||||
|
* pcInsert. iInsertLen contains the size of the buffer pointed to by
|
||||||
|
* pcInsert. The iIndex parameter provides the zero-based index of the tag as
|
||||||
|
* found in the ppcTags array and identifies the tag that is to be processed.
|
||||||
|
*
|
||||||
|
* The handler returns the number of characters written to pcInsert excluding
|
||||||
|
* any terminating NULL or a negative number to indicate a failure (tag not
|
||||||
|
* recognized, for example).
|
||||||
|
*
|
||||||
|
* Note that the behavior of this SSI mechanism is somewhat different from the
|
||||||
|
* "normal" SSI processing as found in, for example, the Apache web server. In
|
||||||
|
* this case, the inserted text is appended following the SSI tag rather than
|
||||||
|
* replacing the tag entirely. This allows for an implementation that does not
|
||||||
|
* require significant additional buffering of output data yet which will still
|
||||||
|
* offer usable SSI functionality. One downside to this approach is when
|
||||||
|
* attempting to use SSI within JavaScript. The SSI tag is structured to
|
||||||
|
* resemble an HTML comment but this syntax does not constitute a comment
|
||||||
|
* within JavaScript and, hence, leaving the tag in place will result in
|
||||||
|
* problems in these cases. To work around this, any SSI tag which needs to
|
||||||
|
* output JavaScript code must do so in an encapsulated way, sending the whole
|
||||||
|
* HTML <script>...</script> section as a single include.
|
||||||
|
*/
|
||||||
|
typedef u16_t (*tSSIHandler)(
|
||||||
|
#if LWIP_HTTPD_SSI_RAW
|
||||||
|
const char* ssi_tag_name,
|
||||||
|
#else /* LWIP_HTTPD_SSI_RAW */
|
||||||
|
int iIndex,
|
||||||
|
#endif /* LWIP_HTTPD_SSI_RAW */
|
||||||
|
char *pcInsert, int iInsertLen
|
||||||
|
#if LWIP_HTTPD_SSI_MULTIPART
|
||||||
|
, u16_t current_tag_part, u16_t *next_tag_part
|
||||||
|
#endif /* LWIP_HTTPD_SSI_MULTIPART */
|
||||||
|
#if defined(LWIP_HTTPD_FILE_STATE) && LWIP_HTTPD_FILE_STATE
|
||||||
|
, void *connection_state
|
||||||
|
#endif /* LWIP_HTTPD_FILE_STATE */
|
||||||
|
);
|
||||||
|
|
||||||
|
/** Set the SSI handler function
|
||||||
|
* (if LWIP_HTTPD_SSI_RAW==1, only the first argument is used)
|
||||||
|
*/
|
||||||
|
void http_set_ssi_handler(tSSIHandler pfnSSIHandler,
|
||||||
|
const char **ppcTags, int iNumTags);
|
||||||
|
|
||||||
|
/** For LWIP_HTTPD_SSI_RAW==1, return this to indicate the tag is unknown.
|
||||||
|
* In this case, the webserver writes a warning into the page.
|
||||||
|
* You can also just return 0 to write nothing for unknown tags.
|
||||||
|
*/
|
||||||
|
#define HTTPD_SSI_TAG_UNKNOWN 0xFFFF
|
||||||
|
|
||||||
|
#endif /* LWIP_HTTPD_SSI */
|
||||||
|
|
||||||
|
#if LWIP_HTTPD_SUPPORT_POST
|
||||||
|
|
||||||
|
/* These functions must be implemented by the application */
|
||||||
|
|
||||||
|
/** Called when a POST request has been received. The application can decide
|
||||||
|
* whether to accept it or not.
|
||||||
|
*
|
||||||
|
* @param connection Unique connection identifier, valid until httpd_post_end
|
||||||
|
* is called.
|
||||||
|
* @param uri The HTTP header URI receiving the POST request.
|
||||||
|
* @param http_request The raw HTTP request (the first packet, normally).
|
||||||
|
* @param http_request_len Size of 'http_request'.
|
||||||
|
* @param content_len Content-Length from HTTP header.
|
||||||
|
* @param response_uri Filename of response file, to be filled when denying the
|
||||||
|
* request
|
||||||
|
* @param response_uri_len Size of the 'response_uri' buffer.
|
||||||
|
* @param post_auto_wnd Set this to 0 to let the callback code handle window
|
||||||
|
* updates by calling 'httpd_post_data_recved' (to throttle rx speed)
|
||||||
|
* default is 1 (httpd handles window updates automatically)
|
||||||
|
* @return ERR_OK: Accept the POST request, data may be passed in
|
||||||
|
* another err_t: Deny the POST request, send back 'bad request'.
|
||||||
|
*/
|
||||||
|
err_t httpd_post_begin(void *connection, const char *uri, const char *http_request,
|
||||||
|
u16_t http_request_len, int content_len, char *response_uri,
|
||||||
|
u16_t response_uri_len, u8_t *post_auto_wnd);
|
||||||
|
|
||||||
|
/** Called for each pbuf of data that has been received for a POST.
|
||||||
|
* ATTENTION: The application is responsible for freeing the pbufs passed in!
|
||||||
|
*
|
||||||
|
* @param connection Unique connection identifier.
|
||||||
|
* @param p Received data.
|
||||||
|
* @return ERR_OK: Data accepted.
|
||||||
|
* another err_t: Data denied, http_post_get_response_uri will be called.
|
||||||
|
*/
|
||||||
|
err_t httpd_post_receive_data(void *connection, struct pbuf *p);
|
||||||
|
|
||||||
|
/** Called when all data is received or when the connection is closed.
|
||||||
|
* The application must return the filename/URI of a file to send in response
|
||||||
|
* to this POST request. If the response_uri buffer is untouched, a 404
|
||||||
|
* response is returned.
|
||||||
|
*
|
||||||
|
* @param connection Unique connection identifier.
|
||||||
|
* @param response_uri Filename of response file, to be filled when denying the request
|
||||||
|
* @param response_uri_len Size of the 'response_uri' buffer.
|
||||||
|
*/
|
||||||
|
void httpd_post_finished(void *connection, char *response_uri, u16_t response_uri_len);
|
||||||
|
|
||||||
|
#if LWIP_HTTPD_POST_MANUAL_WND
|
||||||
|
void httpd_post_data_recved(void *connection, u16_t recved_len);
|
||||||
|
#endif /* LWIP_HTTPD_POST_MANUAL_WND */
|
||||||
|
|
||||||
|
#endif /* LWIP_HTTPD_SUPPORT_POST */
|
||||||
|
|
||||||
|
void httpd_init(void);
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* LWIP_HTTPD_H */
|
|
@ -0,0 +1,327 @@
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* HTTP server options list
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||||
|
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||||
|
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
|
* OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* This file is part of the lwIP TCP/IP stack.
|
||||||
|
*
|
||||||
|
* Author: Adam Dunkels <adam@sics.se>
|
||||||
|
*
|
||||||
|
* This version of the file has been modified by Texas Instruments to offer
|
||||||
|
* simple server-side-include (SSI) and Common Gateway Interface (CGI)
|
||||||
|
* capability.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef LWIP_HDR_APPS_HTTPD_OPTS_H
|
||||||
|
#define LWIP_HDR_APPS_HTTPD_OPTS_H
|
||||||
|
|
||||||
|
#include "lwip/opt.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @defgroup httpd_opts Options
|
||||||
|
* @ingroup httpd
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** Set this to 1 to support CGI (old style) */
|
||||||
|
#if !defined LWIP_HTTPD_CGI || defined __DOXYGEN__
|
||||||
|
#define LWIP_HTTPD_CGI 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** Set this to 1 to support CGI (new style) */
|
||||||
|
#if !defined LWIP_HTTPD_CGI_SSI || defined __DOXYGEN__
|
||||||
|
#define LWIP_HTTPD_CGI_SSI 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** Set this to 1 to support SSI (Server-Side-Includes) */
|
||||||
|
#if !defined LWIP_HTTPD_SSI || defined __DOXYGEN__
|
||||||
|
#define LWIP_HTTPD_SSI 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** Set this to 1 to implement an SSI tag handler callback that gets a const char*
|
||||||
|
* to the tag (instead of an index into a pre-registered array of known tags) */
|
||||||
|
#if !defined LWIP_HTTPD_SSI_RAW || defined __DOXYGEN__
|
||||||
|
#define LWIP_HTTPD_SSI_RAW 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** Set this to 1 to support HTTP POST */
|
||||||
|
#if !defined LWIP_HTTPD_SUPPORT_POST || defined __DOXYGEN__
|
||||||
|
#define LWIP_HTTPD_SUPPORT_POST 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* The maximum number of parameters that the CGI handler can be sent. */
|
||||||
|
#if !defined LWIP_HTTPD_MAX_CGI_PARAMETERS || defined __DOXYGEN__
|
||||||
|
#define LWIP_HTTPD_MAX_CGI_PARAMETERS 16
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** LWIP_HTTPD_SSI_MULTIPART==1: SSI handler function is called with 2 more
|
||||||
|
* arguments indicating a counter for insert string that are too long to be
|
||||||
|
* inserted at once: the SSI handler function must then set 'next_tag_part'
|
||||||
|
* which will be passed back to it in the next call. */
|
||||||
|
#if !defined LWIP_HTTPD_SSI_MULTIPART || defined __DOXYGEN__
|
||||||
|
#define LWIP_HTTPD_SSI_MULTIPART 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* The maximum length of the string comprising the tag name */
|
||||||
|
#if !defined LWIP_HTTPD_MAX_TAG_NAME_LEN || defined __DOXYGEN__
|
||||||
|
#define LWIP_HTTPD_MAX_TAG_NAME_LEN 8
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* The maximum length of string that can be returned to replace any given tag */
|
||||||
|
#if !defined LWIP_HTTPD_MAX_TAG_INSERT_LEN || defined __DOXYGEN__
|
||||||
|
#define LWIP_HTTPD_MAX_TAG_INSERT_LEN 192
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined LWIP_HTTPD_POST_MANUAL_WND || defined __DOXYGEN__
|
||||||
|
#define LWIP_HTTPD_POST_MANUAL_WND 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** This string is passed in the HTTP header as "Server: " */
|
||||||
|
#if !defined HTTPD_SERVER_AGENT || defined __DOXYGEN__
|
||||||
|
#define HTTPD_SERVER_AGENT "lwIP/" LWIP_VERSION_STRING " (http://savannah.nongnu.org/projects/lwip)"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** Set this to 1 if you want to include code that creates HTTP headers
|
||||||
|
* at runtime. Default is off: HTTP headers are then created statically
|
||||||
|
* by the makefsdata tool. Static headers mean smaller code size, but
|
||||||
|
* the (readonly) fsdata will grow a bit as every file includes the HTTP
|
||||||
|
* header. */
|
||||||
|
#if !defined LWIP_HTTPD_DYNAMIC_HEADERS || defined __DOXYGEN__
|
||||||
|
#define LWIP_HTTPD_DYNAMIC_HEADERS 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined HTTPD_DEBUG || defined __DOXYGEN__
|
||||||
|
#define HTTPD_DEBUG LWIP_DBG_OFF
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** Set this to 1 to use a memp pool for allocating
|
||||||
|
* struct http_state instead of the heap.
|
||||||
|
*/
|
||||||
|
#if !defined HTTPD_USE_MEM_POOL || defined __DOXYGEN__
|
||||||
|
#define HTTPD_USE_MEM_POOL 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** The server port for HTTPD to use */
|
||||||
|
#if !defined HTTPD_SERVER_PORT || defined __DOXYGEN__
|
||||||
|
#define HTTPD_SERVER_PORT 80
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** Maximum retries before the connection is aborted/closed.
|
||||||
|
* - number of times pcb->poll is called -> default is 4*500ms = 2s;
|
||||||
|
* - reset when pcb->sent is called
|
||||||
|
*/
|
||||||
|
#if !defined HTTPD_MAX_RETRIES || defined __DOXYGEN__
|
||||||
|
#define HTTPD_MAX_RETRIES 4
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** The poll delay is X*500ms */
|
||||||
|
#if !defined HTTPD_POLL_INTERVAL || defined __DOXYGEN__
|
||||||
|
#define HTTPD_POLL_INTERVAL 4
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** Priority for tcp pcbs created by HTTPD (very low by default).
|
||||||
|
* Lower priorities get killed first when running out of memory.
|
||||||
|
*/
|
||||||
|
#if !defined HTTPD_TCP_PRIO || defined __DOXYGEN__
|
||||||
|
#define HTTPD_TCP_PRIO TCP_PRIO_MIN
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** Set this to 1 to enable timing each file sent */
|
||||||
|
#if !defined LWIP_HTTPD_TIMING || defined __DOXYGEN__
|
||||||
|
#define LWIP_HTTPD_TIMING 0
|
||||||
|
#endif
|
||||||
|
/** Set this to 1 to enable timing each file sent */
|
||||||
|
#if !defined HTTPD_DEBUG_TIMING || defined __DOXYGEN__
|
||||||
|
#define HTTPD_DEBUG_TIMING LWIP_DBG_OFF
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** Set this to one to show error pages when parsing a request fails instead
|
||||||
|
of simply closing the connection. */
|
||||||
|
#if !defined LWIP_HTTPD_SUPPORT_EXTSTATUS || defined __DOXYGEN__
|
||||||
|
#define LWIP_HTTPD_SUPPORT_EXTSTATUS 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** Set this to 0 to drop support for HTTP/0.9 clients (to save some bytes) */
|
||||||
|
#if !defined LWIP_HTTPD_SUPPORT_V09 || defined __DOXYGEN__
|
||||||
|
#define LWIP_HTTPD_SUPPORT_V09 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** Set this to 1 to enable HTTP/1.1 persistent connections.
|
||||||
|
* ATTENTION: If the generated file system includes HTTP headers, these must
|
||||||
|
* include the "Connection: keep-alive" header (pass argument "-11" to makefsdata).
|
||||||
|
*/
|
||||||
|
#if !defined LWIP_HTTPD_SUPPORT_11_KEEPALIVE || defined __DOXYGEN__
|
||||||
|
#define LWIP_HTTPD_SUPPORT_11_KEEPALIVE 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** Set this to 1 to support HTTP request coming in in multiple packets/pbufs */
|
||||||
|
#if !defined LWIP_HTTPD_SUPPORT_REQUESTLIST || defined __DOXYGEN__
|
||||||
|
#define LWIP_HTTPD_SUPPORT_REQUESTLIST 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if LWIP_HTTPD_SUPPORT_REQUESTLIST
|
||||||
|
/** Number of rx pbufs to enqueue to parse an incoming request (up to the first
|
||||||
|
newline) */
|
||||||
|
#if !defined LWIP_HTTPD_REQ_QUEUELEN || defined __DOXYGEN__
|
||||||
|
#define LWIP_HTTPD_REQ_QUEUELEN 5
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** Number of (TCP payload-) bytes (in pbufs) to enqueue to parse and incoming
|
||||||
|
request (up to the first double-newline) */
|
||||||
|
#if !defined LWIP_HTTPD_REQ_BUFSIZE || defined __DOXYGEN__
|
||||||
|
#define LWIP_HTTPD_REQ_BUFSIZE LWIP_HTTPD_MAX_REQ_LENGTH
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** Defines the maximum length of a HTTP request line (up to the first CRLF,
|
||||||
|
copied from pbuf into this a global buffer when pbuf- or packet-queues
|
||||||
|
are received - otherwise the input pbuf is used directly) */
|
||||||
|
#if !defined LWIP_HTTPD_MAX_REQ_LENGTH || defined __DOXYGEN__
|
||||||
|
#define LWIP_HTTPD_MAX_REQ_LENGTH LWIP_MIN(1023, (LWIP_HTTPD_REQ_QUEUELEN * PBUF_POOL_BUFSIZE))
|
||||||
|
#endif
|
||||||
|
#endif /* LWIP_HTTPD_SUPPORT_REQUESTLIST */
|
||||||
|
|
||||||
|
/** This is the size of a static buffer used when URIs end with '/'.
|
||||||
|
* In this buffer, the directory requested is concatenated with all the
|
||||||
|
* configured default file names.
|
||||||
|
* Set to 0 to disable checking default filenames on non-root directories.
|
||||||
|
*/
|
||||||
|
#if !defined LWIP_HTTPD_MAX_REQUEST_URI_LEN || defined __DOXYGEN__
|
||||||
|
#define LWIP_HTTPD_MAX_REQUEST_URI_LEN 63
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** Maximum length of the filename to send as response to a POST request,
|
||||||
|
* filled in by the application when a POST is finished.
|
||||||
|
*/
|
||||||
|
#if !defined LWIP_HTTPD_POST_MAX_RESPONSE_URI_LEN || defined __DOXYGEN__
|
||||||
|
#define LWIP_HTTPD_POST_MAX_RESPONSE_URI_LEN 63
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** Set this to 0 to not send the SSI tag (default is on, so the tag will
|
||||||
|
* be sent in the HTML page */
|
||||||
|
#if !defined LWIP_HTTPD_SSI_INCLUDE_TAG || defined __DOXYGEN__
|
||||||
|
#define LWIP_HTTPD_SSI_INCLUDE_TAG 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** Set this to 1 to call tcp_abort when tcp_close fails with memory error.
|
||||||
|
* This can be used to prevent consuming all memory in situations where the
|
||||||
|
* HTTP server has low priority compared to other communication. */
|
||||||
|
#if !defined LWIP_HTTPD_ABORT_ON_CLOSE_MEM_ERROR || defined __DOXYGEN__
|
||||||
|
#define LWIP_HTTPD_ABORT_ON_CLOSE_MEM_ERROR 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** Set this to 1 to kill the oldest connection when running out of
|
||||||
|
* memory for 'struct http_state' or 'struct http_ssi_state'.
|
||||||
|
* ATTENTION: This puts all connections on a linked list, so may be kind of slow.
|
||||||
|
*/
|
||||||
|
#if !defined LWIP_HTTPD_KILL_OLD_ON_CONNECTIONS_EXCEEDED || defined __DOXYGEN__
|
||||||
|
#define LWIP_HTTPD_KILL_OLD_ON_CONNECTIONS_EXCEEDED 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** Set this to 1 to send URIs without extension without headers
|
||||||
|
* (who uses this at all??) */
|
||||||
|
#if !defined LWIP_HTTPD_OMIT_HEADER_FOR_EXTENSIONLESS_URI || defined __DOXYGEN__
|
||||||
|
#define LWIP_HTTPD_OMIT_HEADER_FOR_EXTENSIONLESS_URI 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** Default: Tags are sent from struct http_state and are therefore volatile */
|
||||||
|
#if !defined HTTP_IS_TAG_VOLATILE || defined __DOXYGEN__
|
||||||
|
#define HTTP_IS_TAG_VOLATILE(ptr) TCP_WRITE_FLAG_COPY
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* By default, the httpd is limited to send 2*pcb->mss to keep resource usage low
|
||||||
|
when http is not an important protocol in the device. */
|
||||||
|
#if !defined HTTPD_LIMIT_SENDING_TO_2MSS || defined __DOXYGEN__
|
||||||
|
#define HTTPD_LIMIT_SENDING_TO_2MSS 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Define this to a function that returns the maximum amount of data to enqueue.
|
||||||
|
The function have this signature: u16_t fn(struct tcp_pcb* pcb); */
|
||||||
|
#if !defined HTTPD_MAX_WRITE_LEN || defined __DOXYGEN__
|
||||||
|
#if HTTPD_LIMIT_SENDING_TO_2MSS
|
||||||
|
#define HTTPD_MAX_WRITE_LEN(pcb) (2 * tcp_mss(pcb))
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*------------------- FS OPTIONS -------------------*/
|
||||||
|
|
||||||
|
/** Set this to 1 and provide the functions:
|
||||||
|
* - "int fs_open_custom(struct fs_file *file, const char *name)"
|
||||||
|
* Called first for every opened file to allow opening files
|
||||||
|
* that are not included in fsdata(_custom).c
|
||||||
|
* - "void fs_close_custom(struct fs_file *file)"
|
||||||
|
* Called to free resources allocated by fs_open_custom().
|
||||||
|
*/
|
||||||
|
#if !defined LWIP_HTTPD_CUSTOM_FILES || defined __DOXYGEN__
|
||||||
|
#define LWIP_HTTPD_CUSTOM_FILES 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** Set this to 1 to support fs_read() to dynamically read file data.
|
||||||
|
* Without this (default=off), only one-block files are supported,
|
||||||
|
* and the contents must be ready after fs_open().
|
||||||
|
*/
|
||||||
|
#if !defined LWIP_HTTPD_DYNAMIC_FILE_READ || defined __DOXYGEN__
|
||||||
|
#define LWIP_HTTPD_DYNAMIC_FILE_READ 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** Set this to 1 to include an application state argument per file
|
||||||
|
* that is opened. This allows to keep a state per connection/file.
|
||||||
|
*/
|
||||||
|
#if !defined LWIP_HTTPD_FILE_STATE || defined __DOXYGEN__
|
||||||
|
#define LWIP_HTTPD_FILE_STATE 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** HTTPD_PRECALCULATED_CHECKSUM==1: include precompiled checksums for
|
||||||
|
* predefined (MSS-sized) chunks of the files to prevent having to calculate
|
||||||
|
* the checksums at runtime. */
|
||||||
|
#if !defined HTTPD_PRECALCULATED_CHECKSUM || defined __DOXYGEN__
|
||||||
|
#define HTTPD_PRECALCULATED_CHECKSUM 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** LWIP_HTTPD_FS_ASYNC_READ==1: support asynchronous read operations
|
||||||
|
* (fs_read_async returns FS_READ_DELAYED and calls a callback when finished).
|
||||||
|
*/
|
||||||
|
#if !defined LWIP_HTTPD_FS_ASYNC_READ || defined __DOXYGEN__
|
||||||
|
#define LWIP_HTTPD_FS_ASYNC_READ 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** Filename (including path) to use as FS data file */
|
||||||
|
#if !defined HTTPD_FSDATA_FILE || defined __DOXYGEN__
|
||||||
|
/* HTTPD_USE_CUSTOM_FSDATA: Compatibility with deprecated lwIP option */
|
||||||
|
#if defined(HTTPD_USE_CUSTOM_FSDATA) && (HTTPD_USE_CUSTOM_FSDATA != 0)
|
||||||
|
#define HTTPD_FSDATA_FILE "fsdata_custom.c"
|
||||||
|
#else
|
||||||
|
#define HTTPD_FSDATA_FILE "fsdata.c"
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
#endif /* LWIP_HDR_APPS_HTTPD_OPTS_H */
|
|
@ -0,0 +1,84 @@
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* lwIP iPerf server implementation
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2014 Simon Goldschmidt
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||||
|
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||||
|
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
|
* OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* This file is part of the lwIP TCP/IP stack.
|
||||||
|
*
|
||||||
|
* Author: Simon Goldschmidt
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef LWIP_HDR_APPS_LWIPERF_H
|
||||||
|
#define LWIP_HDR_APPS_LWIPERF_H
|
||||||
|
|
||||||
|
#include "lwip/opt.h"
|
||||||
|
#include "lwip/ip_addr.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define LWIPERF_TCP_PORT_DEFAULT 5001
|
||||||
|
|
||||||
|
/** lwIPerf test results */
|
||||||
|
enum lwiperf_report_type
|
||||||
|
{
|
||||||
|
/** The server side test is done */
|
||||||
|
LWIPERF_TCP_DONE_SERVER,
|
||||||
|
/** The client side test is done */
|
||||||
|
LWIPERF_TCP_DONE_CLIENT,
|
||||||
|
/** Local error lead to test abort */
|
||||||
|
LWIPERF_TCP_ABORTED_LOCAL,
|
||||||
|
/** Data check error lead to test abort */
|
||||||
|
LWIPERF_TCP_ABORTED_LOCAL_DATAERROR,
|
||||||
|
/** Transmit error lead to test abort */
|
||||||
|
LWIPERF_TCP_ABORTED_LOCAL_TXERROR,
|
||||||
|
/** Remote side aborted the test */
|
||||||
|
LWIPERF_TCP_ABORTED_REMOTE
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Prototype of a report function that is called when a session is finished.
|
||||||
|
This report function can show the test results.
|
||||||
|
@param report_type contains the test result */
|
||||||
|
typedef void (*lwiperf_report_fn)(void *arg, enum lwiperf_report_type report_type,
|
||||||
|
const ip_addr_t* local_addr, u16_t local_port, const ip_addr_t* remote_addr, u16_t remote_port,
|
||||||
|
u32_t bytes_transferred, u32_t ms_duration, u32_t bandwidth_kbitpsec);
|
||||||
|
|
||||||
|
|
||||||
|
void* lwiperf_start_tcp_server(const ip_addr_t* local_addr, u16_t local_port,
|
||||||
|
lwiperf_report_fn report_fn, void* report_arg);
|
||||||
|
void* lwiperf_start_tcp_server_default(lwiperf_report_fn report_fn, void* report_arg);
|
||||||
|
void lwiperf_abort(void* lwiperf_session);
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* LWIP_HDR_APPS_LWIPERF_H */
|
|
@ -0,0 +1,69 @@
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* MDNS responder
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2015 Verisure Innovation AB
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||||
|
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||||
|
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
|
* OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* This file is part of the lwIP TCP/IP stack.
|
||||||
|
*
|
||||||
|
* Author: Erik Ekman <erik@kryo.se>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef LWIP_HDR_MDNS_H
|
||||||
|
#define LWIP_HDR_MDNS_H
|
||||||
|
|
||||||
|
#include "lwip/apps/mdns_opts.h"
|
||||||
|
#include "lwip/netif.h"
|
||||||
|
|
||||||
|
#if LWIP_MDNS_RESPONDER
|
||||||
|
|
||||||
|
enum mdns_sd_proto {
|
||||||
|
DNSSD_PROTO_UDP = 0,
|
||||||
|
DNSSD_PROTO_TCP = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
#define MDNS_LABEL_MAXLEN 63
|
||||||
|
|
||||||
|
struct mdns_host;
|
||||||
|
struct mdns_service;
|
||||||
|
|
||||||
|
/** Callback function to add text to a reply, called when generating the reply */
|
||||||
|
typedef void (*service_get_txt_fn_t)(struct mdns_service *service, void *txt_userdata);
|
||||||
|
|
||||||
|
void mdns_resp_init(void);
|
||||||
|
|
||||||
|
err_t mdns_resp_add_netif(struct netif *netif, const char *hostname, u32_t dns_ttl);
|
||||||
|
err_t mdns_resp_remove_netif(struct netif *netif);
|
||||||
|
|
||||||
|
err_t mdns_resp_add_service(struct netif *netif, const char *name, const char *service, enum mdns_sd_proto proto, u16_t port, u32_t dns_ttl, service_get_txt_fn_t txt_fn, void *txt_userdata);
|
||||||
|
err_t mdns_resp_add_service_txtitem(struct mdns_service *service, const char *txt, u8_t txt_len);
|
||||||
|
void mdns_resp_netif_settings_changed(struct netif *netif);
|
||||||
|
|
||||||
|
#endif /* LWIP_MDNS_RESPONDER */
|
||||||
|
|
||||||
|
#endif /* LWIP_HDR_MDNS_H */
|
|
@ -0,0 +1,74 @@
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* MDNS responder
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2015 Verisure Innovation AB
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||||
|
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||||
|
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
|
* OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* This file is part of the lwIP TCP/IP stack.
|
||||||
|
*
|
||||||
|
* Author: Erik Ekman <erik@kryo.se>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef LWIP_HDR_APPS_MDNS_OPTS_H
|
||||||
|
#define LWIP_HDR_APPS_MDNS_OPTS_H
|
||||||
|
|
||||||
|
#include "lwip/opt.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @defgroup mdns_opts Options
|
||||||
|
* @ingroup mdns
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* LWIP_MDNS_RESPONDER==1: Turn on multicast DNS module. UDP must be available for MDNS
|
||||||
|
* transport. IGMP is needed for IPv4 multicast.
|
||||||
|
*/
|
||||||
|
#ifndef LWIP_MDNS_RESPONDER
|
||||||
|
#define LWIP_MDNS_RESPONDER 1
|
||||||
|
#endif /* LWIP_MDNS_RESPONDER */
|
||||||
|
|
||||||
|
/** The maximum number of services per netif */
|
||||||
|
#ifndef MDNS_MAX_SERVICES
|
||||||
|
#define MDNS_MAX_SERVICES 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MDNS_DEBUG: Enable debugging for multicast DNS.
|
||||||
|
*/
|
||||||
|
#ifndef MDNS_DEBUG
|
||||||
|
#define MDNS_DEBUG LWIP_DBG_OFF
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
#endif /* LWIP_HDR_APPS_MDNS_OPTS_H */
|
||||||
|
|
|
@ -0,0 +1,66 @@
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* MDNS responder private definitions
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2015 Verisure Innovation AB
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||||
|
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||||
|
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
|
* OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* This file is part of the lwIP TCP/IP stack.
|
||||||
|
*
|
||||||
|
* Author: Erik Ekman <erik@kryo.se>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef LWIP_HDR_MDNS_PRIV_H
|
||||||
|
#define LWIP_HDR_MDNS_PRIV_H
|
||||||
|
|
||||||
|
#include "lwip/apps/mdns_opts.h"
|
||||||
|
#include "lwip/pbuf.h"
|
||||||
|
|
||||||
|
#if LWIP_MDNS_RESPONDER
|
||||||
|
|
||||||
|
/* Domain struct and methods - visible for unit tests */
|
||||||
|
|
||||||
|
#define MDNS_DOMAIN_MAXLEN 256
|
||||||
|
#define MDNS_READNAME_ERROR 0xFFFF
|
||||||
|
|
||||||
|
struct mdns_domain {
|
||||||
|
/* Encoded domain name */
|
||||||
|
u8_t name[MDNS_DOMAIN_MAXLEN];
|
||||||
|
/* Total length of domain name, including zero */
|
||||||
|
u16_t length;
|
||||||
|
/* Set if compression of this domain is not allowed */
|
||||||
|
u8_t skip_compression;
|
||||||
|
};
|
||||||
|
|
||||||
|
err_t mdns_domain_add_label(struct mdns_domain *domain, const char *label, u8_t len);
|
||||||
|
u16_t mdns_readname(struct pbuf *p, u16_t offset, struct mdns_domain *domain);
|
||||||
|
int mdns_domain_eq(struct mdns_domain *a, struct mdns_domain *b);
|
||||||
|
u16_t mdns_compress_domain(struct pbuf *pbuf, u16_t *offset, struct mdns_domain *domain);
|
||||||
|
|
||||||
|
#endif /* LWIP_MDNS_RESPONDER */
|
||||||
|
|
||||||
|
#endif /* LWIP_HDR_MDNS_PRIV_H */
|
|
@ -0,0 +1,243 @@
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* MQTT client
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2016 Erik Andersson
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||||
|
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||||
|
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
|
* OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* This file is part of the lwIP TCP/IP stack.
|
||||||
|
*
|
||||||
|
* Author: Erik Andersson
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef LWIP_HDR_APPS_MQTT_CLIENT_H
|
||||||
|
#define LWIP_HDR_APPS_MQTT_CLIENT_H
|
||||||
|
|
||||||
|
#include "lwip/apps/mqtt_opts.h"
|
||||||
|
#include "lwip/err.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct mqtt_client_t mqtt_client_t;
|
||||||
|
|
||||||
|
/** @ingroup mqtt
|
||||||
|
* Default MQTT port */
|
||||||
|
#define MQTT_PORT 1883
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------------------------- */
|
||||||
|
/* Connection with server */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup mqtt
|
||||||
|
* Client information and connection parameters */
|
||||||
|
struct mqtt_connect_client_info_t {
|
||||||
|
/** Client identifier, must be set by caller */
|
||||||
|
const char *client_id;
|
||||||
|
/** User name and password, set to NULL if not used */
|
||||||
|
const char* client_user;
|
||||||
|
const char* client_pass;
|
||||||
|
/** keep alive time in seconds, 0 to disable keep alive functionality*/
|
||||||
|
u16_t keep_alive;
|
||||||
|
/** will topic, set to NULL if will is not to be used,
|
||||||
|
will_msg, will_qos and will retain are then ignored */
|
||||||
|
const char* will_topic;
|
||||||
|
const char* will_msg;
|
||||||
|
u8_t will_qos;
|
||||||
|
u8_t will_retain;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup mqtt
|
||||||
|
* Connection status codes */
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
MQTT_CONNECT_ACCEPTED = 0,
|
||||||
|
MQTT_CONNECT_REFUSED_PROTOCOL_VERSION = 1,
|
||||||
|
MQTT_CONNECT_REFUSED_IDENTIFIER = 2,
|
||||||
|
MQTT_CONNECT_REFUSED_SERVER = 3,
|
||||||
|
MQTT_CONNECT_REFUSED_USERNAME_PASS = 4,
|
||||||
|
MQTT_CONNECT_REFUSED_NOT_AUTHORIZED_ = 5,
|
||||||
|
MQTT_CONNECT_DISCONNECTED = 256,
|
||||||
|
MQTT_CONNECT_TIMEOUT = 257
|
||||||
|
} mqtt_connection_status_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup mqtt
|
||||||
|
* Function prototype for mqtt connection status callback. Called when
|
||||||
|
* client has connected to the server after initiating a mqtt connection attempt by
|
||||||
|
* calling mqtt_connect() or when connection is closed by server or an error
|
||||||
|
*
|
||||||
|
* @param client MQTT client itself
|
||||||
|
* @param arg Additional argument to pass to the callback function
|
||||||
|
* @param status Connect result code or disconnection notification @see mqtt_connection_status_t
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
typedef void (*mqtt_connection_cb_t)(mqtt_client_t *client, void *arg, mqtt_connection_status_t status);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup mqtt
|
||||||
|
* Data callback flags */
|
||||||
|
enum {
|
||||||
|
/** Flag set when last fragment of data arrives in data callback */
|
||||||
|
MQTT_DATA_FLAG_LAST = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup mqtt
|
||||||
|
* Function prototype for MQTT incoming publish data callback function. Called when data
|
||||||
|
* arrives to a subscribed topic @see mqtt_subscribe
|
||||||
|
*
|
||||||
|
* @param arg Additional argument to pass to the callback function
|
||||||
|
* @param data User data, pointed object, data may not be referenced after callback return,
|
||||||
|
NULL is passed when all publish data are delivered
|
||||||
|
* @param len Length of publish data fragment
|
||||||
|
* @param flags MQTT_DATA_FLAG_LAST set when this call contains the last part of data from publish message
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
typedef void (*mqtt_incoming_data_cb_t)(void *arg, const u8_t *data, u16_t len, u8_t flags);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup mqtt
|
||||||
|
* Function prototype for MQTT incoming publish function. Called when an incoming publish
|
||||||
|
* arrives to a subscribed topic @see mqtt_subscribe
|
||||||
|
*
|
||||||
|
* @param arg Additional argument to pass to the callback function
|
||||||
|
* @param topic Zero terminated Topic text string, topic may not be referenced after callback return
|
||||||
|
* @param tot_len Total length of publish data, if set to 0 (no publish payload) data callback will not be invoked
|
||||||
|
*/
|
||||||
|
typedef void (*mqtt_incoming_publish_cb_t)(void *arg, const char *topic, u32_t tot_len);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup mqtt
|
||||||
|
* Function prototype for mqtt request callback. Called when a subscribe, unsubscribe
|
||||||
|
* or publish request has completed
|
||||||
|
* @param arg Pointer to user data supplied when invoking request
|
||||||
|
* @param err ERR_OK on success
|
||||||
|
* ERR_TIMEOUT if no response was received within timeout,
|
||||||
|
* ERR_ABRT if (un)subscribe was denied
|
||||||
|
*/
|
||||||
|
typedef void (*mqtt_request_cb_t)(void *arg, err_t err);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pending request item, binds application callback to pending server requests
|
||||||
|
*/
|
||||||
|
struct mqtt_request_t
|
||||||
|
{
|
||||||
|
/** Next item in list, NULL means this is the last in chain,
|
||||||
|
next pointing at itself means request is unallocated */
|
||||||
|
struct mqtt_request_t *next;
|
||||||
|
/** Callback to upper layer */
|
||||||
|
mqtt_request_cb_t cb;
|
||||||
|
void *arg;
|
||||||
|
/** MQTT packet identifier */
|
||||||
|
u16_t pkt_id;
|
||||||
|
/** Expire time relative to element before this */
|
||||||
|
u16_t timeout_diff;
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Ring buffer */
|
||||||
|
struct mqtt_ringbuf_t {
|
||||||
|
u16_t put;
|
||||||
|
u16_t get;
|
||||||
|
u8_t buf[MQTT_OUTPUT_RINGBUF_SIZE];
|
||||||
|
};
|
||||||
|
|
||||||
|
/** MQTT client */
|
||||||
|
struct mqtt_client_t
|
||||||
|
{
|
||||||
|
/** Timers and timeouts */
|
||||||
|
u16_t cyclic_tick;
|
||||||
|
u16_t keep_alive;
|
||||||
|
u16_t server_watchdog;
|
||||||
|
/** Packet identifier generator*/
|
||||||
|
u16_t pkt_id_seq;
|
||||||
|
/** Packet identifier of pending incoming publish */
|
||||||
|
u16_t inpub_pkt_id;
|
||||||
|
/** Connection state */
|
||||||
|
u8_t conn_state;
|
||||||
|
struct tcp_pcb *conn;
|
||||||
|
/** Connection callback */
|
||||||
|
void *connect_arg;
|
||||||
|
mqtt_connection_cb_t connect_cb;
|
||||||
|
/** Pending requests to server */
|
||||||
|
struct mqtt_request_t *pend_req_queue;
|
||||||
|
struct mqtt_request_t req_list[MQTT_REQ_MAX_IN_FLIGHT];
|
||||||
|
void *inpub_arg;
|
||||||
|
/** Incoming data callback */
|
||||||
|
mqtt_incoming_data_cb_t data_cb;
|
||||||
|
mqtt_incoming_publish_cb_t pub_cb;
|
||||||
|
/** Input */
|
||||||
|
u32_t msg_idx;
|
||||||
|
u8_t rx_buffer[MQTT_VAR_HEADER_BUFFER_LEN];
|
||||||
|
/** Output ring-buffer */
|
||||||
|
struct mqtt_ringbuf_t output;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/** Connect to server */
|
||||||
|
err_t mqtt_client_connect(mqtt_client_t *client, const ip_addr_t *ipaddr, u16_t port, mqtt_connection_cb_t cb, void *arg,
|
||||||
|
const struct mqtt_connect_client_info_t *client_info);
|
||||||
|
|
||||||
|
/** Disconnect from server */
|
||||||
|
void mqtt_disconnect(mqtt_client_t *client);
|
||||||
|
|
||||||
|
/** Create new client */
|
||||||
|
mqtt_client_t *mqtt_client_new(void);
|
||||||
|
|
||||||
|
/** Check connection status */
|
||||||
|
u8_t mqtt_client_is_connected(mqtt_client_t *client);
|
||||||
|
|
||||||
|
/** Set callback to call for incoming publish */
|
||||||
|
void mqtt_set_inpub_callback(mqtt_client_t *client, mqtt_incoming_publish_cb_t,
|
||||||
|
mqtt_incoming_data_cb_t data_cb, void *arg);
|
||||||
|
|
||||||
|
/** Common function for subscribe and unsubscribe */
|
||||||
|
err_t mqtt_sub_unsub(mqtt_client_t *client, const char *topic, u8_t qos, mqtt_request_cb_t cb, void *arg, u8_t sub);
|
||||||
|
|
||||||
|
/** @ingroup mqtt
|
||||||
|
*Subscribe to topic */
|
||||||
|
#define mqtt_subscribe(client, topic, qos, cb, arg) mqtt_sub_unsub(client, topic, qos, cb, arg, 1)
|
||||||
|
/** @ingroup mqtt
|
||||||
|
* Unsubscribe to topic */
|
||||||
|
#define mqtt_unsubscribe(client, topic, cb, arg) mqtt_sub_unsub(client, topic, 0, cb, arg, 0)
|
||||||
|
|
||||||
|
|
||||||
|
/** Publish data to topic */
|
||||||
|
err_t mqtt_publish(mqtt_client_t *client, const char *topic, const void *payload, u16_t payload_length, u8_t qos, u8_t retain,
|
||||||
|
mqtt_request_cb_t cb, void *arg);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* LWIP_HDR_APPS_MQTT_CLIENT_H */
|
|
@ -0,0 +1,103 @@
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* MQTT client options
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2016 Erik Andersson
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||||
|
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||||
|
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
|
* OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* This file is part of the lwIP TCP/IP stack.
|
||||||
|
*
|
||||||
|
* Author: Erik Andersson
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef LWIP_HDR_APPS_MQTT_OPTS_H
|
||||||
|
#define LWIP_HDR_APPS_MQTT_OPTS_H
|
||||||
|
|
||||||
|
#include "lwip/opt.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @defgroup mqtt_opts Options
|
||||||
|
* @ingroup mqtt
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Output ring-buffer size, must be able to fit largest outgoing publish message topic+payloads
|
||||||
|
*/
|
||||||
|
#ifndef MQTT_OUTPUT_RINGBUF_SIZE
|
||||||
|
#define MQTT_OUTPUT_RINGBUF_SIZE 256
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Number of bytes in receive buffer, must be at least the size of the longest incoming topic + 8
|
||||||
|
* If one wants to avoid fragmented incoming publish, set length to max incoming topic length + max payload length + 8
|
||||||
|
*/
|
||||||
|
#ifndef MQTT_VAR_HEADER_BUFFER_LEN
|
||||||
|
#define MQTT_VAR_HEADER_BUFFER_LEN 128
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maximum number of pending subscribe, unsubscribe and publish requests to server .
|
||||||
|
*/
|
||||||
|
#ifndef MQTT_REQ_MAX_IN_FLIGHT
|
||||||
|
#define MQTT_REQ_MAX_IN_FLIGHT 4
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Seconds between each cyclic timer call.
|
||||||
|
*/
|
||||||
|
#ifndef MQTT_CYCLIC_TIMER_INTERVAL
|
||||||
|
#define MQTT_CYCLIC_TIMER_INTERVAL 5
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Publish, subscribe and unsubscribe request timeout in seconds.
|
||||||
|
*/
|
||||||
|
#ifndef MQTT_REQ_TIMEOUT
|
||||||
|
#define MQTT_REQ_TIMEOUT 30
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Seconds for MQTT connect response timeout after sending connect request
|
||||||
|
*/
|
||||||
|
#ifndef MQTT_CONNECT_TIMOUT
|
||||||
|
#define MQTT_CONNECT_TIMOUT 100
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* LWIP_HDR_APPS_MQTT_OPTS_H */
|
|
@ -0,0 +1,43 @@
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* NETBIOS name service responder
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||||
|
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||||
|
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
|
* OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* This file is part of the lwIP TCP/IP stack.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef LWIP_HDR_APPS_NETBIOS_H
|
||||||
|
#define LWIP_HDR_APPS_NETBIOS_H
|
||||||
|
|
||||||
|
#include "lwip/apps/netbiosns_opts.h"
|
||||||
|
|
||||||
|
void netbiosns_init(void);
|
||||||
|
#ifndef NETBIOS_LWIP_NAME
|
||||||
|
void netbiosns_set_name(const char* hostname);
|
||||||
|
#endif
|
||||||
|
void netbiosns_stop(void);
|
||||||
|
|
||||||
|
#endif /* LWIP_HDR_APPS_NETBIOS_H */
|
|
@ -0,0 +1,59 @@
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* NETBIOS name service responder options
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||||
|
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||||
|
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
|
* OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* This file is part of the lwIP TCP/IP stack.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef LWIP_HDR_APPS_NETBIOS_OPTS_H
|
||||||
|
#define LWIP_HDR_APPS_NETBIOS_OPTS_H
|
||||||
|
|
||||||
|
#include "lwip/opt.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @defgroup netbiosns_opts Options
|
||||||
|
* @ingroup netbiosns
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** NetBIOS name of lwip device
|
||||||
|
* This must be uppercase until NETBIOS_STRCMP() is defined to a string
|
||||||
|
* comparision function that is case insensitive.
|
||||||
|
* If you want to use the netif's hostname, use this (with LWIP_NETIF_HOSTNAME):
|
||||||
|
* (ip_current_netif() != NULL ? ip_current_netif()->hostname != NULL ? ip_current_netif()->hostname : "" : "")
|
||||||
|
*
|
||||||
|
* If this is not defined, netbiosns_set_name() can be called at runtime to change the name.
|
||||||
|
*/
|
||||||
|
#ifdef __DOXYGEN__
|
||||||
|
#define NETBIOS_LWIP_NAME "NETBIOSLWIPDEV"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
#endif /* LWIP_HDR_APPS_NETBIOS_OPTS_H */
|
|
@ -0,0 +1,128 @@
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* SNMP server main API - start and basic configuration
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2001, 2002 Leon Woestenberg <leon.woestenberg@axon.tv>
|
||||||
|
* Copyright (c) 2001, 2002 Axon Digital Design B.V., The Netherlands.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||||
|
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||||
|
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
|
* OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* This file is part of the lwIP TCP/IP stack.
|
||||||
|
*
|
||||||
|
* Author: Leon Woestenberg <leon.woestenberg@axon.tv>
|
||||||
|
* Martin Hentschel <info@cl-soft.de>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef LWIP_HDR_APPS_SNMP_H
|
||||||
|
#define LWIP_HDR_APPS_SNMP_H
|
||||||
|
|
||||||
|
#include "lwip/apps/snmp_opts.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */
|
||||||
|
|
||||||
|
#include "lwip/err.h"
|
||||||
|
#include "lwip/apps/snmp_core.h"
|
||||||
|
|
||||||
|
/** SNMP variable binding descriptor (publically needed for traps) */
|
||||||
|
struct snmp_varbind
|
||||||
|
{
|
||||||
|
/** pointer to next varbind, NULL for last in list */
|
||||||
|
struct snmp_varbind *next;
|
||||||
|
/** pointer to previous varbind, NULL for first in list */
|
||||||
|
struct snmp_varbind *prev;
|
||||||
|
|
||||||
|
/** object identifier */
|
||||||
|
struct snmp_obj_id oid;
|
||||||
|
|
||||||
|
/** value ASN1 type */
|
||||||
|
u8_t type;
|
||||||
|
/** object value length */
|
||||||
|
u16_t value_len;
|
||||||
|
/** object value */
|
||||||
|
void *value;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup snmp_core
|
||||||
|
* Agent setup, start listening to port 161.
|
||||||
|
*/
|
||||||
|
void snmp_init(void);
|
||||||
|
void snmp_set_mibs(const struct snmp_mib **mibs, u8_t num_mibs);
|
||||||
|
|
||||||
|
void snmp_set_device_enterprise_oid(const struct snmp_obj_id* device_enterprise_oid);
|
||||||
|
const struct snmp_obj_id* snmp_get_device_enterprise_oid(void);
|
||||||
|
|
||||||
|
void snmp_trap_dst_enable(u8_t dst_idx, u8_t enable);
|
||||||
|
void snmp_trap_dst_ip_set(u8_t dst_idx, const ip_addr_t *dst);
|
||||||
|
|
||||||
|
/** Generic trap: cold start */
|
||||||
|
#define SNMP_GENTRAP_COLDSTART 0
|
||||||
|
/** Generic trap: warm start */
|
||||||
|
#define SNMP_GENTRAP_WARMSTART 1
|
||||||
|
/** Generic trap: link down */
|
||||||
|
#define SNMP_GENTRAP_LINKDOWN 2
|
||||||
|
/** Generic trap: link up */
|
||||||
|
#define SNMP_GENTRAP_LINKUP 3
|
||||||
|
/** Generic trap: authentication failure */
|
||||||
|
#define SNMP_GENTRAP_AUTH_FAILURE 4
|
||||||
|
/** Generic trap: EGP neighbor lost */
|
||||||
|
#define SNMP_GENTRAP_EGP_NEIGHBOR_LOSS 5
|
||||||
|
/** Generic trap: enterprise specific */
|
||||||
|
#define SNMP_GENTRAP_ENTERPRISE_SPECIFIC 6
|
||||||
|
|
||||||
|
err_t snmp_send_trap_generic(s32_t generic_trap);
|
||||||
|
err_t snmp_send_trap_specific(s32_t specific_trap, struct snmp_varbind *varbinds);
|
||||||
|
err_t snmp_send_trap(const struct snmp_obj_id* oid, s32_t generic_trap, s32_t specific_trap, struct snmp_varbind *varbinds);
|
||||||
|
|
||||||
|
#define SNMP_AUTH_TRAPS_DISABLED 0
|
||||||
|
#define SNMP_AUTH_TRAPS_ENABLED 1
|
||||||
|
void snmp_set_auth_traps_enabled(u8_t enable);
|
||||||
|
u8_t snmp_get_auth_traps_enabled(void);
|
||||||
|
|
||||||
|
const char * snmp_get_community(void);
|
||||||
|
const char * snmp_get_community_write(void);
|
||||||
|
const char * snmp_get_community_trap(void);
|
||||||
|
void snmp_set_community(const char * const community);
|
||||||
|
void snmp_set_community_write(const char * const community);
|
||||||
|
void snmp_set_community_trap(const char * const community);
|
||||||
|
|
||||||
|
void snmp_coldstart_trap(void);
|
||||||
|
void snmp_authfail_trap(void);
|
||||||
|
|
||||||
|
typedef void (*snmp_write_callback_fct)(const u32_t* oid, u8_t oid_len, void* callback_arg);
|
||||||
|
void snmp_set_write_callback(snmp_write_callback_fct write_callback, void* callback_arg);
|
||||||
|
|
||||||
|
#endif /* LWIP_SNMP */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* LWIP_HDR_APPS_SNMP_H */
|
|
@ -0,0 +1,364 @@
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* SNMP core API for implementing MIBs
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006 Axon Digital Design B.V., The Netherlands.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||||
|
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||||
|
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
|
* OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* Author: Christiaan Simons <christiaan.simons@axon.tv>
|
||||||
|
* Martin Hentschel <info@cl-soft.de>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef LWIP_HDR_APPS_SNMP_CORE_H
|
||||||
|
#define LWIP_HDR_APPS_SNMP_CORE_H
|
||||||
|
|
||||||
|
#include "lwip/apps/snmp_opts.h"
|
||||||
|
|
||||||
|
#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */
|
||||||
|
|
||||||
|
#include "lwip/ip_addr.h"
|
||||||
|
#include "lwip/err.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* basic ASN1 defines */
|
||||||
|
#define SNMP_ASN1_CLASS_UNIVERSAL 0x00
|
||||||
|
#define SNMP_ASN1_CLASS_APPLICATION 0x40
|
||||||
|
#define SNMP_ASN1_CLASS_CONTEXT 0x80
|
||||||
|
#define SNMP_ASN1_CLASS_PRIVATE 0xC0
|
||||||
|
|
||||||
|
#define SNMP_ASN1_CONTENTTYPE_PRIMITIVE 0x00
|
||||||
|
#define SNMP_ASN1_CONTENTTYPE_CONSTRUCTED 0x20
|
||||||
|
|
||||||
|
/* universal tags (from ASN.1 spec.) */
|
||||||
|
#define SNMP_ASN1_UNIVERSAL_END_OF_CONTENT 0
|
||||||
|
#define SNMP_ASN1_UNIVERSAL_INTEGER 2
|
||||||
|
#define SNMP_ASN1_UNIVERSAL_OCTET_STRING 4
|
||||||
|
#define SNMP_ASN1_UNIVERSAL_NULL 5
|
||||||
|
#define SNMP_ASN1_UNIVERSAL_OBJECT_ID 6
|
||||||
|
#define SNMP_ASN1_UNIVERSAL_SEQUENCE_OF 16
|
||||||
|
|
||||||
|
/* application specific (SNMP) tags (from SNMPv2-SMI) */
|
||||||
|
#define SNMP_ASN1_APPLICATION_IPADDR 0 /* [APPLICATION 0] IMPLICIT OCTET STRING (SIZE (4)) */
|
||||||
|
#define SNMP_ASN1_APPLICATION_COUNTER 1 /* [APPLICATION 1] IMPLICIT INTEGER (0..4294967295) => u32_t */
|
||||||
|
#define SNMP_ASN1_APPLICATION_GAUGE 2 /* [APPLICATION 2] IMPLICIT INTEGER (0..4294967295) => u32_t */
|
||||||
|
#define SNMP_ASN1_APPLICATION_TIMETICKS 3 /* [APPLICATION 3] IMPLICIT INTEGER (0..4294967295) => u32_t */
|
||||||
|
#define SNMP_ASN1_APPLICATION_OPAQUE 4 /* [APPLICATION 4] IMPLICIT OCTET STRING */
|
||||||
|
#define SNMP_ASN1_APPLICATION_COUNTER64 6 /* [APPLICATION 6] IMPLICIT INTEGER (0..18446744073709551615) */
|
||||||
|
|
||||||
|
/* context specific (SNMP) tags (from RFC 1905) */
|
||||||
|
#define SNMP_ASN1_CONTEXT_VARBIND_NO_SUCH_INSTANCE 1
|
||||||
|
|
||||||
|
/* full ASN1 type defines */
|
||||||
|
#define SNMP_ASN1_TYPE_END_OF_CONTENT (SNMP_ASN1_CLASS_UNIVERSAL | SNMP_ASN1_CONTENTTYPE_PRIMITIVE | SNMP_ASN1_UNIVERSAL_END_OF_CONTENT)
|
||||||
|
#define SNMP_ASN1_TYPE_INTEGER (SNMP_ASN1_CLASS_UNIVERSAL | SNMP_ASN1_CONTENTTYPE_PRIMITIVE | SNMP_ASN1_UNIVERSAL_INTEGER)
|
||||||
|
#define SNMP_ASN1_TYPE_OCTET_STRING (SNMP_ASN1_CLASS_UNIVERSAL | SNMP_ASN1_CONTENTTYPE_PRIMITIVE | SNMP_ASN1_UNIVERSAL_OCTET_STRING)
|
||||||
|
#define SNMP_ASN1_TYPE_NULL (SNMP_ASN1_CLASS_UNIVERSAL | SNMP_ASN1_CONTENTTYPE_PRIMITIVE | SNMP_ASN1_UNIVERSAL_NULL)
|
||||||
|
#define SNMP_ASN1_TYPE_OBJECT_ID (SNMP_ASN1_CLASS_UNIVERSAL | SNMP_ASN1_CONTENTTYPE_PRIMITIVE | SNMP_ASN1_UNIVERSAL_OBJECT_ID)
|
||||||
|
#define SNMP_ASN1_TYPE_SEQUENCE (SNMP_ASN1_CLASS_UNIVERSAL | SNMP_ASN1_CONTENTTYPE_CONSTRUCTED | SNMP_ASN1_UNIVERSAL_SEQUENCE_OF)
|
||||||
|
#define SNMP_ASN1_TYPE_IPADDR (SNMP_ASN1_CLASS_APPLICATION | SNMP_ASN1_CONTENTTYPE_PRIMITIVE | SNMP_ASN1_APPLICATION_IPADDR)
|
||||||
|
#define SNMP_ASN1_TYPE_IPADDRESS SNMP_ASN1_TYPE_IPADDR
|
||||||
|
#define SNMP_ASN1_TYPE_COUNTER (SNMP_ASN1_CLASS_APPLICATION | SNMP_ASN1_CONTENTTYPE_PRIMITIVE | SNMP_ASN1_APPLICATION_COUNTER)
|
||||||
|
#define SNMP_ASN1_TYPE_COUNTER32 SNMP_ASN1_TYPE_COUNTER
|
||||||
|
#define SNMP_ASN1_TYPE_GAUGE (SNMP_ASN1_CLASS_APPLICATION | SNMP_ASN1_CONTENTTYPE_PRIMITIVE | SNMP_ASN1_APPLICATION_GAUGE)
|
||||||
|
#define SNMP_ASN1_TYPE_GAUGE32 SNMP_ASN1_TYPE_GAUGE
|
||||||
|
#define SNMP_ASN1_TYPE_UNSIGNED32 SNMP_ASN1_TYPE_GAUGE
|
||||||
|
#define SNMP_ASN1_TYPE_TIMETICKS (SNMP_ASN1_CLASS_APPLICATION | SNMP_ASN1_CONTENTTYPE_PRIMITIVE | SNMP_ASN1_APPLICATION_TIMETICKS)
|
||||||
|
#define SNMP_ASN1_TYPE_OPAQUE (SNMP_ASN1_CLASS_APPLICATION | SNMP_ASN1_CONTENTTYPE_PRIMITIVE | SNMP_ASN1_APPLICATION_OPAQUE)
|
||||||
|
#define SNMP_ASN1_TYPE_COUNTER64 (SNMP_ASN1_CLASS_APPLICATION | SNMP_ASN1_CONTENTTYPE_PRIMITIVE | SNMP_ASN1_APPLICATION_COUNTER64)
|
||||||
|
|
||||||
|
#define SNMP_VARBIND_EXCEPTION_OFFSET 0xF0
|
||||||
|
#define SNMP_VARBIND_EXCEPTION_MASK 0x0F
|
||||||
|
|
||||||
|
/** error codes predefined by SNMP prot. */
|
||||||
|
typedef enum {
|
||||||
|
SNMP_ERR_NOERROR = 0,
|
||||||
|
/*
|
||||||
|
outdated v1 error codes. do not use anmore!
|
||||||
|
#define SNMP_ERR_NOSUCHNAME 2 use SNMP_ERR_NOSUCHINSTANCE instead
|
||||||
|
#define SNMP_ERR_BADVALUE 3 use SNMP_ERR_WRONGTYPE,SNMP_ERR_WRONGLENGTH,SNMP_ERR_WRONGENCODING or SNMP_ERR_WRONGVALUE instead
|
||||||
|
#define SNMP_ERR_READONLY 4 use SNMP_ERR_NOTWRITABLE instead
|
||||||
|
*/
|
||||||
|
SNMP_ERR_GENERROR = 5,
|
||||||
|
SNMP_ERR_NOACCESS = 6,
|
||||||
|
SNMP_ERR_WRONGTYPE = 7,
|
||||||
|
SNMP_ERR_WRONGLENGTH = 8,
|
||||||
|
SNMP_ERR_WRONGENCODING = 9,
|
||||||
|
SNMP_ERR_WRONGVALUE = 10,
|
||||||
|
SNMP_ERR_NOCREATION = 11,
|
||||||
|
SNMP_ERR_INCONSISTENTVALUE = 12,
|
||||||
|
SNMP_ERR_RESOURCEUNAVAILABLE = 13,
|
||||||
|
SNMP_ERR_COMMITFAILED = 14,
|
||||||
|
SNMP_ERR_UNDOFAILED = 15,
|
||||||
|
SNMP_ERR_NOTWRITABLE = 17,
|
||||||
|
SNMP_ERR_INCONSISTENTNAME = 18,
|
||||||
|
|
||||||
|
SNMP_ERR_NOSUCHINSTANCE = SNMP_VARBIND_EXCEPTION_OFFSET + SNMP_ASN1_CONTEXT_VARBIND_NO_SUCH_INSTANCE
|
||||||
|
} snmp_err_t;
|
||||||
|
|
||||||
|
/** internal object identifier representation */
|
||||||
|
struct snmp_obj_id
|
||||||
|
{
|
||||||
|
u8_t len;
|
||||||
|
u32_t id[SNMP_MAX_OBJ_ID_LEN];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct snmp_obj_id_const_ref
|
||||||
|
{
|
||||||
|
u8_t len;
|
||||||
|
const u32_t* id;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern const struct snmp_obj_id_const_ref snmp_zero_dot_zero; /* administrative identifier from SNMPv2-SMI */
|
||||||
|
|
||||||
|
/** SNMP variant value, used as reference in struct snmp_node_instance and table implementation */
|
||||||
|
union snmp_variant_value
|
||||||
|
{
|
||||||
|
void* ptr;
|
||||||
|
const void* const_ptr;
|
||||||
|
u32_t u32;
|
||||||
|
s32_t s32;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
SNMP MIB node types
|
||||||
|
tree node is the only node the stack can process in order to walk the tree,
|
||||||
|
all other nodes are assumed to be leaf nodes.
|
||||||
|
This cannot be an enum because users may want to define their own node types.
|
||||||
|
*/
|
||||||
|
#define SNMP_NODE_TREE 0x00
|
||||||
|
/* predefined leaf node types */
|
||||||
|
#define SNMP_NODE_SCALAR 0x01
|
||||||
|
#define SNMP_NODE_SCALAR_ARRAY 0x02
|
||||||
|
#define SNMP_NODE_TABLE 0x03
|
||||||
|
#define SNMP_NODE_THREADSYNC 0x04
|
||||||
|
|
||||||
|
/** node "base class" layout, the mandatory fields for a node */
|
||||||
|
struct snmp_node
|
||||||
|
{
|
||||||
|
/** one out of SNMP_NODE_TREE or any leaf node type (like SNMP_NODE_SCALAR) */
|
||||||
|
u8_t node_type;
|
||||||
|
/** the number assigned to this node which used as part of the full OID */
|
||||||
|
u32_t oid;
|
||||||
|
};
|
||||||
|
|
||||||
|
/** SNMP node instance access types */
|
||||||
|
typedef enum {
|
||||||
|
SNMP_NODE_INSTANCE_ACCESS_READ = 1,
|
||||||
|
SNMP_NODE_INSTANCE_ACCESS_WRITE = 2,
|
||||||
|
SNMP_NODE_INSTANCE_READ_ONLY = SNMP_NODE_INSTANCE_ACCESS_READ,
|
||||||
|
SNMP_NODE_INSTANCE_READ_WRITE = (SNMP_NODE_INSTANCE_ACCESS_READ | SNMP_NODE_INSTANCE_ACCESS_WRITE),
|
||||||
|
SNMP_NODE_INSTANCE_WRITE_ONLY = SNMP_NODE_INSTANCE_ACCESS_WRITE,
|
||||||
|
SNMP_NODE_INSTANCE_NOT_ACCESSIBLE = 0
|
||||||
|
} snmp_access_t;
|
||||||
|
|
||||||
|
struct snmp_node_instance;
|
||||||
|
|
||||||
|
typedef s16_t (*node_instance_get_value_method)(struct snmp_node_instance*, void*);
|
||||||
|
typedef snmp_err_t (*node_instance_set_test_method)(struct snmp_node_instance*, u16_t, void*);
|
||||||
|
typedef snmp_err_t (*node_instance_set_value_method)(struct snmp_node_instance*, u16_t, void*);
|
||||||
|
typedef void (*node_instance_release_method)(struct snmp_node_instance*);
|
||||||
|
|
||||||
|
#define SNMP_GET_VALUE_RAW_DATA 0x8000
|
||||||
|
|
||||||
|
/** SNMP node instance */
|
||||||
|
struct snmp_node_instance
|
||||||
|
{
|
||||||
|
/** prefilled with the node, get_instance() is called on; may be changed by user to any value to pass an arbitrary node between calls to get_instance() and get_value/test_value/set_value */
|
||||||
|
const struct snmp_node* node;
|
||||||
|
/** prefilled with the instance id requested; for get_instance() this is the exact oid requested; for get_next_instance() this is the relative starting point, stack expects relative oid of next node here */
|
||||||
|
struct snmp_obj_id instance_oid;
|
||||||
|
|
||||||
|
/** ASN type for this object (see snmp_asn1.h for definitions) */
|
||||||
|
u8_t asn1_type;
|
||||||
|
/** one out of instance access types defined above (SNMP_NODE_INSTANCE_READ_ONLY,...) */
|
||||||
|
snmp_access_t access;
|
||||||
|
|
||||||
|
/** returns object value for the given object identifier. Return values <0 to indicate an error */
|
||||||
|
node_instance_get_value_method get_value;
|
||||||
|
/** tests length and/or range BEFORE setting */
|
||||||
|
node_instance_set_test_method set_test;
|
||||||
|
/** sets object value, only called when set_test() was successful */
|
||||||
|
node_instance_set_value_method set_value;
|
||||||
|
/** called in any case when the instance is not required anymore by stack (useful for freeing memory allocated in get_instance/get_next_instance methods) */
|
||||||
|
node_instance_release_method release_instance;
|
||||||
|
|
||||||
|
/** reference to pass arbitrary value between calls to get_instance() and get_value/test_value/set_value */
|
||||||
|
union snmp_variant_value reference;
|
||||||
|
/** see reference (if reference is a pointer, the length of underlying data may be stored here or anything else) */
|
||||||
|
u32_t reference_len;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/** SNMP tree node */
|
||||||
|
struct snmp_tree_node
|
||||||
|
{
|
||||||
|
/** inherited "base class" members */
|
||||||
|
struct snmp_node node;
|
||||||
|
u16_t subnode_count;
|
||||||
|
const struct snmp_node* const *subnodes;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define SNMP_CREATE_TREE_NODE(oid, subnodes) \
|
||||||
|
{{ SNMP_NODE_TREE, (oid) }, \
|
||||||
|
(u16_t)LWIP_ARRAYSIZE(subnodes), (subnodes) }
|
||||||
|
|
||||||
|
#define SNMP_CREATE_EMPTY_TREE_NODE(oid) \
|
||||||
|
{{ SNMP_NODE_TREE, (oid) }, \
|
||||||
|
0, NULL }
|
||||||
|
|
||||||
|
/** SNMP leaf node */
|
||||||
|
struct snmp_leaf_node
|
||||||
|
{
|
||||||
|
/** inherited "base class" members */
|
||||||
|
struct snmp_node node;
|
||||||
|
snmp_err_t (*get_instance)(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance);
|
||||||
|
snmp_err_t (*get_next_instance)(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance);
|
||||||
|
};
|
||||||
|
|
||||||
|
/** represents a single mib with its base oid and root node */
|
||||||
|
struct snmp_mib
|
||||||
|
{
|
||||||
|
const u32_t *base_oid;
|
||||||
|
u8_t base_oid_len;
|
||||||
|
const struct snmp_node *root_node;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define SNMP_MIB_CREATE(oid_list, root_node) { (oid_list), (u8_t)LWIP_ARRAYSIZE(oid_list), root_node }
|
||||||
|
|
||||||
|
/** OID range structure */
|
||||||
|
struct snmp_oid_range
|
||||||
|
{
|
||||||
|
u32_t min;
|
||||||
|
u32_t max;
|
||||||
|
};
|
||||||
|
|
||||||
|
/** checks if incoming OID length and values are in allowed ranges */
|
||||||
|
u8_t snmp_oid_in_range(const u32_t *oid_in, u8_t oid_len, const struct snmp_oid_range *oid_ranges, u8_t oid_ranges_len);
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
SNMP_NEXT_OID_STATUS_SUCCESS,
|
||||||
|
SNMP_NEXT_OID_STATUS_NO_MATCH,
|
||||||
|
SNMP_NEXT_OID_STATUS_BUF_TO_SMALL
|
||||||
|
} snmp_next_oid_status_t;
|
||||||
|
|
||||||
|
/** state for next_oid_init / next_oid_check functions */
|
||||||
|
struct snmp_next_oid_state
|
||||||
|
{
|
||||||
|
const u32_t* start_oid;
|
||||||
|
u8_t start_oid_len;
|
||||||
|
|
||||||
|
u32_t* next_oid;
|
||||||
|
u8_t next_oid_len;
|
||||||
|
u8_t next_oid_max_len;
|
||||||
|
|
||||||
|
snmp_next_oid_status_t status;
|
||||||
|
void* reference;
|
||||||
|
};
|
||||||
|
|
||||||
|
void snmp_next_oid_init(struct snmp_next_oid_state *state,
|
||||||
|
const u32_t *start_oid, u8_t start_oid_len,
|
||||||
|
u32_t *next_oid_buf, u8_t next_oid_max_len);
|
||||||
|
u8_t snmp_next_oid_precheck(struct snmp_next_oid_state *state, const u32_t *oid, const u8_t oid_len);
|
||||||
|
u8_t snmp_next_oid_check(struct snmp_next_oid_state *state, const u32_t *oid, const u8_t oid_len, void* reference);
|
||||||
|
|
||||||
|
void snmp_oid_assign(struct snmp_obj_id* target, const u32_t *oid, u8_t oid_len);
|
||||||
|
void snmp_oid_combine(struct snmp_obj_id* target, const u32_t *oid1, u8_t oid1_len, const u32_t *oid2, u8_t oid2_len);
|
||||||
|
void snmp_oid_prefix(struct snmp_obj_id* target, const u32_t *oid, u8_t oid_len);
|
||||||
|
void snmp_oid_append(struct snmp_obj_id* target, const u32_t *oid, u8_t oid_len);
|
||||||
|
u8_t snmp_oid_equal(const u32_t *oid1, u8_t oid1_len, const u32_t *oid2, u8_t oid2_len);
|
||||||
|
s8_t snmp_oid_compare(const u32_t *oid1, u8_t oid1_len, const u32_t *oid2, u8_t oid2_len);
|
||||||
|
|
||||||
|
#if LWIP_IPV4
|
||||||
|
u8_t snmp_oid_to_ip4(const u32_t *oid, ip4_addr_t *ip);
|
||||||
|
void snmp_ip4_to_oid(const ip4_addr_t *ip, u32_t *oid);
|
||||||
|
#endif /* LWIP_IPV4 */
|
||||||
|
#if LWIP_IPV6
|
||||||
|
u8_t snmp_oid_to_ip6(const u32_t *oid, ip6_addr_t *ip);
|
||||||
|
void snmp_ip6_to_oid(const ip6_addr_t *ip, u32_t *oid);
|
||||||
|
#endif /* LWIP_IPV6 */
|
||||||
|
#if LWIP_IPV4 || LWIP_IPV6
|
||||||
|
u8_t snmp_ip_to_oid(const ip_addr_t *ip, u32_t *oid);
|
||||||
|
u8_t snmp_ip_port_to_oid(const ip_addr_t *ip, u16_t port, u32_t *oid);
|
||||||
|
|
||||||
|
u8_t snmp_oid_to_ip(const u32_t *oid, u8_t oid_len, ip_addr_t *ip);
|
||||||
|
u8_t snmp_oid_to_ip_port(const u32_t *oid, u8_t oid_len, ip_addr_t *ip, u16_t *port);
|
||||||
|
#endif /* LWIP_IPV4 || LWIP_IPV6 */
|
||||||
|
|
||||||
|
struct netif;
|
||||||
|
u8_t netif_to_num(const struct netif *netif);
|
||||||
|
|
||||||
|
snmp_err_t snmp_set_test_ok(struct snmp_node_instance* instance, u16_t value_len, void* value); /* generic function which can be used if test is always successful */
|
||||||
|
|
||||||
|
err_t snmp_decode_bits(const u8_t *buf, u32_t buf_len, u32_t *bit_value);
|
||||||
|
err_t snmp_decode_truthvalue(const s32_t *asn1_value, u8_t *bool_value);
|
||||||
|
u8_t snmp_encode_bits(u8_t *buf, u32_t buf_len, u32_t bit_value, u8_t bit_count);
|
||||||
|
u8_t snmp_encode_truthvalue(s32_t *asn1_value, u32_t bool_value);
|
||||||
|
|
||||||
|
struct snmp_statistics
|
||||||
|
{
|
||||||
|
u32_t inpkts;
|
||||||
|
u32_t outpkts;
|
||||||
|
u32_t inbadversions;
|
||||||
|
u32_t inbadcommunitynames;
|
||||||
|
u32_t inbadcommunityuses;
|
||||||
|
u32_t inasnparseerrs;
|
||||||
|
u32_t intoobigs;
|
||||||
|
u32_t innosuchnames;
|
||||||
|
u32_t inbadvalues;
|
||||||
|
u32_t inreadonlys;
|
||||||
|
u32_t ingenerrs;
|
||||||
|
u32_t intotalreqvars;
|
||||||
|
u32_t intotalsetvars;
|
||||||
|
u32_t ingetrequests;
|
||||||
|
u32_t ingetnexts;
|
||||||
|
u32_t insetrequests;
|
||||||
|
u32_t ingetresponses;
|
||||||
|
u32_t intraps;
|
||||||
|
u32_t outtoobigs;
|
||||||
|
u32_t outnosuchnames;
|
||||||
|
u32_t outbadvalues;
|
||||||
|
u32_t outgenerrs;
|
||||||
|
u32_t outgetrequests;
|
||||||
|
u32_t outgetnexts;
|
||||||
|
u32_t outsetrequests;
|
||||||
|
u32_t outgetresponses;
|
||||||
|
u32_t outtraps;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern struct snmp_statistics snmp_stats;
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* LWIP_SNMP */
|
||||||
|
|
||||||
|
#endif /* LWIP_HDR_APPS_SNMP_CORE_H */
|
|
@ -0,0 +1,78 @@
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* SNMP MIB2 API
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||||
|
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||||
|
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
|
* OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* This file is part of the lwIP TCP/IP stack.
|
||||||
|
*
|
||||||
|
* Author: Dirk Ziegelmeier <dziegel@gmx.de>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef LWIP_HDR_APPS_SNMP_MIB2_H
|
||||||
|
#define LWIP_HDR_APPS_SNMP_MIB2_H
|
||||||
|
|
||||||
|
#include "lwip/apps/snmp_opts.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */
|
||||||
|
#if SNMP_LWIP_MIB2
|
||||||
|
|
||||||
|
#include "lwip/apps/snmp_core.h"
|
||||||
|
|
||||||
|
extern const struct snmp_mib mib2;
|
||||||
|
|
||||||
|
#if SNMP_USE_NETCONN
|
||||||
|
#include "lwip/apps/snmp_threadsync.h"
|
||||||
|
void snmp_mib2_lwip_synchronizer(snmp_threadsync_called_fn fn, void* arg);
|
||||||
|
extern struct snmp_threadsync_instance snmp_mib2_lwip_locks;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef SNMP_SYSSERVICES
|
||||||
|
#define SNMP_SYSSERVICES ((1 << 6) | (1 << 3) | ((IP_FORWARD) << 2))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void snmp_mib2_set_sysdescr(const u8_t* str, const u16_t* len); /* read-only be defintion */
|
||||||
|
void snmp_mib2_set_syscontact(u8_t *ocstr, u16_t *ocstrlen, u16_t bufsize);
|
||||||
|
void snmp_mib2_set_syscontact_readonly(const u8_t *ocstr, const u16_t *ocstrlen);
|
||||||
|
void snmp_mib2_set_sysname(u8_t *ocstr, u16_t *ocstrlen, u16_t bufsize);
|
||||||
|
void snmp_mib2_set_sysname_readonly(const u8_t *ocstr, const u16_t *ocstrlen);
|
||||||
|
void snmp_mib2_set_syslocation(u8_t *ocstr, u16_t *ocstrlen, u16_t bufsize);
|
||||||
|
void snmp_mib2_set_syslocation_readonly(const u8_t *ocstr, const u16_t *ocstrlen);
|
||||||
|
|
||||||
|
#endif /* SNMP_LWIP_MIB2 */
|
||||||
|
#endif /* LWIP_SNMP */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* LWIP_HDR_APPS_SNMP_MIB2_H */
|
|
@ -0,0 +1,293 @@
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* SNMP server options list
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2015 Dirk Ziegelmeier
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||||
|
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||||
|
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
|
* OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* This file is part of the lwIP TCP/IP stack.
|
||||||
|
*
|
||||||
|
* Author: Dirk Ziegelmeier
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef LWIP_HDR_SNMP_OPTS_H
|
||||||
|
#define LWIP_HDR_SNMP_OPTS_H
|
||||||
|
|
||||||
|
#include "lwip/opt.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @defgroup snmp_opts Options
|
||||||
|
* @ingroup snmp
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* LWIP_SNMP==1: This enables the lwIP SNMP agent. UDP must be available
|
||||||
|
* for SNMP transport.
|
||||||
|
* If you want to use your own SNMP agent, leave this disabled.
|
||||||
|
* To integrate MIB2 of an external agent, you need to enable
|
||||||
|
* LWIP_MIB2_CALLBACKS and MIB2_STATS. This will give you the callbacks
|
||||||
|
* and statistics counters you need to get MIB2 working.
|
||||||
|
*/
|
||||||
|
#if !defined LWIP_SNMP || defined __DOXYGEN__
|
||||||
|
#define LWIP_SNMP 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SNMP_USE_NETCONN: Use netconn API instead of raw API.
|
||||||
|
* Makes SNMP agent run in a worker thread, so blocking operations
|
||||||
|
* can be done in MIB calls.
|
||||||
|
*/
|
||||||
|
#if !defined SNMP_USE_NETCONN || defined __DOXYGEN__
|
||||||
|
#define SNMP_USE_NETCONN 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SNMP_USE_RAW: Use raw API.
|
||||||
|
* SNMP agent does not run in a worker thread, so blocking operations
|
||||||
|
* should not be done in MIB calls.
|
||||||
|
*/
|
||||||
|
#if !defined SNMP_USE_RAW || defined __DOXYGEN__
|
||||||
|
#define SNMP_USE_RAW 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if SNMP_USE_NETCONN && SNMP_USE_RAW
|
||||||
|
#error SNMP stack can use only one of the APIs {raw, netconn}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if LWIP_SNMP && !SNMP_USE_NETCONN && !SNMP_USE_RAW
|
||||||
|
#error SNMP stack needs a receive API and UDP {raw, netconn}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if SNMP_USE_NETCONN
|
||||||
|
/**
|
||||||
|
* SNMP_STACK_SIZE: Stack size of SNMP netconn worker thread
|
||||||
|
*/
|
||||||
|
#if !defined SNMP_STACK_SIZE || defined __DOXYGEN__
|
||||||
|
#define SNMP_STACK_SIZE DEFAULT_THREAD_STACKSIZE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SNMP_THREAD_PRIO: SNMP netconn worker thread priority
|
||||||
|
*/
|
||||||
|
#if !defined SNMP_THREAD_PRIO || defined __DOXYGEN__
|
||||||
|
#define SNMP_THREAD_PRIO DEFAULT_THREAD_PRIO
|
||||||
|
#endif
|
||||||
|
#endif /* SNMP_USE_NETCONN */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SNMP_TRAP_DESTINATIONS: Number of trap destinations. At least one trap
|
||||||
|
* destination is required
|
||||||
|
*/
|
||||||
|
#if !defined SNMP_TRAP_DESTINATIONS || defined __DOXYGEN__
|
||||||
|
#define SNMP_TRAP_DESTINATIONS 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Only allow SNMP write actions that are 'safe' (e.g. disabling netifs is not
|
||||||
|
* a safe action and disabled when SNMP_SAFE_REQUESTS = 1).
|
||||||
|
* Unsafe requests are disabled by default!
|
||||||
|
*/
|
||||||
|
#if !defined SNMP_SAFE_REQUESTS || defined __DOXYGEN__
|
||||||
|
#define SNMP_SAFE_REQUESTS 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The maximum length of strings used.
|
||||||
|
*/
|
||||||
|
#if !defined SNMP_MAX_OCTET_STRING_LEN || defined __DOXYGEN__
|
||||||
|
#define SNMP_MAX_OCTET_STRING_LEN 127
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The maximum number of Sub ID's inside an object identifier.
|
||||||
|
* Indirectly this also limits the maximum depth of SNMP tree.
|
||||||
|
*/
|
||||||
|
#if !defined SNMP_MAX_OBJ_ID_LEN || defined __DOXYGEN__
|
||||||
|
#define SNMP_MAX_OBJ_ID_LEN 50
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined SNMP_MAX_VALUE_SIZE || defined __DOXYGEN__
|
||||||
|
/**
|
||||||
|
* The maximum size of a value.
|
||||||
|
*/
|
||||||
|
#define SNMP_MIN_VALUE_SIZE (2 * sizeof(u32_t*)) /* size required to store the basic types (8 bytes for counter64) */
|
||||||
|
/**
|
||||||
|
* The minimum size of a value.
|
||||||
|
*/
|
||||||
|
#define SNMP_MAX_VALUE_SIZE LWIP_MAX(LWIP_MAX((SNMP_MAX_OCTET_STRING_LEN), sizeof(u32_t)*(SNMP_MAX_OBJ_ID_LEN)), SNMP_MIN_VALUE_SIZE)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The snmp read-access community. Used for write-access and traps, too
|
||||||
|
* unless SNMP_COMMUNITY_WRITE or SNMP_COMMUNITY_TRAP are enabled, respectively.
|
||||||
|
*/
|
||||||
|
#if !defined SNMP_COMMUNITY || defined __DOXYGEN__
|
||||||
|
#define SNMP_COMMUNITY "public"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The snmp write-access community.
|
||||||
|
* Set this community to "" in order to disallow any write access.
|
||||||
|
*/
|
||||||
|
#if !defined SNMP_COMMUNITY_WRITE || defined __DOXYGEN__
|
||||||
|
#define SNMP_COMMUNITY_WRITE "private"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The snmp community used for sending traps.
|
||||||
|
*/
|
||||||
|
#if !defined SNMP_COMMUNITY_TRAP || defined __DOXYGEN__
|
||||||
|
#define SNMP_COMMUNITY_TRAP "public"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The maximum length of community string.
|
||||||
|
* If community names shall be adjusted at runtime via snmp_set_community() calls,
|
||||||
|
* enter here the possible maximum length (+1 for terminating null character).
|
||||||
|
*/
|
||||||
|
#if !defined SNMP_MAX_COMMUNITY_STR_LEN || defined __DOXYGEN__
|
||||||
|
#define SNMP_MAX_COMMUNITY_STR_LEN LWIP_MAX(LWIP_MAX(sizeof(SNMP_COMMUNITY), sizeof(SNMP_COMMUNITY_WRITE)), sizeof(SNMP_COMMUNITY_TRAP))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The OID identifiying the device. This may be the enterprise OID itself or any OID located below it in tree.
|
||||||
|
*/
|
||||||
|
#if !defined SNMP_DEVICE_ENTERPRISE_OID || defined __DOXYGEN__
|
||||||
|
#define SNMP_LWIP_ENTERPRISE_OID 26381
|
||||||
|
/**
|
||||||
|
* IANA assigned enterprise ID for lwIP is 26381
|
||||||
|
* @see http://www.iana.org/assignments/enterprise-numbers
|
||||||
|
*
|
||||||
|
* @note this enterprise ID is assigned to the lwIP project,
|
||||||
|
* all object identifiers living under this ID are assigned
|
||||||
|
* by the lwIP maintainers!
|
||||||
|
* @note don't change this define, use snmp_set_device_enterprise_oid()
|
||||||
|
*
|
||||||
|
* If you need to create your own private MIB you'll need
|
||||||
|
* to apply for your own enterprise ID with IANA:
|
||||||
|
* http://www.iana.org/numbers.html
|
||||||
|
*/
|
||||||
|
#define SNMP_DEVICE_ENTERPRISE_OID {1, 3, 6, 1, 4, 1, SNMP_LWIP_ENTERPRISE_OID}
|
||||||
|
/**
|
||||||
|
* Length of SNMP_DEVICE_ENTERPRISE_OID
|
||||||
|
*/
|
||||||
|
#define SNMP_DEVICE_ENTERPRISE_OID_LEN 7
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SNMP_DEBUG: Enable debugging for SNMP messages.
|
||||||
|
*/
|
||||||
|
#if !defined SNMP_DEBUG || defined __DOXYGEN__
|
||||||
|
#define SNMP_DEBUG LWIP_DBG_OFF
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SNMP_MIB_DEBUG: Enable debugging for SNMP MIBs.
|
||||||
|
*/
|
||||||
|
#if !defined SNMP_MIB_DEBUG || defined __DOXYGEN__
|
||||||
|
#define SNMP_MIB_DEBUG LWIP_DBG_OFF
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates if the MIB2 implementation of LWIP SNMP stack is used.
|
||||||
|
*/
|
||||||
|
#if !defined SNMP_LWIP_MIB2 || defined __DOXYGEN__
|
||||||
|
#define SNMP_LWIP_MIB2 LWIP_SNMP
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Value return for sysDesc field of MIB2.
|
||||||
|
*/
|
||||||
|
#if !defined SNMP_LWIP_MIB2_SYSDESC || defined __DOXYGEN__
|
||||||
|
#define SNMP_LWIP_MIB2_SYSDESC "lwIP"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Value return for sysName field of MIB2.
|
||||||
|
* To make sysName field settable, call snmp_mib2_set_sysname() to provide the necessary buffers.
|
||||||
|
*/
|
||||||
|
#if !defined SNMP_LWIP_MIB2_SYSNAME || defined __DOXYGEN__
|
||||||
|
#define SNMP_LWIP_MIB2_SYSNAME "FQDN-unk"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Value return for sysContact field of MIB2.
|
||||||
|
* To make sysContact field settable, call snmp_mib2_set_syscontact() to provide the necessary buffers.
|
||||||
|
*/
|
||||||
|
#if !defined SNMP_LWIP_MIB2_SYSCONTACT || defined __DOXYGEN__
|
||||||
|
#define SNMP_LWIP_MIB2_SYSCONTACT ""
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Value return for sysLocation field of MIB2.
|
||||||
|
* To make sysLocation field settable, call snmp_mib2_set_syslocation() to provide the necessary buffers.
|
||||||
|
*/
|
||||||
|
#if !defined SNMP_LWIP_MIB2_SYSLOCATION || defined __DOXYGEN__
|
||||||
|
#define SNMP_LWIP_MIB2_SYSLOCATION ""
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This value is used to limit the repetitions processed in GetBulk requests (value == 0 means no limitation).
|
||||||
|
* This may be useful to limit the load for a single request.
|
||||||
|
* According to SNMP RFC 1905 it is allowed to not return all requested variables from a GetBulk request if system load would be too high.
|
||||||
|
* so the effect is that the client will do more requests to gather all data.
|
||||||
|
* For the stack this could be useful in case that SNMP processing is done in TCP/IP thread. In this situation a request with many
|
||||||
|
* repetitions could block the thread for a longer time. Setting limit here will keep the stack more responsive.
|
||||||
|
*/
|
||||||
|
#if !defined SNMP_LWIP_GETBULK_MAX_REPETITIONS || defined __DOXYGEN__
|
||||||
|
#define SNMP_LWIP_GETBULK_MAX_REPETITIONS 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
------------------------------------
|
||||||
|
---------- SNMPv3 options ----------
|
||||||
|
------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* LWIP_SNMP_V3==1: This enables EXPERIMENTAL SNMPv3 support. LWIP_SNMP must
|
||||||
|
* also be enabled.
|
||||||
|
* THIS IS UNDER DEVELOPMENT AND SHOULD NOT BE ENABLED IN PRODUCTS.
|
||||||
|
*/
|
||||||
|
#ifndef LWIP_SNMP_V3
|
||||||
|
#define LWIP_SNMP_V3 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef LWIP_SNMP_V3_CRYPTO
|
||||||
|
#define LWIP_SNMP_V3_CRYPTO LWIP_SNMP_V3
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef LWIP_SNMP_V3_MBEDTLS
|
||||||
|
#define LWIP_SNMP_V3_MBEDTLS LWIP_SNMP_V3
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* LWIP_HDR_SNMP_OPTS_H */
|
|
@ -0,0 +1,113 @@
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* SNMP server MIB API to implement scalar nodes
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||||
|
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||||
|
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
|
* OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* This file is part of the lwIP TCP/IP stack.
|
||||||
|
*
|
||||||
|
* Author: Martin Hentschel <info@cl-soft.de>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef LWIP_HDR_APPS_SNMP_SCALAR_H
|
||||||
|
#define LWIP_HDR_APPS_SNMP_SCALAR_H
|
||||||
|
|
||||||
|
#include "lwip/apps/snmp_opts.h"
|
||||||
|
#include "lwip/apps/snmp_core.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */
|
||||||
|
|
||||||
|
/** basic scalar node */
|
||||||
|
struct snmp_scalar_node
|
||||||
|
{
|
||||||
|
/** inherited "base class" members */
|
||||||
|
struct snmp_leaf_node node;
|
||||||
|
u8_t asn1_type;
|
||||||
|
snmp_access_t access;
|
||||||
|
node_instance_get_value_method get_value;
|
||||||
|
node_instance_set_test_method set_test;
|
||||||
|
node_instance_set_value_method set_value;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
snmp_err_t snmp_scalar_get_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance);
|
||||||
|
snmp_err_t snmp_scalar_get_next_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance);
|
||||||
|
|
||||||
|
#define SNMP_SCALAR_CREATE_NODE(oid, access, asn1_type, get_value_method, set_test_method, set_value_method) \
|
||||||
|
{{{ SNMP_NODE_SCALAR, (oid) }, \
|
||||||
|
snmp_scalar_get_instance, \
|
||||||
|
snmp_scalar_get_next_instance }, \
|
||||||
|
(asn1_type), (access), (get_value_method), (set_test_method), (set_value_method) }
|
||||||
|
|
||||||
|
#define SNMP_SCALAR_CREATE_NODE_READONLY(oid, asn1_type, get_value_method) SNMP_SCALAR_CREATE_NODE(oid, SNMP_NODE_INSTANCE_READ_ONLY, asn1_type, get_value_method, NULL, NULL)
|
||||||
|
|
||||||
|
/** scalar array node - a tree node which contains scalars only as children */
|
||||||
|
struct snmp_scalar_array_node_def
|
||||||
|
{
|
||||||
|
u32_t oid;
|
||||||
|
u8_t asn1_type;
|
||||||
|
snmp_access_t access;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef s16_t (*snmp_scalar_array_get_value_method)(const struct snmp_scalar_array_node_def*, void*);
|
||||||
|
typedef snmp_err_t (*snmp_scalar_array_set_test_method)(const struct snmp_scalar_array_node_def*, u16_t, void*);
|
||||||
|
typedef snmp_err_t (*snmp_scalar_array_set_value_method)(const struct snmp_scalar_array_node_def*, u16_t, void*);
|
||||||
|
|
||||||
|
/** basic scalar array node */
|
||||||
|
struct snmp_scalar_array_node
|
||||||
|
{
|
||||||
|
/** inherited "base class" members */
|
||||||
|
struct snmp_leaf_node node;
|
||||||
|
u16_t array_node_count;
|
||||||
|
const struct snmp_scalar_array_node_def* array_nodes;
|
||||||
|
snmp_scalar_array_get_value_method get_value;
|
||||||
|
snmp_scalar_array_set_test_method set_test;
|
||||||
|
snmp_scalar_array_set_value_method set_value;
|
||||||
|
};
|
||||||
|
|
||||||
|
snmp_err_t snmp_scalar_array_get_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance);
|
||||||
|
snmp_err_t snmp_scalar_array_get_next_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance);
|
||||||
|
|
||||||
|
#define SNMP_SCALAR_CREATE_ARRAY_NODE(oid, array_nodes, get_value_method, set_test_method, set_value_method) \
|
||||||
|
{{{ SNMP_NODE_SCALAR_ARRAY, (oid) }, \
|
||||||
|
snmp_scalar_array_get_instance, \
|
||||||
|
snmp_scalar_array_get_next_instance }, \
|
||||||
|
(u16_t)LWIP_ARRAYSIZE(array_nodes), (array_nodes), (get_value_method), (set_test_method), (set_value_method) }
|
||||||
|
|
||||||
|
#endif /* LWIP_SNMP */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* LWIP_HDR_APPS_SNMP_SCALAR_H */
|
|
@ -0,0 +1,134 @@
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* SNMP server MIB API to implement table nodes
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||||
|
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||||
|
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
|
* OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* This file is part of the lwIP TCP/IP stack.
|
||||||
|
*
|
||||||
|
* Author: Martin Hentschel <info@cl-soft.de>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef LWIP_HDR_APPS_SNMP_TABLE_H
|
||||||
|
#define LWIP_HDR_APPS_SNMP_TABLE_H
|
||||||
|
|
||||||
|
#include "lwip/apps/snmp_opts.h"
|
||||||
|
#include "lwip/apps/snmp_core.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */
|
||||||
|
|
||||||
|
/** default (customizable) read/write table */
|
||||||
|
struct snmp_table_col_def
|
||||||
|
{
|
||||||
|
u32_t index;
|
||||||
|
u8_t asn1_type;
|
||||||
|
snmp_access_t access;
|
||||||
|
};
|
||||||
|
|
||||||
|
/** table node */
|
||||||
|
struct snmp_table_node
|
||||||
|
{
|
||||||
|
/** inherited "base class" members */
|
||||||
|
struct snmp_leaf_node node;
|
||||||
|
u16_t column_count;
|
||||||
|
const struct snmp_table_col_def* columns;
|
||||||
|
snmp_err_t (*get_cell_instance)(const u32_t* column, const u32_t* row_oid, u8_t row_oid_len, struct snmp_node_instance* cell_instance);
|
||||||
|
snmp_err_t (*get_next_cell_instance)(const u32_t* column, struct snmp_obj_id* row_oid, struct snmp_node_instance* cell_instance);
|
||||||
|
/** returns object value for the given object identifier */
|
||||||
|
node_instance_get_value_method get_value;
|
||||||
|
/** tests length and/or range BEFORE setting */
|
||||||
|
node_instance_set_test_method set_test;
|
||||||
|
/** sets object value, only called when set_test() was successful */
|
||||||
|
node_instance_set_value_method set_value;
|
||||||
|
};
|
||||||
|
|
||||||
|
snmp_err_t snmp_table_get_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance);
|
||||||
|
snmp_err_t snmp_table_get_next_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance);
|
||||||
|
|
||||||
|
#define SNMP_TABLE_CREATE(oid, columns, get_cell_instance_method, get_next_cell_instance_method, get_value_method, set_test_method, set_value_method) \
|
||||||
|
{{{ SNMP_NODE_TABLE, (oid) }, \
|
||||||
|
snmp_table_get_instance, \
|
||||||
|
snmp_table_get_next_instance }, \
|
||||||
|
(u16_t)LWIP_ARRAYSIZE(columns), (columns), \
|
||||||
|
(get_cell_instance_method), (get_next_cell_instance_method), \
|
||||||
|
(get_value_method), (set_test_method), (set_value_method)}
|
||||||
|
|
||||||
|
#define SNMP_TABLE_GET_COLUMN_FROM_OID(oid) ((oid)[1]) /* first array value is (fixed) row entry (fixed to 1) and 2nd value is column, follow3ed by instance */
|
||||||
|
|
||||||
|
|
||||||
|
/** simple read-only table */
|
||||||
|
typedef enum {
|
||||||
|
SNMP_VARIANT_VALUE_TYPE_U32,
|
||||||
|
SNMP_VARIANT_VALUE_TYPE_S32,
|
||||||
|
SNMP_VARIANT_VALUE_TYPE_PTR,
|
||||||
|
SNMP_VARIANT_VALUE_TYPE_CONST_PTR
|
||||||
|
} snmp_table_column_data_type_t;
|
||||||
|
|
||||||
|
struct snmp_table_simple_col_def
|
||||||
|
{
|
||||||
|
u32_t index;
|
||||||
|
u8_t asn1_type;
|
||||||
|
snmp_table_column_data_type_t data_type; /* depending of what union member is used to store the value*/
|
||||||
|
};
|
||||||
|
|
||||||
|
/** simple read-only table node */
|
||||||
|
struct snmp_table_simple_node
|
||||||
|
{
|
||||||
|
/* inherited "base class" members */
|
||||||
|
struct snmp_leaf_node node;
|
||||||
|
u16_t column_count;
|
||||||
|
const struct snmp_table_simple_col_def* columns;
|
||||||
|
snmp_err_t (*get_cell_value)(const u32_t* column, const u32_t* row_oid, u8_t row_oid_len, union snmp_variant_value* value, u32_t* value_len);
|
||||||
|
snmp_err_t (*get_next_cell_instance_and_value)(const u32_t* column, struct snmp_obj_id* row_oid, union snmp_variant_value* value, u32_t* value_len);
|
||||||
|
};
|
||||||
|
|
||||||
|
snmp_err_t snmp_table_simple_get_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance);
|
||||||
|
snmp_err_t snmp_table_simple_get_next_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance);
|
||||||
|
|
||||||
|
#define SNMP_TABLE_CREATE_SIMPLE(oid, columns, get_cell_value_method, get_next_cell_instance_and_value_method) \
|
||||||
|
{{{ SNMP_NODE_TABLE, (oid) }, \
|
||||||
|
snmp_table_simple_get_instance, \
|
||||||
|
snmp_table_simple_get_next_instance }, \
|
||||||
|
(u16_t)LWIP_ARRAYSIZE(columns), (columns), (get_cell_value_method), (get_next_cell_instance_and_value_method) }
|
||||||
|
|
||||||
|
s16_t snmp_table_extract_value_from_s32ref(struct snmp_node_instance* instance, void* value);
|
||||||
|
s16_t snmp_table_extract_value_from_u32ref(struct snmp_node_instance* instance, void* value);
|
||||||
|
s16_t snmp_table_extract_value_from_refconstptr(struct snmp_node_instance* instance, void* value);
|
||||||
|
|
||||||
|
#endif /* LWIP_SNMP */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* LWIP_HDR_APPS_SNMP_TABLE_H */
|
|
@ -0,0 +1,114 @@
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* SNMP server MIB API to implement thread synchronization
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||||
|
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||||
|
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
|
* OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* This file is part of the lwIP TCP/IP stack.
|
||||||
|
*
|
||||||
|
* Author: Dirk Ziegelmeier <dziegel@gmx.de>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef LWIP_HDR_APPS_SNMP_THREADSYNC_H
|
||||||
|
#define LWIP_HDR_APPS_SNMP_THREADSYNC_H
|
||||||
|
|
||||||
|
#include "lwip/apps/snmp_opts.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */
|
||||||
|
|
||||||
|
#include "lwip/apps/snmp_core.h"
|
||||||
|
#include "lwip/sys.h"
|
||||||
|
|
||||||
|
typedef void (*snmp_threadsync_called_fn)(void* arg);
|
||||||
|
typedef void (*snmp_threadsync_synchronizer_fn)(snmp_threadsync_called_fn fn, void* arg);
|
||||||
|
|
||||||
|
|
||||||
|
/** Thread sync runtime data. For internal usage only. */
|
||||||
|
struct threadsync_data
|
||||||
|
{
|
||||||
|
union {
|
||||||
|
snmp_err_t err;
|
||||||
|
s16_t s16;
|
||||||
|
} retval;
|
||||||
|
union {
|
||||||
|
const u32_t *root_oid;
|
||||||
|
void *value;
|
||||||
|
} arg1;
|
||||||
|
union {
|
||||||
|
u8_t root_oid_len;
|
||||||
|
u16_t len;
|
||||||
|
} arg2;
|
||||||
|
const struct snmp_threadsync_node *threadsync_node;
|
||||||
|
struct snmp_node_instance proxy_instance;
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Thread sync instance. Needed EXCATLY once for every thread to be synced into. */
|
||||||
|
struct snmp_threadsync_instance
|
||||||
|
{
|
||||||
|
sys_sem_t sem;
|
||||||
|
sys_mutex_t sem_usage_mutex;
|
||||||
|
snmp_threadsync_synchronizer_fn sync_fn;
|
||||||
|
struct threadsync_data data;
|
||||||
|
};
|
||||||
|
|
||||||
|
/** SNMP thread sync proxy leaf node */
|
||||||
|
struct snmp_threadsync_node
|
||||||
|
{
|
||||||
|
/* inherited "base class" members */
|
||||||
|
struct snmp_leaf_node node;
|
||||||
|
|
||||||
|
const struct snmp_leaf_node *target;
|
||||||
|
struct snmp_threadsync_instance *instance;
|
||||||
|
};
|
||||||
|
|
||||||
|
snmp_err_t snmp_threadsync_get_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance);
|
||||||
|
snmp_err_t snmp_threadsync_get_next_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance);
|
||||||
|
|
||||||
|
/** Create thread sync proxy node */
|
||||||
|
#define SNMP_CREATE_THREAD_SYNC_NODE(oid, target_leaf_node, threadsync_instance) \
|
||||||
|
{{{ SNMP_NODE_THREADSYNC, (oid) }, \
|
||||||
|
snmp_threadsync_get_instance, \
|
||||||
|
snmp_threadsync_get_next_instance }, \
|
||||||
|
(target_leaf_node), \
|
||||||
|
(threadsync_instance) }
|
||||||
|
|
||||||
|
/** Create thread sync instance data */
|
||||||
|
void snmp_threadsync_init(struct snmp_threadsync_instance *instance, snmp_threadsync_synchronizer_fn sync_fn);
|
||||||
|
|
||||||
|
#endif /* LWIP_SNMP */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* LWIP_HDR_APPS_SNMP_THREADSYNC_H */
|
|
@ -0,0 +1,90 @@
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* Additional SNMPv3 functionality RFC3414 and RFC3826.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2016 Elias Oenal.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||||
|
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||||
|
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
|
* OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* Author: Elias Oenal <lwip@eliasoenal.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef LWIP_HDR_APPS_SNMP_V3_H
|
||||||
|
#define LWIP_HDR_APPS_SNMP_V3_H
|
||||||
|
|
||||||
|
#include "lwip/apps/snmp_opts.h"
|
||||||
|
#include "lwip/err.h"
|
||||||
|
|
||||||
|
#if LWIP_SNMP && LWIP_SNMP_V3
|
||||||
|
|
||||||
|
#define SNMP_V3_AUTH_ALGO_INVAL 0
|
||||||
|
#define SNMP_V3_AUTH_ALGO_MD5 1
|
||||||
|
#define SNMP_V3_AUTH_ALGO_SHA 2
|
||||||
|
|
||||||
|
#define SNMP_V3_PRIV_ALGO_INVAL 0
|
||||||
|
#define SNMP_V3_PRIV_ALGO_DES 1
|
||||||
|
#define SNMP_V3_PRIV_ALGO_AES 2
|
||||||
|
|
||||||
|
#define SNMP_V3_PRIV_MODE_DECRYPT 0
|
||||||
|
#define SNMP_V3_PRIV_MODE_ENCRYPT 1
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The following callback functions must be implemented by the application.
|
||||||
|
* There is a dummy implementation in snmpv3_dummy.c.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void snmpv3_get_engine_id(const char **id, u8_t *len);
|
||||||
|
err_t snmpv3_set_engine_id(const char* id, u8_t len);
|
||||||
|
|
||||||
|
u32_t snmpv3_get_engine_boots(void);
|
||||||
|
void snmpv3_set_engine_boots(u32_t boots);
|
||||||
|
|
||||||
|
u32_t snmpv3_get_engine_time(void);
|
||||||
|
void snmpv3_reset_engine_time(void);
|
||||||
|
|
||||||
|
err_t snmpv3_get_user(const char* username, u8_t *auth_algo, u8_t *auth_key, u8_t *priv_algo, u8_t *priv_key);
|
||||||
|
|
||||||
|
/* The following functions are provided by the SNMPv3 agent */
|
||||||
|
|
||||||
|
void snmpv3_engine_id_changed(void);
|
||||||
|
|
||||||
|
void snmpv3_password_to_key_md5(
|
||||||
|
const u8_t *password, /* IN */
|
||||||
|
u8_t passwordlen, /* IN */
|
||||||
|
const u8_t *engineID, /* IN - pointer to snmpEngineID */
|
||||||
|
u8_t engineLength, /* IN - length of snmpEngineID */
|
||||||
|
u8_t *key); /* OUT - pointer to caller 16-octet buffer */
|
||||||
|
|
||||||
|
void snmpv3_password_to_key_sha(
|
||||||
|
const u8_t *password, /* IN */
|
||||||
|
u8_t passwordlen, /* IN */
|
||||||
|
const u8_t *engineID, /* IN - pointer to snmpEngineID */
|
||||||
|
u8_t engineLength, /* IN - length of snmpEngineID */
|
||||||
|
u8_t *key); /* OUT - pointer to caller 20-octet buffer */
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* LWIP_HDR_APPS_SNMP_V3_H */
|
|
@ -0,0 +1,76 @@
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* SNTP client API
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2007-2009 Frédéric Bernon, Simon Goldschmidt
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||||
|
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||||
|
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
|
* OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* This file is part of the lwIP TCP/IP stack.
|
||||||
|
*
|
||||||
|
* Author: Frédéric Bernon, Simon Goldschmidt
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef LWIP_HDR_APPS_SNTP_H
|
||||||
|
#define LWIP_HDR_APPS_SNTP_H
|
||||||
|
|
||||||
|
#include "lwip/apps/sntp_opts.h"
|
||||||
|
#include "lwip/ip_addr.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* SNTP operating modes: default is to poll using unicast.
|
||||||
|
The mode has to be set before calling sntp_init(). */
|
||||||
|
#define SNTP_OPMODE_POLL 0
|
||||||
|
#define SNTP_OPMODE_LISTENONLY 1
|
||||||
|
void sntp_setoperatingmode(u8_t operating_mode);
|
||||||
|
u8_t sntp_getoperatingmode(void);
|
||||||
|
|
||||||
|
void sntp_init(void);
|
||||||
|
void sntp_stop(void);
|
||||||
|
u8_t sntp_enabled(void);
|
||||||
|
|
||||||
|
void sntp_setserver(u8_t idx, const ip_addr_t *addr);
|
||||||
|
const ip_addr_t* sntp_getserver(u8_t idx);
|
||||||
|
|
||||||
|
#if SNTP_SERVER_DNS
|
||||||
|
void sntp_setservername(u8_t idx, char *server);
|
||||||
|
char *sntp_getservername(u8_t idx);
|
||||||
|
#endif /* SNTP_SERVER_DNS */
|
||||||
|
|
||||||
|
#if SNTP_GET_SERVERS_FROM_DHCP
|
||||||
|
void sntp_servermode_dhcp(int set_servers_from_dhcp);
|
||||||
|
#else /* SNTP_GET_SERVERS_FROM_DHCP */
|
||||||
|
#define sntp_servermode_dhcp(x)
|
||||||
|
#endif /* SNTP_GET_SERVERS_FROM_DHCP */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* LWIP_HDR_APPS_SNTP_H */
|
|
@ -0,0 +1,173 @@
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* SNTP client options list
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2007-2009 Frédéric Bernon, Simon Goldschmidt
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||||
|
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||||
|
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
|
* OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* This file is part of the lwIP TCP/IP stack.
|
||||||
|
*
|
||||||
|
* Author: Frédéric Bernon, Simon Goldschmidt
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef LWIP_HDR_APPS_SNTP_OPTS_H
|
||||||
|
#define LWIP_HDR_APPS_SNTP_OPTS_H
|
||||||
|
|
||||||
|
#include "lwip/opt.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @defgroup sntp_opts Options
|
||||||
|
* @ingroup sntp
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** SNTP macro to change system time in seconds
|
||||||
|
* Define SNTP_SET_SYSTEM_TIME_US(sec, us) to set the time in microseconds instead of this one
|
||||||
|
* if you need the additional precision.
|
||||||
|
*/
|
||||||
|
#if !defined SNTP_SET_SYSTEM_TIME || defined __DOXYGEN__
|
||||||
|
#define SNTP_SET_SYSTEM_TIME(sec) LWIP_UNUSED_ARG(sec)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** The maximum number of SNTP servers that can be set */
|
||||||
|
#if !defined SNTP_MAX_SERVERS || defined __DOXYGEN__
|
||||||
|
#define SNTP_MAX_SERVERS LWIP_DHCP_MAX_NTP_SERVERS
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** Set this to 1 to implement the callback function called by dhcp when
|
||||||
|
* NTP servers are received. */
|
||||||
|
#if !defined SNTP_GET_SERVERS_FROM_DHCP || defined __DOXYGEN__
|
||||||
|
#define SNTP_GET_SERVERS_FROM_DHCP LWIP_DHCP_GET_NTP_SRV
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** Set this to 1 to support DNS names (or IP address strings) to set sntp servers
|
||||||
|
* One server address/name can be defined as default if SNTP_SERVER_DNS == 1:
|
||||||
|
* \#define SNTP_SERVER_ADDRESS "pool.ntp.org"
|
||||||
|
*/
|
||||||
|
#if !defined SNTP_SERVER_DNS || defined __DOXYGEN__
|
||||||
|
#define SNTP_SERVER_DNS 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SNTP_DEBUG: Enable debugging for SNTP.
|
||||||
|
*/
|
||||||
|
#if !defined SNTP_DEBUG || defined __DOXYGEN__
|
||||||
|
#define SNTP_DEBUG LWIP_DBG_OFF
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** SNTP server port */
|
||||||
|
#if !defined SNTP_PORT || defined __DOXYGEN__
|
||||||
|
#define SNTP_PORT 123
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** Set this to 1 to allow config of SNTP server(s) by DNS name */
|
||||||
|
#if !defined SNTP_SERVER_DNS || defined __DOXYGEN__
|
||||||
|
#define SNTP_SERVER_DNS 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** Sanity check:
|
||||||
|
* Define this to
|
||||||
|
* - 0 to turn off sanity checks (default; smaller code)
|
||||||
|
* - >= 1 to check address and port of the response packet to ensure the
|
||||||
|
* response comes from the server we sent the request to.
|
||||||
|
* - >= 2 to check returned Originate Timestamp against Transmit Timestamp
|
||||||
|
* sent to the server (to ensure response to older request).
|
||||||
|
* - >= 3 @todo: discard reply if any of the LI, Stratum, or Transmit Timestamp
|
||||||
|
* fields is 0 or the Mode field is not 4 (unicast) or 5 (broadcast).
|
||||||
|
* - >= 4 @todo: to check that the Root Delay and Root Dispersion fields are each
|
||||||
|
* greater than or equal to 0 and less than infinity, where infinity is
|
||||||
|
* currently a cozy number like one second. This check avoids using a
|
||||||
|
* server whose synchronization source has expired for a very long time.
|
||||||
|
*/
|
||||||
|
#if !defined SNTP_CHECK_RESPONSE || defined __DOXYGEN__
|
||||||
|
#define SNTP_CHECK_RESPONSE 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** According to the RFC, this shall be a random delay
|
||||||
|
* between 1 and 5 minutes (in milliseconds) to prevent load peaks.
|
||||||
|
* This can be defined to a random generation function,
|
||||||
|
* which must return the delay in milliseconds as u32_t.
|
||||||
|
* Turned off by default.
|
||||||
|
*/
|
||||||
|
#if !defined SNTP_STARTUP_DELAY || defined __DOXYGEN__
|
||||||
|
#define SNTP_STARTUP_DELAY 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** If you want the startup delay to be a function, define this
|
||||||
|
* to a function (including the brackets) and define SNTP_STARTUP_DELAY to 1.
|
||||||
|
*/
|
||||||
|
#if !defined SNTP_STARTUP_DELAY_FUNC || defined __DOXYGEN__
|
||||||
|
#define SNTP_STARTUP_DELAY_FUNC SNTP_STARTUP_DELAY
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** SNTP receive timeout - in milliseconds
|
||||||
|
* Also used as retry timeout - this shouldn't be too low.
|
||||||
|
* Default is 3 seconds.
|
||||||
|
*/
|
||||||
|
#if !defined SNTP_RECV_TIMEOUT || defined __DOXYGEN__
|
||||||
|
#define SNTP_RECV_TIMEOUT 3000
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** SNTP update delay - in milliseconds
|
||||||
|
* Default is 1 hour. Must not be beolw 15 seconds by specification (i.e. 15000)
|
||||||
|
*/
|
||||||
|
#if !defined SNTP_UPDATE_DELAY || defined __DOXYGEN__
|
||||||
|
#define SNTP_UPDATE_DELAY 3600000
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** SNTP macro to get system time, used with SNTP_CHECK_RESPONSE >= 2
|
||||||
|
* to send in request and compare in response.
|
||||||
|
*/
|
||||||
|
#if !defined SNTP_GET_SYSTEM_TIME || defined __DOXYGEN__
|
||||||
|
#define SNTP_GET_SYSTEM_TIME(sec, us) do { (sec) = 0; (us) = 0; } while(0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** Default retry timeout (in milliseconds) if the response
|
||||||
|
* received is invalid.
|
||||||
|
* This is doubled with each retry until SNTP_RETRY_TIMEOUT_MAX is reached.
|
||||||
|
*/
|
||||||
|
#if !defined SNTP_RETRY_TIMEOUT || defined __DOXYGEN__
|
||||||
|
#define SNTP_RETRY_TIMEOUT SNTP_RECV_TIMEOUT
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** Maximum retry timeout (in milliseconds). */
|
||||||
|
#if !defined SNTP_RETRY_TIMEOUT_MAX || defined __DOXYGEN__
|
||||||
|
#define SNTP_RETRY_TIMEOUT_MAX (SNTP_RETRY_TIMEOUT * 10)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** Increase retry timeout with every retry sent
|
||||||
|
* Default is on to conform to RFC.
|
||||||
|
*/
|
||||||
|
#if !defined SNTP_RETRY_TIMEOUT_EXP || defined __DOXYGEN__
|
||||||
|
#define SNTP_RETRY_TIMEOUT_EXP 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
#endif /* LWIP_HDR_APPS_SNTP_OPTS_H */
|
|
@ -0,0 +1,105 @@
|
||||||
|
/****************************************************************//**
|
||||||
|
*
|
||||||
|
* @file tftp_opts.h
|
||||||
|
*
|
||||||
|
* @author Logan Gunthorpe <logang@deltatee.com>
|
||||||
|
*
|
||||||
|
* @brief Trivial File Transfer Protocol (RFC 1350) implementation options
|
||||||
|
*
|
||||||
|
* Copyright (c) Deltatee Enterprises Ltd. 2013
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
********************************************************************/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification,are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||||
|
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||||
|
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||||
|
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* Author: Logan Gunthorpe <logang@deltatee.com>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef LWIP_HDR_APPS_TFTP_OPTS_H
|
||||||
|
#define LWIP_HDR_APPS_TFTP_OPTS_H
|
||||||
|
|
||||||
|
#include "lwip/opt.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @defgroup tftp_opts Options
|
||||||
|
* @ingroup tftp
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enable TFTP debug messages
|
||||||
|
*/
|
||||||
|
#if !defined TFTP_DEBUG || defined __DOXYGEN__
|
||||||
|
#define TFTP_DEBUG LWIP_DBG_ON
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TFTP server port
|
||||||
|
*/
|
||||||
|
#if !defined TFTP_PORT || defined __DOXYGEN__
|
||||||
|
#define TFTP_PORT 69
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TFTP timeout
|
||||||
|
*/
|
||||||
|
#if !defined TFTP_TIMEOUT_MSECS || defined __DOXYGEN__
|
||||||
|
#define TFTP_TIMEOUT_MSECS 10000
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Max. number of retries when a file is read from server
|
||||||
|
*/
|
||||||
|
#if !defined TFTP_MAX_RETRIES || defined __DOXYGEN__
|
||||||
|
#define TFTP_MAX_RETRIES 5
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TFTP timer cyclic interval
|
||||||
|
*/
|
||||||
|
#if !defined TFTP_TIMER_MSECS || defined __DOXYGEN__
|
||||||
|
#define TFTP_TIMER_MSECS 50
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Max. length of TFTP filename
|
||||||
|
*/
|
||||||
|
#if !defined TFTP_MAX_FILENAME_LEN || defined __DOXYGEN__
|
||||||
|
#define TFTP_MAX_FILENAME_LEN 20
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Max. length of TFTP mode
|
||||||
|
*/
|
||||||
|
#if !defined TFTP_MAX_MODE_LEN || defined __DOXYGEN__
|
||||||
|
#define TFTP_MAX_MODE_LEN 7
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
#endif /* LWIP_HDR_APPS_TFTP_OPTS_H */
|
|
@ -0,0 +1,94 @@
|
||||||
|
/****************************************************************//**
|
||||||
|
*
|
||||||
|
* @file tftp_server.h
|
||||||
|
*
|
||||||
|
* @author Logan Gunthorpe <logang@deltatee.com>
|
||||||
|
*
|
||||||
|
* @brief Trivial File Transfer Protocol (RFC 1350)
|
||||||
|
*
|
||||||
|
* Copyright (c) Deltatee Enterprises Ltd. 2013
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
********************************************************************/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification,are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||||
|
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||||
|
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||||
|
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* Author: Logan Gunthorpe <logang@deltatee.com>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef LWIP_HDR_APPS_TFTP_SERVER_H
|
||||||
|
#define LWIP_HDR_APPS_TFTP_SERVER_H
|
||||||
|
|
||||||
|
#include "lwip/apps/tftp_opts.h"
|
||||||
|
#include "lwip/err.h"
|
||||||
|
#include "lwip/pbuf.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** @ingroup tftp
|
||||||
|
* TFTP context containing callback functions for TFTP transfers
|
||||||
|
*/
|
||||||
|
struct tftp_context {
|
||||||
|
/**
|
||||||
|
* Open file for read/write.
|
||||||
|
* @param fname Filename
|
||||||
|
* @param mode Mode string from TFTP RFC 1350 (netascii, octet, mail)
|
||||||
|
* @param write Flag indicating read (0) or write (!= 0) access
|
||||||
|
* @returns File handle supplied to other functions
|
||||||
|
*/
|
||||||
|
void* (*open)(const char* fname, const char* mode, u8_t write);
|
||||||
|
/**
|
||||||
|
* Close file handle
|
||||||
|
* @param handle File handle returned by open()
|
||||||
|
*/
|
||||||
|
void (*close)(void* handle);
|
||||||
|
/**
|
||||||
|
* Read from file
|
||||||
|
* @param handle File handle returned by open()
|
||||||
|
* @param buf Target buffer to copy read data to
|
||||||
|
* @param bytes Number of bytes to copy to buf
|
||||||
|
* @returns >= 0: Success; < 0: Error
|
||||||
|
*/
|
||||||
|
int (*read)(void* handle, void* buf, int bytes);
|
||||||
|
/**
|
||||||
|
* Write to file
|
||||||
|
* @param handle File handle returned by open()
|
||||||
|
* @param pbuf PBUF adjusted such that payload pointer points
|
||||||
|
* to the beginning of write data. In other words,
|
||||||
|
* TFTP headers are stripped off.
|
||||||
|
* @returns >= 0: Success; < 0: Error
|
||||||
|
*/
|
||||||
|
int (*write)(void* handle, struct pbuf* p);
|
||||||
|
};
|
||||||
|
|
||||||
|
err_t tftp_init(const struct tftp_context* ctx);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* LWIP_HDR_APPS_TFTP_SERVER_H */
|
|
@ -70,6 +70,45 @@ extern "C" {
|
||||||
#define DNS_RRCLASS_HS 4 /* Hesiod [Dyer 87] */
|
#define DNS_RRCLASS_HS 4 /* Hesiod [Dyer 87] */
|
||||||
#define DNS_RRCLASS_FLUSH 0x800 /* Flush bit */
|
#define DNS_RRCLASS_FLUSH 0x800 /* Flush bit */
|
||||||
|
|
||||||
|
/* DNS protocol flags */
|
||||||
|
#define DNS_FLAG1_RESPONSE 0x80
|
||||||
|
#define DNS_FLAG1_OPCODE_STATUS 0x10
|
||||||
|
#define DNS_FLAG1_OPCODE_INVERSE 0x08
|
||||||
|
#define DNS_FLAG1_OPCODE_STANDARD 0x00
|
||||||
|
#define DNS_FLAG1_AUTHORATIVE 0x04
|
||||||
|
#define DNS_FLAG1_TRUNC 0x02
|
||||||
|
#define DNS_FLAG1_RD 0x01
|
||||||
|
#define DNS_FLAG2_RA 0x80
|
||||||
|
#define DNS_FLAG2_ERR_MASK 0x0f
|
||||||
|
#define DNS_FLAG2_ERR_NONE 0x00
|
||||||
|
#define DNS_FLAG2_ERR_NAME 0x03
|
||||||
|
|
||||||
|
/* DNS protocol states */
|
||||||
|
#define DNS_STATE_UNUSED 0
|
||||||
|
#define DNS_STATE_NEW 1
|
||||||
|
#define DNS_STATE_ASKING 2
|
||||||
|
#define DNS_STATE_DONE 3
|
||||||
|
|
||||||
|
#ifdef PACK_STRUCT_USE_INCLUDES
|
||||||
|
# include "arch/bpstruct.h"
|
||||||
|
#endif
|
||||||
|
PACK_STRUCT_BEGIN
|
||||||
|
/** DNS message header */
|
||||||
|
struct dns_hdr {
|
||||||
|
PACK_STRUCT_FIELD(u16_t id);
|
||||||
|
PACK_STRUCT_FIELD(u8_t flags1);
|
||||||
|
PACK_STRUCT_FIELD(u8_t flags2);
|
||||||
|
PACK_STRUCT_FIELD(u16_t numquestions);
|
||||||
|
PACK_STRUCT_FIELD(u16_t numanswers);
|
||||||
|
PACK_STRUCT_FIELD(u16_t numauthrr);
|
||||||
|
PACK_STRUCT_FIELD(u16_t numextrarr);
|
||||||
|
} PACK_STRUCT_STRUCT;
|
||||||
|
PACK_STRUCT_END
|
||||||
|
#ifdef PACK_STRUCT_USE_INCLUDES
|
||||||
|
# include "arch/epstruct.h"
|
||||||
|
#endif
|
||||||
|
#define SIZEOF_DNS_HDR 12
|
||||||
|
|
||||||
/* The size used for the next line is rather a hack, but it prevents including socket.h in all files
|
/* The size used for the next line is rather a hack, but it prevents including socket.h in all files
|
||||||
that include memp.h, and that would possibly break portability (since socket.h defines some types
|
that include memp.h, and that would possibly break portability (since socket.h defines some types
|
||||||
and constants possibly already define by the OS).
|
and constants possibly already define by the OS).
|
||||||
|
|
|
@ -0,0 +1,78 @@
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* AutoIP protocol definitions
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* Copyright (c) 2007 Dominik Spies <kontakt@dspies.de>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||||
|
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||||
|
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
|
* OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* Author: Dominik Spies <kontakt@dspies.de>
|
||||||
|
*
|
||||||
|
* This is a AutoIP implementation for the lwIP TCP/IP stack. It aims to conform
|
||||||
|
* with RFC 3927.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef LWIP_HDR_PROT_AUTOIP_H
|
||||||
|
#define LWIP_HDR_PROT_AUTOIP_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* 169.254.0.0 */
|
||||||
|
#define AUTOIP_NET 0xA9FE0000
|
||||||
|
/* 169.254.1.0 */
|
||||||
|
#define AUTOIP_RANGE_START (AUTOIP_NET | 0x0100)
|
||||||
|
/* 169.254.254.255 */
|
||||||
|
#define AUTOIP_RANGE_END (AUTOIP_NET | 0xFEFF)
|
||||||
|
|
||||||
|
/* RFC 3927 Constants */
|
||||||
|
#define PROBE_WAIT 1 /* second (initial random delay) */
|
||||||
|
#define PROBE_MIN 1 /* second (minimum delay till repeated probe) */
|
||||||
|
#define PROBE_MAX 2 /* seconds (maximum delay till repeated probe) */
|
||||||
|
#define PROBE_NUM 3 /* (number of probe packets) */
|
||||||
|
#define ANNOUNCE_NUM 2 /* (number of announcement packets) */
|
||||||
|
#define ANNOUNCE_INTERVAL 2 /* seconds (time between announcement packets) */
|
||||||
|
#define ANNOUNCE_WAIT 2 /* seconds (delay before announcing) */
|
||||||
|
#define MAX_CONFLICTS 10 /* (max conflicts before rate limiting) */
|
||||||
|
#define RATE_LIMIT_INTERVAL 60 /* seconds (delay between successive attempts) */
|
||||||
|
#define DEFEND_INTERVAL 10 /* seconds (min. wait between defensive ARPs) */
|
||||||
|
|
||||||
|
/* AutoIP client states */
|
||||||
|
typedef enum {
|
||||||
|
AUTOIP_STATE_OFF = 0,
|
||||||
|
AUTOIP_STATE_PROBING = 1,
|
||||||
|
AUTOIP_STATE_ANNOUNCING = 2,
|
||||||
|
AUTOIP_STATE_BOUND = 3
|
||||||
|
} autoip_state_enum_t;
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* LWIP_HDR_PROT_AUTOIP_H */
|
|
@ -0,0 +1,183 @@
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* DHCP protocol definitions
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2001-2004 Leon Woestenberg <leon.woestenberg@gmx.net>
|
||||||
|
* Copyright (c) 2001-2004 Axon Digital Design B.V., The Netherlands.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||||
|
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||||
|
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
|
* OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* This file is part of the lwIP TCP/IP stack.
|
||||||
|
*
|
||||||
|
* Author: Leon Woestenberg <leon.woestenberg@gmx.net>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef LWIP_HDR_PROT_DHCP_H
|
||||||
|
#define LWIP_HDR_PROT_DHCP_H
|
||||||
|
|
||||||
|
#include "lwip/opt.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define DHCP_CLIENT_PORT 68
|
||||||
|
#define DHCP_SERVER_PORT 67
|
||||||
|
|
||||||
|
|
||||||
|
/* DHCP message item offsets and length */
|
||||||
|
#define DHCP_CHADDR_LEN 16U
|
||||||
|
#define DHCP_SNAME_OFS 44U
|
||||||
|
#define DHCP_SNAME_LEN 64U
|
||||||
|
#define DHCP_FILE_OFS 108U
|
||||||
|
#define DHCP_FILE_LEN 128U
|
||||||
|
#define DHCP_MSG_LEN 236U
|
||||||
|
#define DHCP_OPTIONS_OFS (DHCP_MSG_LEN + 4U) /* 4 byte: cookie */
|
||||||
|
|
||||||
|
#ifdef PACK_STRUCT_USE_INCLUDES
|
||||||
|
# include "arch/bpstruct.h"
|
||||||
|
#endif
|
||||||
|
PACK_STRUCT_BEGIN
|
||||||
|
/** minimum set of fields of any DHCP message */
|
||||||
|
struct dhcp_msg
|
||||||
|
{
|
||||||
|
PACK_STRUCT_FLD_8(u8_t op);
|
||||||
|
PACK_STRUCT_FLD_8(u8_t htype);
|
||||||
|
PACK_STRUCT_FLD_8(u8_t hlen);
|
||||||
|
PACK_STRUCT_FLD_8(u8_t hops);
|
||||||
|
PACK_STRUCT_FIELD(u32_t xid);
|
||||||
|
PACK_STRUCT_FIELD(u16_t secs);
|
||||||
|
PACK_STRUCT_FIELD(u16_t flags);
|
||||||
|
PACK_STRUCT_FLD_S(ip4_addr_p_t ciaddr);
|
||||||
|
PACK_STRUCT_FLD_S(ip4_addr_p_t yiaddr);
|
||||||
|
PACK_STRUCT_FLD_S(ip4_addr_p_t siaddr);
|
||||||
|
PACK_STRUCT_FLD_S(ip4_addr_p_t giaddr);
|
||||||
|
PACK_STRUCT_FLD_8(u8_t chaddr[DHCP_CHADDR_LEN]);
|
||||||
|
PACK_STRUCT_FLD_8(u8_t sname[DHCP_SNAME_LEN]);
|
||||||
|
PACK_STRUCT_FLD_8(u8_t file[DHCP_FILE_LEN]);
|
||||||
|
PACK_STRUCT_FIELD(u32_t cookie);
|
||||||
|
#define DHCP_MIN_OPTIONS_LEN 68U
|
||||||
|
/** make sure user does not configure this too small */
|
||||||
|
#if ((defined(DHCP_OPTIONS_LEN)) && (DHCP_OPTIONS_LEN < DHCP_MIN_OPTIONS_LEN))
|
||||||
|
# undef DHCP_OPTIONS_LEN
|
||||||
|
#endif
|
||||||
|
/** allow this to be configured in lwipopts.h, but not too small */
|
||||||
|
#if (!defined(DHCP_OPTIONS_LEN))
|
||||||
|
/** set this to be sufficient for your options in outgoing DHCP msgs */
|
||||||
|
# define DHCP_OPTIONS_LEN DHCP_MIN_OPTIONS_LEN
|
||||||
|
#endif
|
||||||
|
PACK_STRUCT_FLD_8(u8_t options[DHCP_OPTIONS_LEN]);
|
||||||
|
} PACK_STRUCT_STRUCT;
|
||||||
|
PACK_STRUCT_END
|
||||||
|
#ifdef PACK_STRUCT_USE_INCLUDES
|
||||||
|
# include "arch/epstruct.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* DHCP client states */
|
||||||
|
typedef enum {
|
||||||
|
DHCP_STATE_OFF = 0,
|
||||||
|
DHCP_STATE_REQUESTING = 1,
|
||||||
|
DHCP_STATE_INIT = 2,
|
||||||
|
DHCP_STATE_REBOOTING = 3,
|
||||||
|
DHCP_STATE_REBINDING = 4,
|
||||||
|
DHCP_STATE_RENEWING = 5,
|
||||||
|
DHCP_STATE_SELECTING = 6,
|
||||||
|
DHCP_STATE_INFORMING = 7,
|
||||||
|
DHCP_STATE_CHECKING = 8,
|
||||||
|
DHCP_STATE_PERMANENT = 9, /* not yet implemented */
|
||||||
|
DHCP_STATE_BOUND = 10,
|
||||||
|
DHCP_STATE_RELEASING = 11, /* not yet implemented */
|
||||||
|
DHCP_STATE_BACKING_OFF = 12
|
||||||
|
} dhcp_state_enum_t;
|
||||||
|
|
||||||
|
/* DHCP op codes */
|
||||||
|
#define DHCP_BOOTREQUEST 1
|
||||||
|
#define DHCP_BOOTREPLY 2
|
||||||
|
|
||||||
|
/* DHCP message types */
|
||||||
|
#define DHCP_DISCOVER 1
|
||||||
|
#define DHCP_OFFER 2
|
||||||
|
#define DHCP_REQUEST 3
|
||||||
|
#define DHCP_DECLINE 4
|
||||||
|
#define DHCP_ACK 5
|
||||||
|
#define DHCP_NAK 6
|
||||||
|
#define DHCP_RELEASE 7
|
||||||
|
#define DHCP_INFORM 8
|
||||||
|
|
||||||
|
/** DHCP hardware type, currently only ethernet is supported */
|
||||||
|
#define DHCP_HTYPE_ETH 1
|
||||||
|
|
||||||
|
#define DHCP_MAGIC_COOKIE 0x63825363UL
|
||||||
|
|
||||||
|
/* This is a list of options for BOOTP and DHCP, see RFC 2132 for descriptions */
|
||||||
|
|
||||||
|
/* BootP options */
|
||||||
|
#define DHCP_OPTION_PAD 0
|
||||||
|
#define DHCP_OPTION_SUBNET_MASK 1 /* RFC 2132 3.3 */
|
||||||
|
#define DHCP_OPTION_ROUTER 3
|
||||||
|
#define DHCP_OPTION_DNS_SERVER 6
|
||||||
|
#define DHCP_OPTION_HOSTNAME 12
|
||||||
|
#define DHCP_OPTION_IP_TTL 23
|
||||||
|
#define DHCP_OPTION_MTU 26
|
||||||
|
#define DHCP_OPTION_BROADCAST 28
|
||||||
|
#define DHCP_OPTION_TCP_TTL 37
|
||||||
|
#define DHCP_OPTION_NTP 42
|
||||||
|
#define DHCP_OPTION_END 255
|
||||||
|
|
||||||
|
/* DHCP options */
|
||||||
|
#define DHCP_OPTION_REQUESTED_IP 50 /* RFC 2132 9.1, requested IP address */
|
||||||
|
#define DHCP_OPTION_LEASE_TIME 51 /* RFC 2132 9.2, time in seconds, in 4 bytes */
|
||||||
|
#define DHCP_OPTION_OVERLOAD 52 /* RFC2132 9.3, use file and/or sname field for options */
|
||||||
|
|
||||||
|
#define DHCP_OPTION_MESSAGE_TYPE 53 /* RFC 2132 9.6, important for DHCP */
|
||||||
|
#define DHCP_OPTION_MESSAGE_TYPE_LEN 1
|
||||||
|
|
||||||
|
#define DHCP_OPTION_SERVER_ID 54 /* RFC 2132 9.7, server IP address */
|
||||||
|
#define DHCP_OPTION_PARAMETER_REQUEST_LIST 55 /* RFC 2132 9.8, requested option types */
|
||||||
|
|
||||||
|
#define DHCP_OPTION_MAX_MSG_SIZE 57 /* RFC 2132 9.10, message size accepted >= 576 */
|
||||||
|
#define DHCP_OPTION_MAX_MSG_SIZE_LEN 2
|
||||||
|
|
||||||
|
#define DHCP_OPTION_T1 58 /* T1 renewal time */
|
||||||
|
#define DHCP_OPTION_T2 59 /* T2 rebinding time */
|
||||||
|
#define DHCP_OPTION_US 60
|
||||||
|
#define DHCP_OPTION_CLIENT_ID 61
|
||||||
|
#define DHCP_OPTION_TFTP_SERVERNAME 66
|
||||||
|
#define DHCP_OPTION_BOOTFILE 67
|
||||||
|
|
||||||
|
/* possible combinations of overloading the file and sname fields with options */
|
||||||
|
#define DHCP_OVERLOAD_NONE 0
|
||||||
|
#define DHCP_OVERLOAD_FILE 1
|
||||||
|
#define DHCP_OVERLOAD_SNAME 2
|
||||||
|
#define DHCP_OVERLOAD_SNAME_FILE 3
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /*LWIP_HDR_PROT_DHCP_H*/
|
|
@ -0,0 +1,140 @@
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* DNS - host name to IP address resolver.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Port to lwIP from uIP
|
||||||
|
* by Jim Pettinato April 2007
|
||||||
|
*
|
||||||
|
* security fixes and more by Simon Goldschmidt
|
||||||
|
*
|
||||||
|
* uIP version Copyright (c) 2002-2003, Adam Dunkels.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote
|
||||||
|
* products derived from this software without specific prior
|
||||||
|
* written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
|
||||||
|
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||||
|
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef LWIP_HDR_PROT_DNS_H
|
||||||
|
#define LWIP_HDR_PROT_DNS_H
|
||||||
|
|
||||||
|
#include "lwip/arch.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** DNS server port address */
|
||||||
|
#ifndef DNS_SERVER_PORT
|
||||||
|
#define DNS_SERVER_PORT 53
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* DNS field TYPE used for "Resource Records" */
|
||||||
|
#define DNS_RRTYPE_A 1 /* a host address */
|
||||||
|
#define DNS_RRTYPE_NS 2 /* an authoritative name server */
|
||||||
|
#define DNS_RRTYPE_MD 3 /* a mail destination (Obsolete - use MX) */
|
||||||
|
#define DNS_RRTYPE_MF 4 /* a mail forwarder (Obsolete - use MX) */
|
||||||
|
#define DNS_RRTYPE_CNAME 5 /* the canonical name for an alias */
|
||||||
|
#define DNS_RRTYPE_SOA 6 /* marks the start of a zone of authority */
|
||||||
|
#define DNS_RRTYPE_MB 7 /* a mailbox domain name (EXPERIMENTAL) */
|
||||||
|
#define DNS_RRTYPE_MG 8 /* a mail group member (EXPERIMENTAL) */
|
||||||
|
#define DNS_RRTYPE_MR 9 /* a mail rename domain name (EXPERIMENTAL) */
|
||||||
|
#define DNS_RRTYPE_NULL 10 /* a null RR (EXPERIMENTAL) */
|
||||||
|
#define DNS_RRTYPE_WKS 11 /* a well known service description */
|
||||||
|
#define DNS_RRTYPE_PTR 12 /* a domain name pointer */
|
||||||
|
#define DNS_RRTYPE_HINFO 13 /* host information */
|
||||||
|
#define DNS_RRTYPE_MINFO 14 /* mailbox or mail list information */
|
||||||
|
#define DNS_RRTYPE_MX 15 /* mail exchange */
|
||||||
|
#define DNS_RRTYPE_TXT 16 /* text strings */
|
||||||
|
#define DNS_RRTYPE_AAAA 28 /* IPv6 address */
|
||||||
|
#define DNS_RRTYPE_SRV 33 /* service location */
|
||||||
|
#define DNS_RRTYPE_ANY 255 /* any type */
|
||||||
|
|
||||||
|
/* DNS field CLASS used for "Resource Records" */
|
||||||
|
#define DNS_RRCLASS_IN 1 /* the Internet */
|
||||||
|
#define DNS_RRCLASS_CS 2 /* the CSNET class (Obsolete - used only for examples in some obsolete RFCs) */
|
||||||
|
#define DNS_RRCLASS_CH 3 /* the CHAOS class */
|
||||||
|
#define DNS_RRCLASS_HS 4 /* Hesiod [Dyer 87] */
|
||||||
|
#define DNS_RRCLASS_ANY 255 /* any class */
|
||||||
|
#define DNS_RRCLASS_FLUSH 0x800 /* Flush bit */
|
||||||
|
|
||||||
|
/* DNS protocol flags */
|
||||||
|
#define DNS_FLAG1_RESPONSE 0x80
|
||||||
|
#define DNS_FLAG1_OPCODE_STATUS 0x10
|
||||||
|
#define DNS_FLAG1_OPCODE_INVERSE 0x08
|
||||||
|
#define DNS_FLAG1_OPCODE_STANDARD 0x00
|
||||||
|
#define DNS_FLAG1_AUTHORATIVE 0x04
|
||||||
|
#define DNS_FLAG1_TRUNC 0x02
|
||||||
|
#define DNS_FLAG1_RD 0x01
|
||||||
|
#define DNS_FLAG2_RA 0x80
|
||||||
|
#define DNS_FLAG2_ERR_MASK 0x0f
|
||||||
|
#define DNS_FLAG2_ERR_NONE 0x00
|
||||||
|
#define DNS_FLAG2_ERR_NAME 0x03
|
||||||
|
|
||||||
|
#define DNS_HDR_GET_OPCODE(hdr) ((((hdr)->flags1) >> 3) & 0xF)
|
||||||
|
|
||||||
|
#ifdef PACK_STRUCT_USE_INCLUDES
|
||||||
|
# include "arch/bpstruct.h"
|
||||||
|
#endif
|
||||||
|
PACK_STRUCT_BEGIN
|
||||||
|
/** DNS message header */
|
||||||
|
struct dns_hdr {
|
||||||
|
PACK_STRUCT_FIELD(u16_t id);
|
||||||
|
PACK_STRUCT_FLD_8(u8_t flags1);
|
||||||
|
PACK_STRUCT_FLD_8(u8_t flags2);
|
||||||
|
PACK_STRUCT_FIELD(u16_t numquestions);
|
||||||
|
PACK_STRUCT_FIELD(u16_t numanswers);
|
||||||
|
PACK_STRUCT_FIELD(u16_t numauthrr);
|
||||||
|
PACK_STRUCT_FIELD(u16_t numextrarr);
|
||||||
|
} PACK_STRUCT_STRUCT;
|
||||||
|
PACK_STRUCT_END
|
||||||
|
#ifdef PACK_STRUCT_USE_INCLUDES
|
||||||
|
# include "arch/epstruct.h"
|
||||||
|
#endif
|
||||||
|
#define SIZEOF_DNS_HDR 12
|
||||||
|
|
||||||
|
|
||||||
|
/* Multicast DNS definitions */
|
||||||
|
|
||||||
|
/** UDP port for multicast DNS queries */
|
||||||
|
#ifndef DNS_MQUERY_PORT
|
||||||
|
#define DNS_MQUERY_PORT 5353
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* IPv4 group for multicast DNS queries: 224.0.0.251 */
|
||||||
|
#ifndef DNS_MQUERY_IPV4_GROUP_INIT
|
||||||
|
#define DNS_MQUERY_IPV4_GROUP_INIT IPADDR4_INIT_BYTES(224,0,0,251)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* IPv6 group for multicast DNS queries: FF02::FB */
|
||||||
|
#ifndef DNS_MQUERY_IPV6_GROUP_INIT
|
||||||
|
#define DNS_MQUERY_IPV6_GROUP_INIT IPADDR6_INIT_HOST(0xFF020000,0,0,0xFB)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* LWIP_HDR_PROT_DNS_H */
|
|
@ -0,0 +1,91 @@
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* ARP protocol definitions
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||||
|
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||||
|
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
|
* OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* This file is part of the lwIP TCP/IP stack.
|
||||||
|
*
|
||||||
|
* Author: Adam Dunkels <adam@sics.se>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef LWIP_HDR_PROT_ETHARP_H
|
||||||
|
#define LWIP_HDR_PROT_ETHARP_H
|
||||||
|
|
||||||
|
#include "lwip/arch.h"
|
||||||
|
#include "lwip/prot/ethernet.h"
|
||||||
|
#include "lwip/ip4_addr.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef ETHARP_HWADDR_LEN
|
||||||
|
#define ETHARP_HWADDR_LEN ETH_HWADDR_LEN
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef PACK_STRUCT_USE_INCLUDES
|
||||||
|
# include "arch/bpstruct.h"
|
||||||
|
#endif
|
||||||
|
PACK_STRUCT_BEGIN
|
||||||
|
/** the ARP message, see RFC 826 ("Packet format") */
|
||||||
|
struct etharp_hdr {
|
||||||
|
PACK_STRUCT_FIELD(u16_t hwtype);
|
||||||
|
PACK_STRUCT_FIELD(u16_t proto);
|
||||||
|
PACK_STRUCT_FLD_8(u8_t hwlen);
|
||||||
|
PACK_STRUCT_FLD_8(u8_t protolen);
|
||||||
|
PACK_STRUCT_FIELD(u16_t opcode);
|
||||||
|
PACK_STRUCT_FLD_S(struct eth_addr shwaddr);
|
||||||
|
PACK_STRUCT_FLD_S(struct ip4_addr2 sipaddr);
|
||||||
|
PACK_STRUCT_FLD_S(struct eth_addr dhwaddr);
|
||||||
|
PACK_STRUCT_FLD_S(struct ip4_addr2 dipaddr);
|
||||||
|
} PACK_STRUCT_STRUCT;
|
||||||
|
PACK_STRUCT_END
|
||||||
|
#ifdef PACK_STRUCT_USE_INCLUDES
|
||||||
|
# include "arch/epstruct.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define SIZEOF_ETHARP_HDR 28
|
||||||
|
|
||||||
|
/* ARP hwtype values */
|
||||||
|
enum etharp_hwtype {
|
||||||
|
HWTYPE_ETHERNET = 1
|
||||||
|
/* others not used */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* ARP message types (opcodes) */
|
||||||
|
enum etharp_opcode {
|
||||||
|
ARP_REQUEST = 1,
|
||||||
|
ARP_REPLY = 2
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* LWIP_HDR_PROT_ETHARP_H */
|
|
@ -0,0 +1,164 @@
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* Ethernet protocol definitions
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||||
|
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||||
|
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
|
* OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* This file is part of the lwIP TCP/IP stack.
|
||||||
|
*
|
||||||
|
* Author: Adam Dunkels <adam@sics.se>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef LWIP_HDR_PROT_ETHERNET_H
|
||||||
|
#define LWIP_HDR_PROT_ETHERNET_H
|
||||||
|
|
||||||
|
#include "lwip/arch.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef ETH_HWADDR_LEN
|
||||||
|
#ifdef ETHARP_HWADDR_LEN
|
||||||
|
#define ETH_HWADDR_LEN ETHARP_HWADDR_LEN /* compatibility mode */
|
||||||
|
#else
|
||||||
|
#define ETH_HWADDR_LEN 6
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef PACK_STRUCT_USE_INCLUDES
|
||||||
|
# include "arch/bpstruct.h"
|
||||||
|
#endif
|
||||||
|
PACK_STRUCT_BEGIN
|
||||||
|
struct eth_addr {
|
||||||
|
PACK_STRUCT_FLD_8(u8_t addr[ETH_HWADDR_LEN]);
|
||||||
|
} PACK_STRUCT_STRUCT;
|
||||||
|
PACK_STRUCT_END
|
||||||
|
#ifdef PACK_STRUCT_USE_INCLUDES
|
||||||
|
# include "arch/epstruct.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef PACK_STRUCT_USE_INCLUDES
|
||||||
|
# include "arch/bpstruct.h"
|
||||||
|
#endif
|
||||||
|
PACK_STRUCT_BEGIN
|
||||||
|
/** Ethernet header */
|
||||||
|
struct eth_hdr {
|
||||||
|
#if ETH_PAD_SIZE
|
||||||
|
PACK_STRUCT_FLD_8(u8_t padding[ETH_PAD_SIZE]);
|
||||||
|
#endif
|
||||||
|
PACK_STRUCT_FLD_S(struct eth_addr dest);
|
||||||
|
PACK_STRUCT_FLD_S(struct eth_addr src);
|
||||||
|
PACK_STRUCT_FIELD(u16_t type);
|
||||||
|
} PACK_STRUCT_STRUCT;
|
||||||
|
PACK_STRUCT_END
|
||||||
|
#ifdef PACK_STRUCT_USE_INCLUDES
|
||||||
|
# include "arch/epstruct.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define SIZEOF_ETH_HDR (14 + ETH_PAD_SIZE)
|
||||||
|
|
||||||
|
#ifdef PACK_STRUCT_USE_INCLUDES
|
||||||
|
# include "arch/bpstruct.h"
|
||||||
|
#endif
|
||||||
|
PACK_STRUCT_BEGIN
|
||||||
|
/** VLAN header inserted between ethernet header and payload
|
||||||
|
* if 'type' in ethernet header is ETHTYPE_VLAN.
|
||||||
|
* See IEEE802.Q */
|
||||||
|
struct eth_vlan_hdr {
|
||||||
|
PACK_STRUCT_FIELD(u16_t prio_vid);
|
||||||
|
PACK_STRUCT_FIELD(u16_t tpid);
|
||||||
|
} PACK_STRUCT_STRUCT;
|
||||||
|
PACK_STRUCT_END
|
||||||
|
#ifdef PACK_STRUCT_USE_INCLUDES
|
||||||
|
# include "arch/epstruct.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define SIZEOF_VLAN_HDR 4
|
||||||
|
#define VLAN_ID(vlan_hdr) (lwip_htons((vlan_hdr)->prio_vid) & 0xFFF)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup ethernet
|
||||||
|
* A list of often ethtypes (although lwIP does not use all of them): */
|
||||||
|
enum eth_type {
|
||||||
|
/** Internet protocol v4 */
|
||||||
|
ETHTYPE_IP = 0x0800U,
|
||||||
|
/** Address resolution protocol */
|
||||||
|
ETHTYPE_ARP = 0x0806U,
|
||||||
|
/** Wake on lan */
|
||||||
|
ETHTYPE_WOL = 0x0842U,
|
||||||
|
/** RARP */
|
||||||
|
ETHTYPE_RARP = 0x8035U,
|
||||||
|
/** Virtual local area network */
|
||||||
|
ETHTYPE_VLAN = 0x8100U,
|
||||||
|
/** Internet protocol v6 */
|
||||||
|
ETHTYPE_IPV6 = 0x86DDU,
|
||||||
|
/** PPP Over Ethernet Discovery Stage */
|
||||||
|
ETHTYPE_PPPOEDISC = 0x8863U,
|
||||||
|
/** PPP Over Ethernet Session Stage */
|
||||||
|
ETHTYPE_PPPOE = 0x8864U,
|
||||||
|
/** Jumbo Frames */
|
||||||
|
ETHTYPE_JUMBO = 0x8870U,
|
||||||
|
/** Process field network */
|
||||||
|
ETHTYPE_PROFINET = 0x8892U,
|
||||||
|
/** Ethernet for control automation technology */
|
||||||
|
ETHTYPE_ETHERCAT = 0x88A4U,
|
||||||
|
/** Link layer discovery protocol */
|
||||||
|
ETHTYPE_LLDP = 0x88CCU,
|
||||||
|
/** Serial real-time communication system */
|
||||||
|
ETHTYPE_SERCOS = 0x88CDU,
|
||||||
|
/** Media redundancy protocol */
|
||||||
|
ETHTYPE_MRP = 0x88E3U,
|
||||||
|
/** Precision time protocol */
|
||||||
|
ETHTYPE_PTP = 0x88F7U,
|
||||||
|
/** Q-in-Q, 802.1ad */
|
||||||
|
ETHTYPE_QINQ = 0x9100U
|
||||||
|
};
|
||||||
|
|
||||||
|
/** The 24-bit IANA IPv4-multicast OUI is 01-00-5e: */
|
||||||
|
#define LL_IP4_MULTICAST_ADDR_0 0x01
|
||||||
|
#define LL_IP4_MULTICAST_ADDR_1 0x00
|
||||||
|
#define LL_IP4_MULTICAST_ADDR_2 0x5e
|
||||||
|
|
||||||
|
/** IPv6 multicast uses this prefix */
|
||||||
|
#define LL_IP6_MULTICAST_ADDR_0 0x33
|
||||||
|
#define LL_IP6_MULTICAST_ADDR_1 0x33
|
||||||
|
|
||||||
|
/** MEMCPY-like macro to copy to/from struct eth_addr's that are no local
|
||||||
|
* variables and known to be 16-bit aligned within the protocol header. */
|
||||||
|
#ifndef ETHADDR16_COPY
|
||||||
|
#define ETHADDR16_COPY(dst, src) SMEMCPY(dst, src, ETH_HWADDR_LEN)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define eth_addr_cmp(addr1, addr2) (memcmp((addr1)->addr, (addr2)->addr, ETH_HWADDR_LEN) == 0)
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* LWIP_HDR_PROT_ETHERNET_H */
|
|
@ -0,0 +1,91 @@
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* ICMP protocol definitions
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||||
|
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||||
|
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
|
* OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* This file is part of the lwIP TCP/IP stack.
|
||||||
|
*
|
||||||
|
* Author: Adam Dunkels <adam@sics.se>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef LWIP_HDR_PROT_ICMP_H
|
||||||
|
#define LWIP_HDR_PROT_ICMP_H
|
||||||
|
|
||||||
|
#include "lwip/arch.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define ICMP_ER 0 /* echo reply */
|
||||||
|
#define ICMP_DUR 3 /* destination unreachable */
|
||||||
|
#define ICMP_SQ 4 /* source quench */
|
||||||
|
#define ICMP_RD 5 /* redirect */
|
||||||
|
#define ICMP_ECHO 8 /* echo */
|
||||||
|
#define ICMP_TE 11 /* time exceeded */
|
||||||
|
#define ICMP_PP 12 /* parameter problem */
|
||||||
|
#define ICMP_TS 13 /* timestamp */
|
||||||
|
#define ICMP_TSR 14 /* timestamp reply */
|
||||||
|
#define ICMP_IRQ 15 /* information request */
|
||||||
|
#define ICMP_IR 16 /* information reply */
|
||||||
|
#define ICMP_AM 17 /* address mask request */
|
||||||
|
#define ICMP_AMR 18 /* address mask reply */
|
||||||
|
|
||||||
|
#ifdef PACK_STRUCT_USE_INCLUDES
|
||||||
|
# include "arch/bpstruct.h"
|
||||||
|
#endif
|
||||||
|
/** This is the standard ICMP header only that the u32_t data
|
||||||
|
* is split to two u16_t like ICMP echo needs it.
|
||||||
|
* This header is also used for other ICMP types that do not
|
||||||
|
* use the data part.
|
||||||
|
*/
|
||||||
|
PACK_STRUCT_BEGIN
|
||||||
|
struct icmp_echo_hdr {
|
||||||
|
PACK_STRUCT_FLD_8(u8_t type);
|
||||||
|
PACK_STRUCT_FLD_8(u8_t code);
|
||||||
|
PACK_STRUCT_FIELD(u16_t chksum);
|
||||||
|
PACK_STRUCT_FIELD(u16_t id);
|
||||||
|
PACK_STRUCT_FIELD(u16_t seqno);
|
||||||
|
} PACK_STRUCT_STRUCT;
|
||||||
|
PACK_STRUCT_END
|
||||||
|
#ifdef PACK_STRUCT_USE_INCLUDES
|
||||||
|
# include "arch/epstruct.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Compatibility defines, old versions used to combine type and code to an u16_t */
|
||||||
|
#define ICMPH_TYPE(hdr) ((hdr)->type)
|
||||||
|
#define ICMPH_CODE(hdr) ((hdr)->code)
|
||||||
|
#define ICMPH_TYPE_SET(hdr, t) ((hdr)->type = (t))
|
||||||
|
#define ICMPH_CODE_SET(hdr, c) ((hdr)->code = (c))
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* LWIP_HDR_PROT_ICMP_H */
|
|
@ -0,0 +1,170 @@
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* ICMP6 protocol definitions
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||||
|
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||||
|
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
|
* OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* This file is part of the lwIP TCP/IP stack.
|
||||||
|
*
|
||||||
|
* Author: Adam Dunkels <adam@sics.se>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef LWIP_HDR_PROT_ICMP6_H
|
||||||
|
#define LWIP_HDR_PROT_ICMP6_H
|
||||||
|
|
||||||
|
#include "lwip/arch.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** ICMP type */
|
||||||
|
enum icmp6_type {
|
||||||
|
/** Destination unreachable */
|
||||||
|
ICMP6_TYPE_DUR = 1,
|
||||||
|
/** Packet too big */
|
||||||
|
ICMP6_TYPE_PTB = 2,
|
||||||
|
/** Time exceeded */
|
||||||
|
ICMP6_TYPE_TE = 3,
|
||||||
|
/** Parameter problem */
|
||||||
|
ICMP6_TYPE_PP = 4,
|
||||||
|
/** Private experimentation */
|
||||||
|
ICMP6_TYPE_PE1 = 100,
|
||||||
|
/** Private experimentation */
|
||||||
|
ICMP6_TYPE_PE2 = 101,
|
||||||
|
/** Reserved for expansion of error messages */
|
||||||
|
ICMP6_TYPE_RSV_ERR = 127,
|
||||||
|
|
||||||
|
/** Echo request */
|
||||||
|
ICMP6_TYPE_EREQ = 128,
|
||||||
|
/** Echo reply */
|
||||||
|
ICMP6_TYPE_EREP = 129,
|
||||||
|
/** Multicast listener query */
|
||||||
|
ICMP6_TYPE_MLQ = 130,
|
||||||
|
/** Multicast listener report */
|
||||||
|
ICMP6_TYPE_MLR = 131,
|
||||||
|
/** Multicast listener done */
|
||||||
|
ICMP6_TYPE_MLD = 132,
|
||||||
|
/** Router solicitation */
|
||||||
|
ICMP6_TYPE_RS = 133,
|
||||||
|
/** Router advertisement */
|
||||||
|
ICMP6_TYPE_RA = 134,
|
||||||
|
/** Neighbor solicitation */
|
||||||
|
ICMP6_TYPE_NS = 135,
|
||||||
|
/** Neighbor advertisement */
|
||||||
|
ICMP6_TYPE_NA = 136,
|
||||||
|
/** Redirect */
|
||||||
|
ICMP6_TYPE_RD = 137,
|
||||||
|
/** Multicast router advertisement */
|
||||||
|
ICMP6_TYPE_MRA = 151,
|
||||||
|
/** Multicast router solicitation */
|
||||||
|
ICMP6_TYPE_MRS = 152,
|
||||||
|
/** Multicast router termination */
|
||||||
|
ICMP6_TYPE_MRT = 153,
|
||||||
|
/** Private experimentation */
|
||||||
|
ICMP6_TYPE_PE3 = 200,
|
||||||
|
/** Private experimentation */
|
||||||
|
ICMP6_TYPE_PE4 = 201,
|
||||||
|
/** Reserved for expansion of informational messages */
|
||||||
|
ICMP6_TYPE_RSV_INF = 255
|
||||||
|
};
|
||||||
|
|
||||||
|
/** ICMP destination unreachable codes */
|
||||||
|
enum icmp6_dur_code {
|
||||||
|
/** No route to destination */
|
||||||
|
ICMP6_DUR_NO_ROUTE = 0,
|
||||||
|
/** Communication with destination administratively prohibited */
|
||||||
|
ICMP6_DUR_PROHIBITED = 1,
|
||||||
|
/** Beyond scope of source address */
|
||||||
|
ICMP6_DUR_SCOPE = 2,
|
||||||
|
/** Address unreachable */
|
||||||
|
ICMP6_DUR_ADDRESS = 3,
|
||||||
|
/** Port unreachable */
|
||||||
|
ICMP6_DUR_PORT = 4,
|
||||||
|
/** Source address failed ingress/egress policy */
|
||||||
|
ICMP6_DUR_POLICY = 5,
|
||||||
|
/** Reject route to destination */
|
||||||
|
ICMP6_DUR_REJECT_ROUTE = 6
|
||||||
|
};
|
||||||
|
|
||||||
|
/** ICMP time exceeded codes */
|
||||||
|
enum icmp6_te_code {
|
||||||
|
/** Hop limit exceeded in transit */
|
||||||
|
ICMP6_TE_HL = 0,
|
||||||
|
/** Fragment reassembly time exceeded */
|
||||||
|
ICMP6_TE_FRAG = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
/** ICMP parameter code */
|
||||||
|
enum icmp6_pp_code {
|
||||||
|
/** Erroneous header field encountered */
|
||||||
|
ICMP6_PP_FIELD = 0,
|
||||||
|
/** Unrecognized next header type encountered */
|
||||||
|
ICMP6_PP_HEADER = 1,
|
||||||
|
/** Unrecognized IPv6 option encountered */
|
||||||
|
ICMP6_PP_OPTION = 2
|
||||||
|
};
|
||||||
|
|
||||||
|
/** This is the standard ICMP6 header. */
|
||||||
|
#ifdef PACK_STRUCT_USE_INCLUDES
|
||||||
|
# include "arch/bpstruct.h"
|
||||||
|
#endif
|
||||||
|
PACK_STRUCT_BEGIN
|
||||||
|
struct icmp6_hdr {
|
||||||
|
PACK_STRUCT_FLD_8(u8_t type);
|
||||||
|
PACK_STRUCT_FLD_8(u8_t code);
|
||||||
|
PACK_STRUCT_FIELD(u16_t chksum);
|
||||||
|
PACK_STRUCT_FIELD(u32_t data);
|
||||||
|
} PACK_STRUCT_STRUCT;
|
||||||
|
PACK_STRUCT_END
|
||||||
|
#ifdef PACK_STRUCT_USE_INCLUDES
|
||||||
|
# include "arch/epstruct.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** This is the ICMP6 header adapted for echo req/resp. */
|
||||||
|
#ifdef PACK_STRUCT_USE_INCLUDES
|
||||||
|
# include "arch/bpstruct.h"
|
||||||
|
#endif
|
||||||
|
PACK_STRUCT_BEGIN
|
||||||
|
struct icmp6_echo_hdr {
|
||||||
|
PACK_STRUCT_FLD_8(u8_t type);
|
||||||
|
PACK_STRUCT_FLD_8(u8_t code);
|
||||||
|
PACK_STRUCT_FIELD(u16_t chksum);
|
||||||
|
PACK_STRUCT_FIELD(u16_t id);
|
||||||
|
PACK_STRUCT_FIELD(u16_t seqno);
|
||||||
|
} PACK_STRUCT_STRUCT;
|
||||||
|
PACK_STRUCT_END
|
||||||
|
#ifdef PACK_STRUCT_USE_INCLUDES
|
||||||
|
# include "arch/epstruct.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* LWIP_HDR_PROT_ICMP6_H */
|
|
@ -0,0 +1,90 @@
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* IGMP protocol definitions
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||||
|
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||||
|
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
|
* OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* This file is part of the lwIP TCP/IP stack.
|
||||||
|
*
|
||||||
|
* Author: Adam Dunkels <adam@sics.se>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef LWIP_HDR_PROT_IGMP_H
|
||||||
|
#define LWIP_HDR_PROT_IGMP_H
|
||||||
|
|
||||||
|
#include "lwip/arch.h"
|
||||||
|
#include "lwip/ip4_addr.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* IGMP constants
|
||||||
|
*/
|
||||||
|
#define IGMP_TTL 1
|
||||||
|
#define IGMP_MINLEN 8
|
||||||
|
#define ROUTER_ALERT 0x9404U
|
||||||
|
#define ROUTER_ALERTLEN 4
|
||||||
|
|
||||||
|
/*
|
||||||
|
* IGMP message types, including version number.
|
||||||
|
*/
|
||||||
|
#define IGMP_MEMB_QUERY 0x11 /* Membership query */
|
||||||
|
#define IGMP_V1_MEMB_REPORT 0x12 /* Ver. 1 membership report */
|
||||||
|
#define IGMP_V2_MEMB_REPORT 0x16 /* Ver. 2 membership report */
|
||||||
|
#define IGMP_LEAVE_GROUP 0x17 /* Leave-group message */
|
||||||
|
|
||||||
|
/* Group membership states */
|
||||||
|
#define IGMP_GROUP_NON_MEMBER 0
|
||||||
|
#define IGMP_GROUP_DELAYING_MEMBER 1
|
||||||
|
#define IGMP_GROUP_IDLE_MEMBER 2
|
||||||
|
|
||||||
|
/**
|
||||||
|
* IGMP packet format.
|
||||||
|
*/
|
||||||
|
#ifdef PACK_STRUCT_USE_INCLUDES
|
||||||
|
# include "arch/bpstruct.h"
|
||||||
|
#endif
|
||||||
|
PACK_STRUCT_BEGIN
|
||||||
|
struct igmp_msg {
|
||||||
|
PACK_STRUCT_FLD_8(u8_t igmp_msgtype);
|
||||||
|
PACK_STRUCT_FLD_8(u8_t igmp_maxresp);
|
||||||
|
PACK_STRUCT_FIELD(u16_t igmp_checksum);
|
||||||
|
PACK_STRUCT_FLD_S(ip4_addr_p_t igmp_group_address);
|
||||||
|
} PACK_STRUCT_STRUCT;
|
||||||
|
PACK_STRUCT_END
|
||||||
|
#ifdef PACK_STRUCT_USE_INCLUDES
|
||||||
|
# include "arch/epstruct.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* LWIP_HDR_PROT_IGMP_H */
|
|
@ -0,0 +1,51 @@
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* IP protocol definitions
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||||
|
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||||
|
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
|
* OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* This file is part of the lwIP TCP/IP stack.
|
||||||
|
*
|
||||||
|
* Author: Adam Dunkels <adam@sics.se>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef LWIP_HDR_PROT_IP_H
|
||||||
|
#define LWIP_HDR_PROT_IP_H
|
||||||
|
|
||||||
|
#include "lwip/arch.h"
|
||||||
|
|
||||||
|
#define IP_PROTO_ICMP 1
|
||||||
|
#define IP_PROTO_IGMP 2
|
||||||
|
#define IP_PROTO_UDP 17
|
||||||
|
#define IP_PROTO_UDPLITE 136
|
||||||
|
#define IP_PROTO_TCP 6
|
||||||
|
|
||||||
|
/** This operates on a void* by loading the first byte */
|
||||||
|
#define IP_HDR_GET_VERSION(ptr) ((*(u8_t*)(ptr)) >> 4)
|
||||||
|
|
||||||
|
#endif /* LWIP_HDR_PROT_IP_H */
|
|
@ -0,0 +1,127 @@
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* IPv4 protocol definitions
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||||
|
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||||
|
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
|
* OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* This file is part of the lwIP TCP/IP stack.
|
||||||
|
*
|
||||||
|
* Author: Adam Dunkels <adam@sics.se>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef LWIP_HDR_PROT_IP4_H
|
||||||
|
#define LWIP_HDR_PROT_IP4_H
|
||||||
|
|
||||||
|
#include "lwip/arch.h"
|
||||||
|
#include "lwip/ip4_addr.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** This is the packed version of ip4_addr_t,
|
||||||
|
used in network headers that are itself packed */
|
||||||
|
#ifdef PACK_STRUCT_USE_INCLUDES
|
||||||
|
# include "arch/bpstruct.h"
|
||||||
|
#endif
|
||||||
|
PACK_STRUCT_BEGIN
|
||||||
|
struct ip4_addr_packed {
|
||||||
|
PACK_STRUCT_FIELD(u32_t addr);
|
||||||
|
} PACK_STRUCT_STRUCT;
|
||||||
|
PACK_STRUCT_END
|
||||||
|
#ifdef PACK_STRUCT_USE_INCLUDES
|
||||||
|
# include "arch/epstruct.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct ip4_addr_packed ip4_addr_p_t;
|
||||||
|
|
||||||
|
/* Size of the IPv4 header. Same as 'sizeof(struct ip_hdr)'. */
|
||||||
|
#define IP_HLEN 20
|
||||||
|
|
||||||
|
#ifdef PACK_STRUCT_USE_INCLUDES
|
||||||
|
# include "arch/bpstruct.h"
|
||||||
|
#endif
|
||||||
|
PACK_STRUCT_BEGIN
|
||||||
|
/* The IPv4 header */
|
||||||
|
struct ip_hdr {
|
||||||
|
/* version / header length */
|
||||||
|
PACK_STRUCT_FLD_8(u8_t _v_hl);
|
||||||
|
/* type of service */
|
||||||
|
PACK_STRUCT_FLD_8(u8_t _tos);
|
||||||
|
/* total length */
|
||||||
|
PACK_STRUCT_FIELD(u16_t _len);
|
||||||
|
/* identification */
|
||||||
|
PACK_STRUCT_FIELD(u16_t _id);
|
||||||
|
/* fragment offset field */
|
||||||
|
PACK_STRUCT_FIELD(u16_t _offset);
|
||||||
|
#define IP_RF 0x8000U /* reserved fragment flag */
|
||||||
|
#define IP_DF 0x4000U /* don't fragment flag */
|
||||||
|
#define IP_MF 0x2000U /* more fragments flag */
|
||||||
|
#define IP_OFFMASK 0x1fffU /* mask for fragmenting bits */
|
||||||
|
/* time to live */
|
||||||
|
PACK_STRUCT_FLD_8(u8_t _ttl);
|
||||||
|
/* protocol*/
|
||||||
|
PACK_STRUCT_FLD_8(u8_t _proto);
|
||||||
|
/* checksum */
|
||||||
|
PACK_STRUCT_FIELD(u16_t _chksum);
|
||||||
|
/* source and destination IP addresses */
|
||||||
|
PACK_STRUCT_FLD_S(ip4_addr_p_t src);
|
||||||
|
PACK_STRUCT_FLD_S(ip4_addr_p_t dest);
|
||||||
|
} PACK_STRUCT_STRUCT;
|
||||||
|
PACK_STRUCT_END
|
||||||
|
#ifdef PACK_STRUCT_USE_INCLUDES
|
||||||
|
# include "arch/epstruct.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Macros to get struct ip_hdr fields: */
|
||||||
|
#define IPH_V(hdr) ((hdr)->_v_hl >> 4)
|
||||||
|
#define IPH_HL(hdr) ((hdr)->_v_hl & 0x0f)
|
||||||
|
#define IPH_TOS(hdr) ((hdr)->_tos)
|
||||||
|
#define IPH_LEN(hdr) ((hdr)->_len)
|
||||||
|
#define IPH_ID(hdr) ((hdr)->_id)
|
||||||
|
#define IPH_OFFSET(hdr) ((hdr)->_offset)
|
||||||
|
#define IPH_TTL(hdr) ((hdr)->_ttl)
|
||||||
|
#define IPH_PROTO(hdr) ((hdr)->_proto)
|
||||||
|
#define IPH_CHKSUM(hdr) ((hdr)->_chksum)
|
||||||
|
|
||||||
|
/* Macros to set struct ip_hdr fields: */
|
||||||
|
#define IPH_VHL_SET(hdr, v, hl) (hdr)->_v_hl = (u8_t)((((v) << 4) | (hl)))
|
||||||
|
#define IPH_TOS_SET(hdr, tos) (hdr)->_tos = (tos)
|
||||||
|
#define IPH_LEN_SET(hdr, len) (hdr)->_len = (len)
|
||||||
|
#define IPH_ID_SET(hdr, id) (hdr)->_id = (id)
|
||||||
|
#define IPH_OFFSET_SET(hdr, off) (hdr)->_offset = (off)
|
||||||
|
#define IPH_TTL_SET(hdr, ttl) (hdr)->_ttl = (u8_t)(ttl)
|
||||||
|
#define IPH_PROTO_SET(hdr, proto) (hdr)->_proto = (u8_t)(proto)
|
||||||
|
#define IPH_CHKSUM_SET(hdr, chksum) (hdr)->_chksum = (chksum)
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* LWIP_HDR_PROT_IP4_H */
|
|
@ -0,0 +1,169 @@
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* IPv6 protocol definitions
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||||
|
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||||
|
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
|
* OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* This file is part of the lwIP TCP/IP stack.
|
||||||
|
*
|
||||||
|
* Author: Adam Dunkels <adam@sics.se>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef LWIP_HDR_PROT_IP6_H
|
||||||
|
#define LWIP_HDR_PROT_IP6_H
|
||||||
|
|
||||||
|
#include "lwip/arch.h"
|
||||||
|
#include "lwip/ip6_addr.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** This is the packed version of ip6_addr_t,
|
||||||
|
used in network headers that are itself packed */
|
||||||
|
#ifdef PACK_STRUCT_USE_INCLUDES
|
||||||
|
# include "arch/bpstruct.h"
|
||||||
|
#endif
|
||||||
|
PACK_STRUCT_BEGIN
|
||||||
|
struct ip6_addr_packed {
|
||||||
|
PACK_STRUCT_FIELD(u32_t addr[4]);
|
||||||
|
} PACK_STRUCT_STRUCT;
|
||||||
|
PACK_STRUCT_END
|
||||||
|
#ifdef PACK_STRUCT_USE_INCLUDES
|
||||||
|
# include "arch/epstruct.h"
|
||||||
|
#endif
|
||||||
|
typedef struct ip6_addr_packed ip6_addr_p_t;
|
||||||
|
|
||||||
|
#define IP6_HLEN 40
|
||||||
|
|
||||||
|
#define IP6_NEXTH_HOPBYHOP 0
|
||||||
|
#define IP6_NEXTH_TCP 6
|
||||||
|
#define IP6_NEXTH_UDP 17
|
||||||
|
#define IP6_NEXTH_ENCAPS 41
|
||||||
|
#define IP6_NEXTH_ROUTING 43
|
||||||
|
#define IP6_NEXTH_FRAGMENT 44
|
||||||
|
#define IP6_NEXTH_ICMP6 58
|
||||||
|
#define IP6_NEXTH_NONE 59
|
||||||
|
#define IP6_NEXTH_DESTOPTS 60
|
||||||
|
#define IP6_NEXTH_UDPLITE 136
|
||||||
|
|
||||||
|
/** The IPv6 header. */
|
||||||
|
#ifdef PACK_STRUCT_USE_INCLUDES
|
||||||
|
# include "arch/bpstruct.h"
|
||||||
|
#endif
|
||||||
|
PACK_STRUCT_BEGIN
|
||||||
|
struct ip6_hdr {
|
||||||
|
/** version / traffic class / flow label */
|
||||||
|
PACK_STRUCT_FIELD(u32_t _v_tc_fl);
|
||||||
|
/** payload length */
|
||||||
|
PACK_STRUCT_FIELD(u16_t _plen);
|
||||||
|
/** next header */
|
||||||
|
PACK_STRUCT_FLD_8(u8_t _nexth);
|
||||||
|
/** hop limit */
|
||||||
|
PACK_STRUCT_FLD_8(u8_t _hoplim);
|
||||||
|
/** source and destination IP addresses */
|
||||||
|
PACK_STRUCT_FLD_S(ip6_addr_p_t src);
|
||||||
|
PACK_STRUCT_FLD_S(ip6_addr_p_t dest);
|
||||||
|
} PACK_STRUCT_STRUCT;
|
||||||
|
PACK_STRUCT_END
|
||||||
|
#ifdef PACK_STRUCT_USE_INCLUDES
|
||||||
|
# include "arch/epstruct.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Hop-by-hop router alert option. */
|
||||||
|
#define IP6_HBH_HLEN 8
|
||||||
|
#define IP6_PAD1_OPTION 0
|
||||||
|
#define IP6_PADN_ALERT_OPTION 1
|
||||||
|
#define IP6_ROUTER_ALERT_OPTION 5
|
||||||
|
#define IP6_ROUTER_ALERT_VALUE_MLD 0
|
||||||
|
#ifdef PACK_STRUCT_USE_INCLUDES
|
||||||
|
# include "arch/bpstruct.h"
|
||||||
|
#endif
|
||||||
|
PACK_STRUCT_BEGIN
|
||||||
|
struct ip6_hbh_hdr {
|
||||||
|
/* next header */
|
||||||
|
PACK_STRUCT_FLD_8(u8_t _nexth);
|
||||||
|
/* header length */
|
||||||
|
PACK_STRUCT_FLD_8(u8_t _hlen);
|
||||||
|
/* router alert option type */
|
||||||
|
PACK_STRUCT_FLD_8(u8_t _ra_opt_type);
|
||||||
|
/* router alert option data len */
|
||||||
|
PACK_STRUCT_FLD_8(u8_t _ra_opt_dlen);
|
||||||
|
/* router alert option data */
|
||||||
|
PACK_STRUCT_FIELD(u16_t _ra_opt_data);
|
||||||
|
/* PadN option type */
|
||||||
|
PACK_STRUCT_FLD_8(u8_t _padn_opt_type);
|
||||||
|
/* PadN option data len */
|
||||||
|
PACK_STRUCT_FLD_8(u8_t _padn_opt_dlen);
|
||||||
|
} PACK_STRUCT_STRUCT;
|
||||||
|
PACK_STRUCT_END
|
||||||
|
#ifdef PACK_STRUCT_USE_INCLUDES
|
||||||
|
# include "arch/epstruct.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Fragment header. */
|
||||||
|
#define IP6_FRAG_HLEN 8
|
||||||
|
#define IP6_FRAG_OFFSET_MASK 0xfff8
|
||||||
|
#define IP6_FRAG_MORE_FLAG 0x0001
|
||||||
|
#ifdef PACK_STRUCT_USE_INCLUDES
|
||||||
|
# include "arch/bpstruct.h"
|
||||||
|
#endif
|
||||||
|
PACK_STRUCT_BEGIN
|
||||||
|
struct ip6_frag_hdr {
|
||||||
|
/* next header */
|
||||||
|
PACK_STRUCT_FLD_8(u8_t _nexth);
|
||||||
|
/* reserved */
|
||||||
|
PACK_STRUCT_FLD_8(u8_t reserved);
|
||||||
|
/* fragment offset */
|
||||||
|
PACK_STRUCT_FIELD(u16_t _fragment_offset);
|
||||||
|
/* fragmented packet identification */
|
||||||
|
PACK_STRUCT_FIELD(u32_t _identification);
|
||||||
|
} PACK_STRUCT_STRUCT;
|
||||||
|
PACK_STRUCT_END
|
||||||
|
#ifdef PACK_STRUCT_USE_INCLUDES
|
||||||
|
# include "arch/epstruct.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define IP6H_V(hdr) ((lwip_ntohl((hdr)->_v_tc_fl) >> 28) & 0x0f)
|
||||||
|
#define IP6H_TC(hdr) ((lwip_ntohl((hdr)->_v_tc_fl) >> 20) & 0xff)
|
||||||
|
#define IP6H_FL(hdr) (lwip_ntohl((hdr)->_v_tc_fl) & 0x000fffff)
|
||||||
|
#define IP6H_PLEN(hdr) (lwip_ntohs((hdr)->_plen))
|
||||||
|
#define IP6H_NEXTH(hdr) ((hdr)->_nexth)
|
||||||
|
#define IP6H_NEXTH_P(hdr) ((u8_t *)(hdr) + 6)
|
||||||
|
#define IP6H_HOPLIM(hdr) ((hdr)->_hoplim)
|
||||||
|
|
||||||
|
#define IP6H_VTCFL_SET(hdr, v, tc, fl) (hdr)->_v_tc_fl = (lwip_htonl((((u32_t)(v)) << 28) | (((u32_t)(tc)) << 20) | (fl)))
|
||||||
|
#define IP6H_PLEN_SET(hdr, plen) (hdr)->_plen = lwip_htons(plen)
|
||||||
|
#define IP6H_NEXTH_SET(hdr, nexth) (hdr)->_nexth = (nexth)
|
||||||
|
#define IP6H_HOPLIM_SET(hdr, hl) (hdr)->_hoplim = (u8_t)(hl)
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* LWIP_HDR_PROT_IP6_H */
|
|
@ -0,0 +1,70 @@
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* MLD6 protocol definitions
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||||
|
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||||
|
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
|
* OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* This file is part of the lwIP TCP/IP stack.
|
||||||
|
*
|
||||||
|
* Author: Adam Dunkels <adam@sics.se>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef LWIP_HDR_PROT_MLD6_H
|
||||||
|
#define LWIP_HDR_PROT_MLD6_H
|
||||||
|
|
||||||
|
#include "lwip/arch.h"
|
||||||
|
#include "lwip/prot/ip6.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** Multicast listener report/query/done message header. */
|
||||||
|
#ifdef PACK_STRUCT_USE_INCLUDES
|
||||||
|
# include "arch/bpstruct.h"
|
||||||
|
#endif
|
||||||
|
PACK_STRUCT_BEGIN
|
||||||
|
struct mld_header {
|
||||||
|
PACK_STRUCT_FLD_8(u8_t type);
|
||||||
|
PACK_STRUCT_FLD_8(u8_t code);
|
||||||
|
PACK_STRUCT_FIELD(u16_t chksum);
|
||||||
|
PACK_STRUCT_FIELD(u16_t max_resp_delay);
|
||||||
|
PACK_STRUCT_FIELD(u16_t reserved);
|
||||||
|
PACK_STRUCT_FLD_S(ip6_addr_p_t multicast_address);
|
||||||
|
/* Options follow. */
|
||||||
|
} PACK_STRUCT_STRUCT;
|
||||||
|
PACK_STRUCT_END
|
||||||
|
#ifdef PACK_STRUCT_USE_INCLUDES
|
||||||
|
# include "arch/epstruct.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* LWIP_HDR_PROT_MLD6_H */
|
|
@ -0,0 +1,277 @@
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* ND6 protocol definitions
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||||
|
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||||
|
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
|
* OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* This file is part of the lwIP TCP/IP stack.
|
||||||
|
*
|
||||||
|
* Author: Adam Dunkels <adam@sics.se>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef LWIP_HDR_PROT_ND6_H
|
||||||
|
#define LWIP_HDR_PROT_ND6_H
|
||||||
|
|
||||||
|
#include "lwip/arch.h"
|
||||||
|
#include "lwip/ip6_addr.h"
|
||||||
|
#include "lwip/prot/ip6.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** Neighbor solicitation message header. */
|
||||||
|
#ifdef PACK_STRUCT_USE_INCLUDES
|
||||||
|
# include "arch/bpstruct.h"
|
||||||
|
#endif
|
||||||
|
PACK_STRUCT_BEGIN
|
||||||
|
struct ns_header {
|
||||||
|
PACK_STRUCT_FLD_8(u8_t type);
|
||||||
|
PACK_STRUCT_FLD_8(u8_t code);
|
||||||
|
PACK_STRUCT_FIELD(u16_t chksum);
|
||||||
|
PACK_STRUCT_FIELD(u32_t reserved);
|
||||||
|
PACK_STRUCT_FLD_S(ip6_addr_p_t target_address);
|
||||||
|
/* Options follow. */
|
||||||
|
} PACK_STRUCT_STRUCT;
|
||||||
|
PACK_STRUCT_END
|
||||||
|
#ifdef PACK_STRUCT_USE_INCLUDES
|
||||||
|
# include "arch/epstruct.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** Neighbor advertisement message header. */
|
||||||
|
#ifdef PACK_STRUCT_USE_INCLUDES
|
||||||
|
# include "arch/bpstruct.h"
|
||||||
|
#endif
|
||||||
|
PACK_STRUCT_BEGIN
|
||||||
|
struct na_header {
|
||||||
|
PACK_STRUCT_FLD_8(u8_t type);
|
||||||
|
PACK_STRUCT_FLD_8(u8_t code);
|
||||||
|
PACK_STRUCT_FIELD(u16_t chksum);
|
||||||
|
PACK_STRUCT_FLD_8(u8_t flags);
|
||||||
|
PACK_STRUCT_FLD_8(u8_t reserved[3]);
|
||||||
|
PACK_STRUCT_FLD_S(ip6_addr_p_t target_address);
|
||||||
|
/* Options follow. */
|
||||||
|
} PACK_STRUCT_STRUCT;
|
||||||
|
PACK_STRUCT_END
|
||||||
|
#ifdef PACK_STRUCT_USE_INCLUDES
|
||||||
|
# include "arch/epstruct.h"
|
||||||
|
#endif
|
||||||
|
#define ND6_FLAG_ROUTER (0x80)
|
||||||
|
#define ND6_FLAG_SOLICITED (0x40)
|
||||||
|
#define ND6_FLAG_OVERRIDE (0x20)
|
||||||
|
|
||||||
|
/** Router solicitation message header. */
|
||||||
|
#ifdef PACK_STRUCT_USE_INCLUDES
|
||||||
|
# include "arch/bpstruct.h"
|
||||||
|
#endif
|
||||||
|
PACK_STRUCT_BEGIN
|
||||||
|
struct rs_header {
|
||||||
|
PACK_STRUCT_FLD_8(u8_t type);
|
||||||
|
PACK_STRUCT_FLD_8(u8_t code);
|
||||||
|
PACK_STRUCT_FIELD(u16_t chksum);
|
||||||
|
PACK_STRUCT_FIELD(u32_t reserved);
|
||||||
|
/* Options follow. */
|
||||||
|
} PACK_STRUCT_STRUCT;
|
||||||
|
PACK_STRUCT_END
|
||||||
|
#ifdef PACK_STRUCT_USE_INCLUDES
|
||||||
|
# include "arch/epstruct.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** Router advertisement message header. */
|
||||||
|
#define ND6_RA_FLAG_MANAGED_ADDR_CONFIG (0x80)
|
||||||
|
#define ND6_RA_FLAG_OTHER_CONFIG (0x40)
|
||||||
|
#define ND6_RA_FLAG_HOME_AGENT (0x20)
|
||||||
|
#define ND6_RA_PREFERENCE_MASK (0x18)
|
||||||
|
#define ND6_RA_PREFERENCE_HIGH (0x08)
|
||||||
|
#define ND6_RA_PREFERENCE_MEDIUM (0x00)
|
||||||
|
#define ND6_RA_PREFERENCE_LOW (0x18)
|
||||||
|
#define ND6_RA_PREFERENCE_DISABLED (0x10)
|
||||||
|
#ifdef PACK_STRUCT_USE_INCLUDES
|
||||||
|
# include "arch/bpstruct.h"
|
||||||
|
#endif
|
||||||
|
PACK_STRUCT_BEGIN
|
||||||
|
struct ra_header {
|
||||||
|
PACK_STRUCT_FLD_8(u8_t type);
|
||||||
|
PACK_STRUCT_FLD_8(u8_t code);
|
||||||
|
PACK_STRUCT_FIELD(u16_t chksum);
|
||||||
|
PACK_STRUCT_FLD_8(u8_t current_hop_limit);
|
||||||
|
PACK_STRUCT_FLD_8(u8_t flags);
|
||||||
|
PACK_STRUCT_FIELD(u16_t router_lifetime);
|
||||||
|
PACK_STRUCT_FIELD(u32_t reachable_time);
|
||||||
|
PACK_STRUCT_FIELD(u32_t retrans_timer);
|
||||||
|
/* Options follow. */
|
||||||
|
} PACK_STRUCT_STRUCT;
|
||||||
|
PACK_STRUCT_END
|
||||||
|
#ifdef PACK_STRUCT_USE_INCLUDES
|
||||||
|
# include "arch/epstruct.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** Redirect message header. */
|
||||||
|
#ifdef PACK_STRUCT_USE_INCLUDES
|
||||||
|
# include "arch/bpstruct.h"
|
||||||
|
#endif
|
||||||
|
PACK_STRUCT_BEGIN
|
||||||
|
struct redirect_header {
|
||||||
|
PACK_STRUCT_FLD_8(u8_t type);
|
||||||
|
PACK_STRUCT_FLD_8(u8_t code);
|
||||||
|
PACK_STRUCT_FIELD(u16_t chksum);
|
||||||
|
PACK_STRUCT_FIELD(u32_t reserved);
|
||||||
|
PACK_STRUCT_FLD_S(ip6_addr_p_t target_address);
|
||||||
|
PACK_STRUCT_FLD_S(ip6_addr_p_t destination_address);
|
||||||
|
/* Options follow. */
|
||||||
|
} PACK_STRUCT_STRUCT;
|
||||||
|
PACK_STRUCT_END
|
||||||
|
#ifdef PACK_STRUCT_USE_INCLUDES
|
||||||
|
# include "arch/epstruct.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** Link-layer address option. */
|
||||||
|
#define ND6_OPTION_TYPE_SOURCE_LLADDR (0x01)
|
||||||
|
#define ND6_OPTION_TYPE_TARGET_LLADDR (0x02)
|
||||||
|
#ifdef PACK_STRUCT_USE_INCLUDES
|
||||||
|
# include "arch/bpstruct.h"
|
||||||
|
#endif
|
||||||
|
PACK_STRUCT_BEGIN
|
||||||
|
struct lladdr_option {
|
||||||
|
PACK_STRUCT_FLD_8(u8_t type);
|
||||||
|
PACK_STRUCT_FLD_8(u8_t length);
|
||||||
|
PACK_STRUCT_FLD_8(u8_t addr[NETIF_MAX_HWADDR_LEN]);
|
||||||
|
} PACK_STRUCT_STRUCT;
|
||||||
|
PACK_STRUCT_END
|
||||||
|
#ifdef PACK_STRUCT_USE_INCLUDES
|
||||||
|
# include "arch/epstruct.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** Prefix information option. */
|
||||||
|
#define ND6_OPTION_TYPE_PREFIX_INFO (0x03)
|
||||||
|
#define ND6_PREFIX_FLAG_ON_LINK (0x80)
|
||||||
|
#define ND6_PREFIX_FLAG_AUTONOMOUS (0x40)
|
||||||
|
#define ND6_PREFIX_FLAG_ROUTER_ADDRESS (0x20)
|
||||||
|
#define ND6_PREFIX_FLAG_SITE_PREFIX (0x10)
|
||||||
|
#ifdef PACK_STRUCT_USE_INCLUDES
|
||||||
|
# include "arch/bpstruct.h"
|
||||||
|
#endif
|
||||||
|
PACK_STRUCT_BEGIN
|
||||||
|
struct prefix_option {
|
||||||
|
PACK_STRUCT_FLD_8(u8_t type);
|
||||||
|
PACK_STRUCT_FLD_8(u8_t length);
|
||||||
|
PACK_STRUCT_FLD_8(u8_t prefix_length);
|
||||||
|
PACK_STRUCT_FLD_8(u8_t flags);
|
||||||
|
PACK_STRUCT_FIELD(u32_t valid_lifetime);
|
||||||
|
PACK_STRUCT_FIELD(u32_t preferred_lifetime);
|
||||||
|
PACK_STRUCT_FLD_8(u8_t reserved2[3]);
|
||||||
|
PACK_STRUCT_FLD_8(u8_t site_prefix_length);
|
||||||
|
PACK_STRUCT_FLD_S(ip6_addr_p_t prefix);
|
||||||
|
} PACK_STRUCT_STRUCT;
|
||||||
|
PACK_STRUCT_END
|
||||||
|
#ifdef PACK_STRUCT_USE_INCLUDES
|
||||||
|
# include "arch/epstruct.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** Redirected header option. */
|
||||||
|
#define ND6_OPTION_TYPE_REDIR_HDR (0x04)
|
||||||
|
#ifdef PACK_STRUCT_USE_INCLUDES
|
||||||
|
# include "arch/bpstruct.h"
|
||||||
|
#endif
|
||||||
|
PACK_STRUCT_BEGIN
|
||||||
|
struct redirected_header_option {
|
||||||
|
PACK_STRUCT_FLD_8(u8_t type);
|
||||||
|
PACK_STRUCT_FLD_8(u8_t length);
|
||||||
|
PACK_STRUCT_FLD_8(u8_t reserved[6]);
|
||||||
|
/* Portion of redirected packet follows. */
|
||||||
|
/* PACK_STRUCT_FLD_8(u8_t redirected[8]); */
|
||||||
|
} PACK_STRUCT_STRUCT;
|
||||||
|
PACK_STRUCT_END
|
||||||
|
#ifdef PACK_STRUCT_USE_INCLUDES
|
||||||
|
# include "arch/epstruct.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** MTU option. */
|
||||||
|
#define ND6_OPTION_TYPE_MTU (0x05)
|
||||||
|
#ifdef PACK_STRUCT_USE_INCLUDES
|
||||||
|
# include "arch/bpstruct.h"
|
||||||
|
#endif
|
||||||
|
PACK_STRUCT_BEGIN
|
||||||
|
struct mtu_option {
|
||||||
|
PACK_STRUCT_FLD_8(u8_t type);
|
||||||
|
PACK_STRUCT_FLD_8(u8_t length);
|
||||||
|
PACK_STRUCT_FIELD(u16_t reserved);
|
||||||
|
PACK_STRUCT_FIELD(u32_t mtu);
|
||||||
|
} PACK_STRUCT_STRUCT;
|
||||||
|
PACK_STRUCT_END
|
||||||
|
#ifdef PACK_STRUCT_USE_INCLUDES
|
||||||
|
# include "arch/epstruct.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** Route information option. */
|
||||||
|
#define ND6_OPTION_TYPE_ROUTE_INFO (24)
|
||||||
|
#ifdef PACK_STRUCT_USE_INCLUDES
|
||||||
|
# include "arch/bpstruct.h"
|
||||||
|
#endif
|
||||||
|
PACK_STRUCT_BEGIN
|
||||||
|
struct route_option {
|
||||||
|
PACK_STRUCT_FLD_8(u8_t type);
|
||||||
|
PACK_STRUCT_FLD_8(u8_t length);
|
||||||
|
PACK_STRUCT_FLD_8(u8_t prefix_length);
|
||||||
|
PACK_STRUCT_FLD_8(u8_t preference);
|
||||||
|
PACK_STRUCT_FIELD(u32_t route_lifetime);
|
||||||
|
PACK_STRUCT_FLD_S(ip6_addr_p_t prefix);
|
||||||
|
} PACK_STRUCT_STRUCT;
|
||||||
|
PACK_STRUCT_END
|
||||||
|
#ifdef PACK_STRUCT_USE_INCLUDES
|
||||||
|
# include "arch/epstruct.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** Recursive DNS Server Option. */
|
||||||
|
#if LWIP_ND6_RDNSS_MAX_DNS_SERVERS
|
||||||
|
#define LWIP_RDNSS_OPTION_MAX_SERVERS LWIP_ND6_RDNSS_MAX_DNS_SERVERS
|
||||||
|
#else
|
||||||
|
#define LWIP_RDNSS_OPTION_MAX_SERVERS 1
|
||||||
|
#endif
|
||||||
|
#define ND6_OPTION_TYPE_RDNSS (25)
|
||||||
|
#ifdef PACK_STRUCT_USE_INCLUDES
|
||||||
|
# include "arch/bpstruct.h"
|
||||||
|
#endif
|
||||||
|
PACK_STRUCT_BEGIN
|
||||||
|
struct rdnss_option {
|
||||||
|
PACK_STRUCT_FLD_8(u8_t type);
|
||||||
|
PACK_STRUCT_FLD_8(u8_t length);
|
||||||
|
PACK_STRUCT_FIELD(u16_t reserved);
|
||||||
|
PACK_STRUCT_FIELD(u32_t lifetime);
|
||||||
|
PACK_STRUCT_FLD_S(ip6_addr_p_t rdnss_address[LWIP_RDNSS_OPTION_MAX_SERVERS]);
|
||||||
|
} PACK_STRUCT_STRUCT;
|
||||||
|
PACK_STRUCT_END
|
||||||
|
#ifdef PACK_STRUCT_USE_INCLUDES
|
||||||
|
# include "arch/epstruct.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* LWIP_HDR_PROT_ND6_H */
|
|
@ -0,0 +1,97 @@
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* TCP protocol definitions
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||||
|
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||||
|
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
|
* OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* This file is part of the lwIP TCP/IP stack.
|
||||||
|
*
|
||||||
|
* Author: Adam Dunkels <adam@sics.se>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef LWIP_HDR_PROT_TCP_H
|
||||||
|
#define LWIP_HDR_PROT_TCP_H
|
||||||
|
|
||||||
|
#include "lwip/arch.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Length of the TCP header, excluding options. */
|
||||||
|
#define TCP_HLEN 20
|
||||||
|
|
||||||
|
/* Fields are (of course) in network byte order.
|
||||||
|
* Some fields are converted to host byte order in tcp_input().
|
||||||
|
*/
|
||||||
|
#ifdef PACK_STRUCT_USE_INCLUDES
|
||||||
|
# include "arch/bpstruct.h"
|
||||||
|
#endif
|
||||||
|
PACK_STRUCT_BEGIN
|
||||||
|
struct tcp_hdr {
|
||||||
|
PACK_STRUCT_FIELD(u16_t src);
|
||||||
|
PACK_STRUCT_FIELD(u16_t dest);
|
||||||
|
PACK_STRUCT_FIELD(u32_t seqno);
|
||||||
|
PACK_STRUCT_FIELD(u32_t ackno);
|
||||||
|
PACK_STRUCT_FIELD(u16_t _hdrlen_rsvd_flags);
|
||||||
|
PACK_STRUCT_FIELD(u16_t wnd);
|
||||||
|
PACK_STRUCT_FIELD(u16_t chksum);
|
||||||
|
PACK_STRUCT_FIELD(u16_t urgp);
|
||||||
|
} PACK_STRUCT_STRUCT;
|
||||||
|
PACK_STRUCT_END
|
||||||
|
#ifdef PACK_STRUCT_USE_INCLUDES
|
||||||
|
# include "arch/epstruct.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* TCP header flags bits */
|
||||||
|
#define TCP_FIN 0x01U
|
||||||
|
#define TCP_SYN 0x02U
|
||||||
|
#define TCP_RST 0x04U
|
||||||
|
#define TCP_PSH 0x08U
|
||||||
|
#define TCP_ACK 0x10U
|
||||||
|
#define TCP_URG 0x20U
|
||||||
|
#define TCP_ECE 0x40U
|
||||||
|
#define TCP_CWR 0x80U
|
||||||
|
/* Valid TCP header flags */
|
||||||
|
#define TCP_FLAGS 0x3fU
|
||||||
|
|
||||||
|
#define TCPH_HDRLEN(phdr) ((u16_t)(lwip_ntohs((phdr)->_hdrlen_rsvd_flags) >> 12))
|
||||||
|
#define TCPH_FLAGS(phdr) ((u16_t)(lwip_ntohs((phdr)->_hdrlen_rsvd_flags) & TCP_FLAGS))
|
||||||
|
|
||||||
|
#define TCPH_HDRLEN_SET(phdr, len) (phdr)->_hdrlen_rsvd_flags = lwip_htons(((len) << 12) | TCPH_FLAGS(phdr))
|
||||||
|
#define TCPH_FLAGS_SET(phdr, flags) (phdr)->_hdrlen_rsvd_flags = (((phdr)->_hdrlen_rsvd_flags & PP_HTONS(~TCP_FLAGS)) | lwip_htons(flags))
|
||||||
|
#define TCPH_HDRLEN_FLAGS_SET(phdr, len, flags) (phdr)->_hdrlen_rsvd_flags = (u16_t)(lwip_htons((u16_t)((len) << 12) | (flags)))
|
||||||
|
|
||||||
|
#define TCPH_SET_FLAG(phdr, flags ) (phdr)->_hdrlen_rsvd_flags = ((phdr)->_hdrlen_rsvd_flags | lwip_htons(flags))
|
||||||
|
#define TCPH_UNSET_FLAG(phdr, flags) (phdr)->_hdrlen_rsvd_flags = ((phdr)->_hdrlen_rsvd_flags & ~lwip_htons(flags))
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* LWIP_HDR_PROT_TCP_H */
|
|
@ -0,0 +1,68 @@
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* UDP protocol definitions
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||||
|
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||||
|
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
|
* OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* This file is part of the lwIP TCP/IP stack.
|
||||||
|
*
|
||||||
|
* Author: Adam Dunkels <adam@sics.se>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef LWIP_HDR_PROT_UDP_H
|
||||||
|
#define LWIP_HDR_PROT_UDP_H
|
||||||
|
|
||||||
|
#include "lwip/arch.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define UDP_HLEN 8
|
||||||
|
|
||||||
|
/* Fields are (of course) in network byte order. */
|
||||||
|
#ifdef PACK_STRUCT_USE_INCLUDES
|
||||||
|
# include "arch/bpstruct.h"
|
||||||
|
#endif
|
||||||
|
PACK_STRUCT_BEGIN
|
||||||
|
struct udp_hdr {
|
||||||
|
PACK_STRUCT_FIELD(u16_t src);
|
||||||
|
PACK_STRUCT_FIELD(u16_t dest); /* src/dest UDP ports */
|
||||||
|
PACK_STRUCT_FIELD(u16_t len);
|
||||||
|
PACK_STRUCT_FIELD(u16_t chksum);
|
||||||
|
} PACK_STRUCT_STRUCT;
|
||||||
|
PACK_STRUCT_END
|
||||||
|
#ifdef PACK_STRUCT_USE_INCLUDES
|
||||||
|
# include "arch/epstruct.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* LWIP_HDR_PROT_UDP_H */
|
File diff suppressed because it is too large
Load diff
|
@ -96,24 +96,54 @@ VOID ShowRamBuildInfo(VOID)
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_APP_DEMO
|
#if 1 //def CONFIG_APP_DEMO
|
||||||
#include "device.h"
|
#include "rtl8195a.h"
|
||||||
#include "gpio_api.h" // mbed
|
//#include "device.h"
|
||||||
|
//#include "gpio_api.h" // mbed
|
||||||
|
typedef struct _UART_LOG_BUF_ {
|
||||||
|
u8 BufCount; //record the input cmd char number.
|
||||||
|
u8 UARTLogBuf[127]; //record the input command.
|
||||||
|
} UART_LOG_BUF, *PUART_LOG_BUF;
|
||||||
|
|
||||||
|
//MON_RAM_BSS_SECTION
|
||||||
|
typedef struct _UART_LOG_CTL_ {
|
||||||
|
u8 NewIdx; //+0
|
||||||
|
u8 SeeIdx; //+1
|
||||||
|
u8 RevdNo; //+2
|
||||||
|
u8 EscSTS; //+3
|
||||||
|
u8 ExecuteCmd; //+4
|
||||||
|
u8 ExecuteEsc; //+5
|
||||||
|
u8 BootRdy; //+6
|
||||||
|
u8 Resvd; //+7
|
||||||
|
PUART_LOG_BUF pTmpLogBuf;
|
||||||
|
VOID *pfINPUT;
|
||||||
|
PCOMMAND_TABLE pCmdTbl;
|
||||||
|
u32 CmdTblSz;
|
||||||
|
|
||||||
|
u32 CRSTS;
|
||||||
|
|
||||||
|
u8 (*pHistoryBuf)[127];
|
||||||
|
|
||||||
|
u32 TaskRdy;
|
||||||
|
u32 Sema;
|
||||||
|
} UART_LOG_CTL, *PUART_LOG_CTL;
|
||||||
|
|
||||||
|
extern volatile UART_LOG_CTL *pUartLogCtl;
|
||||||
|
|
||||||
_WEAK int main(void)
|
_WEAK int main(void)
|
||||||
{
|
{
|
||||||
HalPinCtrlRtl8195A(JTAG, 0, 1);
|
HalPinCtrlRtl8195A(JTAG, 0, 1);
|
||||||
|
|
||||||
DiagPrintf("\r\nRTL Console ROM: Start - press key 'Up', Help '?'\r\n");
|
DiagPrintf("\r\nRTL Console ROM: Start - press key 'Up', Help '?'\r\n");
|
||||||
while(pUartLogCtl[5] != 1);
|
while(pUartLogCtl->ExecuteEsc != 1);
|
||||||
pUartLogCtl[3] = 0;
|
pUartLogCtl->RevdNo = 0;
|
||||||
pUartLogCtl[6] = 1;
|
pUartLogCtl->BootRdy = 1;
|
||||||
DiagPrintf("\r<RTL8710AF>");
|
DiagPrintf("\r<RTL8710AF>");
|
||||||
while(1) {
|
while(1) {
|
||||||
while(pUartLogCtl[4] != 1 );
|
while(pUartLogCtl->ExecuteCmd != 1 );
|
||||||
UartLogCmdExecute(pUartLogCtl);
|
UartLogCmdExecute(pUartLogCtl);
|
||||||
DiagPrintf("\r<RTL8710AF>");
|
DiagPrintf("\r<RTL8710AF>");
|
||||||
pUartLogCtl[4] = 0;
|
pUartLogCtl->ExecuteCmd = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -190,6 +220,7 @@ void _AppStart(void)
|
||||||
xTaskCreate( (TaskFunction_t)main, "MAIN_APP__TASK", (MAIN_APP_DEFAULT_STACK_SIZE/4), (void *)NULL, MAIN_APP_DEFAULT_PRIORITY, NULL);
|
xTaskCreate( (TaskFunction_t)main, "MAIN_APP__TASK", (MAIN_APP_DEFAULT_STACK_SIZE/4), (void *)NULL, MAIN_APP_DEFAULT_PRIORITY, NULL);
|
||||||
vTaskStartScheduler();
|
vTaskStartScheduler();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
__low_level_init();
|
__low_level_init();
|
||||||
|
|
|
@ -48,7 +48,6 @@
|
||||||
//#define __SYSTEM_CLOCK (5*__XTAL)
|
//#define __SYSTEM_CLOCK (5*__XTAL)
|
||||||
#define __SYSTEM_CLOCK (200000000UL/6*5) // PLATFORM_CLOCK //
|
#define __SYSTEM_CLOCK (200000000UL/6*5) // PLATFORM_CLOCK //
|
||||||
|
|
||||||
extern unsigned int rand_x;
|
|
||||||
//extern u32 HalGetCpuClk(VOID);
|
//extern u32 HalGetCpuClk(VOID);
|
||||||
|
|
||||||
#ifdef CONFIG_CHIP_A_CUT
|
#ifdef CONFIG_CHIP_A_CUT
|
||||||
|
@ -62,6 +61,8 @@ const u32 SysCpkClkTbl[]= {
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
unsigned int rand_x = 12345;
|
||||||
|
|
||||||
u32 Rand2(void)
|
u32 Rand2(void)
|
||||||
{
|
{
|
||||||
static unsigned int y = 362436;
|
static unsigned int y = 362436;
|
||||||
|
|
|
@ -244,7 +244,7 @@ HAL_GPIO_IP_DeInit(
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//extern u16 GPIOState[_PORT_MAX-1]; // побитно 16 бит для каждого порта (A..K), бит=номер задействованного пина в порту на периферию.
|
extern u16 GPIOState[_PORT_MAX]; // побитно 16 бит для каждого порта (A..K), бит=номер задействованного пина в порту на периферию.
|
||||||
|
|
||||||
#endif // end of "#define _HAL_GPIO_H_"
|
#endif // end of "#define _HAL_GPIO_H_"
|
||||||
|
|
||||||
|
|
|
@ -16,12 +16,6 @@
|
||||||
|
|
||||||
#define SYSTEM_CLK PLATFORM_CLOCK
|
#define SYSTEM_CLK PLATFORM_CLOCK
|
||||||
|
|
||||||
#define SDR_SDRAM_BASE 0x30000000
|
|
||||||
#define SYSTEM_CTRL_BASE 0x40000000
|
|
||||||
#define PERI_ON_BASE 0x40000000
|
|
||||||
#define VENDOR_REG_BASE 0x40002800
|
|
||||||
#define SPI_FLASH_BASE 0x98000000
|
|
||||||
#define SDR_CTRL_BASE 0x40005000
|
|
||||||
|
|
||||||
#define PERIPHERAL_IRQ_STATUS 0x04
|
#define PERIPHERAL_IRQ_STATUS 0x04
|
||||||
#define PERIPHERAL_IRQ_MODE 0x08
|
#define PERIPHERAL_IRQ_MODE 0x08
|
||||||
|
@ -34,13 +28,21 @@
|
||||||
|
|
||||||
#define TIMER_CLK 32*1000
|
#define TIMER_CLK 32*1000
|
||||||
|
|
||||||
|
#define SDR_SDRAM_BASE 0x30000000
|
||||||
|
#define SYSTEM_CTRL_BASE 0x40000000
|
||||||
|
#define PERI_ON_BASE 0x40000000
|
||||||
|
#define SPI_FLASH_BASE 0x98000000
|
||||||
|
|
||||||
//3 Peripheral IP Base Address
|
//3 Peripheral IP Base Address
|
||||||
|
|
||||||
#define GPIO_REG_BASE 0x40001000
|
#define GPIO_REG_BASE 0x40001000
|
||||||
#define TIMER_REG_BASE 0x40002000
|
#define TIMER_REG_BASE 0x40002000
|
||||||
|
#define VENDOR_REG_BASE 0x40002800
|
||||||
#define NFC_INTERFACE_BASE 0x40002400
|
#define NFC_INTERFACE_BASE 0x40002400
|
||||||
#define LOG_UART_REG_BASE 0x40003000
|
#define LOG_UART_REG_BASE 0x40003000
|
||||||
#define I2C2_REG_BASE 0x40003400
|
#define I2C2_REG_BASE 0x40003400
|
||||||
#define I2C3_REG_BASE 0x40003800
|
#define I2C3_REG_BASE 0x40003800
|
||||||
|
#define SDR_CTRL_BASE 0x40005000
|
||||||
#define SPI_FLASH_CTRL_BASE 0x40006000
|
#define SPI_FLASH_CTRL_BASE 0x40006000
|
||||||
#define ADC_REG_BASE 0x40010000
|
#define ADC_REG_BASE 0x40010000
|
||||||
#define DAC_REG_BASE 0x40011000
|
#define DAC_REG_BASE 0x40011000
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
#ifndef _HAL_SDR_CONTROLLER_H_
|
#ifndef _HAL_SDR_CONTROLLER_H_
|
||||||
#define _HAL_SDR_CONTROLLER_H_
|
#define _HAL_SDR_CONTROLLER_H_
|
||||||
|
|
||||||
#if 1 // def CONFIG_SDR_EN
|
#if 1 //def CONFIG_SDR_EN
|
||||||
|
|
||||||
typedef enum _DRAM_TYPE_ {
|
typedef enum _DRAM_TYPE_ {
|
||||||
DRAM_DDR_1 = 1,
|
DRAM_DDR_1 = 1,
|
||||||
|
@ -187,5 +187,5 @@ typedef struct _DRAM_DEVICE_INFO_ {
|
||||||
#define HAL_SDRAM_READ8(addr) HAL_READ8(SDR_SDRAM_BASE, addr)
|
#define HAL_SDRAM_READ8(addr) HAL_READ8(SDR_SDRAM_BASE, addr)
|
||||||
|
|
||||||
#endif // CONFIG_SDR_EN
|
#endif // CONFIG_SDR_EN
|
||||||
// extern unsigned int rand_x; // in rtl_bios_data.h
|
//extern unsigned int rand_x;
|
||||||
#endif // end of "#ifndef _HAL_SDR_CONTROLLER_H_"
|
#endif // end of "#ifndef _HAL_SDR_CONTROLLER_H_"
|
||||||
|
|
|
@ -68,7 +68,7 @@ enum _SPIC_BIT_MODE_ {
|
||||||
#define FLASH_EON 5
|
#define FLASH_EON 5
|
||||||
|
|
||||||
//#define FLASH_MXIC_MX25L4006E 0
|
//#define FLASH_MXIC_MX25L4006E 0
|
||||||
//#define FLASH_MXIC_MX25L8073E 0
|
//#define FLASH_MXIC_MX25L8073E 1
|
||||||
//#define FLASH_MICRON_N25Q512A 1
|
//#define FLASH_MICRON_N25Q512A 1
|
||||||
// The below parts are based on the flash characteristics
|
// The below parts are based on the flash characteristics
|
||||||
//====== Flash Command Definition ======
|
//====== Flash Command Definition ======
|
||||||
|
@ -244,6 +244,7 @@ enum _SPIC_BIT_MODE_ {
|
||||||
|
|
||||||
|
|
||||||
//#endif
|
//#endif
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
#if FLASH_MXIC_MX25L4006E
|
#if FLASH_MXIC_MX25L4006E
|
||||||
#define FLASH_RD_2IO_EN 1
|
#define FLASH_RD_2IO_EN 1
|
||||||
|
|
|
@ -0,0 +1,130 @@
|
||||||
|
/*
|
||||||
|
* Routines to access hardware
|
||||||
|
*
|
||||||
|
* Copyright (c) 2015 Realtek Semiconductor Corp.
|
||||||
|
*
|
||||||
|
* This module is a confidential and proprietary property of RealTek and
|
||||||
|
* possession or use of this module requires written permission of RealTek.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "rtl8195a.h"
|
||||||
|
#include "build_info.h"
|
||||||
|
#include "PinNames.h"
|
||||||
|
#include "serial_api.h"
|
||||||
|
|
||||||
|
extern void serial_init (serial_t *obj, PinName tx, PinName rx);
|
||||||
|
extern void serial_free (serial_t *obj);
|
||||||
|
extern void serial_baud (serial_t *obj, int baudrate);
|
||||||
|
extern void serial_format (serial_t *obj, int data_bits, SerialParity parity, int stop_bits);
|
||||||
|
extern int main(void);
|
||||||
|
|
||||||
|
void iar_data_init_fw_loader(void);
|
||||||
|
void fw_loader_main(void);// __attribute__ ((weak));
|
||||||
|
|
||||||
|
#pragma section=".image2.start.table1"
|
||||||
|
#pragma section=".fwloader_ram.bss"
|
||||||
|
|
||||||
|
FW_LOADER_START_RAM_FUN_SECTION
|
||||||
|
RAM_START_FUNCTION gFWLoaderEntryFun0 = {fw_loader_main};
|
||||||
|
|
||||||
|
u8* __image4_entry_func__;
|
||||||
|
u8* __image4_validate_code__;
|
||||||
|
u8* __fwloader_bss_start__;
|
||||||
|
u8* __fwloader_bss_end__;
|
||||||
|
|
||||||
|
FW_LOADER_VALID_PATTEN_SECTION const u8 RAM_FW_LOADER_VALID_PATTEN[20] = {
|
||||||
|
'R', 'T', 'K', 'W', 'i', 'n', 0x0, 0xff,
|
||||||
|
(FW_VERSION&0xff), ((FW_VERSION >> 8)&0xff),
|
||||||
|
(FW_SUBVERSION&0xff), ((FW_SUBVERSION >> 8)&0xff),
|
||||||
|
(FW_CHIP_ID&0xff), ((FW_CHIP_ID >> 8)&0xff),
|
||||||
|
(FW_CHIP_VER),
|
||||||
|
(FW_BUS_TYPE),
|
||||||
|
(FW_INFO_RSV1),
|
||||||
|
(FW_INFO_RSV2),
|
||||||
|
(FW_INFO_RSV3),
|
||||||
|
(FW_INFO_RSV4)
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* @brief Main program.
|
||||||
|
* @param None
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void fw_loader_main(void)
|
||||||
|
{
|
||||||
|
#if defined ( __ICCARM__ )
|
||||||
|
iar_data_init_fw_loader();
|
||||||
|
#endif
|
||||||
|
u32 Image2Len, Image2Addr, ImageIndex, SpicBitMode, SpicImageIndex;
|
||||||
|
u32 Image2LoadAddr = 0x13000;
|
||||||
|
DBG_8195A("===== Enter FW Loader Image ====\n");
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef BOOTLOADER
|
||||||
|
main();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
IGMAE4:
|
||||||
|
PRAM_START_FUNCTION Image4EntryFun=(PRAM_START_FUNCTION)__image4_entry_func__;
|
||||||
|
|
||||||
|
Image2Len = HAL_READ32(SPI_FLASH_BASE, Image2LoadAddr);
|
||||||
|
Image2Addr = HAL_READ32(SPI_FLASH_BASE, (Image2LoadAddr+0x4));
|
||||||
|
|
||||||
|
DBG_8195A("Flash FW Loader:Addr 0x%x, Len %d, Load to SRAM 0x%x\n", Image2LoadAddr, Image2Len, Image2Addr);
|
||||||
|
|
||||||
|
SpicImageIndex = 0;
|
||||||
|
for (ImageIndex = 0x10 + Image2LoadAddr; ImageIndex < (Image2Len + Image2LoadAddr + 0x10); ImageIndex = ImageIndex + 4) {
|
||||||
|
HAL_WRITE32(Image2Addr, SpicImageIndex,
|
||||||
|
HAL_READ32(SPI_FLASH_BASE, ImageIndex));
|
||||||
|
|
||||||
|
SpicImageIndex += 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef CONFIG_SDR_EN
|
||||||
|
u32 Image3LoadAddr;
|
||||||
|
u32 Image3Len;
|
||||||
|
u32 Image3Addr;
|
||||||
|
|
||||||
|
Image3LoadAddr = Image2LoadAddr + Image2Len+0x10;
|
||||||
|
Image3Len = HAL_READ32(SPI_FLASH_BASE, Image3LoadAddr);
|
||||||
|
Image3Addr = HAL_READ32(SPI_FLASH_BASE, Image3LoadAddr + 0x4);
|
||||||
|
|
||||||
|
if( (Image3Len==0xFFFFFFFF) || (Image3Len==0) || (Image3Addr!=0x30000000)){
|
||||||
|
DBG_8195A("No Image3\n\r");
|
||||||
|
}else{
|
||||||
|
DBG_8195A("Image3 length: 0x%x, Image3 Addr: 0x%x\n",Image3Len, Image3Addr);
|
||||||
|
SpicImageIndex = 0;
|
||||||
|
|
||||||
|
for (ImageIndex = 0x10 + Image3LoadAddr;
|
||||||
|
ImageIndex < (Image3Len + Image3LoadAddr + 0x10);
|
||||||
|
ImageIndex = ImageIndex + 4) {
|
||||||
|
HAL_WRITE32(Image3Addr, SpicImageIndex,
|
||||||
|
HAL_READ32(SPI_FLASH_BASE, ImageIndex));
|
||||||
|
|
||||||
|
SpicImageIndex += 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
//3 3) Jump to image 4
|
||||||
|
DBG_8195A("InfraStart: %p, Img2 Sign %s \n", __image4_entry_func__, (char*)__image4_validate_code__);
|
||||||
|
if (_strcmp((char *)__image4_validate_code__, "RTKWin")) {
|
||||||
|
while (1) {
|
||||||
|
DBG_8195A("Invalid Image4 Signature\n");
|
||||||
|
RtlConsolRom(1000);//each delay is 100us
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef BOOTLOADER
|
||||||
|
deinit_platform_bootloader();
|
||||||
|
#endif
|
||||||
|
Image4EntryFun->RamStartFun();
|
||||||
|
}
|
||||||
|
|
||||||
|
void iar_data_init_fw_loader(void)
|
||||||
|
{
|
||||||
|
__image4_entry_func__ = (u8*)__section_begin(".image2.start.table1");
|
||||||
|
__image4_validate_code__ = __image4_entry_func__+4;//(u8*)__section_begin(".image2.start.table2");
|
||||||
|
__fwloader_bss_start__ = (u8*)__section_begin(".fwloader_ram.bss");
|
||||||
|
__fwloader_bss_end__ = (u8*)__section_end(".fwloader_ram.bss");
|
||||||
|
}
|
|
@ -0,0 +1,82 @@
|
||||||
|
/*
|
||||||
|
decompiled low_level_io.o
|
||||||
|
*/
|
||||||
|
#include ......
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
// Function declarations
|
||||||
|
void mode_init();
|
||||||
|
void HalSerialPutcRtl8195a(int c, int a2, char a3);
|
||||||
|
signed int DiagPrintf(const char *fmt, ...);
|
||||||
|
void log_uart_enable_printf();
|
||||||
|
void log_uart_disable_printf();
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
// Data declarations
|
||||||
|
uint32_t backupWarn;
|
||||||
|
uint32_t backupErr;
|
||||||
|
uint32_t backupInfo;
|
||||||
|
int disablePrintf;
|
||||||
|
// extern _UNKNOWN use_mode;
|
||||||
|
// extern _UNKNOWN ConfigDebugErr;
|
||||||
|
// extern _UNKNOWN ConfigDebugInfo;
|
||||||
|
// extern _UNKNOWN ConfigDebugWarn;
|
||||||
|
|
||||||
|
//-----
|
||||||
|
void mode_init()
|
||||||
|
{
|
||||||
|
use_mode = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----
|
||||||
|
void HalSerialPutcRtl8195a(int c)
|
||||||
|
{
|
||||||
|
signed int v3; // r3@2
|
||||||
|
|
||||||
|
if ( disablePrintf != 1 )
|
||||||
|
{
|
||||||
|
v3 = 6540;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if ( !--v3 )
|
||||||
|
break;
|
||||||
|
a3 = v40003014;
|
||||||
|
}
|
||||||
|
while ( !(v40003014 & 0x60) );
|
||||||
|
if ( c == 10 ) a3 = 13;
|
||||||
|
v40003000 = c;
|
||||||
|
if ( c == 10 ) v40003000 = a3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----
|
||||||
|
signed int DiagPrintf(const char *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list va;
|
||||||
|
|
||||||
|
va_start(va, fmt);
|
||||||
|
if ( disablePrintf != 1 )
|
||||||
|
VSprintf(0, fmt, va);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----
|
||||||
|
void log_uart_enable_printf()
|
||||||
|
{
|
||||||
|
disablePrintf = 0;
|
||||||
|
ConfigDebugErr = backupErr;
|
||||||
|
ConfigDebugInfo = backupInfo;
|
||||||
|
ConfigDebugWarn = backupWarn;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----
|
||||||
|
void log_uart_disable_printf()
|
||||||
|
{
|
||||||
|
disablePrintf = 1;
|
||||||
|
backupErr = ConfigDebugErr;
|
||||||
|
backupInfo = ConfigDebugInfo;
|
||||||
|
backupWarn = ConfigDebugWarn;
|
||||||
|
ConfigDebugErr = 0;
|
||||||
|
ConfigDebugInfo = 0;
|
||||||
|
ConfigDebugWarn = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -911,30 +911,30 @@
|
||||||
#define BIT_CTRL_FLUSH_FIFO(x) (((x) & BIT_MASK_FLUSH_FIFO) << BIT_SHIFT_FLUSH_FIFO)
|
#define BIT_CTRL_FLUSH_FIFO(x) (((x) & BIT_MASK_FLUSH_FIFO) << BIT_SHIFT_FLUSH_FIFO)
|
||||||
|
|
||||||
//=================== Register Address Definition ============================//
|
//=================== Register Address Definition ============================//
|
||||||
#define REG_SPIC_CTRLR0 0x0000//O
|
#define REG_SPIC_CTRLR0 0x0000 //O 0x1040300
|
||||||
#define REG_SPIC_CTRLR1 0x0004//O
|
#define REG_SPIC_CTRLR1 0x0004 //O 0x10
|
||||||
#define REG_SPIC_SSIENR 0x0008//O
|
#define REG_SPIC_SSIENR 0x0008 //O 0
|
||||||
#define REG_SPIC_MWCR 0x000C
|
#define REG_SPIC_MWCR 0x000C // 0
|
||||||
#define REG_SPIC_SER 0x0010//O
|
#define REG_SPIC_SER 0x0010 //O 1
|
||||||
#define REG_SPIC_BAUDR 0x0014//O
|
#define REG_SPIC_BAUDR 0x0014 //O 1
|
||||||
#define REG_SPIC_TXFTLR 0x0018
|
#define REG_SPIC_TXFTLR 0x0018 // 0
|
||||||
#define REG_SPIC_RXFTLR 0x001C//O
|
#define REG_SPIC_RXFTLR 0x001C //O 0x1F
|
||||||
#define REG_SPIC_TXFLR 0x0020//O
|
#define REG_SPIC_TXFLR 0x0020 //O 0
|
||||||
#define REG_SPIC_RXFLR 0x0024
|
#define REG_SPIC_RXFLR 0x0024 // 0
|
||||||
#define REG_SPIC_SR 0x0028
|
#define REG_SPIC_SR 0x0028 // 6
|
||||||
#define REG_SPIC_IMR 0x002C//O
|
#define REG_SPIC_IMR 0x002C //O 0x1FF
|
||||||
#define REG_SPIC_ISR 0x0030
|
#define REG_SPIC_ISR 0x0030 // 4
|
||||||
#define REG_SPIC_RISR 0x0034
|
#define REG_SPIC_RISR 0x0034 // 4
|
||||||
#define REG_SPIC_TXOICR 0x0038
|
#define REG_SPIC_TXOICR 0x0038 // 0
|
||||||
#define REG_SPIC_RXOICR 0x003C
|
#define REG_SPIC_RXOICR 0x003C // 0
|
||||||
#define REG_SPC_RXUICR 0x0040
|
#define REG_SPC_RXUICR 0x0040 // 0
|
||||||
#define REG_SPIC_MSTICR 0x0044
|
#define REG_SPIC_MSTICR 0x0044 // 0
|
||||||
#define REG_SPIC_ICR 0x0048
|
#define REG_SPIC_ICR 0x0048 // 0
|
||||||
#define REG_SPIC_DMACR 0x004C
|
#define REG_SPIC_DMACR 0x004C // 0
|
||||||
#define REG_SPIC_DMATDLR0 0x0050
|
#define REG_SPIC_DMATDLR0 0x0050 // 0
|
||||||
#define REG_SPIC_DMATDLR1 0x0054
|
#define REG_SPIC_DMATDLR1 0x0054 // 0
|
||||||
#define REG_SPIC_IDR 0x0058
|
#define REG_SPIC_IDR 0x0058 // 0x10001
|
||||||
#define REG_SPIC_VERSION 0x005C
|
#define REG_SPIC_VERSION 0x005C // 0x40470603
|
||||||
#define REG_SPIC_DR0 0x0060
|
#define REG_SPIC_DR0 0x0060
|
||||||
#define REG_SPIC_DR1 0x0064
|
#define REG_SPIC_DR1 0x0064
|
||||||
#define REG_SPIC_DR2 0x0068
|
#define REG_SPIC_DR2 0x0068
|
||||||
|
@ -966,26 +966,26 @@
|
||||||
#define REG_SPIC_DR28 0x00D0
|
#define REG_SPIC_DR28 0x00D0
|
||||||
#define REG_SPIC_DR29 0x00D4
|
#define REG_SPIC_DR29 0x00D4
|
||||||
#define REG_SPIC_DR30 0x00D8
|
#define REG_SPIC_DR30 0x00D8
|
||||||
#define REG_SPIC_DR31 0x00DC
|
#define REG_SPIC_DR31 0x00DC // MXIC (DeviceID: FC, Flash Size: 1048576 bytes, FlashID: C22014/1, SpicMode: DIO)
|
||||||
#define REG_SPIC_READ_FAST_SINGLE 0x00E0//O
|
#define REG_SPIC_READ_FAST_SINGLE 0x00E0 //O 0x0B
|
||||||
#define REG_SPIC_READ_DUAL_DATA 0x00E4//O
|
#define REG_SPIC_READ_DUAL_DATA 0x00E4 //O 0x3B
|
||||||
#define REG_SPIC_READ_DUAL_ADDR_DATA 0x00E8//O
|
#define REG_SPIC_READ_DUAL_ADDR_DATA 0x00E8 //O 0x3B
|
||||||
#define REG_SPIC_READ_QUAD_DATA 0x00EC//O
|
#define REG_SPIC_READ_QUAD_DATA 0x00EC //O 0x6B
|
||||||
#define REG_SPIC_READ_QUAD_ADDR_DATA 0x00F0//O
|
#define REG_SPIC_READ_QUAD_ADDR_DATA 0x00F0 //O 0xEB
|
||||||
#define REG_SPIC_WRITE_SIGNLE 0x00F4//O
|
#define REG_SPIC_WRITE_SIGNLE 0x00F4 //O 0x02
|
||||||
#define REG_SPIC_WRITE_DUAL_DATA 0x00F8//O
|
#define REG_SPIC_WRITE_DUAL_DATA 0x00F8 //O 0xA2
|
||||||
#define REG_SPIC_WRITE_DUAL_ADDR_DATA 0x00FC//O
|
#define REG_SPIC_WRITE_DUAL_ADDR_DATA 0x00FC//O 0xA2
|
||||||
#define REG_SPIC_WRITE_QUAD_DATA 0x0100//O
|
#define REG_SPIC_WRITE_QUAD_DATA 0x0100 //O 0x32
|
||||||
#define REG_SPIC_WRITE_QUAD_ADDR_DATA 0x0104//O
|
#define REG_SPIC_WRITE_QUAD_ADDR_DATA 0x0104//O 0x38
|
||||||
#define REG_SPIC_WRITE_ENABLE 0x0108//O
|
#define REG_SPIC_WRITE_ENABLE 0x0108 //O 0x06
|
||||||
#define REG_SPIC_READ_STATUS 0x010C//O
|
#define REG_SPIC_READ_STATUS 0x010C //O 0x05
|
||||||
#define REG_SPIC_CTRLR2 0x0110//O
|
#define REG_SPIC_CTRLR2 0x0110 //O 0x51
|
||||||
#define REG_SPIC_FBAUDR 0x0114//O
|
#define REG_SPIC_FBAUDR 0x0114 //O 0x1
|
||||||
#define REG_SPIC_ADDR_LENGTH 0x0118//O
|
#define REG_SPIC_ADDR_LENGTH 0x0118 //O 0x3
|
||||||
#define REG_SPIC_AUTO_LENGTH 0x011C//O
|
#define REG_SPIC_AUTO_LENGTH 0x011C //O 0x20030011/0x20030021
|
||||||
#define REG_SPIC_VALID_CMD 0x0120//O
|
#define REG_SPIC_VALID_CMD 0x0120 //O 0x202
|
||||||
#define REG_SPIC_FLASE_SIZE 0x0124//O
|
#define REG_SPIC_FLASE_SIZE 0x0124 //O 0x0E
|
||||||
#define REG_SPIC_FLUSH_FIFO 0x0128//O
|
#define REG_SPIC_FLUSH_FIFO 0x0128 //O 0
|
||||||
|
|
||||||
VOID SpicInitRtl8195A(u8 InitBaudRate, u8 SpicBitMode); // spi-flash controller initialization
|
VOID SpicInitRtl8195A(u8 InitBaudRate, u8 SpicBitMode); // spi-flash controller initialization
|
||||||
VOID SpicRxCmdRtl8195A(u8 cmd); // recieve command
|
VOID SpicRxCmdRtl8195A(u8 cmd); // recieve command
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue