diff --git a/TESTS/mbedmicro-rtos-mbed/basic/main.cpp b/TESTS/mbedmicro-rtos-mbed/basic/main.cpp index 434e55de44..278ce036ad 100644 --- a/TESTS/mbedmicro-rtos-mbed/basic/main.cpp +++ b/TESTS/mbedmicro-rtos-mbed/basic/main.cpp @@ -11,11 +11,7 @@ * the C standard library. For GCC, ARM_STD and IAR it is defined with a size of 2048 bytes * and for ARM_MICRO 512. Because of reduce RAM size some targets need a reduced stacksize. */ -#if (defined(TARGET_STM32L053R8) || defined(TARGET_STM32L053C8)) && defined(TOOLCHAIN_GCC) -#define STACK_SIZE DEFAULT_STACK_SIZE/2 -#elif (defined(TARGET_STM32F030R8) || defined(TARGET_STM32F070RB)) && defined(TOOLCHAIN_GCC) -#define STACK_SIZE DEFAULT_STACK_SIZE/2 -#elif (defined(TARGET_STM32F030R8)) && defined(TOOLCHAIN_IAR) +#if defined(TARGET_STM32F070RB) && defined(TOOLCHAIN_GCC) #define STACK_SIZE DEFAULT_STACK_SIZE/2 #elif (defined(TARGET_EFM32HG_STK3400)) && !defined(TOOLCHAIN_ARM_MICRO) #define STACK_SIZE 512 diff --git a/TESTS/mbedmicro-rtos-mbed/isr/main.cpp b/TESTS/mbedmicro-rtos-mbed/isr/main.cpp index 92064d567c..fc133eca37 100644 --- a/TESTS/mbedmicro-rtos-mbed/isr/main.cpp +++ b/TESTS/mbedmicro-rtos-mbed/isr/main.cpp @@ -16,11 +16,7 @@ * the C standard library. For GCC, ARM_STD and IAR it is defined with a size of 2048 bytes * and for ARM_MICRO 512. Because of reduce RAM size some targets need a reduced stacksize. */ -#if defined(TARGET_STM32L053R8) || defined(TARGET_STM32L053C8) - #define STACK_SIZE DEFAULT_STACK_SIZE/4 -#elif (defined(TARGET_STM32F030R8)) && defined(TOOLCHAIN_IAR) - #define STACK_SIZE DEFAULT_STACK_SIZE/2 -#elif (defined(TARGET_EFM32HG_STK3400)) && !defined(TOOLCHAIN_ARM_MICRO) +#if (defined(TARGET_EFM32HG_STK3400)) && !defined(TOOLCHAIN_ARM_MICRO) #define STACK_SIZE 512 #elif (defined(TARGET_EFM32LG_STK3600) || defined(TARGET_EFM32WG_STK3800) || defined(TARGET_EFM32PG_STK3401)) && !defined(TOOLCHAIN_ARM_MICRO) #define STACK_SIZE 768 diff --git a/TESTS/mbedmicro-rtos-mbed/mail/main.cpp b/TESTS/mbedmicro-rtos-mbed/mail/main.cpp index 3f9523513e..eed2671b72 100644 --- a/TESTS/mbedmicro-rtos-mbed/mail/main.cpp +++ b/TESTS/mbedmicro-rtos-mbed/mail/main.cpp @@ -22,13 +22,7 @@ typedef struct { * the C standard library. For GCC, ARM_STD and IAR it is defined with a size of 2048 bytes * and for ARM_MICRO 512. Because of reduce RAM size some targets need a reduced stacksize. */ -#if (defined(TARGET_STM32L053R8) || defined(TARGET_STM32L053C8)) && defined(TOOLCHAIN_GCC) - #define STACK_SIZE DEFAULT_STACK_SIZE/4 -#elif (defined(TARGET_STM32F030R8)) && defined(TOOLCHAIN_GCC) - #define STACK_SIZE DEFAULT_STACK_SIZE/2 -#elif (defined(TARGET_STM32F030R8)) && defined(TOOLCHAIN_IAR) - #define STACK_SIZE DEFAULT_STACK_SIZE/2 -#elif (defined(TARGET_EFM32HG_STK3400)) && !defined(TOOLCHAIN_ARM_MICRO) +#if (defined(TARGET_EFM32HG_STK3400)) && !defined(TOOLCHAIN_ARM_MICRO) #define STACK_SIZE 512 #elif (defined(TARGET_EFM32LG_STK3600) || defined(TARGET_EFM32WG_STK3800) || defined(TARGET_EFM32PG_STK3401)) && !defined(TOOLCHAIN_ARM_MICRO) #define STACK_SIZE 768 diff --git a/TESTS/mbedmicro-rtos-mbed/mutex/main.cpp b/TESTS/mbedmicro-rtos-mbed/mutex/main.cpp index 05f38376c3..d3612f6a7c 100644 --- a/TESTS/mbedmicro-rtos-mbed/mutex/main.cpp +++ b/TESTS/mbedmicro-rtos-mbed/mutex/main.cpp @@ -14,14 +14,8 @@ * the C standard library. For GCC, ARM_STD and IAR it is defined with a size of 2048 bytes * and for ARM_MICRO 512. Because of reduce RAM size some targets need a reduced stacksize. */ -#if (defined(TARGET_STM32L053R8) || defined(TARGET_STM32L053C8)) && defined(TOOLCHAIN_GCC) +#if defined(TARGET_STM32F334R8) && defined(TOOLCHAIN_IAR) #define STACK_SIZE DEFAULT_STACK_SIZE/4 -#elif defined(TARGET_STM32F030R8) && defined(TOOLCHAIN_GCC) - #define STACK_SIZE DEFAULT_STACK_SIZE/4 -#elif defined(TARGET_STM32F334R8) && defined(TOOLCHAIN_IAR) - #define STACK_SIZE DEFAULT_STACK_SIZE/4 -#elif defined(TARGET_STM32F030R8) && defined(TOOLCHAIN_IAR) - #define STACK_SIZE DEFAULT_STACK_SIZE/4 #elif defined(TARGET_STM32F070RB) #define STACK_SIZE DEFAULT_STACK_SIZE/2 #elif defined(TARGET_STM32F072RB) @@ -30,6 +24,8 @@ #define STACK_SIZE DEFAULT_STACK_SIZE/2 #elif defined(TARGET_STM32F303K8) && defined(TOOLCHAIN_IAR) #define STACK_SIZE DEFAULT_STACK_SIZE/2 +#elif defined(TARGET_STM32L073RZ) + #define STACK_SIZE DEFAULT_STACK_SIZE/2 #elif (defined(TARGET_EFM32HG_STK3400)) && !defined(TOOLCHAIN_ARM_MICRO) #define STACK_SIZE 512 #elif (defined(TARGET_EFM32LG_STK3600) || defined(TARGET_EFM32WG_STK3800) || defined(TARGET_EFM32PG_STK3401)) && !defined(TOOLCHAIN_ARM_MICRO) diff --git a/TESTS/mbedmicro-rtos-mbed/queue/main.cpp b/TESTS/mbedmicro-rtos-mbed/queue/main.cpp index f4aca165db..fcee38e66b 100644 --- a/TESTS/mbedmicro-rtos-mbed/queue/main.cpp +++ b/TESTS/mbedmicro-rtos-mbed/queue/main.cpp @@ -22,13 +22,7 @@ typedef struct { * the C standard library. For GCC, ARM_STD and IAR it is defined with a size of 2048 bytes * and for ARM_MICRO 512. Because of reduce RAM size some targets need a reduced stacksize. */ -#if (defined(TARGET_STM32L053R8) || defined(TARGET_STM32L053C8)) && defined(TOOLCHAIN_GCC) - #define STACK_SIZE DEFAULT_STACK_SIZE/4 -#elif (defined(TARGET_STM32F030R8)) && defined(TOOLCHAIN_GCC) - #define STACK_SIZE DEFAULT_STACK_SIZE/4 -#elif (defined(TARGET_STM32F030R8)) && defined(TOOLCHAIN_IAR) - #define STACK_SIZE DEFAULT_STACK_SIZE/2 -#elif (defined(TARGET_EFM32HG_STK3400)) && !defined(TOOLCHAIN_ARM_MICRO) +#if (defined(TARGET_EFM32HG_STK3400)) && !defined(TOOLCHAIN_ARM_MICRO) #define STACK_SIZE 512 #elif (defined(TARGET_EFM32LG_STK3600) || defined(TARGET_EFM32WG_STK3800) || defined(TARGET_EFM32PG_STK3401)) && !defined(TOOLCHAIN_ARM_MICRO) #define STACK_SIZE 768 diff --git a/TESTS/mbedmicro-rtos-mbed/semaphore/main.cpp b/TESTS/mbedmicro-rtos-mbed/semaphore/main.cpp index d359ce3e12..60f3f79918 100644 --- a/TESTS/mbedmicro-rtos-mbed/semaphore/main.cpp +++ b/TESTS/mbedmicro-rtos-mbed/semaphore/main.cpp @@ -15,22 +15,18 @@ * the C standard library. For GCC, ARM_STD and IAR it is defined with a size of 2048 bytes * and for ARM_MICRO 512. Because of reduce RAM size some targets need a reduced stacksize. */ -#if (defined(TARGET_STM32L053R8) || defined(TARGET_STM32L053C8)) && defined(TOOLCHAIN_GCC) - #define STACK_SIZE DEFAULT_STACK_SIZE/16 -#elif defined(TARGET_STM32F030R8) && defined(TOOLCHAIN_GCC) - #define STACK_SIZE DEFAULT_STACK_SIZE/8 -#elif defined(TARGET_STM32F334R8) && (defined(TOOLCHAIN_GCC) || defined(TOOLCHAIN_IAR)) +#if defined(TARGET_STM32F334R8) && (defined(TOOLCHAIN_GCC) || defined(TOOLCHAIN_IAR)) #define STACK_SIZE DEFAULT_STACK_SIZE/4 #elif defined(TARGET_STM32F103RB) #define STACK_SIZE DEFAULT_STACK_SIZE/2 -#elif defined(TARGET_STM32F030R8) && defined(TOOLCHAIN_IAR) - #define STACK_SIZE DEFAULT_STACK_SIZE/4 #elif defined(TARGET_STM32F070RB) #define STACK_SIZE DEFAULT_STACK_SIZE/2 #elif defined(TARGET_STM32F072RB) #define STACK_SIZE DEFAULT_STACK_SIZE/2 #elif defined(TARGET_STM32F302R8) && defined(TOOLCHAIN_IAR) #define STACK_SIZE DEFAULT_STACK_SIZE/2 +#elif defined(TARGET_STM32L073RZ) + #define STACK_SIZE DEFAULT_STACK_SIZE/2 #elif defined(TARGET_STM32F303K8) && defined(TOOLCHAIN_IAR) #define STACK_SIZE DEFAULT_STACK_SIZE/4 #elif (defined(TARGET_EFM32HG_STK3400)) && !defined(TOOLCHAIN_ARM_MICRO) diff --git a/TESTS/mbedmicro-rtos-mbed/signals/main.cpp b/TESTS/mbedmicro-rtos-mbed/signals/main.cpp index b8c385156f..281b322b66 100644 --- a/TESTS/mbedmicro-rtos-mbed/signals/main.cpp +++ b/TESTS/mbedmicro-rtos-mbed/signals/main.cpp @@ -15,11 +15,7 @@ const int SIGNAL_HANDLE_DELEY = 25; * the C standard library. For GCC, ARM_STD and IAR it is defined with a size of 2048 bytes * and for ARM_MICRO 512. Because of reduce RAM size some targets need a reduced stacksize. */ -#if defined(TARGET_STM32L053R8) || defined(TARGET_STM32L053C8) - #define STACK_SIZE DEFAULT_STACK_SIZE/4 -#elif (defined(TARGET_STM32F030R8)) && defined(TOOLCHAIN_IAR) - #define STACK_SIZE DEFAULT_STACK_SIZE/2 -#elif (defined(TARGET_EFM32HG_STK3400)) && !defined(TOOLCHAIN_ARM_MICRO) +#if (defined(TARGET_EFM32HG_STK3400)) && !defined(TOOLCHAIN_ARM_MICRO) #define STACK_SIZE 512 #elif (defined(TARGET_EFM32LG_STK3600) || defined(TARGET_EFM32WG_STK3800) || defined(TARGET_EFM32PG_STK3401)) && !defined(TOOLCHAIN_ARM_MICRO) #define STACK_SIZE 768 diff --git a/TESTS/mbedmicro-rtos-mbed/threads/main.cpp b/TESTS/mbedmicro-rtos-mbed/threads/main.cpp index 82b074c9cc..52286f11f7 100644 --- a/TESTS/mbedmicro-rtos-mbed/threads/main.cpp +++ b/TESTS/mbedmicro-rtos-mbed/threads/main.cpp @@ -17,7 +17,11 @@ */ #if defined(TARGET_MCU_NRF51822) || defined(TARGET_MCU_NRF52832) #define STACK_SIZE 512 -#elif (defined(TARGET_STM32F070RB) || defined(TARGET_STM32F072RB) || defined(TARGET_STM32F103RB)) +#elif defined(TARGET_STM32F070RB) || defined(TARGET_STM32F072RB) || defined(TARGET_STM32F103RB) || defined(TARGET_STM32F091RC) + #define STACK_SIZE 512 +#elif defined(TARGET_STM32F410RB) + #define STACK_SIZE 512 +#elif defined(TARGET_STM32L073RZ) #define STACK_SIZE 512 #else #define STACK_SIZE DEFAULT_STACK_SIZE diff --git a/features/FEATURE_BLE/ble/deprecate.h b/features/FEATURE_BLE/ble/deprecate.h index 47fd3bb2d5..f0b7d38cb8 100644 --- a/features/FEATURE_BLE/ble/deprecate.h +++ b/features/FEATURE_BLE/ble/deprecate.h @@ -23,4 +23,4 @@ #define __deprecated_message(msg) #endif -#endif \ No newline at end of file +#endif diff --git a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_MCU_NRF51822/sdk/source/ble/common/ble_conn_state.c b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_MCU_NRF51822/sdk/source/ble/common/ble_conn_state.c index 739cf1f638..a5f5461595 100644 --- a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_MCU_NRF51822/sdk/source/ble/common/ble_conn_state.c +++ b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_MCU_NRF51822/sdk/source/ble/common/ble_conn_state.c @@ -169,7 +169,7 @@ static void record_purge_disconnected() m_bcs.valid_conn_handles, (~m_bcs.flags.connected_flags) & (m_bcs.flags.valid_flags)); - for (int i = 0; i < disconnected_list.len; i++) + for (uint32_t i = 0; i < disconnected_list.len; i++) { record_invalidate(disconnected_list.flag_keys[i]); } diff --git a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_MCU_NRF51822/sdk/source/ble/peer_manager/peer_database.c b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_MCU_NRF51822/sdk/source/ble/peer_manager/peer_database.c index a34fc78fb3..8a790c02dd 100644 --- a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_MCU_NRF51822/sdk/source/ble/peer_manager/peer_database.c +++ b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_MCU_NRF51822/sdk/source/ble/peer_manager/peer_database.c @@ -172,7 +172,7 @@ static pdb_buffer_record_t * write_buffer_record_find_unused(void) */ static void write_buffer_record_release(pdb_buffer_record_t * p_write_buffer_record) { - for (int i = 0; i < p_write_buffer_record->n_bufs; i++) + for (uint32_t i = 0; i < p_write_buffer_record->n_bufs; i++) { pm_buffer_release(&m_pdb.write_buffer, p_write_buffer_record->buffer_block_id + i); } diff --git a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_MCU_NRF51822/sdk/source/ble/peer_manager/pm_buffer.c b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_MCU_NRF51822/sdk/source/ble/peer_manager/pm_buffer.c index 87379e3ac0..4299793732 100644 --- a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_MCU_NRF51822/sdk/source/ble/peer_manager/pm_buffer.c +++ b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_MCU_NRF51822/sdk/source/ble/peer_manager/pm_buffer.c @@ -93,7 +93,7 @@ uint8_t pm_buffer_block_acquire(pm_buffer_t * p_buffer, uint32_t n_blocks) { first_locked_mutex = i; } - if ((i - first_locked_mutex + 1) == n_blocks) + if ((i - first_locked_mutex + 1) >= 0 && ((uint32_t)(i - first_locked_mutex + 1)) == n_blocks) { return first_locked_mutex; } diff --git a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_MCU_NRF51822/sdk/source/drivers_nrf/delay/nrf_delay.h b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_MCU_NRF51822/sdk/source/drivers_nrf/delay/nrf_delay.h index 79ba8872fb..85e2c3c8ba 100644 --- a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_MCU_NRF51822/sdk/source/drivers_nrf/delay/nrf_delay.h +++ b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_MCU_NRF51822/sdk/source/drivers_nrf/delay/nrf_delay.h @@ -191,8 +191,8 @@ __STATIC_INLINE void nrf_delay_us(uint32_t volatile number_of_us) #elif defined ( __GNUC__ ) -static void __INLINE nrf_delay_us(uint32_t volatile number_of_us) __attribute__((always_inline)); -static void __INLINE nrf_delay_us(uint32_t volatile number_of_us) +static __INLINE void nrf_delay_us(uint32_t volatile number_of_us) __attribute__((always_inline)); +static __INLINE void nrf_delay_us(uint32_t volatile number_of_us) { register uint32_t delay __ASM ("r0") = number_of_us; __ASM volatile ( diff --git a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_MCU_NRF51822/sdk/source/libraries/fds/fds.c b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_MCU_NRF51822/sdk/source/libraries/fds/fds.c index 6de311a34b..edcefd3010 100644 --- a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_MCU_NRF51822/sdk/source/libraries/fds/fds.c +++ b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_MCU_NRF51822/sdk/source/libraries/fds/fds.c @@ -40,6 +40,10 @@ #include "nrf_error.h" #include "app_util.h" +static void fs_callback(uint8_t op_code, + uint32_t result, + uint32_t const * p_data, + fs_length_t length_words); /** Our fstorage configuration. * The other fields will be assigned automatically during compilation. */ diff --git a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_MCU_NRF51822/sdk/source/libraries/fds/fds_types_internal.h b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_MCU_NRF51822/sdk/source/libraries/fds/fds_types_internal.h index a97a6af196..9429285333 100644 --- a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_MCU_NRF51822/sdk/source/libraries/fds/fds_types_internal.h +++ b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_MCU_NRF51822/sdk/source/libraries/fds/fds_types_internal.h @@ -68,7 +68,7 @@ #define FDS_CMD_QUEUE_SIZE_GC (1) -static uint8_t m_nested_critical; +//static uint8_t m_nested_critical; /** Macros to enable and disable application interrupts. */ #define CRITICAL_SECTION_ENTER() //sd_nvic_critical_region_enter(&m_nested_critical) diff --git a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_MCU_NRF51822/sdk/source/libraries/fstorage/fstorage.c b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_MCU_NRF51822/sdk/source/libraries/fstorage/fstorage.c index d75df2ecb1..8cc8cc1af0 100644 --- a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_MCU_NRF51822/sdk/source/libraries/fstorage/fstorage.c +++ b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_MCU_NRF51822/sdk/source/libraries/fstorage/fstorage.c @@ -559,7 +559,7 @@ void fs_debug_print() printf("Num items: 0x%08lx\r\n", (unsigned long)FS_SECTION_VARS_COUNT); printf("===== ITEMS %lu =====\r\n", (unsigned long)FS_SECTION_VARS_COUNT); - for(int i = 0; i < FS_SECTION_VARS_COUNT; i++) + for(uint32_t i = 0; i < FS_SECTION_VARS_COUNT; i++) { fs_config_t* config = FS_SECTION_VARS_GET(i); printf( "Address: 0x%08lx, CB: 0x%08lx\r\n", diff --git a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_MCU_NRF51822/sdk/source/libraries/fstorage/fstorage.h b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_MCU_NRF51822/sdk/source/libraries/fstorage/fstorage.h index cf19e2e25b..6f364ca27c 100644 --- a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_MCU_NRF51822/sdk/source/libraries/fstorage/fstorage.h +++ b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_MCU_NRF51822/sdk/source/libraries/fstorage/fstorage.h @@ -74,23 +74,6 @@ typedef void (*fs_cb_t)(uint8_t op_code, fs_length_t length_words); -/**@brief Function prototype for a callback handler. - * - * @details This function is expected to be implemented by the module that - * registers for fstorage usage. Its usage is described - * in the function pointer type fs_cb_t. - * - * @param[in] op_code Flash operation code. - * @param[in] result Result of the flash operation. - * @param[in] p_data Pointer to the resulting data (or NULL if not in use). - * @param[in] length_words Length of data in words. - */ -static void fs_callback(uint8_t op_code, - uint32_t result, - uint32_t const * p_data, - fs_length_t length_words); - - /**@brief Flash storage config variable. * * @details The fstorage module will update the start_addr and end_address according to diff --git a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_MCU_NRF51822/sdk/source/libraries/util/app_util_platform.h b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_MCU_NRF51822/sdk/source/libraries/util/app_util_platform.h index de07685736..dd5c984357 100644 --- a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_MCU_NRF51822/sdk/source/libraries/util/app_util_platform.h +++ b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_MCU_NRF51822/sdk/source/libraries/util/app_util_platform.h @@ -68,8 +68,6 @@ typedef enum #define EXTERNAL_INT_VECTOR_OFFSET 16 /**@endcond */ -#define PACKED(TYPE) __packed TYPE - void critical_region_enter (void); void critical_region_exit (void); diff --git a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_MCU_NRF51822/sdk/source/libraries/util/sdk_mapped_flags.c b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_MCU_NRF51822/sdk/source/libraries/util/sdk_mapped_flags.c index 93a17d7e9f..78d3929ea8 100644 --- a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_MCU_NRF51822/sdk/source/libraries/util/sdk_mapped_flags.c +++ b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_MCU_NRF51822/sdk/source/libraries/util/sdk_mapped_flags.c @@ -111,7 +111,7 @@ void sdk_mapped_flags_bulk_update_by_key(uint16_t * p_keys, { if (p_keys[i] == key) { - for (int j = 0; j < n_flag_collections; j++) + for (uint32_t j = 0; j < n_flag_collections; j++) { if (value) { diff --git a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_MCU_NRF51822/sdk/source/softdevice/s130/headers/nrf_svc.h b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_MCU_NRF51822/sdk/source/softdevice/s130/headers/nrf_svc.h index e7b8f59471..9311be90cc 100644 --- a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_MCU_NRF51822/sdk/source/softdevice/s130/headers/nrf_svc.h +++ b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_MCU_NRF51822/sdk/source/softdevice/s130/headers/nrf_svc.h @@ -42,11 +42,11 @@ #define SVCALL(number, return_type, signature) return_type __svc(number) signature #elif defined (__GNUC__) #define SVCALL(number, return_type, signature) \ - _Pragma("GCC diagnostic ignored \"-Wunused-function\"") \ - _Pragma("GCC diagnostic ignored \"-Wunused-parameter\"") \ _Pragma("GCC diagnostic push") \ _Pragma("GCC diagnostic ignored \"-Wreturn-type\"") \ - __attribute__((naked)) static return_type signature \ + __attribute__((naked)) \ + __attribute__((unused)) \ + static return_type signature \ { \ __asm( \ "svc %0\n" \ diff --git a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_MCU_NRF51822/source/btle/btle.cpp b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_MCU_NRF51822/source/btle/btle.cpp index cee1cfca9e..0bb0c400fe 100644 --- a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_MCU_NRF51822/source/btle/btle.cpp +++ b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_MCU_NRF51822/source/btle/btle.cpp @@ -234,7 +234,7 @@ static void btle_handler(ble_evt_t *p_ble_evt) /*! @brief Callback when an error occurs inside the SoftDevice */ void assert_nrf_callback(uint16_t line_num, const uint8_t *p_file_name) { - ASSERT(false, (void) 0); + ASSERT_TRUE(false, (void) 0); } /*! diff --git a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_MCU_NRF51822/source/btle/btle_discovery.cpp b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_MCU_NRF51822/source/btle/btle_discovery.cpp index 4d5eea004d..d6f815d64e 100644 --- a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_MCU_NRF51822/source/btle/btle_discovery.cpp +++ b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_MCU_NRF51822/source/btle/btle_discovery.cpp @@ -23,7 +23,6 @@ void bleGattcEventHandler(const ble_evt_t *p_ble_evt) { nRF5xn &ble = nRF5xn::Instance(BLE::DEFAULT_INSTANCE); - nRF5xGap &gap = (nRF5xGap &) ble.getGap(); nRF5xGattClient &gattClient = (nRF5xGattClient &) ble.getGattClient(); nRF5xServiceDiscovery &sdSingleton = gattClient.discovery(); nRF5xCharacteristicDescriptorDiscoverer &characteristicDescriptorDiscoverer = diff --git a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_MCU_NRF51822/source/btle/custom/custom_helper.cpp b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_MCU_NRF51822/source/btle/custom/custom_helper.cpp index 60ff8544c5..b7fbb61d77 100644 --- a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_MCU_NRF51822/source/btle/custom/custom_helper.cpp +++ b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_MCU_NRF51822/source/btle/custom/custom_helper.cpp @@ -135,7 +135,7 @@ ble_uuid_t custom_convert_to_nordic_uuid(const UUID &uuid) #define CFG_CUSTOM_UUID_BASE "\x6E\x40\x00\x00\xB5\xA3\xF3\x93\xE0\xA9\xE5\x0E\x24\xDC\xCA\x9E" uint8_t uuid_type = custom_add_uuid_base(CFG_CUSTOM_UUID_BASE); - ASSERT(uuid_type > 0, ERROR_NOT_FOUND); + ASSERT_TRUE(uuid_type > 0, ERROR_NOT_FOUND); // We can now safely add the primary service and any characteristics // for our custom service ... diff --git a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_MCU_NRF51822/source/common/assertion.h b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_MCU_NRF51822/source/common/assertion.h index c0bd8c0d66..71bacb3e81 100644 --- a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_MCU_NRF51822/source/common/assertion.h +++ b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_MCU_NRF51822/source/common/assertion.h @@ -125,7 +125,6 @@ static inline void debugger_breakpoint(void) //--------------------------------------------------------------------+ // Logical Assert //--------------------------------------------------------------------+ -#define ASSERT(...) ASSERT_TRUE(__VA_ARGS__) #define ASSERT_TRUE(condition , error) ASSERT_DEFINE( , (condition), error, "%s", "evaluated to false") #define ASSERT_FALSE(condition , error) ASSERT_DEFINE( ,!(condition), error, "%s", "evaluated to true") diff --git a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_MCU_NRF51822/source/nRF5xGap.cpp b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_MCU_NRF51822/source/nRF5xGap.cpp index 629f471c9f..77cb11b91d 100644 --- a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_MCU_NRF51822/source/nRF5xGap.cpp +++ b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_MCU_NRF51822/source/nRF5xGap.cpp @@ -96,7 +96,7 @@ ble_error_t nRF5xGap::setAdvertisingData(const GapAdvertisingData &advData, cons //} /* Send advertising data! */ - ASSERT(ERROR_NONE == + ASSERT_TRUE(ERROR_NONE == sd_ble_gap_adv_data_set(advData.getPayload(), advData.getPayloadLen(), scanResponse.getPayload(), @@ -105,7 +105,7 @@ ble_error_t nRF5xGap::setAdvertisingData(const GapAdvertisingData &advData, cons /* Make sure the GAP Service appearance value is aligned with the *appearance from GapAdvertisingData */ - ASSERT(ERROR_NONE == sd_ble_gap_appearance_set(advData.getAppearance()), + ASSERT_TRUE(ERROR_NONE == sd_ble_gap_appearance_set(advData.getAppearance()), BLE_ERROR_PARAM_OUT_OF_RANGE); /* ToDo: Perform some checks on the payload, for example the Scan Response can't */ @@ -196,7 +196,7 @@ ble_error_t nRF5xGap::startAdvertising(const GapAdvertisingParams ¶ms) adv_para.interval = params.getIntervalInADVUnits(); // advertising interval (in units of 0.625 ms) adv_para.timeout = params.getTimeout(); - ASSERT(ERROR_NONE == sd_ble_gap_adv_start(&adv_para), BLE_ERROR_PARAM_OUT_OF_RANGE); + ASSERT_TRUE(ERROR_NONE == sd_ble_gap_adv_start(&adv_para), BLE_ERROR_PARAM_OUT_OF_RANGE); return BLE_ERROR_NONE; } @@ -267,7 +267,7 @@ ble_error_t nRF5xGap::stopScan(void) { ble_error_t nRF5xGap::stopAdvertising(void) { /* Stop Advertising */ - ASSERT(ERROR_NONE == sd_ble_gap_adv_stop(), BLE_ERROR_PARAM_OUT_OF_RANGE); + ASSERT_TRUE(ERROR_NONE == sd_ble_gap_adv_stop(), BLE_ERROR_PARAM_OUT_OF_RANGE); state.advertising = 0; diff --git a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_MCU_NRF51822/source/nRF5xGap.h b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_MCU_NRF51822/source/nRF5xGap.h index 25c507c19a..90a2e2a383 100644 --- a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_MCU_NRF51822/source/nRF5xGap.h +++ b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_MCU_NRF51822/source/nRF5xGap.h @@ -220,7 +220,7 @@ private: */ void processRadioNotificationEvent(bool param) { radioNotificationCallbackParam = param; - radioNotificationTimeout.attach_us(this, &nRF5xGap::postRadioNotificationCallback, 0); + radioNotificationTimeout.attach_us(mbed::callback(this, &nRF5xGap::postRadioNotificationCallback), 0); } friend void radioNotificationStaticCallback(bool param); /* allow invocations of processRadioNotificationEvent() */ diff --git a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_MCU_NRF51822/source/nRF5xGattServer.cpp b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_MCU_NRF51822/source/nRF5xGattServer.cpp index db0647583a..4c5365f1b7 100644 --- a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_MCU_NRF51822/source/nRF5xGattServer.cpp +++ b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_MCU_NRF51822/source/nRF5xGattServer.cpp @@ -52,7 +52,7 @@ ble_error_t nRF5xGattServer::addService(GattService &service) nordicUUID = custom_convert_to_nordic_uuid(service.getUUID()); uint16_t serviceHandle; - ASSERT( ERROR_NONE == + ASSERT_TRUE( ERROR_NONE == sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY, &nordicUUID, &serviceHandle), @@ -88,7 +88,7 @@ ble_error_t nRF5xGattServer::addService(GattService &service) } } - ASSERT ( ERROR_NONE == + ASSERT_TRUE ( ERROR_NONE == custom_add_in_characteristic(BLE_GATT_HANDLE_INVALID, &nordicUUID, p_char->getProperties(), @@ -123,7 +123,7 @@ ble_error_t nRF5xGattServer::addService(GattService &service) nordicUUID = custom_convert_to_nordic_uuid(p_desc->getUUID()); - ASSERT(ERROR_NONE == + ASSERT_TRUE(ERROR_NONE == custom_add_in_descriptor(BLE_GATT_HANDLE_INVALID, &nordicUUID, p_desc->getValuePtr(), @@ -177,7 +177,7 @@ ble_error_t nRF5xGattServer::read(Gap::Handle_t connectionHandle, GattAttribute: .p_value = buffer, }; - ASSERT( ERROR_NONE == + ASSERT_TRUE( ERROR_NONE == sd_ble_gatts_value_get(connectionHandle, attributeHandle, &value), BLE_ERROR_PARAM_OUT_OF_RANGE); *lengthP = value.len; diff --git a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF5/source/btle/btle.cpp b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF5/source/btle/btle.cpp index afe6c77d8f..f004d86cb1 100644 --- a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF5/source/btle/btle.cpp +++ b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF5/source/btle/btle.cpp @@ -292,7 +292,7 @@ static void btle_handler(ble_evt_t *p_ble_evt) /*! @brief Callback when an error occurs inside the SoftDevice */ void assert_nrf_callback(uint16_t line_num, const uint8_t *p_file_name) { - ASSERT(false, (void) 0); + ASSERT_TRUE(false, (void) 0); } /*! diff --git a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF5/source/common/assertion.h b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF5/source/common/assertion.h index c0bd8c0d66..71bacb3e81 100644 --- a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF5/source/common/assertion.h +++ b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF5/source/common/assertion.h @@ -125,7 +125,6 @@ static inline void debugger_breakpoint(void) //--------------------------------------------------------------------+ // Logical Assert //--------------------------------------------------------------------+ -#define ASSERT(...) ASSERT_TRUE(__VA_ARGS__) #define ASSERT_TRUE(condition , error) ASSERT_DEFINE( , (condition), error, "%s", "evaluated to false") #define ASSERT_FALSE(condition , error) ASSERT_DEFINE( ,!(condition), error, "%s", "evaluated to true") diff --git a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF5/source/nRF5xGap.cpp b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF5/source/nRF5xGap.cpp index a2f59dd4da..f874bfefe5 100644 --- a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF5/source/nRF5xGap.cpp +++ b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF5/source/nRF5xGap.cpp @@ -96,7 +96,7 @@ ble_error_t nRF5xGap::setAdvertisingData(const GapAdvertisingData &advData, cons //} /* Send advertising data! */ - ASSERT(ERROR_NONE == + ASSERT_TRUE(ERROR_NONE == sd_ble_gap_adv_data_set(advData.getPayload(), advData.getPayloadLen(), scanResponse.getPayload(), @@ -105,7 +105,7 @@ ble_error_t nRF5xGap::setAdvertisingData(const GapAdvertisingData &advData, cons /* Make sure the GAP Service appearance value is aligned with the *appearance from GapAdvertisingData */ - ASSERT(ERROR_NONE == sd_ble_gap_appearance_set(advData.getAppearance()), + ASSERT_TRUE(ERROR_NONE == sd_ble_gap_appearance_set(advData.getAppearance()), BLE_ERROR_PARAM_OUT_OF_RANGE); /* ToDo: Perform some checks on the payload, for example the Scan Response can't */ @@ -273,7 +273,7 @@ ble_error_t nRF5xGap::stopScan(void) { ble_error_t nRF5xGap::stopAdvertising(void) { /* Stop Advertising */ - ASSERT(ERROR_NONE == sd_ble_gap_adv_stop(), BLE_ERROR_PARAM_OUT_OF_RANGE); + ASSERT_TRUE(ERROR_NONE == sd_ble_gap_adv_stop(), BLE_ERROR_PARAM_OUT_OF_RANGE); state.advertising = 0; diff --git a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF5/source/nRF5xGap.h b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF5/source/nRF5xGap.h index adb80851dd..cdcd9fa8fe 100644 --- a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF5/source/nRF5xGap.h +++ b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF5/source/nRF5xGap.h @@ -221,7 +221,7 @@ private: */ void processRadioNotificationEvent(bool param) { radioNotificationCallbackParam = param; - radioNotificationTimeout.attach_us(this, &nRF5xGap::postRadioNotificationCallback, 0); + radioNotificationTimeout.attach_us(mbed::callback(this, &nRF5xGap::postRadioNotificationCallback), 0); } friend void radioNotificationStaticCallback(bool param); /* allow invocations of processRadioNotificationEvent() */ diff --git a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF5/source/nRF5xGattServer.cpp b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF5/source/nRF5xGattServer.cpp index 4f4c562920..7d079855cb 100644 --- a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF5/source/nRF5xGattServer.cpp +++ b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF5/source/nRF5xGattServer.cpp @@ -52,7 +52,7 @@ ble_error_t nRF5xGattServer::addService(GattService &service) nordicUUID = custom_convert_to_nordic_uuid(service.getUUID()); uint16_t serviceHandle; - ASSERT( ERROR_NONE == + ASSERT_TRUE( ERROR_NONE == sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY, &nordicUUID, &serviceHandle), @@ -88,7 +88,7 @@ ble_error_t nRF5xGattServer::addService(GattService &service) } } - ASSERT ( ERROR_NONE == + ASSERT_TRUE ( ERROR_NONE == custom_add_in_characteristic(BLE_GATT_HANDLE_INVALID, &nordicUUID, p_char->getProperties(), @@ -123,7 +123,7 @@ ble_error_t nRF5xGattServer::addService(GattService &service) nordicUUID = custom_convert_to_nordic_uuid(p_desc->getUUID()); - ASSERT(ERROR_NONE == + ASSERT_TRUE(ERROR_NONE == custom_add_in_descriptor(BLE_GATT_HANDLE_INVALID, &nordicUUID, p_desc->getValuePtr(), @@ -177,7 +177,7 @@ ble_error_t nRF5xGattServer::read(Gap::Handle_t connectionHandle, GattAttribute: .p_value = buffer, }; - ASSERT( ERROR_NONE == + ASSERT_TRUE( ERROR_NONE == sd_ble_gatts_value_get(connectionHandle, attributeHandle, &value), BLE_ERROR_PARAM_OUT_OF_RANGE); *lengthP = value.len; diff --git a/features/FEATURE_UVISOR/AUTHORS.txt b/features/FEATURE_UVISOR/AUTHORS.txt index dbb409636a..7f5adde714 100644 --- a/features/FEATURE_UVISOR/AUTHORS.txt +++ b/features/FEATURE_UVISOR/AUTHORS.txt @@ -1,7 +1,7 @@ - 568 Milosch Meriac - 477 Alessandro Angelino - 72 Jaeden Amero - 53 Niklas Hauser + 569 Milosch Meriac + 478 Alessandro Angelino + 73 Jaeden Amero + 54 Niklas Hauser 3 Hugo Vincent 3 JaredCJR 3 Jim Huang diff --git a/features/FEATURE_UVISOR/VERSION.txt b/features/FEATURE_UVISOR/VERSION.txt index 5bd9725a34..70449b9e7a 100644 --- a/features/FEATURE_UVISOR/VERSION.txt +++ b/features/FEATURE_UVISOR/VERSION.txt @@ -1 +1 @@ -v0.25.0 +v0.25.1 diff --git a/features/FEATURE_UVISOR/targets/TARGET_UVISOR_SUPPORTED/TARGET_ARM_BEETLE_SOC/TARGET_DEBUG/TARGET_M3/libconfiguration_beetle_cortex_m3_0x20000000_0x140.a b/features/FEATURE_UVISOR/targets/TARGET_UVISOR_SUPPORTED/TARGET_ARM_BEETLE_SOC/TARGET_DEBUG/TARGET_M3/libconfiguration_beetle_cortex_m3_0x20000000_0x140.a index f8a77d9958..82f0425942 100644 Binary files a/features/FEATURE_UVISOR/targets/TARGET_UVISOR_SUPPORTED/TARGET_ARM_BEETLE_SOC/TARGET_DEBUG/TARGET_M3/libconfiguration_beetle_cortex_m3_0x20000000_0x140.a and b/features/FEATURE_UVISOR/targets/TARGET_UVISOR_SUPPORTED/TARGET_ARM_BEETLE_SOC/TARGET_DEBUG/TARGET_M3/libconfiguration_beetle_cortex_m3_0x20000000_0x140.a differ diff --git a/features/FEATURE_UVISOR/targets/TARGET_UVISOR_SUPPORTED/TARGET_ARM_BEETLE_SOC/TARGET_RELEASE/TARGET_M3/libconfiguration_beetle_cortex_m3_0x20000000_0x140.a b/features/FEATURE_UVISOR/targets/TARGET_UVISOR_SUPPORTED/TARGET_ARM_BEETLE_SOC/TARGET_RELEASE/TARGET_M3/libconfiguration_beetle_cortex_m3_0x20000000_0x140.a index 9afd573c17..c0a286c320 100644 Binary files a/features/FEATURE_UVISOR/targets/TARGET_UVISOR_SUPPORTED/TARGET_ARM_BEETLE_SOC/TARGET_RELEASE/TARGET_M3/libconfiguration_beetle_cortex_m3_0x20000000_0x140.a and b/features/FEATURE_UVISOR/targets/TARGET_UVISOR_SUPPORTED/TARGET_ARM_BEETLE_SOC/TARGET_RELEASE/TARGET_M3/libconfiguration_beetle_cortex_m3_0x20000000_0x140.a differ diff --git a/features/FEATURE_UVISOR/targets/TARGET_UVISOR_SUPPORTED/TARGET_EFM32/TARGET_DEBUG/TARGET_M3/libconfiguration_efm32_cortex_m3_p1.a b/features/FEATURE_UVISOR/targets/TARGET_UVISOR_SUPPORTED/TARGET_EFM32/TARGET_DEBUG/TARGET_M3/libconfiguration_efm32_cortex_m3_p1.a index 559e174c4e..1df03a95e3 100644 Binary files a/features/FEATURE_UVISOR/targets/TARGET_UVISOR_SUPPORTED/TARGET_EFM32/TARGET_DEBUG/TARGET_M3/libconfiguration_efm32_cortex_m3_p1.a and b/features/FEATURE_UVISOR/targets/TARGET_UVISOR_SUPPORTED/TARGET_EFM32/TARGET_DEBUG/TARGET_M3/libconfiguration_efm32_cortex_m3_p1.a differ diff --git a/features/FEATURE_UVISOR/targets/TARGET_UVISOR_SUPPORTED/TARGET_EFM32/TARGET_DEBUG/TARGET_M4/libconfiguration_efm32_cortex_m4_p1.a b/features/FEATURE_UVISOR/targets/TARGET_UVISOR_SUPPORTED/TARGET_EFM32/TARGET_DEBUG/TARGET_M4/libconfiguration_efm32_cortex_m4_p1.a index 2f0f800f1d..b23250df3a 100644 Binary files a/features/FEATURE_UVISOR/targets/TARGET_UVISOR_SUPPORTED/TARGET_EFM32/TARGET_DEBUG/TARGET_M4/libconfiguration_efm32_cortex_m4_p1.a and b/features/FEATURE_UVISOR/targets/TARGET_UVISOR_SUPPORTED/TARGET_EFM32/TARGET_DEBUG/TARGET_M4/libconfiguration_efm32_cortex_m4_p1.a differ diff --git a/features/FEATURE_UVISOR/targets/TARGET_UVISOR_SUPPORTED/TARGET_EFM32/TARGET_RELEASE/TARGET_M3/libconfiguration_efm32_cortex_m3_p1.a b/features/FEATURE_UVISOR/targets/TARGET_UVISOR_SUPPORTED/TARGET_EFM32/TARGET_RELEASE/TARGET_M3/libconfiguration_efm32_cortex_m3_p1.a index d225f979e1..2bd980af35 100644 Binary files a/features/FEATURE_UVISOR/targets/TARGET_UVISOR_SUPPORTED/TARGET_EFM32/TARGET_RELEASE/TARGET_M3/libconfiguration_efm32_cortex_m3_p1.a and b/features/FEATURE_UVISOR/targets/TARGET_UVISOR_SUPPORTED/TARGET_EFM32/TARGET_RELEASE/TARGET_M3/libconfiguration_efm32_cortex_m3_p1.a differ diff --git a/features/FEATURE_UVISOR/targets/TARGET_UVISOR_SUPPORTED/TARGET_EFM32/TARGET_RELEASE/TARGET_M4/libconfiguration_efm32_cortex_m4_p1.a b/features/FEATURE_UVISOR/targets/TARGET_UVISOR_SUPPORTED/TARGET_EFM32/TARGET_RELEASE/TARGET_M4/libconfiguration_efm32_cortex_m4_p1.a index 101369956d..3716dcd7f7 100644 Binary files a/features/FEATURE_UVISOR/targets/TARGET_UVISOR_SUPPORTED/TARGET_EFM32/TARGET_RELEASE/TARGET_M4/libconfiguration_efm32_cortex_m4_p1.a and b/features/FEATURE_UVISOR/targets/TARGET_UVISOR_SUPPORTED/TARGET_EFM32/TARGET_RELEASE/TARGET_M4/libconfiguration_efm32_cortex_m4_p1.a differ diff --git a/features/FEATURE_UVISOR/targets/TARGET_UVISOR_SUPPORTED/TARGET_MCU_K64F/TARGET_DEBUG/TARGET_M4/libconfiguration_kinetis_cortex_m4_0x1fff0000.a b/features/FEATURE_UVISOR/targets/TARGET_UVISOR_SUPPORTED/TARGET_MCU_K64F/TARGET_DEBUG/TARGET_M4/libconfiguration_kinetis_cortex_m4_0x1fff0000.a index 6e56c19556..23a463ee18 100644 Binary files a/features/FEATURE_UVISOR/targets/TARGET_UVISOR_SUPPORTED/TARGET_MCU_K64F/TARGET_DEBUG/TARGET_M4/libconfiguration_kinetis_cortex_m4_0x1fff0000.a and b/features/FEATURE_UVISOR/targets/TARGET_UVISOR_SUPPORTED/TARGET_MCU_K64F/TARGET_DEBUG/TARGET_M4/libconfiguration_kinetis_cortex_m4_0x1fff0000.a differ diff --git a/features/FEATURE_UVISOR/targets/TARGET_UVISOR_SUPPORTED/TARGET_MCU_K64F/TARGET_RELEASE/TARGET_M4/libconfiguration_kinetis_cortex_m4_0x1fff0000.a b/features/FEATURE_UVISOR/targets/TARGET_UVISOR_SUPPORTED/TARGET_MCU_K64F/TARGET_RELEASE/TARGET_M4/libconfiguration_kinetis_cortex_m4_0x1fff0000.a index e8c2149141..88c0818ed9 100644 Binary files a/features/FEATURE_UVISOR/targets/TARGET_UVISOR_SUPPORTED/TARGET_MCU_K64F/TARGET_RELEASE/TARGET_M4/libconfiguration_kinetis_cortex_m4_0x1fff0000.a and b/features/FEATURE_UVISOR/targets/TARGET_UVISOR_SUPPORTED/TARGET_MCU_K64F/TARGET_RELEASE/TARGET_M4/libconfiguration_kinetis_cortex_m4_0x1fff0000.a differ diff --git a/features/FEATURE_UVISOR/targets/TARGET_UVISOR_SUPPORTED/TARGET_STM32F4/TARGET_DEBUG/TARGET_M4/libconfiguration_stm32_cortex_m4_0x10000000_0x0.a b/features/FEATURE_UVISOR/targets/TARGET_UVISOR_SUPPORTED/TARGET_STM32F4/TARGET_DEBUG/TARGET_M4/libconfiguration_stm32_cortex_m4_0x10000000_0x0.a index 8942e8033c..81d410822a 100644 Binary files a/features/FEATURE_UVISOR/targets/TARGET_UVISOR_SUPPORTED/TARGET_STM32F4/TARGET_DEBUG/TARGET_M4/libconfiguration_stm32_cortex_m4_0x10000000_0x0.a and b/features/FEATURE_UVISOR/targets/TARGET_UVISOR_SUPPORTED/TARGET_STM32F4/TARGET_DEBUG/TARGET_M4/libconfiguration_stm32_cortex_m4_0x10000000_0x0.a differ diff --git a/features/FEATURE_UVISOR/targets/TARGET_UVISOR_SUPPORTED/TARGET_STM32F4/TARGET_RELEASE/TARGET_M4/libconfiguration_stm32_cortex_m4_0x10000000_0x0.a b/features/FEATURE_UVISOR/targets/TARGET_UVISOR_SUPPORTED/TARGET_STM32F4/TARGET_RELEASE/TARGET_M4/libconfiguration_stm32_cortex_m4_0x10000000_0x0.a index 9f6bb87ae7..ef9dd331fe 100644 Binary files a/features/FEATURE_UVISOR/targets/TARGET_UVISOR_SUPPORTED/TARGET_STM32F4/TARGET_RELEASE/TARGET_M4/libconfiguration_stm32_cortex_m4_0x10000000_0x0.a and b/features/FEATURE_UVISOR/targets/TARGET_UVISOR_SUPPORTED/TARGET_STM32F4/TARGET_RELEASE/TARGET_M4/libconfiguration_stm32_cortex_m4_0x10000000_0x0.a differ diff --git a/features/frameworks/greentea-client/greentea-client/greentea_serial.h b/features/frameworks/greentea-client/greentea-client/greentea_serial.h index 9adba96e5c..056c61cb27 100644 --- a/features/frameworks/greentea-client/greentea-client/greentea_serial.h +++ b/features/frameworks/greentea-client/greentea-client/greentea_serial.h @@ -10,4 +10,4 @@ public: }; extern SingletonPtr greentea_serial; -#endif \ No newline at end of file +#endif diff --git a/features/frameworks/greentea-client/source/greentea_metrics.cpp b/features/frameworks/greentea-client/source/greentea_metrics.cpp index 0dc700ec08..2491a0de91 100644 --- a/features/frameworks/greentea-client/source/greentea_metrics.cpp +++ b/features/frameworks/greentea-client/source/greentea_metrics.cpp @@ -35,10 +35,13 @@ typedef struct { // Mutex to protect "buf" SingletonPtr mutex; +#if defined(MBED_STACK_STATS_ENABLED) && MBED_STACK_STATS_ENABLED static char buf[128]; static SingletonPtr > queue; +#endif static void send_heap_info(void); +#if defined(MBED_STACK_STATS_ENABLED) && MBED_STACK_STATS_ENABLED static void send_stack_info(void); static void on_thread_terminate(osThreadId id); static void enqeue_thread_info(osThreadId id); @@ -47,6 +50,7 @@ static void deque_and_print_thread_info(void); // sprintf uses a lot of stack so use these instead static uint32_t print_hex(char *buf, uint32_t value); static uint32_t print_dec(char *buf, uint32_t value); +#endif void greentea_metrics_setup() { @@ -71,6 +75,7 @@ static void send_heap_info() greentea_send_kv("max_heap_usage",heap_stats.max_size); } +#if defined(MBED_STACK_STATS_ENABLED) && MBED_STACK_STATS_ENABLED MBED_UNUSED static void send_stack_info() { mutex->lock(); @@ -205,3 +210,5 @@ static uint32_t print_dec(char *buf, uint32_t value) return pos; } + +#endif diff --git a/features/frameworks/greentea-client/source/greentea_serial.cpp b/features/frameworks/greentea-client/source/greentea_serial.cpp index ee9f31b58f..009b67fd36 100644 --- a/features/frameworks/greentea-client/source/greentea_serial.cpp +++ b/features/frameworks/greentea-client/source/greentea_serial.cpp @@ -2,4 +2,4 @@ SingletonPtr greentea_serial; -GreenteaSerial::GreenteaSerial() : mbed::RawSerial(USBTX, USBRX) {}; \ No newline at end of file +GreenteaSerial::GreenteaSerial() : mbed::RawSerial(USBTX, USBRX) {}; diff --git a/features/frameworks/greentea-client/source/test_env.cpp b/features/frameworks/greentea-client/source/test_env.cpp index 3fb1e9cd3c..c0a69a8a79 100644 --- a/features/frameworks/greentea-client/source/test_env.cpp +++ b/features/frameworks/greentea-client/source/test_env.cpp @@ -574,7 +574,6 @@ int greentea_parse_kv(char *out_key, break; } } - return 0; } /** diff --git a/features/frameworks/utest/source/utest_harness.cpp b/features/frameworks/utest/source/utest_harness.cpp index 52b8513bcd..2a020c6899 100644 --- a/features/frameworks/utest/source/utest_harness.cpp +++ b/features/frameworks/utest/source/utest_harness.cpp @@ -144,7 +144,6 @@ bool Harness::run(const Specification& specification) if (handlers->test_teardown) handlers->test_teardown(0, 0, failure); test_cases = NULL; exit(1); - return true; } notify_testcases(); @@ -159,7 +158,6 @@ bool Harness::run(const Specification& specification) if (handlers->test_teardown) handlers->test_teardown(0, 0, failure); test_cases = NULL; exit(1); - return true; } return true; } diff --git a/features/frameworks/utest/source/utest_shim.cpp b/features/frameworks/utest/source/utest_shim.cpp index 6b5ab7596a..07a1f82f80 100644 --- a/features/frameworks/utest/source/utest_shim.cpp +++ b/features/frameworks/utest/source/utest_shim.cpp @@ -123,7 +123,6 @@ static int32_t utest_us_ticker_run() callback(); } } - return 0; } diff --git a/features/mbedtls/importer/Makefile b/features/mbedtls/importer/Makefile index 01037bae34..8f3a4ae9c9 100644 --- a/features/mbedtls/importer/Makefile +++ b/features/mbedtls/importer/Makefile @@ -35,7 +35,7 @@ TARGET_SRC:=$(TARGET_PREFIX)src TARGET_INC:=$(TARGET_PREFIX)inc # mbed TLS source directory - hidden from mbed via TARGET_IGNORE -MBED_TLS_URL:=https://github.com/ARMmbed/mbedtls-restricted.git +MBED_TLS_URL:=https://github.com/ARMmbed/mbedtls.git MBED_TLS_DIR:=TARGET_IGNORE/mbedtls MBED_TLS_API:=$(MBED_TLS_DIR)/include/mbedtls MBED_TLS_GIT_CFG=$(MBED_TLS_DIR)/.git/config @@ -66,6 +66,9 @@ deploy: rsync # # Adjusting the default mbed TLS config file to mbed purposes ./adjust-config.sh $(MBED_TLS_DIR)/scripts/config.pl $(TARGET_INC)/mbedtls/config.h + # + # Copy the trimmed config that does not require entropy source + cp $(MBED_TLS_DIR)/configs/config-no-entropy.h $(TARGET_INC)/mbedtls/. update: $(MBED_TLS_GIT_CFG) $(MBED_TLS_HA_GIT_CFG) # diff --git a/features/mbedtls/importer/adjust-config.sh b/features/mbedtls/importer/adjust-config.sh index 660a348eca..a197d05052 100755 --- a/features/mbedtls/importer/adjust-config.sh +++ b/features/mbedtls/importer/adjust-config.sh @@ -25,6 +25,36 @@ conf() { $SCRIPT -f $FILE $@ } +add_code() { + MATCH_PATTERN="$1" + shift + CODE=$(IFS=""; printf "%s" "$*") + + perl -i -pe \ + "s/$MATCH_PATTERN/$MATCH_PATTERN$CODE/igs" \ + "$FILE" +} + +# add an #ifndef to include config-no-entropy.h when the target does not have +# an entropy source we can use. +add_code \ + "#ifndef MBEDTLS_CONFIG_H\n" \ + "\n" \ + "#include \"platform\/inc\/platform_mbed.h\"\n" \ + "\n" \ + "\/*\n" \ + " * Only use features that do not require an entropy source when\n" \ + " * DEVICE_ENTROPY_SOURCE is not defined in mbed OS.\n" \ + " *\/\n" \ + "#if !defined(MBEDTLS_ENTROPY_HARDWARE_ALT)\n" \ + "#include \"mbedtls\/config-no-entropy.h\"\n" \ + "#else\n" + +add_code \ + "#include \"check_config.h\"\n" \ + "\n" \ + "#endif \/* !MBEDTLS_ENTROPY_HARDWARE_ALT *\/" + # not supported on mbed OS, nor used by mbed Client conf unset MBEDTLS_NET_C conf unset MBEDTLS_TIMING_C diff --git a/features/mbedtls/inc/mbedtls/check_config.h b/features/mbedtls/inc/mbedtls/check_config.h index a95af6ca4c..75cdcbc2f0 100644 --- a/features/mbedtls/inc/mbedtls/check_config.h +++ b/features/mbedtls/inc/mbedtls/check_config.h @@ -256,6 +256,36 @@ #error "MBEDTLS_PLATFORM_EXIT_MACRO and MBEDTLS_PLATFORM_STD_EXIT/MBEDTLS_PLATFORM_EXIT_ALT cannot be defined simultaneously" #endif +#if defined(MBEDTLS_PLATFORM_TIME_ALT) &&\ + ( !defined(MBEDTLS_PLATFORM_C) ||\ + !defined(MBEDTLS_HAVE_TIME) ) +#error "MBEDTLS_PLATFORM_TIME_ALT defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_TIME_MACRO) &&\ + ( !defined(MBEDTLS_PLATFORM_C) ||\ + !defined(MBEDTLS_HAVE_TIME) ) +#error "MBEDTLS_PLATFORM_TIME_MACRO defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_TIME_TYPE_MACRO) &&\ + ( !defined(MBEDTLS_PLATFORM_C) ||\ + !defined(MBEDTLS_HAVE_TIME) ) +#error "MBEDTLS_PLATFORM_TIME_TYPE_MACRO defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_TIME_MACRO) &&\ + ( defined(MBEDTLS_PLATFORM_STD_TIME) ||\ + defined(MBEDTLS_PLATFORM_TIME_ALT) ) +#error "MBEDTLS_PLATFORM_TIME_MACRO and MBEDTLS_PLATFORM_STD_TIME/MBEDTLS_PLATFORM_TIME_ALT cannot be defined simultaneously" +#endif + +#if defined(MBEDTLS_PLATFORM_TIME_TYPE_MACRO) &&\ + ( defined(MBEDTLS_PLATFORM_STD_TIME) ||\ + defined(MBEDTLS_PLATFORM_TIME_ALT) ) +#error "MBEDTLS_PLATFORM_TIME_TYPE_MACRO and MBEDTLS_PLATFORM_STD_TIME/MBEDTLS_PLATFORM_TIME_ALT cannot be defined simultaneously" +#endif + #if defined(MBEDTLS_PLATFORM_FPRINTF_ALT) && !defined(MBEDTLS_PLATFORM_C) #error "MBEDTLS_PLATFORM_FPRINTF_ALT defined, but not all prerequisites" #endif @@ -352,6 +382,12 @@ #error "MBEDTLS_PLATFORM_STD_EXIT defined, but not all prerequisites" #endif +#if defined(MBEDTLS_PLATFORM_STD_TIME) &&\ + ( !defined(MBEDTLS_PLATFORM_TIME_ALT) ||\ + !defined(MBEDTLS_HAVE_TIME) ) +#error "MBEDTLS_PLATFORM_STD_TIME defined, but not all prerequisites" +#endif + #if defined(MBEDTLS_PLATFORM_STD_FPRINTF) &&\ !defined(MBEDTLS_PLATFORM_FPRINTF_ALT) #error "MBEDTLS_PLATFORM_STD_FPRINTF defined, but not all prerequisites" diff --git a/features/mbedtls/inc/mbedtls/config-no-entropy.h b/features/mbedtls/inc/mbedtls/config-no-entropy.h new file mode 100644 index 0000000000..95f17d456b --- /dev/null +++ b/features/mbedtls/inc/mbedtls/config-no-entropy.h @@ -0,0 +1,85 @@ +/** + * Minimal configuration of features that do not require an entropy source + * + * Copyright (C) 2016, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ +/* + * Minimal configuration of features that do not require an entropy source + * Distinguishing reatures: + * - no entropy module + * - no TLS protocol implementation available due to absence of an entropy + * source + * + * See README.txt for usage instructions. + */ + +#ifndef MBEDTLS_CONFIG_H +#define MBEDTLS_CONFIG_H + +/* System support */ +#define MBEDTLS_HAVE_ASM +#define MBEDTLS_HAVE_TIME + +/* mbed TLS feature support */ +#define MBEDTLS_CIPHER_MODE_CBC +#define MBEDTLS_CIPHER_PADDING_PKCS7 +#define MBEDTLS_REMOVE_ARC4_CIPHERSUITES +#define MBEDTLS_ECP_DP_SECP256R1_ENABLED +#define MBEDTLS_ECP_DP_SECP384R1_ENABLED +#define MBEDTLS_ECP_DP_CURVE25519_ENABLED +#define MBEDTLS_ECP_NIST_OPTIM +#define MBEDTLS_ECDSA_DETERMINISTIC +#define MBEDTLS_PK_RSA_ALT_SUPPORT +#define MBEDTLS_PKCS1_V15 +#define MBEDTLS_PKCS1_V21 +#define MBEDTLS_SELF_TEST +#define MBEDTLS_VERSION_FEATURES +#define MBEDTLS_X509_CHECK_KEY_USAGE +#define MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE + +/* mbed TLS modules */ +#define MBEDTLS_AES_C +#define MBEDTLS_ASN1_PARSE_C +#define MBEDTLS_ASN1_WRITE_C +#define MBEDTLS_BASE64_C +#define MBEDTLS_BIGNUM_C +#define MBEDTLS_CCM_C +#define MBEDTLS_CIPHER_C +#define MBEDTLS_ECDSA_C +#define MBEDTLS_ECP_C +#define MBEDTLS_ERROR_C +#define MBEDTLS_GCM_C +#define MBEDTLS_HMAC_DRBG_C +#define MBEDTLS_MD_C +#define MBEDTLS_OID_C +#define MBEDTLS_PEM_PARSE_C +#define MBEDTLS_PK_C +#define MBEDTLS_PK_PARSE_C +#define MBEDTLS_PK_WRITE_C +#define MBEDTLS_PLATFORM_C +#define MBEDTLS_RSA_C +#define MBEDTLS_SHA256_C +#define MBEDTLS_SHA512_C +#define MBEDTLS_VERSION_C +#define MBEDTLS_X509_USE_C +#define MBEDTLS_X509_CRT_PARSE_C +#define MBEDTLS_X509_CRL_PARSE_C + +#include "check_config.h" + +#endif /* MBEDTLS_CONFIG_H */ diff --git a/features/mbedtls/inc/mbedtls/config.h b/features/mbedtls/inc/mbedtls/config.h index 86b8a01836..e32e90f662 100644 --- a/features/mbedtls/inc/mbedtls/config.h +++ b/features/mbedtls/inc/mbedtls/config.h @@ -26,6 +26,16 @@ */ #ifndef MBEDTLS_CONFIG_H + +#include "platform/inc/platform_mbed.h" + +/* + * Only use features that do not require an entropy source when + * DEVICE_ENTROPY_SOURCE is not defined in mbed OS. + */ +#if !defined(MBEDTLS_ENTROPY_HARDWARE_ALT) +#include "mbedtls/config-no-entropy.h" +#else #define MBEDTLS_CONFIG_H #if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE) @@ -71,6 +81,10 @@ * The time does not need to be correct, only time differences are used, * by contrast with MBEDTLS_HAVE_TIME_DATE * + * Defining MBEDTLS_HAVE_TIME allows you to specify MBEDTLS_PLATFORM_TIME_ALT, + * MBEDTLS_PLATFORM_TIME_MACRO, MBEDTLS_PLATFORM_TIME_TYPE_MACRO and + * MBEDTLS_PLATFORM_STD_TIME. + * * Comment if your system does not support time functions */ #define MBEDTLS_HAVE_TIME @@ -148,6 +162,8 @@ * \warning MBEDTLS_PLATFORM_XXX_ALT cannot be defined at the same time as * MBEDTLS_PLATFORM_XXX_MACRO! * + * Requires: MBEDTLS_PLATFORM_TIME_ALT requires MBEDTLS_HAVE_TIME + * * Uncomment a macro to enable alternate implementation of specific base * platform function */ @@ -1954,7 +1970,7 @@ * environment: * https://tls.mbed.org/kb/how-to/how-do-i-port-mbed-tls-to-a-new-environment-OS * - * Module: library/net.c + * Module: library/net_sockets.c * * This module provides networking routines. */ @@ -2503,6 +2519,7 @@ /* Entropy options */ //#define MBEDTLS_ENTROPY_MAX_SOURCES 20 /**< Maximum number of sources supported */ //#define MBEDTLS_ENTROPY_MAX_GATHER 128 /**< Maximum amount requested from entropy sources */ +//#define MBEDTLS_ENTROPY_MIN_HARDWARE 32 /**< Default minimum number of bytes required for the hardware entropy source mbedtls_hardware_poll() before entropy is released */ /* Memory buffer allocator options */ //#define MBEDTLS_MEMORY_ALIGN_MULTIPLE 4 /**< Align on multiples of this value */ @@ -2512,7 +2529,7 @@ //#define MBEDTLS_PLATFORM_STD_CALLOC calloc /**< Default allocator to use, can be undefined */ //#define MBEDTLS_PLATFORM_STD_FREE free /**< Default free to use, can be undefined */ //#define MBEDTLS_PLATFORM_STD_EXIT exit /**< Default exit to use, can be undefined */ -//#define MBEDTLS_PLATFORM_STD_TIME time /**< Default time to use, can be undefined */ +//#define MBEDTLS_PLATFORM_STD_TIME time /**< Default time to use, can be undefined. MBEDTLS_HAVE_TIME must be enabled */ //#define MBEDTLS_PLATFORM_STD_FPRINTF fprintf /**< Default fprintf to use, can be undefined */ //#define MBEDTLS_PLATFORM_STD_PRINTF printf /**< Default printf to use, can be undefined */ /* Note: your snprintf must correclty zero-terminate the buffer! */ @@ -2528,8 +2545,8 @@ //#define MBEDTLS_PLATFORM_CALLOC_MACRO calloc /**< Default allocator macro to use, can be undefined */ //#define MBEDTLS_PLATFORM_FREE_MACRO free /**< Default free macro to use, can be undefined */ //#define MBEDTLS_PLATFORM_EXIT_MACRO exit /**< Default exit macro to use, can be undefined */ -//#define MBEDTLS_PLATFORM_TIME_MACRO time /**< Default time macro to use, can be undefined */ -//#define MBEDTLS_PLATFORM_TIME_TYPE_MACRO time_t /**< Default time macro to use, can be undefined */ +//#define MBEDTLS_PLATFORM_TIME_MACRO time /**< Default time macro to use, can be undefined. MBEDTLS_HAVE_TIME must be enabled */ +//#define MBEDTLS_PLATFORM_TIME_TYPE_MACRO time_t /**< Default time macro to use, can be undefined. MBEDTLS_HAVE_TIME must be enabled */ //#define MBEDTLS_PLATFORM_FPRINTF_MACRO fprintf /**< Default fprintf macro to use, can be undefined */ //#define MBEDTLS_PLATFORM_PRINTF_MACRO printf /**< Default printf macro to use, can be undefined */ /* Note: your snprintf must correclty zero-terminate the buffer! */ @@ -2563,11 +2580,16 @@ /* X509 options */ //#define MBEDTLS_X509_MAX_INTERMEDIATE_CA 8 /**< Maximum number of intermediate CAs in a verification chain. */ +//#define MBEDTLS_X509_MAX_FILE_PATH_LEN 512 /**< Maximum length of a path/filename string in bytes including the null terminator character ('\0'). */ /* \} name SECTION: Customisation configuration options */ /* Target and application specific configurations */ -//#define YOTTA_CFG_MBEDTLS_USER_CONFIG_FILE "target_config.h" +//#define YOTTA_CFG_MBEDTLS_TARGET_CONFIG_FILE "mbedtls/target_config.h" + +#if defined(TARGET_LIKE_MBED) && defined(YOTTA_CFG_MBEDTLS_TARGET_CONFIG_FILE) +#include YOTTA_CFG_MBEDTLS_TARGET_CONFIG_FILE +#endif /* * Allow user to override any previous default. @@ -2584,4 +2606,5 @@ #include "check_config.h" +#endif /* !MBEDTLS_ENTROPY_HARDWARE_ALT */ #endif /* MBEDTLS_CONFIG_H */ diff --git a/features/mbedtls/inc/mbedtls/entropy.h b/features/mbedtls/inc/mbedtls/entropy.h index fed0494ed1..747aca4dfa 100644 --- a/features/mbedtls/inc/mbedtls/entropy.h +++ b/features/mbedtls/inc/mbedtls/entropy.h @@ -255,9 +255,29 @@ int mbedtls_entropy_update_seed_file( mbedtls_entropy_context *ctx, const char * /** * \brief Checkup routine * + * This module self-test also calls the entropy self-test, + * mbedtls_entropy_source_self_test(); + * * \return 0 if successful, or 1 if a test failed */ int mbedtls_entropy_self_test( int verbose ); + +#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT) +/** + * \brief Checkup routine + * + * Verifies the integrity of the hardware entropy source + * provided by the function 'mbedtls_hardware_poll()'. + * + * Note this is the only hardware entropy source that is known + * at link time, and other entropy sources configured + * dynamically at runtime by the function + * mbedtls_entropy_add_source() will not be tested. + * + * \return 0 if successful, or 1 if a test failed + */ +int mbedtls_entropy_source_self_test( int verbose ); +#endif /* MBEDTLS_ENTROPY_HARDWARE_ALT */ #endif /* MBEDTLS_SELF_TEST */ #ifdef __cplusplus diff --git a/features/mbedtls/inc/mbedtls/entropy_poll.h b/features/mbedtls/inc/mbedtls/entropy_poll.h index 430e8651c7..81258d5f39 100644 --- a/features/mbedtls/inc/mbedtls/entropy_poll.h +++ b/features/mbedtls/inc/mbedtls/entropy_poll.h @@ -41,7 +41,9 @@ extern "C" { #define MBEDTLS_ENTROPY_MIN_PLATFORM 32 /**< Minimum for platform source */ #define MBEDTLS_ENTROPY_MIN_HAVEGE 32 /**< Minimum for HAVEGE */ #define MBEDTLS_ENTROPY_MIN_HARDCLOCK 4 /**< Minimum for mbedtls_timing_hardclock() */ +#if !defined(MBEDTLS_ENTROPY_MIN_HARDWARE) #define MBEDTLS_ENTROPY_MIN_HARDWARE 32 /**< Minimum for the hardware source */ +#endif /** * \brief Entropy poll callback that provides 0 entropy. diff --git a/features/mbedtls/inc/mbedtls/net.h b/features/mbedtls/inc/mbedtls/net.h index 8c6534cfb8..774559b3cf 100644 --- a/features/mbedtls/inc/mbedtls/net.h +++ b/features/mbedtls/inc/mbedtls/net.h @@ -1,9 +1,9 @@ /** * \file net.h * - * \brief Network communication functions + * \brief Deprecated header file that includes mbedtls/net_sockets.h * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright (C) 2006-2016, ARM Limited, All Rights Reserved * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); you may @@ -19,207 +19,13 @@ * limitations under the License. * * This file is part of mbed TLS (https://tls.mbed.org) + * + * \deprecated Superseded by mbedtls/net_sockets.h */ -#ifndef MBEDTLS_NET_H -#define MBEDTLS_NET_H -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#include "ssl.h" - -#include -#include - -#define MBEDTLS_ERR_NET_SOCKET_FAILED -0x0042 /**< Failed to open a socket. */ -#define MBEDTLS_ERR_NET_CONNECT_FAILED -0x0044 /**< The connection to the given server / port failed. */ -#define MBEDTLS_ERR_NET_BIND_FAILED -0x0046 /**< Binding of the socket failed. */ -#define MBEDTLS_ERR_NET_LISTEN_FAILED -0x0048 /**< Could not listen on the socket. */ -#define MBEDTLS_ERR_NET_ACCEPT_FAILED -0x004A /**< Could not accept the incoming connection. */ -#define MBEDTLS_ERR_NET_RECV_FAILED -0x004C /**< Reading information from the socket failed. */ -#define MBEDTLS_ERR_NET_SEND_FAILED -0x004E /**< Sending information through the socket failed. */ -#define MBEDTLS_ERR_NET_CONN_RESET -0x0050 /**< Connection was reset by peer. */ -#define MBEDTLS_ERR_NET_UNKNOWN_HOST -0x0052 /**< Failed to get an IP address for the given hostname. */ -#define MBEDTLS_ERR_NET_BUFFER_TOO_SMALL -0x0043 /**< Buffer is too small to hold the data. */ -#define MBEDTLS_ERR_NET_INVALID_CONTEXT -0x0045 /**< The context is invalid, eg because it was free()ed. */ - -#define MBEDTLS_NET_LISTEN_BACKLOG 10 /**< The backlog that listen() should use. */ - -#define MBEDTLS_NET_PROTO_TCP 0 /**< The TCP transport protocol */ -#define MBEDTLS_NET_PROTO_UDP 1 /**< The UDP transport protocol */ - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * Wrapper type for sockets. - * - * Currently backed by just a file descriptor, but might be more in the future - * (eg two file descriptors for combined IPv4 + IPv6 support, or additional - * structures for hand-made UDP demultiplexing). - */ -typedef struct -{ - int fd; /**< The underlying file descriptor */ -} -mbedtls_net_context; - -/** - * \brief Initialize a context - * Just makes the context ready to be used or freed safely. - * - * \param ctx Context to initialize - */ -void mbedtls_net_init( mbedtls_net_context *ctx ); - -/** - * \brief Initiate a connection with host:port in the given protocol - * - * \param ctx Socket to use - * \param host Host to connect to - * \param port Port to connect to - * \param proto Protocol: MBEDTLS_NET_PROTO_TCP or MBEDTLS_NET_PROTO_UDP - * - * \return 0 if successful, or one of: - * MBEDTLS_ERR_NET_SOCKET_FAILED, - * MBEDTLS_ERR_NET_UNKNOWN_HOST, - * MBEDTLS_ERR_NET_CONNECT_FAILED - * - * \note Sets the socket in connected mode even with UDP. - */ -int mbedtls_net_connect( mbedtls_net_context *ctx, const char *host, const char *port, int proto ); - -/** - * \brief Create a receiving socket on bind_ip:port in the chosen - * protocol. If bind_ip == NULL, all interfaces are bound. - * - * \param ctx Socket to use - * \param bind_ip IP to bind to, can be NULL - * \param port Port number to use - * \param proto Protocol: MBEDTLS_NET_PROTO_TCP or MBEDTLS_NET_PROTO_UDP - * - * \return 0 if successful, or one of: - * MBEDTLS_ERR_NET_SOCKET_FAILED, - * MBEDTLS_ERR_NET_BIND_FAILED, - * MBEDTLS_ERR_NET_LISTEN_FAILED - * - * \note Regardless of the protocol, opens the sockets and binds it. - * In addition, make the socket listening if protocol is TCP. - */ -int mbedtls_net_bind( mbedtls_net_context *ctx, const char *bind_ip, const char *port, int proto ); - -/** - * \brief Accept a connection from a remote client - * - * \param bind_ctx Relevant socket - * \param client_ctx Will contain the connected client socket - * \param client_ip Will contain the client IP address - * \param buf_size Size of the client_ip buffer - * \param ip_len Will receive the size of the client IP written - * - * \return 0 if successful, or - * MBEDTLS_ERR_NET_ACCEPT_FAILED, or - * MBEDTLS_ERR_NET_BUFFER_TOO_SMALL if buf_size is too small, - * MBEDTLS_ERR_SSL_WANT_READ if bind_fd was set to - * non-blocking and accept() would block. - */ -int mbedtls_net_accept( mbedtls_net_context *bind_ctx, - mbedtls_net_context *client_ctx, - void *client_ip, size_t buf_size, size_t *ip_len ); - -/** - * \brief Set the socket blocking - * - * \param ctx Socket to set - * - * \return 0 if successful, or a non-zero error code - */ -int mbedtls_net_set_block( mbedtls_net_context *ctx ); - -/** - * \brief Set the socket non-blocking - * - * \param ctx Socket to set - * - * \return 0 if successful, or a non-zero error code - */ -int mbedtls_net_set_nonblock( mbedtls_net_context *ctx ); - -/** - * \brief Portable usleep helper - * - * \param usec Amount of microseconds to sleep - * - * \note Real amount of time slept will not be less than - * select()'s timeout granularity (typically, 10ms). - */ -void mbedtls_net_usleep( unsigned long usec ); - -/** - * \brief Read at most 'len' characters. If no error occurs, - * the actual amount read is returned. - * - * \param ctx Socket - * \param buf The buffer to write to - * \param len Maximum length of the buffer - * - * \return the number of bytes received, - * or a non-zero error code; with a non-blocking socket, - * MBEDTLS_ERR_SSL_WANT_READ indicates read() would block. - */ -int mbedtls_net_recv( void *ctx, unsigned char *buf, size_t len ); - -/** - * \brief Write at most 'len' characters. If no error occurs, - * the actual amount read is returned. - * - * \param ctx Socket - * \param buf The buffer to read from - * \param len The length of the buffer - * - * \return the number of bytes sent, - * or a non-zero error code; with a non-blocking socket, - * MBEDTLS_ERR_SSL_WANT_WRITE indicates write() would block. - */ -int mbedtls_net_send( void *ctx, const unsigned char *buf, size_t len ); - -/** - * \brief Read at most 'len' characters, blocking for at most - * 'timeout' seconds. If no error occurs, the actual amount - * read is returned. - * - * \param ctx Socket - * \param buf The buffer to write to - * \param len Maximum length of the buffer - * \param timeout Maximum number of milliseconds to wait for data - * 0 means no timeout (wait forever) - * - * \return the number of bytes received, - * or a non-zero error code: - * MBEDTLS_ERR_SSL_TIMEOUT if the operation timed out, - * MBEDTLS_ERR_SSL_WANT_READ if interrupted by a signal. - * - * \note This function will block (until data becomes available or - * timeout is reached) even if the socket is set to - * non-blocking. Handling timeouts with non-blocking reads - * requires a different strategy. - */ -int mbedtls_net_recv_timeout( void *ctx, unsigned char *buf, size_t len, - uint32_t timeout ); - -/** - * \brief Gracefully shutdown the connection and free associated data - * - * \param ctx The context to free - */ -void mbedtls_net_free( mbedtls_net_context *ctx ); - -#ifdef __cplusplus -} -#endif - -#endif /* net.h */ +#if !defined(MBEDTLS_DEPRECATED_REMOVED) +#include "mbedtls/net_sockets.h" +#if defined(MBEDTLS_DEPRECATED_WARNING) +#warning "Deprecated header file: Superseded by mbedtls/net_sockets.h" +#endif /* MBEDTLS_DEPRECATED_WARNING */ +#endif /* !MBEDTLS_DEPRECATED_REMOVED */ diff --git a/features/mbedtls/inc/mbedtls/net_sockets.h b/features/mbedtls/inc/mbedtls/net_sockets.h new file mode 100644 index 0000000000..de335526fe --- /dev/null +++ b/features/mbedtls/inc/mbedtls/net_sockets.h @@ -0,0 +1,225 @@ +/** + * \file net_sockets.h + * + * \brief Network communication functions + * + * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ +#ifndef MBEDTLS_NET_SOCKETS_H +#define MBEDTLS_NET_SOCKETS_H + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#include "ssl.h" + +#include +#include + +#define MBEDTLS_ERR_NET_SOCKET_FAILED -0x0042 /**< Failed to open a socket. */ +#define MBEDTLS_ERR_NET_CONNECT_FAILED -0x0044 /**< The connection to the given server / port failed. */ +#define MBEDTLS_ERR_NET_BIND_FAILED -0x0046 /**< Binding of the socket failed. */ +#define MBEDTLS_ERR_NET_LISTEN_FAILED -0x0048 /**< Could not listen on the socket. */ +#define MBEDTLS_ERR_NET_ACCEPT_FAILED -0x004A /**< Could not accept the incoming connection. */ +#define MBEDTLS_ERR_NET_RECV_FAILED -0x004C /**< Reading information from the socket failed. */ +#define MBEDTLS_ERR_NET_SEND_FAILED -0x004E /**< Sending information through the socket failed. */ +#define MBEDTLS_ERR_NET_CONN_RESET -0x0050 /**< Connection was reset by peer. */ +#define MBEDTLS_ERR_NET_UNKNOWN_HOST -0x0052 /**< Failed to get an IP address for the given hostname. */ +#define MBEDTLS_ERR_NET_BUFFER_TOO_SMALL -0x0043 /**< Buffer is too small to hold the data. */ +#define MBEDTLS_ERR_NET_INVALID_CONTEXT -0x0045 /**< The context is invalid, eg because it was free()ed. */ + +#define MBEDTLS_NET_LISTEN_BACKLOG 10 /**< The backlog that listen() should use. */ + +#define MBEDTLS_NET_PROTO_TCP 0 /**< The TCP transport protocol */ +#define MBEDTLS_NET_PROTO_UDP 1 /**< The UDP transport protocol */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Wrapper type for sockets. + * + * Currently backed by just a file descriptor, but might be more in the future + * (eg two file descriptors for combined IPv4 + IPv6 support, or additional + * structures for hand-made UDP demultiplexing). + */ +typedef struct +{ + int fd; /**< The underlying file descriptor */ +} +mbedtls_net_context; + +/** + * \brief Initialize a context + * Just makes the context ready to be used or freed safely. + * + * \param ctx Context to initialize + */ +void mbedtls_net_init( mbedtls_net_context *ctx ); + +/** + * \brief Initiate a connection with host:port in the given protocol + * + * \param ctx Socket to use + * \param host Host to connect to + * \param port Port to connect to + * \param proto Protocol: MBEDTLS_NET_PROTO_TCP or MBEDTLS_NET_PROTO_UDP + * + * \return 0 if successful, or one of: + * MBEDTLS_ERR_NET_SOCKET_FAILED, + * MBEDTLS_ERR_NET_UNKNOWN_HOST, + * MBEDTLS_ERR_NET_CONNECT_FAILED + * + * \note Sets the socket in connected mode even with UDP. + */ +int mbedtls_net_connect( mbedtls_net_context *ctx, const char *host, const char *port, int proto ); + +/** + * \brief Create a receiving socket on bind_ip:port in the chosen + * protocol. If bind_ip == NULL, all interfaces are bound. + * + * \param ctx Socket to use + * \param bind_ip IP to bind to, can be NULL + * \param port Port number to use + * \param proto Protocol: MBEDTLS_NET_PROTO_TCP or MBEDTLS_NET_PROTO_UDP + * + * \return 0 if successful, or one of: + * MBEDTLS_ERR_NET_SOCKET_FAILED, + * MBEDTLS_ERR_NET_BIND_FAILED, + * MBEDTLS_ERR_NET_LISTEN_FAILED + * + * \note Regardless of the protocol, opens the sockets and binds it. + * In addition, make the socket listening if protocol is TCP. + */ +int mbedtls_net_bind( mbedtls_net_context *ctx, const char *bind_ip, const char *port, int proto ); + +/** + * \brief Accept a connection from a remote client + * + * \param bind_ctx Relevant socket + * \param client_ctx Will contain the connected client socket + * \param client_ip Will contain the client IP address + * \param buf_size Size of the client_ip buffer + * \param ip_len Will receive the size of the client IP written + * + * \return 0 if successful, or + * MBEDTLS_ERR_NET_ACCEPT_FAILED, or + * MBEDTLS_ERR_NET_BUFFER_TOO_SMALL if buf_size is too small, + * MBEDTLS_ERR_SSL_WANT_READ if bind_fd was set to + * non-blocking and accept() would block. + */ +int mbedtls_net_accept( mbedtls_net_context *bind_ctx, + mbedtls_net_context *client_ctx, + void *client_ip, size_t buf_size, size_t *ip_len ); + +/** + * \brief Set the socket blocking + * + * \param ctx Socket to set + * + * \return 0 if successful, or a non-zero error code + */ +int mbedtls_net_set_block( mbedtls_net_context *ctx ); + +/** + * \brief Set the socket non-blocking + * + * \param ctx Socket to set + * + * \return 0 if successful, or a non-zero error code + */ +int mbedtls_net_set_nonblock( mbedtls_net_context *ctx ); + +/** + * \brief Portable usleep helper + * + * \param usec Amount of microseconds to sleep + * + * \note Real amount of time slept will not be less than + * select()'s timeout granularity (typically, 10ms). + */ +void mbedtls_net_usleep( unsigned long usec ); + +/** + * \brief Read at most 'len' characters. If no error occurs, + * the actual amount read is returned. + * + * \param ctx Socket + * \param buf The buffer to write to + * \param len Maximum length of the buffer + * + * \return the number of bytes received, + * or a non-zero error code; with a non-blocking socket, + * MBEDTLS_ERR_SSL_WANT_READ indicates read() would block. + */ +int mbedtls_net_recv( void *ctx, unsigned char *buf, size_t len ); + +/** + * \brief Write at most 'len' characters. If no error occurs, + * the actual amount read is returned. + * + * \param ctx Socket + * \param buf The buffer to read from + * \param len The length of the buffer + * + * \return the number of bytes sent, + * or a non-zero error code; with a non-blocking socket, + * MBEDTLS_ERR_SSL_WANT_WRITE indicates write() would block. + */ +int mbedtls_net_send( void *ctx, const unsigned char *buf, size_t len ); + +/** + * \brief Read at most 'len' characters, blocking for at most + * 'timeout' seconds. If no error occurs, the actual amount + * read is returned. + * + * \param ctx Socket + * \param buf The buffer to write to + * \param len Maximum length of the buffer + * \param timeout Maximum number of milliseconds to wait for data + * 0 means no timeout (wait forever) + * + * \return the number of bytes received, + * or a non-zero error code: + * MBEDTLS_ERR_SSL_TIMEOUT if the operation timed out, + * MBEDTLS_ERR_SSL_WANT_READ if interrupted by a signal. + * + * \note This function will block (until data becomes available or + * timeout is reached) even if the socket is set to + * non-blocking. Handling timeouts with non-blocking reads + * requires a different strategy. + */ +int mbedtls_net_recv_timeout( void *ctx, unsigned char *buf, size_t len, + uint32_t timeout ); + +/** + * \brief Gracefully shutdown the connection and free associated data + * + * \param ctx The context to free + */ +void mbedtls_net_free( mbedtls_net_context *ctx ); + +#ifdef __cplusplus +} +#endif + +#endif /* net_sockets.h */ diff --git a/features/mbedtls/inc/mbedtls/platform.h b/features/mbedtls/inc/mbedtls/platform.h index caf8f25271..b1b019e55e 100644 --- a/features/mbedtls/inc/mbedtls/platform.h +++ b/features/mbedtls/inc/mbedtls/platform.h @@ -29,6 +29,10 @@ #include MBEDTLS_CONFIG_FILE #endif +#if defined(MBEDTLS_HAVE_TIME) +#include "mbedtls/platform_time.h" +#endif + #ifdef __cplusplus extern "C" { #endif @@ -243,39 +247,6 @@ int mbedtls_platform_set_exit( void (*exit_func)( int status ) ); #define MBEDTLS_EXIT_FAILURE 1 #endif -/* - * The time_t datatype - */ -#if defined(MBEDTLS_PLATFORM_TIME_TYPE_MACRO) -typedef MBEDTLS_PLATFORM_TIME_TYPE_MACRO mbedtls_time_t; -#else -/* For time_t */ -#include -typedef time_t mbedtls_time_t; -#endif /* MBEDTLS_PLATFORM_TIME_TYPE_MACRO */ - -/* - * The function pointers for time - */ -#if defined(MBEDTLS_PLATFORM_TIME_ALT) -extern mbedtls_time_t (*mbedtls_time)( mbedtls_time_t* time ); - -/** - * \brief Set your own time function pointer - * - * \param time_func the time function implementation - * - * \return 0 - */ -int mbedtls_platform_set_time( mbedtls_time_t (*time_func)( mbedtls_time_t* time ) ); -#else -#if defined(MBEDTLS_PLATFORM_TIME_MACRO) -#define mbedtls_time MBEDTLS_PLATFORM_TIME_MACRO -#else -#define mbedtls_time time -#endif /* MBEDTLS_PLATFORM_TIME_MACRO */ -#endif /* MBEDTLS_PLATFORM_TIME_ALT */ - /* * The function pointers for reading from and writing a seed file to * Non-Volatile storage (NV) in a platform-independent way diff --git a/features/mbedtls/inc/mbedtls/platform_time.h b/features/mbedtls/inc/mbedtls/platform_time.h new file mode 100644 index 0000000000..abb3431420 --- /dev/null +++ b/features/mbedtls/inc/mbedtls/platform_time.h @@ -0,0 +1,81 @@ +/** + * \file platform_time.h + * + * \brief mbed TLS Platform time abstraction + * + * Copyright (C) 2006-2016, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ +#ifndef MBEDTLS_PLATFORM_TIME_H +#define MBEDTLS_PLATFORM_TIME_H + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \name SECTION: Module settings + * + * The configuration options you can set for this module are in this section. + * Either change them in config.h or define them on the compiler command line. + * \{ + */ + +/* + * The time_t datatype + */ +#if defined(MBEDTLS_PLATFORM_TIME_TYPE_MACRO) +typedef MBEDTLS_PLATFORM_TIME_TYPE_MACRO mbedtls_time_t; +#else +/* For time_t */ +#include +typedef time_t mbedtls_time_t; +#endif /* MBEDTLS_PLATFORM_TIME_TYPE_MACRO */ + +/* + * The function pointers for time + */ +#if defined(MBEDTLS_PLATFORM_TIME_ALT) +extern mbedtls_time_t (*mbedtls_time)( mbedtls_time_t* time ); + +/** + * \brief Set your own time function pointer + * + * \param time_func the time function implementation + * + * \return 0 + */ +int mbedtls_platform_set_time( mbedtls_time_t (*time_func)( mbedtls_time_t* time ) ); +#else +#if defined(MBEDTLS_PLATFORM_TIME_MACRO) +#define mbedtls_time MBEDTLS_PLATFORM_TIME_MACRO +#else +#define mbedtls_time time +#endif /* MBEDTLS_PLATFORM_TIME_MACRO */ +#endif /* MBEDTLS_PLATFORM_TIME_ALT */ + +#ifdef __cplusplus +} +#endif + +#endif /* platform_time.h */ diff --git a/features/mbedtls/inc/mbedtls/rsa.h b/features/mbedtls/inc/mbedtls/rsa.h index 9c8645df69..35185dfda1 100644 --- a/features/mbedtls/inc/mbedtls/rsa.h +++ b/features/mbedtls/inc/mbedtls/rsa.h @@ -99,7 +99,7 @@ typedef struct mbedtls_mpi Vf; /*!< cached un-blinding value */ int padding; /*!< MBEDTLS_RSA_PKCS_V15 for 1.5 padding and - RSA_PKCS_v21 for OAEP/PSS */ + MBEDTLS_RSA_PKCS_v21 for OAEP/PSS */ int hash_id; /*!< Hash identifier of mbedtls_md_type_t as specified in the mbedtls_md.h header file for the EME-OAEP and EMSA-PSS diff --git a/features/mbedtls/inc/mbedtls/ssl.h b/features/mbedtls/inc/mbedtls/ssl.h index 82c07607f5..1c0513da7f 100644 --- a/features/mbedtls/inc/mbedtls/ssl.h +++ b/features/mbedtls/inc/mbedtls/ssl.h @@ -52,7 +52,7 @@ #endif #if defined(MBEDTLS_HAVE_TIME) -#include +#include "mbedtls/platform_time.h" #endif /* @@ -1105,9 +1105,10 @@ void mbedtls_ssl_conf_dbg( mbedtls_ssl_config *conf, * \c mbedtls_ssl_recv_t and \c mbedtls_ssl_recv_timeout_t for * the conventions those callbacks must follow. * - * \note On some platforms, net.c provides \c mbedtls_net_send(), - * \c mbedtls_net_recv() and \c mbedtls_net_recv_timeout() - * that are suitable to be used here. + * \note On some platforms, net_sockets.c provides + * \c mbedtls_net_send(), \c mbedtls_net_recv() and + * \c mbedtls_net_recv_timeout() that are suitable to be used + * here. */ void mbedtls_ssl_set_bio( mbedtls_ssl_context *ssl, void *p_bio, diff --git a/features/mbedtls/inc/mbedtls/x509_crt.h b/features/mbedtls/inc/mbedtls/x509_crt.h index 41b6bfe57e..383e484f71 100644 --- a/features/mbedtls/inc/mbedtls/x509_crt.h +++ b/features/mbedtls/inc/mbedtls/x509_crt.h @@ -120,6 +120,10 @@ mbedtls_x509_crt_profile; #define MBEDTLS_X509_RFC5280_MAX_SERIAL_LEN 32 #define MBEDTLS_X509_RFC5280_UTC_TIME_LEN 15 +#if !defined( MBEDTLS_X509_MAX_FILE_PATH_LEN ) +#define MBEDTLS_X509_MAX_FILE_PATH_LEN 512 +#endif + /** * Container for writing a certificate (CRT) */ diff --git a/features/mbedtls/platform/inc/platform_mbed.h b/features/mbedtls/platform/inc/platform_mbed.h new file mode 100644 index 0000000000..53b2fca16a --- /dev/null +++ b/features/mbedtls/platform/inc/platform_mbed.h @@ -0,0 +1,22 @@ +/** + * Copyright (C) 2006-2016, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ + +#if defined(DEVICE_TRNG) +#define MBEDTLS_ENTROPY_HARDWARE_ALT +#endif diff --git a/features/mbedtls/platform/src/mbed_trng.c b/features/mbedtls/platform/src/mbed_trng.c new file mode 100644 index 0000000000..e5a1cbbe1f --- /dev/null +++ b/features/mbedtls/platform/src/mbed_trng.c @@ -0,0 +1,29 @@ +/* mbed Microcontroller Library + * Copyright (c) 2016 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#if defined(DEVICE_TRNG) + +#include "hal/trng_api.h" + +int mbedtls_hardware_poll( void *data, unsigned char *output, size_t len, size_t *olen ) { + trng_t trng_obj; + trng_init(&trng_obj); + int ret = trng_get_bytes(&trng_obj, output, len, olen); + trng_free(&trng_obj); + return ret; +} + +#endif diff --git a/features/mbedtls/src/Makefile b/features/mbedtls/src/Makefile index 00528b3c86..4b296282b7 100644 --- a/features/mbedtls/src/Makefile +++ b/features/mbedtls/src/Makefile @@ -68,9 +68,10 @@ OBJS_X509= certs.o pkcs11.o x509.o \ x509_create.o x509_crl.o x509_crt.o \ x509_csr.o x509write_crt.o x509write_csr.o -OBJS_TLS= debug.o net.o ssl_cache.o \ - ssl_ciphersuites.o ssl_cli.o \ - ssl_cookie.o ssl_srv.o ssl_ticket.o \ +OBJS_TLS= debug.o net_sockets.o \ + ssl_cache.o ssl_ciphersuites.o \ + ssl_cli.o ssl_cookie.o \ + ssl_srv.o ssl_ticket.o \ ssl_tls.o .SILENT: diff --git a/features/mbedtls/src/asn1write.c b/features/mbedtls/src/asn1write.c index 027c858e7a..69b61b205f 100644 --- a/features/mbedtls/src/asn1write.c +++ b/features/mbedtls/src/asn1write.c @@ -60,16 +60,43 @@ int mbedtls_asn1_write_len( unsigned char **p, unsigned char *start, size_t len return( 2 ); } - if( *p - start < 3 ) - return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); + if( len <= 0xFFFF ) + { + if( *p - start < 3 ) + return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); - // We assume we never have lengths larger than 65535 bytes - // - *--(*p) = len % 256; - *--(*p) = ( len / 256 ) % 256; - *--(*p) = 0x82; + *--(*p) = ( len ) & 0xFF; + *--(*p) = ( len >> 8 ) & 0xFF; + *--(*p) = 0x82; + return( 3 ); + } - return( 3 ); + if( len <= 0xFFFFFF ) + { + if( *p - start < 4 ) + return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); + + *--(*p) = ( len ) & 0xFF; + *--(*p) = ( len >> 8 ) & 0xFF; + *--(*p) = ( len >> 16 ) & 0xFF; + *--(*p) = 0x83; + return( 4 ); + } + + if( len <= 0xFFFFFFFF ) + { + if( *p - start < 5 ) + return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); + + *--(*p) = ( len ) & 0xFF; + *--(*p) = ( len >> 8 ) & 0xFF; + *--(*p) = ( len >> 16 ) & 0xFF; + *--(*p) = ( len >> 24 ) & 0xFF; + *--(*p) = 0x84; + return( 5 ); + } + + return( MBEDTLS_ERR_ASN1_INVALID_LENGTH ); } int mbedtls_asn1_write_tag( unsigned char **p, unsigned char *start, unsigned char tag ) diff --git a/features/mbedtls/src/entropy.c b/features/mbedtls/src/entropy.c index 45c894b1df..d4d1b27b7f 100644 --- a/features/mbedtls/src/entropy.c +++ b/features/mbedtls/src/entropy.c @@ -42,6 +42,10 @@ #include #endif +#if defined(MBEDTLS_ENTROPY_NV_SEED) +#include "mbedtls/platform.h" +#endif + #if defined(MBEDTLS_SELF_TEST) #if defined(MBEDTLS_PLATFORM_C) #include "mbedtls/platform.h" @@ -452,6 +456,7 @@ int mbedtls_entropy_update_seed_file( mbedtls_entropy_context *ctx, const char * #endif /* MBEDTLS_FS_IO */ #if defined(MBEDTLS_SELF_TEST) +#if !defined(MBEDTLS_TEST_NULL_ENTROPY) /* * Dummy source function */ @@ -465,6 +470,105 @@ static int entropy_dummy_source( void *data, unsigned char *output, return( 0 ); } +#endif /* !MBEDTLS_TEST_NULL_ENTROPY */ + +#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT) + +static int mbedtls_entropy_source_self_test_gather( unsigned char *buf, size_t buf_len ) +{ + int ret = 0; + size_t entropy_len = 0; + size_t olen = 0; + size_t attempts = buf_len; + + while( attempts > 0 && entropy_len < buf_len ) + { + if( ( ret = mbedtls_hardware_poll( NULL, buf + entropy_len, + buf_len - entropy_len, &olen ) ) != 0 ) + return( ret ); + + entropy_len += olen; + attempts--; + } + + if( entropy_len < buf_len ) + { + ret = 1; + } + + return( ret ); +} + + +static int mbedtls_entropy_source_self_test_check_bits( const unsigned char *buf, + size_t buf_len ) +{ + unsigned char set= 0xFF; + unsigned char unset = 0x00; + size_t i; + + for( i = 0; i < buf_len; i++ ) + { + set &= buf[i]; + unset |= buf[i]; + } + + return( set == 0xFF || unset == 0x00 ); +} + +/* + * A test to ensure hat the entropy sources are functioning correctly + * and there is no obvious failure. The test performs the following checks: + * - The entropy source is not providing only 0s (all bits unset) or 1s (all + * bits set). + * - The entropy source is not providing values in a pattern. Because the + * hardware could be providing data in an arbitrary length, this check polls + * the hardware entropy source twice and compares the result to ensure they + * are not equal. + * - The error code returned by the entropy source is not an error. + */ +int mbedtls_entropy_source_self_test( int verbose ) +{ + int ret = 0; + unsigned char buf0[2 * sizeof( unsigned long long int )]; + unsigned char buf1[2 * sizeof( unsigned long long int )]; + + if( verbose != 0 ) + mbedtls_printf( " ENTROPY_BIAS test: " ); + + memset( buf0, 0x00, sizeof( buf0 ) ); + memset( buf1, 0x00, sizeof( buf1 ) ); + + if( ( ret = mbedtls_entropy_source_self_test_gather( buf0, sizeof( buf0 ) ) ) != 0 ) + goto cleanup; + if( ( ret = mbedtls_entropy_source_self_test_gather( buf1, sizeof( buf1 ) ) ) != 0 ) + goto cleanup; + + /* Make sure that the returned values are not all 0 or 1 */ + if( ( ret = mbedtls_entropy_source_self_test_check_bits( buf0, sizeof( buf0 ) ) ) != 0 ) + goto cleanup; + if( ( ret = mbedtls_entropy_source_self_test_check_bits( buf1, sizeof( buf1 ) ) ) != 0 ) + goto cleanup; + + /* Make sure that the entropy source is not returning values in a + * pattern */ + ret = memcmp( buf0, buf1, sizeof( buf0 ) ) == 0; + +cleanup: + if( verbose != 0 ) + { + if( ret != 0 ) + mbedtls_printf( "failed\n" ); + else + mbedtls_printf( "passed\n" ); + + mbedtls_printf( "\n" ); + } + + return( ret != 0 ); +} + +#endif /* MBEDTLS_ENTROPY_HARDWARE_ALT */ /* * The actual entropy quality is hard to test, but we can at least @@ -473,15 +577,18 @@ static int entropy_dummy_source( void *data, unsigned char *output, */ int mbedtls_entropy_self_test( int verbose ) { - int ret = 0; + int ret = 1; +#if !defined(MBEDTLS_TEST_NULL_ENTROPY) mbedtls_entropy_context ctx; unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE] = { 0 }; unsigned char acc[MBEDTLS_ENTROPY_BLOCK_SIZE] = { 0 }; size_t i, j; +#endif /* !MBEDTLS_TEST_NULL_ENTROPY */ if( verbose != 0 ) mbedtls_printf( " ENTROPY test: " ); +#if !defined(MBEDTLS_TEST_NULL_ENTROPY) mbedtls_entropy_init( &ctx ); /* First do a gather to make sure we have default sources */ @@ -522,8 +629,14 @@ int mbedtls_entropy_self_test( int verbose ) } } +#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT) + if( ( ret = mbedtls_entropy_source_self_test( 0 ) ) != 0 ) + goto cleanup; +#endif + cleanup: mbedtls_entropy_free( &ctx ); +#endif /* !MBEDTLS_TEST_NULL_ENTROPY */ if( verbose != 0 ) { diff --git a/features/mbedtls/src/error.c b/features/mbedtls/src/error.c index 4bd15bfee4..71d4faa708 100644 --- a/features/mbedtls/src/error.c +++ b/features/mbedtls/src/error.c @@ -102,7 +102,7 @@ #endif #if defined(MBEDTLS_NET_C) -#include "mbedtls/net.h" +#include "mbedtls/net_sockets.h" #endif #if defined(MBEDTLS_OID_C) diff --git a/features/mbedtls/src/net.c b/features/mbedtls/src/net_sockets.c similarity index 99% rename from features/mbedtls/src/net.c rename to features/mbedtls/src/net_sockets.c index 4142bc061e..cc06cbfad3 100644 --- a/features/mbedtls/src/net.c +++ b/features/mbedtls/src/net_sockets.c @@ -36,10 +36,9 @@ #include "mbedtls/platform.h" #else #include -#define mbedtls_time_t time_t #endif -#include "mbedtls/net.h" +#include "mbedtls/net_sockets.h" #include diff --git a/features/mbedtls/src/oid.c b/features/mbedtls/src/oid.c index c71cd9bc1b..f13826ed74 100644 --- a/features/mbedtls/src/oid.c +++ b/features/mbedtls/src/oid.c @@ -152,6 +152,7 @@ int FN_NAME( ATTR1_TYPE ATTR1, ATTR2_TYPE ATTR2, const char **oid , \ return( MBEDTLS_ERR_OID_NOT_FOUND ); \ } +#if defined(MBEDTLS_X509_USE_C) || defined(MBEDTLS_X509_CREATE_C) /* * For X520 attribute types */ @@ -247,7 +248,6 @@ static const oid_x520_attr_t oid_x520_attr_type[] = FN_OID_TYPED_FROM_ASN1(oid_x520_attr_t, x520_attr, oid_x520_attr_type) FN_OID_GET_ATTR1(mbedtls_oid_get_attr_short_name, oid_x520_attr_t, x520_attr, const char *, short_name) -#if defined(MBEDTLS_X509_USE_C) || defined(MBEDTLS_X509_CREATE_C) /* * For X509 extensions */ @@ -314,22 +314,32 @@ typedef struct { static const oid_sig_alg_t oid_sig_alg[] = { +#if defined(MBEDTLS_RSA_C) +#if defined(MBEDTLS_MD2_C) { { ADD_LEN( MBEDTLS_OID_PKCS1_MD2 ), "md2WithRSAEncryption", "RSA with MD2" }, MBEDTLS_MD_MD2, MBEDTLS_PK_RSA, }, +#endif /* MBEDTLS_MD2_C */ +#if defined(MBEDTLS_MD4_C) { { ADD_LEN( MBEDTLS_OID_PKCS1_MD4 ), "md4WithRSAEncryption", "RSA with MD4" }, MBEDTLS_MD_MD4, MBEDTLS_PK_RSA, }, +#endif /* MBEDTLS_MD4_C */ +#if defined(MBEDTLS_MD5_C) { { ADD_LEN( MBEDTLS_OID_PKCS1_MD5 ), "md5WithRSAEncryption", "RSA with MD5" }, MBEDTLS_MD_MD5, MBEDTLS_PK_RSA, }, +#endif /* MBEDTLS_MD5_C */ +#if defined(MBEDTLS_SHA1_C) { { ADD_LEN( MBEDTLS_OID_PKCS1_SHA1 ), "sha-1WithRSAEncryption", "RSA with SHA1" }, MBEDTLS_MD_SHA1, MBEDTLS_PK_RSA, }, +#endif /* MBEDTLS_SHA1_C */ +#if defined(MBEDTLS_SHA256_C) { { ADD_LEN( MBEDTLS_OID_PKCS1_SHA224 ), "sha224WithRSAEncryption", "RSA with SHA-224" }, MBEDTLS_MD_SHA224, MBEDTLS_PK_RSA, @@ -338,6 +348,8 @@ static const oid_sig_alg_t oid_sig_alg[] = { ADD_LEN( MBEDTLS_OID_PKCS1_SHA256 ), "sha256WithRSAEncryption", "RSA with SHA-256" }, MBEDTLS_MD_SHA256, MBEDTLS_PK_RSA, }, +#endif /* MBEDTLS_SHA256_C */ +#if defined(MBEDTLS_SHA512_C) { { ADD_LEN( MBEDTLS_OID_PKCS1_SHA384 ), "sha384WithRSAEncryption", "RSA with SHA-384" }, MBEDTLS_MD_SHA384, MBEDTLS_PK_RSA, @@ -346,14 +358,22 @@ static const oid_sig_alg_t oid_sig_alg[] = { ADD_LEN( MBEDTLS_OID_PKCS1_SHA512 ), "sha512WithRSAEncryption", "RSA with SHA-512" }, MBEDTLS_MD_SHA512, MBEDTLS_PK_RSA, }, +#endif /* MBEDTLS_SHA512_C */ +#if defined(MBEDTLS_SHA1_C) { { ADD_LEN( MBEDTLS_OID_RSA_SHA_OBS ), "sha-1WithRSAEncryption", "RSA with SHA1" }, MBEDTLS_MD_SHA1, MBEDTLS_PK_RSA, }, +#endif /* MBEDTLS_SHA1_C */ +#endif /* MBEDTLS_RSA_C */ +#if defined(MBEDTLS_ECDSA_C) +#if defined(MBEDTLS_SHA1_C) { { ADD_LEN( MBEDTLS_OID_ECDSA_SHA1 ), "ecdsa-with-SHA1", "ECDSA with SHA1" }, MBEDTLS_MD_SHA1, MBEDTLS_PK_ECDSA, }, +#endif /* MBEDTLS_SHA1_C */ +#if defined(MBEDTLS_SHA256_C) { { ADD_LEN( MBEDTLS_OID_ECDSA_SHA224 ), "ecdsa-with-SHA224", "ECDSA with SHA224" }, MBEDTLS_MD_SHA224, MBEDTLS_PK_ECDSA, @@ -362,6 +382,8 @@ static const oid_sig_alg_t oid_sig_alg[] = { ADD_LEN( MBEDTLS_OID_ECDSA_SHA256 ), "ecdsa-with-SHA256", "ECDSA with SHA256" }, MBEDTLS_MD_SHA256, MBEDTLS_PK_ECDSA, }, +#endif /* MBEDTLS_SHA256_C */ +#if defined(MBEDTLS_SHA512_C) { { ADD_LEN( MBEDTLS_OID_ECDSA_SHA384 ), "ecdsa-with-SHA384", "ECDSA with SHA384" }, MBEDTLS_MD_SHA384, MBEDTLS_PK_ECDSA, @@ -370,10 +392,14 @@ static const oid_sig_alg_t oid_sig_alg[] = { ADD_LEN( MBEDTLS_OID_ECDSA_SHA512 ), "ecdsa-with-SHA512", "ECDSA with SHA512" }, MBEDTLS_MD_SHA512, MBEDTLS_PK_ECDSA, }, +#endif /* MBEDTLS_SHA512_C */ +#endif /* MBEDTLS_ECDSA_C */ +#if defined(MBEDTLS_RSA_C) { { ADD_LEN( MBEDTLS_OID_RSASSA_PSS ), "RSASSA-PSS", "RSASSA-PSS" }, MBEDTLS_MD_NONE, MBEDTLS_PK_RSASSA_PSS, }, +#endif /* MBEDTLS_RSA_C */ { { NULL, 0, NULL, NULL }, MBEDTLS_MD_NONE, MBEDTLS_PK_NONE, @@ -429,50 +455,72 @@ typedef struct { static const oid_ecp_grp_t oid_ecp_grp[] = { +#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) { { ADD_LEN( MBEDTLS_OID_EC_GRP_SECP192R1 ), "secp192r1", "secp192r1" }, MBEDTLS_ECP_DP_SECP192R1, }, +#endif /* MBEDTLS_ECP_DP_SECP192R1_ENABLED */ +#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) { { ADD_LEN( MBEDTLS_OID_EC_GRP_SECP224R1 ), "secp224r1", "secp224r1" }, MBEDTLS_ECP_DP_SECP224R1, }, +#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED */ +#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) { { ADD_LEN( MBEDTLS_OID_EC_GRP_SECP256R1 ), "secp256r1", "secp256r1" }, MBEDTLS_ECP_DP_SECP256R1, }, +#endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED */ +#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) { { ADD_LEN( MBEDTLS_OID_EC_GRP_SECP384R1 ), "secp384r1", "secp384r1" }, MBEDTLS_ECP_DP_SECP384R1, }, +#endif /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */ +#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) { { ADD_LEN( MBEDTLS_OID_EC_GRP_SECP521R1 ), "secp521r1", "secp521r1" }, MBEDTLS_ECP_DP_SECP521R1, }, +#endif /* MBEDTLS_ECP_DP_SECP521R1_ENABLED */ +#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) { { ADD_LEN( MBEDTLS_OID_EC_GRP_SECP192K1 ), "secp192k1", "secp192k1" }, MBEDTLS_ECP_DP_SECP192K1, }, +#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */ +#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) { { ADD_LEN( MBEDTLS_OID_EC_GRP_SECP224K1 ), "secp224k1", "secp224k1" }, MBEDTLS_ECP_DP_SECP224K1, }, +#endif /* MBEDTLS_ECP_DP_SECP224K1_ENABLED */ +#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) { { ADD_LEN( MBEDTLS_OID_EC_GRP_SECP256K1 ), "secp256k1", "secp256k1" }, MBEDTLS_ECP_DP_SECP256K1, }, +#endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */ +#if defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) { { ADD_LEN( MBEDTLS_OID_EC_GRP_BP256R1 ), "brainpoolP256r1","brainpool256r1" }, MBEDTLS_ECP_DP_BP256R1, }, +#endif /* MBEDTLS_ECP_DP_BP256R1_ENABLED */ +#if defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) { { ADD_LEN( MBEDTLS_OID_EC_GRP_BP384R1 ), "brainpoolP384r1","brainpool384r1" }, MBEDTLS_ECP_DP_BP384R1, }, +#endif /* MBEDTLS_ECP_DP_BP384R1_ENABLED */ +#if defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) { { ADD_LEN( MBEDTLS_OID_EC_GRP_BP512R1 ), "brainpoolP512r1","brainpool512r1" }, MBEDTLS_ECP_DP_BP512R1, }, +#endif /* MBEDTLS_ECP_DP_BP512R1_ENABLED */ { { NULL, 0, NULL, NULL }, MBEDTLS_ECP_DP_NONE, @@ -524,22 +572,31 @@ typedef struct { static const oid_md_alg_t oid_md_alg[] = { +#if defined(MBEDTLS_MD2_C) { { ADD_LEN( MBEDTLS_OID_DIGEST_ALG_MD2 ), "id-md2", "MD2" }, MBEDTLS_MD_MD2, }, +#endif /* MBEDTLS_MD2_C */ +#if defined(MBEDTLS_MD4_C) { { ADD_LEN( MBEDTLS_OID_DIGEST_ALG_MD4 ), "id-md4", "MD4" }, MBEDTLS_MD_MD4, }, +#endif /* MBEDTLS_MD4_C */ +#if defined(MBEDTLS_MD5_C) { { ADD_LEN( MBEDTLS_OID_DIGEST_ALG_MD5 ), "id-md5", "MD5" }, MBEDTLS_MD_MD5, }, +#endif /* MBEDTLS_MD5_C */ +#if defined(MBEDTLS_SHA1_C) { { ADD_LEN( MBEDTLS_OID_DIGEST_ALG_SHA1 ), "id-sha1", "SHA-1" }, MBEDTLS_MD_SHA1, }, +#endif /* MBEDTLS_SHA1_C */ +#if defined(MBEDTLS_SHA256_C) { { ADD_LEN( MBEDTLS_OID_DIGEST_ALG_SHA224 ), "id-sha224", "SHA-224" }, MBEDTLS_MD_SHA224, @@ -548,6 +605,8 @@ static const oid_md_alg_t oid_md_alg[] = { ADD_LEN( MBEDTLS_OID_DIGEST_ALG_SHA256 ), "id-sha256", "SHA-256" }, MBEDTLS_MD_SHA256, }, +#endif /* MBEDTLS_SHA256_C */ +#if defined(MBEDTLS_SHA512_C) { { ADD_LEN( MBEDTLS_OID_DIGEST_ALG_SHA384 ), "id-sha384", "SHA-384" }, MBEDTLS_MD_SHA384, @@ -556,6 +615,7 @@ static const oid_md_alg_t oid_md_alg[] = { ADD_LEN( MBEDTLS_OID_DIGEST_ALG_SHA512 ), "id-sha512", "SHA-512" }, MBEDTLS_MD_SHA512, }, +#endif /* MBEDTLS_SHA512_C */ { { NULL, 0, NULL, NULL }, MBEDTLS_MD_NONE, diff --git a/features/mbedtls/src/pkcs5.c b/features/mbedtls/src/pkcs5.c index 44af9869b1..e28d5a8473 100644 --- a/features/mbedtls/src/pkcs5.c +++ b/features/mbedtls/src/pkcs5.c @@ -391,7 +391,8 @@ int mbedtls_pkcs5_self_test( int verbose ) mbedtls_printf( "passed\n" ); } - mbedtls_printf( "\n" ); + if( verbose != 0 ) + mbedtls_printf( "\n" ); exit: mbedtls_md_free( &sha1_ctx ); diff --git a/features/mbedtls/src/platform.c b/features/mbedtls/src/platform.c index 68ca45d10b..2591c45d75 100644 --- a/features/mbedtls/src/platform.c +++ b/features/mbedtls/src/platform.c @@ -190,6 +190,8 @@ int mbedtls_platform_set_exit( void (*exit_func)( int status ) ) } #endif /* MBEDTLS_PLATFORM_EXIT_ALT */ +#if defined(MBEDTLS_HAVE_TIME) + #if defined(MBEDTLS_PLATFORM_TIME_ALT) #if !defined(MBEDTLS_PLATFORM_STD_TIME) /* @@ -213,6 +215,8 @@ int mbedtls_platform_set_time( mbedtls_time_t (*time_func)( mbedtls_time_t* time } #endif /* MBEDTLS_PLATFORM_TIME_ALT */ +#endif /* MBEDTLS_HAVE_TIME */ + #if defined(MBEDTLS_ENTROPY_NV_SEED) #if !defined(MBEDTLS_PLATFORM_NO_STD_FUNCTIONS) && defined(MBEDTLS_FS_IO) /* Default implementations for the platform independent seed functions use diff --git a/features/mbedtls/src/ripemd160.c b/features/mbedtls/src/ripemd160.c index a55cc3eb41..cdb0a63c0f 100644 --- a/features/mbedtls/src/ripemd160.c +++ b/features/mbedtls/src/ripemd160.c @@ -456,6 +456,9 @@ int mbedtls_ripemd160_self_test( int verbose ) mbedtls_printf( "passed\n" ); } + if( verbose != 0 ) + mbedtls_printf( "\n" ); + return( 0 ); } diff --git a/features/mbedtls/src/ssl_cache.c b/features/mbedtls/src/ssl_cache.c index 01c66aed14..9b62de2dcc 100644 --- a/features/mbedtls/src/ssl_cache.c +++ b/features/mbedtls/src/ssl_cache.c @@ -37,8 +37,6 @@ #include #define mbedtls_calloc calloc #define mbedtls_free free -#define mbedtls_time time -#define mbedtls_time_t time_t #endif #include "mbedtls/ssl_cache.h" diff --git a/features/mbedtls/src/ssl_ciphersuites.c b/features/mbedtls/src/ssl_ciphersuites.c index 35463317fd..a762bf7c4f 100644 --- a/features/mbedtls/src/ssl_ciphersuites.c +++ b/features/mbedtls/src/ssl_ciphersuites.c @@ -33,7 +33,6 @@ #include "mbedtls/platform.h" #else #include -#define mbedtls_time_t time_t #endif #include "mbedtls/ssl_ciphersuites.h" diff --git a/features/mbedtls/src/ssl_cli.c b/features/mbedtls/src/ssl_cli.c index cd39db027e..29a3943584 100644 --- a/features/mbedtls/src/ssl_cli.c +++ b/features/mbedtls/src/ssl_cli.c @@ -33,8 +33,6 @@ #include #define mbedtls_calloc calloc #define mbedtls_free free -#define mbedtls_time time -#define mbedtls_time_t time_t #endif #include "mbedtls/debug.h" @@ -46,7 +44,7 @@ #include #if defined(MBEDTLS_HAVE_TIME) -#include +#include "mbedtls/platform_time.h" #endif #if defined(MBEDTLS_SSL_SESSION_TICKETS) @@ -2513,7 +2511,9 @@ exit: #if !defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) && \ !defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) && \ + !defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) && \ !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) && \ + !defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)&& \ !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl ) { @@ -2659,7 +2659,9 @@ exit: } #endif /* !MBEDTLS_KEY_EXCHANGE_RSA_ENABLED && !MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED && + !MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED && !MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED && + !MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED && !MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */ static int ssl_parse_server_hello_done( mbedtls_ssl_context *ssl ) @@ -2961,7 +2963,9 @@ static int ssl_write_client_key_exchange( mbedtls_ssl_context *ssl ) #if !defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) && \ !defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) && \ + !defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) && \ !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) && \ + !defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)&& \ !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) static int ssl_write_certificate_verify( mbedtls_ssl_context *ssl ) { @@ -3141,7 +3145,10 @@ static int ssl_write_certificate_verify( mbedtls_ssl_context *ssl ) } #endif /* !MBEDTLS_KEY_EXCHANGE_RSA_ENABLED && !MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED && - !MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED */ + !MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED && + !MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED && + !MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED && + !MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */ #if defined(MBEDTLS_SSL_SESSION_TICKETS) static int ssl_parse_new_session_ticket( mbedtls_ssl_context *ssl ) diff --git a/features/mbedtls/src/ssl_cookie.c b/features/mbedtls/src/ssl_cookie.c index f241c86d8c..9fb32de7a6 100644 --- a/features/mbedtls/src/ssl_cookie.c +++ b/features/mbedtls/src/ssl_cookie.c @@ -36,8 +36,6 @@ #else #define mbedtls_calloc calloc #define mbedtls_free free -#define mbedtls_time time -#define mbedtls_time_t time_t #endif #include "mbedtls/ssl_cookie.h" diff --git a/features/mbedtls/src/ssl_srv.c b/features/mbedtls/src/ssl_srv.c index 7271045297..4b0f997143 100644 --- a/features/mbedtls/src/ssl_srv.c +++ b/features/mbedtls/src/ssl_srv.c @@ -33,8 +33,6 @@ #include #define mbedtls_calloc calloc #define mbedtls_free free -#define mbedtls_time time -#define mbedtls_time_t time_t #endif #include "mbedtls/debug.h" @@ -48,7 +46,7 @@ #endif #if defined(MBEDTLS_HAVE_TIME) -#include +#include "mbedtls/platform_time.h" #endif #if defined(MBEDTLS_SSL_SESSION_TICKETS) @@ -2450,7 +2448,9 @@ static int ssl_write_server_hello( mbedtls_ssl_context *ssl ) #if !defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) && \ !defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) && \ + !defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) && \ !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) && \ + !defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)&& \ !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) static int ssl_write_certificate_request( mbedtls_ssl_context *ssl ) { @@ -2637,7 +2637,9 @@ static int ssl_write_certificate_request( mbedtls_ssl_context *ssl ) } #endif /* !MBEDTLS_KEY_EXCHANGE_RSA_ENABLED && !MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED && + !MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED && !MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED && + !MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED && !MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */ #if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ @@ -3527,7 +3529,9 @@ static int ssl_parse_client_key_exchange( mbedtls_ssl_context *ssl ) #if !defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) && \ !defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) && \ + !defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) && \ !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) && \ + !defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)&& \ !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl ) { @@ -3706,7 +3710,10 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl ) } #endif /* !MBEDTLS_KEY_EXCHANGE_RSA_ENABLED && !MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED && - !MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED */ + !MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED && + !MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED && + !MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED && + !MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */ #if defined(MBEDTLS_SSL_SESSION_TICKETS) static int ssl_write_new_session_ticket( mbedtls_ssl_context *ssl ) diff --git a/features/mbedtls/src/ssl_ticket.c b/features/mbedtls/src/ssl_ticket.c index 5d77403e55..4d9116d214 100644 --- a/features/mbedtls/src/ssl_ticket.c +++ b/features/mbedtls/src/ssl_ticket.c @@ -33,8 +33,6 @@ #include #define mbedtls_calloc calloc #define mbedtls_free free -#define mbedtls_time time -#define mbedtls_time_t time_t #endif #include "mbedtls/ssl_ticket.h" diff --git a/features/mbedtls/src/ssl_tls.c b/features/mbedtls/src/ssl_tls.c index 80a908d9c5..505bb6cb3a 100644 --- a/features/mbedtls/src/ssl_tls.c +++ b/features/mbedtls/src/ssl_tls.c @@ -41,7 +41,6 @@ #include #define mbedtls_calloc calloc #define mbedtls_free free -#define mbedtls_time_t time_t #endif #include "mbedtls/debug.h" diff --git a/features/mbedtls/src/x509.c b/features/mbedtls/src/x509.c index a0df817081..bc3bfe018f 100644 --- a/features/mbedtls/src/x509.c +++ b/features/mbedtls/src/x509.c @@ -55,12 +55,15 @@ #include #define mbedtls_free free #define mbedtls_calloc calloc -#define mbedtls_time time -#define mbedtls_time_t time_t #define mbedtls_printf printf #define mbedtls_snprintf snprintf #endif + +#if defined(MBEDTLS_HAVE_TIME) +#include "mbedtls/platform_time.h" +#endif + #if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) #include #else diff --git a/features/mbedtls/src/x509_crt.c b/features/mbedtls/src/x509_crt.c index af6c2a4a53..60e14f90e7 100644 --- a/features/mbedtls/src/x509_crt.c +++ b/features/mbedtls/src/x509_crt.c @@ -1160,9 +1160,10 @@ int mbedtls_x509_crt_parse_path( mbedtls_x509_crt *chain, const char *path ) FindClose( hFind ); #else /* _WIN32 */ int t_ret; + int snp_ret; struct stat sb; struct dirent *entry; - char entry_name[255]; + char entry_name[MBEDTLS_X509_MAX_FILE_PATH_LEN]; DIR *dir = opendir( path ); if( dir == NULL ) @@ -1178,11 +1179,16 @@ int mbedtls_x509_crt_parse_path( mbedtls_x509_crt *chain, const char *path ) while( ( entry = readdir( dir ) ) != NULL ) { - mbedtls_snprintf( entry_name, sizeof entry_name, "%s/%s", path, entry->d_name ); + snp_ret = mbedtls_snprintf( entry_name, sizeof entry_name, + "%s/%s", path, entry->d_name ); - if( stat( entry_name, &sb ) == -1 ) + if( snp_ret < 0 || (size_t)snp_ret >= sizeof entry_name ) + { + ret = MBEDTLS_ERR_X509_BUFFER_TOO_SMALL; + goto cleanup; + } + else if( stat( entry_name, &sb ) == -1 ) { - closedir( dir ); ret = MBEDTLS_ERR_X509_FILE_IO_ERROR; goto cleanup; } @@ -1198,9 +1204,10 @@ int mbedtls_x509_crt_parse_path( mbedtls_x509_crt *chain, const char *path ) else ret += t_ret; } - closedir( dir ); cleanup: + closedir( dir ); + #if defined(MBEDTLS_THREADING_PTHREAD) if( mbedtls_mutex_unlock( &mbedtls_threading_readdir_mutex ) != 0 ) ret = MBEDTLS_ERR_THREADING_MUTEX_ERROR; diff --git a/features/net/FEATURE_IPV4/lwip-interface/.mbedignore b/features/net/FEATURE_IPV4/lwip-interface/.mbedignore new file mode 100644 index 0000000000..13aba88ae4 --- /dev/null +++ b/features/net/FEATURE_IPV4/lwip-interface/.mbedignore @@ -0,0 +1,7 @@ +lwip/doc/* +lwip/test/* +lwip/src/apps/* +lwip/src/netif/ppp/* +lwip/src/netif/lwip_slipif.c +lwip/src/include/lwip/apps/* +lwip/src/include/posix/* diff --git a/features/net/FEATURE_IPV4/lwip-interface/EthernetInterface.cpp b/features/net/FEATURE_IPV4/lwip-interface/EthernetInterface.cpp index 2dfad9f103..125c53b5e0 100644 --- a/features/net/FEATURE_IPV4/lwip-interface/EthernetInterface.cpp +++ b/features/net/FEATURE_IPV4/lwip-interface/EthernetInterface.cpp @@ -59,17 +59,29 @@ const char *EthernetInterface::get_mac_address() const char *EthernetInterface::get_ip_address() { - return lwip_get_ip_address(); + if (lwip_get_ip_address(_ip_address, sizeof _ip_address)) { + return _ip_address; + } + + return 0; } const char *EthernetInterface::get_netmask() { - return lwip_get_netmask(); + if (lwip_get_netmask(_netmask, sizeof _netmask)) { + return _netmask; + } + + return 0; } const char *EthernetInterface::get_gateway() { - return lwip_get_gateway(); + if (lwip_get_gateway(_gateway, sizeof _gateway)) { + return _gateway; + } + + return 0; } NetworkStack *EthernetInterface::get_stack() diff --git a/features/net/FEATURE_IPV4/lwip-interface/EthernetInterface.h b/features/net/FEATURE_IPV4/lwip-interface/EthernetInterface.h index ea20c10548..dfb01950d3 100644 --- a/features/net/FEATURE_IPV4/lwip-interface/EthernetInterface.h +++ b/features/net/FEATURE_IPV4/lwip-interface/EthernetInterface.h @@ -92,7 +92,7 @@ public: */ virtual const char *get_netmask(); - /** Get the local gateway + /** Get the local gateways * * @return Null-terminated representation of the local gateway * or null if no network mask has been recieved @@ -107,7 +107,7 @@ protected: virtual NetworkStack *get_stack(); bool _dhcp; - char _ip_address[NSAPI_IPv4_SIZE]; + char _ip_address[IPADDR_STRLEN_MAX]; char _netmask[NSAPI_IPv4_SIZE]; char _gateway[NSAPI_IPv4_SIZE]; }; diff --git a/features/net/FEATURE_IPV4/lwip-interface/lwip-eth/arch/TARGET_Freescale/k64f_emac.c b/features/net/FEATURE_IPV4/lwip-interface/lwip-eth/arch/TARGET_Freescale/k64f_emac.c index 705db64484..7fb4dcf7e6 100644 --- a/features/net/FEATURE_IPV4/lwip-interface/lwip-eth/arch/TARGET_Freescale/k64f_emac.c +++ b/features/net/FEATURE_IPV4/lwip-interface/lwip-eth/arch/TARGET_Freescale/k64f_emac.c @@ -6,8 +6,11 @@ #include "lwip/stats.h" #include "lwip/snmp.h" #include "lwip/tcpip.h" +#include "lwip/ethip6.h" +#include "lwip/igmp.h" +#include "lwip/mld6.h" #include "netif/etharp.h" -#include "netif/ppp_oe.h" +#include "netif/ppp/pppoe.h" #include "eth_arch.h" #include "sys_arch.h" @@ -236,7 +239,7 @@ static err_t low_level_init(struct netif *netif) /** - * This function is the ethernet packet send function. It calls + * This function is the ipv4 ethernet packet send function. It calls * etharp_output after checking link status. * * \param[in] netif the lwip network interface structure for this enetif @@ -244,14 +247,106 @@ static err_t low_level_init(struct netif *netif) * \param[in] ipaddr IP address * \return ERR_OK or error code */ -err_t k64f_etharp_output(struct netif *netif, struct pbuf *q, ip_addr_t *ipaddr) +#if LWIP_IPV4 +err_t k64f_etharp_output_ipv4(struct netif *netif, struct pbuf *q, const ip4_addr_t *ipaddr) { /* Only send packet is link is up */ - if (netif->flags & NETIF_FLAG_LINK_UP) + if (netif->flags & NETIF_FLAG_LINK_UP) { return etharp_output(netif, q, ipaddr); + } return ERR_CONN; } +#endif + +/** + * This function is the ipv6 ethernet packet send function. It calls + * ethip6_output after checking link status. + * + * \param[in] netif the lwip network interface structure for this enetif + * \param[in] q Pointer to pbug to send + * \param[in] ipaddr IP address + * \return ERR_OK or error code + */ +#if LWIP_IPV6 +err_t k64f_etharp_output_ipv6(struct netif *netif, struct pbuf *q, const ip6_addr_t *ipaddr) +{ + /* Only send packet is link is up */ + if (netif->flags & NETIF_FLAG_LINK_UP) { + return ethip6_output(netif, q, ipaddr); + } + + return ERR_CONN; +} +#endif + +#if LWIP_IGMP +/** + * IPv4 address filtering setup. + * + * \param[in] netif the lwip network interface structure for this enetif + * \param[in] group IPv4 group to modify + * \param[in] action + * \return ERR_OK or error code + */ +err_t igmp_mac_filter(struct netif *netif, const ip4_addr_t *group, u8_t action) +{ + switch (action) { + case IGMP_ADD_MAC_FILTER: + { + uint32_t group23 = ntohl(group->addr) & 0x007FFFFF; + uint8_t addr[6]; + addr[0] = LL_IP4_MULTICAST_ADDR_0; + addr[1] = LL_IP4_MULTICAST_ADDR_1; + addr[2] = LL_IP4_MULTICAST_ADDR_2; + addr[3] = group23 >> 16; + addr[4] = group23 >> 8; + addr[5] = group23; + ENET_AddMulticastGroup(ENET, addr); + return ERR_OK; + } + case IGMP_DEL_MAC_FILTER: + /* As we don't reference count, silently ignore delete requests */ + return ERR_OK; + default: + return ERR_ARG; + } +} +#endif + +#if LWIP_IPV6_MLD +/** + * IPv6 address filtering setup. + * + * \param[in] netif the lwip network interface structure for this enetif + * \param[in] group IPv6 group to modify + * \param[in] action + * \return ERR_OK or error code + */ +err_t mld_mac_filter(struct netif *netif, const ip6_addr_t *group, u8_t action) +{ + switch (action) { + case MLD6_ADD_MAC_FILTER: + { + uint32_t group32 = ntohl(group->addr[3]); + uint8_t addr[6]; + addr[0] = LL_IP6_MULTICAST_ADDR_0; + addr[1] = LL_IP6_MULTICAST_ADDR_1; + addr[2] = group32 >> 24; + addr[3] = group32 >> 16; + addr[4] = group32 >> 8; + addr[5] = group32; + ENET_AddMulticastGroup(ENET, addr); + return ERR_OK; + } + case MLD6_DEL_MAC_FILTER: + /* As we don't reference count, silently ignore delete requests */ + return ERR_OK; + default: + return ERR_ARG; + } +} +#endif /** \brief Allocates a pbuf and returns the data from the incoming packet. * @@ -322,7 +417,7 @@ static struct pbuf *k64f_low_level_input(struct netif *netif, int idx) update_read_buffer(rx_buff[idx]->payload); LWIP_DEBUGF(UDP_LPC_EMAC | LWIP_DBG_TRACE, - ("k64f_low_level_input: Packet received: %p, size %d (index=%d)\n", + ("k64f_low_level_input: Packet received: %p, size %"PRIu32" (index=%d)\n", p, length, idx)); /* Save size */ @@ -344,7 +439,6 @@ static struct pbuf *k64f_low_level_input(struct netif *netif, int idx) */ void k64f_enetif_input(struct netif *netif, int idx) { - struct eth_hdr *ethhdr; struct pbuf *p; /* move received packet into a new pbuf */ @@ -352,28 +446,11 @@ void k64f_enetif_input(struct netif *netif, int idx) if (p == NULL) return; - /* points to packet payload, which starts with an Ethernet header */ - ethhdr = (struct eth_hdr*)p->payload; - - switch (htons(ethhdr->type)) { - case ETHTYPE_IP: - case ETHTYPE_ARP: -#if PPPOE_SUPPORT - case ETHTYPE_PPPOEDISC: - case ETHTYPE_PPPOE: -#endif /* PPPOE_SUPPORT */ - /* full packet send to tcpip_thread to process */ - if (netif->input(p, netif) != ERR_OK) { - LWIP_DEBUGF(NETIF_DEBUG, ("k64f_enetif_input: IP input error\n")); - /* Free buffer */ - pbuf_free(p); - } - break; - - default: - /* Return buffer */ + /* pass all packets to ethernet_input, which decides what packets it supports */ + if (netif->input(p, netif) != ERR_OK) { + LWIP_DEBUGF(NETIF_DEBUG, ("k64f_enetif_input: input error\n")); + /* Free buffer */ pbuf_free(p); - break; } } @@ -432,7 +509,6 @@ static err_t k64f_low_level_output(struct netif *netif, struct pbuf *p) struct pbuf *temp_pbuf; uint8_t *psend = NULL, *dst; - temp_pbuf = pbuf_alloc(PBUF_RAW, p->tot_len + ENET_BUFF_ALIGNMENT, PBUF_RAM); if (NULL == temp_pbuf) return ERR_MEM; @@ -569,14 +645,16 @@ err_t eth_arch_enetif_init(struct netif *netif) #else mbed_mac_address((char *)netif->hwaddr); #endif - netif->hwaddr_len = ETHARP_HWADDR_LEN; + + /* Ethernet address length */ + netif->hwaddr_len = ETH_HWADDR_LEN; /* maximum transfer unit */ netif->mtu = 1500; /* device capabilities */ // TODOETH: check if the flags are correct below - netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_ETHERNET | NETIF_FLAG_IGMP; + netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_ETHERNET; /* Initialize the hardware */ netif->state = &k64f_enetdata; @@ -592,7 +670,23 @@ err_t eth_arch_enetif_init(struct netif *netif) netif->name[0] = 'e'; netif->name[1] = 'n'; - netif->output = k64f_etharp_output; +#if LWIP_IPV4 + netif->output = k64f_etharp_output_ipv4; +#if LWIP_IGMP + netif->igmp_mac_filter = igmp_mac_filter; + netif->flags |= NETIF_FLAG_IGMP; +#endif +#endif +#if LWIP_IPV6 + netif->output_ip6 = k64f_etharp_output_ipv6; +#if LWIP_IPV6_MLD + netif->mld_mac_filter = mld_mac_filter; + netif->flags |= NETIF_FLAG_MLD6; +#else + // Would need to enable all multicasts here - no API in fsl_enet to do that + #error "IPv6 multicasts won't be received if LWIP_IPV6_MLD is disabled, breaking the system" +#endif +#endif netif->linkoutput = k64f_low_level_output; /* CMSIS-RTOS, start tasks */ @@ -610,7 +704,12 @@ err_t eth_arch_enetif_init(struct netif *netif) /* Packet receive task */ err = sys_sem_new(&k64f_enetdata.RxReadySem, 0); LWIP_ASSERT("RxReadySem creation error", (err == ERR_OK)); + +#ifdef LWIP_DEBUG + sys_thread_new("receive_thread", packet_rx, netif->state, DEFAULT_THREAD_STACKSIZE*5, RX_PRIORITY); +#else sys_thread_new("receive_thread", packet_rx, netif->state, DEFAULT_THREAD_STACKSIZE, RX_PRIORITY); +#endif /* Transmit cleanup task */ err = sys_sem_new(&k64f_enetdata.TxCleanSem, 0); diff --git a/features/net/FEATURE_IPV4/lwip-interface/lwip-eth/arch/TARGET_NUVOTON/TARGET_NUC472/nuc472_netif.c b/features/net/FEATURE_IPV4/lwip-interface/lwip-eth/arch/TARGET_NUVOTON/TARGET_NUC472/nuc472_netif.c index 5aaf6853fe..738b141179 100644 --- a/features/net/FEATURE_IPV4/lwip-interface/lwip-eth/arch/TARGET_NUVOTON/TARGET_NUC472/nuc472_netif.c +++ b/features/net/FEATURE_IPV4/lwip-interface/lwip-eth/arch/TARGET_NUVOTON/TARGET_NUC472/nuc472_netif.c @@ -52,7 +52,8 @@ #include #include #include "netif/etharp.h" -#include "netif/ppp_oe.h" +#include "lwip/ethip6.h" +#include "netif/ppp/pppoe.h" #include "nuc472_eth.h" #include "string.h" @@ -129,7 +130,6 @@ void mbed_mac_address(char *mac) } - /** * In this function, the hardware should be initialized. * Called from ethernetif_init(). @@ -142,7 +142,7 @@ low_level_init(struct netif *netif) { /* set MAC hardware address length */ - netif->hwaddr_len = ETHARP_HWADDR_LEN; + netif->hwaddr_len = ETH_HWADDR_LEN; /* set MAC hardware address */ #if 1 // set MAC HW address @@ -174,9 +174,20 @@ low_level_init(struct netif *netif) netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_ETHERNET; #ifdef LWIP_IGMP netif->flags |= NETIF_FLAG_IGMP; +#endif +#if LWIP_IPV6_MLD + netif->flags |= NETIF_FLAG_MLD6; #endif // TODO: enable clock & configure GPIO function ETH_init(netif->hwaddr); + +#if LWIP_IGMP + EMAC_ENABLE_RECV_BCASTPKT(); +#endif + +#if LWIP_IPV6_MLD + EMAC_ENABLE_RECV_MCASTPKT(); +#endif } /** @@ -335,32 +346,11 @@ ethernetif_input(u16_t len, u8_t *buf, u32_t s, u32_t ns) void ethernetif_loopback_input(struct pbuf *p) // TODO: make sure packet not drop in input() { - struct eth_hdr *ethhdr; - - /* points to packet payload, which starts with an Ethernet header */ - ethhdr = p->payload; - - switch (htons(ethhdr->type)) { - /* IP or ARP packet? */ - case ETHTYPE_IP: - case ETHTYPE_ARP: -#if PPPOE_SUPPORT - /* PPPoE packet? */ - case ETHTYPE_PPPOEDISC: - case ETHTYPE_PPPOE: -#endif /* PPPOE_SUPPORT */ - /* full packet send to tcpip_thread to process */ - if (_netif->input(p, _netif)!=ERR_OK) { - LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: IP input error\n")); - pbuf_free(p); - p = NULL; - } - break; - - default: + /* pass all packets to ethernet_input, which decides what packets it supports */ + if (netif->input(p, netif) != ERR_OK) { + LWIP_DEBUGF(NETIF_DEBUG, ("k64f_enetif_input: input error\n")); + /* Free buffer */ pbuf_free(p); - p = NULL; - break; } } @@ -415,7 +405,12 @@ err_t * You can instead declare your own function an call etharp_output() * from it if you have to do some checks before sending (e.g. if link * is available...) */ +#if LWIP_IPV4 netif->output = etharp_output; +#endif +#if LWIP_IPV6 + netif->output_ip6 = ethip6_output; +#endif netif->linkoutput = low_level_output; ethernetif->ethaddr = (struct eth_addr *)&(netif->hwaddr[0]); @@ -523,4 +518,4 @@ static void __packet_rx_task(void *data) { sys_arch_sem_wait(&RxReadySem, 0); EMAC_RX_Action(); } -} \ No newline at end of file +} diff --git a/features/net/FEATURE_IPV4/lwip-interface/lwip-eth/arch/TARGET_NXP/lpc17_emac.c b/features/net/FEATURE_IPV4/lwip-interface/lwip-eth/arch/TARGET_NXP/lpc17_emac.c index 82ad9b951c..99072c0d0e 100644 --- a/features/net/FEATURE_IPV4/lwip-interface/lwip-eth/arch/TARGET_NXP/lpc17_emac.c +++ b/features/net/FEATURE_IPV4/lwip-interface/lwip-eth/arch/TARGET_NXP/lpc17_emac.c @@ -31,7 +31,8 @@ #include "lwip/stats.h" #include "lwip/snmp.h" #include "netif/etharp.h" -#include "netif/ppp_oe.h" +#include "lwip/ethip6.h" +#include "netif/ppp/pppoe.h" #include "lpc17xx_emac.h" #include "eth_arch.h" @@ -409,29 +410,12 @@ void lpc_enetif_input(struct netif *netif) if (p == NULL) return; - /* points to packet payload, which starts with an Ethernet header */ - ethhdr = p->payload; - - switch (htons(ethhdr->type)) { - case ETHTYPE_IP: - case ETHTYPE_ARP: -#if PPPOE_SUPPORT - case ETHTYPE_PPPOEDISC: - case ETHTYPE_PPPOE: -#endif /* PPPOE_SUPPORT */ - /* full packet send to tcpip_thread to process */ - if (netif->input(p, netif) != ERR_OK) { - LWIP_DEBUGF(NETIF_DEBUG, ("lpc_enetif_input: IP input error\n")); - /* Free buffer */ - pbuf_free(p); - } - break; - - default: - /* Return buffer */ - pbuf_free(p); - break; - } + /* full packet send to tcpip_thread to process */ + if (netif->input(p, netif) != ERR_OK) { + LWIP_DEBUGF(NETIF_DEBUG, ("lpc_enetif_input: IP input error\n")); + /* Free buffer */ + pbuf_free(p); + } } /** \brief Determine if the passed address is usable for the ethernet @@ -920,7 +904,7 @@ void lpc_emac_set_speed(int mbs_100) } /** - * This function is the ethernet packet send function. It calls + * This function is the ethernet IPv4 packet send function. It calls * etharp_output after checking link status. * * \param[in] netif the lwip network interface structure for this lpc_enetif @@ -928,8 +912,9 @@ void lpc_emac_set_speed(int mbs_100) * \param[in] ipaddr IP address * \return ERR_OK or error code */ -err_t lpc_etharp_output(struct netif *netif, struct pbuf *q, - ip_addr_t *ipaddr) +#if LWIP_IPV4 +err_t lpc_etharp_output_ipv4(struct netif *netif, struct pbuf *q, + const ip4_addr_t *ipaddr) { /* Only send packet is link is up */ if (netif->flags & NETIF_FLAG_LINK_UP) @@ -937,6 +922,28 @@ err_t lpc_etharp_output(struct netif *netif, struct pbuf *q, return ERR_CONN; } +#endif + +/** + * This function is the ethernet IPv6 packet send function. It calls + * etharp_output after checking link status. + * + * \param[in] netif the lwip network interface structure for this lpc_enetif + * \param[in] q Pointer to pbug to send + * \param[in] ipaddr IP address + * \return ERR_OK or error code + */ +#if LWIP_IPV6 +err_t lpc_etharp_output_ipv6(struct netif *netif, struct pbuf *q, + const ip6_addr_t *ipaddr) +{ + /* Only send packet is link is up */s + if (netif->flags & NETIF_FLAG_LINK_UP) + return ethip6_output(netif, q, ipaddr); + + return ERR_CONN; +} +#endif #if NO_SYS == 0 /* periodic PHY status update */ @@ -976,13 +983,19 @@ err_t eth_arch_enetif_init(struct netif *netif) #else mbed_mac_address((char *)netif->hwaddr); #endif - netif->hwaddr_len = ETHARP_HWADDR_LEN; + netif->hwaddr_len = ETH_HWADDR_LEN; /* maximum transfer unit */ netif->mtu = 1500; /* device capabilities */ - netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_ETHERNET | NETIF_FLAG_IGMP; + netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_ETHERNET; +#ifdef LWIP_IGMP + netif->flags |= NETIF_FLAG_IGMP; +#endif +#if LWIP_IPV6_MLD + netif->flags |= NETIF_FLAG_MLD6; +#endif /* Initialize the hardware */ netif->state = &lpc_enetdata; @@ -998,7 +1011,13 @@ err_t eth_arch_enetif_init(struct netif *netif) netif->name[0] = 'e'; netif->name[1] = 'n'; - netif->output = lpc_etharp_output; +#if LWIP_IPV4 + netif->output = lpc_etharp_output_ipv4; +#endif +#if LWIP_IPV6 + netif->output_ip6 = lpc_etharp_output_ipv6; +#endif + netif->linkoutput = lpc_low_level_output; /* CMSIS-RTOS, start tasks */ diff --git a/features/net/FEATURE_IPV4/lwip-interface/lwip-eth/arch/TARGET_RZ_A1H/rza1_emac.c b/features/net/FEATURE_IPV4/lwip-interface/lwip-eth/arch/TARGET_RZ_A1H/rza1_emac.c index 40b339d856..0953de1da4 100644 --- a/features/net/FEATURE_IPV4/lwip-interface/lwip-eth/arch/TARGET_RZ_A1H/rza1_emac.c +++ b/features/net/FEATURE_IPV4/lwip-interface/lwip-eth/arch/TARGET_RZ_A1H/rza1_emac.c @@ -1,6 +1,7 @@ #include "lwip/opt.h" #include "lwip/tcpip.h" #include "netif/etharp.h" +#include "lwip/ethip6.h" #include "mbed_interface.h" #include "ethernet_api.h" #include "ethernetext_api.h" @@ -15,13 +16,17 @@ static sys_sem_t recv_ready_sem; /* receive ready semaphore */ /* function */ static void rza1_recv_task(void *arg); static void rza1_phy_task(void *arg); -static err_t rza1_etharp_output(struct netif *netif, struct pbuf *q, ip_addr_t *ipaddr); +#if LWIP_IPV4 +static err_t rza1_etharp_output_ipv4(struct netif *netif, struct pbuf *q, const ip4_addr_t *ipaddr); +#endif +#if LWIP_IPV6 +static err_t rza1_etharp_output_ipv6(struct netif *netif, struct pbuf *q, const ip6_addr_t *ipaddr); +#endif static err_t rza1_low_level_output(struct netif *netif, struct pbuf *p); static void rza1_recv_callback(void); static void rza1_recv_task(void *arg) { struct netif *netif = (struct netif*)arg; - struct eth_hdr *ethhdr; u16_t recv_size; struct pbuf *p; int cnt; @@ -34,24 +39,10 @@ static void rza1_recv_task(void *arg) { p = pbuf_alloc(PBUF_RAW, recv_size, PBUF_RAM); if (p != NULL) { (void)ethernet_read((char *)p->payload, p->len); - ethhdr = p->payload; - switch (htons(ethhdr->type)) { - case ETHTYPE_IP: - case ETHTYPE_ARP: -#if PPPOE_SUPPORT - case ETHTYPE_PPPOEDISC: - case ETHTYPE_PPPOE: -#endif /* PPPOE_SUPPORT */ - /* full packet send to tcpip_thread to process */ - if (netif->input(p, netif) != ERR_OK) { - /* Free buffer */ - pbuf_free(p); - } - break; - default: - /* Return buffer */ - pbuf_free(p); - break; + /* full packet send to tcpip_thread to process */ + if (netif->input(p, netif) != ERR_OK) { + /* Free buffer */ + pbuf_free(p); } } } else { @@ -94,7 +85,8 @@ static void rza1_phy_task(void *arg) { } } -static err_t rza1_etharp_output(struct netif *netif, struct pbuf *q, ip_addr_t *ipaddr) { +#if LWIP_IPV4 +static err_t rza1_etharp_output_ipv4(struct netif *netif, struct pbuf *q, const ip4_addr_t *ipaddr) { /* Only send packet is link is up */ if (netif->flags & NETIF_FLAG_LINK_UP) { return etharp_output(netif, q, ipaddr); @@ -102,6 +94,18 @@ static err_t rza1_etharp_output(struct netif *netif, struct pbuf *q, ip_addr_t * return ERR_CONN; } +#endif + +#if LWIP_IPV6 +static err_t rza1_etharp_output_ipv6(struct netif *netif, struct pbuf *q, const ip6_addr_t *ipaddr) { + /* Only send packet is link is up */ + if (netif->flags & NETIF_FLAG_LINK_UP) { + return ethip6_output(netif, q, ipaddr); + } + + return ERR_CONN; +} +#endif static err_t rza1_low_level_output(struct netif *netif, struct pbuf *p) { struct pbuf *q; @@ -150,13 +154,19 @@ err_t eth_arch_enetif_init(struct netif *netif) #else mbed_mac_address((char *)netif->hwaddr); #endif - netif->hwaddr_len = ETHARP_HWADDR_LEN; + netif->hwaddr_len = ETH_HWADDR_LEN; /* maximum transfer unit */ netif->mtu = 1500; /* device capabilities */ - netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_ETHERNET | NETIF_FLAG_IGMP; + netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_ETHERNET; +#ifdef LWIP_IGMP + netif->flags |= NETIF_FLAG_IGMP; +#endif +#if LWIP_IPV6_MLD + netif->flags |= NETIF_FLAG_MLD6; +#endif #if LWIP_NETIF_HOSTNAME /* Initialize interface hostname */ @@ -166,7 +176,13 @@ err_t eth_arch_enetif_init(struct netif *netif) netif->name[0] = 'e'; netif->name[1] = 'n'; - netif->output = rza1_etharp_output; +#if LWIP_IPV4 + netif->output = rza1_etharp_output_ipv4; +#endif +#if LWIP_IPV6 + netif->output_ip6 = rza1_etharp_output_ipv6; +#endif + netif->linkoutput = rza1_low_level_output; /* Initialize the hardware */ diff --git a/features/net/FEATURE_IPV4/lwip-interface/lwip-eth/arch/TARGET_STM/stm32xx_emac.c b/features/net/FEATURE_IPV4/lwip-interface/lwip-eth/arch/TARGET_STM/stm32xx_emac.c index eed385c248..9962e237ee 100644 --- a/features/net/FEATURE_IPV4/lwip-interface/lwip-eth/arch/TARGET_STM/stm32xx_emac.c +++ b/features/net/FEATURE_IPV4/lwip-interface/lwip-eth/arch/TARGET_STM/stm32xx_emac.c @@ -1,8 +1,8 @@ #include "lwip/opt.h" -#include "lwip/timers.h" #include "netif/etharp.h" #include "lwip/tcpip.h" +#include "lwip/ethip6.h" #include #include "cmsis_os.h" #include "mbed_interface.h" @@ -40,7 +40,14 @@ static sys_mutex_t tx_lock_mutex; /* function */ static void _eth_arch_rx_task(void *arg); static void _eth_arch_phy_task(void *arg); -static err_t _eth_arch_netif_output(struct netif *netif, struct pbuf *q, ip_addr_t *ipaddr); + +#if LWIP_IPV4 +static err_t _eth_arch_netif_output_ipv4(struct netif *netif, struct pbuf *q, const ip4_addr_t *ipaddr); +#endif +#if LWIP_IPV6 +static err_t _eth_arch_netif_output_ipv6(struct netif *netif, struct pbuf *q, const ip6_addr_t *ipaddr); +#endif + static err_t _eth_arch_low_level_output(struct netif *netif, struct pbuf *p); static struct pbuf * _eth_arch_low_level_input(struct netif *netif); @@ -112,7 +119,7 @@ static void _eth_arch_low_level_init(struct netif *netif) #if LWIP_ARP || LWIP_ETHERNET /* set MAC hardware address length */ - netif->hwaddr_len = ETHARP_HWADDR_LEN; + netif->hwaddr_len = ETH_HWADDR_LEN; /* set MAC hardware address */ netif->hwaddr[0] = EthHandle.Init.MACAddr[0]; @@ -356,7 +363,7 @@ static void _eth_arch_phy_task(void *arg) } /** - * This function is the ethernet packet send function. It calls + * This function is the ethernet IPv4 packet send function. It calls * etharp_output after checking link status. * * \param[in] netif the lwip network interface structure for this lpc_enetif @@ -364,7 +371,8 @@ static void _eth_arch_phy_task(void *arg) * \param[in] ipaddr IP address * \return ERR_OK or error code */ -static err_t _eth_arch_netif_output(struct netif *netif, struct pbuf *q, ip_addr_t *ipaddr) +#if LWIP_IPV4 +static err_t _eth_arch_netif_output_ipv4(struct netif *netif, struct pbuf *q, const ip4_addr_t *ipaddr) { /* Only send packet is link is up */ if (netif->flags & NETIF_FLAG_LINK_UP) { @@ -372,6 +380,27 @@ static err_t _eth_arch_netif_output(struct netif *netif, struct pbuf *q, ip_addr } return ERR_CONN; } +#endif + +/** + * This function is the ethernet packet send function. It calls + * etharp_output after checking link status. + * + * \param[in] netif the lwip network IPv6 interface structure for this lpc_enetif + * \param[in] q Pointer to pbug to send + * \param[in] ipaddr IP address + * \return ERR_OK or error code + */ +#if LWIP_IPV6 +static err_t _eth_arch_netif_output_ipv6(struct netif *netif, struct pbuf *q, const ip6_addr_t *ipaddr) +{ + /* Only send packet is link is up */ + if (netif->flags & NETIF_FLAG_LINK_UP) { + return ethip6_output(netif, q, ipaddr); + } + return ERR_CONN; +} +#endif /** * Should be called at the beginning of the program to set up the @@ -387,13 +416,13 @@ static err_t _eth_arch_netif_output(struct netif *netif, struct pbuf *q, ip_addr err_t eth_arch_enetif_init(struct netif *netif) { /* set MAC hardware address */ - netif->hwaddr_len = ETHARP_HWADDR_LEN; + netif->hwaddr_len = ETH_HWADDR_LEN; /* maximum transfer unit */ netif->mtu = 1500; /* device capabilities */ - netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_ETHERNET | NETIF_FLAG_IGMP; + netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_ETHERNET; #if LWIP_NETIF_HOSTNAME /* Initialize interface hostname */ @@ -403,7 +432,15 @@ err_t eth_arch_enetif_init(struct netif *netif) netif->name[0] = 'e'; netif->name[1] = 'n'; - netif->output = _eth_arch_netif_output; +#if LWIP_IPV4 + netif->output = _eth_arch_netif_output_ipv4; + netif->flags |= NETIF_FLAG_IGMP; +#endif +#if LWIP_IPV6 + netif->output_ip6 = _eth_arch_netif_output_ipv6; + netif->flags |= NETIF_FLAG_MLD6; +#endif + netif->linkoutput = _eth_arch_low_level_output; /* semaphore */ diff --git a/features/net/FEATURE_IPV4/lwip-interface/lwip-eth/arch/TARGET_VK_RZ_A1H/rza1_emac.c b/features/net/FEATURE_IPV4/lwip-interface/lwip-eth/arch/TARGET_VK_RZ_A1H/rza1_emac.c index 40b339d856..0953de1da4 100644 --- a/features/net/FEATURE_IPV4/lwip-interface/lwip-eth/arch/TARGET_VK_RZ_A1H/rza1_emac.c +++ b/features/net/FEATURE_IPV4/lwip-interface/lwip-eth/arch/TARGET_VK_RZ_A1H/rza1_emac.c @@ -1,6 +1,7 @@ #include "lwip/opt.h" #include "lwip/tcpip.h" #include "netif/etharp.h" +#include "lwip/ethip6.h" #include "mbed_interface.h" #include "ethernet_api.h" #include "ethernetext_api.h" @@ -15,13 +16,17 @@ static sys_sem_t recv_ready_sem; /* receive ready semaphore */ /* function */ static void rza1_recv_task(void *arg); static void rza1_phy_task(void *arg); -static err_t rza1_etharp_output(struct netif *netif, struct pbuf *q, ip_addr_t *ipaddr); +#if LWIP_IPV4 +static err_t rza1_etharp_output_ipv4(struct netif *netif, struct pbuf *q, const ip4_addr_t *ipaddr); +#endif +#if LWIP_IPV6 +static err_t rza1_etharp_output_ipv6(struct netif *netif, struct pbuf *q, const ip6_addr_t *ipaddr); +#endif static err_t rza1_low_level_output(struct netif *netif, struct pbuf *p); static void rza1_recv_callback(void); static void rza1_recv_task(void *arg) { struct netif *netif = (struct netif*)arg; - struct eth_hdr *ethhdr; u16_t recv_size; struct pbuf *p; int cnt; @@ -34,24 +39,10 @@ static void rza1_recv_task(void *arg) { p = pbuf_alloc(PBUF_RAW, recv_size, PBUF_RAM); if (p != NULL) { (void)ethernet_read((char *)p->payload, p->len); - ethhdr = p->payload; - switch (htons(ethhdr->type)) { - case ETHTYPE_IP: - case ETHTYPE_ARP: -#if PPPOE_SUPPORT - case ETHTYPE_PPPOEDISC: - case ETHTYPE_PPPOE: -#endif /* PPPOE_SUPPORT */ - /* full packet send to tcpip_thread to process */ - if (netif->input(p, netif) != ERR_OK) { - /* Free buffer */ - pbuf_free(p); - } - break; - default: - /* Return buffer */ - pbuf_free(p); - break; + /* full packet send to tcpip_thread to process */ + if (netif->input(p, netif) != ERR_OK) { + /* Free buffer */ + pbuf_free(p); } } } else { @@ -94,7 +85,8 @@ static void rza1_phy_task(void *arg) { } } -static err_t rza1_etharp_output(struct netif *netif, struct pbuf *q, ip_addr_t *ipaddr) { +#if LWIP_IPV4 +static err_t rza1_etharp_output_ipv4(struct netif *netif, struct pbuf *q, const ip4_addr_t *ipaddr) { /* Only send packet is link is up */ if (netif->flags & NETIF_FLAG_LINK_UP) { return etharp_output(netif, q, ipaddr); @@ -102,6 +94,18 @@ static err_t rza1_etharp_output(struct netif *netif, struct pbuf *q, ip_addr_t * return ERR_CONN; } +#endif + +#if LWIP_IPV6 +static err_t rza1_etharp_output_ipv6(struct netif *netif, struct pbuf *q, const ip6_addr_t *ipaddr) { + /* Only send packet is link is up */ + if (netif->flags & NETIF_FLAG_LINK_UP) { + return ethip6_output(netif, q, ipaddr); + } + + return ERR_CONN; +} +#endif static err_t rza1_low_level_output(struct netif *netif, struct pbuf *p) { struct pbuf *q; @@ -150,13 +154,19 @@ err_t eth_arch_enetif_init(struct netif *netif) #else mbed_mac_address((char *)netif->hwaddr); #endif - netif->hwaddr_len = ETHARP_HWADDR_LEN; + netif->hwaddr_len = ETH_HWADDR_LEN; /* maximum transfer unit */ netif->mtu = 1500; /* device capabilities */ - netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_ETHERNET | NETIF_FLAG_IGMP; + netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_ETHERNET; +#ifdef LWIP_IGMP + netif->flags |= NETIF_FLAG_IGMP; +#endif +#if LWIP_IPV6_MLD + netif->flags |= NETIF_FLAG_MLD6; +#endif #if LWIP_NETIF_HOSTNAME /* Initialize interface hostname */ @@ -166,7 +176,13 @@ err_t eth_arch_enetif_init(struct netif *netif) netif->name[0] = 'e'; netif->name[1] = 'n'; - netif->output = rza1_etharp_output; +#if LWIP_IPV4 + netif->output = rza1_etharp_output_ipv4; +#endif +#if LWIP_IPV6 + netif->output_ip6 = rza1_etharp_output_ipv6; +#endif + netif->linkoutput = rza1_low_level_output; /* Initialize the hardware */ diff --git a/features/net/FEATURE_IPV4/lwip-interface/lwip-sys/arch/lwip_sys_arch.c b/features/net/FEATURE_IPV4/lwip-interface/lwip-sys/arch/lwip_sys_arch.c index 25e2f14ef5..4ec57613d3 100644 --- a/features/net/FEATURE_IPV4/lwip-interface/lwip-sys/arch/lwip_sys_arch.c +++ b/features/net/FEATURE_IPV4/lwip-interface/lwip-sys/arch/lwip_sys_arch.c @@ -29,6 +29,49 @@ #include "lwip/sys.h" #include "lwip/mem.h" +/* Define the heap ourselves to give us section placement control */ +#ifndef ETHMEM_SECTION +#if defined(TARGET_LPC4088) || defined(TARGET_LPC4088_DM) +# if defined (__ICCARM__) +# define ETHMEM_SECTION +# elif defined(TOOLCHAIN_GCC_CR) +# define ETHMEM_SECTION __attribute__((section(".data.$RamPeriph32"))) +# else +# define ETHMEM_SECTION __attribute__((section("AHBSRAM1"),aligned)) +# endif +#elif defined(TARGET_LPC1768) +# if defined (__ICCARM__) +# define ETHMEM_SECTION +# elif defined(TOOLCHAIN_GCC_CR) +# define ETHMEM_SECTION __attribute__((section(".data.$RamPeriph32"))) +# else +# define ETHMEM_SECTION __attribute__((section("AHBSRAM0"),aligned)) +# endif +#else +#define ETHMEM_SECTION +#endif +#endif + +/* LWIP's mem.c doesn't give visibility of its overhead; memory area has to be big + * enough to hold "MEM_SIZE" (which we specify) plus mem.c's overhead. Have to work + * it all out here, copying code from mem.c */ +struct mem { + /** index (-> ram[next]) of the next struct */ + mem_size_t next; + /** index (-> ram[prev]) of the previous struct */ + mem_size_t prev; + /** 1: this area is used; 0: this area is unused */ + u8_t used; +}; + +#define SIZEOF_STRUCT_MEM LWIP_MEM_ALIGN_SIZE(sizeof(struct mem)) +#define MEM_SIZE_ALIGNED LWIP_MEM_ALIGN_SIZE(MEM_SIZE) + +#if defined (__ICCARM__) +#pragma location = ".ethusbram" +#endif +LWIP_DECLARE_MEMORY_ALIGNED(lwip_ram_heap, MEM_SIZE_ALIGNED + (2U*SIZEOF_STRUCT_MEM)) ETHMEM_SECTION; + #if NO_SYS==1 #include "cmsis.h" diff --git a/features/net/FEATURE_IPV4/lwip-interface/lwip-sys/arch/sys_arch.h b/features/net/FEATURE_IPV4/lwip-interface/lwip-sys/arch/sys_arch.h index 7678e24eab..57766ac249 100644 --- a/features/net/FEATURE_IPV4/lwip-interface/lwip-sys/arch/sys_arch.h +++ b/features/net/FEATURE_IPV4/lwip-interface/lwip-sys/arch/sys_arch.h @@ -20,6 +20,8 @@ #include "lwip/opt.h" +extern u8_t lwip_ram_heap[]; + #if NO_SYS == 0 #include "cmsis_os.h" diff --git a/features/net/FEATURE_IPV4/lwip-interface/lwip/.gitattributes b/features/net/FEATURE_IPV4/lwip-interface/lwip/.gitattributes new file mode 100644 index 0000000000..f34d43dc57 --- /dev/null +++ b/features/net/FEATURE_IPV4/lwip-interface/lwip/.gitattributes @@ -0,0 +1,4 @@ +# These files are text and should be normalized +*.txt text +*.c text +*.h text diff --git a/features/net/FEATURE_IPV4/lwip-interface/lwip/.gitignore b/features/net/FEATURE_IPV4/lwip-interface/lwip/.gitignore new file mode 100644 index 0000000000..0f13a3e8c2 --- /dev/null +++ b/features/net/FEATURE_IPV4/lwip-interface/lwip/.gitignore @@ -0,0 +1,13 @@ +/doc/doxygen/output +/src/apps/snmp/LwipMibCompiler/CCodeGeneration/bin/ +/src/apps/snmp/LwipMibCompiler/CCodeGeneration/obj/ +/src/apps/snmp/LwipMibCompiler/LwipMibCompiler/bin/ +/src/apps/snmp/LwipMibCompiler/LwipMibCompiler/obj/ +/src/apps/snmp/LwipMibCompiler/MibViewer/bin/ +/src/apps/snmp/LwipMibCompiler/MibViewer/obj/ +/src/apps/snmp/LwipMibCompiler/LwipSnmpCodeGeneration/bin/ +/src/apps/snmp/LwipMibCompiler/LwipSnmpCodeGeneration/obj/ +/src/apps/snmp/LwipMibCompiler/SharpSnmpLib/bin/ +/src/apps/snmp/LwipMibCompiler/SharpSnmpLib/obj/ +/src/apps/snmp/LwipMibCompiler/LwipMibCompiler.userprefs +/src/apps/snmp/LwipMibCompiler/*.suo diff --git a/features/net/FEATURE_IPV4/lwip-interface/lwip/CHANGELOG b/features/net/FEATURE_IPV4/lwip-interface/lwip/CHANGELOG new file mode 100644 index 0000000000..39177b8f3b --- /dev/null +++ b/features/net/FEATURE_IPV4/lwip-interface/lwip/CHANGELOG @@ -0,0 +1,4126 @@ +HISTORY + +(git master) + + * [Enter new changes just after this line - do not remove this line] + + ++ New features: + + 2016-07-27: Simon Goldschmidt + * opt.h, timeouts.h/.c: added LWIP_TIMERS_CUSTOM to override the default + implementation of timeouts + + 2016-07-xx: Dirk Ziegelmeier + * Large overhaul of doxygen documentation + + 2016-04-05: Simon Goldschmidt + * timers.h/.c: prepare for overriding current timeout implementation: all + stack-internal caclic timers are avaliable in the lwip_cyclic_timers array + + 2016-03-23: Simon Goldschmidt + * tcp: call accept-callback with ERR_MEM when allocating a pcb fails on + passive open to inform the application about this error + ATTENTION: applications have to handle NULL pcb in accept callback! + + 2016-02-22: Ivan Delamer + * Initial 6LoWPAN support + + 2016-02-XX to 2016-03-XX: Dirk Ziegelmeier + * Cleanup TCPIP thread sync methods in a way that it is possibe to use them + in arbitrary code that needs things to be done in TCPIP thread. Used to + decouple netconn, netif, ppp and 6LoWPAN from LWIP core. + + 2016-02-XX: Dirk Ziegelmeier + * Implement dual-stack support in RAW, UDP and TCP. Add new IP address + type IPADDR_ANY_TYPE for this. Netconn/Socket API: Dual-stack is + automatically supported when an IPv6 netconn/socket is created. + + 2015-12-26: Martin Hentschel and Dirk Ziegelmeier + * Rewrite SNMP agent. SNMPv2c + MIB compiler. + + 2015-11-12: Dirk Ziegelmeier + * Decouple SNMP stack from lwIP core and move stack to apps/ directory. + Breaking change: Users have to call snmp_init() now! + + 2015-11-12: Dirk Ziegelmeier + * Implement possibility to declare private memory pools. This is useful to + decouple some apps from the core (SNMP stack) or make contrib app usage + simpler (httpserver_raw) + + 2015-10-09: Simon Goldschmidt + * started to move "private" header files containing implementation details to + "lwip/priv/" include directory to seperate the API from the implementation. + + 2015-10-07: Simon Goldschmidt + * added sntp client as first "supported" application layer protocol implementation + added 'apps' folder + + 2015-09-30: Dirk Ziegelmeier + * snmp_structs.h, mib_structs.c, mib2.c: snmp: fixed ugly inheritance + implementation by aggregating the "base class" (struct mib_node) in all + derived node classes to get more type-safe code + + 2015-09-23: Simon Goldschmidt + * netif.h/.c, nd6.c: task #13729: Convert netif addresses (IPv4 & IPv6) to + ip_addr_t (so they can be used without conversion/temporary storage) + + 2015-09-08: Dirk Ziegelmeier + * snmp: Separate mib2 counter/table callbacks from snmp agent. This both cleans + up the code and should allow integration of a 3rd party agent/mib2. Simple + counters are kept in MIB2_STATS, tree/table change function prototypes moved to + snmp_mib2.h. + + 2015-09-03: Simon Goldschmidt + * opt.h, dns.h/.c: DNS/IPv6: added support for AAAA records + + 2015-09-01: Simon Goldschmidt + * task #12178: hardware checksum capabilities can be configured per netif + (use NETIF_SET_CHECKSUM_CTRL() in your netif's init function) + + 2015-08-30: Simon Goldschmidt + * PBUF_REF with "custom" pbufs is now supported for RX pbufs (see pcapif in + contrib for an example, LWIP_SUPPORT_CUSTOM_PBUF is required) + + 2015-08-30: Simon Goldschmidt + * support IPv4 source based routing: define LWIP_HOOK_IP4_ROUTE_SRC to point + to a routing function + + 2015-08-05: Simon Goldschmidt + * many files: allow multicast socket options IP_MULTICAST_TTL, IP_MULTICAST_IF + and IP_MULTICAST_LOOP to be used without IGMP + + 2015-04-24: Simon Goldschmidt + * dhcp.h/c, autoip.h/.c: added functions dhcp/autoip_supplied_address() to + check for the source of address assignment (replacement for NETIF_FLAG_DHCP) + + 2015-04-10: Simon Goldschmidt + * many files: task #13480: added LWIP_IPV4 define - IPv4 can be disabled, + leaving an IPv6-only stack + + 2015-04-09: Simon Goldschmidt + * nearly all files: task #12722 (improve IPv4/v6 address handling): renamed + ip_addr_t to ip4_addr_t, renamed ipX_addr_t to ip_addr_t and added IP + version; ip_addr_t is used for all generic IP addresses for the API, + ip(4/6)_addr_t are only used internally or when initializing netifs or when + calling version-related functions + + 2015-03-24: Simon Goldschmidt + * opt.h, ip4_addr.h, ip4.c, ip6.c: loopif is not required for loopback traffic + any more but passed through any netif (ENABLE_LOOPBACK has to be enabled) + + 2015-03-23: Simon Goldschmidt + * opt.h, etharp.c: with ETHARP_TABLE_MATCH_NETIF== 1, duplicate (Auto)-IP + addresses on multiple netifs should now be working correctly (if correctly + addressed by routing, that is) + + 2015-03-23: Simon Goldschmidt + * etharp.c: Stable etharp entries that are about to expire are now refreshed + using unicast to prevent unnecessary broadcast. Only if no answer is received + after 15 seconds, broadcast is used. + + 2015-03-06: Philip Gladstone + * netif.h/.c: patch #8359 (Provide utility function to add an IPv6 address to + an interface) + + 2015-03-05: Simon Goldschmidt + * netif.c, ip4.c, dhcp.c, autoip.c: fixed bug #37068 (netif up/down handling + is unclear): correclty separated administrative status of a netif (up/down) + from 'valid address' status + ATTENTION: netif_set_up() now always has to be called, even when dhcp/autoip + is used! + + 2015-02-26: patch by TabascoEye + * netif.c, udp.h/.c: fixed bug #40753 (re-bind UDP pcbs on change of IP address) + + 2015-02-22: chrysn, Simon Goldschmidt + * *.*: Changed nearly all functions taking 'ip(X)_addr_t' pointer to take + const pointers (changed user callbacks: raw_recv_fn, udp_recv_fn; changed + port callbacks: netif_output_fn, netif_igmp_mac_filter_fn) + + 2015-02-19: Ivan Delamer + * netif.h, dhcp.c: Removed unused netif flag for DHCP. The preferred way to evaluate + if DHCP is active is through netif->dhcp field. + + 2015-02-19: Ivan Delamer + * netif.h, slipif.c, ppp.c: Removed unused netif flag for point to point connections + + 2015-02-18: Simon Goldschmidt + * api_lib.c: fixed bug #37958 "netconn API doesn't handle correctly + connections half-closed by peer" + + 2015-02-18: Simon Goldschmidt + * tcp.c: tcp_alloc() prefers killing CLOSING/LAST_ACK over active connections + (see bug #39565) + + 2015-02-16: Claudius Zingerli, Sergio Caprile + * opt.h, dhcp.h/.c: patch #8361 "Add support for NTP option in DHCP" + + 2015-02-14: Simon Goldschmidt + * opt.h, snmp*: added support for write-access community and dedicated + community for sending traps + + 2015-02-13: Simon Goldschmidt + * opt.h, memp.c: added hook LWIP_HOOK_MEMP_AVAILABLE() to get informed when + a memp pool was empty and an item is now available + + 2015-02-13: Simon Goldschmidt + * opt.h, pbuf.h/.c, etharp.c: Added the option PBUF_LINK_ENCAPSULATION_HLEN to + allocate additional header space for TX on netifs requiring additional headers + + 2015-02-12: chrysn + * timers.h/.c: introduce sys_timeouts_sleeptime (returns the time left before + the next timeout is due, for NO_SYS==1) + + 2015-02-11: Nick van Ijzendoorn + * opt.h, sockets.h/c: patch #7702 "Include ability to increase the socket number + with defined offset" + + 2015-02-11: Frederick Baksik + * opt.h, def.h, others: patch #8423 "arch/perf.h" should be made an optional item + + 2015-02-11: Simon Goldschmidt + * api_msg.c, opt.h: started to implement fullduplex sockets/netconns + (note that this is highly unstable yet!) + + 2015-01-17: Simon Goldschmidt + * api: allow enabling socket API without (public) netconn API - netconn API is + still used by sockets, but keeping it private (static) should allow better + compiler optimizations + + 2015-01-16: Simon Goldschmidt + * tcp_in.c: fixed bug #20506 "Initial congestion window is very small" again + by implementing the calculation formula from RFC3390 + + 2014-12-10: Simon Goldschmidt + * api: added option LWIP_NETCONN_SEM_PER_THREAD to use a semaphore per thread + instead of using one per netconn and per select call + + 2014-12-08: Simon Goldschmidt + * ip6.h: fixed bug #43778: IPv6 header version not set on 16-bit platform + (macro IP6H_VTCFL_SET()) + + 2014-12-08: Simon Goldschmidt + * icmp.c, ip4.c, pbuf.c, udp.c, pbuf.h: task #11472 Support PBUF_REF for RX + (IPv6 and IPv4/v6 reassembly might not work yet) + + 2014-11-06: Simon Goldschmidt + * sockets.c/.h, init.c: lwip_socket_init() is not needed any more + -> compatibility define + + 2014-09-16: Simon Goldschmidt + * dns.c, opt.h: reduced ram usage by parsing DNS responses in place + + 2014-09-16: Simon Goldschmidt + * pbuf.h/.c: added pbuf_take_at() and pbuf_put_at() + + 2014-09-15: Simon Goldschmidt + * dns.c: added source port randomization to make the DNS client more robust + (see bug #43144) + + 2013-09-02: Simon Goldschmidt + * arch.h and many other files: added optional macros PACK_STRUCT_FLD_8() and + PACK_STRUCT_FLD_S() to prevent gcc 4 from warning about struct members that + do not need packing + + 2013-08-19: Simon Goldschmidt + * netif.h: bug #42998: made NETIF_MAX_HWADDR_LEN overridable for some special + networks + + 2013-03-17: Simon Goldschmidt (patch by Ghobad Emadi) + * opt.h, etharp.c: Added LWIP_HOOK_ETHARP_GET_GW to implement IPv4 routing with + multiple gateways + + 2013-04-20: Fatih Asici + * opt.h, etharp.h/.c: patch #7993: Added support for transmitting packets + with VLAN headers via hook function LWIP_HOOK_VLAN_SET and to check them + via hook function LWIP_HOOK_VLAN_CHECK + + 2014-02-20: Simon Goldschmidt (based on patch by Artem Pisarenko) + * patch #7885: modification of api modules to support FreeRTOS-MPU + (don't pass stack-pointers to other threads) + + 2014-02-05: Simon Goldschmidt (patch by "xtian" and "alex_ab") + * patch #6537/#7858: TCP window scaling support + + 2014-01-17: Jiri Engelthaler + * icmp, icmp6, opt.h: patch #8027: Completed HW checksuming for IPv4 and + IPv6 ICMP's + + 2012-08-22: Sylvain Rochet + * New PPP stack for lwIP, developed in ppp-new branch. + Based from pppd 2.4.5, released 2009-11-17, with huge changes to match + code size and memory requirements for embedded devices, including: + - Gluing together the previous low-level PPP code in lwIP to pppd 2.4.5, which + is more or less what pppd sys-* files are, so that we get something working + using the unix port. + - Merged some patchs from lwIP Git repository which add interesting features + or fix bugs. + - Merged some patchs from Debian pppd package which add interesting features + or fix bugs. + - Ported PPP timeout handling to the lwIP timers system + - Disabled all the PPP code using filesystem access, replaced in necessary cases + to configuration variables. + - Disabled all the PPP code forking processes. + - Removed IPX support, lwIP does not support IPX. + - Ported and improved random module from the previous PPP port. + - Removed samba TDB (file-driven database) usage, because it needs a filesystem. + - MS-CHAP required a DES implementation, we added the latest PolarSSL DES + implementation which is under a BSD-ish license. + - Also switched to PolarSSL MD4,MD5,SHA1 implementations, which are meant to be + used in embedded devices with reduced memory footprint. + - Removed PPP configuration file parsing support. + - Added macro definition EAP_SUPPORT to make EAP support optional. + - Added macro definition CHAP_SUPPORT to make CHAP support optional. + - Added macro definition MSCHAP_SUPPORT to make MSCHAP support optional. + - Added macro definition PAP_SUPPORT to make PAP support optional. + - Cleared all Linux syscall calls. + - Disabled demand support using a macro, so that it can be ported later. + - Disabled ECP support using a macro, so that it can be ported later. + - Disabled CCP support using a macro, so that it can be ported later. + - Disabled CBCP support using a macro, so that it can be ported later. + - Disabled LQR support using a macro, so that it can be ported later. + - Print packet debug feature optional, through PRINTPKT_SUPPORT + - Removed POSIX signal usage. + - Fully ported PPPoS code from the previous port. + - Fully ported PPPoE code from the previous port. + - Fully ported VJ compression protocol code from the previous port. + - Removed all malloc()/free() use from PPP, replaced by stack usage or PBUF. + - Disabled PPP server support using a macro, so that it can be ported later. + - Switched all PPP debug to lwIP debug system. + - Created PPP Control Block (PPP PCB), removed PPP unit integer everywhere, + removed all global variables everywhere, did everything necessary for + the PPP stack to support more than one PPP session (pppd only support + one session per process). + - Removed the statically allocated output buffer, now using PBUF. + - Improved structure size of all PPP modules, deep analyze of code to reduce + variables size to the bare minimum. Switched all boolean type (char type in + most architecture) to compiler generated bitfields. + - Added PPP IPv6 support, glued lwIP IPv6 support to PPP. + - Now using a persistent netif interface which can then be used in lwIP + functions requiring a netif. + - Now initializing PPP in lwip_init() function. + - Reworked completely the PPP state machine, so that we don't end up in + anymore in inconsistent state, especially with PPPoE. + - Improved the way we handle PPP reconnection after disconnect, cleaning + everything required so that we start the PPP connection again from a + clean state. + - Added PPP holdoff support, allow the lwIP user to wait a little bit before + reconnecting, prevents connection flood, especially when using PPPoL2TP. + - Added PPPoL2TP LAC support (a.k.a. UDP tunnels), adding a VPN client + feature to lwIP, L2TP being a widely used tunnel protocol. + - Switched all used PPP types to lwIP types (u8t, u16t, u32t, ...) + - Added PPP API "sequential" thread-safe API, based from NETIFAPI. + + 2011-07-21: Simon Goldschmidt + * sockets.c, opt.h: (bug #30185): added LWIP_FIONREAD_LINUXMODE that makes + ioctl/FIONREAD return the size of the next pending datagram. + + 2011-05-25: Simon Goldschmidt + * again nearly the whole stack, renamed ip.c to ip4.c, ip_addr.c to ip4_addr.c, + combined ipv4/ipv6 inet_chksum.c, added ip.h, ip_addr.h: Combined IPv4 + and IPv6 code where possible, added defines to access IPv4/IPv6 in non-IP + code so that the code is more readable. + + 2011-05-17: Patch by Ivan Delamer (only checked in by Simon Goldschmidt) + * nearly the whole stack: Finally, we got decent IPv6 support, big thanks to + Ivan! (this is work in progress: we're just post release anyway :-) + + + ++ Bugfixes: + + 2016-07-20: Simon Goldschmidt + * memp.h/.c: fixed bug #48442 (memp stats don't work for MEMP_MEM_MALLOC) + + 2016-07-21: Simon Goldschmidt (patch by Ambroz Bizjak) + * tcp_in.c, tcp_out.c: fixed bug #48543 (TCP sent callback may prematurely + report sent data when only part of a segment is acked) and don't include + SYN/FIN in snd_buf counter + + 2016-07-19: Simon Goldschmidt + * etharp.c: fixed bug #48477 (ARP input packet might update static entry) + + 2016-07-11: Simon Goldschmidt + * tcp_in.c: fixed bug #48476 (TCP sent callback called wrongly due to picking + up old pcb->acked + + 2016-06-30: Simon Goldschmidt (original patch by Fabian Koch) + * tcp_in.c: fixed bug #48170 (Vulnerable to TCP RST spoofing) + + 2016-05-20: Dirk Ziegelmeier + * sntp.h/.c: Fix return value of sntp_getserver() call to return a pointer + + 2016-04-05: Simon Goldschmidt (patch by Philip Gladstone) + * udp.c: patch #8358: allow more combinations of listening PCB for IPv6 + + 2016-04-05: Simon Goldschmidt + * netconn/socket API: fixed bug# 43739 (Accept not reporting errors about + aborted connections): netconn_accept() returns ERR_ABRT (sockets: ECONNABORTED) + for aborted connections, ERR_CLSD (sockets: EINVAL) if the listening netconn + is closed, which better seems to follow the standard. + + 2016-03-23: Florent Matignon + * dhcp.c: fixed bug #38203: DHCP options are not recorded in all DHCP ack messages + + 2016-03-22: Simon Goldschmidt + * tcp: changed accept handling to be done internally: the application does not + have to call tcp_accepted() any more. Instead, when delaying accept (e.g. sockets + do), call tcp_backlog_delayed()/tcp_backlog_accepted() (fixes bug #46696) + + 2016-03-22: Simon Goldschmidt + * dns.c: ignore dns response parsing errors, only abort resolving for correct + responses or error responses from correct server (bug #47459) + + 2016-03-17: Simon Goldschmidt + * api_msg.c: fixed bug #47448 (netconn/socket leak if RST is received during close) + + 2016-03-17: Joel Cunningham + * api_msg.c: don't fail closing a socket/netconn when failing to allocate the + FIN segment; blocking the calling thread for a while is better than risking + leaking a netconn/socket (see bug #46701) + + 2016-03-16: Joel Cunningham + * tcp_out.c: reset rto timer on fast retransmission + + 2016-03-16: Deomid Ryabkov + * tcp_out.c: fixed bug #46384 Segment size calculation bug with MSS != TCP_MSS + + 2016-03-05: Simon Goldschmidt + * err.h/.c, sockets.c: ERR_IF is not necessarily a fatal error + + 2015-11-19: fix by Kerem Hadimli + * sockets.c: fixed bug #46471: lwip_accept() leaks socket descriptors if new + netconn was already closed because of peer behavior + + 2015-11-12: fix by Valery Ushakov + * tcp_in.c: fixed bug #46365 tcp_accept_null() should call tcp_abort() + + 2015-10-02: Dirk Ziegelmeier/Simon Goldschmidt + * snmp: cleaned up snmp structs API (fixed race conditions from bug #46089, + reduce ram/rom usage of tables): incompatible change for private MIBs + + 2015-09-30: Simon Goldschmidt + * ip4_addr.c: fixed bug #46072: ip4addr_aton() does not check the number range + of all address parts + + 2015-08-28: Simon Goldschmidt + * tcp.c, tcp_in.c: fixed bug #44023: TCP ssthresh value is unclear: ssthresh + is set to the full send window for active open, too, and is updated once + after SYN to ensure the correct send window is used + + 2015-08-28: Simon Goldschmidt + * tcp: fixed bug #45559: Window scaling casts u32_t to u16_t without checks + + 2015-08-26: Simon Goldschmidt + * ip6_frag.h/.c: fixed bug bug #41009: IPv6 reassembly broken on 64-bit platforms: + define IPV6_FRAG_COPYHEADER==1 on these platforms to copy the IPv6 header + instead of referencing it, which gives more room for struct ip6_reass_helper + + 2015-08-25: Simon Goldschmidt + * sockets.c: fixed bug #45827: recvfrom: TCP window is updated with MSG_PEEK + + 2015-08-20: Manoj Kumar + * snmp_msg.h, msg_in.c: fixed bug #43790: Sending octet string of Length >255 + from SNMP agent + + 2015-08-19: Jens Nielsen + * icmp.c, ip4.c, tcp_in.c, udp.c, raw.c: fixed bug #45120: Broadcast & multiple + interfaces handling + + 2015-08-19: Simon Goldschmidt (patch by "Sandra") + * dns.c: fixed bug #45004: dns response without answer might be discarded + + 2015-08-18: Chrysn + * timers.c: patch #8704 fix sys_timeouts_sleeptime function + + 2015-07-01: Erik Ekman + * puf.c: fixed bug #45454 (pbuf_take_at() skips write and returns OK if offset + is at start of pbuf in chain) + + 2015-05-19: Simon Goldschmidt + * dhcp.h/.c: fixed bugs #45140 and #45141 (dhcp was not stopped correctly after + fixing bug #38204) + + 2015-03-21: Simon Goldschmidt (patch by Homyak) + * tcp_in.c: fixed bug #44766 (LWIP_WND_SCALE: tcphdr->wnd was not scaled in + two places) + + 2015-03-21: Simon Goldschmidt + * tcp_impl.h, tcp.c, tcp_in.c: fixed bug #41318 (Bad memory ref in tcp_input() + after tcp_close()) + + 2015-03-21: Simon Goldschmidt + * tcp_in.c: fixed bug #38468 (tcp_sent() not called on half-open connection for + data ACKed with the same ack as FIN) + + 2015-03-21: Simon Goldschmidt (patch by Christoffer Lind) + * dhcp.h/.c: fixed bug #38204 (DHCP lease time not handled correctly) + + 2015-03-20: Simon Goldschmidt + * dhcp.c: fixed bug #38714 (Missing option and client address in DHCPRELEASE message) + + 2015-03-19: Simon Goldschmidt + * api.h, tcpip.h, api_lib.c, api_msg.c: fixed race conditions in assigning + netconn->last_err (fixed bugs #38121 and #37676) + + 2015-03-09: Simon Goldschmidt + * ip4.c: fixed the IPv4 part of bug #43904 (ip_route() must detect linkup status) + + 2015-03-04: Simon Goldschmidt + * nd6.c: fixed bug #43784 (a host should send at least one Router Solicitation) + + 2015-03-04: Valery Ushakov + * ip6.c: fixed bug #41094 (Byte-order bug in IPv6 fragmentation header test) + + 2015-03-04: Zach Smith + * nd6.c: fixed bug #38153 (nd6_input() byte order issues) + + 2015-02-26: Simon Goldschmidt + * netif.c, tcp.h/.c: fixed bug #44378 (TCP connections are not aborted on netif + remove) + + 2015-02-25: Simon Goldschmidt + * ip4.c, etharp.c: fixed bug #40177 (System hangs when dealing with corrupted + packets), implemented task #12357 (Ensure that malicious packets don't + assert-fail): improved some pbuf_header calls to not assert-fail. + + 2015-02-25: patch by Joel Cunningham + * udp.h/.c, sockets.c: fixed bug #43028 (IP_MULTICAST_TTL affects unicast + datagrams) + + 2015-02-25: patch by Greg Renda + * ip4_frag.c: fixed bug #38210 (ip reassembly while remove oldest datagram) + + 2015-02-25: Simon Goldschmidt + * sockets.c: fixed bug #38165 (socket with mulicast): ensure igmp membership + are dropped when socket (not netconn!) is closed. + + 2015-02-25: Simon Goldschmidt + * ip4.h/.c, udp.c: fixed bug #38061 (wrong multicast routing in IPv4) by + adding an optional default netif for multicast routing + + 2015-02-25: Simon Goldschmidt + * netconn API: fixed that netconn_connect still used message passing for + LWIP_TCPIP_CORE_LOCKING==1 + + 2015-02-22: patch by Jens Nielsen + * icmp.c: fixed bug #38803 (Source address in broadcast ping reply) + + 2015-02-22: Simon Goldschmidt + * udp.h, sockets.c: added proper accessor functions for pcb->multicast_ip + (previously used by get/setsockopt only) + + 2015-02-18: Simon Goldschmidt + * sockets.c: Fixed select not reporting received FIN as 'readable' in certain + rare cases (bug #43779: select(), close(), and TCP retransmission error) + + 2015-02-17: Simon Goldschmidt + * err.h, sockets.c, api_msg.c: fixed bug #38853 "connect() use a wrong errno": + return ERR_ALREADY/EALRADY during connect, ERR_ISCONN/EISCONN when already + connected + + 2015-02-17: Simon Goldschmidt + * tcp_impl.h, tcp_out.c, tcp.c, api_msg.c: fixed bug #37614 "Errors from + ipX_output are not processed". Now tcp_output(_segment) checks for the return + value of ipX_output and does not try to send more on error. A netif driver + can call tcp_txnow() (from tcpip_thread!) to try to send again if TX buffers + are available again. + + 2015-02-14: patches by Freddie Chopin + * snmp*: made community writable, fixed some const pointers + + 2015-02-13: Simon Goldschmidt + * msg_in.c: fixed bug #22070 "MIB_OBJECT_WRITE_ONLY not implemented in SNMP" + + 2015-02-12: Simon Goldschmidt + * ip.h, ip4.c, ip6.c: fixed bug #36403 "ip4_input() and ip6_input() always pass + inp to higher layers": now the accepting netif is passed up, but the input + netif is available through ip_current_input_netif() if required. + + 2015-02-11: patch by hichard + * tcpip.c: fixed bug #43094 "The function tcpip_input() forget to handle IPv6" + + 2015-02-10: Simon Goldschmidt + * netconn API: fixed that netconn_close/netconn_delete still used message passing + for LWIP_TCPIP_CORE_LOCKING==1 + + 2015-02-10: Simon Goldschmidt + * netconn/socket api: fixed bug #44225 "closing TCP socket should time out + eventually", implemented task #6930 "Implement SO_LINGER": closing TCP sockets + times out after 20 seconds or after the configured SND_TIMEOUT or depending + on the linger settings. + + 2015-01-27: Simon Goldschmidt + * api_msg.c: fixed that SHUT_RD followed by SHUT_WR was different to SHUT_RDWR, + fixed return value of lwip_netconn_do_close on unconnected netconns + + 2015-01-17: Simon Goldschmidt + * sockets.c: fixed bug #43361 select() crashes with stale FDs + + 2015-01-17: Simon Goldschmidt + * sockets.c/.h, memp_std.h: fixed bug #40788 "lwip_setsockopt_internal() crashes" + by rewriting set/getsockopt functions to combine checks with the actual code + and add more NULL checks; this also fixes that CORE_LOCKING used message + passing for set/getsockopt. + + 2014-12-19: Simon Goldschmidt + * opt.h, dhcp.h/.c: prevent dhcp from starting when netif link is down (only + when LWIP_DHCP_CHECK_LINK_UP==1, which is disabled by default for + compatibility reasons) + + 2014-12-17: Simon Goldschmidt + * tcp_out.c: fixed bug #43840 Checksum error for TCP_CHECKSUM_ON_COPY==1 for + no-copy data with odd length + + 2014-12-10: Simon Goldschmidt + * sockets.c, tcp.c, others: fixed bug #43797 set/getsockopt: SO_SNDTIMEO/SO_RCVTIMEO + take int as option but should take timeval (LWIP_SO_SNDRCVTIMEO_STANDARD==0 can + be used to revert to the old 'winsock' style behaviour) + Fixed implementation of SO_ACCEPTCONN to just look at the pcb state + + 2014-12-09: Simon Goldschmidt + * ip4.c: fixed bug #43596 IGMP queries from 0.0.0.0 are discarded + + 2014-10-21: Simon Goldschmidt (patch by Joel Cunningham and Albert Huitsing) + * sockts.c: fixed bugs #41495 Possible threading issue in select() and #43278 + event_callback() handle context switch when calling sys_sem_signal() + + 2014-10-21: Simon Goldschmidt + * api_msg.c: fixed bug #38219 Assert on TCP netconn_write with sndtimeout set + + 2014-09-16: Kevin Cernekee + * dns.c: patch #8480 Fix handling of dns_seqno wraparound + + 2014-09-16: Simon Goldschmidt + * tcp_out.c: fixed bug #43192 tcp_enqueue_flags() should not check TCP_SND_QUEUELEN + when sending FIN + + 2014-09-03: Simon Goldschmidt + * msg_in.c: fixed bug #39355 SNMP Memory Leak in case of error + + 2014-09-02: Simon Goldschmidt + * err.h/.c, sockets.c, api_msg.c: fixed bug #43110 call getpeername() before + listen() will cause a error + + 2014-09-02: Simon Goldschmidt + * sockets.c: fixed bug #42117 lwip_fcntl does not set errno + + 2014-09-02: Simon Goldschmidt + * tcp.c: fixed bug #42299 tcp_abort() leaves freed pcb on tcp_bound_pcbs list + + 2014-08-20: Simon Goldschmidt + * dns.c: fixed bug #42987 lwIP is vulnerable to DNS cache poisoning due to + non-randomized TXIDs + + 2014-06-03: Simon Goldschmidt + * tcp_impl.h, tcp_in.c: fixed bug #37969 SYN packet dropped as short packet in + tcp_input function + + 2014-05-20: Simon Goldschmidt + * tcp_out.c: fixed bug #37184 tcp_write problem for pcbs in the SYN_SENT state + + 2014-05-19: Simon Goldschmidt + * *.h: Fixed bug #35874 reserved identifier violation (removed leading underscores + from header include guards) + + 2014-04-08: Simon Goldschmidt + * tcp.c: Fixed bug #36167 tcp server crash when client closes (maximum window) + + 2014-04-06: Simon Goldschmidt + * tcp_in.c: Fixed bug #36210 lwIP does not elicit an empty ACK when received + unacceptable ACK + + 2014-04-06: Simon Goldschmidt + * dhcp.c, ip4.c/.h, ip6.c/.h, udp.c/.h, ip.h: Fixed bug #41787 DHCP Discovery + is invalid when an IP is set to thet netif. + + 2014-03-14: Simon Goldschmidt + * tcp_out.c: Fixed bug #36153 TCP Cheksum error if LWIP_CHECKSUM_ON_COPY=1 + + 2014-03-11: Simon Goldschmidt (patch by Mason) + * opt.h, sockets.c: fixed bug #35928 BSD sockets functions must set errno for + POSIX-compliance + + 2014-02-27: Simon Goldschmidt + * dhcp.c: fixed bug #40303 DHCP xid renewed when sending a DHCPREQUEST + + 2014-02-27: Simon Goldschmidt + * raw.c: fixed bug #41680 raw socket can not receive IPv6 packet when + IP_SOF_BROADCAST_RECV==1 + + 2014-02-27: Simon Goldschmidt + * api_msg.c, sockets.c: fixed bug #38404 getpeeraddr returns success on + unconnected/listening TCP sockets + + 2014-02-27: Simon Goldschmidt + * sockets.c: fixed bug #41729 Some socket functions return Exyz instead of -1 + + 2014-02-25: Simon Goldschmidt + * ip4.c: fixed bug #39514 ip_route() may return an IPv6-only interface + + 2014-02-25: Simon Goldschmidt, patch by Fatih Asici + * pbuf.c: fixed bug #39356 Wrong increment in pbuf_memfind() + + 2014-02-25: Simon Goldschmidt + * netif.c/.h, udp.c: fixed bug #39225 udp.c uses netif_matches_ip6_addr() incorrectly; + renamed function netif_matches_ip6_addr() to netif_get_ip6_addr_match() + + 2014-02-25: Simon Goldschmidt + * igmp.c: fixed bug #39145 IGMP membership report for 224.0.0.1 + + 2014-02-22: Simon Goldschmidt (patch by Amir Shalem) + * etharp.c, opt.h: fixed bug #34681 Limit ARP queue length by ARP_QUEUE_LEN (=3) + + 2014-02-22: Simon Goldschmidt (patch by Amir Shalem) + * etharp.h/.c: fixed bug #34682 Limit ARP request flood for unresolved entry + + 2014-02-20: Simon Goldschmidt + * tcp_out.c: fixed bug #39683 Assertion "seg->tcphdr not aligned" failed with + MEM_ALIGNMENT = 8 + + 2014-02-20: Simon Goldschmidt + * sockets.c: fixed bug #39882 No function shall set errno to 0 + + 2014-02-20: Simon Goldschmidt + * mib_structs.c: fixed bug #40050 SNMP problem with MIB arrays > 255 + + 2014-02-20: Simon Goldschmidt + * api.h, sockets.c: fixed bug #41499 netconn::recv_avail can overflow + + 2014-01-08: Stathis Voukelatos + * memp_std.h: patch #7928 Fixed size calculation in MALLOC memory pool + creation macro + + 2014-01-18: Brian Fahs + * tcp_out.c: patch #8237: tcp_rexmit_rto fails to update pcb->unsent_oversize + when necessary + + 2014-01-17: Grant Erickson, Jay Logue, Simon Goldschmidt + * ipv6.c, netif.c: patch #7913 Enable Support for IPv6 Loopback + + 2014-01-16: Stathis Voukelatos + * netif.c: patch #7902 Fixed netif_poll() operation when LWIP_LOOPBACK_MAX_PBUFS > 0 + + 2014-01-14: "Freddie Chopin" + * snmp.h, mib2.c: fixed constness and spelling of sysdescr + + 2014-01-14: Simon Goldschmidt (patch by Thomas Faber) + * tcpip.c: patch #8241: Fix implicit declaration of ip_input with + LWIP_TCPIP_CORE_LOCKING_INPUT disabled + + 2014-01-14: chrysn + * timers.c: patch #8244 make timeouts usable reliably from outside of the + timeout routine + + 2014-01-10: Simon Goldschmidt + * ip_frag.c, ip6_frag.c: fixed bug #41041 Potential use-after-free in IPv6 reassembly + + 2014-01-10: Simon Goldschmidt + * memp.c: fixed bug #41188 Alignment error in memp_init() when MEMP_SEPARATE_POOLS==1 + + 2014-01-10: Simon Goldschmidt + * tcp.c: fixed bug #39898 tcp_fasttmr() possible lock due to infinte queue process loop + + 2013-06-29: Simon Goldschmidt + * inet.h, sockets.h: partially fixed bug #37585: IPv6 compatibility (in socket structs) + + 2013-06-29: Simon Goldschmidt + * inet6.h: bug #37585/task #12600: fixed struct in6_addr.s6_addr to conform to spec + + 2013-04-24: patch by Liam + * api_msg.c: patch #8008 Fix a potential null pointer dereference in assert + + 2013-04-24: Simon Goldschmidt + * igmp.c: fixed possible division by zero + + 2013-04-24: Simon Goldschmidt + * ip6.h, some ipv6 C files: fixed bug #38526 Coverity: Recursive Header Inclusion in ip6.h + + 2013-04-24: Simon Goldschmidt (patch by Emil Ljungdahl): + * netif.c: fixed bug #38586 netif_loop_output() "deadlocks" + + 2013-01-15: Simon Goldschmidt + * ip4.c: fixed bug #37665 ip_canforward operates on address in wrong byte order + + 2013-01-15: Simon Goldschmidt + * pbuf.h: fixed bug #38097 pbuf_free_ooseq() warning + + 2013-01-14: Simon Goldschmidt + * dns.c: fixed bug #37705 Possible memory corruption in DNS query + + 2013-01-11: Simon Goldschmidt + * raw.c: fixed bug #38066 Raw pcbs can alter packet without eating it + + 2012-08-22: Simon Goldschmidt + * memp.c: fixed bug #37166: memp_sanity check loops itself + + 2012-08-13: Simon Goldschmidt + * dhcp.c: fixed bug #36645: Calling dhcp_release before dhcp_start + dereferences NULL + + 2012-08-13: Simon Goldschmidt + * msg_out.c: fixed bug #36840 snmp_send_trap() NULL de-reference if traps + configured but no interfaces available + + 2012-08-13: Simon Goldschmidt + * dns.c: fixed bug #36899 DNS TTL 0 is cached for a long time + + 2012-05-11: Simon Goldschmidt (patch by Marty) + * memp.c: fixed bug #36412: memp.c does not compile when + MEMP_OVERFLOW_CHECK > zero and MEMP_SEPARATE_POOLS == 1 + + 2012-05-03: Simon Goldschmidt (patch by Sylvain Rochet) + * ppp.c: fixed bug #36283 (PPP struct used on header size computation and + not packed) + + 2012-05-03: Simon Goldschmidt (patch by David Empson) + * ppp.c: fixed bug #36388 (PPP: checksum-only in last pbuf leads to pbuf with + zero length) + + 2012-03-25: Simon Goldschmidt + * api_msg.c: Fixed bug #35817: do_connect() invalidly signals op_completed + for UDP/RAW with LWIP_TCPIP_CORE_LOCKING==1 + + 2012-03-25: Simon Goldschmidt + * api_msg.h, api_lib.c, api_msg.c, netifapi.c: fixed bug #35931: Name space + pollution in api_msg.c and netifapi.c + + 2011-08-24: Simon Goldschmidt + * inet6.h: fixed bug #34124 struct in6_addr does not conform to the standard + + + +(STABLE-1.4.1) + + ++ New features: + + 2012-03-25: Simon Goldschmidt (idea by Mason) + * posix/*: added posix-compatibility include files posix/netdb.h and posix/sys/socket.h + which are a simple wrapper to the correct lwIP include files. + + 2012-01-16: Simon Goldschmidt + * opt.h, icmp.c: Added option CHECKSUM_GEN_ICMP + + 2011-12-17: Simon Goldschmidt + * ip.h: implemented API functions to access so_options of IP pcbs (UDP, TCP, RAW) + (fixes bug #35061) + + 2011-09-27: Simon Goldschmidt + * opt.h, tcp.c, tcp_in.c: Implemented limiting data on ooseq queue (task #9989) + (define TCP_OOSEQ_MAX_BYTES / TCP_OOSEQ_MAX_PBUFS in lwipopts.h) + + 2011-09-21: Simon Goldschmidt + * opt.h, api.h, api_lib.c, api_msg.h/.c, sockets.c: Implemented timeout on + send (TCP only, bug #33820) + + 2011-09-21: Simon Goldschmidt + * init.c: Converted runtime-sanity-checks into compile-time checks that can + be disabled (since runtime checks can often not be seen on embedded targets) + + 2011-09-11: Simon Goldschmidt + * ppp.h, ppp_impl.h: splitted ppp.h to an internal and external header file + to get a clear separation of which functions an application or port may use + (task #11281) + + 2011-09-11: Simon Goldschmidt + * opt.h, tcp_impl.h, tcp.c, udp.h/.c: Added a config option to randomize + initial local TCP/UDP ports (so that different port ranges are used after + a reboot; bug #33818; this one added tcp_init/udp_init functions again) + + 2011-09-03: Simon Goldschmidt + * dhcp.c: DHCP uses LWIP_RAND() for xid's (bug #30302) + + 2011-08-24: Simon Goldschmidt + * opt.h, netif.h/.c: added netif remove callback (bug #32397) + + 2011-07-26: Simon Goldschmidt + * etharp.c: ETHARP_SUPPORT_VLAN: add support for an external VLAN filter + function instead of only checking for one VLAN (define ETHARP_VLAN_CHECK_FN) + + 2011-07-21: Simon Goldschmidt (patch by hanhui) + * ip4.c, etharp.c, pbuf.h: bug #33634 ip_forward() have a faulty behaviour: + Added pbuf flags to mark incoming packets as link-layer broadcast/multicast. + Also added code to allow ip_forward() to forward non-broadcast packets to + the input netif (set IP_FORWARD_ALLOW_TX_ON_RX_NETIF==1). + + 2011-06-26: Simon Goldschmidt (patch by Cameron Gutman) + * tcp.c, tcp_out.c: bug #33604: added some more asserts to check that + pcb->state != LISTEN + + 2011-05-14: Simon Goldschmidt (patch by Stéphane Lesage) + * tcpip.c/.h: patch #7449 allow tcpip callback from interrupt with static + memory message + + + ++ Bugfixes: + + 2012-09-26: Simon Goldschmidt + * api_msg.c: fixed bug #37405 'err_tcp()' uses already freed 'netconn' object + + 2012-09-26: patch by Henrik Persson + * dhcp.c: patch #7843 Fix corner case with dhcp timeouts + + 2012-09-26: patch by Henrik Persson + * dhcp.c: patch #7840 Segfault in dhcp_parse_reply if no end marker in dhcp packet + + 2012-08-22: Simon Goldschmidt + * memp.c: fixed bug #37166: memp_sanity check loops itself + + 2012-05-08: Simon Goldschmidt + * tcp_out.c: fixed bug: #36380 unsent_oversize mismatch in 1.4.1RC1 (this was + a debug-check issue only) + + 2012-03-27: Simon Goldschmidt + * vj.c: fixed bug #35756 header length calculation problem in ppp/vj.c + + 2012-03-27: Simon Goldschmidt (patch by Mason) + * tcp_out.c: fixed bug #35945: SYN packet should provide the recv MSS not the + send MSS + + 2012-03-22: Simon Goldschmidt + * ip4.c: fixed bug #35927: missing refragmentaion in ip_forward + + 2012-03-20: Simon Goldschmidt (patch by Mason) + * netdb.c: fixed bug #35907: lwip_gethostbyname_r returns an invalid h_addr_list + + 2012-03-12: Simon Goldschmidt (patch by Bostjan Meglic) + * ppp.c: fixed bug #35809: PPP GetMask(): Compiler warning on big endian, + possible bug on little endian system + + 2012-02-23: Simon Goldschmidt + * etharp.c: fixed bug #35595: Impossible to send broadcast without a gateway + (introduced when fixing bug# 33551) + + 2012-02-16: Simon Goldschmidt + * ppp.c: fixed pbuf leak when PPP session is aborted through pppSigHUP() + (bug #35541: PPP Memory Leak) + + 2012-02-16: Simon Goldschmidt + * etharp.c: fixed bug #35531: Impossible to send multicast without a gateway + (introduced when fixing bug# 33551) + + 2012-02-16: Simon Goldschmidt (patch by Stéphane Lesage) + * msg_in.c, msg_out.c: fixed bug #35536 SNMP: error too big response is malformed + + 2012-02-15: Simon Goldschmidt + * init.c: fixed bug #35537: MEMP_NUM_* sanity checks should be disabled with + MEMP_MEM_MALLOC==1 + + 2012-02-12: Simon Goldschmidt + * tcp.h, tcp_in.c, tcp_out.c: partly fixed bug #25882: TCP hangs on + MSS > pcb->snd_wnd (by not creating segments bigger than half the window) + + 2012-02-11: Simon Goldschmidt + * tcp.c: fixed bug #35435: No pcb state check before adding it to time-wait + queue while closing + + 2012-01-22: Simon Goldschmidt + * tcp.c, tcp_in.c: fixed bug #35305: pcb may be freed too early on shutdown(WR) + + 2012-01-21: Simon Goldschmidt + * tcp.c: fixed bug #34636: FIN_WAIT_2 - Incorrect shutdown of TCP pcb + + 2012-01-20: Simon Goldschmidt + * dhcp.c: fixed bug #35151: DHCP asserts on incoming option lengths + + 2012-01-20: Simon Goldschmidt + * pbuf.c: fixed bug #35291: NULL pointer in pbuf_copy + + 2011-11-25: Simon Goldschmidt + * tcp.h/.c, tcp_impl.h, tcp_in.c: fixed bug #31177: tcp timers can corrupt + tcp_active_pcbs in some cases + + 2011-11-23: Simon Goldschmidt + * sys.c: fixed bug #34884: sys_msleep() body needs to be surrounded with + '#ifndef sys_msleep' + + 2011-11-22: Simon Goldschmidt + * netif.c, etharp.h/.c: fixed bug #34684: Clear the arp table cache when + netif is brought down + + 2011-10-28: Simon Goldschmidt + * tcp_in.c: fixed bug #34638: Dead code in tcp_receive - pcb->dupacks + + 2011-10-23: Simon Goldschmidt + * mem.c: fixed bug #34429: possible memory corruption with + LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT set to 1 + + 2011-10-18: Simon Goldschmidt + * arch.h, netdb.c: fixed bug #34592: lwip_gethostbyname_r uses nonstandard + error value + + 2011-10-18: Simon Goldschmidt + * opt.h: fixed default values of TCP_SNDLOWAT and TCP_SNDQUEUELOWAT for small + windows (bug #34176 select after non-blocking send times out) + + 2011-10-18: Simon Goldschmidt + * tcp_impl.h, tcp_out.c: fixed bug #34587: TCP_BUILD_MSS_OPTION doesn't + consider netif->mtu, causes slow network + + 2011-10-18: Simon Goldschmidt + * sockets.c: fixed bug #34581 missing parentheses in udplite sockets code + + 2011-10-18: Simon Goldschmidt + * sockets.h: fixed bug #34580 fcntl() is missing in LWIP_COMPAT_SOCKETS + + 2011-10-17: Simon Goldschmidt + * api_msg.c: fixed bug #34569: shutdown(SHUT_WR) crashes netconn/socket api + + 2011-10-13: Simon Goldschmidt + * tcp_in.c, tcp_out.c: fixed bug #34517 (persist timer is started although no + zero window is received) by starting the persist timer when a zero window is + received, not when we have more data queued for sending than fits into the + window + + 2011-10-13: Simon Goldschmidt + * def.h, timers.c: fixed bug #34541: LWIP_U32_DIFF is unnecessarily complex + + 2011-10-13: Simon Goldschmidt + * sockets.c, api_lib.c: fixed bug #34540: compiler error when CORE_LOCKING is + used and not all protocols are enabled + + 2011-10-12: Simon Goldschmidt + * pbuf.c: fixed bug #34534: Error in sending fragmented IP if MEM_ALIGNMENT > 4 + + 2011-10-09: Simon Goldschmidt + * tcp_out.c: fixed bug #34426: tcp_zero_window_probe() transmits incorrect + byte value when pcb->unacked != NULL + + 2011-10-09: Simon Goldschmidt + * ip4.c: fixed bug #34447 LWIP_IP_ACCEPT_UDP_PORT(dst_port) wrong + + 2011-09-27: Simon Goldschmidt + * tcp_in.c, tcp_out.c: Reset pcb->unsent_oversize in 2 more places... + + 2011-09-27: Simon Goldschmidt + * tcp_in.c: fixed bug #28288: Data after FIN in oos queue + + 2011-09-27: Simon Goldschmidt + * dhcp.c: fixed bug #34406 dhcp_option_hostname() can overflow the pbuf + + 2011-09-24: Simon Goldschmidt + * mem.h: fixed bug #34377 MEM_SIZE_F is not defined if MEM_LIBC_MALLOC==1 + + 2011-09-23: Simon Goldschmidt + * pbuf.h, tcp.c, tcp_in.c: fixed bug #33871: rejecting TCP_EVENT_RECV() for + the last packet including FIN can lose data + + 2011-09-22: Simon Goldschmidt + * tcp_impl.h: fixed bug #34355: nagle does not take snd_buf/snd_queuelen into + account + + 2011-09-21: Simon Goldschmidt + * opt.h: fixed default value of TCP_SND_BUF to not violate the sanity checks + in init.c + + 2011-09-20: Simon Goldschmidt + * timers.c: fixed bug #34337 (possible NULL pointer in sys_check_timeouts) + + 2011-09-11: Simon Goldschmidt + * tcp_out.c: use pcb->mss instead of TCP_MSS for preallocate mss-sized pbufs + (bug #34019) + + 2011-09-09: Simon Goldschmidt + * udp.c: fixed bug #34072: UDP broadcast is received from wrong UDP pcb if + udp port matches + + 2011-09-03: Simon Goldschmidt + * tcp_in.c: fixed bug #33952 PUSH flag in incoming packet is lost when packet + is aggregated and sent to application + + 2011-09-01: Simon Goldschmidt + * opt.h: fixed bug #31809 LWIP_EVENT_API in opts.h is inconsistent compared + to other options + + 2011-09-01: Simon Goldschmidt + * tcp_in.c: fixed bug #34111 RST for ACK to listening pcb has wrong seqno + + 2011-08-24: Simon Goldschmidt + * api_msg.c, sockets.c: fixed bug #33956 Wrong error returned when calling + accept() on UDP connections + + 2011-08-24: Simon Goldschmidt + * sockets.h: fixed bug #34057 socklen_t should be a typedef + + 2011-08-24: Simon Goldschmidt + * pbuf.c: fixed bug #34112 Odd check in pbuf_alloced_custom (typo) + + 2011-08-24: Simon Goldschmidt + * dhcp.c: fixed bug #34122 dhcp: hostname can overflow + + 2011-08-24: Simon Goldschmidt + * netif.c: fixed bug #34121 netif_add/netif_set_ipaddr fail on NULL ipaddr + + 2011-08-22: Simon Goldschmidt + * tcp_out.c: fixed bug #33962 TF_FIN not always set after FIN is sent. (This + merely prevents nagle from not transmitting fast after closing.) + + 2011-07-22: Simon Goldschmidt + * api_lib.c, api_msg.c, sockets.c, api.h: fixed bug #31084 (socket API returns + always EMSGSIZE on non-blocking sockets if data size > send buffers) -> now + lwip_send() sends as much as possible for non-blocking sockets + + 2011-07-22: Simon Goldschmidt + * pbuf.c/.h, timers.c: freeing ooseq pbufs when the pbuf pool is empty implemented + for NO_SYS==1: when not using sys_check_timeouts(), call PBUF_CHECK_FREE_OOSEQ() + at regular intervals from main level. + + 2011-07-21: Simon Goldschmidt + * etharp.c: fixed bug #33551 (ARP entries may time out although in use) by + sending an ARP request when an ARP entry is used in the last minute before + it would time out. + + 2011-07-04: Simon Goldschmidt + * sys_arch.txt: Fixed documentation after changing sys arch prototypes for 1.4.0. + + 2011-06-26: Simon Goldschmidt + * tcp.c: fixed bug #31723 (tcp_kill_prio() kills pcbs with the same prio) by + updating its documentation only. + + 2011-06-26: Simon Goldschmidt + * mem.c: fixed bug #33545: With MEM_USE_POOLS==1, mem_malloc can return an + unaligned pointer. + + 2011-06-26: Simon Goldschmidt + * mem.c: fixed bug #33544 "warning in mem.c in lwip 1.4.0 with NO_SYS=1" + + 2011-05-25: Simon Goldschmidt + * tcp.c: fixed bug #33398 (pointless conversion when checking TCP port range) + + + +(STABLE-1.4.0) + + ++ New features: + + 2011-03-27: Simon Goldschmidt + * tcp_impl.h, tcp_in.c, tcp_out.c: Removed 'dataptr' from 'struct tcp_seg' and + calculate it in tcp_zero_window_probe (the only place where it was used). + + 2010-11-21: Simon Goldschmidt + * dhcp.c/.h: Added a function to deallocate the struct dhcp from a netif + (fixes bug #31525). + + 2010-07-12: Simon Goldschmidt (patch by Stephane Lesage) + * ip.c, udp.c/.h, pbuf.h, sockets.c: task #10495: Added support for + IP_MULTICAST_LOOP at socket- and raw-API level. + + 2010-06-16: Simon Goldschmidt + * ip.c: Added an optional define (LWIP_IP_ACCEPT_UDP_PORT) that can allow + link-layer-addressed UDP traffic to be received while a netif is down (just + like DHCP during configuration) + + 2010-05-22: Simon Goldschmidt + * many many files: bug #27352: removed packing from ip_addr_t, the packed + version is now only used in protocol headers. Added global storage for + current src/dest IP address while in input functions. + + 2010-05-16: Simon Goldschmidt + * def.h: task #10391: Add preprocessor-macros for compile-time htonl + calculation (and use them throughout the stack where applicable) + + 2010-05-16: Simon Goldschmidt + * opt.h, memp_std.h, memp.c, ppp_oe.h/.c: PPPoE now uses its own MEMP pool + instead of the heap (moved struct pppoe_softc from ppp_oe.c to ppp_oe.h) + + 2010-05-16: Simon Goldschmidt + * opt.h, memp_std.h, dns.h/.c: DNS_LOCAL_HOSTLIST_IS_DYNAMIC uses its own + MEMP pool instead of the heap + + 2010-05-13: Simon Goldschmidt + * tcp.c, udp.c: task #6995: Implement SO_REUSEADDR (correctly), added + new option SO_REUSE_RXTOALL to pass received UDP broadcast/multicast + packets to more than one pcb. + + 2010-05-02: Simon Goldschmidt + * netbuf.h/.c, sockets.c, api_msg.c: use checksum-on-copy for sending + UDP data for LWIP_NETIF_TX_SINGLE_PBUF==1 + + 2010-04-30: Simon Goldschmidt + * udp.h/.c, pbuf.h/.c: task #6849: added udp_send(_to/_if) functions that + take a precalculated checksum, added pbuf_fill_chksum() to copy data + into a pbuf and at the same time calculating the checksum for that data + + 2010-04-29: Simon Goldschmidt + * ip_addr.h, etharp.h/.c, autoip.c: Create overridable macros for copying + 2-byte-aligned IP addresses and MAC addresses + + 2010-04-28: Patch by Bill Auerbach + * ip.c: Inline generating IP checksum to save a function call + + 2010-04-14: Simon Goldschmidt + * tcpip.h/.c, timers.c: Added an overridable define to get informed when the + tcpip_thread processes messages or timeouts to implement a watchdog. + + 2010-03-28: Simon Goldschmidt + * ip_frag.c: create a new (contiguous) PBUF_RAM for every outgoing + fragment if LWIP_NETIF_TX_SINGLE_PBUF==1 + + 2010-03-27: Simon Goldschmidt + * etharp.c: Speedup TX by moving code from find_entry to etharp_output/ + etharp_query to prevent unnecessary function calls (inspired by + patch #7135). + + 2010-03-20: Simon Goldschmidt + * opt.h, tcpip.c/.h: Added an option to disable tcpip_(un)timeout code + since the linker cannot do this automatically to save space. + + 2010-03-20: Simon Goldschmidt + * opt.h, etharp.c/.h: Added support for static ARP table entries + + 2010-03-14: Simon Goldschmidt + * tcp_impl.h, tcp_out.c, inet_chksum.h/.c: task #6849: Calculate checksum + when creating TCP segments, not when (re-)transmitting them. + + 2010-03-07: Simon Goldschmidt + * sockets.c: bug #28775 (select/event_callback: only check select_cb_list + on change) plus use SYS_LIGHTWEIGHT_PROT to protect the select code. + This should speed up receiving data on sockets as the select code in + event_callback is only executed when select is waiting. + + 2010-03-06: Simon Goldschmidt + * tcp_out.c: task #7013 (Create option to have all packets delivered to + netif->output in one piece): Always copy to try to create single pbufs + in tcp_write. + + 2010-03-06: Simon Goldschmidt + * api.h, api_lib.c, sockets.c: task #10167 (sockets: speed up TCP recv + by not allocating a netbuf): added function netconn_recv_tcp_pbuf() + for tcp netconns to receive pbufs, not netbufs; use that function + for tcp sockets. + + 2010-03-05: Jakob Ole Stoklundsen / Simon Goldschmidt + * opt.h, tcp.h, tcp_impl.h, tcp.c, tcp_in.c, tcp_out.c: task #7040: + Work on tcp_enqueue: Don't waste memory when chaining segments, + added option TCP_OVERSIZE to prevent creating many small pbufs when + calling tcp_write with many small blocks of data. Instead, pbufs are + allocated larger than needed and the space is used for later calls to + tcp_write. + + 2010-02-21: Simon Goldschmidt + * stats.c/.h: Added const char* name to mem- and memp-stats for easier + debugging. + + 2010-02-21: Simon Goldschmidt + * tcp.h (and usages), added tcp_impl.h: Splitted API and internal + implementation of tcp to make API usage cleare to application programmers + + 2010-02-14: Simon Goldschmidt/Stephane Lesage + * ip_addr.h: Improved some defines working on ip addresses, added faster + macro to copy addresses that cannot be NULL + + 2010-02-13: Simon Goldschmidt + * api.h, api_lib.c, api_msg.c, sockets.c: task #7865 (implement non- + blocking send operation) + + 2010-02-12: Simon Goldschmidt + * sockets.c/.h: Added a minimal version of posix fctl() to have a + standardised way to set O_NONBLOCK for nonblocking sockets. + + 2010-02-12: Simon Goldschmidt + * dhcp.c/.h, autoip.c/.h: task #10139 (Prefer statically allocated + memory): added autoip_set_struct() and dhcp_set_struct() to let autoip + and dhcp work with user-allocated structs instead of callin mem_malloc + + 2010-02-12: Simon Goldschmidt/Jeff Barber + * tcp.c/h: patch #6865 (SO_REUSEADDR for TCP): if pcb.so_options has + SOF_REUSEADDR set, allow binding to endpoint in TIME_WAIT + + 2010-02-12: Simon Goldschmidt + * sys layer: task #10139 (Prefer statically allocated memory): converted + mbox and semaphore functions to take pointers to sys_mbox_t/sys_sem_t; + converted sys_mbox_new/sys_sem_new to take pointers and return err_t; + task #7212: Add Mutex concept in sys_arch (define LWIP_COMPAT_MUTEX + to let sys.h use binary semaphores instead of mutexes - as before) + + 2010-02-09: Simon Goldschmidt (Simon Kallweit) + * timers.c/.h: Added function sys_restart_timeouts() from patch #7085 + (Restart system timeout handling) + + 2010-02-09: Simon Goldschmidt + * netif.c/.h, removed loopif.c/.h: task #10153 (Integrate loopif into + netif.c) - loopif does not have to be created by the port any more, + just define LWIP_HAVE_LOOPIF to 1. + + 2010-02-08: Simon Goldschmidt + * inet.h, ip_addr.c/.h: Added reentrant versions of inet_ntoa/ipaddr_ntoa + inet_ntoa_r/ipaddr_ntoa_r + + 2010-02-08: Simon Goldschmidt + * netif.h: Added netif_s/get_igmp_mac_filter() macros + + 2010-02-05: Simon Goldschmidt + * netif.h: Added function-like macros to get/set the hostname on a netif + + 2010-02-04: Simon Goldschmidt + * nearly every file: Replaced struct ip_addr by typedef ip_addr_t to + make changing the actual implementation behind the typedef easier. + + 2010-02-01: Simon Goldschmidt + * opt.h, memp_std.h, dns.h, netdb.c, memp.c: Let netdb use a memp pool + for allocating memory when getaddrinfo() is called. + + 2010-01-31: Simon Goldschmidt + * dhcp.h, dhcp.c: Reworked the code that parses DHCP options: parse + them once instead of parsing for every option. This also removes + the need for mem_malloc from dhcp_recv and makes it possible to + correctly retrieve the BOOTP file. + + 2010-01-30: simon Goldschmidt + * sockets.c: Use SYS_LIGHTWEIGHT_PROT instead of a semaphore to protect + the sockets array. + + 2010-01-29: Simon Goldschmidt (patch by Laura Garrett) + * api.h, api_msg.c, sockets.c: Added except set support in select + (patch #6860) + + 2010-01-29: Simon Goldschmidt (patch by Laura Garrett) + * api.h, sockets.h, err.h, api_lib.c, api_msg.c, sockets.c, err.c: + Add non-blocking support for connect (partly from patch #6860), + plus many cleanups in socket & netconn API. + + 2010-01-27: Simon Goldschmidt + * opt.h, tcp.h, init.c, api_msg.c: Added TCP_SNDQUEUELOWAT corresponding + to TCP_SNDLOWAT and added tcp_sndqueuelen() - this fixes bug #28605 + + 2010-01-26: Simon Goldschmidt + * snmp: Use memp pools for snmp instead of the heap; added 4 new pools. + + 2010-01-14: Simon Goldschmidt + * ppp.c/.h: Fixed bug #27856: PPP: Set netif link- and status-callback + by adding ppp_set_netif_statuscallback()/ppp_set_netif_linkcallback() + + 2010-01-13: Simon Goldschmidt + * mem.c: The heap now may be moved to user-defined memory by defining + LWIP_RAM_HEAP_POINTER as a void pointer to that memory's address + (patch #6966 and bug #26133) + + 2010-01-10: Simon Goldschmidt (Bill Auerbach) + * opt.h, memp.c: patch #6822 (Add option to place memory pools in + separate arrays) + + 2010-01-10: Simon Goldschmidt + * init.c, igmp.c: patch #6463 (IGMP - Adding Random Delay): added define + LWIP_RAND() for lwip-wide randomization (to be defined in cc.h) + + 2009-12-31: Simon Goldschmidt + * tcpip.c, init.c, memp.c, sys.c, memp_std.h, sys.h, tcpip.h + added timers.c/.h: Separated timer implementation from semaphore/mbox + implementation, moved timer implementation to timers.c/.h, timers are + now only called from tcpip_thread or by explicitly checking them. + (TASK#7235) + + 2009-12-27: Simon Goldschmidt + * opt.h, etharp.h/.c, init.c, tcpip.c: Added an additional option + LWIP_ETHERNET to support ethernet without ARP (necessary for pure PPPoE) + + + ++ Bugfixes: + + 2011-04-20: Simon Goldschmidt + * sys_arch.txt: sys_arch_timeouts() is not needed any more. + + 2011-04-13: Simon Goldschmidt + * tcp.c, udp.c: Fixed bug #33048 (Bad range for IP source port numbers) by + using ports in the IANA private/dynamic range (49152 through 65535). + + 2011-03-29: Simon Goldschmidt, patch by Emil Lhungdahl: + * etharp.h/.c: Fixed broken VLAN support. + + 2011-03-27: Simon Goldschmidt + * tcp.c: Fixed bug #32926 (TCP_RMV(&tcp_bound_pcbs) is called on unbound tcp + pcbs) by checking if the pcb was bound (local_port != 0). + + 2011-03-27: Simon Goldschmidt + * ppp.c: Fixed bug #32280 (ppp: a pbuf is freed twice) + + 2011-03-27: Simon Goldschmidt + * sockets.c: Fixed bug #32906: lwip_connect+lwip_send did not work for udp and + raw pcbs with LWIP_TCPIP_CORE_LOCKING==1. + + 2011-03-27: Simon Goldschmidt + * tcp_out.c: Fixed bug #32820 (Outgoing TCP connections created before route + is present never times out) by starting retransmission timer before checking + route. + + 2011-03-22: Simon Goldschmidt + * ppp.c: Fixed bug #32648 (PPP code crashes when terminating a link) by only + calling sio_read_abort() if the file descriptor is valid. + + 2011-03-14: Simon Goldschmidt + * err.h/.c, sockets.c, api_msg.c: fixed bug #31748 (Calling non-blocking connect + more than once can render a socket useless) since it mainly involves changing + "FATAL" classification of error codes: ERR_USE and ERR_ISCONN just aren't fatal. + + 2011-03-13: Simon Goldschmidt + * sockets.c: fixed bug #32769 (ESHUTDOWN is linux-specific) by fixing + err_to_errno_table (ERR_CLSD: ENOTCONN instead of ESHUTDOWN), ERR_ISCONN: + use EALRADY instead of -1 + + 2011-03-13: Simon Goldschmidt + * api_lib.c: netconn_accept: return ERR_ABRT instead of ERR_CLSD if the + connection has been aborted by err_tcp (since this is not a normal closing + procedure). + + 2011-03-13: Simon Goldschmidt + * tcp.c: tcp_bind: return ERR_VAL instead of ERR_ISCONN when trying to bind + with pcb->state != CLOSED + + 2011-02-17: Simon Goldschmidt + * rawapi.txt: Fixed bug #32561 tcp_poll argument definition out-of-order in + documentation + + 2011-02-17: Simon Goldschmidt + * many files: Added missing U/UL modifiers to fix 16-bit-arch portability. + + 2011-01-24: Simon Goldschmidt + * sockets.c: Fixed bug #31741: lwip_select seems to have threading problems + + 2010-12-02: Simon Goldschmidt + * err.h: Fixed ERR_IS_FATAL so that ERR_WOULDBLOCK is not fatal. + + 2010-11-23: Simon Goldschmidt + * api.h, api_lib.c, api_msg.c, sockets.c: netconn.recv_avail is only used for + LWIP_SO_RCVBUF and ioctl/FIONREAD. + + 2010-11-23: Simon Goldschmidt + * etharp.c: Fixed bug #31720: ARP-queueing: RFC 1122 recommends to queue at + least 1 packet -> ARP_QUEUEING==0 now queues the most recent packet. + + 2010-11-23: Simon Goldschmidt + * tcp_in.c: Fixed bug #30577: tcp_input: don't discard ACK-only packets after + refusing 'refused_data' again. + + 2010-11-22: Simon Goldschmidt + * sockets.c: Fixed bug #31590: getsockopt(... SO_ERROR ...) gives EINPROGRESS + after a successful nonblocking connection. + + 2010-11-22: Simon Goldschmidt + * etharp.c: Fixed bug #31722: IP packets sent with an AutoIP source addr + must be sent link-local + + 2010-11-22: Simon Goldschmidt + * timers.c: patch #7329: tcp_timer_needed prototype was ifdef'ed out for + LWIP_TIMERS==0 + + 2010-11-20: Simon Goldschmidt + * sockets.c: Fixed bug #31170: lwip_setsockopt() does not set socket number + + 2010-11-20: Simon Goldschmidt + * sockets.h: Fixed bug #31304: Changed SHUT_RD, SHUT_WR and SHUT_RDWR to + resemble other stacks. + + 2010-11-20: Simon Goldschmidt + * dns.c: Fixed bug #31535: TCP_SND_QUEUELEN must be at least 2 or else + no-copy TCP writes will never succeed. + + 2010-11-20: Simon Goldschmidt + * dns.c: Fixed bug #31701: Error return value from dns_gethostbyname() does + not match documentation: return ERR_ARG instead of ERR_VAL if not + initialized or wrong argument. + + 2010-10-20: Simon Goldschmidt + * sockets.h: Fixed bug #31385: sizeof(struct sockaddr) is 30 but should be 16 + + 2010-10-05: Simon Goldschmidt + * dhcp.c: Once again fixed #30038: DHCP/AutoIP cooperation failed when + replugging the network cable after an AutoIP address was assigned. + + 2010-08-10: Simon Goldschmidt + * tcp.c: Fixed bug #30728: tcp_new_port() did not check listen pcbs + + 2010-08-03: Simon Goldschmidt + * udp.c, raw.c: Don't chain empty pbufs when sending them (fixes bug #30625) + + 2010-08-01: Simon Goldschmidt (patch by Greg Renda) + * ppp.c: Applied patch #7264 (PPP protocols are rejected incorrectly on big + endian architectures) + + 2010-07-28: Simon Goldschmidt + * api_lib.c, api_msg.c, sockets.c, mib2.c: Fixed compilation with TCP or UDP + disabled. + + 2010-07-27: Simon Goldschmidt + * tcp.c: Fixed bug #30565 (tcp_connect() check bound list): that check did no + harm but never did anything + + 2010-07-21: Simon Goldschmidt + * ip.c: Fixed invalid fix for bug #30402 (CHECKSUM_GEN_IP_INLINE does not + add IP options) + + 2010-07-16: Kieran Mansley + * msg_in.c: Fixed SNMP ASN constant defines to not use ! operator + + 2010-07-10: Simon Goldschmidt + * ip.c: Fixed bug #30402: CHECKSUM_GEN_IP_INLINE does not add IP options + + 2010-06-30: Simon Goldschmidt + * api_msg.c: fixed bug #30300 (shutdown parameter was not initialized in + netconn_delete) + + 2010-06-28: Kieran Mansley + * timers.c remove unportable printing of C function pointers + + 2010-06-24: Simon Goldschmidt + * init.c, timers.c/.h, opt.h, memp_std.h: From patch #7221: added flag + NO_SYS_NO_TIMERS to drop timer support for NO_SYS==1 for easier upgrading + + 2010-06-24: Simon Goldschmidt + * api(_lib).c/.h, api_msg.c/.h, sockets.c/.h: Fixed bug #10088: Correctly + implemented shutdown at socket level. + + 2010-06-21: Simon Goldschmidt + * pbuf.c/.h, ip_frag.c/.h, opt.h, memp_std.h: Fixed bug #29361 (ip_frag has + problems with zero-copy DMA MACs) by adding custom pbufs and implementing + custom pbufs that reference other (original) pbufs. Additionally set + IP_FRAG_USES_STATIC_BUF=0 as default to be on the safe side. + + 2010-06-15: Simon Goldschmidt + * dhcp.c: Fixed bug #29970: DHCP endian issue parsing option responses + + 2010-06-14: Simon Goldschmidt + * autoip.c: Fixed bug #30039: AutoIP does not reuse previous addresses + + 2010-06-12: Simon Goldschmidt + * dhcp.c: Fixed bug #30038: dhcp_network_changed doesn't reset AUTOIP coop + state + + 2010-05-17: Simon Goldschmidt + * netdb.c: Correctly NULL-terminate h_addr_list + + 2010-05-16: Simon Goldschmidt + * def.h/.c: changed the semantics of LWIP_PREFIX_BYTEORDER_FUNCS to prevent + "symbol already defined" i.e. when linking to winsock + + 2010-05-05: Simon Goldschmidt + * def.h, timers.c: Fixed bug #29769 (sys_check_timeouts: sys_now() may + overflow) + + 2010-04-21: Simon Goldschmidt + * api_msg.c: Fixed bug #29617 (sometime cause stall on delete listening + connection) + + 2010-03-28: Luca Ceresoli + * ip_addr.c/.h: patch #7143: Add a few missing const qualifiers + + 2010-03-27: Luca Ceresoli + * mib2.c: patch #7130: remove meaningless const qualifiers + + 2010-03-26: Simon Goldschmidt + * tcp_out.c: Make LWIP_NETIF_TX_SINGLE_PBUF work for TCP, too + + 2010-03-26: Simon Goldschmidt + * various files: Fixed compiling with different options disabled (TCP/UDP), + triggered by bug #29345; don't allocate acceptmbox if LWIP_TCP is disabled + + 2010-03-25: Simon Goldschmidt + * sockets.c: Fixed bug #29332: lwip_select() processes readset incorrectly + + 2010-03-25: Simon Goldschmidt + * tcp_in.c, test_tcp_oos.c: Fixed bug #29080: Correctly handle remote side + overrunning our rcv_wnd in ooseq case. + + 2010-03-22: Simon Goldschmidt + * tcp.c: tcp_listen() did not copy the pcb's prio. + + 2010-03-19: Simon Goldschmidt + * snmp_msg.c: Fixed bug #29256: SNMP Trap address was not correctly set + + 2010-03-14: Simon Goldschmidt + * opt.h, etharp.h: Fixed bug #29148 (Incorrect PBUF_POOL_BUFSIZE for ports + where ETH_PAD_SIZE > 0) by moving definition of ETH_PAD_SIZE to opt.h + and basing PBUF_LINK_HLEN on it. + + 2010-03-08: Simon Goldschmidt + * netif.c, ipv4/ip.c: task #10241 (AutoIP: don't break existing connections + when assiging routable address): when checking incoming packets and + aborting existing connection on address change, filter out link-local + addresses. + + 2010-03-06: Simon Goldschmidt + * sockets.c: Fixed LWIP_NETIF_TX_SINGLE_PBUF for LWIP_TCPIP_CORE_LOCKING + + 2010-03-06: Simon Goldschmidt + * ipv4/ip.c: Don't try to forward link-local addresses + + 2010-03-06: Simon Goldschmidt + * etharp.c: Fixed bug #29087: etharp: don't send packets for LinkLocal- + addresses to gw + + 2010-03-05: Simon Goldschmidt + * dhcp.c: Fixed bug #29072: Correctly set ciaddr based on message-type + and state. + + 2010-03-05: Simon Goldschmidt + * api_msg.c: Correctly set TCP_WRITE_FLAG_MORE when netconn_write is split + into multiple calls to tcp_write. + + 2010-02-21: Simon Goldschmidt + * opt.h, mem.h, dns.c: task #10140: Remove DNS_USES_STATIC_BUF (keep + the implementation of DNS_USES_STATIC_BUF==1) + + 2010-02-20: Simon Goldschmidt + * tcp.h, tcp.c, tcp_in.c, tcp_out.c: Task #10088: Correctly implement + close() vs. shutdown(). Now the application does not get any more + recv callbacks after calling tcp_close(). Added tcp_shutdown(). + + 2010-02-19: Simon Goldschmidt + * mem.c/.h, pbuf.c: Renamed mem_realloc() to mem_trim() to prevent + confusion with realloc() + + 2010-02-15: Simon Goldschmidt/Stephane Lesage + * netif.c/.h: Link status does not depend on LWIP_NETIF_LINK_CALLBACK + (fixes bug #28899) + + 2010-02-14: Simon Goldschmidt + * netif.c: Fixed bug #28877 (Duplicate ARP gratuitous packet with + LWIP_NETIF_LINK_CALLBACK set on) by only sending if both link- and + admin-status of a netif are up + + 2010-02-14: Simon Goldschmidt + * opt.h: Disable ETHARP_TRUST_IP_MAC by default since it slows down packet + reception and is not really necessary + + 2010-02-14: Simon Goldschmidt + * etharp.c/.h: Fixed ARP input processing: only add a new entry if a + request was directed as us (RFC 826, Packet Reception), otherwise + only update existing entries; internalized some functions + + 2010-02-14: Simon Goldschmidt + * netif.h, etharp.c, tcpip.c: Fixed bug #28183 (ARP and TCP/IP cannot be + disabled on netif used for PPPoE) by adding a new netif flag + (NETIF_FLAG_ETHERNET) that tells the stack the device is an ethernet + device but prevents usage of ARP (so that ethernet_input can be used + for PPPoE). + + 2010-02-12: Simon Goldschmidt + * netif.c: netif_set_link_up/down: only do something if the link state + actually changes + + 2010-02-12: Simon Goldschmidt/Stephane Lesage + * api_msg.c: Fixed bug #28865 (Cannot close socket/netconn in non-blocking + connect) + + 2010-02-12: Simon Goldschmidt + * mem.h: Fixed bug #28866 (mem_realloc function defined in mem.h) + + 2010-02-09: Simon Goldschmidt + * api_lib.c, api_msg.c, sockets.c, api.h, api_msg.h: Fixed bug #22110 + (recv() makes receive window update for data that wasn't received by + application) + + 2010-02-09: Simon Goldschmidt/Stephane Lesage + * sockets.c: Fixed bug #28853 (lwip_recvfrom() returns 0 on receive time-out + or any netconn_recv() error) + + 2010-02-09: Simon Goldschmidt + * ppp.c: task #10154 (PPP: Update snmp in/out counters for tx/rx packets) + + 2010-02-09: Simon Goldschmidt + * netif.c: For loopback packets, adjust the stats- and snmp-counters + for the loopback netif. + + 2010-02-08: Simon Goldschmidt + * igmp.c/.h, ip.h: Moved most defines from igmp.h to igmp.c for clarity + since they are not used anywhere else. + + 2010-02-08: Simon Goldschmidt (Stéphane Lesage) + * igmp.c, igmp.h, stats.c, stats.h: Improved IGMP stats + (patch from bug #28798) + + 2010-02-08: Simon Goldschmidt (Stéphane Lesage) + * igmp.c: Fixed bug #28798 (Error in "Max Response Time" processing) and + another bug when LWIP_RAND() returns zero. + + 2010-02-04: Simon Goldschmidt + * nearly every file: Use macros defined in ip_addr.h (some of them new) + to work with IP addresses (preparation for bug #27352 - Change ip_addr + from struct to typedef (u32_t) - and better code). + + 2010-01-31: Simon Goldschmidt + * netif.c: Don't call the link-callback from netif_set_up/down() since + this invalidly retriggers DHCP. + + 2010-01-29: Simon Goldschmidt + * ip_addr.h, inet.h, def.h, inet.c, def.c, more: Cleanly separate the + portability file inet.h and its contents from the stack: moved htonX- + functions to def.h (and the new def.c - they are not ipv4 dependent), + let inet.h depend on ip_addr.h and not the other way round. + This fixes bug #28732. + + 2010-01-28: Kieran Mansley + * tcp.c: Ensure ssthresh >= 2*MSS + + 2010-01-27: Simon Goldschmidt + * tcp.h, tcp.c, tcp_in.c: Fixed bug #27871: Calling tcp_abort() in recv + callback can lead to accessing unallocated memory. As a consequence, + ERR_ABRT means the application has called tcp_abort()! + + 2010-01-25: Simon Goldschmidt + * snmp_structs.h, msg_in.c: Partly fixed bug #22070 (MIB_OBJECT_WRITE_ONLY + not implemented in SNMP): write-only or not-accessible are still + returned by getnext (though not by get) + + 2010-01-24: Simon Goldschmidt + * snmp: Renamed the private mib node from 'private' to 'mib_private' to + not use reserved C/C++ keywords + + 2010-01-23: Simon Goldschmidt + * sockets.c: Fixed bug #28716: select() returns 0 after waiting for less + than 1 ms + + 2010-01-21: Simon Goldschmidt + * tcp.c, api_msg.c: Fixed bug #28651 (tcp_connect: no callbacks called + if tcp_enqueue fails) both in raw- and netconn-API + + 2010-01-19: Simon Goldschmidt + * api_msg.c: Fixed bug #27316: netconn: Possible deadlock in err_tcp + + 2010-01-18: Iordan Neshev/Simon Goldschmidt + * src/netif/ppp: reorganised PPP sourcecode to 2.3.11 including some + bugfix backports from 2.4.x. + + 2010-01-18: Simon Goldschmidt + * mem.c: Fixed bug #28679: mem_realloc calculates mem_stats wrong + + 2010-01-17: Simon Goldschmidt + * api_lib.c, api_msg.c, (api_msg.h, api.h, sockets.c, tcpip.c): + task #10102: "netconn: clean up conn->err threading issues" by adding + error return value to struct api_msg_msg + + 2010-01-17: Simon Goldschmidt + * api.h, api_lib.c, sockets.c: Changed netconn_recv() and netconn_accept() + to return err_t (bugs #27709 and #28087) + + 2010-01-14: Simon Goldschmidt + * ...: Use typedef for function prototypes throughout the stack. + + 2010-01-13: Simon Goldschmidt + * api_msg.h/.c, api_lib.c: Fixed bug #26672 (close connection when receive + window = 0) by correctly draining recvmbox/acceptmbox + + 2010-01-11: Simon Goldschmidt + * pap.c: Fixed bug #13315 (PPP PAP authentication can result in + erroneous callbacks) by copying the code from recent pppd + + 2010-01-10: Simon Goldschmidt + * raw.c: Fixed bug #28506 (raw_bind should filter received packets) + + 2010-01-10: Simon Goldschmidt + * tcp.h/.c: bug #28127 (remove call to tcp_output() from tcp_ack(_now)()) + + 2010-01-08: Simon Goldschmidt + * sockets.c: Fixed bug #28519 (lwip_recvfrom bug with len > 65535) + + 2010-01-08: Simon Goldschmidt + * dns.c: Copy hostname for DNS_LOCAL_HOSTLIST_IS_DYNAMIC==1 since string + passed to dns_local_addhost() might be volatile + + 2010-01-07: Simon Goldschmidt + * timers.c, tcp.h: Call tcp_timer_needed() with NO_SYS==1, too + + 2010-01-06: Simon Goldschmidt + * netdb.h: Fixed bug #28496: missing include guards in netdb.h + + 2009-12-31: Simon Goldschmidt + * many ppp files: Reorganised PPP source code from ucip structure to pppd + structure to easily compare our code against the pppd code (around v2.3.1) + + 2009-12-27: Simon Goldschmidt + * tcp_in.c: Another fix for bug #28241 (ooseq processing) and adapted + unit test + + +(STABLE-1.3.2) + + ++ New features: + + 2009-10-27 Simon Goldschmidt/Stephan Lesage + * netifapi.c/.h: Added netifapi_netif_set_addr() + + 2009-10-07 Simon Goldschmidt/Fabian Koch + * api_msg.c, netbuf.c/.h, opt.h: patch #6888: Patch for UDP Netbufs to + support dest-addr and dest-port (optional: LWIP_NETBUF_RECVINFO) + + 2009-08-26 Simon Goldschmidt/Simon Kallweit + * slipif.c/.h: bug #26397: SLIP polling support + + 2009-08-25 Simon Goldschmidt + * opt.h, etharp.h/.c: task #9033: Support IEEE 802.1q tagged frame (VLAN), + New configuration options ETHARP_SUPPORT_VLAN and ETHARP_VLAN_CHECK. + + 2009-08-25 Simon Goldschmidt + * ip_addr.h, netdb.c: patch #6900: added define ip_ntoa(struct ip_addr*) + + 2009-08-24 Jakob Stoklund Olesen + * autoip.c, dhcp.c, netif.c: patch #6725: Teach AutoIP and DHCP to respond + to netif_set_link_up(). + + 2009-08-23 Simon Goldschmidt + * tcp.h/.c: Added function tcp_debug_state_str() to convert a tcp state + to a human-readable string. + + ++ Bugfixes: + + 2009-12-24: Kieran Mansley + * tcp_in.c Apply patches from Oleg Tyshev to improve OOS processing + (BUG#28241) + + 2009-12-06: Simon Goldschmidt + * ppp.h/.c: Fixed bug #27079 (Yet another leak in PPP): outpacket_buf can + be statically allocated (like in ucip) + + 2009-12-04: Simon Goldschmidt (patch by Ioardan Neshev) + * pap.c: patch #6969: PPP: missing PAP authentication UNTIMEOUT + + 2009-12-03: Simon Goldschmidt + * tcp.h, tcp_in.c, tcp_out.c: Fixed bug #28106: dup ack for fast retransmit + could have non-zero length + + 2009-12-02: Simon Goldschmidt + * tcp_in.c: Fixed bug #27904: TCP sends too many ACKs: delay resetting + tcp_input_pcb until after calling the pcb's callbacks + + 2009-11-29: Simon Goldschmidt + * tcp_in.c: Fixed bug #28054: Two segments with FIN flag on the out-of- + sequence queue, also fixed PBUF_POOL leak in the out-of-sequence code + + 2009-11-29: Simon Goldschmidt + * pbuf.c: Fixed bug #28064: pbuf_alloc(PBUF_POOL) is not thread-safe by + queueing a call into tcpip_thread to free ooseq-bufs if the pool is empty + + 2009-11-26: Simon Goldschmidt + * tcp.h: Fixed bug #28098: Nagle can prevent fast retransmit from sending + segment + + 2009-11-26: Simon Goldschmidt + * tcp.h, sockets.c: Fixed bug #28099: API required to disable Nagle + algorithm at PCB level + + 2009-11-22: Simon Goldschmidt + * tcp_out.c: Fixed bug #27905: FIN isn't combined with data on unsent + + 2009-11-22: Simon Goldschmidt (suggested by Bill Auerbach) + * tcp.c: tcp_alloc: prevent increasing stats.err for MEMP_TCP_PCB when + reusing time-wait pcb + + 2009-11-20: Simon Goldschmidt (patch by Albert Bartel) + * sockets.c: Fixed bug #28062: Data received directly after accepting + does not wake up select + + 2009-11-11: Simon Goldschmidt + * netdb.h: Fixed bug #27994: incorrect define for freeaddrinfo(addrinfo) + + 2009-10-30: Simon Goldschmidt + * opt.h: Increased default value for TCP_MSS to 536, updated default + value for TCP_WND to 4*TCP_MSS to keep delayed ACK working. + + 2009-10-28: Kieran Mansley + * tcp_in.c, tcp_out.c, tcp.h: re-work the fast retransmission code + to follow algorithm from TCP/IP Illustrated + + 2009-10-27: Kieran Mansley + * tcp_in.c: fix BUG#27445: grow cwnd with every duplicate ACK + + 2009-10-25: Simon Goldschmidt + * tcp.h: bug-fix in the TCP_EVENT_RECV macro (has to call tcp_recved if + pcb->recv is NULL to keep rcv_wnd correct) + + 2009-10-25: Simon Goldschmidt + * tcp_in.c: Fixed bug #26251: RST process in TIME_WAIT TCP state + + 2009-10-23: Simon Goldschmidt (David Empson) + * tcp.c: Fixed bug #27783: Silly window avoidance for small window sizes + + 2009-10-21: Simon Goldschmidt + * tcp_in.c: Fixed bug #27215: TCP sent() callback gives leading and + trailing 1 byte len (SYN/FIN) + + 2009-10-21: Simon Goldschmidt + * tcp_out.c: Fixed bug #27315: zero window probe and FIN + + 2009-10-19: Simon Goldschmidt + * dhcp.c/.h: Minor code simplification (don't store received pbuf, change + conditional code to assert where applicable), check pbuf length before + testing for valid reply + + 2009-10-19: Simon Goldschmidt + * dhcp.c: Removed most calls to udp_connect since they aren't necessary + when using udp_sendto_if() - always stay connected to IP_ADDR_ANY. + + 2009-10-16: Simon Goldschmidt + * ip.c: Fixed bug #27390: Source IP check in ip_input() causes it to drop + valid DHCP packets -> allow 0.0.0.0 as source address when LWIP_DHCP is + enabled + + 2009-10-15: Simon Goldschmidt (Oleg Tyshev) + * tcp_in.c: Fixed bug #27329: dupacks by unidirectional data transmit + + 2009-10-15: Simon Goldschmidt + * api_lib.c: Fixed bug #27709: conn->err race condition on netconn_recv() + timeout + + 2009-10-15: Simon Goldschmidt + * autoip.c: Fixed bug #27704: autoip starts with wrong address + LWIP_AUTOIP_CREATE_SEED_ADDR() returned address in host byte order instead + of network byte order + + 2009-10-11 Simon Goldschmidt (Jörg Kesten) + * tcp_out.c: Fixed bug #27504: tcp_enqueue wrongly concatenates segments + which are not consecutive when retransmitting unacked segments + + 2009-10-09 Simon Goldschmidt + * opt.h: Fixed default values of some stats to only be enabled if used + Fixes bug #27338: sys_stats is defined when NO_SYS = 1 + + 2009-08-30 Simon Goldschmidt + * ip.c: Fixed bug bug #27345: "ip_frag() does not use the LWIP_NETIF_LOOPBACK + function" by checking for loopback before calling ip_frag + + 2009-08-25 Simon Goldschmidt + * dhcp.c: fixed invalid dependency to etharp_query if DHCP_DOES_ARP_CHECK==0 + + 2009-08-23 Simon Goldschmidt + * ppp.c: bug #27078: Possible memory leak in pppInit() + + 2009-08-23 Simon Goldschmidt + * netdb.c, dns.c: bug #26657: DNS, if host name is "localhost", result + is error. + + 2009-08-23 Simon Goldschmidt + * opt.h, init.c: bug #26649: TCP fails when TCP_MSS > TCP_SND_BUF + Fixed wrong parenthesis, added check in init.c + + 2009-08-23 Simon Goldschmidt + * ppp.c: bug #27266: wait-state debug message in pppMain occurs every ms + + 2009-08-23 Simon Goldschmidt + * many ppp files: bug #27267: Added include to string.h where needed + + 2009-08-23 Simon Goldschmidt + * tcp.h: patch #6843: tcp.h macro optimization patch (for little endian) + + +(STABLE-1.3.1) + + ++ New features: + + 2009-05-10 Simon Goldschmidt + * opt.h, sockets.c, pbuf.c, netbuf.h, pbuf.h: task #7013: Added option + LWIP_NETIF_TX_SINGLE_PBUF to try to create transmit packets from only + one pbuf to help MACs that don't support scatter-gather DMA. + + 2009-05-09 Simon Goldschmidt + * icmp.h, icmp.c: Shrinked ICMP code, added option to NOT check icoming + ECHO pbuf for size (just use it): LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN + + 2009-05-05 Simon Goldschmidt, Jakob Stoklund Olesen + * ip.h, ip.c: Added ip_current_netif() & ip_current_header() to receive + extended info about the currently received packet. + + 2009-04-27 Simon Goldschmidt + * sys.h: Made SYS_LIGHTWEIGHT_PROT and sys_now() work with NO_SYS=1 + + 2009-04-25 Simon Goldschmidt + * mem.c, opt.h: Added option MEM_USE_POOLS_TRY_BIGGER_POOL to try the next + bigger malloc pool if one is empty (only usable with MEM_USE_POOLS). + + 2009-04-21 Simon Goldschmidt + * dns.c, init.c, dns.h, opt.h: task #7507, patch #6786: DNS supports static + hosts table. New configuration options DNS_LOCAL_HOSTLIST and + DNS_LOCAL_HOSTLIST_IS_DYNAMIC. Also, DNS_LOOKUP_LOCAL_EXTERN() can be defined + as an external function for lookup. + + 2009-04-15 Simon Goldschmidt + * dhcp.c: patch #6763: Global DHCP XID can be redefined to something more unique + + 2009-03-31 Kieran Mansley + * tcp.c, tcp_out.c, tcp_in.c, sys.h, tcp.h, opts.h: add support for + TCP timestamp options, off by default. Rework tcp_enqueue() to + take option flags rather than specified option data + + 2009-02-18 Simon Goldschmidt + * cc.h: Added printf formatter for size_t: SZT_F + + 2009-02-16 Simon Goldschmidt (patch by Rishi Khan) + * icmp.c, opt.h: patch #6539: (configurable) response to broadcast- and multicast + pings + + 2009-02-12 Simon Goldschmidt + * init.h: Added LWIP_VERSION to get the current version of the stack + + 2009-02-11 Simon Goldschmidt (suggested by Gottfried Spitaler) + * opt.h, memp.h/.c: added MEMP_MEM_MALLOC to use mem_malloc/mem_free instead + of the pool allocator (can save code size with MEM_LIBC_MALLOC if libc-malloc + is otherwise used) + + 2009-01-28 Jonathan Larmour (suggested by Bill Bauerbach) + * ipv4/inet_chksum.c, ipv4/lwip/inet_chksum.h: inet_chksum_pseudo_partial() + is only used by UDPLITE at present, so conditionalise it. + + 2008-12-03 Simon Goldschmidt (base on patch from Luca Ceresoli) + * autoip.c: checked in (slightly modified) patch #6683: Customizable AUTOIP + "seed" address. This should reduce AUTOIP conflicts if + LWIP_AUTOIP_CREATE_SEED_ADDR is overridden. + + 2008-10-02 Jonathan Larmour and Rishi Khan + * sockets.c (lwip_accept): Return EWOULDBLOCK if would block on non-blocking + socket. + + 2008-06-30 Simon Goldschmidt + * mem.c, opt.h, stats.h: fixed bug #21433: Calling mem_free/pbuf_free from + interrupt context isn't safe: LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT allows + mem_free to run between mem_malloc iterations. Added illegal counter for + mem stats. + + 2008-06-27 Simon Goldschmidt + * stats.h/.c, some other files: patch #6483: stats module improvement: + Added defines to display each module's statistic individually, added stats + defines for MEM, MEMP and SYS modules, removed (unused) rexmit counter. + + 2008-06-17 Simon Goldschmidt + * err.h: patch #6459: Made err_t overridable to use a more efficient type + (define LWIP_ERR_T in cc.h) + + 2008-06-17 Simon Goldschmidt + * slipif.c: patch #6480: Added a configuration option for slipif for symmetry + to loopif + + 2008-06-17 Simon Goldschmidt (patch by Luca Ceresoli) + * netif.c, loopif.c, ip.c, netif.h, loopif.h, opt.h: Checked in slightly + modified version of patch # 6370: Moved loopif code to netif.c so that + loopback traffic is supported on all netifs (all local IPs). + Added option to limit loopback packets for each netifs. + + + ++ Bugfixes: + 2009-08-12 Kieran Mansley + * tcp_in.c, tcp.c: Fix bug #27209: handle trimming of segments when + out of window or out of order properly + + 2009-08-12 Kieran Mansley + * tcp_in.c: Fix bug #27199: use snd_wl2 instead of snd_wl1 + + 2009-07-28 Simon Goldschmidt + * mem.h: Fixed bug #27105: "realloc() cannot replace mem_realloc()"s + + 2009-07-27 Kieran Mansley + * api.h api_msg.h netdb.h sockets.h: add missing #include directives + + 2009-07-09 Kieran Mansley + * api_msg.c, sockets.c, api.h: BUG23240 use signed counters for + recv_avail and don't increment counters until message successfully + sent to mbox + + 2009-06-25 Kieran Mansley + * api_msg.c api.h: BUG26722: initialise netconn write variables + in netconn_alloc + + 2009-06-25 Kieran Mansley + * tcp.h: BUG26879: set ret value in TCP_EVENT macros when function is not set + + 2009-06-25 Kieran Mansley + * tcp.c, tcp_in.c, tcp_out.c, tcp.h: BUG26301 and BUG26267: correct + simultaneous close behaviour, and make snd_nxt have the same meaning + as in the RFCs. + + 2009-05-12 Simon Goldschmidt + * etharp.h, etharp.c, netif.c: fixed bug #26507: "Gratuitous ARP depends on + arp_table / uses etharp_query" by adding etharp_gratuitous() + + 2009-05-12 Simon Goldschmidt + * ip.h, ip.c, igmp.c: bug #26487: Added ip_output_if_opt that can add IP options + to the IP header (used by igmp_ip_output_if) + + 2009-05-06 Simon Goldschmidt + * inet_chksum.c: On little endian architectures, use LWIP_PLATFORM_HTONS (if + defined) for SWAP_BYTES_IN_WORD to speed up checksumming. + + 2009-05-05 Simon Goldschmidt + * sockets.c: bug #26405: Prematurely released semaphore causes lwip_select() + to crash + + 2009-05-04 Simon Goldschmidt + * init.c: snmp was not initialized in lwip_init() + + 2009-05-04 Frédéric Bernon + * dhcp.c, netbios.c: Changes if IP_SOF_BROADCAST is enabled. + + 2009-05-03 Simon Goldschmidt + * tcp.h: bug #26349: Nagle algorithm doesn't send although segment is full + (and unsent->next == NULL) + + 2009-05-02 Simon Goldschmidt + * tcpip.h, tcpip.c: fixed tcpip_untimeout (does not need the time, broken after + 1.3.0 in CVS only) - fixes compilation of ppp_oe.c + + 2009-05-02 Simon Goldschmidt + * msg_in.c: fixed bug #25636: SNMPSET value is ignored for integer fields + + 2009-05-01 Simon Goldschmidt + * pap.c: bug #21680: PPP upap_rauthnak() drops legal NAK packets + + 2009-05-01 Simon Goldschmidt + * ppp.c: bug #24228: Memory corruption with PPP and DHCP + + 2009-04-29 Frédéric Bernon + * raw.c, udp.c, init.c, opt.h, ip.h, sockets.h: bug #26309: Implement the + SO(F)_BROADCAST filter for all API layers. Avoid the unindented reception + of broadcast packets even when this option wasn't set. Port maintainers + which want to enable this filter have to set IP_SOF_BROADCAST=1 in opt.h. + If you want this option also filter broadcast on recv operations, you also + have to set IP_SOF_BROADCAST_RECV=1 in opt.h. + + 2009-04-28 Simon Goldschmidt, Jakob Stoklund Olesen + * dhcp.c: patch #6721, bugs #25575, #25576: Some small fixes to DHCP and + DHCP/AUTOIP cooperation + + 2009-04-25 Simon Goldschmidt, Oleg Tyshev + * tcp_out.c: bug #24212: Deadlocked tcp_retransmit due to exceeded pcb->cwnd + Fixed by sorting the unsent and unacked queues (segments are inserted at the + right place in tcp_output and tcp_rexmit). + + 2009-04-25 Simon Goldschmidt + * memp.c, mem.c, memp.h, mem_std.h: bug #26213 "Problem with memory allocation + when debugging": memp_sizes contained the wrong sizes (including sanity + regions); memp pools for MEM_USE_POOLS were too small + + 2009-04-24 Simon Goldschmidt, Frédéric Bernon + * inet.c: patch #6765: Fix a small problem with the last changes (incorrect + behavior, with with ip address string not ended by a '\0', a space or a + end of line) + + 2009-04-19 Simon Goldschmidt + * rawapi.txt: Fixed bug #26069: Corrected documentation: if tcp_connect fails, + pcb->err is called, not pcb->connected (with an error code). + + 2009-04-19 Simon Goldschmidt + * tcp_out.c: Fixed bug #26236: "TCP options (timestamp) don't work with + no-copy-tcpwrite": deallocate option data, only concat segments with same flags + + 2009-04-19 Simon Goldschmidt + * tcp_out.c: Fixed bug #25094: "Zero-length pbuf" (options are now allocated + in the header pbuf, not the data pbuf) + + 2009-04-18 Simon Goldschmidt + * api_msg.c: fixed bug #25695: Segmentation fault in do_writemore() + + 2009-04-15 Simon Goldschmidt + * sockets.c: tried to fix bug #23559: lwip_recvfrom problem with tcp + + 2009-04-15 Simon Goldschmidt + * dhcp.c: task #9192: mem_free of dhcp->options_in and dhcp->msg_in + + 2009-04-15 Simon Goldschmidt + * ip.c, ip6.c, tcp_out.c, ip.h: patch #6808: Add a utility function + ip_hinted_output() (for smaller code mainly) + + 2009-04-15 Simon Goldschmidt + * inet.c: patch #6765: Supporting new line characters in inet_aton() + + 2009-04-15 Simon Goldschmidt + * dhcp.c: patch #6764: DHCP rebind and renew did not send hostnam option; + Converted constant OPTION_MAX_MSG_SIZE to netif->mtu, check if netif->mtu + is big enough in dhcp_start + + 2009-04-15 Simon Goldschmidt + * netbuf.c: bug #26027: netbuf_chain resulted in pbuf memory leak + + 2009-04-15 Simon Goldschmidt + * sockets.c, ppp.c: bug #25763: corrected 4 occurrences of SMEMCPY to MEMCPY + + 2009-04-15 Simon Goldschmidt + * sockets.c: bug #26121: set_errno can be overridden + + 2009-04-09 Kieran Mansley (patch from Luca Ceresoli ) + * init.c, opt.h: Patch#6774 TCP_QUEUE_OOSEQ breaks compilation when + LWIP_TCP==0 + + 2009-04-09 Kieran Mansley (patch from Roy Lee ) + * tcp.h: Patch#6802 Add do-while-clauses to those function like + macros in tcp.h + + 2009-03-31 Kieran Mansley + * tcp.c, tcp_in.c, tcp_out.c, tcp.h, opt.h: Rework the way window + updates are calculated and sent (BUG20515) + + * tcp_in.c: cope with SYN packets received during established states, + and retransmission of initial SYN. + + * tcp_out.c: set push bit correctly when tcp segments are merged + + 2009-03-27 Kieran Mansley + * tcp_out.c set window correctly on probes (correcting change made + yesterday) + + 2009-03-26 Kieran Mansley + * tcp.c, tcp_in.c, tcp.h: add tcp_abandon() to cope with dropping + connections where no reset required (bug #25622) + + * tcp_out.c: set TCP_ACK flag on keepalive and zero window probes + (bug #20779) + + 2009-02-18 Simon Goldschmidt (Jonathan Larmour and Bill Auerbach) + * ip_frag.c: patch #6528: the buffer used for IP_FRAG_USES_STATIC_BUF could be + too small depending on MEM_ALIGNMENT + + 2009-02-16 Simon Goldschmidt + * sockets.h/.c, api_*.h/.c: fixed arguments of socket functions to match the standard; + converted size argument of netconn_write to 'size_t' + + 2009-02-16 Simon Goldschmidt + * tcp.h, tcp.c: fixed bug #24440: TCP connection close problem on 64-bit host + by moving accept callback function pointer to TCP_PCB_COMMON + + 2009-02-12 Simon Goldschmidt + * dhcp.c: fixed bug #25345 (DHCPDECLINE is sent with "Maximum message size" + option) + + 2009-02-11 Simon Goldschmidt + * dhcp.c: fixed bug #24480 (releasing old udp_pdb and pbuf in dhcp_start) + + 2009-02-11 Simon Goldschmidt + * opt.h, api_msg.c: added configurable default valud for netconn->recv_bufsize: + RECV_BUFSIZE_DEFAULT (fixes bug #23726: pbuf pool exhaustion on slow recv()) + + 2009-02-10 Simon Goldschmidt + * tcp.c: fixed bug #25467: Listen backlog is not reset on timeout in SYN_RCVD: + Accepts_pending is decrease on a corresponding listen pcb when a connection + in state SYN_RCVD is close. + + 2009-01-28 Jonathan Larmour + * pbuf.c: reclaim pbufs from TCP out-of-sequence segments if we run + out of pool pbufs. + + 2008-12-19 Simon Goldschmidt + * many files: patch #6699: fixed some warnings on platform where sizeof(int) == 2 + + 2008-12-10 Tamas Somogyi, Frédéric Bernon + * sockets.c: fixed bug #25051: lwip_recvfrom problem with udp: fromaddr and + port uses deleted netbuf. + + 2008-10-18 Simon Goldschmidt + * tcp_in.c: fixed bug ##24596: Vulnerability on faulty TCP options length + in tcp_parseopt + + 2008-10-15 Simon Goldschmidt + * ip_frag.c: fixed bug #24517: IP reassembly crashes on unaligned IP headers + by packing the struct ip_reass_helper. + + 2008-10-03 David Woodhouse, Jonathan Larmour + * etharp.c (etharp_arp_input): Fix type aliasing problem copying ip address. + + 2008-10-02 Jonathan Larmour + * dns.c: Hard-code structure sizes, to avoid issues on some compilers where + padding is included. + + 2008-09-30 Jonathan Larmour + * sockets.c (lwip_accept): check addr isn't NULL. If it's valid, do an + assertion check that addrlen isn't NULL. + + 2008-09-30 Jonathan Larmour + * tcp.c: Fix bug #24227, wrong error message in tcp_bind. + + 2008-08-26 Simon Goldschmidt + * inet.h, ip_addr.h: fixed bug #24132: Cross-dependency between ip_addr.h and + inet.h -> moved declaration of struct in_addr from ip_addr.h to inet.h + + 2008-08-14 Simon Goldschmidt + * api_msg.c: fixed bug #23847: do_close_internal references freed memory (when + tcp_close returns != ERR_OK) + + 2008-07-08 Frédéric Bernon + * stats.h: Fix some build bugs introduced with patch #6483 (missing some parameters + in macros, mainly if MEM_STATS=0 and MEMP_STATS=0). + + 2008-06-24 Jonathan Larmour + * tcp_in.c: Fix for bug #23693 as suggested by Art R. Ensure cseg is unused + if tcp_seg_copy fails. + + 2008-06-17 Simon Goldschmidt + * inet_chksum.c: Checked in some ideas of patch #6460 (loop optimizations) + and created defines for swapping bytes and folding u32 to u16. + + 2008-05-30 Kieran Mansley + * tcp_in.c Remove redundant "if" statement, and use real rcv_wnd + rather than rcv_ann_wnd when deciding if packets are in-window. + Contributed by + + 2008-05-30 Kieran Mansley + * mem.h: Fix BUG#23254. Change macro definition of mem_* to allow + passing as function pointers when MEM_LIBC_MALLOC is defined. + + 2008-05-09 Jonathan Larmour + * err.h, err.c, sockets.c: Fix bug #23119: Reorder timeout error code to + stop it being treated as a fatal error. + + 2008-04-15 Simon Goldschmidt + * dhcp.c: fixed bug #22804: dhcp_stop doesn't clear NETIF_FLAG_DHCP + (flag now cleared) + + 2008-03-27 Simon Goldschmidt + * mem.c, tcpip.c, tcpip.h, opt.h: fixed bug #21433 (Calling mem_free/pbuf_free + from interrupt context isn't safe): set LWIP_USE_HEAP_FROM_INTERRUPT to 1 + in lwipopts.h or use pbuf_free_callback(p)/mem_free_callback(m) to free pbufs + or heap memory from interrupt context + + 2008-03-26 Simon Goldschmidt + * tcp_in.c, tcp.c: fixed bug #22249: division by zero could occur if a remote + host sent a zero mss as TCP option. + + +(STABLE-1.3.0) + + ++ New features: + + 2008-03-10 Jonathan Larmour + * inet_chksum.c: Allow choice of one of the sample algorithms to be + made from lwipopts.h. Fix comment on how to override LWIP_CHKSUM. + + 2008-01-22 Frédéric Bernon + * tcp.c, tcp_in.c, tcp.h, opt.h: Rename LWIP_CALCULATE_EFF_SEND_MSS in + TCP_CALCULATE_EFF_SEND_MSS to have coherent TCP options names. + + 2008-01-14 Frédéric Bernon + * rawapi.txt, api_msg.c, tcp.c, tcp_in.c, tcp.h: changes for task #7675 "Enable + to refuse data on a TCP_EVENT_RECV call". Important, behavior changes for the + tcp_recv callback (see rawapi.txt). + + 2008-01-14 Frédéric Bernon, Marc Chaland + * ip.c: Integrate patch #6369" ip_input : checking before realloc". + + 2008-01-12 Frédéric Bernon + * tcpip.h, tcpip.c, api.h, api_lib.c, api_msg.c, sockets.c: replace the field + netconn::sem per netconn::op_completed like suggested for the task #7490 + "Add return value to sys_mbox_post". + + 2008-01-12 Frédéric Bernon + * api_msg.c, opt.h: replace DEFAULT_RECVMBOX_SIZE per DEFAULT_TCP_RECVMBOX_SIZE, + DEFAULT_UDP_RECVMBOX_SIZE and DEFAULT_RAW_RECVMBOX_SIZE (to optimize queues + sizes), like suggested for the task #7490 "Add return value to sys_mbox_post". + + 2008-01-10 Frédéric Bernon + * tcpip.h, tcpip.c: add tcpip_callback_with_block function for the task #7490 + "Add return value to sys_mbox_post". tcpip_callback is always defined as + "blocking" ("block" parameter = 1). + + 2008-01-10 Frédéric Bernon + * tcpip.h, tcpip.c, api.h, api_lib.c, api_msg.c, sockets.c: replace the field + netconn::mbox (sys_mbox_t) per netconn::sem (sys_sem_t) for the task #7490 + "Add return value to sys_mbox_post". + + 2008-01-05 Frédéric Bernon + * sys_arch.txt, api.h, api_lib.c, api_msg.h, api_msg.c, tcpip.c, sys.h, opt.h: + Introduce changes for task #7490 "Add return value to sys_mbox_post" with some + modifications in the sys_mbox api: sys_mbox_new take a "size" parameters which + indicate the number of pointers query by the mailbox. There is three defines + in opt.h to indicate sizes for tcpip::mbox, netconn::recvmbox, and for the + netconn::acceptmbox. Port maintainers, you can decide to just add this new + parameter in your implementation, but to ignore it to keep the previous behavior. + The new sys_mbox_trypost function return a value to know if the mailbox is + full or if the message is posted. Take a look to sys_arch.txt for more details. + This new function is used in tcpip_input (so, can be called in an interrupt + context since the function is not blocking), and in recv_udp and recv_raw. + + 2008-01-04 Frédéric Bernon, Simon Goldschmidt, Jonathan Larmour + * rawapi.txt, api.h, api_lib.c, api_msg.h, api_msg.c, sockets.c, tcp.h, tcp.c, + tcp_in.c, init.c, opt.h: rename backlog options with TCP_ prefix, limit the + "backlog" parameter in an u8_t, 0 is interpreted as "smallest queue", add + documentation in the rawapi.txt file. + + 2007-12-31 Kieran Mansley (based on patch from Per-Henrik Lundbolm) + * tcp.c, tcp_in.c, tcp_out.c, tcp.h: Add TCP persist timer + + 2007-12-31 Frédéric Bernon, Luca Ceresoli + * autoip.c, etharp.c: ip_addr.h: Integrate patch #6348: "Broadcast ARP packets + in autoip". The change in etharp_raw could be removed, since all calls to + etharp_raw use ethbroadcast for the "ethdst_addr" parameter. But it could be + wrong in the future. + + 2007-12-30 Frédéric Bernon, Tom Evans + * ip.c: Fix bug #21846 "LwIP doesn't appear to perform any IP Source Address + Filtering" reported by Tom Evans. + + 2007-12-21 Frédéric Bernon, Simon Goldschmidt, Jonathan Larmour + * tcp.h, opt.h, api.h, api_msg.h, tcp.c, tcp_in.c, api_lib.c, api_msg.c, + sockets.c, init.c: task #7252: Implement TCP listen backlog: Warning: raw API + applications have to call 'tcp_accepted(pcb)' in their accept callback to + keep accepting new connections. + + 2007-12-13 Frédéric Bernon + * api_msg.c, err.h, err.c, sockets.c, dns.c, dns.h: replace "enum dns_result" + by err_t type. Add a new err_t code "ERR_INPROGRESS". + + 2007-12-12 Frédéric Bernon + * dns.h, dns.c, opt.h: move DNS options to the "right" place. Most visibles + are the one which have ram usage. + + 2007-12-05 Frédéric Bernon + * netdb.c: add a LWIP_DNS_API_HOSTENT_STORAGE option to decide to use a static + set of variables (=0) or a local one (=1). In this last case, your port should + provide a function "struct hostent* sys_thread_hostent( struct hostent* h)" + which have to do a copy of "h" and return a pointer ont the "per-thread" copy. + + 2007-12-03 Simon Goldschmidt + * ip.c: ip_input: check if a packet is for inp first before checking all other + netifs on netif_list (speeds up packet receiving in most cases) + + 2007-11-30 Simon Goldschmidt + * udp.c, raw.c: task #7497: Sort lists (pcb, netif, ...) for faster access + UDP: move a (connected) pcb selected for input to the front of the list of + pcbs so that it is found faster next time. Same for RAW pcbs that have eaten + a packet. + + 2007-11-28 Simon Goldschmidt + * etharp.c, stats.c, stats.h, opt.h: Introduced ETHARP_STATS + + 2007-11-25 Simon Goldschmidt + * dhcp.c: dhcp_unfold_reply() uses pbuf_copy_partial instead of its own copy + algorithm. + + 2007-11-24 Simon Goldschmidt + * netdb.h, netdb.c, sockets.h/.c: Moved lwip_gethostbyname from sockets.c + to the new file netdb.c; included lwip_getaddrinfo. + + 2007-11-21 Simon Goldschmidt + * tcp.h, opt.h, tcp.c, tcp_in.c: implemented calculating the effective send-mss + based on the MTU of the netif used to send. Enabled by default. Disable by + setting LWIP_CALCULATE_EFF_SEND_MSS to 0. This fixes bug #21492. + + 2007-11-19 Frédéric Bernon + * api_msg.c, dns.h, dns.c: Implement DNS_DOES_NAME_CHECK option (check if name + received match the name query), implement DNS_USES_STATIC_BUF (the place where + copy dns payload to parse the response), return an error if there is no place + for a new query, and fix some minor problems. + + 2007-11-16 Simon Goldschmidt + * new files: ipv4/inet.c, ipv4/inet_chksum.c, ipv6/inet6.c + removed files: core/inet.c, core/inet6.c + Moved inet files into ipv4/ipv6 directory; splitted inet.c/inet.h into + inet and chksum part; changed includes in all lwIP files as appropriate + + 2007-11-16 Simon Goldschmidt + * api.h, api_msg.h, api_lib.c, api_msg.c, socket.h, socket.c: Added sequential + dns resolver function for netconn api (netconn_gethostbyname) and socket api + (gethostbyname/gethostbyname_r). + + 2007-11-15 Jim Pettinato, Frédéric Bernon + * opt.h, init.c, tcpip.c, dhcp.c, dns.h, dns.c: add DNS client for simple name + requests with RAW api interface. Initialization is done in lwip_init() with + build time options. DNS timer is added in tcpip_thread context. DHCP can set + DNS server ip addresses when options are received. You need to set LWIP_DNS=1 + in your lwipopts.h file (LWIP_DNS=0 in opt.h). DNS_DEBUG can be set to get + some traces with LWIP_DEBUGF. Sanity check have been added. There is a "todo" + list with points to improve. + + 2007-11-06 Simon Goldschmidt + * opt.h, mib2.c: Patch #6215: added ifAdminStatus write support (if explicitly + enabled by defining SNMP_SAFE_REQUESTS to 0); added code to check link status + for ifOperStatus if LWIP_NETIF_LINK_CALLBACK is defined. + + 2007-11-06 Simon Goldschmidt + * api.h, api_msg.h and dependent files: Task #7410: Removed the need to include + core header files in api.h (ip/tcp/udp/raw.h) to hide the internal + implementation from netconn api applications. + + 2007-11-03 Frédéric Bernon + * api.h, api_lib.c, api_msg.c, sockets.c, opt.h: add SO_RCVBUF option for UDP & + RAW netconn. You need to set LWIP_SO_RCVBUF=1 in your lwipopts.h (it's disabled + by default). Netconn API users can use the netconn_recv_bufsize macro to access + it. This is a first release which have to be improve for TCP. Note it used the + netconn::recv_avail which need to be more "thread-safe" (note there is already + the problem for FIONREAD with lwip_ioctl/ioctlsocket). + + 2007-11-01 Frédéric Bernon, Marc Chaland + * sockets.h, sockets.c, api.h, api_lib.c, api_msg.h, api_msg.c, tcp.h, tcp_out.c: + Integrate "patch #6250 : MSG_MORE flag for send". MSG_MORE is used at socket api + layer, NETCONN_MORE at netconn api layer, and TCP_WRITE_FLAG_MORE at raw api + layer. This option enable to delayed TCP PUSH flag on multiple "write" calls. + Note that previous "copy" parameter for "write" APIs is now called "apiflags". + + 2007-10-24 Frédéric Bernon + * api.h, api_lib.c, api_msg.c: Add macro API_EVENT in the same spirit than + TCP_EVENT_xxx macros to get a code more readable. It could also help to remove + some code (like we have talk in "patch #5919 : Create compile switch to remove + select code"), but it could be done later. + + 2007-10-08 Simon Goldschmidt + * many files: Changed initialization: many init functions are not needed any + more since we now rely on the compiler initializing global and static + variables to zero! + + 2007-10-06 Simon Goldschmidt + * ip_frag.c, memp.c, mib2.c, ip_frag.h, memp_std.h, opt.h: Changed IP_REASSEMBLY + to enqueue the received pbufs so that multiple packets can be reassembled + simultaneously and no static reassembly buffer is needed. + + 2007-10-05 Simon Goldschmidt + * tcpip.c, etharp.h, etharp.c: moved ethernet_input from tcpip.c to etharp.c so + all netifs (or ports) can use it. + + 2007-10-05 Frédéric Bernon + * netifapi.h, netifapi.c: add function netifapi_netif_set_default. Change the + common function to reduce a little bit the footprint (for all functions using + only the "netif" parameter). + + 2007-10-03 Frédéric Bernon + * netifapi.h, netifapi.c: add functions netifapi_netif_set_up, netifapi_netif_set_down, + netifapi_autoip_start and netifapi_autoip_stop. Use a common function to reduce + a little bit the footprint (for all functions using only the "netif" parameter). + + 2007-09-15 Frédéric Bernon + * udp.h, udp.c, sockets.c: Changes for "#20503 IGMP Improvement". Add IP_MULTICAST_IF + option in socket API, and a new field "multicast_ip" in "struct udp_pcb" (for + netconn and raw API users), only if LWIP_IGMP=1. Add getsockopt processing for + IP_MULTICAST_TTL and IP_MULTICAST_IF. + + 2007-09-10 Frédéric Bernon + * snmp.h, mib2.c: enable to remove SNMP timer (which consumne several cycles + even when it's not necessary). snmp_agent.txt tell to call snmp_inc_sysuptime() + each 10ms (but, it's intrusive if you use sys_timeout feature). Now, you can + decide to call snmp_add_sysuptime(100) each 1000ms (which is bigger "step", but + call to a lower frequency). Or, you can decide to not call snmp_inc_sysuptime() + or snmp_add_sysuptime(), and to define the SNMP_GET_SYSUPTIME(sysuptime) macro. + This one is undefined by default in mib2.c. SNMP_GET_SYSUPTIME is called inside + snmp_get_sysuptime(u32_t *value), and enable to change "sysuptime" value only + when it's queried (any direct call to "sysuptime" is changed by a call to + snmp_get_sysuptime). + + 2007-09-09 Frédéric Bernon, Bill Florac + * igmp.h, igmp.c, netif.h, netif.c, ip.c: To enable to have interfaces with IGMP, + and others without it, there is a new NETIF_FLAG_IGMP flag to set in netif->flags + if you want IGMP on an interface. igmp_stop() is now called inside netif_remove(). + igmp_report_groups() is now called inside netif_set_link_up() (need to have + LWIP_NETIF_LINK_CALLBACK=1) to resend reports once the link is up (avoid to wait + the next query message to receive the matching multicast streams). + + 2007-09-08 Frédéric Bernon + * sockets.c, ip.h, api.h, tcp.h: declare a "struct ip_pcb" which only contains + IP_PCB. Add in the netconn's "pcb" union a "struct ip_pcb *ip;" (no size change). + Use this new field to access to common pcb fields (ttl, tos, so_options, etc...). + Enable to access to these fields with LWIP_TCP=0. + + 2007-09-05 Frédéric Bernon + * udp.c, ipv4/icmp.c, ipv4/ip.c, ipv6/icmp.c, ipv6/ip6.c, ipv4/icmp.h, + ipv6/icmp.h, opt.h: Integrate "task #7272 : LWIP_ICMP option". The new option + LWIP_ICMP enable/disable ICMP module inside the IP stack (enable per default). + Be careful, disabling ICMP make your product non-compliant to RFC1122, but + help to reduce footprint, and to reduce "visibility" on the Internet. + + 2007-09-05 Frédéric Bernon, Bill Florac + * opt.h, sys.h, tcpip.c, slipif.c, ppp.c, sys_arch.txt: Change parameters list + for sys_thread_new (see "task #7252 : Create sys_thread_new_ex()"). Two new + parameters have to be provided: a task name, and a task stack size. For this + one, since it's platform dependant, you could define the best one for you in + your lwipopts.h. For port maintainers, you can just add these new parameters + in your sys_arch.c file, and but it's not mandatory, use them in your OS + specific functions. + + 2007-09-05 Frédéric Bernon + * inet.c, autoip.c, msg_in.c, msg_out.c, init.c: Move some build time checkings + inside init.c for task #7142 "Sanity check user-configurable values". + + 2007-09-04 Frédéric Bernon, Bill Florac + * igmp.h, igmp.c, memp_std.h, memp.c, init.c, opt.h: Replace mem_malloc call by + memp_malloc, and use a new MEMP_NUM_IGMP_GROUP option (see opt.h to define the + value). It will avoid potential fragmentation problems, use a counter to know + how many times a group is used on an netif, and free it when all applications + leave it. MEMP_NUM_IGMP_GROUP got 8 as default value (and init.c got a sanity + check if LWIP_IGMP!=0). + + 2007-09-03 Frédéric Bernon + * igmp.h, igmp.c, sockets.c, api_msg.c: Changes for "#20503 IGMP Improvement". + Initialize igmp_mac_filter to NULL in netif_add (this field should be set in + the netif's "init" function). Use the "imr_interface" field (for socket layer) + and/or the "interface" field (for netconn layer), for join/leave operations. + The igmp_join/leavegroup first parameter change from a netif to an ipaddr. + This field could be a netif's ipaddr, or "any" (same meaning than ip_addr_isany). + + 2007-08-30 Frédéric Bernon + * Add netbuf.h, netbuf.c, Change api.h, api_lib.c: #7249 "Split netbuf functions + from api/api_lib". Now netbuf API is independant of netconn, and can be used + with other API (application based on raw API, or future "socket2" API). Ports + maintainers just have to add src/api/netbuf.c in their makefile/projects. + + 2007-08-30 Frédéric Bernon, Jonathan Larmour + * init.c: Add first version of lwip_sanity_check for task #7142 "Sanity check + user-configurable values". + + 2007-08-29 Frédéric Bernon + * igmp.h, igmp.c, tcpip.c, init.c, netif.c: change igmp_init and add igmp_start. + igmp_start is call inside netif_add. Now, igmp initialization is in the same + spirit than the others modules. Modify some IGMP debug traces. + + 2007-08-29 Frédéric Bernon + * Add init.h, init.c, Change opt.h, tcpip.c: Task #7213 "Add a lwip_init function" + Add lwip_init function to regroup all modules initializations, and to provide + a place to add code for task #7142 "Sanity check user-configurable values". + Ports maintainers should remove direct initializations calls from their code, + and add init.c in their makefiles. Note that lwip_init() function is called + inside tcpip_init, but can also be used by raw api users since all calls are + disabled when matching options are disabled. Also note that their is new options + in opt.h, you should configure in your lwipopts.h (they are enabled per default). + + 2007-08-26 Marc Boucher + * api_msg.c: do_close_internal(): Reset the callbacks and arg (conn) to NULL + since they can under certain circumstances be called with an invalid conn + pointer after the connection has been closed (and conn has been freed). + + 2007-08-25 Frédéric Bernon (Artem Migaev's Patch) + * netif.h, netif.c: Integrate "patch #6163 : Function to check if link layer is up". + Add a netif_is_link_up() function if LWIP_NETIF_LINK_CALLBACK option is set. + + 2007-08-22 Frédéric Bernon + * netif.h, netif.c, opt.h: Rename LWIP_NETIF_CALLBACK in LWIP_NETIF_STATUS_CALLBACK + to be coherent with new LWIP_NETIF_LINK_CALLBACK option before next release. + + 2007-08-22 Frédéric Bernon + * tcpip.h, tcpip.c, ethernetif.c, opt.h: remove options ETHARP_TCPIP_INPUT & + ETHARP_TCPIP_ETHINPUT, now, only "ethinput" code is supported, even if the + name is tcpip_input (we keep the name of 1.2.0 function). + + 2007-08-17 Jared Grubb + * memp_std.h, memp.h, memp.c, mem.c, stats.c: (Task #7136) Centralize mempool + settings into new memp_std.h and optional user file lwippools.h. This adds + more dynamic mempools, and allows the user to create an arbitrary number of + mempools for mem_malloc. + + 2007-08-16 Marc Boucher + * api_msg.c: Initialize newconn->state to NETCONN_NONE in accept_function; + otherwise it was left to NETCONN_CLOSE and sent_tcp() could prematurely + close the connection. + + 2007-08-16 Marc Boucher + * sockets.c: lwip_accept(): check netconn_peer() error return. + + 2007-08-16 Marc Boucher + * mem.c, mem.h: Added mem_calloc(). + + 2007-08-16 Marc Boucher + * tcpip.c, tcpip.h memp.c, memp.h: Added distinct memp (MEMP_TCPIP_MSG_INPKT) + for input packets to prevent floods from consuming all of MEMP_TCPIP_MSG + and starving other message types. + Renamed MEMP_TCPIP_MSG to MEMP_TCPIP_MSG_API + + 2007-08-16 Marc Boucher + * pbuf.c, pbuf.h, etharp.c, tcp_in.c, sockets.c: Split pbuf flags in pbuf + type and flgs (later renamed to flags). + Use enum pbuf_flag as pbuf_type. Renumber PBUF_FLAG_*. + Improved lwip_recvfrom(). TCP push now propagated. + + 2007-08-16 Marc Boucher + * ethernetif.c, contrib/ports/various: ethbroadcast now a shared global + provided by etharp. + + 2007-08-16 Marc Boucher + * ppp_oe.c ppp_oe.h, auth.c chap.c fsm.c lcp.c ppp.c ppp.h, + etharp.c ethernetif.c, etharp.h, opt.h tcpip.h, tcpip.c: + Added PPPoE support and various PPP improvements. + + 2007-07-25 Simon Goldschmidt + * api_lib.c, ip_frag.c, pbuf.c, api.h, pbuf.h: Introduced pbuf_copy_partial, + making netbuf_copy_partial use this function. + + 2007-07-25 Simon Goldschmidt + * tcp_in.c: Fix bug #20506: Slow start / initial congestion window starts with + 2 * mss (instead of 1 * mss previously) to comply with some newer RFCs and + other stacks. + + 2007-07-13 Jared Grubb (integrated by Frédéric Bernon) + * opt.h, netif.h, netif.c, ethernetif.c: Add new configuration option to add + a link callback in the netif struct, and functions to handle it. Be carefull + for port maintainers to add the NETIF_FLAG_LINK_UP flag (like in ethernetif.c) + if you want to be sure to be compatible with future changes... + + 2007-06-30 Frédéric Bernon + * sockets.h, sockets.c: Implement MSG_PEEK flag for recv/recvfrom functions. + + 2007-06-21 Simon Goldschmidt + * etharp.h, etharp.c: Combined etharp_request with etharp_raw for both + LWIP_AUTOIP =0 and =1 to remove redundant code. + + 2007-06-21 Simon Goldschmidt + * mem.c, memp.c, mem.h, memp.h, opt.h: task #6863: Introduced the option + MEM_USE_POOLS to use 4 pools with different sized elements instead of a + heap. This both prevents memory fragmentation and gives a higher speed + at the cost of more memory consumption. Turned off by default. + + 2007-06-21 Simon Goldschmidt + * api_lib.c, api_msg.c, api.h, api_msg.h: Converted the length argument of + netconn_write (and therefore also api_msg_msg.msg.w.len) from u16_t into + int to be able to send a bigger buffer than 64K with one time (mainly + used from lwip_send). + + 2007-06-21 Simon Goldschmidt + * tcp.h, api_msg.c: Moved the nagle algorithm from netconn_write/do_write + into a define (tcp_output_nagle) in tcp.h to provide it to raw api users, too. + + 2007-06-21 Simon Goldschmidt + * api.h, api_lib.c, api_msg.c: Fixed bug #20021: Moved sendbuf-processing in + netconn_write from api_lib.c to api_msg.c to also prevent multiple context- + changes on low memory or empty send-buffer. + + 2007-06-18 Simon Goldschmidt + * etharp.c, etharp.h: Changed etharp to use a defined hardware address length + of 6 to avoid loading netif->hwaddr_len every time (since this file is only + used for ethernet and struct eth_addr already had a defined length of 6). + + 2007-06-17 Simon Goldschmidt + * sockets.c, sockets.h: Implemented socket options SO_NO_CHECK for UDP sockets + to disable UDP checksum generation on transmit. + + 2007-06-13 Frédéric Bernon, Simon Goldschmidt + * debug.h, api_msg.c: change LWIP_ERROR to use it to check errors like invalid + pointers or parameters, and let the possibility to redefined it in cc.h. Use + this macro to check "conn" parameter in api_msg.c functions. + + 2007-06-11 Simon Goldschmidt + * sockets.c, sockets.h: Added UDP lite support for sockets + + 2007-06-10 Simon Goldschmidt + * udp.h, opt.h, api_msg.c, ip.c, udp.c: Included switch LWIP_UDPLITE (enabled + by default) to switch off UDP-Lite support if not needed (reduces udp.c code + size) + + 2007-06-09 Dominik Spies (integrated by Frédéric Bernon) + * autoip.h, autoip.c, dhcp.h, dhcp.c, netif.h, netif.c, etharp.h, etharp.c, opt.h: + AutoIP implementation available for IPv4, with new options LWIP_AUTOIP and + LWIP_DHCP_AUTOIP_COOP if you want to cooperate with DHCP. Some tips to adapt + (see TODO mark in the source code). + + 2007-06-09 Simon Goldschmidt + * etharp.h, etharp.c, ethernetif.c: Modified order of parameters for + etharp_output() to match netif->output so etharp_output() can be used + directly as netif->output to save one function call. + + 2007-06-08 Simon Goldschmidt + * netif.h, ethernetif.c, slipif.c, loopif.c: Added define + NETIF_INIT_SNMP(netif, type, speed) to initialize per-netif snmp variables, + added initialization of those to ethernetif, slipif and loopif. + + 2007-05-18 Simon Goldschmidt + * opt.h, ip_frag.c, ip_frag.h, ip.c: Added option IP_FRAG_USES_STATIC_BUF + (defaulting to off for now) that can be set to 0 to send fragmented + packets by passing PBUF_REFs down the stack. + + 2007-05-23 Frédéric Bernon + * api_lib.c: Implement SO_RCVTIMEO for accept and recv on TCP + connections, such present in patch #5959. + + 2007-05-23 Frédéric Bernon + * api.h, api_lib.c, api_msg.c, sockets.c: group the different NETCONN_UDPxxx + code in only one part... + + 2007-05-18 Simon Goldschmidt + * opt.h, memp.h, memp.c: Added option MEMP_OVERFLOW_CHECK to check for memp + elements to overflow. This is achieved by adding some bytes before and after + each pool element (increasing their size, of course), filling them with a + prominent value and checking them on freeing the element. + Set it to 2 to also check every element in every pool each time memp_malloc() + or memp_free() is called (slower but more helpful). + + 2007-05-10 Simon Goldschmidt + * opt.h, memp.h, memp.c, pbuf.c (see task #6831): use a new memp pool for + PBUF_POOL pbufs instead of the old pool implementation in pbuf.c to reduce + code size. + + 2007-05-11 Frédéric Bernon + * sockets.c, api_lib.c, api_msg.h, api_msg.c, netifapi.h, netifapi.c, tcpip.c: + Include a function pointer instead of a table index in the message to reduce + footprint. Disable some part of lwip_send and lwip_sendto if some options are + not set (LWIP_TCP, LWIP_UDP, LWIP_RAW). + + 2007-05-10 Simon Goldschmidt + * *.h (except netif/ppp/*.h): Included patch #5448: include '#ifdef __cplusplus + \ extern "C" {' in all header files. Now you can write your application using + the lwIP stack in C++ and simply #include the core files. Note I have left + out the netif/ppp/*h header files for now, since I don't know which files are + included by applications and which are for internal use only. + + 2007-05-09 Simon Goldschmidt + * opt.h, *.c/*.h: Included patch #5920: Create define to override C-library + memcpy. 2 Defines are created: MEMCPY() for normal memcpy, SMEMCPY() for + situations where some compilers might inline the copy and save a function + call. Also replaced all calls to memcpy() with calls to (S)MEMCPY(). + + 2007-05-08 Simon Goldschmidt + * mem.h: If MEM_LIBC_MALLOC==1, allow the defines (e.g. mem_malloc() -> malloc()) + to be overriden in case the C-library malloc implementation is not protected + against concurrent access. + + 2007-05-04 Simon Goldschmidt (Atte Kojo) + * etharp.c: Introduced fast one-entry-cache to speed up ARP lookup when sending + multiple packets to the same host. + + 2007-05-04 Frédéric Bernon, Jonathan Larmour + * sockets.c, api.h, api_lib.c, api_msg.h, api_msg.c: Fix bug #19162 "lwip_sento: a possible + to corrupt remote addr/port connection state". Reduce problems "not enought memory" with + netbuf (if we receive lot of datagrams). Improve lwip_sendto (only one exchange between + sockets api and api_msg which run in tcpip_thread context). Add netconn_sento function. + Warning, if you directly access to "fromaddr" & "fromport" field from netbuf struct, + these fields are now renamed "addr" & "port". + + 2007-04-11 Jonathan Larmour + * sys.h, api_lib.c: Provide new sys_mbox_tryfetch function. Require ports to provide new + sys_arch_mbox_tryfetch function to get a message if one is there, otherwise return + with SYS_MBOX_EMPTY. sys_arch_mbox_tryfetch can be implemented as a function-like macro + by the port in sys_arch.h if desired. + + 2007-04-06 Frédéric Bernon, Simon Goldschmidt + * opt.h, tcpip.h, tcpip.c, netifapi.h, netifapi.c: New configuration option LWIP_NETIF_API + allow to use thread-safe functions to add/remove netif in list, and to start/stop dhcp + clients, using new functions from netifapi.h. Disable as default (no port change to do). + + 2007-04-05 Frédéric Bernon + * sockets.c: remplace ENOBUFS errors on alloc_socket by ENFILE to be more BSD compliant. + + 2007-04-04 Simon Goldschmidt + * arch.h, api_msg.c, dhcp.c, msg_in.c, sockets.c: Introduced #define LWIP_UNUSED_ARG(x) + use this for and architecture-independent form to tell the compiler you intentionally + are not using this variable. Can be overriden in cc.h. + + 2007-03-28 Frédéric Bernon + * opt.h, netif.h, dhcp.h, dhcp.c: New configuration option LWIP_NETIF_HOSTNAME allow to + define a hostname in netif struct (this is just a pointer, so, you can use a hardcoded + string, point on one of your's ethernetif field, or alloc a string you will free yourself). + It will be used by DHCP to register a client hostname, but can also be use when you call + snmp_set_sysname. + + 2007-03-28 Frédéric Bernon + * netif.h, netif.c: A new NETIF_FLAG_ETHARP flag is defined in netif.h, to allow to + initialize a network interface's flag with. It tell this interface is an ethernet + device, and we can use ARP with it to do a "gratuitous ARP" (RFC 3220 "IP Mobility + Support for IPv4" section 4.6) when interface is "up" with netif_set_up(). + + 2007-03-26 Frédéric Bernon, Jonathan Larmour + * opt.h, tcpip.c: New configuration option LWIP_ARP allow to disable ARP init at build + time if you only use PPP or SLIP. The default is enable. Note we don't have to call + etharp_init in your port's initilization sequence if you use tcpip.c, because this call + is done in tcpip_init function. + + 2007-03-22 Frédéric Bernon + * stats.h, stats.c, msg_in.c: Stats counters can be change to u32_t if necessary with the + new option LWIP_STATS_LARGE. If you need this option, define LWIP_STATS_LARGE to 1 in + your lwipopts.h. More, unused counters are not defined in the stats structs, and not + display by stats_display(). Note that some options (SYS_STATS and RAW_STATS) are defined + but never used. Fix msg_in.c with the correct #if test for a stat display. + + 2007-03-21 Kieran Mansley + * netif.c, netif.h: Apply patch#4197 with some changes (originator: rireland@hmgsl.com). + Provides callback on netif up/down state change. + + 2007-03-11 Frédéric Bernon, Mace Gael, Steve Reynolds + * sockets.h, sockets.c, api.h, api_lib.c, api_msg.h, api_msg.c, igmp.h, igmp.c, + ip.c, netif.h, tcpip.c, opt.h: + New configuration option LWIP_IGMP to enable IGMP processing. Based on only one + filter per all network interfaces. Declare a new function in netif to enable to + control the MAC filter (to reduce lwIP traffic processing). + + 2007-03-11 Frédéric Bernon + * tcp.h, tcp.c, sockets.c, tcp_out.c, tcp_in.c, opt.h: Keepalive values can + be configured at run time with LWIP_TCP_KEEPALIVE, but don't change this + unless you know what you're doing (default are RFC1122 compliant). Note + that TCP_KEEPIDLE and TCP_KEEPINTVL have to be set in seconds. + + 2007-03-08 Frédéric Bernon + * tcp.h: Keepalive values can be configured at compile time, but don't change + this unless you know what you're doing (default are RFC1122 compliant). + + 2007-03-08 Frédéric Bernon + * sockets.c, api.h, api_lib.c, tcpip.c, sys.h, sys.c, err.c, opt.h: + Implement LWIP_SO_RCVTIMEO configuration option to enable/disable SO_RCVTIMEO + on UDP sockets/netconn. + + 2007-03-08 Simon Goldschmidt + * snmp_msg.h, msg_in.c: SNMP UDP ports can be configured at compile time. + + 2007-03-06 Frédéric Bernon + * api.h, api_lib.c, sockets.h, sockets.c, tcpip.c, sys.h, sys.c, err.h: + Implement SO_RCVTIMEO on UDP sockets/netconn. + + 2007-02-28 Kieran Mansley (based on patch from Simon Goldschmidt) + * api_lib.c, tcpip.c, memp.c, memp.h: make API msg structs allocated + on the stack and remove the API msg type from memp + + 2007-02-26 Jonathan Larmour (based on patch from Simon Goldschmidt) + * sockets.h, sockets.c: Move socket initialization to new + lwip_socket_init() function. + NOTE: this changes the API with ports. Ports will have to be + updated to call lwip_socket_init() now. + + 2007-02-26 Jonathan Larmour (based on patch from Simon Goldschmidt) + * api_lib.c: Use memcpy in netbuf_copy_partial. + + + ++ Bug fixes: + + 2008-03-17 Frédéric Bernon, Ed Kerekes + * igmp.h, igmp.c: Fix bug #22613 "IGMP iphdr problem" (could have + some problems to fill the IP header on some targets, use now the + ip.h macros to do it). + + 2008-03-13 Frédéric Bernon + * sockets.c: Fix bug #22435 "lwip_recvfrom with TCP break;". Using + (lwip_)recvfrom with valid "from" and "fromlen" parameters, on a + TCP connection caused a crash. Note that using (lwip_)recvfrom + like this is a bit slow and that using (lwip)getpeername is the + good lwip way to do it (so, using recv is faster on tcp sockets). + + 2008-03-12 Frédéric Bernon, Jonathan Larmour + * api_msg.c, contrib/apps/ping.c: Fix bug #22530 "api_msg.c's + recv_raw() does not consume data", and the ping sample (with + LWIP_SOCKET=1, the code did the wrong supposition that lwip_recvfrom + returned the IP payload, without the IP header). + + 2008-03-04 Jonathan Larmour + * mem.c, stats.c, mem.h: apply patch #6414 to avoid compiler errors + and/or warnings on some systems where mem_size_t and size_t differ. + * pbuf.c, ppp.c: Fix warnings on some systems with mem_malloc. + + 2008-03-04 Kieran Mansley (contributions by others) + * Numerous small compiler error/warning fixes from contributions to + mailing list after 1.3.0 release candidate made. + + 2008-01-25 Cui hengbin (integrated by Frédéric Bernon) + * dns.c: Fix bug #22108 "DNS problem" caused by unaligned structures. + + 2008-01-15 Kieran Mansley + * tcp_out.c: BUG20511. Modify persist timer to start when we are + prevented from sending by a small send window, not just a zero + send window. + + 2008-01-09 Jonathan Larmour + * opt.h, ip.c: Rename IP_OPTIONS define to IP_OPTIONS_ALLOWED to avoid + conflict with Linux system headers. + + 2008-01-06 Jonathan Larmour + * dhcp.c: fix bug #19927: "DHCP NACK problem" by clearing any existing set IP + address entirely on receiving a DHCPNAK, and restarting discovery. + + 2007-12-21 Simon Goldschmidt + * sys.h, api_lib.c, api_msg.c, sockets.c: fix bug #21698: "netconn->recv_avail + is not protected" by using new macros for interlocked access to modify/test + netconn->recv_avail. + + 2007-12-20 Kieran Mansley (based on patch from Oleg Tyshev) + * tcp_in.c: fix bug# 21535 (nrtx not reset correctly in SYN_SENT state) + + 2007-12-20 Kieran Mansley (based on patch from Per-Henrik Lundbolm) + * tcp.c, tcp_in.c, tcp_out.c, tcp.h: fix bug #20199 (better handling + of silly window avoidance and prevent lwIP from shrinking the window) + + 2007-12-04 Simon Goldschmidt + * tcp.c, tcp_in.c: fix bug #21699 (segment leak in ooseq processing when last + data packet was lost): add assert that all segment lists are empty in + tcp_pcb_remove before setting pcb to CLOSED state; don't directly set CLOSED + state from LAST_ACK in tcp_process + + 2007-12-02 Simon Goldschmidt + * sockets.h: fix bug #21654: exclude definition of struct timeval from #ifndef FD_SET + If including for system-struct timeval, LWIP_TIMEVAL_PRIVATE now + has to be set to 0 in lwipopts.h + + 2007-12-02 Simon Goldschmidt + * api_msg.c, api_lib.c: fix bug #21656 (recvmbox problem in netconn API): always + allocate a recvmbox in netconn_new_with_proto_and_callback. For a tcp-listen + netconn, this recvmbox is later freed and a new mbox is allocated for acceptmbox. + This is a fix for thread-safety and allocates all items needed for a netconn + when the netconn is created. + + 2007-11-30 Simon Goldschmidt + * udp.c: first attempt to fix bug #21655 (DHCP doesn't work reliably with multiple + netifs): if LWIP_DHCP is enabled, UDP packets to DHCP_CLIENT_PORT are passed + to netif->dhcp->pcb only (if that exists) and not to any other pcb for the same + port (only solution to let UDP pcbs 'bind' to a netif instead of an IP address) + + 2007-11-27 Simon Goldschmidt + * ip.c: fixed bug #21643 (udp_send/raw_send don't fail if netif is down) by + letting ip_route only use netifs that are up. + + 2007-11-27 Simon Goldschmidt + * err.h, api_lib.c, api_msg.c, sockets.c: Changed error handling: ERR_MEM, ERR_BUF + and ERR_RTE are seen as non-fatal, all other errors are fatal. netconns and + sockets block most operations once they have seen a fatal error. + + 2007-11-27 Simon Goldschmidt + * udp.h, udp.c, dhcp.c: Implemented new function udp_sendto_if which takes the + netif to send as an argument (to be able to send on netifs that are down). + + 2007-11-26 Simon Goldschmidt + * tcp_in.c: Fixed bug #21582: pcb->acked accounting can be wrong when ACKs + arrive out-of-order + + 2007-11-21 Simon Goldschmidt + * tcp.h, tcp_out.c, api_msg.c: Fixed bug #20287: tcp_output_nagle sends too early + Fixed the nagle algorithm; nagle now also works for all raw API applications + and has to be explicitly disabled with 'tcp_pcb->flags |= TF_NODELAY' + + 2007-11-12 Frédéric Bernon + * sockets.c, api.h, api_lib.c, api_msg.h, api_msg.c: Fixed bug #20900. Now, most + of the netconn_peer and netconn_addr processing is done inside tcpip_thread + context in do_getaddr. + + 2007-11-10 Simon Goldschmidt + * etharp.c: Fixed bug: assert fired when MEMP_ARP_QUEUE was empty (which can + happen any time). Now the packet simply isn't enqueued when out of memory. + + 2007-11-01 Simon Goldschmidt + * tcp.c, tcp_in.c: Fixed bug #21494: The send mss (pcb->mss) is set to 536 (or + TCP_MSS if that is smaller) as long as no MSS option is received from the + remote host. + + 2007-11-01 Simon Goldschmidt + * tcp.h, tcp.c, tcp_in.c: Fixed bug #21491: The MSS option sent (with SYN) + is now based on TCP_MSS instead of pcb->mss (on passive open now effectively + sending our configured TCP_MSS instead of the one received). + + 2007-11-01 Simon Goldschmidt + * tcp_in.c: Fixed bug #21181: On active open, the initial congestion window was + calculated based on the configured TCP_MSS, not on the MSS option received + with SYN+ACK. + + 2007-10-09 Simon Goldschmidt + * udp.c, inet.c, inet.h: Fixed UDPLite: send: Checksum was always generated too + short and also was generated wrong if checksum coverage != tot_len; + receive: checksum was calculated wrong if checksum coverage != tot_len + + 2007-10-08 Simon Goldschmidt + * mem.c: lfree was not updated in mem_realloc! + + 2007-10-07 Frédéric Bernon + * sockets.c, api.h, api_lib.c: First step to fix "bug #20900 : Potential + crash error problem with netconn_peer & netconn_addr". VERY IMPORTANT: + this change cause an API breakage for netconn_addr, since a parameter + type change. Any compiler should cause an error without any changes in + yours netconn_peer calls (so, it can't be a "silent change"). It also + reduce a little bit the footprint for socket layer (lwip_getpeername & + lwip_getsockname use now a common lwip_getaddrname function since + netconn_peer & netconn_addr have the same parameters). + + 2007-09-20 Simon Goldschmidt + * tcp.c: Fixed bug #21080 (tcp_bind without check pcbs in TIME_WAIT state) + by checking tcp_tw_pcbs also + + 2007-09-19 Simon Goldschmidt + * icmp.c: Fixed bug #21107 (didn't reset IP TTL in ICMP echo replies) + + 2007-09-15 Mike Kleshov + * mem.c: Fixed bug #21077 (inaccuracy in calculation of lwip_stat.mem.used) + + 2007-09-06 Frédéric Bernon + * several-files: replace some #include "arch/cc.h" by "lwip/arch.h", or simply remove + it as long as "lwip/opt.h" is included before (this one include "lwip/debug.h" which + already include "lwip/arch.h"). Like that, default defines are provided by "lwip/arch.h" + if they are not defined in cc.h, in the same spirit than "lwip/opt.h" for lwipopts.h. + + 2007-08-30 Frédéric Bernon + * igmp.h, igmp.c: Some changes to remove some redundant code, add some traces, + and fix some coding style. + + 2007-08-28 Frédéric Bernon + * tcpip.c: Fix TCPIP_MSG_INPKT processing: now, tcpip_input can be used for any + kind of packets. These packets are considered like Ethernet packets (payload + pointing to ethhdr) if the netif got the NETIF_FLAG_ETHARP flag. Else, packets + are considered like IP packets (payload pointing to iphdr). + + 2007-08-27 Frédéric Bernon + * api.h, api_lib.c, api_msg.c: First fix for "bug #20900 : Potential crash error + problem with netconn_peer & netconn_addr". Introduce NETCONN_LISTEN netconn_state + and remove obsolete ones (NETCONN_RECV & NETCONN_ACCEPT). + + 2007-08-24 Kieran Mansley + * inet.c Modify (acc >> 16) test to ((acc >> 16) != 0) to help buggy + compiler (Paradigm C++) + + 2007-08-09 Frédéric Bernon, Bill Florac + * stats.h, stats.c, igmp.h, igmp.c, opt.h: Fix for bug #20503 : IGMP Improvement. + Introduce IGMP_STATS to centralize statistics management. + + 2007-08-09 Frédéric Bernon, Bill Florac + * udp.c: Fix for bug #20503 : IGMP Improvement. Enable to receive a multicast + packet on a udp pcb binded on an netif's IP address, and not on "any". + + 2007-08-09 Frédéric Bernon, Bill Florac + * igmp.h, igmp.c, ip.c: Fix minor changes from bug #20503 : IGMP Improvement. + This is mainly on using lookup/lookfor, and some coding styles... + + 2007-07-26 Frédéric Bernon (and "thedoctor") + * igmp.c: Fix bug #20595 to accept IGMPv3 "Query" messages. + + 2007-07-25 Simon Goldschmidt + * api_msg.c, tcp.c: Another fix for bug #20021: by not returning an error if + tcp_output fails in tcp_close, the code in do_close_internal gets simpler + (tcp_output is called again later from tcp timers). + + 2007-07-25 Simon Goldschmidt + * ip_frag.c: Fixed bug #20429: use the new pbuf_copy_partial instead of the old + copy_from_pbuf, which illegally modified the given pbuf. + + 2007-07-25 Simon Goldschmidt + * tcp_out.c: tcp_enqueue: pcb->snd_queuelen didn't work for chaine PBUF_RAMs: + changed snd_queuelen++ to snd_queuelen += pbuf_clen(p). + + 2007-07-24 Simon Goldschmidt + * api_msg.c, tcp.c: Fix bug #20480: Check the pcb passed to tcp_listen() for the + correct state (must be CLOSED). + + 2007-07-13 Thomas Taranowski (commited by Jared Grubb) + * memp.c: Fix bug #20478: memp_malloc returned NULL+MEMP_SIZE on failed + allocation. It now returns NULL. + + 2007-07-13 Frédéric Bernon + * api_msg.c: Fix bug #20318: api_msg "recv" callbacks don't call pbuf_free in + all error cases. + + 2007-07-13 Frédéric Bernon + * api_msg.c: Fix bug #20315: possible memory leak problem if tcp_listen failed, + because current code doesn't follow rawapi.txt documentation. + + 2007-07-13 Kieran Mansley + * src/core/tcp_in.c Apply patch#5741 from Oleg Tyshev to fix bug in + out of sequence processing of received packets + + 2007-07-03 Simon Goldschmidt + * nearly-all-files: Added assertions where PBUF_RAM pbufs are used and an + assumption is made that this pbuf is in one piece (i.e. not chained). These + assumptions clash with the possibility of converting to fully pool-based + pbuf implementations, where PBUF_RAM pbufs might be chained. + + 2007-07-03 Simon Goldschmidt + * api.h, api_lib.c, api_msg.c: Final fix for bug #20021 and some other problems + when closing tcp netconns: removed conn->sem, less context switches when + closing, both netconn_close and netconn_delete should safely close tcp + connections. + + 2007-07-02 Simon Goldschmidt + * ipv4/ip.h, ipv6/ip.h, opt.h, netif.h, etharp.h, ipv4/ip.c, netif.c, raw.c, + tcp_out.c, udp.c, etharp.c: Added option LWIP_NETIF_HWADDRHINT (default=off) + to cache ARP table indices with each pcb instead of single-entry cache for + the complete stack. + + 2007-07-02 Simon Goldschmidt + * tcp.h, tcp.c, tcp_in.c, tcp_out.c: Added some ASSERTS and casts to prevent + warnings when assigning to smaller types. + + 2007-06-28 Simon Goldschmidt + * tcp_out.c: Added check to prevent tcp_pcb->snd_queuelen from overflowing. + + 2007-06-28 Simon Goldschmidt + * tcp.h: Fixed bug #20287: Fixed nagle algorithm (sending was done too early if + a segment contained chained pbufs) + + 2007-06-28 Frédéric Bernon + * autoip.c: replace most of rand() calls by a macro LWIP_AUTOIP_RAND which compute + a "pseudo-random" value based on netif's MAC and some autoip fields. It's always + possible to define this macro in your own lwipopts.h to always use C library's + rand(). Note that autoip_create_rand_addr doesn't use this macro. + + 2007-06-28 Frédéric Bernon + * netifapi.h, netifapi.c, tcpip.h, tcpip.c: Update code to handle the option + LWIP_TCPIP_CORE_LOCKING, and do some changes to be coherent with last modifications + in api_lib/api_msg (use pointers and not type with table, etc...) + + 2007-06-26 Simon Goldschmidt + * udp.h: Fixed bug #20259: struct udp_hdr was lacking the packin defines. + + 2007-06-25 Simon Goldschmidt + * udp.c: Fixed bug #20253: icmp_dest_unreach was called with a wrong p->payload + for udp packets with no matching pcb. + + 2007-06-25 Simon Goldschmidt + * udp.c: Fixed bug #20220: UDP PCB search in udp_input(): a non-local match + could get udp input packets if the remote side matched. + + 2007-06-13 Simon Goldschmidt + * netif.c: Fixed bug #20180 (TCP pcbs listening on IP_ADDR_ANY could get + changed in netif_set_ipaddr if previous netif->ip_addr.addr was 0. + + 2007-06-13 Simon Goldschmidt + * api_msg.c: pcb_new sets conn->err if protocol is not implemented + -> netconn_new_..() does not allocate a new connection for unsupported + protocols. + + 2007-06-13 Frédéric Bernon, Simon Goldschmidt + * api_lib.c: change return expression in netconn_addr and netconn_peer, because + conn->err was reset to ERR_OK without any reasons (and error was lost)... + + 2007-06-13 Frédéric Bernon, Matthias Weisser + * opt.h, mem.h, mem.c, memp.c, pbuf.c, ip_frag.c, vj.c: Fix bug #20162. Rename + MEM_ALIGN in LWIP_MEM_ALIGN and MEM_ALIGN_SIZE in LWIP_MEM_ALIGN_SIZE to avoid + some macro names collision with some OS macros. + + 2007-06-11 Simon Goldschmidt + * udp.c: UDP Lite: corrected the use of chksum_len (based on RFC3828: if it's 0, + create checksum over the complete packet. On RX, if it's < 8 (and not 0), + discard the packet. Also removed the duplicate 'udphdr->chksum = 0' for both + UDP & UDP Lite. + + 2007-06-11 Srinivas Gollakota & Oleg Tyshev + * tcp_out.c: Fix for bug #20075 : "A problem with keep-alive timer and TCP flags" + where TCP flags wasn't initialized in tcp_keepalive. + + 2007-06-03 Simon Goldschmidt + * udp.c: udp_input(): Input pbuf was not freed if pcb had no recv function + registered, p->payload was modified without modifying p->len if sending + icmp_dest_unreach() (had no negative effect but was definitively wrong). + + 2007-06-03 Simon Goldschmidt + * icmp.c: Corrected bug #19937: For responding to an icmp echo request, icmp + re-used the input pbuf even if that didn't have enough space to include the + link headers. Now the space is tested and a new pbuf is allocated for the + echo response packet if the echo request pbuf isn't big enough. + + 2007-06-01 Simon Goldschmidt + * sockets.c: Checked in patch #5914: Moved sockopt processing into tcpip_thread. + + 2007-05-23 Frédéric Bernon + * api_lib.c, sockets.c: Fixed bug #5958 for netconn_listen (acceptmbox only + allocated by do_listen if success) and netconn_accept errors handling. In + most of api_lib functions, we replace some errors checkings like "if (conn==NULL)" + by ASSERT, except for netconn_delete. + + 2007-05-23 Frédéric Bernon + * api_lib.c: Fixed bug #5957 "Safe-thread problem inside netconn_recv" to return + an error code if it's impossible to fetch a pbuf on a TCP connection (and not + directly close the recvmbox). + + 2007-05-22 Simon Goldschmidt + * tcp.c: Fixed bug #1895 (tcp_bind not correct) by introducing a list of + bound but unconnected (and non-listening) tcp_pcbs. + + 2007-05-22 Frédéric Bernon + * sys.h, sys.c, api_lib.c, tcpip.c: remove sys_mbox_fetch_timeout() (was only + used for LWIP_SO_RCVTIMEO option) and use sys_arch_mbox_fetch() instead of + sys_mbox_fetch() in api files. Now, users SHOULD NOT use internal lwIP features + like "sys_timeout" in their application threads. + + 2007-05-22 Frédéric Bernon + * api.h, api_lib.c, api_msg.h, api_msg.c: change the struct api_msg_msg to see + which parameters are used by which do_xxx function, and to avoid "misusing" + parameters (patch #5938). + + 2007-05-22 Simon Goldschmidt + * api_lib.c, api_msg.c, raw.c, api.h, api_msg.h, raw.h: Included patch #5938: + changed raw_pcb.protocol from u16_t to u8_t since for IPv4 and IPv6, proto + is only 8 bits wide. This affects the api, as there, the protocol was + u16_t, too. + + 2007-05-18 Simon Goldschmidt + * memp.c: addition to patch #5913: smaller pointer was returned but + memp_memory was the same size -> did not save memory. + + 2007-05-16 Simon Goldschmidt + * loopif.c, slipif.c: Fix bug #19729: free pbuf if netif->input() returns + != ERR_OK. + + 2007-05-16 Simon Goldschmidt + * api_msg.c, udp.c: If a udp_pcb has a local_ip set, check if it is the same + as the one of the netif used for sending to prevent sending from old + addresses after a netif address gets changed (partly fixes bug #3168). + + 2007-05-16 Frédéric Bernon + * tcpip.c, igmp.h, igmp.c: Fixed bug "#19800 : IGMP: igmp_tick() will not work + with NO_SYS=1". Note that igmp_init is always in tcpip_thread (and not in + tcpip_init) because we have to be sure that network interfaces are already + added (mac filter is updated only in igmp_init for the moment). + + 2007-05-16 Simon Goldschmidt + * mem.c, memp.c: Removed semaphores from memp, changed sys_sem_wait calls + into sys_arch_sem_wait calls to prevent timers from running while waiting + for the heap. This fixes bug #19167. + + 2007-05-13 Simon Goldschmidt + * tcp.h, sockets.h, sockets.c: Fixed bug from patch #5865 by moving the defines + for socket options (lwip_set/-getsockopt) used with level IPPROTO_TCP from + tcp.h to sockets.h. + + 2007-05-07 Simon Goldschmidt + * mem.c: Another attempt to fix bug #17922. + + 2007-05-04 Simon Goldschmidt + * pbuf.c, pbuf.h, etharp.c: Further update to ARP queueing: Changed pbuf_copy() + implementation so that it can be reused (don't allocate the target + pbuf inside pbuf_copy()). + + 2007-05-04 Simon Goldschmidt + * memp.c: checked in patch #5913: in memp_malloc() we can return memp as mem + to save a little RAM (next pointer of memp is not used while not in pool). + + 2007-05-03 "maq" + * sockets.c: Fix ioctl FIONREAD when some data remains from last recv. + (patch #3574). + + 2007-04-23 Simon Goldschmidt + * loopif.c, loopif.h, opt.h, src/netif/FILES: fix bug #2595: "loopif results + in NULL reference for incoming TCP packets". Loopif has to be configured + (using LWIP_LOOPIF_MULTITHREADING) to directly call netif->input() + (multithreading environments, e.g. netif->input() = tcpip_input()) or + putting packets on a list that is fed to the stack by calling loopif_poll() + (single-thread / NO_SYS / polling environment where e.g. + netif->input() = ip_input). + + 2007-04-17 Jonathan Larmour + * pbuf.c: Use s32_t in pbuf_realloc(), as an s16_t can't reliably hold + the difference between two u16_t's. + * sockets.h: FD_SETSIZE needs to match number of sockets, which is + MEMP_NUM_NETCONN in sockets.c right now. + + 2007-04-12 Jonathan Larmour + * icmp.c: Reset IP header TTL in ICMP ECHO responses (bug #19580). + + 2007-04-12 Kieran Mansley + * tcp.c, tcp_in.c, tcp_out.c, tcp.h: Modify way the retransmission + timer is reset to fix bug#19434, with help from Oleg Tyshev. + + 2007-04-11 Simon Goldschmidt + * etharp.c, pbuf.c, pbuf.h: 3rd fix for bug #11400 (arp-queuing): More pbufs than + previously thought need to be copied (everything but PBUF_ROM!). Cleaned up + pbuf.c: removed functions no needed any more (by etharp). + + 2007-04-11 Kieran Mansley + * inet.c, ip_addr.h, sockets.h, sys.h, tcp.h: Apply patch #5745: Fix + "Constant is long" warnings with 16bit compilers. Contributed by + avatar@mmlab.cse.yzu.edu.tw + + 2007-04-05 Frédéric Bernon, Jonathan Larmour + * api_msg.c: Fix bug #16830: "err_tcp() posts to connection mailbox when no pend on + the mailbox is active". Now, the post is only done during a connect, and do_send, + do_write and do_join_leave_group don't do anything if a previous error was signaled. + + 2007-04-03 Frédéric Bernon + * ip.c: Don't set the IP_DF ("Don't fragment") flag in the IP header in IP output + packets. See patch #5834. + + 2007-03-30 Frédéric Bernon + * api_msg.c: add a "pcb_new" helper function to avoid redundant code, and to add + missing pcb allocations checking (in do_bind, and for each raw_new). Fix style. + + 2007-03-30 Frédéric Bernon + * most of files: prefix all debug.h define with "LWIP_" to avoid any conflict with + others environment defines (these were too "generic"). + + 2007-03-28 Frédéric Bernon + * api.h, api_lib.c, sockets.c: netbuf_ref doesn't check its internal pbuf_alloc call + result and can cause a crash. lwip_send now check netbuf_ref result. + + 2007-03-28 Simon Goldschmidt + * sockets.c Remove "#include " from sockets.c to avoid multiple + definition of macros (in errno.h and lwip/arch.h) if LWIP_PROVIDE_ERRNO is + defined. This is the way it should have been already (looking at + doc/sys_arch.txt) + + 2007-03-28 Kieran Mansley + * opt.h Change default PBUF_POOL_BUFSIZE (again) to accomodate default MSS + + IP and TCP headers *and* physical link headers + + 2007-03-26 Frédéric Bernon (based on patch from Dmitry Potapov) + * api_lib.c: patch for netconn_write(), fixes a possible race condition which cause + to send some garbage. It is not a definitive solution, but the patch does solve + the problem for most cases. + + 2007-03-22 Frédéric Bernon + * api_msg.h, api_msg.c: Remove obsolete API_MSG_ACCEPT and do_accept (never used). + + 2007-03-22 Frédéric Bernon + * api_lib.c: somes resources couldn't be freed if there was errors during + netconn_new_with_proto_and_callback. + + 2007-03-22 Frédéric Bernon + * ethernetif.c: update netif->input calls to check return value. In older ports, + it's a good idea to upgrade them, even if before, there could be another problem + (access to an uninitialized mailbox). + + 2007-03-21 Simon Goldschmidt + * sockets.c: fixed bug #5067 (essentialy a signed/unsigned warning fixed + by casting to unsigned). + + 2007-03-21 Frédéric Bernon + * api_lib.c, api_msg.c, tcpip.c: integrate sys_mbox_fetch(conn->mbox, NULL) calls from + api_lib.c to tcpip.c's tcpip_apimsg(). Now, use a local variable and not a + dynamic one from memp to send tcpip_msg to tcpip_thread in a synchrone call. + Free tcpip_msg from tcpip_apimsg is not done in tcpip_thread. This give a + faster and more reliable communication between api_lib and tcpip. + + 2007-03-21 Frédéric Bernon + * opt.h: Add LWIP_NETIF_CALLBACK (to avoid compiler warning) and set it to 0. + + 2007-03-21 Frédéric Bernon + * api_msg.c, igmp.c, igmp.h: Fix C++ style comments + + 2007-03-21 Kieran Mansley + * opt.h Change default PBUF_POOL_BUFSIZE to accomodate default MSS + + IP and TCP headers + + 2007-03-21 Kieran Mansley + * Fix all uses of pbuf_header to check the return value. In some + cases just assert if it fails as I'm not sure how to fix them, but + this is no worse than before when they would carry on regardless + of the failure. + + 2007-03-21 Kieran Mansley + * sockets.c, igmp.c, igmp.h, memp.h: Fix C++ style comments and + comment out missing header include in icmp.c + + 2007-03-20 Frédéric Bernon + * memp.h, stats.c: Fix stats_display function where memp_names table wasn't + synchronized with memp.h. + + 2007-03-20 Frédéric Bernon + * tcpip.c: Initialize tcpip's mbox, and verify if initialized in tcpip_input, + tcpip_ethinput, tcpip_callback, tcpip_apimsg, to fix a init problem with + network interfaces. Also fix a compiler warning. + + 2007-03-20 Kieran Mansley + * udp.c: Only try and use pbuf_header() to make space for headers if + not a ROM or REF pbuf. + + 2007-03-19 Frédéric Bernon + * api_msg.h, api_msg.c, tcpip.h, tcpip.c: Add return types to tcpip_apimsg() + and api_msg_post(). + + 2007-03-19 Frédéric Bernon + * Remove unimplemented "memp_realloc" function from memp.h. + + 2007-03-11 Simon Goldschmidt + * pbuf.c: checked in patch #5796: pbuf_alloc: len field claculation caused + memory corruption. + + 2007-03-11 Simon Goldschmidt (based on patch from Dmitry Potapov) + * api_lib.c, sockets.c, api.h, api_msg.h, sockets.h: Fixed bug #19251 + (missing `const' qualifier in socket functions), to get more compatible to + standard POSIX sockets. + + 2007-03-11 Frédéric Bernon (based on patch from Dmitry Potapov) + * sockets.c: Add asserts inside bind, connect and sendto to check input + parameters. Remove excessive set_errno() calls after get_socket(), because + errno is set inside of get_socket(). Move last sock_set_errno() inside + lwip_close. + + 2007-03-09 Simon Goldschmidt + * memp.c: Fixed bug #11400: New etharp queueing introduced bug: memp_memory + was allocated too small. + + 2007-03-06 Simon Goldschmidt + * tcpip.c: Initialize dhcp timers in tcpip_thread (if LWIP_DHCP) to protect + the stack from concurrent access. + + 2007-03-06 Frédéric Bernon, Dmitry Potapov + * tcpip.c, ip_frag.c, ethernetif.c: Fix some build problems, and a redundancy + call to "lwip_stats.link.recv++;" in low_level_input() & ethernetif_input(). + + 2007-03-06 Simon Goldschmidt + * ip_frag.c, ip_frag.h: Reduce code size: don't include code in those files + if IP_FRAG == 0 and IP_REASSEMBLY == 0 + + 2007-03-06 Frédéric Bernon, Simon Goldschmidt + * opt.h, ip_frag.h, tcpip.h, tcpip.c, ethernetif.c: add new configuration + option named ETHARP_TCPIP_ETHINPUT, which enable the new tcpip_ethinput. + Allow to do ARP processing for incoming packets inside tcpip_thread + (protecting ARP layer against concurrent access). You can also disable + old code using tcp_input with new define ETHARP_TCPIP_INPUT set to 0. + Older ports have to use tcpip_ethinput. + + 2007-03-06 Simon Goldschmidt (based on patch from Dmitry Potapov) + * err.h, err.c: fixed compiler warning "initialization dircards qualifiers + from pointer target type" + + 2007-03-05 Frédéric Bernon + * opt.h, sockets.h: add new configuration options (LWIP_POSIX_SOCKETS_IO_NAMES, + ETHARP_TRUST_IP_MAC, review SO_REUSE) + + 2007-03-04 Frédéric Bernon + * api_msg.c: Remove some compiler warnings : parameter "pcb" was never + referenced. + + 2007-03-04 Frédéric Bernon + * api_lib.c: Fix "[patch #5764] api_lib.c cleanup: after patch #5687" (from + Dmitry Potapov). + The api_msg struct stay on the stack (not moved to netconn struct). + + 2007-03-04 Simon Goldschmidt (based on patch from Dmitry Potapov) + * pbuf.c: Fix BUG#19168 - pbuf_free can cause deadlock (if + SYS_LIGHTWEIGHT_PROT=1 & freeing PBUF_RAM when mem_sem is not available) + Also fixed cast warning in pbuf_alloc() + + 2007-03-04 Simon Goldschmidt + * etharp.c, etharp.h, memp.c, memp.h, opt.h: Fix BUG#11400 - don't corrupt + existing pbuf chain when enqueuing multiple pbufs to a pending ARP request + + 2007-03-03 Frédéric Bernon + * udp.c: remove obsolete line "static struct udp_pcb *pcb_cache = NULL;" + It is static, and never used in udp.c except udp_init(). + + 2007-03-02 Simon Goldschmidt + * tcpip.c: Moved call to ip_init(), udp_init() and tcp_init() from + tcpip_thread() to tcpip_init(). This way, raw API connections can be + initialized before tcpip_thread is running (e.g. before OS is started) + + 2007-03-02 Frédéric Bernon + * rawapi.txt: Fix documentation mismatch with etharp.h about etharp_tmr's call + interval. + + 2007-02-28 Kieran Mansley + * pbuf.c: Fix BUG#17645 - ensure pbuf payload pointer is not moved + outside the region of the pbuf by pbuf_header() + + 2007-02-28 Kieran Mansley + * sockets.c: Fix BUG#19161 - ensure milliseconds timeout is non-zero + when supplied timeout is also non-zero + +(STABLE-1.2.0) + + 2006-12-05 Leon Woestenberg + * CHANGELOG: Mention STABLE-1.2.0 release. + + ++ New features: + + 2006-12-01 Christiaan Simons + * mem.h, opt.h: Added MEM_LIBC_MALLOC option. + Note this is a workaround. Currently I have no other options left. + + 2006-10-26 Christiaan Simons (accepted patch by Jonathan Larmour) + * ipv4/ip_frag.c: rename MAX_MTU to IP_FRAG_MAX_MTU and move define + to include/lwip/opt.h. + * ipv4/lwip/ip_frag.h: Remove unused IP_REASS_INTERVAL. + Move IP_REASS_MAXAGE and IP_REASS_BUFSIZE to include/lwip/opt.h. + * opt.h: Add above new options. + + 2006-08-18 Christiaan Simons + * tcp_{in,out}.c: added SNMP counters. + * ipv4/ip.c: added SNMP counters. + * ipv4/ip_frag.c: added SNMP counters. + + 2006-08-08 Christiaan Simons + * etharp.{c,h}: added etharp_find_addr() to read + (stable) ethernet/IP address pair from ARP table + + 2006-07-14 Christiaan Simons + * mib_structs.c: added + * include/lwip/snmp_structs.h: added + * netif.{c,h}, netif/ethernetif.c: added SNMP statistics to netif struct + + 2006-07-06 Christiaan Simons + * snmp/asn1_{enc,dec}.c added + * snmp/mib2.c added + * snmp/msg_{in,out}.c added + * include/lwip/snmp_asn1.h added + * include/lwip/snmp_msg.h added + * doc/snmp_agent.txt added + + 2006-03-29 Christiaan Simons + * inet.c, inet.h: Added platform byteswap support. + Added LWIP_PLATFORM_BYTESWAP define (defaults to 0) and + optional LWIP_PLATFORM_HTONS(), LWIP_PLATFORM_HTONL() macros. + + ++ Bug fixes: + + 2006-11-30 Christiaan Simons + * dhcp.c: Fixed false triggers of request_timeout. + + 2006-11-28 Christiaan Simons + * netif.c: In netif_add() fixed missing clear of ip_addr, netmask, gw and flags. + + 2006-10-11 Christiaan Simons + * api_lib.c etharp.c, ip.c, memp.c, stats.c, sys.{c,h} tcp.h: + Partially accepted patch #5449 for ANSI C compatibility / build fixes. + * ipv4/lwip/ip.h ipv6/lwip/ip.h: Corrected UDP-Lite protocol + identifier from 170 to 136 (bug #17574). + + 2006-10-10 Christiaan Simons + * api_msg.c: Fixed Nagle algorithm as reported by Bob Grice. + + 2006-08-17 Christiaan Simons + * udp.c: Fixed bug #17200, added check for broadcast + destinations for PCBs bound to a unicast address. + + 2006-08-07 Christiaan Simons + * api_msg.c: Flushing TCP output in do_close() (bug #15926). + + 2006-06-27 Christiaan Simons + * api_msg.c: Applied patch for cold case (bug #11135). + In accept_function() ensure newconn->callback is always initialized. + + 2006-06-15 Christiaan Simons + * mem.h: added MEM_SIZE_F alias to fix an ancient cold case (bug #1748), + facilitate printing of mem_size_t and u16_t statistics. + + 2006-06-14 Christiaan Simons + * api_msg.c: Applied patch #5146 to handle allocation failures + in accept() by Kevin Lawson. + + 2006-05-26 Christiaan Simons + * api_lib.c: Removed conn->sem creation and destruction + from netconn_write() and added sys_sem_new to netconn_new_*. + +(STABLE-1_1_1) + + 2006-03-03 Christiaan Simons + * ipv4/ip_frag.c: Added bound-checking assertions on ip_reassbitmap + access and added pbuf_alloc() return value checks. + + 2006-01-01 Leon Woestenberg + * tcp_{in,out}.c, tcp_out.c: Removed 'even sndbuf' fix in TCP, which is + now handled by the checksum routine properly. + + 2006-02-27 Leon Woestenberg + * pbuf.c: Fix alignment; pbuf_init() would not work unless + pbuf_pool_memory[] was properly aligned. (Patch by Curt McDowell.) + + 2005-12-20 Leon Woestenberg + * tcp.c: Remove PCBs which stay in LAST_ACK state too long. Patch + submitted by Mitrani Hiroshi. + + 2005-12-15 Christiaan Simons + * inet.c: Disabled the added summing routine to preserve code space. + + 2005-12-14 Leon Woestenberg + * tcp_in.c: Duplicate FIN ACK race condition fix by Kelvin Lawson. + Added Curt McDowell's optimized checksumming routine for future + inclusion. Need to create test case for unaliged, aligned, odd, + even length combination of cases on various endianess machines. + + 2005-12-09 Christiaan Simons + * inet.c: Rewrote standard checksum routine in proper portable C. + + 2005-11-25 Christiaan Simons + * udp.c tcp.c: Removed SO_REUSE hack. Should reside in socket code only. + * *.c: introduced cc.h LWIP_DEBUG formatters matching the u16_t, s16_t, + u32_t, s32_t typedefs. This solves most debug word-length assumes. + + 2005-07-17 Leon Woestenberg + * inet.c: Fixed unaligned 16-bit access in the standard checksum + routine by Peter Jolasson. + * slipif.c: Fixed implementation assumption of single-pbuf datagrams. + + 2005-02-04 Leon Woestenberg + * tcp_out.c: Fixed uninitialized 'queue' referenced in memerr branch. + * tcp_{out|in}.c: Applied patch fixing unaligned access. + + 2005-01-04 Leon Woestenberg + * pbuf.c: Fixed missing semicolon after LWIP_DEBUG statement. + + 2005-01-03 Leon Woestenberg + * udp.c: UDP pcb->recv() was called even when it was NULL. + +(STABLE-1_1_0) + + 2004-12-28 Leon Woestenberg + * etharp.*: Disabled multiple packets on the ARP queue. + This clashes with TCP queueing. + + 2004-11-28 Leon Woestenberg + * etharp.*: Fixed race condition from ARP request to ARP timeout. + Halved the ARP period, doubled the period counts. + ETHARP_MAX_PENDING now should be at least 2. This prevents + the counter from reaching 0 right away (which would allow + too little time for ARP responses to be received). + + 2004-11-25 Leon Woestenberg + * dhcp.c: Decline messages were not multicast but unicast. + * etharp.c: ETHARP_CREATE is renamed to ETHARP_TRY_HARD. + Do not try hard to insert arbitrary packet's source address, + etharp_ip_input() now calls etharp_update() without ETHARP_TRY_HARD. + etharp_query() now always DOES call ETHARP_TRY_HARD so that users + querying an address will see it appear in the cache (DHCP could + suffer from this when a server invalidly gave an in-use address.) + * ipv4/ip_addr.h: Renamed ip_addr_maskcmp() to _netcmp() as we are + comparing network addresses (identifiers), not the network masks + themselves. + * ipv4/ip_addr.c: ip_addr_isbroadcast() now checks that the given + IP address actually belongs to the network of the given interface. + + 2004-11-24 Kieran Mansley + * tcp.c: Increment pcb->snd_buf when ACK is received in SYN_SENT state. + +(STABLE-1_1_0-RC1) + + 2004-10-16 Kieran Mansley + * tcp.c: Add code to tcp_recved() to send an ACK (window update) immediately, + even if one is already pending, if the rcv_wnd is above a threshold + (currently TCP_WND/2). This avoids waiting for a timer to expire to send a + delayed ACK in order to open the window if the stack is only receiving data. + + 2004-09-12 Kieran Mansley + * tcp*.*: Retransmit time-out handling improvement by Sam Jansen. + + 2004-08-20 Tony Mountifield + * etharp.c: Make sure the first pbuf queued on an ARP entry + is properly ref counted. + + 2004-07-27 Tony Mountifield + * debug.h: Added (int) cast in LWIP_DEBUGF() to avoid compiler + warnings about comparison. + * pbuf.c: Stopped compiler complaining of empty if statement + when LWIP_DEBUGF() empty. Closed an unclosed comment. + * tcp.c: Stopped compiler complaining of empty if statement + when LWIP_DEBUGF() empty. + * ip.h Corrected IPH_TOS() macro: returns a byte, so doesn't need htons(). + * inet.c: Added a couple of casts to quiet the compiler. + No need to test isascii(c) before isdigit(c) or isxdigit(c). + + 2004-07-22 Tony Mountifield + * inet.c: Made data types consistent in inet_ntoa(). + Added casts for return values of checksum routines, to pacify compiler. + * ip_frag.c, tcp_out.c, sockets.c, pbuf.c + Small corrections to some debugging statements, to pacify compiler. + + 2004-07-21 Tony Mountifield + * etharp.c: Removed spurious semicolon and added missing end-of-comment. + * ethernetif.c Updated low_level_output() to match prototype for + netif->linkoutput and changed low_level_input() similarly for consistency. + * api_msg.c: Changed recv_raw() from int to u8_t, to match prototype + of raw_recv() in raw.h and so avoid compiler error. + * sockets.c: Added trivial (int) cast to keep compiler happier. + * ip.c, netif.c Changed debug statements to use the tidier ip4_addrN() macros. + +(STABLE-1_0_0) + + ++ Changes: + + 2004-07-05 Leon Woestenberg + * sockets.*: Restructured LWIP_PRIVATE_TIMEVAL. Make sure + your cc.h file defines this either 1 or 0. If non-defined, + defaults to 1. + * .c: Added and includes where used. + * etharp.c: Made some array indices unsigned. + + 2004-06-27 Leon Woestenberg + * netif.*: Added netif_set_up()/down(). + * dhcp.c: Changes to restart program flow. + + 2004-05-07 Leon Woestenberg + * etharp.c: In find_entry(), instead of a list traversal per candidate, do a + single-pass lookup for different candidates. Should exploit locality. + + 2004-04-29 Leon Woestenberg + * tcp*.c: Cleaned up source comment documentation for Doxygen processing. + * opt.h: ETHARP_ALWAYS_INSERT option removed to comply with ARP RFC. + * etharp.c: update_arp_entry() only adds new ARP entries when adviced to by + the caller. This deprecates the ETHARP_ALWAYS_INSERT overrule option. + + ++ Bug fixes: + + 2004-04-27 Leon Woestenberg + * etharp.c: Applied patch of bug #8708 by Toni Mountifield with a solution + suggested by Timmy Brolin. Fix for 32-bit processors that cannot access + non-aligned 32-bit words, such as soms 32-bit TCP/IP header fields. Fix + is to prefix the 14-bit Ethernet headers with two padding bytes. + + 2004-04-23 Leon Woestenberg + * ip_addr.c: Fix in the ip_addr_isbroadcast() check. + * etharp.c: Fixed the case where the packet that initiates the ARP request + is not queued, and gets lost. Fixed the case where the packets destination + address is already known; we now always queue the packet and perform an ARP + request. + +(STABLE-0_7_0) + + ++ Bug fixes: + + * Fixed TCP bug for SYN_SENT to ESTABLISHED state transition. + * Fixed TCP bug in dequeueing of FIN from out of order segment queue. + * Fixed two possible NULL references in rare cases. + +(STABLE-0_6_6) + + ++ Bug fixes: + + * Fixed DHCP which did not include the IP address in DECLINE messages. + + ++ Changes: + + * etharp.c has been hauled over a bit. + +(STABLE-0_6_5) + + ++ Bug fixes: + + * Fixed TCP bug induced by bad window resizing with unidirectional TCP traffic. + * Packets sent from ARP queue had invalid source hardware address. + + ++ Changes: + + * Pass-by ARP requests do now update the cache. + + ++ New features: + + * No longer dependent on ctype.h. + * New socket options. + * Raw IP pcb support. + +(STABLE-0_6_4) + + ++ Bug fixes: + + * Some debug formatters and casts fixed. + * Numereous fixes in PPP. + + ++ Changes: + + * DEBUGF now is LWIP_DEBUGF + * pbuf_dechain() has been re-enabled. + * Mentioned the changed use of CVS branches in README. + +(STABLE-0_6_3) + + ++ Bug fixes: + + * Fixed pool pbuf memory leak in pbuf_alloc(). + Occured if not enough PBUF_POOL pbufs for a packet pbuf chain. + Reported by Savin Zlobec. + + * PBUF_POOL chains had their tot_len field not set for non-first + pbufs. Fixed in pbuf_alloc(). + + ++ New features: + + * Added PPP stack contributed by Marc Boucher + + ++ Changes: + + * Now drops short packets for ICMP/UDP/TCP protocols. More robust. + + * ARP queueuing now queues the latest packet instead of the first. + This is the RFC recommended behaviour, but can be overridden in + lwipopts.h. + +(0.6.2) + + ++ Bugfixes: + + * TCP has been fixed to deal with the new use of the pbuf->ref + counter. + + * DHCP dhcp_inform() crash bug fixed. + + ++ Changes: + + * Removed pbuf_pool_free_cache and pbuf_pool_alloc_cache. Also removed + pbuf_refresh(). This has sped up pbuf pool operations considerably. + Implemented by David Haas. + +(0.6.1) + + ++ New features: + + * The packet buffer implementation has been enhanced to support + zero-copy and copy-on-demand for packet buffers which have their + payloads in application-managed memory. + Implemented by David Haas. + + Use PBUF_REF to make a pbuf refer to RAM. lwIP will use zero-copy + if an outgoing packet can be directly sent on the link, or perform + a copy-on-demand when necessary. + + The application can safely assume the packet is sent, and the RAM + is available to the application directly after calling udp_send() + or similar function. + + ++ Bugfixes: + + * ARP_QUEUEING should now correctly work for all cases, including + PBUF_REF. + Implemented by Leon Woestenberg. + + ++ Changes: + + * IP_ADDR_ANY is no longer a NULL pointer. Instead, it is a pointer + to a '0.0.0.0' IP address. + + * The packet buffer implementation is changed. The pbuf->ref counter + meaning has changed, and several pbuf functions have been + adapted accordingly. + + * netif drivers have to be changed to set the hardware address length field + that must be initialized correctly by the driver (hint: 6 for Ethernet MAC). + See the contrib/ports/c16x cs8900 driver as a driver example. + + * netif's have a dhcp field that must be initialized to NULL by the driver. + See the contrib/ports/c16x cs8900 driver as a driver example. + +(0.5.x) This file has been unmaintained up to 0.6.1. All changes are + logged in CVS but have not been explained here. + +(0.5.3) Changes since version 0.5.2 + + ++ Bugfixes: + + * memp_malloc(MEMP_API_MSG) could fail with multiple application + threads because it wasn't protected by semaphores. + + ++ Other changes: + + * struct ip_addr now packed. + + * The name of the time variable in arp.c has been changed to ctime + to avoid conflicts with the time() function. + +(0.5.2) Changes since version 0.5.1 + + ++ New features: + + * A new TCP function, tcp_tmr(), now handles both TCP timers. + + ++ Bugfixes: + + * A bug in tcp_parseopt() could cause the stack to hang because of a + malformed TCP option. + + * The address of new connections in the accept() function in the BSD + socket library was not handled correctly. + + * pbuf_dechain() did not update the ->tot_len field of the tail. + + * Aborted TCP connections were not handled correctly in all + situations. + + ++ Other changes: + + * All protocol header structs are now packed. + + * The ->len field in the tcp_seg structure now counts the actual + amount of data, and does not add one for SYN and FIN segments. + +(0.5.1) Changes since version 0.5.0 + + ++ New features: + + * Possible to run as a user process under Linux. + + * Preliminary support for cross platform packed structs. + + * ARP timer now implemented. + + ++ Bugfixes: + + * TCP output queue length was badly initialized when opening + connections. + + * TCP delayed ACKs were not sent correctly. + + * Explicit initialization of BSS segment variables. + + * read() in BSD socket library could drop data. + + * Problems with memory alignment. + + * Situations when all TCP buffers were used could lead to + starvation. + + * TCP MSS option wasn't parsed correctly. + + * Problems with UDP checksum calculation. + + * IP multicast address tests had endianess problems. + + * ARP requests had wrong destination hardware address. + + ++ Other changes: + + * struct eth_addr changed from u16_t[3] array to u8_t[6]. + + * A ->linkoutput() member was added to struct netif. + + * TCP and UDP ->dest_* struct members where changed to ->remote_*. + + * ntoh* macros are now null definitions for big endian CPUs. + +(0.5.0) Changes since version 0.4.2 + + ++ New features: + + * Redesigned operating system emulation layer to make porting easier. + + * Better control over TCP output buffers. + + * Documenation added. + + ++ Bugfixes: + + * Locking issues in buffer management. + + * Bugfixes in the sequential API. + + * IP forwarding could cause memory leakage. This has been fixed. + + ++ Other changes: + + * Directory structure somewhat changed; the core/ tree has been + collapsed. + +(0.4.2) Changes since version 0.4.1 + + ++ New features: + + * Experimental ARP implementation added. + + * Skeleton Ethernet driver added. + + * Experimental BSD socket API library added. + + ++ Bugfixes: + + * In very intense situations, memory leakage could occur. This has + been fixed. + + ++ Other changes: + + * Variables named "data" and "code" have been renamed in order to + avoid name conflicts in certain compilers. + + * Variable++ have in appliciable cases been translated to ++variable + since some compilers generate better code in the latter case. + +(0.4.1) Changes since version 0.4 + + ++ New features: + + * TCP: Connection attempts time out earlier than data + transmissions. Nagle algorithm implemented. Push flag set on the + last segment in a burst. + + * UDP: experimental support for UDP-Lite extensions. + + ++ Bugfixes: + + * TCP: out of order segments were in some cases handled incorrectly, + and this has now been fixed. Delayed acknowledgements was broken + in 0.4, has now been fixed. Binding to an address that is in use + now results in an error. Reset connections sometimes hung an + application; this has been fixed. + + * Checksum calculation sometimes failed for chained pbufs with odd + lengths. This has been fixed. + + * API: a lot of bug fixes in the API. The UDP API has been improved + and tested. Error reporting and handling has been + improved. Logical flaws and race conditions for incoming TCP + connections has been found and removed. + + * Memory manager: alignment issues. Reallocating memory sometimes + failed, this has been fixed. + + * Generic library: bcopy was flawed and has been fixed. + + ++ Other changes: + + * API: all datatypes has been changed from generic ones such as + ints, to specified ones such as u16_t. Functions that return + errors now have the correct type (err_t). + + * General: A lot of code cleaned up and debugging code removed. Many + portability issues have been fixed. + + * The license was changed; the advertising clause was removed. + + * C64 port added. + + * Thanks: Huge thanks go to Dagan Galarneau, Horst Garnetzke, Petri + Kosunen, Mikael Caleres, and Frits Wilmink for reporting and + fixing bugs! + +(0.4) Changes since version 0.3.1 + + * Memory management has been radically changed; instead of + allocating memory from a shared heap, memory for objects that are + rapidly allocated and deallocated is now kept in pools. Allocation + and deallocation from those memory pools is very fast. The shared + heap is still present but is used less frequently. + + * The memory, memory pool, and packet buffer subsystems now support + 4-, 2-, or 1-byte alignment. + + * "Out of memory" situations are handled in a more robust way. + + * Stack usage has been reduced. + + * Easier configuration of lwIP parameters such as memory usage, + TTLs, statistics gathering, etc. All configuration parameters are + now kept in a single header file "lwipopts.h". + + * The directory structure has been changed slightly so that all + architecture specific files are kept under the src/arch + hierarchy. + + * Error propagation has been improved, both in the protocol modules + and in the API. + + * The code for the RTXC architecture has been implemented, tested + and put to use. + + * Bugs have been found and corrected in the TCP, UDP, IP, API, and + the Internet checksum modules. + + * Bugs related to porting between a 32-bit and a 16-bit architecture + have been found and corrected. + + * The license has been changed slightly to conform more with the + original BSD license, including the advertisement clause. + +(0.3.1) Changes since version 0.3 + + * Fix of a fatal bug in the buffer management. Pbufs with allocated + RAM never returned the RAM when the pbuf was deallocated. + + * TCP congestion control, window updates and retransmissions did not + work correctly. This has now been fixed. + + * Bugfixes in the API. + +(0.3) Changes since version 0.2 + + * New and improved directory structure. All include files are now + kept in a dedicated include/ directory. + + * The API now has proper error handling. A new function, + netconn_err(), now returns an error code for the connection in + case of errors. + + * Improvements in the memory management subsystem. The system now + keeps a pointer to the lowest free memory block. A new function, + mem_malloc2() tries to allocate memory once, and if it fails tries + to free some memory and retry the allocation. + + * Much testing has been done with limited memory + configurations. lwIP now does a better job when overloaded. + + * Some bugfixes and improvements to the buffer (pbuf) subsystem. + + * Many bugfixes in the TCP code: + + - Fixed a bug in tcp_close(). + + - The TCP receive window was incorrectly closed when out of + sequence segments was received. This has been fixed. + + - Connections are now timed-out of the FIN-WAIT-2 state. + + - The initial congestion window could in some cases be too + large. This has been fixed. + + - The retransmission queue could in some cases be screwed up. This + has been fixed. + + - TCP RST flag now handled correctly. + + - Out of sequence data was in some cases never delivered to the + application. This has been fixed. + + - Retransmitted segments now contain the correct acknowledgment + number and advertised window. + + - TCP retransmission timeout backoffs are not correctly computed + (ala BSD). After a number of retransmissions, TCP now gives up + the connection. + + * TCP connections now are kept on three lists, one for active + connections, one for listening connections, and one for + connections that are in TIME-WAIT. This greatly speeds up the fast + timeout processing for sending delayed ACKs. + + * TCP now provides proper feedback to the application when a + connection has been successfully set up. + + * More comments have been added to the code. The code has also been + somewhat cleaned up. + +(0.2) Initial public release. diff --git a/features/net/FEATURE_IPV4/lwip-interface/lwip/COPYING b/features/net/FEATURE_IPV4/lwip-interface/lwip/COPYING new file mode 100644 index 0000000000..e23898b5e8 --- /dev/null +++ b/features/net/FEATURE_IPV4/lwip-interface/lwip/COPYING @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2001, 2002 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 + * + */ + + diff --git a/features/net/FEATURE_IPV4/lwip-interface/lwip/FILES b/features/net/FEATURE_IPV4/lwip-interface/lwip/FILES new file mode 100644 index 0000000000..66253196f9 --- /dev/null +++ b/features/net/FEATURE_IPV4/lwip-interface/lwip/FILES @@ -0,0 +1,4 @@ +src/ - The source code for the lwIP TCP/IP stack. +doc/ - The documentation for lwIP. + +See also the FILES file in each subdirectory. diff --git a/features/net/FEATURE_IPV4/lwip-interface/lwip/README b/features/net/FEATURE_IPV4/lwip-interface/lwip/README new file mode 100644 index 0000000000..fb881317d7 --- /dev/null +++ b/features/net/FEATURE_IPV4/lwip-interface/lwip/README @@ -0,0 +1,97 @@ +INTRODUCTION + +lwIP is a small independent implementation of the TCP/IP protocol +suite that has been developed by Adam Dunkels at the Computer and +Networks Architectures (CNA) lab at the Swedish Institute of Computer +Science (SICS). + +The focus of the lwIP TCP/IP implementation is to reduce the RAM usage +while still having a full scale TCP. This making lwIP suitable for use +in embedded systems with tens of kilobytes of free RAM and room for +around 40 kilobytes of code ROM. + + +FEATURES + + * IP (Internet Protocol, IPv4 and IPv6) including packet forwarding over + multiple network interfaces + * ICMP (Internet Control Message Protocol) for network maintenance and debugging + * IGMP (Internet Group Management Protocol) for multicast traffic management + * MLD (Multicast listener discovery for IPv6). Aims to be compliant with + RFC 2710. No support for MLDv2 + * ND (Neighbor discovery and stateless address autoconfiguration for IPv6). + Aims to be compliant with RFC 4861 (Neighbor discovery) and RFC 4862 + (Address autoconfiguration) + * UDP (User Datagram Protocol) including experimental UDP-lite extensions + * TCP (Transmission Control Protocol) with congestion control, RTT estimation + and fast recovery/fast retransmit + * raw/native API for enhanced performance + * Optional Berkeley-like socket API + * DNS (Domain names resolver) + + +APPLICATIONS + + * HTTP server with SSI and CGI + * SNMPv2c agent with MIB compiler (Simple Network Management Protocol) + * SNTP (Simple network time protocol) + + +LICENSE + +lwIP is freely available under a BSD license. + + +DEVELOPMENT + +lwIP has grown into an excellent TCP/IP stack for embedded devices, +and developers using the stack often submit bug fixes, improvements, +and additions to the stack to further increase its usefulness. + +Development of lwIP is hosted on Savannah, a central point for +software development, maintenance and distribution. Everyone can +help improve lwIP by use of Savannah's interface, Git and the +mailing list. A core team of developers will commit changes to the +Git source tree. + +The lwIP TCP/IP stack is maintained in the 'lwip' Git module and +contributions (such as platform ports) are in the 'contrib' Git module. + +See doc/savannah.txt for details on Git server access for users and +developers. + +The current Git trees are web-browsable: + http://git.savannah.gnu.org/cgit/lwip.git + http://git.savannah.gnu.org/cgit/lwip/lwip-contrib.git + +Submit patches and bugs via the lwIP project page: + http://savannah.nongnu.org/projects/lwip/ + +Continuous integration builds (GCC, clang): + https://travis-ci.org/yarrick/lwip-merged + + +DOCUMENTATION + +Self documentation of the source code is regularly extracted from the current +Git sources and is available from this web page: + http://www.nongnu.org/lwip/ + +There is now a constantly growin wiki about lwIP at + http://lwip.wikia.com/wiki/LwIP_Wiki + +Also, there are mailing lists you can subscribe at + http://savannah.nongnu.org/mail/?group=lwip +plus searchable archives: + http://lists.nongnu.org/archive/html/lwip-users/ + http://lists.nongnu.org/archive/html/lwip-devel/ + +lwIP was originally written by Adam Dunkels: + http://dunkels.com/adam/ + +Reading Adam's papers, the files in docs/, browsing the source code +documentation and browsing the mailing list archives is a good way to +become familiar with the design of lwIP. + +Adam Dunkels +Leon Woestenberg diff --git a/features/net/FEATURE_IPV4/lwip-interface/lwip/UPGRADING b/features/net/FEATURE_IPV4/lwip-interface/lwip/UPGRADING new file mode 100644 index 0000000000..f44fb48795 --- /dev/null +++ b/features/net/FEATURE_IPV4/lwip-interface/lwip/UPGRADING @@ -0,0 +1,217 @@ +This file lists major changes between release versions that require +ports or applications to be changed. Use it to update a port or an +application written for an older version of lwIP to correctly work +with newer versions. + + +(git master) + + * [Enter new changes just after this line - do not remove this line] + + * TODO + +(2.0.0) + + ++ Application changes: + + * Changed netif "up" flag handling to be an administrative flag (as opposed to the previous meaning of + "ip4-address-valid", a netif will now not be used for transmission if not up) -> even a DHCP netif + has to be set "up" before starting the DHCP client + * Added IPv6 support (dual-stack or IPv4/IPv6 only) + * Changed ip_addr_t to be a union in dual-stack mode (use ip4_addr_t where referring to IPv4 only). + * Major rewrite of SNMP (added MIB parser that creates code stubs for custom MIBs); + supports SNMP2vc (experimental v3 support) + * Moved some core applications from contrib repository to src/apps (and include/lwip/apps) + + +++ Raw API: + * Changed TCP listen backlog: removed tcp_accepted(), added the function pair tcp_backlog_delayed()/ + tcp_backlog_accepted() to explicitly delay backlog handling on a connection pcb + + +++ Socket API: + * Added an implementation for posix sendmsg() + * Added LWIP_FIONREAD_LINUXMODE that makes ioctl/FIONREAD return the size of the next pending datagram + + ++ Port changes + + +++ new files: + * MANY new and moved files! + * Continued moving stack-internal parts from abc.h to abc_priv.h in sub-folder "priv" + to let abc.h only contain the actual application programmer's API + + +++ sys layer: + * Made LWIP_TCPIP_CORE_LOCKING==1 the default as it usually performs better than + the traditional message passing (although with LWIP_COMPAT_MUTEX you are still + open to priority inversion, so this is not recommended any more) + * Added LWIP_NETCONN_SEM_PER_THREAD to use one "op_completed" semaphore per thread + instead of using one per netconn (these semaphores are used even with core locking + enabled as some longer lasting functions like big writes still need to delay) + + +++ new options: + * TODO + + +++ new pools: + * Added LWIP_MEMPOOL_* (declare/init/alloc/free) to declare private memp pools + that share memp.c code but do not have to be made global via lwippools.h + * Added pools for IPv6, MPU_COMPATIBLE, dns-api, netif-api, etc. + * added hook LWIP_HOOK_MEMP_AVAILABLE() to get informed when a memp pool was empty and an item + is now available + + * LWIP_DECLARE_MEMORY_ALIGNED() may be used to declare aligned memory buffers (mem/memp) + or to move buffers to dedicated memory using compiler attributes + + * Standard C headers are used to define sized types and printf formatters + (disable by setting LWIP_NO_STDINT_H=1 or LWIP_NO_INTTYPES_H=1 if your compiler + does not support these) + + + ++ Major bugfixes/improvements + + * Added IPv6 support (dual-stack or IPv4/IPv6 only) + * Major rewrite of PPP (incl. keep-up with apache pppd) + * Major rewrite of SNMP (incl. MIB parser) + * Fixed timing issues that might have lead to losing a DHCP lease + * Made rx processing path more robust against crafted errors + * TCP window scaling support + * modification of api modules to support FreeRTOS-MPU (don't pass stack-pointers to other threads) + * made DNS client more robust + * support PBUF_REF for RX packets + * LWIP_NETCONN_FULLDUPLEX allows netconn/sockets to be used for reading/writing from separate + threads each (needs LWIP_NETCONN_SEM_PER_THREAD) + * Moved and reorderd stats (mainly memp/mib2) + +(1.4.0) + + ++ Application changes: + + * Replaced struct ip_addr by typedef ip_addr_t (struct ip_addr is kept for + compatibility to old applications, but will be removed in the future). + + * Renamed mem_realloc() to mem_trim() to prevent confusion with realloc() + + +++ Raw API: + * Changed the semantics of tcp_close() (since it was rather a + shutdown before): Now the application does *NOT* get any calls to the recv + callback (aside from NULL/closed) after calling tcp_close() + + * When calling tcp_abort() from a raw API TCP callback function, + make sure you return ERR_ABRT to prevent accessing unallocated memory. + (ERR_ABRT now means the applicaiton has called tcp_abort!) + + +++ Netconn API: + * Changed netconn_receive() and netconn_accept() to return + err_t, not a pointer to new data/netconn. + + +++ Socket API: + * LWIP_SO_RCVTIMEO: when accept() or recv() time out, they + now set errno to EWOULDBLOCK/EAGAIN, not ETIMEDOUT. + + * Added a minimal version of posix fctl() to have a + standardised way to set O_NONBLOCK for nonblocking sockets. + + +++ all APIs: + * correctly implemented SO(F)_REUSEADDR + + ++ Port changes + + +++ new files: + + * Added 4 new files: def.c, timers.c, timers.h, tcp_impl.h: + + * Moved stack-internal parts of tcp.h to tcp_impl.h, tcp.h now only contains + the actual application programmer's API + + * Separated timer implementation from sys.h/.c, moved to timers.h/.c; + Added timer implementation for NO_SYS==1, set NO_SYS_NO_TIMERS==1 if you + still want to use your own timer implementation for NO_SYS==0 (as before). + + +++ sys layer: + + * Converted mbox- and semaphore-functions to take pointers to sys_mbox_t/ + sys_sem_t; + + * Converted sys_mbox_new/sys_sem_new to take pointers and return err_t; + + * Added Mutex concept in sys_arch (define LWIP_COMPAT_MUTEX to let sys.h use + binary semaphores instead of mutexes - as before) + + +++ new options: + + * Don't waste memory when chaining segments, added option TCP_OVERSIZE to + prevent creating many small pbufs when calling tcp_write with many small + blocks of data. Instead, pbufs are allocated larger than needed and the + space is used for later calls to tcp_write. + + * Added LWIP_NETIF_TX_SINGLE_PBUF to always copy to try to create single pbufs + in tcp_write/udp_send. + + * Added an additional option LWIP_ETHERNET to support ethernet without ARP + (necessary for pure PPPoE) + + * Add MEMP_SEPARATE_POOLS to place memory pools in separate arrays. This may + be used to place these pools into user-defined memory by using external + declaration. + + * Added TCP_SNDQUEUELOWAT corresponding to TCP_SNDLOWAT + + +++ new pools: + + * Netdb uses a memp pool for allocating memory when getaddrinfo() is called, + so MEMP_NUM_NETDB has to be set accordingly. + + * DNS_LOCAL_HOSTLIST_IS_DYNAMIC uses a memp pool instead of the heap, so + MEMP_NUM_LOCALHOSTLIST has to be set accordingly. + + * Snmp-agent uses a memp pools instead of the heap, so MEMP_NUM_SNMP_* have + to be set accordingly. + + * PPPoE uses a MEMP pool instead of the heap, so MEMP_NUM_PPPOE_INTERFACES + has to be set accordingly + + * Integrated loopif into netif.c - loopif does not have to be created by the + port any more, just define LWIP_HAVE_LOOPIF to 1. + + * Added define LWIP_RAND() for lwip-wide randomization (needs to be defined + in cc.h, e.g. used by igmp) + + * Added printf-formatter X8_F to printf u8_t as hex + + * The heap now may be moved to user-defined memory by defining + LWIP_RAM_HEAP_POINTER as a void pointer to that memory's address + + * added autoip_set_struct() and dhcp_set_struct() to let autoip and dhcp work + with user-allocated structs instead of calling mem_malloc + + * Added const char* name to mem- and memp-stats for easier debugging. + + * Calculate the TCP/UDP checksum while copying to only fetch data once: + Define LWIP_CHKSUM_COPY to a memcpy-like function that returns the checksum + + * Added SO_REUSE_RXTOALL to pass received UDP broadcast/multicast packets to + more than one pcb. + + * Changed the semantics of ARP_QUEUEING==0: ARP_QUEUEING now cannot be turned + off any more, if this is set to 0, only one packet (the most recent one) is + queued (like demanded by RFC 1122). + + + ++ Major bugfixes/improvements + + * Implemented tcp_shutdown() to only shut down one end of a connection + * Implemented shutdown() at socket- and netconn-level + * Added errorset support to select() + improved select speed overhead + * Merged pppd to v2.3.11 (including some backported bugfixes from 2.4.x) + * Added timer implementation for NO_SYS==1 (may be disabled with NO_SYS_NO_TIMERS==1 + * Use macros defined in ip_addr.h to work with IP addresses + * Implemented many nonblocking socket/netconn functions + * Fixed ARP input processing: only add a new entry if a request was directed as us + * mem_realloc() to mem_trim() to prevent confusion with realloc() + * Some improvements for AutoIP (don't route/forward link-local addresses, don't break + existing connections when assigning a routable address) + * Correctly handle remote side overrunning our rcv_wnd in ooseq case + * Removed packing from ip_addr_t, the packed version is now only used in protocol headers + * Corrected PBUF_POOL_BUFSIZE for ports where ETH_PAD_SIZE > 0 + * Added support for static ARP table entries + +(STABLE-1.3.2) + + * initial version of this file diff --git a/features/net/FEATURE_IPV4/lwip-interface/lwip/api/lwip_netifapi.c b/features/net/FEATURE_IPV4/lwip-interface/lwip/api/lwip_netifapi.c deleted file mode 100644 index 43e47203a9..0000000000 --- a/features/net/FEATURE_IPV4/lwip-interface/lwip/api/lwip_netifapi.c +++ /dev/null @@ -1,160 +0,0 @@ -/** - * @file - * Network Interface Sequential API module - * - */ - -/* - * 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/opt.h" - -#if LWIP_NETIF_API /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/netifapi.h" -#include "lwip/tcpip.h" - -/** - * Call netif_add() inside the tcpip_thread context. - */ -void -do_netifapi_netif_add(struct netifapi_msg_msg *msg) -{ - if (!netif_add( msg->netif, - msg->msg.add.ipaddr, - msg->msg.add.netmask, - msg->msg.add.gw, - msg->msg.add.state, - msg->msg.add.init, - msg->msg.add.input)) { - msg->err = ERR_IF; - } else { - msg->err = ERR_OK; - } - TCPIP_NETIFAPI_ACK(msg); -} - -/** - * Call netif_set_addr() inside the tcpip_thread context. - */ -void -do_netifapi_netif_set_addr(struct netifapi_msg_msg *msg) -{ - netif_set_addr( msg->netif, - msg->msg.add.ipaddr, - msg->msg.add.netmask, - msg->msg.add.gw); - msg->err = ERR_OK; - TCPIP_NETIFAPI_ACK(msg); -} - -/** - * Call the "errtfunc" (or the "voidfunc" if "errtfunc" is NULL) inside the - * tcpip_thread context. - */ -void -do_netifapi_netif_common(struct netifapi_msg_msg *msg) -{ - if (msg->msg.common.errtfunc != NULL) { - msg->err = msg->msg.common.errtfunc(msg->netif); - } else { - msg->err = ERR_OK; - msg->msg.common.voidfunc(msg->netif); - } - TCPIP_NETIFAPI_ACK(msg); -} - -/** - * Call netif_add() in a thread-safe way by running that function inside the - * tcpip_thread context. - * - * @note for params @see netif_add() - */ -err_t -netifapi_netif_add(struct netif *netif, - ip_addr_t *ipaddr, - ip_addr_t *netmask, - ip_addr_t *gw, - void *state, - netif_init_fn init, - netif_input_fn input) -{ - struct netifapi_msg msg; - msg.function = do_netifapi_netif_add; - msg.msg.netif = netif; - msg.msg.msg.add.ipaddr = ipaddr; - msg.msg.msg.add.netmask = netmask; - msg.msg.msg.add.gw = gw; - msg.msg.msg.add.state = state; - msg.msg.msg.add.init = init; - msg.msg.msg.add.input = input; - TCPIP_NETIFAPI(&msg); - return msg.msg.err; -} - -/** - * Call netif_set_addr() in a thread-safe way by running that function inside the - * tcpip_thread context. - * - * @note for params @see netif_set_addr() - */ -err_t -netifapi_netif_set_addr(struct netif *netif, - ip_addr_t *ipaddr, - ip_addr_t *netmask, - ip_addr_t *gw) -{ - struct netifapi_msg msg; - msg.function = do_netifapi_netif_set_addr; - msg.msg.netif = netif; - msg.msg.msg.add.ipaddr = ipaddr; - msg.msg.msg.add.netmask = netmask; - msg.msg.msg.add.gw = gw; - TCPIP_NETIFAPI(&msg); - return msg.msg.err; -} - -/** - * call the "errtfunc" (or the "voidfunc" if "errtfunc" is NULL) in a thread-safe - * way by running that function inside the tcpip_thread context. - * - * @note use only for functions where there is only "netif" parameter. - */ -err_t -netifapi_netif_common(struct netif *netif, netifapi_void_fn voidfunc, - netifapi_errt_fn errtfunc) -{ - struct netifapi_msg msg; - msg.function = do_netifapi_netif_common; - msg.msg.netif = netif; - msg.msg.msg.common.voidfunc = voidfunc; - msg.msg.msg.common.errtfunc = errtfunc; - TCPIP_NETIFAPI(&msg); - return msg.msg.err; -} - -#endif /* LWIP_NETIF_API */ diff --git a/features/net/FEATURE_IPV4/lwip-interface/lwip/api/lwip_sockets.c b/features/net/FEATURE_IPV4/lwip-interface/lwip/api/lwip_sockets.c deleted file mode 100644 index e36012ce43..0000000000 --- a/features/net/FEATURE_IPV4/lwip-interface/lwip/api/lwip_sockets.c +++ /dev/null @@ -1,2347 +0,0 @@ -/** - * @file - * Sockets BSD-Like API module - * - */ - -/* - * 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 - * - * Improved by Marc Boucher and David Haas - * - */ - -#include "lwip/opt.h" - -#if LWIP_SOCKET /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/sockets.h" -#include "lwip/api.h" -#include "lwip/sys.h" -#include "lwip/igmp.h" -#include "lwip/inet.h" -#include "lwip/tcp.h" -#include "lwip/raw.h" -#include "lwip/udp.h" -#include "lwip/tcpip.h" -#include "lwip/pbuf.h" -#if LWIP_CHECKSUM_ON_COPY -#include "lwip/inet_chksum.h" -#endif - -#include - -#define NUM_SOCKETS MEMP_NUM_NETCONN - -/** Contains all internal pointers and states used for a socket */ -struct lwip_sock { - /** sockets currently are built on netconns, each socket has one netconn */ - struct netconn *conn; - /** data that was left from the previous read */ - void *lastdata; - /** offset in the data that was left from the previous read */ - u16_t lastoffset; - /** number of times data was received, set by event_callback(), - tested by the receive and select functions */ - s16_t rcvevent; - /** number of times data was ACKed (free send buffer), set by event_callback(), - tested by select */ - u16_t sendevent; - /** error happened for this socket, set by event_callback(), tested by select */ - u16_t errevent; - /** last error that occurred on this socket */ - int err; - /** counter of how many threads are waiting for this socket using select */ - int select_waiting; -}; - -/** Description for a task waiting in select */ -struct lwip_select_cb { - /** Pointer to the next waiting task */ - struct lwip_select_cb *next; - /** Pointer to the previous waiting task */ - struct lwip_select_cb *prev; - /** readset passed to select */ - fd_set *readset; - /** writeset passed to select */ - fd_set *writeset; - /** unimplemented: exceptset passed to select */ - fd_set *exceptset; - /** don't signal the same semaphore twice: set to 1 when signalled */ - int sem_signalled; - /** semaphore to wake up a task waiting for select */ - sys_sem_t sem; -}; - -/** This struct is used to pass data to the set/getsockopt_internal - * functions running in tcpip_thread context (only a void* is allowed) */ -struct lwip_setgetsockopt_data { - /** socket struct for which to change options */ - struct lwip_sock *sock; -#ifdef LWIP_DEBUG - /** socket index for which to change options */ - int s; -#endif /* LWIP_DEBUG */ - /** level of the option to process */ - int level; - /** name of the option to process */ - int optname; - /** set: value to set the option to - * get: value of the option is stored here */ - void *optval; - /** size of *optval */ - socklen_t *optlen; - /** if an error occures, it is temporarily stored here */ - err_t err; -}; - -/** The global array of available sockets */ -static struct lwip_sock sockets[NUM_SOCKETS]; -/** The global list of tasks waiting for select */ -static struct lwip_select_cb *select_cb_list; -/** This counter is increased from lwip_select when the list is chagned - and checked in event_callback to see if it has changed. */ -static volatile int select_cb_ctr; - -/** Table to quickly map an lwIP error (err_t) to a socket error - * by using -err as an index */ -static const int err_to_errno_table[] = { - 0, /* ERR_OK 0 No error, everything OK. */ - ENOMEM, /* ERR_MEM -1 Out of memory error. */ - ENOBUFS, /* ERR_BUF -2 Buffer error. */ - EWOULDBLOCK, /* ERR_TIMEOUT -3 Timeout */ - EHOSTUNREACH, /* ERR_RTE -4 Routing problem. */ - EINPROGRESS, /* ERR_INPROGRESS -5 Operation in progress */ - EINVAL, /* ERR_VAL -6 Illegal value. */ - EWOULDBLOCK, /* ERR_WOULDBLOCK -7 Operation would block. */ - EADDRINUSE, /* ERR_USE -8 Address in use. */ - EALREADY, /* ERR_ISCONN -9 Already connected. */ - ECONNABORTED, /* ERR_ABRT -10 Connection aborted. */ - ECONNRESET, /* ERR_RST -11 Connection reset. */ - ENOTCONN, /* ERR_CLSD -12 Connection closed. */ - ENOTCONN, /* ERR_CONN -13 Not connected. */ - EIO, /* ERR_ARG -14 Illegal argument. */ - -1, /* ERR_IF -15 Low-level netif error */ -}; - -#define ERR_TO_ERRNO_TABLE_SIZE \ - (sizeof(err_to_errno_table)/sizeof(err_to_errno_table[0])) - -#define err_to_errno(err) \ - ((unsigned)(-(err)) < ERR_TO_ERRNO_TABLE_SIZE ? \ - err_to_errno_table[-(err)] : EIO) - -#ifdef ERRNO -#ifndef set_errno -#define set_errno(err) errno = (err) -#endif -#else /* ERRNO */ -#define set_errno(err) -#endif /* ERRNO */ - -#define sock_set_errno(sk, e) do { \ - sk->err = (e); \ - set_errno(sk->err); \ -} while (0) - -/* Forward delcaration of some functions */ -static void event_callback(struct netconn *conn, enum netconn_evt evt, u16_t len); -static void lwip_getsockopt_internal(void *arg); -static void lwip_setsockopt_internal(void *arg); - -/** - * Initialize this module. This function has to be called before any other - * functions in this module! - */ -void -lwip_socket_init(void) -{ -} - -/** - * Map a externally used socket index to the internal socket representation. - * - * @param s externally used socket index - * @return struct lwip_sock for the socket or NULL if not found - */ -static struct lwip_sock * -get_socket(int s) -{ - struct lwip_sock *sock; - - if ((s < 0) || (s >= NUM_SOCKETS)) { - LWIP_DEBUGF(SOCKETS_DEBUG, ("get_socket(%d): invalid\n", s)); - set_errno(EBADF); - return NULL; - } - - sock = &sockets[s]; - - if (!sock->conn) { - LWIP_DEBUGF(SOCKETS_DEBUG, ("get_socket(%d): not active\n", s)); - set_errno(EBADF); - return NULL; - } - - return sock; -} - -/** - * Same as get_socket but doesn't set errno - * - * @param s externally used socket index - * @return struct lwip_sock for the socket or NULL if not found - */ -static struct lwip_sock * -tryget_socket(int s) -{ - if ((s < 0) || (s >= NUM_SOCKETS)) { - return NULL; - } - if (!sockets[s].conn) { - return NULL; - } - return &sockets[s]; -} - -/** - * Allocate a new socket for a given netconn. - * - * @param newconn the netconn for which to allocate a socket - * @param accepted 1 if socket has been created by accept(), - * 0 if socket has been created by socket() - * @return the index of the new socket; -1 on error - */ -static int -alloc_socket(struct netconn *newconn, int accepted) -{ - int i; - SYS_ARCH_DECL_PROTECT(lev); - - /* allocate a new socket identifier */ - for (i = 0; i < NUM_SOCKETS; ++i) { - /* Protect socket array */ - SYS_ARCH_PROTECT(lev); - if (!sockets[i].conn) { - sockets[i].conn = newconn; - /* The socket is not yet known to anyone, so no need to protect - after having marked it as used. */ - SYS_ARCH_UNPROTECT(lev); - sockets[i].lastdata = NULL; - sockets[i].lastoffset = 0; - sockets[i].rcvevent = 0; - /* TCP sendbuf is empty, but the socket is not yet writable until connected - * (unless it has been created by accept()). */ - sockets[i].sendevent = (newconn->type == NETCONN_TCP ? (accepted != 0) : 1); - sockets[i].errevent = 0; - sockets[i].err = 0; - sockets[i].select_waiting = 0; - return i; - } - SYS_ARCH_UNPROTECT(lev); - } - return -1; -} - -/** Free a socket. The socket's netconn must have been - * delete before! - * - * @param sock the socket to free - * @param is_tcp != 0 for TCP sockets, used to free lastdata - */ -static void -free_socket(struct lwip_sock *sock, int is_tcp) -{ - void *lastdata; - SYS_ARCH_DECL_PROTECT(lev); - - lastdata = sock->lastdata; - sock->lastdata = NULL; - sock->lastoffset = 0; - sock->err = 0; - - /* Protect socket array */ - SYS_ARCH_PROTECT(lev); - sock->conn = NULL; - SYS_ARCH_UNPROTECT(lev); - /* don't use 'sock' after this line, as another task might have allocated it */ - - if (lastdata != NULL) { - if (is_tcp) { - pbuf_free((struct pbuf *)lastdata); - } else { - netbuf_delete((struct netbuf *)lastdata); - } - } -} - -/* Below this, the well-known socket functions are implemented. - * Use google.com or opengroup.org to get a good description :-) - * - * Exceptions are documented! - */ - -int -lwip_accept(int s, struct sockaddr *addr, socklen_t *addrlen) -{ - struct lwip_sock *sock, *nsock; - struct netconn *newconn; - ip_addr_t naddr; - u16_t port; - int newsock; - struct sockaddr_in sin; - err_t err; - SYS_ARCH_DECL_PROTECT(lev); - - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d)...\n", s)); - sock = get_socket(s); - if (!sock) { - return -1; - } - - if (netconn_is_nonblocking(sock->conn) && (sock->rcvevent <= 0)) { - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d): returning EWOULDBLOCK\n", s)); - sock_set_errno(sock, EWOULDBLOCK); - return -1; - } - - /* wait for a new connection */ - err = netconn_accept(sock->conn, &newconn); - if (err != ERR_OK) { - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d): netconn_acept failed, err=%d\n", s, err)); - sock_set_errno(sock, err_to_errno(err)); - return -1; - } - LWIP_ASSERT("newconn != NULL", newconn != NULL); - /* Prevent automatic window updates, we do this on our own! */ - netconn_set_noautorecved(newconn, 1); - - /* get the IP address and port of the remote host */ - err = netconn_peer(newconn, &naddr, &port); - if (err != ERR_OK) { - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d): netconn_peer failed, err=%d\n", s, err)); - netconn_delete(newconn); - sock_set_errno(sock, err_to_errno(err)); - return -1; - } - - /* Note that POSIX only requires us to check addr is non-NULL. addrlen must - * not be NULL if addr is valid. - */ - if (NULL != addr) { - LWIP_ASSERT("addr valid but addrlen NULL", addrlen != NULL); - memset(&sin, 0, sizeof(sin)); - sin.sin_len = sizeof(sin); - sin.sin_family = AF_INET; - sin.sin_port = htons(port); - inet_addr_from_ipaddr(&sin.sin_addr, &naddr); - - if (*addrlen > sizeof(sin)) - *addrlen = sizeof(sin); - - MEMCPY(addr, &sin, *addrlen); - } - - newsock = alloc_socket(newconn, 1); - if (newsock == -1) { - netconn_delete(newconn); - sock_set_errno(sock, ENFILE); - return -1; - } - LWIP_ASSERT("invalid socket index", (newsock >= 0) && (newsock < NUM_SOCKETS)); - LWIP_ASSERT("newconn->callback == event_callback", newconn->callback == event_callback); - nsock = &sockets[newsock]; - - /* See event_callback: If data comes in right away after an accept, even - * though the server task might not have created a new socket yet. - * In that case, newconn->socket is counted down (newconn->socket--), - * so nsock->rcvevent is >= 1 here! - */ - SYS_ARCH_PROTECT(lev); - nsock->rcvevent += (s16_t)(-1 - newconn->socket); - newconn->socket = newsock; - SYS_ARCH_UNPROTECT(lev); - - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d) returning new sock=%d addr=", s, newsock)); - ip_addr_debug_print(SOCKETS_DEBUG, &naddr); - LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F"\n", port)); - - sock_set_errno(sock, 0); - return newsock; -} - -int -lwip_bind(int s, const struct sockaddr *name, socklen_t namelen) -{ - struct lwip_sock *sock; - ip_addr_t local_addr; - u16_t local_port; - err_t err; - const struct sockaddr_in *name_in; - - sock = get_socket(s); - if (!sock) { - return -1; - } - - /* check size, familiy and alignment of 'name' */ - LWIP_ERROR("lwip_bind: invalid address", ((namelen == sizeof(struct sockaddr_in)) && - ((name->sa_family) == AF_INET) && ((((mem_ptr_t)name) % 4) == 0)), - sock_set_errno(sock, err_to_errno(ERR_ARG)); return -1;); - name_in = (const struct sockaddr_in *)(void*)name; - - inet_addr_to_ipaddr(&local_addr, &name_in->sin_addr); - local_port = name_in->sin_port; - - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_bind(%d, addr=", s)); - ip_addr_debug_print(SOCKETS_DEBUG, &local_addr); - LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F")\n", ntohs(local_port))); - - err = netconn_bind(sock->conn, &local_addr, ntohs(local_port)); - - if (err != ERR_OK) { - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_bind(%d) failed, err=%d\n", s, err)); - sock_set_errno(sock, err_to_errno(err)); - return -1; - } - - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_bind(%d) succeeded\n", s)); - sock_set_errno(sock, 0); - return 0; -} - -int -lwip_close(int s) -{ - struct lwip_sock *sock; - int is_tcp = 0; - - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_close(%d)\n", s)); - - sock = get_socket(s); - if (!sock) { - return -1; - } - - if(sock->conn != NULL) { - is_tcp = netconn_type(sock->conn) == NETCONN_TCP; - } else { - LWIP_ASSERT("sock->lastdata == NULL", sock->lastdata == NULL); - } - - netconn_delete(sock->conn); - - free_socket(sock, is_tcp); - set_errno(0); - return 0; -} - -int -lwip_connect(int s, const struct sockaddr *name, socklen_t namelen) -{ - struct lwip_sock *sock; - err_t err; - const struct sockaddr_in *name_in; - - sock = get_socket(s); - if (!sock) { - return -1; - } - - /* check size, familiy and alignment of 'name' */ - LWIP_ERROR("lwip_connect: invalid address", ((namelen == sizeof(struct sockaddr_in)) && - ((name->sa_family) == AF_INET) && ((((mem_ptr_t)name) % 4) == 0)), - sock_set_errno(sock, err_to_errno(ERR_ARG)); return -1;); - name_in = (const struct sockaddr_in *)(void*)name; - - if (name_in->sin_family == AF_UNSPEC) { - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d, AF_UNSPEC)\n", s)); - err = netconn_disconnect(sock->conn); - } else { - ip_addr_t remote_addr; - u16_t remote_port; - - inet_addr_to_ipaddr(&remote_addr, &name_in->sin_addr); - remote_port = name_in->sin_port; - - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d, addr=", s)); - ip_addr_debug_print(SOCKETS_DEBUG, &remote_addr); - LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F")\n", ntohs(remote_port))); - - err = netconn_connect(sock->conn, &remote_addr, ntohs(remote_port)); - } - - if (err != ERR_OK) { - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d) failed, err=%d\n", s, err)); - sock_set_errno(sock, err_to_errno(err)); - return -1; - } - - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d) succeeded\n", s)); - sock_set_errno(sock, 0); - return 0; -} - -/** - * Set a socket into listen mode. - * The socket may not have been used for another connection previously. - * - * @param s the socket to set to listening mode - * @param backlog (ATTENTION: needs TCP_LISTEN_BACKLOG=1) - * @return 0 on success, non-zero on failure - */ -int -lwip_listen(int s, int backlog) -{ - struct lwip_sock *sock; - err_t err; - - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_listen(%d, backlog=%d)\n", s, backlog)); - - sock = get_socket(s); - if (!sock) { - return -1; - } - - /* limit the "backlog" parameter to fit in an u8_t */ - backlog = LWIP_MIN(LWIP_MAX(backlog, 0), 0xff); - - err = netconn_listen_with_backlog(sock->conn, (u8_t)backlog); - - if (err != ERR_OK) { - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_listen(%d) failed, err=%d\n", s, err)); - sock_set_errno(sock, err_to_errno(err)); - return -1; - } - - sock_set_errno(sock, 0); - return 0; -} - -int -lwip_recvfrom(int s, void *mem, size_t len, int flags, - struct sockaddr *from, socklen_t *fromlen) -{ - struct lwip_sock *sock; - void *buf = NULL; - struct pbuf *p; - u16_t buflen, copylen; - int off = 0; - ip_addr_t *addr; - u16_t port; - u8_t done = 0; - err_t err; - - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d, %p, %"SZT_F", 0x%x, ..)\n", s, mem, len, flags)); - sock = get_socket(s); - if (!sock) { - return -1; - } - - do { - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom: top while sock->lastdata=%p\n", sock->lastdata)); - /* Check if there is data left from the last recv operation. */ - if (sock->lastdata) { - buf = sock->lastdata; - } else { - /* If this is non-blocking call, then check first */ - if (((flags & MSG_DONTWAIT) || netconn_is_nonblocking(sock->conn)) && - (sock->rcvevent <= 0)) { - if (off > 0) { - /* update receive window */ - netconn_recved(sock->conn, (u32_t)off); - /* already received data, return that */ - sock_set_errno(sock, 0); - return off; - } - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d): returning EWOULDBLOCK\n", s)); - sock_set_errno(sock, EWOULDBLOCK); - return -1; - } - - /* No data was left from the previous operation, so we try to get - some from the network. */ - if (netconn_type(sock->conn) == NETCONN_TCP) { - err = netconn_recv_tcp_pbuf(sock->conn, (struct pbuf **)&buf); - } else { - err = netconn_recv(sock->conn, (struct netbuf **)&buf); - } - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom: netconn_recv err=%d, netbuf=%p\n", - err, buf)); - - if (err != ERR_OK) { - if (off > 0) { - /* update receive window */ - netconn_recved(sock->conn, (u32_t)off); - /* already received data, return that */ - sock_set_errno(sock, 0); - return off; - } - /* We should really do some error checking here. */ - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d): buf == NULL, error is \"%s\"!\n", - s, lwip_strerr(err))); - sock_set_errno(sock, err_to_errno(err)); - if (err == ERR_CLSD) { - return 0; - } else { - return -1; - } - } - LWIP_ASSERT("buf != NULL", buf != NULL); - sock->lastdata = buf; - } - - if (netconn_type(sock->conn) == NETCONN_TCP) { - p = (struct pbuf *)buf; - } else { - p = ((struct netbuf *)buf)->p; - } - buflen = p->tot_len; - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom: buflen=%"U16_F" len=%"SZT_F" off=%d sock->lastoffset=%"U16_F"\n", - buflen, len, off, sock->lastoffset)); - - buflen -= sock->lastoffset; - - if (len > buflen) { - copylen = buflen; - } else { - copylen = (u16_t)len; - } - - /* copy the contents of the received buffer into - the supplied memory pointer mem */ - pbuf_copy_partial(p, (u8_t*)mem + off, copylen, sock->lastoffset); - - off += copylen; - - if (netconn_type(sock->conn) == NETCONN_TCP) { - LWIP_ASSERT("invalid copylen, len would underflow", len >= copylen); - len -= copylen; - if ( (len <= 0) || - (p->flags & PBUF_FLAG_PUSH) || - (sock->rcvevent <= 0) || - ((flags & MSG_PEEK)!=0)) { - done = 1; - } - } else { - done = 1; - } - - /* Check to see from where the data was.*/ - if (done) { - ip_addr_t fromaddr; - if (from && fromlen) { - struct sockaddr_in sin; - - if (netconn_type(sock->conn) == NETCONN_TCP) { - addr = &fromaddr; - netconn_getaddr(sock->conn, addr, &port, 0); - } else { - addr = netbuf_fromaddr((struct netbuf *)buf); - port = netbuf_fromport((struct netbuf *)buf); - } - - memset(&sin, 0, sizeof(sin)); - sin.sin_len = sizeof(sin); - sin.sin_family = AF_INET; - sin.sin_port = htons(port); - inet_addr_from_ipaddr(&sin.sin_addr, addr); - - if (*fromlen > sizeof(sin)) { - *fromlen = sizeof(sin); - } - - MEMCPY(from, &sin, *fromlen); - - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d): addr=", s)); - ip_addr_debug_print(SOCKETS_DEBUG, addr); - LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F" len=%d\n", port, off)); - } else { -#if SOCKETS_DEBUG - if (netconn_type(sock->conn) == NETCONN_TCP) { - addr = &fromaddr; - netconn_getaddr(sock->conn, addr, &port, 0); - } else { - addr = netbuf_fromaddr((struct netbuf *)buf); - port = netbuf_fromport((struct netbuf *)buf); - } - - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d): addr=", s)); - ip_addr_debug_print(SOCKETS_DEBUG, addr); - LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F" len=%d\n", port, off)); -#endif /* SOCKETS_DEBUG */ - } - } - - /* If we don't peek the incoming message... */ - if ((flags & MSG_PEEK) == 0) { - /* If this is a TCP socket, check if there is data left in the - buffer. If so, it should be saved in the sock structure for next - time around. */ - if ((netconn_type(sock->conn) == NETCONN_TCP) && (buflen - copylen > 0)) { - sock->lastdata = buf; - sock->lastoffset += copylen; - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom: lastdata now netbuf=%p\n", buf)); - } else { - sock->lastdata = NULL; - sock->lastoffset = 0; - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom: deleting netbuf=%p\n", buf)); - if (netconn_type(sock->conn) == NETCONN_TCP) { - pbuf_free((struct pbuf *)buf); - } else { - netbuf_delete((struct netbuf *)buf); - } - } - } - } while (!done); - - if (off > 0) { - /* update receive window */ - netconn_recved(sock->conn, (u32_t)off); - } - sock_set_errno(sock, 0); - return off; -} - -int -lwip_read(int s, void *mem, size_t len) -{ - return lwip_recvfrom(s, mem, len, 0, NULL, NULL); -} - -int -lwip_recv(int s, void *mem, size_t len, int flags) -{ - return lwip_recvfrom(s, mem, len, flags, NULL, NULL); -} - -int -lwip_send(int s, const void *data, size_t size, int flags) -{ - struct lwip_sock *sock; - err_t err; - u8_t write_flags; - - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_send(%d, data=%p, size=%"SZT_F", flags=0x%x)\n", - s, data, size, flags)); - - sock = get_socket(s); - if (!sock) { - return -1; - } - - if (sock->conn->type != NETCONN_TCP) { -#if (LWIP_UDP || LWIP_RAW) - return lwip_sendto(s, data, size, flags, NULL, 0); -#else /* (LWIP_UDP || LWIP_RAW) */ - sock_set_errno(sock, err_to_errno(ERR_ARG)); - return -1; -#endif /* (LWIP_UDP || LWIP_RAW) */ - } - - if ((flags & MSG_DONTWAIT) || netconn_is_nonblocking(sock->conn)) { - if ((size > TCP_SND_BUF) || ((size / TCP_MSS) > TCP_SND_QUEUELEN)) { - /* too much data to ever send nonblocking! */ - sock_set_errno(sock, EMSGSIZE); - return -1; - } - } - - write_flags = NETCONN_COPY | - ((flags & MSG_MORE) ? NETCONN_MORE : 0) | - ((flags & MSG_DONTWAIT) ? NETCONN_DONTBLOCK : 0); - err = netconn_write(sock->conn, data, size, write_flags); - - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_send(%d) err=%d size=%"SZT_F"\n", s, err, size)); - sock_set_errno(sock, err_to_errno(err)); - return (err == ERR_OK ? (int)size : -1); -} - -int -lwip_sendto(int s, const void *data, size_t size, int flags, - const struct sockaddr *to, socklen_t tolen) -{ - struct lwip_sock *sock; - err_t err; - u16_t short_size; - const struct sockaddr_in *to_in; - u16_t remote_port; -#if !LWIP_TCPIP_CORE_LOCKING - struct netbuf buf; -#endif - - sock = get_socket(s); - if (!sock) { - return -1; - } - - if (sock->conn->type == NETCONN_TCP) { -#if LWIP_TCP - return lwip_send(s, data, size, flags); -#else /* LWIP_TCP */ - LWIP_UNUSED_ARG(flags); - sock_set_errno(sock, err_to_errno(ERR_ARG)); - return -1; -#endif /* LWIP_TCP */ - } - - /* @todo: split into multiple sendto's? */ - LWIP_ASSERT("lwip_sendto: size must fit in u16_t", size <= 0xffff); - short_size = (u16_t)size; - LWIP_ERROR("lwip_sendto: invalid address", (((to == NULL) && (tolen == 0)) || - ((tolen == sizeof(struct sockaddr_in)) && - ((to->sa_family) == AF_INET) && ((((mem_ptr_t)to) % 4) == 0))), - sock_set_errno(sock, err_to_errno(ERR_ARG)); return -1;); - to_in = (const struct sockaddr_in *)(void*)to; - -#if LWIP_TCPIP_CORE_LOCKING - /* Should only be consider like a sample or a simple way to experiment this option (no check of "to" field...) */ - { - struct pbuf* p; - ip_addr_t *remote_addr; - -#if LWIP_NETIF_TX_SINGLE_PBUF - p = pbuf_alloc(PBUF_TRANSPORT, short_size, PBUF_RAM); - if (p != NULL) { -#if LWIP_CHECKSUM_ON_COPY - u16_t chksum = 0; - if (sock->conn->type != NETCONN_RAW) { - chksum = LWIP_CHKSUM_COPY(p->payload, data, short_size); - } else -#endif /* LWIP_CHECKSUM_ON_COPY */ - MEMCPY(p->payload, data, size); -#else /* LWIP_NETIF_TX_SINGLE_PBUF */ - p = pbuf_alloc(PBUF_TRANSPORT, short_size, PBUF_REF); - if (p != NULL) { - p->payload = (void*)data; -#endif /* LWIP_NETIF_TX_SINGLE_PBUF */ - - if (to_in != NULL) { - inet_addr_to_ipaddr_p(remote_addr, &to_in->sin_addr); - remote_port = ntohs(to_in->sin_port); - } else { - remote_addr = &sock->conn->pcb.raw->remote_ip; - if (sock->conn->type == NETCONN_RAW) { - remote_port = 0; - } else { - remote_port = sock->conn->pcb.udp->remote_port; - } - } - - LOCK_TCPIP_CORE(); - if (sock->conn->type == NETCONN_RAW) { - err = sock->conn->last_err = raw_sendto(sock->conn->pcb.raw, p, remote_addr); - } else { -#if LWIP_UDP -#if LWIP_CHECKSUM_ON_COPY && LWIP_NETIF_TX_SINGLE_PBUF - err = sock->conn->last_err = udp_sendto_chksum(sock->conn->pcb.udp, p, - remote_addr, remote_port, 1, chksum); -#else /* LWIP_CHECKSUM_ON_COPY && LWIP_NETIF_TX_SINGLE_PBUF */ - err = sock->conn->last_err = udp_sendto(sock->conn->pcb.udp, p, - remote_addr, remote_port); -#endif /* LWIP_CHECKSUM_ON_COPY && LWIP_NETIF_TX_SINGLE_PBUF */ -#else /* LWIP_UDP */ - err = ERR_ARG; -#endif /* LWIP_UDP */ - } - UNLOCK_TCPIP_CORE(); - - pbuf_free(p); - } else { - err = ERR_MEM; - } - } -#else /* LWIP_TCPIP_CORE_LOCKING */ - /* initialize a buffer */ - buf.p = buf.ptr = NULL; -#if LWIP_CHECKSUM_ON_COPY - buf.flags = 0; -#endif /* LWIP_CHECKSUM_ON_COPY */ - if (to) { - inet_addr_to_ipaddr(&buf.addr, &to_in->sin_addr); - remote_port = ntohs(to_in->sin_port); - netbuf_fromport(&buf) = remote_port; - } else { - remote_port = 0; - ip_addr_set_any(&buf.addr); - netbuf_fromport(&buf) = 0; - } - - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_sendto(%d, data=%p, short_size=%"U16_F", flags=0x%x to=", - s, data, short_size, flags)); - ip_addr_debug_print(SOCKETS_DEBUG, &buf.addr); - LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F"\n", remote_port)); - - /* make the buffer point to the data that should be sent */ -#if LWIP_NETIF_TX_SINGLE_PBUF - /* Allocate a new netbuf and copy the data into it. */ - if (netbuf_alloc(&buf, short_size) == NULL) { - err = ERR_MEM; - } else { -#if LWIP_CHECKSUM_ON_COPY - if (sock->conn->type != NETCONN_RAW) { - u16_t chksum = LWIP_CHKSUM_COPY(buf.p->payload, data, short_size); - netbuf_set_chksum(&buf, chksum); - err = ERR_OK; - } else -#endif /* LWIP_CHECKSUM_ON_COPY */ - { - err = netbuf_take(&buf, data, short_size); - } - } -#else /* LWIP_NETIF_TX_SINGLE_PBUF */ - err = netbuf_ref(&buf, data, short_size); -#endif /* LWIP_NETIF_TX_SINGLE_PBUF */ - if (err == ERR_OK) { - /* send the data */ - err = netconn_send(sock->conn, &buf); - } - - /* deallocated the buffer */ - netbuf_free(&buf); -#endif /* LWIP_TCPIP_CORE_LOCKING */ - sock_set_errno(sock, err_to_errno(err)); - return (err == ERR_OK ? short_size : -1); -} - -int -lwip_socket(int domain, int type, int protocol) -{ - struct netconn *conn; - int i; - - LWIP_UNUSED_ARG(domain); - - /* create a netconn */ - switch (type) { - case SOCK_RAW: - conn = netconn_new_with_proto_and_callback(NETCONN_RAW, (u8_t)protocol, event_callback); - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_socket(%s, SOCK_RAW, %d) = ", - domain == PF_INET ? "PF_INET" : "UNKNOWN", protocol)); - break; - case SOCK_DGRAM: - conn = netconn_new_with_callback( (protocol == IPPROTO_UDPLITE) ? - NETCONN_UDPLITE : NETCONN_UDP, event_callback); - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_socket(%s, SOCK_DGRAM, %d) = ", - domain == PF_INET ? "PF_INET" : "UNKNOWN", protocol)); - break; - case SOCK_STREAM: - conn = netconn_new_with_callback(NETCONN_TCP, event_callback); - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_socket(%s, SOCK_STREAM, %d) = ", - domain == PF_INET ? "PF_INET" : "UNKNOWN", protocol)); - if (conn != NULL) { - /* Prevent automatic window updates, we do this on our own! */ - netconn_set_noautorecved(conn, 1); - } - break; - default: - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_socket(%d, %d/UNKNOWN, %d) = -1\n", - domain, type, protocol)); - set_errno(EINVAL); - return -1; - } - - if (!conn) { - LWIP_DEBUGF(SOCKETS_DEBUG, ("-1 / ENOBUFS (could not create netconn)\n")); - set_errno(ENOBUFS); - return -1; - } - - i = alloc_socket(conn, 0); - - if (i == -1) { - netconn_delete(conn); - set_errno(ENFILE); - return -1; - } - conn->socket = i; - LWIP_DEBUGF(SOCKETS_DEBUG, ("%d\n", i)); - set_errno(0); - return i; -} - -int -lwip_write(int s, const void *data, size_t size) -{ - return lwip_send(s, data, size, 0); -} - -/** - * Go through the readset and writeset lists and see which socket of the sockets - * set in the sets has events. On return, readset, writeset and exceptset have - * the sockets enabled that had events. - * - * exceptset is not used for now!!! - * - * @param maxfdp1 the highest socket index in the sets - * @param readset_in: set of sockets to check for read events - * @param writeset_in: set of sockets to check for write events - * @param exceptset_in: set of sockets to check for error events - * @param readset_out: set of sockets that had read events - * @param writeset_out: set of sockets that had write events - * @param exceptset_out: set os sockets that had error events - * @return number of sockets that had events (read/write/exception) (>= 0) - */ -static int -lwip_selscan(int maxfdp1, fd_set *readset_in, fd_set *writeset_in, fd_set *exceptset_in, - fd_set *readset_out, fd_set *writeset_out, fd_set *exceptset_out) -{ - int i, nready = 0; - fd_set lreadset, lwriteset, lexceptset; - struct lwip_sock *sock; - SYS_ARCH_DECL_PROTECT(lev); - - FD_ZERO(&lreadset); - FD_ZERO(&lwriteset); - FD_ZERO(&lexceptset); - - /* Go through each socket in each list to count number of sockets which - currently match */ - for(i = 0; i < maxfdp1; i++) { - void* lastdata = NULL; - s16_t rcvevent = 0; - u16_t sendevent = 0; - u16_t errevent = 0; - /* First get the socket's status (protected)... */ - SYS_ARCH_PROTECT(lev); - sock = tryget_socket(i); - if (sock != NULL) { - lastdata = sock->lastdata; - rcvevent = sock->rcvevent; - sendevent = sock->sendevent; - errevent = sock->errevent; - } - SYS_ARCH_UNPROTECT(lev); - /* ... then examine it: */ - /* See if netconn of this socket is ready for read */ - if (readset_in && FD_ISSET(i, readset_in) && ((lastdata != NULL) || (rcvevent > 0))) { - FD_SET(i, &lreadset); - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_selscan: fd=%d ready for reading\n", i)); - nready++; - } - /* See if netconn of this socket is ready for write */ - if (writeset_in && FD_ISSET(i, writeset_in) && (sendevent != 0)) { - FD_SET(i, &lwriteset); - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_selscan: fd=%d ready for writing\n", i)); - nready++; - } - /* See if netconn of this socket had an error */ - if (exceptset_in && FD_ISSET(i, exceptset_in) && (errevent != 0)) { - FD_SET(i, &lexceptset); - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_selscan: fd=%d ready for exception\n", i)); - nready++; - } - } - /* copy local sets to the ones provided as arguments */ - *readset_out = lreadset; - *writeset_out = lwriteset; - *exceptset_out = lexceptset; - - LWIP_ASSERT("nready >= 0", nready >= 0); - return nready; -} - -/** - * Processing exceptset is not yet implemented. - */ -int -lwip_select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset, - struct timeval *timeout) -{ - u32_t waitres = 0; - int nready; - fd_set lreadset, lwriteset, lexceptset; - u32_t msectimeout; - struct lwip_select_cb select_cb; - err_t err; - int i; - SYS_ARCH_DECL_PROTECT(lev); - - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select(%d, %p, %p, %p, tvsec=%"S32_F" tvusec=%"S32_F")\n", - maxfdp1, (void *)readset, (void *) writeset, (void *) exceptset, - timeout ? (s32_t)timeout->tv_sec : (s32_t)-1, - timeout ? (s32_t)timeout->tv_usec : (s32_t)-1)); - - /* Go through each socket in each list to count number of sockets which - currently match */ - nready = lwip_selscan(maxfdp1, readset, writeset, exceptset, &lreadset, &lwriteset, &lexceptset); - - /* If we don't have any current events, then suspend if we are supposed to */ - if (!nready) { - if (timeout && timeout->tv_sec == 0 && timeout->tv_usec == 0) { - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select: no timeout, returning 0\n")); - /* This is OK as the local fdsets are empty and nready is zero, - or we would have returned earlier. */ - goto return_copy_fdsets; - } - - /* None ready: add our semaphore to list: - We don't actually need any dynamic memory. Our entry on the - list is only valid while we are in this function, so it's ok - to use local variables. */ - - select_cb.next = NULL; - select_cb.prev = NULL; - select_cb.readset = readset; - select_cb.writeset = writeset; - select_cb.exceptset = exceptset; - select_cb.sem_signalled = 0; - err = sys_sem_new(&select_cb.sem, 0); - if (err != ERR_OK) { - /* failed to create semaphore */ - set_errno(ENOMEM); - return -1; - } - - /* Protect the select_cb_list */ - SYS_ARCH_PROTECT(lev); - - /* Put this select_cb on top of list */ - select_cb.next = select_cb_list; - if (select_cb_list != NULL) { - select_cb_list->prev = &select_cb; - } - select_cb_list = &select_cb; - /* Increasing this counter tells even_callback that the list has changed. */ - select_cb_ctr++; - - /* Now we can safely unprotect */ - SYS_ARCH_UNPROTECT(lev); - - /* Increase select_waiting for each socket we are interested in */ - for(i = 0; i < maxfdp1; i++) { - if ((readset && FD_ISSET(i, readset)) || - (writeset && FD_ISSET(i, writeset)) || - (exceptset && FD_ISSET(i, exceptset))) { - struct lwip_sock *sock = tryget_socket(i); - LWIP_ASSERT("sock != NULL", sock != NULL); - SYS_ARCH_PROTECT(lev); - sock->select_waiting++; - LWIP_ASSERT("sock->select_waiting > 0", sock->select_waiting > 0); - SYS_ARCH_UNPROTECT(lev); - } - } - - /* Call lwip_selscan again: there could have been events between - the last scan (whithout us on the list) and putting us on the list! */ - nready = lwip_selscan(maxfdp1, readset, writeset, exceptset, &lreadset, &lwriteset, &lexceptset); - if (!nready) { - /* Still none ready, just wait to be woken */ - if (timeout == 0) { - /* Wait forever */ - msectimeout = 0; - } else { - msectimeout = ((timeout->tv_sec * 1000) + ((timeout->tv_usec + 500)/1000)); - if (msectimeout == 0) { - /* Wait 1ms at least (0 means wait forever) */ - msectimeout = 1; - } - } - - waitres = sys_arch_sem_wait(&select_cb.sem, msectimeout); - } - /* Increase select_waiting for each socket we are interested in */ - for(i = 0; i < maxfdp1; i++) { - if ((readset && FD_ISSET(i, readset)) || - (writeset && FD_ISSET(i, writeset)) || - (exceptset && FD_ISSET(i, exceptset))) { - struct lwip_sock *sock = tryget_socket(i); - LWIP_ASSERT("sock != NULL", sock != NULL); - SYS_ARCH_PROTECT(lev); - sock->select_waiting--; - LWIP_ASSERT("sock->select_waiting >= 0", sock->select_waiting >= 0); - SYS_ARCH_UNPROTECT(lev); - } - } - /* Take us off the list */ - SYS_ARCH_PROTECT(lev); - if (select_cb.next != NULL) { - select_cb.next->prev = select_cb.prev; - } - if (select_cb_list == &select_cb) { - LWIP_ASSERT("select_cb.prev == NULL", select_cb.prev == NULL); - select_cb_list = select_cb.next; - } else { - LWIP_ASSERT("select_cb.prev != NULL", select_cb.prev != NULL); - select_cb.prev->next = select_cb.next; - } - /* Increasing this counter tells even_callback that the list has changed. */ - select_cb_ctr++; - SYS_ARCH_UNPROTECT(lev); - - sys_sem_free(&select_cb.sem); - if (waitres == SYS_ARCH_TIMEOUT) { - /* Timeout */ - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select: timeout expired\n")); - /* This is OK as the local fdsets are empty and nready is zero, - or we would have returned earlier. */ - goto return_copy_fdsets; - } - - /* See what's set */ - nready = lwip_selscan(maxfdp1, readset, writeset, exceptset, &lreadset, &lwriteset, &lexceptset); - } - - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select: nready=%d\n", nready)); -return_copy_fdsets: - set_errno(0); - if (readset) { - *readset = lreadset; - } - if (writeset) { - *writeset = lwriteset; - } - if (exceptset) { - *exceptset = lexceptset; - } - - - return nready; -} - -/** - * Callback registered in the netconn layer for each socket-netconn. - * Processes recvevent (data available) and wakes up tasks waiting for select. - */ -static void -event_callback(struct netconn *conn, enum netconn_evt evt, u16_t len) -{ - int s; - struct lwip_sock *sock; - struct lwip_select_cb *scb; - int last_select_cb_ctr; - SYS_ARCH_DECL_PROTECT(lev); - - LWIP_UNUSED_ARG(len); - - /* Get socket */ - if (conn) { - s = conn->socket; - if (s < 0) { - /* Data comes in right away after an accept, even though - * the server task might not have created a new socket yet. - * Just count down (or up) if that's the case and we - * will use the data later. Note that only receive events - * can happen before the new socket is set up. */ - SYS_ARCH_PROTECT(lev); - if (conn->socket < 0) { - if (evt == NETCONN_EVT_RCVPLUS) { - conn->socket--; - } - SYS_ARCH_UNPROTECT(lev); - return; - } - s = conn->socket; - SYS_ARCH_UNPROTECT(lev); - } - - sock = get_socket(s); - if (!sock) { - return; - } - } else { - return; - } - - SYS_ARCH_PROTECT(lev); - /* Set event as required */ - switch (evt) { - case NETCONN_EVT_RCVPLUS: - sock->rcvevent++; - break; - case NETCONN_EVT_RCVMINUS: - sock->rcvevent--; - break; - case NETCONN_EVT_SENDPLUS: - sock->sendevent = 1; - break; - case NETCONN_EVT_SENDMINUS: - sock->sendevent = 0; - break; - case NETCONN_EVT_ERROR: - sock->errevent = 1; - break; - default: - LWIP_ASSERT("unknown event", 0); - break; - } - - if (sock->select_waiting == 0) { - /* noone is waiting for this socket, no need to check select_cb_list */ - SYS_ARCH_UNPROTECT(lev); - return; - } - - /* Now decide if anyone is waiting for this socket */ - /* NOTE: This code goes through the select_cb_list list multiple times - ONLY IF a select was actually waiting. We go through the list the number - of waiting select calls + 1. This list is expected to be small. */ - - /* At this point, SYS_ARCH is still protected! */ -again: - for (scb = select_cb_list; scb != NULL; scb = scb->next) { - if (scb->sem_signalled == 0) { - /* semaphore not signalled yet */ - int do_signal = 0; - /* Test this select call for our socket */ - if (sock->rcvevent > 0) { - if (scb->readset && FD_ISSET(s, scb->readset)) { - do_signal = 1; - } - } - if (sock->sendevent != 0) { - if (!do_signal && scb->writeset && FD_ISSET(s, scb->writeset)) { - do_signal = 1; - } - } - if (sock->errevent != 0) { - if (!do_signal && scb->exceptset && FD_ISSET(s, scb->exceptset)) { - do_signal = 1; - } - } - if (do_signal) { - scb->sem_signalled = 1; - /* Don't call SYS_ARCH_UNPROTECT() before signaling the semaphore, as this might - lead to the select thread taking itself off the list, invalidagin the semaphore. */ - sys_sem_signal(&scb->sem); - } - } - /* unlock interrupts with each step */ - last_select_cb_ctr = select_cb_ctr; - SYS_ARCH_UNPROTECT(lev); - /* this makes sure interrupt protection time is short */ - SYS_ARCH_PROTECT(lev); - if (last_select_cb_ctr != select_cb_ctr) { - /* someone has changed select_cb_list, restart at the beginning */ - goto again; - } - } - SYS_ARCH_UNPROTECT(lev); -} - -/** - * Unimplemented: Close one end of a full-duplex connection. - * Currently, the full connection is closed. - */ -int -lwip_shutdown(int s, int how) -{ - struct lwip_sock *sock; - err_t err; - u8_t shut_rx = 0, shut_tx = 0; - - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_shutdown(%d, how=%d)\n", s, how)); - - sock = get_socket(s); - if (!sock) { - return -1; - } - - if (sock->conn != NULL) { - if (netconn_type(sock->conn) != NETCONN_TCP) { - sock_set_errno(sock, EOPNOTSUPP); - return EOPNOTSUPP; - } - } else { - sock_set_errno(sock, ENOTCONN); - return ENOTCONN; - } - - if (how == SHUT_RD) { - shut_rx = 1; - } else if (how == SHUT_WR) { - shut_tx = 1; - } else if(how == SHUT_RDWR) { - shut_rx = 1; - shut_tx = 1; - } else { - sock_set_errno(sock, EINVAL); - return EINVAL; - } - err = netconn_shutdown(sock->conn, shut_rx, shut_tx); - - sock_set_errno(sock, err_to_errno(err)); - return (err == ERR_OK ? 0 : -1); -} - -static int -lwip_getaddrname(int s, struct sockaddr *name, socklen_t *namelen, u8_t local) -{ - struct lwip_sock *sock; - struct sockaddr_in sin; - ip_addr_t naddr; - - sock = get_socket(s); - if (!sock) { - return -1; - } - - memset(&sin, 0, sizeof(sin)); - sin.sin_len = sizeof(sin); - sin.sin_family = AF_INET; - - /* get the IP address and port */ - netconn_getaddr(sock->conn, &naddr, &sin.sin_port, local); - - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getaddrname(%d, addr=", s)); - ip_addr_debug_print(SOCKETS_DEBUG, &naddr); - LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F")\n", sin.sin_port)); - - sin.sin_port = htons(sin.sin_port); - inet_addr_from_ipaddr(&sin.sin_addr, &naddr); - - if (*namelen > sizeof(sin)) { - *namelen = sizeof(sin); - } - - MEMCPY(name, &sin, *namelen); - sock_set_errno(sock, 0); - return 0; -} - -int -lwip_getpeername(int s, struct sockaddr *name, socklen_t *namelen) -{ - return lwip_getaddrname(s, name, namelen, 0); -} - -int -lwip_getsockname(int s, struct sockaddr *name, socklen_t *namelen) -{ - return lwip_getaddrname(s, name, namelen, 1); -} - -int -lwip_getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen) -{ - err_t err = ERR_OK; - struct lwip_sock *sock = get_socket(s); - struct lwip_setgetsockopt_data data; - - if (!sock) { - return -1; - } - - if ((NULL == optval) || (NULL == optlen)) { - sock_set_errno(sock, EFAULT); - return -1; - } - - /* Do length and type checks for the various options first, to keep it readable. */ - switch (level) { - -/* Level: SOL_SOCKET */ - case SOL_SOCKET: - switch (optname) { - - case SO_ACCEPTCONN: - case SO_BROADCAST: - /* UNIMPL case SO_DEBUG: */ - /* UNIMPL case SO_DONTROUTE: */ - case SO_ERROR: - case SO_KEEPALIVE: - /* UNIMPL case SO_CONTIMEO: */ - /* UNIMPL case SO_SNDTIMEO: */ -#if LWIP_SO_RCVTIMEO - case SO_RCVTIMEO: -#endif /* LWIP_SO_RCVTIMEO */ -#if LWIP_SO_RCVBUF - case SO_RCVBUF: -#endif /* LWIP_SO_RCVBUF */ - /* UNIMPL case SO_OOBINLINE: */ - /* UNIMPL case SO_SNDBUF: */ - /* UNIMPL case SO_RCVLOWAT: */ - /* UNIMPL case SO_SNDLOWAT: */ -#if SO_REUSE - case SO_REUSEADDR: - case SO_REUSEPORT: -#endif /* SO_REUSE */ - case SO_TYPE: - /* UNIMPL case SO_USELOOPBACK: */ - if (*optlen < sizeof(int)) { - err = EINVAL; - } - break; - - case SO_NO_CHECK: - if (*optlen < sizeof(int)) { - err = EINVAL; - } -#if LWIP_UDP - if ((sock->conn->type != NETCONN_UDP) || - ((udp_flags(sock->conn->pcb.udp) & UDP_FLAGS_UDPLITE) != 0)) { - /* this flag is only available for UDP, not for UDP lite */ - err = EAFNOSUPPORT; - } -#endif /* LWIP_UDP */ - break; - - default: - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, SOL_SOCKET, UNIMPL: optname=0x%x, ..)\n", - s, optname)); - err = ENOPROTOOPT; - } /* switch (optname) */ - break; - -/* Level: IPPROTO_IP */ - case IPPROTO_IP: - switch (optname) { - /* UNIMPL case IP_HDRINCL: */ - /* UNIMPL case IP_RCVDSTADDR: */ - /* UNIMPL case IP_RCVIF: */ - case IP_TTL: - case IP_TOS: - if (*optlen < sizeof(int)) { - err = EINVAL; - } - break; -#if LWIP_IGMP - case IP_MULTICAST_TTL: - if (*optlen < sizeof(u8_t)) { - err = EINVAL; - } - break; - case IP_MULTICAST_IF: - if (*optlen < sizeof(struct in_addr)) { - err = EINVAL; - } - break; - case IP_MULTICAST_LOOP: - if (*optlen < sizeof(u8_t)) { - err = EINVAL; - } - if (NETCONNTYPE_GROUP(sock->conn->type) != NETCONN_UDP) { - err = EAFNOSUPPORT; - } - break; -#endif /* LWIP_IGMP */ - - default: - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, UNIMPL: optname=0x%x, ..)\n", - s, optname)); - err = ENOPROTOOPT; - } /* switch (optname) */ - break; - -#if LWIP_TCP -/* Level: IPPROTO_TCP */ - case IPPROTO_TCP: - if (*optlen < sizeof(int)) { - err = EINVAL; - break; - } - - /* If this is no TCP socket, ignore any options. */ - if (sock->conn->type != NETCONN_TCP) - return 0; - - switch (optname) { - case TCP_NODELAY: - case TCP_KEEPALIVE: -#if LWIP_TCP_KEEPALIVE - case TCP_KEEPIDLE: - case TCP_KEEPINTVL: - case TCP_KEEPCNT: -#endif /* LWIP_TCP_KEEPALIVE */ - break; - - default: - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_TCP, UNIMPL: optname=0x%x, ..)\n", - s, optname)); - err = ENOPROTOOPT; - } /* switch (optname) */ - break; -#endif /* LWIP_TCP */ -#if LWIP_UDP && LWIP_UDPLITE -/* Level: IPPROTO_UDPLITE */ - case IPPROTO_UDPLITE: - if (*optlen < sizeof(int)) { - err = EINVAL; - break; - } - - /* If this is no UDP lite socket, ignore any options. */ - if (sock->conn->type != NETCONN_UDPLITE) { - return 0; - } - - switch (optname) { - case UDPLITE_SEND_CSCOV: - case UDPLITE_RECV_CSCOV: - break; - - default: - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_UDPLITE, UNIMPL: optname=0x%x, ..)\n", - s, optname)); - err = ENOPROTOOPT; - } /* switch (optname) */ - break; -#endif /* LWIP_UDP && LWIP_UDPLITE*/ -/* UNDEFINED LEVEL */ - default: - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, level=0x%x, UNIMPL: optname=0x%x, ..)\n", - s, level, optname)); - err = ENOPROTOOPT; - } /* switch */ - - - if (err != ERR_OK) { - sock_set_errno(sock, err); - return -1; - } - - /* Now do the actual option processing */ - data.sock = sock; -#ifdef LWIP_DEBUG - data.s = s; -#endif /* LWIP_DEBUG */ - data.level = level; - data.optname = optname; - data.optval = optval; - data.optlen = optlen; - data.err = err; - tcpip_callback(lwip_getsockopt_internal, &data); - sys_arch_sem_wait(&sock->conn->op_completed, 0); - /* maybe lwip_getsockopt_internal has changed err */ - err = data.err; - - sock_set_errno(sock, err); - return err ? -1 : 0; -} - -static void -lwip_getsockopt_internal(void *arg) -{ - struct lwip_sock *sock; -#ifdef LWIP_DEBUG - int s; -#endif /* LWIP_DEBUG */ - int level, optname; - void *optval; - struct lwip_setgetsockopt_data *data; - - LWIP_ASSERT("arg != NULL", arg != NULL); - - data = (struct lwip_setgetsockopt_data*)arg; - sock = data->sock; -#ifdef LWIP_DEBUG - s = data->s; -#endif /* LWIP_DEBUG */ - level = data->level; - optname = data->optname; - optval = data->optval; - - switch (level) { - -/* Level: SOL_SOCKET */ - case SOL_SOCKET: - switch (optname) { - - /* The option flags */ - case SO_ACCEPTCONN: - case SO_BROADCAST: - /* UNIMPL case SO_DEBUG: */ - /* UNIMPL case SO_DONTROUTE: */ - case SO_KEEPALIVE: - /* UNIMPL case SO_OOBINCLUDE: */ -#if SO_REUSE - case SO_REUSEADDR: - case SO_REUSEPORT: -#endif /* SO_REUSE */ - /*case SO_USELOOPBACK: UNIMPL */ - *(int*)optval = sock->conn->pcb.ip->so_options & optname; - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, SOL_SOCKET, optname=0x%x, ..) = %s\n", - s, optname, (*(int*)optval?"on":"off"))); - break; - - case SO_TYPE: - switch (NETCONNTYPE_GROUP(sock->conn->type)) { - case NETCONN_RAW: - *(int*)optval = SOCK_RAW; - break; - case NETCONN_TCP: - *(int*)optval = SOCK_STREAM; - break; - case NETCONN_UDP: - *(int*)optval = SOCK_DGRAM; - break; - default: /* unrecognized socket type */ - *(int*)optval = sock->conn->type; - LWIP_DEBUGF(SOCKETS_DEBUG, - ("lwip_getsockopt(%d, SOL_SOCKET, SO_TYPE): unrecognized socket type %d\n", - s, *(int *)optval)); - } /* switch (sock->conn->type) */ - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, SOL_SOCKET, SO_TYPE) = %d\n", - s, *(int *)optval)); - break; - - case SO_ERROR: - /* only overwrite ERR_OK or tempoary errors */ - if ((sock->err == 0) || (sock->err == EINPROGRESS)) { - sock_set_errno(sock, err_to_errno(sock->conn->last_err)); - } - *(int *)optval = sock->err; - sock->err = 0; - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, SOL_SOCKET, SO_ERROR) = %d\n", - s, *(int *)optval)); - break; - -#if LWIP_SO_RCVTIMEO - case SO_RCVTIMEO: - *(int *)optval = netconn_get_recvtimeout(sock->conn); - break; -#endif /* LWIP_SO_RCVTIMEO */ -#if LWIP_SO_RCVBUF - case SO_RCVBUF: - *(int *)optval = netconn_get_recvbufsize(sock->conn); - break; -#endif /* LWIP_SO_RCVBUF */ -#if LWIP_UDP - case SO_NO_CHECK: - *(int*)optval = (udp_flags(sock->conn->pcb.udp) & UDP_FLAGS_NOCHKSUM) ? 1 : 0; - break; -#endif /* LWIP_UDP*/ - default: - LWIP_ASSERT("unhandled optname", 0); - break; - } /* switch (optname) */ - break; - -/* Level: IPPROTO_IP */ - case IPPROTO_IP: - switch (optname) { - case IP_TTL: - *(int*)optval = sock->conn->pcb.ip->ttl; - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, IP_TTL) = %d\n", - s, *(int *)optval)); - break; - case IP_TOS: - *(int*)optval = sock->conn->pcb.ip->tos; - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, IP_TOS) = %d\n", - s, *(int *)optval)); - break; -#if LWIP_IGMP - case IP_MULTICAST_TTL: - *(u8_t*)optval = sock->conn->pcb.ip->ttl; - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, IP_MULTICAST_TTL) = %d\n", - s, *(int *)optval)); - break; - case IP_MULTICAST_IF: - inet_addr_from_ipaddr((struct in_addr*)optval, &sock->conn->pcb.udp->multicast_ip); - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, IP_MULTICAST_IF) = 0x%"X32_F"\n", - s, *(u32_t *)optval)); - break; - case IP_MULTICAST_LOOP: - if ((sock->conn->pcb.udp->flags & UDP_FLAGS_MULTICAST_LOOP) != 0) { - *(u8_t*)optval = 1; - } else { - *(u8_t*)optval = 0; - } - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, IP_MULTICAST_LOOP) = %d\n", - s, *(int *)optval)); - break; -#endif /* LWIP_IGMP */ - default: - LWIP_ASSERT("unhandled optname", 0); - break; - } /* switch (optname) */ - break; - -#if LWIP_TCP -/* Level: IPPROTO_TCP */ - case IPPROTO_TCP: - switch (optname) { - case TCP_NODELAY: - *(int*)optval = tcp_nagle_disabled(sock->conn->pcb.tcp); - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_TCP, TCP_NODELAY) = %s\n", - s, (*(int*)optval)?"on":"off") ); - break; - case TCP_KEEPALIVE: - *(int*)optval = (int)sock->conn->pcb.tcp->keep_idle; - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, TCP_KEEPALIVE) = %d\n", - s, *(int *)optval)); - break; - -#if LWIP_TCP_KEEPALIVE - case TCP_KEEPIDLE: - *(int*)optval = (int)(sock->conn->pcb.tcp->keep_idle/1000); - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, TCP_KEEPIDLE) = %d\n", - s, *(int *)optval)); - break; - case TCP_KEEPINTVL: - *(int*)optval = (int)(sock->conn->pcb.tcp->keep_intvl/1000); - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, TCP_KEEPINTVL) = %d\n", - s, *(int *)optval)); - break; - case TCP_KEEPCNT: - *(int*)optval = (int)sock->conn->pcb.tcp->keep_cnt; - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, TCP_KEEPCNT) = %d\n", - s, *(int *)optval)); - break; -#endif /* LWIP_TCP_KEEPALIVE */ - default: - LWIP_ASSERT("unhandled optname", 0); - break; - } /* switch (optname) */ - break; -#endif /* LWIP_TCP */ -#if LWIP_UDP && LWIP_UDPLITE - /* Level: IPPROTO_UDPLITE */ - case IPPROTO_UDPLITE: - switch (optname) { - case UDPLITE_SEND_CSCOV: - *(int*)optval = sock->conn->pcb.udp->chksum_len_tx; - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_UDPLITE, UDPLITE_SEND_CSCOV) = %d\n", - s, (*(int*)optval)) ); - break; - case UDPLITE_RECV_CSCOV: - *(int*)optval = sock->conn->pcb.udp->chksum_len_rx; - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_UDPLITE, UDPLITE_RECV_CSCOV) = %d\n", - s, (*(int*)optval)) ); - break; - default: - LWIP_ASSERT("unhandled optname", 0); - break; - } /* switch (optname) */ - break; -#endif /* LWIP_UDP */ - default: - LWIP_ASSERT("unhandled level", 0); - break; - } /* switch (level) */ - sys_sem_signal(&sock->conn->op_completed); -} - -int -lwip_setsockopt(int s, int level, int optname, const void *optval, socklen_t optlen) -{ - struct lwip_sock *sock = get_socket(s); - err_t err = ERR_OK; - struct lwip_setgetsockopt_data data; - - if (!sock) { - return -1; - } - - if (NULL == optval) { - sock_set_errno(sock, EFAULT); - return -1; - } - - /* Do length and type checks for the various options first, to keep it readable. */ - switch (level) { - -/* Level: SOL_SOCKET */ - case SOL_SOCKET: - switch (optname) { - - case SO_BROADCAST: - /* UNIMPL case SO_DEBUG: */ - /* UNIMPL case SO_DONTROUTE: */ - case SO_KEEPALIVE: - /* UNIMPL case case SO_CONTIMEO: */ - /* UNIMPL case case SO_SNDTIMEO: */ -#if LWIP_SO_RCVTIMEO - case SO_RCVTIMEO: -#endif /* LWIP_SO_RCVTIMEO */ -#if LWIP_SO_RCVBUF - case SO_RCVBUF: -#endif /* LWIP_SO_RCVBUF */ - /* UNIMPL case SO_OOBINLINE: */ - /* UNIMPL case SO_SNDBUF: */ - /* UNIMPL case SO_RCVLOWAT: */ - /* UNIMPL case SO_SNDLOWAT: */ -#if SO_REUSE - case SO_REUSEADDR: - case SO_REUSEPORT: -#endif /* SO_REUSE */ - /* UNIMPL case SO_USELOOPBACK: */ - if (optlen < sizeof(int)) { - err = EINVAL; - } - break; - case SO_NO_CHECK: - if (optlen < sizeof(int)) { - err = EINVAL; - } -#if LWIP_UDP - if ((sock->conn->type != NETCONN_UDP) || - ((udp_flags(sock->conn->pcb.udp) & UDP_FLAGS_UDPLITE) != 0)) { - /* this flag is only available for UDP, not for UDP lite */ - err = EAFNOSUPPORT; - } -#endif /* LWIP_UDP */ - break; - default: - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, SOL_SOCKET, UNIMPL: optname=0x%x, ..)\n", - s, optname)); - err = ENOPROTOOPT; - } /* switch (optname) */ - break; - -/* Level: IPPROTO_IP */ - case IPPROTO_IP: - switch (optname) { - /* UNIMPL case IP_HDRINCL: */ - /* UNIMPL case IP_RCVDSTADDR: */ - /* UNIMPL case IP_RCVIF: */ - case IP_TTL: - case IP_TOS: - if (optlen < sizeof(int)) { - err = EINVAL; - } - break; -#if LWIP_IGMP - case IP_MULTICAST_TTL: - if (optlen < sizeof(u8_t)) { - err = EINVAL; - } - if (NETCONNTYPE_GROUP(sock->conn->type) != NETCONN_UDP) { - err = EAFNOSUPPORT; - } - break; - case IP_MULTICAST_IF: - if (optlen < sizeof(struct in_addr)) { - err = EINVAL; - } - if (NETCONNTYPE_GROUP(sock->conn->type) != NETCONN_UDP) { - err = EAFNOSUPPORT; - } - break; - case IP_MULTICAST_LOOP: - if (optlen < sizeof(u8_t)) { - err = EINVAL; - } - if (NETCONNTYPE_GROUP(sock->conn->type) != NETCONN_UDP) { - err = EAFNOSUPPORT; - } - break; - case IP_ADD_MEMBERSHIP: - case IP_DROP_MEMBERSHIP: - if (optlen < sizeof(struct ip_mreq)) { - err = EINVAL; - } - if (NETCONNTYPE_GROUP(sock->conn->type) != NETCONN_UDP) { - err = EAFNOSUPPORT; - } - break; -#endif /* LWIP_IGMP */ - default: - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_IP, UNIMPL: optname=0x%x, ..)\n", - s, optname)); - err = ENOPROTOOPT; - } /* switch (optname) */ - break; - -#if LWIP_TCP -/* Level: IPPROTO_TCP */ - case IPPROTO_TCP: - if (optlen < sizeof(int)) { - err = EINVAL; - break; - } - - /* If this is no TCP socket, ignore any options. */ - if (sock->conn->type != NETCONN_TCP) - return 0; - - switch (optname) { - case TCP_NODELAY: - case TCP_KEEPALIVE: -#if LWIP_TCP_KEEPALIVE - case TCP_KEEPIDLE: - case TCP_KEEPINTVL: - case TCP_KEEPCNT: -#endif /* LWIP_TCP_KEEPALIVE */ - break; - - default: - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, UNIMPL: optname=0x%x, ..)\n", - s, optname)); - err = ENOPROTOOPT; - } /* switch (optname) */ - break; -#endif /* LWIP_TCP */ -#if LWIP_UDP && LWIP_UDPLITE -/* Level: IPPROTO_UDPLITE */ - case IPPROTO_UDPLITE: - if (optlen < sizeof(int)) { - err = EINVAL; - break; - } - - /* If this is no UDP lite socket, ignore any options. */ - if (sock->conn->type != NETCONN_UDPLITE) - return 0; - - switch (optname) { - case UDPLITE_SEND_CSCOV: - case UDPLITE_RECV_CSCOV: - break; - - default: - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_UDPLITE, UNIMPL: optname=0x%x, ..)\n", - s, optname)); - err = ENOPROTOOPT; - } /* switch (optname) */ - break; -#endif /* LWIP_UDP && LWIP_UDPLITE */ -/* UNDEFINED LEVEL */ - default: - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, level=0x%x, UNIMPL: optname=0x%x, ..)\n", - s, level, optname)); - err = ENOPROTOOPT; - } /* switch (level) */ - - - if (err != ERR_OK) { - sock_set_errno(sock, err); - return -1; - } - - - /* Now do the actual option processing */ - data.sock = sock; -#ifdef LWIP_DEBUG - data.s = s; -#endif /* LWIP_DEBUG */ - data.level = level; - data.optname = optname; - data.optval = (void*)optval; - data.optlen = &optlen; - data.err = err; - tcpip_callback(lwip_setsockopt_internal, &data); - sys_arch_sem_wait(&sock->conn->op_completed, 0); - /* maybe lwip_setsockopt_internal has changed err */ - err = data.err; - - sock_set_errno(sock, err); - return err ? -1 : 0; -} - -static void -lwip_setsockopt_internal(void *arg) -{ - struct lwip_sock *sock; -#ifdef LWIP_DEBUG - int s; -#endif /* LWIP_DEBUG */ - int level, optname; - const void *optval; - struct lwip_setgetsockopt_data *data; - - LWIP_ASSERT("arg != NULL", arg != NULL); - - data = (struct lwip_setgetsockopt_data*)arg; - sock = data->sock; -#ifdef LWIP_DEBUG - s = data->s; -#endif /* LWIP_DEBUG */ - level = data->level; - optname = data->optname; - optval = data->optval; - - switch (level) { - -/* Level: SOL_SOCKET */ - case SOL_SOCKET: - switch (optname) { - - /* The option flags */ - case SO_BROADCAST: - /* UNIMPL case SO_DEBUG: */ - /* UNIMPL case SO_DONTROUTE: */ - case SO_KEEPALIVE: - /* UNIMPL case SO_OOBINCLUDE: */ -#if SO_REUSE - case SO_REUSEADDR: - case SO_REUSEPORT: -#endif /* SO_REUSE */ - /* UNIMPL case SO_USELOOPBACK: */ - if (*(int*)optval) { - sock->conn->pcb.ip->so_options |= optname; - } else { - sock->conn->pcb.ip->so_options &= ~optname; - } - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, SOL_SOCKET, optname=0x%x, ..) -> %s\n", - s, optname, (*(int*)optval?"on":"off"))); - break; -#if LWIP_SO_RCVTIMEO - case SO_RCVTIMEO: - netconn_set_recvtimeout(sock->conn, *(int*)optval); - break; -#endif /* LWIP_SO_RCVTIMEO */ -#if LWIP_SO_RCVBUF - case SO_RCVBUF: - netconn_set_recvbufsize(sock->conn, *(int*)optval); - break; -#endif /* LWIP_SO_RCVBUF */ -#if LWIP_UDP - case SO_NO_CHECK: - if (*(int*)optval) { - udp_setflags(sock->conn->pcb.udp, udp_flags(sock->conn->pcb.udp) | UDP_FLAGS_NOCHKSUM); - } else { - udp_setflags(sock->conn->pcb.udp, udp_flags(sock->conn->pcb.udp) & ~UDP_FLAGS_NOCHKSUM); - } - break; -#endif /* LWIP_UDP */ - default: - LWIP_ASSERT("unhandled optname", 0); - break; - } /* switch (optname) */ - break; - -/* Level: IPPROTO_IP */ - case IPPROTO_IP: - switch (optname) { - case IP_TTL: - sock->conn->pcb.ip->ttl = (u8_t)(*(int*)optval); - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_IP, IP_TTL, ..) -> %d\n", - s, sock->conn->pcb.ip->ttl)); - break; - case IP_TOS: - sock->conn->pcb.ip->tos = (u8_t)(*(int*)optval); - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_IP, IP_TOS, ..)-> %d\n", - s, sock->conn->pcb.ip->tos)); - break; -#if LWIP_IGMP - case IP_MULTICAST_TTL: - sock->conn->pcb.udp->ttl = (u8_t)(*(u8_t*)optval); - break; - case IP_MULTICAST_IF: - inet_addr_to_ipaddr(&sock->conn->pcb.udp->multicast_ip, (struct in_addr*)optval); - break; - case IP_MULTICAST_LOOP: - if (*(u8_t*)optval) { - udp_setflags(sock->conn->pcb.udp, udp_flags(sock->conn->pcb.udp) | UDP_FLAGS_MULTICAST_LOOP); - } else { - udp_setflags(sock->conn->pcb.udp, udp_flags(sock->conn->pcb.udp) & ~UDP_FLAGS_MULTICAST_LOOP); - } - break; - case IP_ADD_MEMBERSHIP: - case IP_DROP_MEMBERSHIP: - { - /* If this is a TCP or a RAW socket, ignore these options. */ - struct ip_mreq *imr = (struct ip_mreq *)optval; - ip_addr_t if_addr; - ip_addr_t multi_addr; - inet_addr_to_ipaddr(&if_addr, &imr->imr_interface); - inet_addr_to_ipaddr(&multi_addr, &imr->imr_multiaddr); - if(optname == IP_ADD_MEMBERSHIP){ - data->err = igmp_joingroup(&if_addr, &multi_addr); - } else { - data->err = igmp_leavegroup(&if_addr, &multi_addr); - } - if(data->err != ERR_OK) { - data->err = EADDRNOTAVAIL; - } - } - break; -#endif /* LWIP_IGMP */ - default: - LWIP_ASSERT("unhandled optname", 0); - break; - } /* switch (optname) */ - break; - -#if LWIP_TCP -/* Level: IPPROTO_TCP */ - case IPPROTO_TCP: - switch (optname) { - case TCP_NODELAY: - if (*(int*)optval) { - tcp_nagle_disable(sock->conn->pcb.tcp); - } else { - tcp_nagle_enable(sock->conn->pcb.tcp); - } - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, TCP_NODELAY) -> %s\n", - s, (*(int *)optval)?"on":"off") ); - break; - case TCP_KEEPALIVE: - sock->conn->pcb.tcp->keep_idle = (u32_t)(*(int*)optval); - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, TCP_KEEPALIVE) -> %"U32_F"\n", - s, sock->conn->pcb.tcp->keep_idle)); - break; - -#if LWIP_TCP_KEEPALIVE - case TCP_KEEPIDLE: - sock->conn->pcb.tcp->keep_idle = 1000*(u32_t)(*(int*)optval); - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, TCP_KEEPIDLE) -> %"U32_F"\n", - s, sock->conn->pcb.tcp->keep_idle)); - break; - case TCP_KEEPINTVL: - sock->conn->pcb.tcp->keep_intvl = 1000*(u32_t)(*(int*)optval); - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, TCP_KEEPINTVL) -> %"U32_F"\n", - s, sock->conn->pcb.tcp->keep_intvl)); - break; - case TCP_KEEPCNT: - sock->conn->pcb.tcp->keep_cnt = (u32_t)(*(int*)optval); - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, TCP_KEEPCNT) -> %"U32_F"\n", - s, sock->conn->pcb.tcp->keep_cnt)); - break; -#endif /* LWIP_TCP_KEEPALIVE */ - default: - LWIP_ASSERT("unhandled optname", 0); - break; - } /* switch (optname) */ - break; -#endif /* LWIP_TCP*/ -#if LWIP_UDP && LWIP_UDPLITE - /* Level: IPPROTO_UDPLITE */ - case IPPROTO_UDPLITE: - switch (optname) { - case UDPLITE_SEND_CSCOV: - if ((*(int*)optval != 0) && ((*(int*)optval < 8)) || (*(int*)optval > 0xffff)) { - /* don't allow illegal values! */ - sock->conn->pcb.udp->chksum_len_tx = 8; - } else { - sock->conn->pcb.udp->chksum_len_tx = (u16_t)*(int*)optval; - } - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_UDPLITE, UDPLITE_SEND_CSCOV) -> %d\n", - s, (*(int*)optval)) ); - break; - case UDPLITE_RECV_CSCOV: - if ((*(int*)optval != 0) && ((*(int*)optval < 8)) || (*(int*)optval > 0xffff)) { - /* don't allow illegal values! */ - sock->conn->pcb.udp->chksum_len_rx = 8; - } else { - sock->conn->pcb.udp->chksum_len_rx = (u16_t)*(int*)optval; - } - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_UDPLITE, UDPLITE_RECV_CSCOV) -> %d\n", - s, (*(int*)optval)) ); - break; - default: - LWIP_ASSERT("unhandled optname", 0); - break; - } /* switch (optname) */ - break; -#endif /* LWIP_UDP */ - default: - LWIP_ASSERT("unhandled level", 0); - break; - } /* switch (level) */ - sys_sem_signal(&sock->conn->op_completed); -} - -int -lwip_ioctl(int s, long cmd, void *argp) -{ - struct lwip_sock *sock = get_socket(s); - u8_t val; -#if LWIP_SO_RCVBUF - u16_t buflen = 0; - s16_t recv_avail; -#endif /* LWIP_SO_RCVBUF */ - - if (!sock) { - return -1; - } - - switch (cmd) { -#if LWIP_SO_RCVBUF - case FIONREAD: - if (!argp) { - sock_set_errno(sock, EINVAL); - return -1; - } - - SYS_ARCH_GET(sock->conn->recv_avail, recv_avail); - if (recv_avail < 0) { - recv_avail = 0; - } - *((u16_t*)argp) = (u16_t)recv_avail; - - /* Check if there is data left from the last recv operation. /maq 041215 */ - if (sock->lastdata) { - struct pbuf *p = (struct pbuf *)sock->lastdata; - if (netconn_type(sock->conn) != NETCONN_TCP) { - p = ((struct netbuf *)p)->p; - } - buflen = p->tot_len; - buflen -= sock->lastoffset; - - *((u16_t*)argp) += buflen; - } - - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_ioctl(%d, FIONREAD, %p) = %"U16_F"\n", s, argp, *((u16_t*)argp))); - sock_set_errno(sock, 0); - return 0; -#endif /* LWIP_SO_RCVBUF */ - - case FIONBIO: - val = 0; - if (argp && *(u32_t*)argp) { - val = 1; - } - netconn_set_nonblocking(sock->conn, val); - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_ioctl(%d, FIONBIO, %d)\n", s, val)); - sock_set_errno(sock, 0); - return 0; - - default: - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_ioctl(%d, UNIMPL: 0x%lx, %p)\n", s, cmd, argp)); - sock_set_errno(sock, ENOSYS); /* not yet implemented */ - return -1; - } /* switch (cmd) */ -} - -/** A minimal implementation of fcntl. - * Currently only the commands F_GETFL and F_SETFL are implemented. - * Only the flag O_NONBLOCK is implemented. - */ -int -lwip_fcntl(int s, int cmd, int val) -{ - struct lwip_sock *sock = get_socket(s); - int ret = -1; - - if (!sock || !sock->conn) { - return -1; - } - - switch (cmd) { - case F_GETFL: - ret = netconn_is_nonblocking(sock->conn) ? O_NONBLOCK : 0; - break; - case F_SETFL: - if ((val & ~O_NONBLOCK) == 0) { - /* only O_NONBLOCK, all other bits are zero */ - netconn_set_nonblocking(sock->conn, val & O_NONBLOCK); - ret = 0; - } - break; - default: - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_fcntl(%d, UNIMPL: %d, %d)\n", s, cmd, val)); - break; - } - return ret; -} - -#endif /* LWIP_SOCKET */ diff --git a/features/net/FEATURE_IPV4/lwip-interface/lwip/core/lwip_dns.c b/features/net/FEATURE_IPV4/lwip-interface/lwip/core/lwip_dns.c deleted file mode 100644 index d63361226f..0000000000 --- a/features/net/FEATURE_IPV4/lwip-interface/lwip/core/lwip_dns.c +++ /dev/null @@ -1,970 +0,0 @@ -/** - * @file - * DNS - host name to IP address resolver. - * - */ - -/** - - * This file implements a DNS host name to IP address resolver. - - * Port to lwIP from uIP - * by Jim Pettinato April 2007 - - * 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. - * - * - * DNS.C - * - * The lwIP DNS resolver functions are used to lookup a host name and - * map it to a numerical IP address. It maintains a list of resolved - * hostnames that can be queried with the dns_lookup() function. - * New hostnames can be resolved using the dns_query() function. - * - * The lwIP version of the resolver also adds a non-blocking version of - * gethostbyname() that will work with a raw API application. This function - * checks for an IP address string first and converts it if it is valid. - * gethostbyname() then does a dns_lookup() to see if the name is - * already in the table. If so, the IP is returned. If not, a query is - * issued and the function returns with a ERR_INPROGRESS status. The app - * using the dns client must then go into a waiting state. - * - * Once a hostname has been resolved (or found to be non-existent), - * the resolver code calls a specified callback function (which - * must be implemented by the module that uses the resolver). - */ - -/*----------------------------------------------------------------------------- - * RFC 1035 - Domain names - implementation and specification - * RFC 2181 - Clarifications to the DNS Specification - *----------------------------------------------------------------------------*/ - -/** @todo: define good default values (rfc compliance) */ -/** @todo: improve answer parsing, more checkings... */ -/** @todo: check RFC1035 - 7.3. Processing responses */ - -/*----------------------------------------------------------------------------- - * Includes - *----------------------------------------------------------------------------*/ - -#include "lwip/opt.h" - -#if LWIP_DNS /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/udp.h" -#include "lwip/mem.h" -#include "lwip/memp.h" -#include "lwip/dns.h" - -#include - -/** DNS server IP address */ -#ifndef DNS_SERVER_ADDRESS -#define DNS_SERVER_ADDRESS(ipaddr) (ip4_addr_set_u32(ipaddr, ipaddr_addr("208.67.222.222"))) /* resolver1.opendns.com */ -#endif - -/** DNS server port address */ -#ifndef DNS_SERVER_PORT -#define DNS_SERVER_PORT 53 -#endif - -/** DNS maximum number of retries when asking for a name, before "timeout". */ -#ifndef DNS_MAX_RETRIES -#define DNS_MAX_RETRIES 4 -#endif - -/** DNS resource record max. TTL (one week as default) */ -#ifndef DNS_MAX_TTL -#define DNS_MAX_TTL 604800 -#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. - No packing needed: only used locally on the stack. */ -struct dns_query { - /* DNS query record starts with either a domain name or a pointer - to a name already present somewhere in the packet. */ - u16_t type; - u16_t cls; -}; -#define SIZEOF_DNS_QUERY 4 - -/** DNS answer message structure. - No packing needed: only used locally on the stack. */ -struct dns_answer { - /* DNS answer record starts with either a domain name or a pointer - to a name already present somewhere in the packet. */ - u16_t type; - u16_t cls; - u32_t ttl; - u16_t len; -}; -#define SIZEOF_DNS_ANSWER 10 - -/** DNS table entry */ -struct dns_table_entry { - u8_t state; - u8_t numdns; - u8_t tmr; - u8_t retries; - u8_t seqno; - u8_t err; - u32_t ttl; - char name[DNS_MAX_NAME_LENGTH]; - ip_addr_t ipaddr; - /* pointer to callback on DNS query done */ - dns_found_callback found; - void *arg; -}; - -#if DNS_LOCAL_HOSTLIST - -#if DNS_LOCAL_HOSTLIST_IS_DYNAMIC -/** Local host-list. For hostnames in this list, no - * external name resolution is performed */ -static struct local_hostlist_entry *local_hostlist_dynamic; -#else /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC */ - -/** Defining this allows the local_hostlist_static to be placed in a different - * linker section (e.g. FLASH) */ -#ifndef DNS_LOCAL_HOSTLIST_STORAGE_PRE -#define DNS_LOCAL_HOSTLIST_STORAGE_PRE static -#endif /* DNS_LOCAL_HOSTLIST_STORAGE_PRE */ -/** Defining this allows the local_hostlist_static to be placed in a different - * linker section (e.g. FLASH) */ -#ifndef DNS_LOCAL_HOSTLIST_STORAGE_POST -#define DNS_LOCAL_HOSTLIST_STORAGE_POST -#endif /* DNS_LOCAL_HOSTLIST_STORAGE_POST */ -DNS_LOCAL_HOSTLIST_STORAGE_PRE struct local_hostlist_entry local_hostlist_static[] - DNS_LOCAL_HOSTLIST_STORAGE_POST = DNS_LOCAL_HOSTLIST_INIT; - -#endif /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC */ - -static void dns_init_local(); -#endif /* DNS_LOCAL_HOSTLIST */ - - -/* forward declarations */ -static void dns_recv(void *s, struct udp_pcb *pcb, struct pbuf *p, ip_addr_t *addr, u16_t port); -static void dns_check_entries(void); - -/*----------------------------------------------------------------------------- - * Globales - *----------------------------------------------------------------------------*/ - -/* DNS variables */ -static struct udp_pcb *dns_pcb; -static u8_t dns_seqno; -static struct dns_table_entry dns_table[DNS_TABLE_SIZE]; -static ip_addr_t dns_servers[DNS_MAX_SERVERS]; -/** Contiguous buffer for processing responses */ -static u8_t dns_payload_buffer[LWIP_MEM_ALIGN_BUFFER(DNS_MSG_SIZE)]; -static u8_t* dns_payload; - -/** - * Initialize the resolver: set up the UDP pcb and configure the default server - * (DNS_SERVER_ADDRESS). - */ -void -dns_init() -{ - ip_addr_t dnsserver; - - dns_payload = (u8_t *)LWIP_MEM_ALIGN(dns_payload_buffer); - - /* initialize default DNS server address */ - DNS_SERVER_ADDRESS(&dnsserver); - - LWIP_DEBUGF(DNS_DEBUG, ("dns_init: initializing\n")); - - /* if dns client not yet initialized... */ - if (dns_pcb == NULL) { - dns_pcb = udp_new(); - - if (dns_pcb != NULL) { - /* initialize DNS table not needed (initialized to zero since it is a - * global variable) */ - LWIP_ASSERT("For implicit initialization to work, DNS_STATE_UNUSED needs to be 0", - DNS_STATE_UNUSED == 0); - - /* initialize DNS client */ - udp_bind(dns_pcb, IP_ADDR_ANY, 0); - udp_recv(dns_pcb, dns_recv, NULL); - - /* initialize default DNS primary server */ - dns_setserver(0, &dnsserver); - } - } -#if DNS_LOCAL_HOSTLIST - dns_init_local(); -#endif -} - -/** - * Initialize one of the DNS servers. - * - * @param numdns the index of the DNS server to set must be < DNS_MAX_SERVERS - * @param dnsserver IP address of the DNS server to set - */ -void -dns_setserver(u8_t numdns, ip_addr_t *dnsserver) -{ - if ((numdns < DNS_MAX_SERVERS) && (dns_pcb != NULL) && - (dnsserver != NULL) && !ip_addr_isany(dnsserver)) { - dns_servers[numdns] = (*dnsserver); - } -} - -/** - * Obtain one of the currently configured DNS server. - * - * @param numdns the index of the DNS server - * @return IP address of the indexed DNS server or "ip_addr_any" if the DNS - * server has not been configured. - */ -ip_addr_t -dns_getserver(u8_t numdns) -{ - if (numdns < DNS_MAX_SERVERS) { - return dns_servers[numdns]; - } else { - return *IP_ADDR_ANY; - } -} - -/** - * The DNS resolver client timer - handle retries and timeouts and should - * be called every DNS_TMR_INTERVAL milliseconds (every second by default). - */ -void -dns_tmr(void) -{ - if (dns_pcb != NULL) { - LWIP_DEBUGF(DNS_DEBUG, ("dns_tmr: dns_check_entries\n")); - dns_check_entries(); - } -} - -#if DNS_LOCAL_HOSTLIST -static void -dns_init_local() -{ -#if DNS_LOCAL_HOSTLIST_IS_DYNAMIC && defined(DNS_LOCAL_HOSTLIST_INIT) - int i; - struct local_hostlist_entry *entry; - /* Dynamic: copy entries from DNS_LOCAL_HOSTLIST_INIT to list */ - struct local_hostlist_entry local_hostlist_init[] = DNS_LOCAL_HOSTLIST_INIT; - size_t namelen; - for (i = 0; i < sizeof(local_hostlist_init) / sizeof(struct local_hostlist_entry); i++) { - struct local_hostlist_entry *init_entry = &local_hostlist_init[i]; - LWIP_ASSERT("invalid host name (NULL)", init_entry->name != NULL); - namelen = strlen(init_entry->name); - LWIP_ASSERT("namelen <= DNS_LOCAL_HOSTLIST_MAX_NAMELEN", namelen <= DNS_LOCAL_HOSTLIST_MAX_NAMELEN); - entry = (struct local_hostlist_entry *)memp_malloc(MEMP_LOCALHOSTLIST); - LWIP_ASSERT("mem-error in dns_init_local", entry != NULL); - if (entry != NULL) { - entry->name = (char*)entry + sizeof(struct local_hostlist_entry); - MEMCPY((char*)entry->name, init_entry->name, namelen); - ((char*)entry->name)[namelen] = 0; - entry->addr = init_entry->addr; - entry->next = local_hostlist_dynamic; - local_hostlist_dynamic = entry; - } - } -#endif /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC && defined(DNS_LOCAL_HOSTLIST_INIT) */ -} - -/** - * Scans the local host-list for a hostname. - * - * @param hostname Hostname to look for in the local host-list - * @return The first IP address for the hostname in the local host-list or - * IPADDR_NONE if not found. - */ -static u32_t -dns_lookup_local(const char *hostname) -{ -#if DNS_LOCAL_HOSTLIST_IS_DYNAMIC - struct local_hostlist_entry *entry = local_hostlist_dynamic; - while(entry != NULL) { - if(strcmp(entry->name, hostname) == 0) { - return ip4_addr_get_u32(&entry->addr); - } - entry = entry->next; - } -#else /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC */ - int i; - for (i = 0; i < sizeof(local_hostlist_static) / sizeof(struct local_hostlist_entry); i++) { - if(strcmp(local_hostlist_static[i].name, hostname) == 0) { - return ip4_addr_get_u32(&local_hostlist_static[i].addr); - } - } -#endif /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC */ - return IPADDR_NONE; -} - -#if DNS_LOCAL_HOSTLIST_IS_DYNAMIC -/** Remove all entries from the local host-list for a specific hostname - * and/or IP addess - * - * @param hostname hostname for which entries shall be removed from the local - * host-list - * @param addr address for which entries shall be removed from the local host-list - * @return the number of removed entries - */ -int -dns_local_removehost(const char *hostname, const ip_addr_t *addr) -{ - int removed = 0; - struct local_hostlist_entry *entry = local_hostlist_dynamic; - struct local_hostlist_entry *last_entry = NULL; - while (entry != NULL) { - if (((hostname == NULL) || !strcmp(entry->name, hostname)) && - ((addr == NULL) || ip_addr_cmp(&entry->addr, addr))) { - struct local_hostlist_entry *free_entry; - if (last_entry != NULL) { - last_entry->next = entry->next; - } else { - local_hostlist_dynamic = entry->next; - } - free_entry = entry; - entry = entry->next; - memp_free(MEMP_LOCALHOSTLIST, free_entry); - removed++; - } else { - last_entry = entry; - entry = entry->next; - } - } - return removed; -} - -/** - * Add a hostname/IP address pair to the local host-list. - * Duplicates are not checked. - * - * @param hostname hostname of the new entry - * @param addr IP address of the new entry - * @return ERR_OK if succeeded or ERR_MEM on memory error - */ -err_t -dns_local_addhost(const char *hostname, const ip_addr_t *addr) -{ - struct local_hostlist_entry *entry; - size_t namelen; - LWIP_ASSERT("invalid host name (NULL)", hostname != NULL); - namelen = strlen(hostname); - LWIP_ASSERT("namelen <= DNS_LOCAL_HOSTLIST_MAX_NAMELEN", namelen <= DNS_LOCAL_HOSTLIST_MAX_NAMELEN); - entry = (struct local_hostlist_entry *)memp_malloc(MEMP_LOCALHOSTLIST); - if (entry == NULL) { - return ERR_MEM; - } - entry->name = (char*)entry + sizeof(struct local_hostlist_entry); - MEMCPY((char*)entry->name, hostname, namelen); - ((char*)entry->name)[namelen] = 0; - ip_addr_copy(entry->addr, *addr); - entry->next = local_hostlist_dynamic; - local_hostlist_dynamic = entry; - return ERR_OK; -} -#endif /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC*/ -#endif /* DNS_LOCAL_HOSTLIST */ - -/** - * Look up a hostname in the array of known hostnames. - * - * @note This function only looks in the internal array of known - * hostnames, it does not send out a query for the hostname if none - * was found. The function dns_enqueue() can be used to send a query - * for a hostname. - * - * @param name the hostname to look up - * @return the hostname's IP address, as u32_t (instead of ip_addr_t to - * better check for failure: != IPADDR_NONE) or IPADDR_NONE if the hostname - * was not found in the cached dns_table. - */ -static u32_t -dns_lookup(const char *name) -{ - u8_t i; -#if DNS_LOCAL_HOSTLIST || defined(DNS_LOOKUP_LOCAL_EXTERN) - u32_t addr; -#endif /* DNS_LOCAL_HOSTLIST || defined(DNS_LOOKUP_LOCAL_EXTERN) */ -#if DNS_LOCAL_HOSTLIST - if ((addr = dns_lookup_local(name)) != IPADDR_NONE) { - return addr; - } -#endif /* DNS_LOCAL_HOSTLIST */ -#ifdef DNS_LOOKUP_LOCAL_EXTERN - if((addr = DNS_LOOKUP_LOCAL_EXTERN(name)) != IPADDR_NONE) { - return addr; - } -#endif /* DNS_LOOKUP_LOCAL_EXTERN */ - - /* Walk through name list, return entry if found. If not, return NULL. */ - for (i = 0; i < DNS_TABLE_SIZE; ++i) { - if ((dns_table[i].state == DNS_STATE_DONE) && - (strcmp(name, dns_table[i].name) == 0)) { - LWIP_DEBUGF(DNS_DEBUG, ("dns_lookup: \"%s\": found = ", name)); - ip_addr_debug_print(DNS_DEBUG, &(dns_table[i].ipaddr)); - LWIP_DEBUGF(DNS_DEBUG, ("\n")); - return ip4_addr_get_u32(&dns_table[i].ipaddr); - } - } - - return IPADDR_NONE; -} - -#if DNS_DOES_NAME_CHECK -/** - * Compare the "dotted" name "query" with the encoded name "response" - * to make sure an answer from the DNS server matches the current dns_table - * entry (otherwise, answers might arrive late for hostname not on the list - * any more). - * - * @param query hostname (not encoded) from the dns_table - * @param response encoded hostname in the DNS response - * @return 0: names equal; 1: names differ - */ -static u8_t -dns_compare_name(unsigned char *query, unsigned char *response) -{ - unsigned char n; - - do { - n = *response++; - /** @see RFC 1035 - 4.1.4. Message compression */ - if ((n & 0xc0) == 0xc0) { - /* Compressed name */ - break; - } else { - /* Not compressed name */ - while (n > 0) { - if ((*query) != (*response)) { - return 1; - } - ++response; - ++query; - --n; - }; - ++query; - } - } while (*response != 0); - - return 0; -} -#endif /* DNS_DOES_NAME_CHECK */ - -/** - * Walk through a compact encoded DNS name and return the end of the name. - * - * @param query encoded DNS name in the DNS server response - * @return end of the name - */ -static unsigned char * -dns_parse_name(unsigned char *query) -{ - unsigned char n; - - do { - n = *query++; - /** @see RFC 1035 - 4.1.4. Message compression */ - if ((n & 0xc0) == 0xc0) { - /* Compressed name */ - break; - } else { - /* Not compressed name */ - while (n > 0) { - ++query; - --n; - }; - } - } while (*query != 0); - - return query + 1; -} - -/** - * Send a DNS query packet. - * - * @param numdns index of the DNS server in the dns_servers table - * @param name hostname to query - * @param id index of the hostname in dns_table, used as transaction ID in the - * DNS query packet - * @return ERR_OK if packet is sent; an err_t indicating the problem otherwise - */ -static err_t -dns_send(u8_t numdns, const char* name, u8_t id) -{ - err_t err; - struct dns_hdr *hdr; - struct dns_query qry; - struct pbuf *p; - char *query, *nptr; - const char *pHostname; - u8_t n; - - LWIP_DEBUGF(DNS_DEBUG, ("dns_send: dns_servers[%"U16_F"] \"%s\": request\n", - (u16_t)(numdns), name)); - LWIP_ASSERT("dns server out of array", numdns < DNS_MAX_SERVERS); - LWIP_ASSERT("dns server has no IP address set", !ip_addr_isany(&dns_servers[numdns])); - - /* if here, we have either a new query or a retry on a previous query to process */ - p = pbuf_alloc(PBUF_TRANSPORT, SIZEOF_DNS_HDR + DNS_MAX_NAME_LENGTH + - SIZEOF_DNS_QUERY, PBUF_RAM); - if (p != NULL) { - LWIP_ASSERT("pbuf must be in one piece", p->next == NULL); - /* fill dns header */ - hdr = (struct dns_hdr*)p->payload; - memset(hdr, 0, SIZEOF_DNS_HDR); - hdr->id = htons(id); - hdr->flags1 = DNS_FLAG1_RD; - hdr->numquestions = PP_HTONS(1); - query = (char*)hdr + SIZEOF_DNS_HDR; - pHostname = name; - --pHostname; - - /* convert hostname into suitable query format. */ - do { - ++pHostname; - nptr = query; - ++query; - for(n = 0; *pHostname != '.' && *pHostname != 0; ++pHostname) { - *query = *pHostname; - ++query; - ++n; - } - *nptr = n; - } while(*pHostname != 0); - *query++='\0'; - - /* fill dns query */ - qry.type = PP_HTONS(DNS_RRTYPE_A); - qry.cls = PP_HTONS(DNS_RRCLASS_IN); - SMEMCPY(query, &qry, SIZEOF_DNS_QUERY); - - /* resize pbuf to the exact dns query */ - pbuf_realloc(p, (u16_t)((query + SIZEOF_DNS_QUERY) - ((char*)(p->payload)))); - - /* connect to the server for faster receiving */ - udp_connect(dns_pcb, &dns_servers[numdns], DNS_SERVER_PORT); - /* send dns packet */ - err = udp_sendto(dns_pcb, p, &dns_servers[numdns], DNS_SERVER_PORT); - - /* free pbuf */ - pbuf_free(p); - } else { - err = ERR_MEM; - } - - return err; -} - -/** - * dns_check_entry() - see if pEntry has not yet been queried and, if so, sends out a query. - * Check an entry in the dns_table: - * - send out query for new entries - * - retry old pending entries on timeout (also with different servers) - * - remove completed entries from the table if their TTL has expired - * - * @param i index of the dns_table entry to check - */ -static void -dns_check_entry(u8_t i) -{ - err_t err; - struct dns_table_entry *pEntry = &dns_table[i]; - - LWIP_ASSERT("array index out of bounds", i < DNS_TABLE_SIZE); - - switch(pEntry->state) { - - case DNS_STATE_NEW: { - /* initialize new entry */ - pEntry->state = DNS_STATE_ASKING; - pEntry->numdns = 0; - pEntry->tmr = 1; - pEntry->retries = 0; - - /* send DNS packet for this entry */ - err = dns_send(pEntry->numdns, pEntry->name, i); - if (err != ERR_OK) { - LWIP_DEBUGF(DNS_DEBUG | LWIP_DBG_LEVEL_WARNING, - ("dns_send returned error: %s\n", lwip_strerr(err))); - } - break; - } - - case DNS_STATE_ASKING: { - if (--pEntry->tmr == 0) { - if (++pEntry->retries == DNS_MAX_RETRIES) { - if ((pEntry->numdns+1numdns+1])) { - /* change of server */ - pEntry->numdns++; - pEntry->tmr = 1; - pEntry->retries = 0; - break; - } else { - LWIP_DEBUGF(DNS_DEBUG, ("dns_check_entry: \"%s\": timeout\n", pEntry->name)); - /* call specified callback function if provided */ - if (pEntry->found) - (*pEntry->found)(pEntry->name, NULL, pEntry->arg); - /* flush this entry */ - pEntry->state = DNS_STATE_UNUSED; - pEntry->found = NULL; - break; - } - } - - /* wait longer for the next retry */ - pEntry->tmr = pEntry->retries; - - /* send DNS packet for this entry */ - err = dns_send(pEntry->numdns, pEntry->name, i); - if (err != ERR_OK) { - LWIP_DEBUGF(DNS_DEBUG | LWIP_DBG_LEVEL_WARNING, - ("dns_send returned error: %s\n", lwip_strerr(err))); - } - } - break; - } - - case DNS_STATE_DONE: { - /* if the time to live is nul */ - if (--pEntry->ttl == 0) { - LWIP_DEBUGF(DNS_DEBUG, ("dns_check_entry: \"%s\": flush\n", pEntry->name)); - /* flush this entry */ - pEntry->state = DNS_STATE_UNUSED; - pEntry->found = NULL; - } - break; - } - case DNS_STATE_UNUSED: - /* nothing to do */ - break; - default: - LWIP_ASSERT("unknown dns_table entry state:", 0); - break; - } -} - -/** - * Call dns_check_entry for each entry in dns_table - check all entries. - */ -static void -dns_check_entries(void) -{ - u8_t i; - - for (i = 0; i < DNS_TABLE_SIZE; ++i) { - dns_check_entry(i); - } -} - -/** - * Receive input function for DNS response packets arriving for the dns UDP pcb. - * - * @params see udp.h - */ -static void -dns_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, ip_addr_t *addr, u16_t port) -{ - u16_t i; - char *pHostname; - struct dns_hdr *hdr; - struct dns_answer ans; - struct dns_table_entry *pEntry; - u16_t nquestions, nanswers; - - LWIP_UNUSED_ARG(arg); - LWIP_UNUSED_ARG(pcb); - LWIP_UNUSED_ARG(addr); - LWIP_UNUSED_ARG(port); - - /* is the dns message too big ? */ - if (p->tot_len > DNS_MSG_SIZE) { - LWIP_DEBUGF(DNS_DEBUG, ("dns_recv: pbuf too big\n")); - /* free pbuf and return */ - goto memerr; - } - - /* is the dns message big enough ? */ - if (p->tot_len < (SIZEOF_DNS_HDR + SIZEOF_DNS_QUERY + SIZEOF_DNS_ANSWER)) { - LWIP_DEBUGF(DNS_DEBUG, ("dns_recv: pbuf too small\n")); - /* free pbuf and return */ - goto memerr; - } - - /* copy dns payload inside static buffer for processing */ - if (pbuf_copy_partial(p, dns_payload, p->tot_len, 0) == p->tot_len) { - /* The ID in the DNS header should be our entry into the name table. */ - hdr = (struct dns_hdr*)dns_payload; - i = htons(hdr->id); - if (i < DNS_TABLE_SIZE) { - pEntry = &dns_table[i]; - if(pEntry->state == DNS_STATE_ASKING) { - /* This entry is now completed. */ - pEntry->state = DNS_STATE_DONE; - pEntry->err = hdr->flags2 & DNS_FLAG2_ERR_MASK; - - /* We only care about the question(s) and the answers. The authrr - and the extrarr are simply discarded. */ - nquestions = htons(hdr->numquestions); - nanswers = htons(hdr->numanswers); - - /* Check for error. If so, call callback to inform. */ - if (((hdr->flags1 & DNS_FLAG1_RESPONSE) == 0) || (pEntry->err != 0) || (nquestions != 1)) { - LWIP_DEBUGF(DNS_DEBUG, ("dns_recv: \"%s\": error in flags\n", pEntry->name)); - /* call callback to indicate error, clean up memory and return */ - goto responseerr; - } - -#if DNS_DOES_NAME_CHECK - /* Check if the name in the "question" part match with the name in the entry. */ - if (dns_compare_name((unsigned char *)(pEntry->name), (unsigned char *)dns_payload + SIZEOF_DNS_HDR) != 0) { - LWIP_DEBUGF(DNS_DEBUG, ("dns_recv: \"%s\": response not match to query\n", pEntry->name)); - /* call callback to indicate error, clean up memory and return */ - goto responseerr; - } -#endif /* DNS_DOES_NAME_CHECK */ - - /* Skip the name in the "question" part */ - pHostname = (char *) dns_parse_name((unsigned char *)dns_payload + SIZEOF_DNS_HDR) + SIZEOF_DNS_QUERY; - - while (nanswers > 0) { - /* skip answer resource record's host name */ - pHostname = (char *) dns_parse_name((unsigned char *)pHostname); - - /* Check for IP address type and Internet class. Others are discarded. */ - SMEMCPY(&ans, pHostname, SIZEOF_DNS_ANSWER); - if((ans.type == PP_HTONS(DNS_RRTYPE_A)) && (ans.cls == PP_HTONS(DNS_RRCLASS_IN)) && - (ans.len == PP_HTONS(sizeof(ip_addr_t))) ) { - /* read the answer resource record's TTL, and maximize it if needed */ - pEntry->ttl = ntohl(ans.ttl); - if (pEntry->ttl > DNS_MAX_TTL) { - pEntry->ttl = DNS_MAX_TTL; - } - /* read the IP address after answer resource record's header */ - SMEMCPY(&(pEntry->ipaddr), (pHostname+SIZEOF_DNS_ANSWER), sizeof(ip_addr_t)); - LWIP_DEBUGF(DNS_DEBUG, ("dns_recv: \"%s\": response = ", pEntry->name)); - ip_addr_debug_print(DNS_DEBUG, (&(pEntry->ipaddr))); - LWIP_DEBUGF(DNS_DEBUG, ("\n")); - /* call specified callback function if provided */ - if (pEntry->found) { - (*pEntry->found)(pEntry->name, &pEntry->ipaddr, pEntry->arg); - } - /* deallocate memory and return */ - goto memerr; - } else { - pHostname = pHostname + SIZEOF_DNS_ANSWER + htons(ans.len); - } - --nanswers; - } - LWIP_DEBUGF(DNS_DEBUG, ("dns_recv: \"%s\": error in response\n", pEntry->name)); - /* call callback to indicate error, clean up memory and return */ - goto responseerr; - } - } - } - - /* deallocate memory and return */ - goto memerr; - -responseerr: - /* ERROR: call specified callback function with NULL as name to indicate an error */ - if (pEntry->found) { - (*pEntry->found)(pEntry->name, NULL, pEntry->arg); - } - /* flush this entry */ - pEntry->state = DNS_STATE_UNUSED; - pEntry->found = NULL; - -memerr: - /* free pbuf */ - pbuf_free(p); - return; -} - -/** - * Queues a new hostname to resolve and sends out a DNS query for that hostname - * - * @param name the hostname that is to be queried - * @param found a callback founction to be called on success, failure or timeout - * @param callback_arg argument to pass to the callback function - * @return @return a err_t return code. - */ -static err_t -dns_enqueue(const char *name, dns_found_callback found, void *callback_arg) -{ - u8_t i; - u8_t lseq, lseqi; - struct dns_table_entry *pEntry = NULL; - size_t namelen; - - /* search an unused entry, or the oldest one */ - lseq = lseqi = 0; - for (i = 0; i < DNS_TABLE_SIZE; ++i) { - pEntry = &dns_table[i]; - /* is it an unused entry ? */ - if (pEntry->state == DNS_STATE_UNUSED) - break; - - /* check if this is the oldest completed entry */ - if (pEntry->state == DNS_STATE_DONE) { - if ((dns_seqno - pEntry->seqno) > lseq) { - lseq = dns_seqno - pEntry->seqno; - lseqi = i; - } - } - } - - /* if we don't have found an unused entry, use the oldest completed one */ - if (i == DNS_TABLE_SIZE) { - if ((lseqi >= DNS_TABLE_SIZE) || (dns_table[lseqi].state != DNS_STATE_DONE)) { - /* no entry can't be used now, table is full */ - LWIP_DEBUGF(DNS_DEBUG, ("dns_enqueue: \"%s\": DNS entries table is full\n", name)); - return ERR_MEM; - } else { - /* use the oldest completed one */ - i = lseqi; - pEntry = &dns_table[i]; - } - } - - /* use this entry */ - LWIP_DEBUGF(DNS_DEBUG, ("dns_enqueue: \"%s\": use DNS entry %"U16_F"\n", name, (u16_t)(i))); - - /* fill the entry */ - pEntry->state = DNS_STATE_NEW; - pEntry->seqno = dns_seqno++; - pEntry->found = found; - pEntry->arg = callback_arg; - namelen = LWIP_MIN(strlen(name), DNS_MAX_NAME_LENGTH-1); - MEMCPY(pEntry->name, name, namelen); - pEntry->name[namelen] = 0; - - /* force to send query without waiting timer */ - dns_check_entry(i); - - /* dns query is enqueued */ - return ERR_INPROGRESS; -} - -/** - * Resolve a hostname (string) into an IP address. - * NON-BLOCKING callback version for use with raw API!!! - * - * Returns immediately with one of err_t return codes: - * - ERR_OK if hostname is a valid IP address string or the host - * name is already in the local names table. - * - ERR_INPROGRESS enqueue a request to be sent to the DNS server - * for resolution if no errors are present. - * - ERR_ARG: dns client not initialized or invalid hostname - * - * @param hostname the hostname that is to be queried - * @param addr pointer to a ip_addr_t where to store the address if it is already - * cached in the dns_table (only valid if ERR_OK is returned!) - * @param found a callback function to be called on success, failure or timeout (only if - * ERR_INPROGRESS is returned!) - * @param callback_arg argument to pass to the callback function - * @return a err_t return code. - */ -err_t -dns_gethostbyname(const char *hostname, ip_addr_t *addr, dns_found_callback found, - void *callback_arg) -{ - u32_t ipaddr; - /* not initialized or no valid server yet, or invalid addr pointer - * or invalid hostname or invalid hostname length */ - if ((dns_pcb == NULL) || (addr == NULL) || - (!hostname) || (!hostname[0]) || - (strlen(hostname) >= DNS_MAX_NAME_LENGTH)) { - return ERR_ARG; - } - -#if LWIP_HAVE_LOOPIF - if (strcmp(hostname, "localhost")==0) { - ip_addr_set_loopback(addr); - return ERR_OK; - } -#endif /* LWIP_HAVE_LOOPIF */ - - /* host name already in octet notation? set ip addr and return ERR_OK */ - ipaddr = ipaddr_addr(hostname); - if (ipaddr == IPADDR_NONE) { - /* already have this address cached? */ - ipaddr = dns_lookup(hostname); - } - if (ipaddr != IPADDR_NONE) { - ip4_addr_set_u32(addr, ipaddr); - return ERR_OK; - } - - /* queue query with specified callback */ - return dns_enqueue(hostname, found, callback_arg); -} - -#endif /* LWIP_DNS */ diff --git a/features/net/FEATURE_IPV4/lwip-interface/lwip/core/lwip_memp.c b/features/net/FEATURE_IPV4/lwip-interface/lwip/core/lwip_memp.c deleted file mode 100644 index 688c210dd6..0000000000 --- a/features/net/FEATURE_IPV4/lwip-interface/lwip/core/lwip_memp.c +++ /dev/null @@ -1,484 +0,0 @@ -/** - * @file - * Dynamic pool memory manager - * - * lwIP has dedicated pools for many structures (netconn, protocol control blocks, - * packet buffers, ...). All these pools are managed here. - */ - -/* - * 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 - * - */ - -#include "lwip/opt.h" - -#include "lwip/memp.h" -#include "lwip/pbuf.h" -#include "lwip/udp.h" -#include "lwip/raw.h" -#include "lwip/tcp_impl.h" -#include "lwip/igmp.h" -#include "lwip/api.h" -#include "lwip/api_msg.h" -#include "lwip/tcpip.h" -#include "lwip/sys.h" -#include "lwip/timers.h" -#include "lwip/stats.h" -#include "netif/etharp.h" -#include "lwip/ip_frag.h" -#include "lwip/snmp_structs.h" -#include "lwip/snmp_msg.h" -#include "lwip/dns.h" -#include "netif/ppp_oe.h" - -#include - -#if !MEMP_MEM_MALLOC /* don't build if not configured for use in lwipopts.h */ - -struct memp { - struct memp *next; -#if MEMP_OVERFLOW_CHECK - const char *file; - int line; -#endif /* MEMP_OVERFLOW_CHECK */ -}; - -#if MEMP_OVERFLOW_CHECK -/* if MEMP_OVERFLOW_CHECK is turned on, we reserve some bytes at the beginning - * and at the end of each element, initialize them as 0xcd and check - * them later. */ -/* If MEMP_OVERFLOW_CHECK is >= 2, on every call to memp_malloc or memp_free, - * every single element in each pool is checked! - * This is VERY SLOW but also very helpful. */ -/* MEMP_SANITY_REGION_BEFORE and MEMP_SANITY_REGION_AFTER can be overridden in - * lwipopts.h to change the amount reserved for checking. */ -#ifndef MEMP_SANITY_REGION_BEFORE -#define MEMP_SANITY_REGION_BEFORE 16 -#endif /* MEMP_SANITY_REGION_BEFORE*/ -#if MEMP_SANITY_REGION_BEFORE > 0 -#define MEMP_SANITY_REGION_BEFORE_ALIGNED LWIP_MEM_ALIGN_SIZE(MEMP_SANITY_REGION_BEFORE) -#else -#define MEMP_SANITY_REGION_BEFORE_ALIGNED 0 -#endif /* MEMP_SANITY_REGION_BEFORE*/ -#ifndef MEMP_SANITY_REGION_AFTER -#define MEMP_SANITY_REGION_AFTER 16 -#endif /* MEMP_SANITY_REGION_AFTER*/ -#if MEMP_SANITY_REGION_AFTER > 0 -#define MEMP_SANITY_REGION_AFTER_ALIGNED LWIP_MEM_ALIGN_SIZE(MEMP_SANITY_REGION_AFTER) -#else -#define MEMP_SANITY_REGION_AFTER_ALIGNED 0 -#endif /* MEMP_SANITY_REGION_AFTER*/ - -/* MEMP_SIZE: save space for struct memp and for sanity check */ -#define MEMP_SIZE (LWIP_MEM_ALIGN_SIZE(sizeof(struct memp)) + MEMP_SANITY_REGION_BEFORE_ALIGNED) -#define MEMP_ALIGN_SIZE(x) (LWIP_MEM_ALIGN_SIZE(x) + MEMP_SANITY_REGION_AFTER_ALIGNED) - -#else /* MEMP_OVERFLOW_CHECK */ - -/* No sanity checks - * We don't need to preserve the struct memp while not allocated, so we - * can save a little space and set MEMP_SIZE to 0. - */ -#define MEMP_SIZE 0 -#define MEMP_ALIGN_SIZE(x) (LWIP_MEM_ALIGN_SIZE(x)) - -#endif /* MEMP_OVERFLOW_CHECK */ - -/** This array holds the first free element of each pool. - * Elements form a linked list. */ -static struct memp *memp_tab[MEMP_MAX]; - -#else /* MEMP_MEM_MALLOC */ - -#define MEMP_ALIGN_SIZE(x) (LWIP_MEM_ALIGN_SIZE(x)) - -#endif /* MEMP_MEM_MALLOC */ - -/** This array holds the element sizes of each pool. */ -#if !MEM_USE_POOLS && !MEMP_MEM_MALLOC -static -#endif -const u16_t memp_sizes[MEMP_MAX] = { -#define LWIP_MEMPOOL(name,num,size,desc) LWIP_MEM_ALIGN_SIZE(size), -#include "lwip/memp_std.h" -}; - -#if !MEMP_MEM_MALLOC /* don't build if not configured for use in lwipopts.h */ - -/** This array holds the number of elements in each pool. */ -static const u16_t memp_num[MEMP_MAX] = { -#define LWIP_MEMPOOL(name,num,size,desc) (num), -#include "lwip/memp_std.h" -}; - -/** This array holds a textual description of each pool. */ -#ifdef LWIP_DEBUG -static const char *memp_desc[MEMP_MAX] = { -#define LWIP_MEMPOOL(name,num,size,desc) (desc), -#include "lwip/memp_std.h" -}; -#endif /* LWIP_DEBUG */ - -#if MEMP_SEPARATE_POOLS - -/** This creates each memory pool. These are named memp_memory_XXX_base (where - * XXX is the name of the pool defined in memp_std.h). - * To relocate a pool, declare it as extern in cc.h. Example for GCC: - * extern u8_t __attribute__((section(".onchip_mem"))) memp_memory_UDP_PCB_base[]; - */ -#define LWIP_MEMPOOL(name,num,size,desc) u8_t memp_memory_ ## name ## _base \ - [((num) * (MEMP_SIZE + MEMP_ALIGN_SIZE(size)))]; -#include "lwip/memp_std.h" - -/** This array holds the base of each memory pool. */ -static u8_t *const memp_bases[] = { -#define LWIP_MEMPOOL(name,num,size,desc) memp_memory_ ## name ## _base, -#include "lwip/memp_std.h" -}; - -#else /* MEMP_SEPARATE_POOLS */ - -#if defined(TARGET_LPC1768) -# if defined (__ICCARM__) -# define ETHMEM_SECTION -# elif defined(TOOLCHAIN_GCC_CR) -# define ETHMEM_SECTION __attribute__((section(".data.$RamPeriph32"))) -# else -# define ETHMEM_SECTION __attribute__((section("AHBSRAM1"),aligned)) -# endif -#else -#define ETHMEM_SECTION -#endif - -/** This is the actual memory used by the pools (all pools in one big block). */ -#if defined (__ICCARM__) -#pragma location = ".ethusbram" -#endif -static u8_t memp_memory[MEM_ALIGNMENT - 1 -#define LWIP_MEMPOOL(name,num,size,desc) + ( (num) * (MEMP_SIZE + MEMP_ALIGN_SIZE(size) ) ) -#include "lwip/memp_std.h" -] ETHMEM_SECTION; - -#endif /* MEMP_SEPARATE_POOLS */ - -#if MEMP_SANITY_CHECK -/** - * Check that memp-lists don't form a circle - */ -static int -memp_sanity(void) -{ - s16_t i, c; - struct memp *m, *n; - - for (i = 0; i < MEMP_MAX; i++) { - for (m = memp_tab[i]; m != NULL; m = m->next) { - c = 1; - for (n = memp_tab[i]; n != NULL; n = n->next) { - if (n == m && --c < 0) { - return 0; - } - } - } - } - return 1; -} -#endif /* MEMP_SANITY_CHECK*/ -#if MEMP_OVERFLOW_CHECK -#if defined(LWIP_DEBUG) && MEMP_STATS -static const char * memp_overflow_names[] = { -#define LWIP_MEMPOOL(name,num,size,desc) "/"desc, -#include "lwip/memp_std.h" - }; -#endif - -/** - * Check if a memp element was victim of an overflow - * (e.g. the restricted area after it has been altered) - * - * @param p the memp element to check - * @param memp_type the pool p comes from - */ -static void -memp_overflow_check_element_overflow(struct memp *p, u16_t memp_type) -{ - u16_t k; - u8_t *m; -#if MEMP_SANITY_REGION_AFTER_ALIGNED > 0 - m = (u8_t*)p + MEMP_SIZE + memp_sizes[memp_type]; - for (k = 0; k < MEMP_SANITY_REGION_AFTER_ALIGNED; k++) { - if (m[k] != 0xcd) { - char errstr[128] = "detected memp overflow in pool "; - char digit[] = "0"; - if(memp_type >= 10) { - digit[0] = '0' + (memp_type/10); - strcat(errstr, digit); - } - digit[0] = '0' + (memp_type%10); - strcat(errstr, digit); -#if defined(LWIP_DEBUG) && MEMP_STATS - strcat(errstr, memp_overflow_names[memp_type]); -#endif - LWIP_ASSERT(errstr, 0); - } - } -#endif -} - -/** - * Check if a memp element was victim of an underflow - * (e.g. the restricted area before it has been altered) - * - * @param p the memp element to check - * @param memp_type the pool p comes from - */ -static void -memp_overflow_check_element_underflow(struct memp *p, u16_t memp_type) -{ - u16_t k; - u8_t *m; -#if MEMP_SANITY_REGION_BEFORE_ALIGNED > 0 - m = (u8_t*)p + MEMP_SIZE - MEMP_SANITY_REGION_BEFORE_ALIGNED; - for (k = 0; k < MEMP_SANITY_REGION_BEFORE_ALIGNED; k++) { - if (m[k] != 0xcd) { - char errstr[128] = "detected memp underflow in pool "; - char digit[] = "0"; - if(memp_type >= 10) { - digit[0] = '0' + (memp_type/10); - strcat(errstr, digit); - } - digit[0] = '0' + (memp_type%10); - strcat(errstr, digit); -#if defined(LWIP_DEBUG) && MEMP_STATS - strcat(errstr, memp_overflow_names[memp_type]); -#endif - LWIP_ASSERT(errstr, 0); - } - } -#endif -} - -/** - * Do an overflow check for all elements in every pool. - * - * @see memp_overflow_check_element for a description of the check - */ -static void -memp_overflow_check_all(void) -{ - u16_t i, j; - struct memp *p; - - p = (struct memp *)LWIP_MEM_ALIGN(memp_memory); - for (i = 0; i < MEMP_MAX; ++i) { - p = p; - for (j = 0; j < memp_num[i]; ++j) { - memp_overflow_check_element_overflow(p, i); - p = (struct memp*)((u8_t*)p + MEMP_SIZE + memp_sizes[i] + MEMP_SANITY_REGION_AFTER_ALIGNED); - } - } - p = (struct memp *)LWIP_MEM_ALIGN(memp_memory); - for (i = 0; i < MEMP_MAX; ++i) { - p = p; - for (j = 0; j < memp_num[i]; ++j) { - memp_overflow_check_element_underflow(p, i); - p = (struct memp*)((u8_t*)p + MEMP_SIZE + memp_sizes[i] + MEMP_SANITY_REGION_AFTER_ALIGNED); - } - } -} - -/** - * Initialize the restricted areas of all memp elements in every pool. - */ -static void -memp_overflow_init(void) -{ - u16_t i, j; - struct memp *p; - u8_t *m; - - p = (struct memp *)LWIP_MEM_ALIGN(memp_memory); - for (i = 0; i < MEMP_MAX; ++i) { - p = p; - for (j = 0; j < memp_num[i]; ++j) { -#if MEMP_SANITY_REGION_BEFORE_ALIGNED > 0 - m = (u8_t*)p + MEMP_SIZE - MEMP_SANITY_REGION_BEFORE_ALIGNED; - memset(m, 0xcd, MEMP_SANITY_REGION_BEFORE_ALIGNED); -#endif -#if MEMP_SANITY_REGION_AFTER_ALIGNED > 0 - m = (u8_t*)p + MEMP_SIZE + memp_sizes[i]; - memset(m, 0xcd, MEMP_SANITY_REGION_AFTER_ALIGNED); -#endif - p = (struct memp*)((u8_t*)p + MEMP_SIZE + memp_sizes[i] + MEMP_SANITY_REGION_AFTER_ALIGNED); - } - } -} -#endif /* MEMP_OVERFLOW_CHECK */ - -/** - * Initialize this module. - * - * Carves out memp_memory into linked lists for each pool-type. - */ -void -memp_init(void) -{ - struct memp *memp; - u16_t i, j; - - for (i = 0; i < MEMP_MAX; ++i) { - MEMP_STATS_AVAIL(used, i, 0); - MEMP_STATS_AVAIL(max, i, 0); - MEMP_STATS_AVAIL(err, i, 0); - MEMP_STATS_AVAIL(avail, i, memp_num[i]); - } - -#if !MEMP_SEPARATE_POOLS - memp = (struct memp *)LWIP_MEM_ALIGN(memp_memory); -#endif /* !MEMP_SEPARATE_POOLS */ - /* for every pool: */ - for (i = 0; i < MEMP_MAX; ++i) { - memp_tab[i] = NULL; -#if MEMP_SEPARATE_POOLS - memp = (struct memp*)memp_bases[i]; -#endif /* MEMP_SEPARATE_POOLS */ - /* create a linked list of memp elements */ - for (j = 0; j < memp_num[i]; ++j) { - memp->next = memp_tab[i]; - memp_tab[i] = memp; - memp = (struct memp *)(void *)((u8_t *)memp + MEMP_SIZE + memp_sizes[i] -#if MEMP_OVERFLOW_CHECK - + MEMP_SANITY_REGION_AFTER_ALIGNED -#endif - ); - } - } -#if MEMP_OVERFLOW_CHECK - memp_overflow_init(); - /* check everything a first time to see if it worked */ - memp_overflow_check_all(); -#endif /* MEMP_OVERFLOW_CHECK */ -} - -/** - * Get an element from a specific pool. - * - * @param type the pool to get an element from - * - * the debug version has two more parameters: - * @param file file name calling this function - * @param line number of line where this function is called - * - * @return a pointer to the allocated memory or a NULL pointer on error - */ -void * -#if !MEMP_OVERFLOW_CHECK -memp_malloc(memp_t type) -#else -memp_malloc_fn(memp_t type, const char* file, const int line) -#endif -{ - struct memp *memp; - SYS_ARCH_DECL_PROTECT(old_level); - - LWIP_ERROR("memp_malloc: type < MEMP_MAX", (type < MEMP_MAX), return NULL;); - - SYS_ARCH_PROTECT(old_level); -#if MEMP_OVERFLOW_CHECK >= 2 - memp_overflow_check_all(); -#endif /* MEMP_OVERFLOW_CHECK >= 2 */ - - memp = memp_tab[type]; - - if (memp != NULL) { - memp_tab[type] = memp->next; -#if MEMP_OVERFLOW_CHECK - memp->next = NULL; - memp->file = file; - memp->line = line; -#endif /* MEMP_OVERFLOW_CHECK */ - MEMP_STATS_INC_USED(used, type); - LWIP_ASSERT("memp_malloc: memp properly aligned", - ((mem_ptr_t)memp % MEM_ALIGNMENT) == 0); - memp = (struct memp*)(void *)((u8_t*)memp + MEMP_SIZE); - } else { - LWIP_DEBUGF(MEMP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("memp_malloc: out of memory in pool %s\n", memp_desc[type])); - MEMP_STATS_INC(err, type); - } - - SYS_ARCH_UNPROTECT(old_level); - - return memp; -} - -/** - * Put an element back into its pool. - * - * @param type the pool where to put mem - * @param mem the memp element to free - */ -void -memp_free(memp_t type, void *mem) -{ - struct memp *memp; - SYS_ARCH_DECL_PROTECT(old_level); - - if (mem == NULL) { - return; - } - LWIP_ASSERT("memp_free: mem properly aligned", - ((mem_ptr_t)mem % MEM_ALIGNMENT) == 0); - - memp = (struct memp *)(void *)((u8_t*)mem - MEMP_SIZE); - - SYS_ARCH_PROTECT(old_level); -#if MEMP_OVERFLOW_CHECK -#if MEMP_OVERFLOW_CHECK >= 2 - memp_overflow_check_all(); -#else - memp_overflow_check_element_overflow(memp, type); - memp_overflow_check_element_underflow(memp, type); -#endif /* MEMP_OVERFLOW_CHECK >= 2 */ -#endif /* MEMP_OVERFLOW_CHECK */ - - MEMP_STATS_DEC(used, type); - - memp->next = memp_tab[type]; - memp_tab[type] = memp; - -#if MEMP_SANITY_CHECK - LWIP_ASSERT("memp sanity", memp_sanity()); -#endif /* MEMP_SANITY_CHECK */ - - SYS_ARCH_UNPROTECT(old_level); -} - -#endif /* MEMP_MEM_MALLOC */ diff --git a/features/net/FEATURE_IPV4/lwip-interface/lwip/core/lwip_netif.c b/features/net/FEATURE_IPV4/lwip-interface/lwip/core/lwip_netif.c deleted file mode 100644 index b3a5e16337..0000000000 --- a/features/net/FEATURE_IPV4/lwip-interface/lwip/core/lwip_netif.c +++ /dev/null @@ -1,758 +0,0 @@ -/** - * @file - * lwIP network interface abstraction - * - */ - -/* - * 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 - * - */ - -#include "lwip/opt.h" - -#include "lwip/def.h" -#include "lwip/ip_addr.h" -#include "lwip/netif.h" -#include "lwip/tcp_impl.h" -#include "lwip/snmp.h" -#include "lwip/igmp.h" -#include "netif/etharp.h" -#include "lwip/stats.h" -#if ENABLE_LOOPBACK -#include "lwip/sys.h" -#if LWIP_NETIF_LOOPBACK_MULTITHREADING -#include "lwip/tcpip.h" -#endif /* LWIP_NETIF_LOOPBACK_MULTITHREADING */ -#endif /* ENABLE_LOOPBACK */ - -#if LWIP_AUTOIP -#include "lwip/autoip.h" -#endif /* LWIP_AUTOIP */ -#if LWIP_DHCP -#include "lwip/dhcp.h" -#endif /* LWIP_DHCP */ - -#if LWIP_NETIF_STATUS_CALLBACK -#define NETIF_STATUS_CALLBACK(n) do{ if (n->status_callback) { (n->status_callback)(n); }}while(0) -#else -#define NETIF_STATUS_CALLBACK(n) -#endif /* LWIP_NETIF_STATUS_CALLBACK */ - -#if LWIP_NETIF_LINK_CALLBACK -#define NETIF_LINK_CALLBACK(n) do{ if (n->link_callback) { (n->link_callback)(n); }}while(0) -#else -#define NETIF_LINK_CALLBACK(n) -#endif /* LWIP_NETIF_LINK_CALLBACK */ - -struct netif *netif_list; -struct netif *netif_default; - -#if LWIP_HAVE_LOOPIF -static struct netif loop_netif; - -/** - * Initialize a lwip network interface structure for a loopback interface - * - * @param netif the lwip network interface structure for this loopif - * @return ERR_OK if the loopif is initialized - * ERR_MEM if private data couldn't be allocated - */ -static err_t -netif_loopif_init(struct netif *netif) -{ - /* initialize the snmp variables and counters inside the struct netif - * ifSpeed: no assumption can be made! - */ - NETIF_INIT_SNMP(netif, snmp_ifType_softwareLoopback, 0); - - netif->name[0] = 'l'; - netif->name[1] = 'o'; - netif->output = netif_loop_output; - return ERR_OK; -} -#endif /* LWIP_HAVE_LOOPIF */ - -void -netif_init(void) -{ -#if LWIP_HAVE_LOOPIF - ip_addr_t loop_ipaddr, loop_netmask, loop_gw; - IP4_ADDR(&loop_gw, 127,0,0,1); - IP4_ADDR(&loop_ipaddr, 127,0,0,1); - IP4_ADDR(&loop_netmask, 255,0,0,0); - -#if NO_SYS - netif_add(&loop_netif, &loop_ipaddr, &loop_netmask, &loop_gw, NULL, netif_loopif_init, ip_input); -#else /* NO_SYS */ - netif_add(&loop_netif, &loop_ipaddr, &loop_netmask, &loop_gw, NULL, netif_loopif_init, tcpip_input); -#endif /* NO_SYS */ - netif_set_up(&loop_netif); - -#endif /* LWIP_HAVE_LOOPIF */ -} - -/** - * Add a network interface to the list of lwIP netifs. - * - * @param netif a pre-allocated netif structure - * @param ipaddr IP address for the new netif - * @param netmask network mask for the new netif - * @param gw default gateway IP address for the new netif - * @param state opaque data passed to the new netif - * @param init callback function that initializes the interface - * @param input callback function that is called to pass - * ingress packets up in the protocol layer stack. - * - * @return netif, or NULL if failed. - */ -struct netif * -netif_add(struct netif *netif, ip_addr_t *ipaddr, ip_addr_t *netmask, - ip_addr_t *gw, void *state, netif_init_fn init, netif_input_fn input) -{ - static u8_t netifnum = 0; - - LWIP_ASSERT("No init function given", init != NULL); - - /* reset new interface configuration state */ - ip_addr_set_zero(&netif->ip_addr); - ip_addr_set_zero(&netif->netmask); - ip_addr_set_zero(&netif->gw); - netif->flags = 0; -#if LWIP_DHCP - /* netif not under DHCP control by default */ - netif->dhcp = NULL; -#endif /* LWIP_DHCP */ -#if LWIP_AUTOIP - /* netif not under AutoIP control by default */ - netif->autoip = NULL; -#endif /* LWIP_AUTOIP */ -#if LWIP_NETIF_STATUS_CALLBACK - netif->status_callback = NULL; -#endif /* LWIP_NETIF_STATUS_CALLBACK */ -#if LWIP_NETIF_LINK_CALLBACK - netif->link_callback = NULL; -#endif /* LWIP_NETIF_LINK_CALLBACK */ -#if LWIP_IGMP - netif->igmp_mac_filter = NULL; -#endif /* LWIP_IGMP */ -#if ENABLE_LOOPBACK - netif->loop_first = NULL; - netif->loop_last = NULL; -#endif /* ENABLE_LOOPBACK */ - - /* remember netif specific state information data */ - netif->state = state; - netif->num = netifnum++; - netif->input = input; -#if LWIP_NETIF_HWADDRHINT - netif->addr_hint = NULL; -#endif /* LWIP_NETIF_HWADDRHINT*/ -#if ENABLE_LOOPBACK && LWIP_LOOPBACK_MAX_PBUFS - netif->loop_cnt_current = 0; -#endif /* ENABLE_LOOPBACK && LWIP_LOOPBACK_MAX_PBUFS */ - - netif_set_addr(netif, ipaddr, netmask, gw); - - /* call user specified initialization function for netif */ - if (init(netif) != ERR_OK) { - return NULL; - } - - /* add this netif to the list */ - netif->next = netif_list; - netif_list = netif; - snmp_inc_iflist(); - -#if LWIP_IGMP - /* start IGMP processing */ - if (netif->flags & NETIF_FLAG_IGMP) { - igmp_start(netif); - } -#endif /* LWIP_IGMP */ - - LWIP_DEBUGF(NETIF_DEBUG, ("netif: added interface %c%c IP addr ", - netif->name[0], netif->name[1])); - ip_addr_debug_print(NETIF_DEBUG, ipaddr); - LWIP_DEBUGF(NETIF_DEBUG, (" netmask ")); - ip_addr_debug_print(NETIF_DEBUG, netmask); - LWIP_DEBUGF(NETIF_DEBUG, (" gw ")); - ip_addr_debug_print(NETIF_DEBUG, gw); - LWIP_DEBUGF(NETIF_DEBUG, ("\n")); - return netif; -} - -/** - * Change IP address configuration for a network interface (including netmask - * and default gateway). - * - * @param netif the network interface to change - * @param ipaddr the new IP address - * @param netmask the new netmask - * @param gw the new default gateway - */ -void -netif_set_addr(struct netif *netif, ip_addr_t *ipaddr, ip_addr_t *netmask, - ip_addr_t *gw) -{ - netif_set_ipaddr(netif, ipaddr); - netif_set_netmask(netif, netmask); - netif_set_gw(netif, gw); -} - -/** - * Remove a network interface from the list of lwIP netifs. - * - * @param netif the network interface to remove - */ -void -netif_remove(struct netif *netif) -{ - if (netif == NULL) { - return; - } - -#if LWIP_IGMP - /* stop IGMP processing */ - if (netif->flags & NETIF_FLAG_IGMP) { - igmp_stop(netif); - } -#endif /* LWIP_IGMP */ - if (netif_is_up(netif)) { - /* set netif down before removing (call callback function) */ - netif_set_down(netif); - } - - snmp_delete_ipaddridx_tree(netif); - - /* is it the first netif? */ - if (netif_list == netif) { - netif_list = netif->next; - } else { - /* look for netif further down the list */ - struct netif * tmpNetif; - for (tmpNetif = netif_list; tmpNetif != NULL; tmpNetif = tmpNetif->next) { - if (tmpNetif->next == netif) { - tmpNetif->next = netif->next; - break; - } - } - if (tmpNetif == NULL) - return; /* we didn't find any netif today */ - } - snmp_dec_iflist(); - /* this netif is default? */ - if (netif_default == netif) { - /* reset default netif */ - netif_set_default(NULL); - } - LWIP_DEBUGF( NETIF_DEBUG, ("netif_remove: removed netif\n") ); -} - -/** - * Find a network interface by searching for its name - * - * @param name the name of the netif (like netif->name) plus concatenated number - * in ascii representation (e.g. 'en0') - */ -struct netif * -netif_find(char *name) -{ - struct netif *netif; - u8_t num; - - if (name == NULL) { - return NULL; - } - - num = name[2] - '0'; - - for(netif = netif_list; netif != NULL; netif = netif->next) { - if (num == netif->num && - name[0] == netif->name[0] && - name[1] == netif->name[1]) { - LWIP_DEBUGF(NETIF_DEBUG, ("netif_find: found %c%c\n", name[0], name[1])); - return netif; - } - } - LWIP_DEBUGF(NETIF_DEBUG, ("netif_find: didn't find %c%c\n", name[0], name[1])); - return NULL; -} - -/** - * Change the IP address of a network interface - * - * @param netif the network interface to change - * @param ipaddr the new IP address - * - * @note call netif_set_addr() if you also want to change netmask and - * default gateway - */ -void -netif_set_ipaddr(struct netif *netif, ip_addr_t *ipaddr) -{ - /* Protect against dereferencing NULL pointers by - treating like ANY, as does ip_addr_set() */ - if (!ipaddr) { - ipaddr = IP_ADDR_ANY; - } - - /* TODO: Handling of obsolete pcbs */ - /* See: http://mail.gnu.org/archive/html/lwip-users/2003-03/msg00118.html */ -#if LWIP_TCP - struct tcp_pcb *pcb; - struct tcp_pcb_listen *lpcb; - - /* address is actually being changed? */ - if ((ip_addr_cmp(ipaddr, &(netif->ip_addr))) == 0) { - /* extern struct tcp_pcb *tcp_active_pcbs; defined by tcp.h */ - LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_STATE, ("netif_set_ipaddr: netif address being changed\n")); - pcb = tcp_active_pcbs; - while (pcb != NULL) { - /* PCB bound to current local interface address? */ - if (ip_addr_cmp(&(pcb->local_ip), &(netif->ip_addr)) -#if LWIP_AUTOIP - /* connections to link-local addresses must persist (RFC3927 ch. 1.9) */ - && !ip_addr_islinklocal(&(pcb->local_ip)) -#endif /* LWIP_AUTOIP */ - ) { - /* this connection must be aborted */ - struct tcp_pcb *next = pcb->next; - LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_STATE, ("netif_set_ipaddr: aborting TCP pcb %p\n", (void *)pcb)); - tcp_abort(pcb); - pcb = next; - } else { - pcb = pcb->next; - } - } - for (lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = lpcb->next) { - /* PCB bound to current local interface address? */ - if ((!(ip_addr_isany(&(lpcb->local_ip)))) && - (ip_addr_cmp(&(lpcb->local_ip), &(netif->ip_addr)))) { - /* The PCB is listening to the old ipaddr and - * is set to listen to the new one instead */ - ip_addr_set(&(lpcb->local_ip), ipaddr); - } - } - } -#endif - snmp_delete_ipaddridx_tree(netif); - snmp_delete_iprteidx_tree(0,netif); - /* set new IP address to netif */ - ip_addr_set(&(netif->ip_addr), ipaddr); - snmp_insert_ipaddridx_tree(netif); - snmp_insert_iprteidx_tree(0,netif); - - LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("netif: IP address of interface %c%c set to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", - netif->name[0], netif->name[1], - ip4_addr1_16(&netif->ip_addr), - ip4_addr2_16(&netif->ip_addr), - ip4_addr3_16(&netif->ip_addr), - ip4_addr4_16(&netif->ip_addr))); -} - -/** - * Change the default gateway for a network interface - * - * @param netif the network interface to change - * @param gw the new default gateway - * - * @note call netif_set_addr() if you also want to change ip address and netmask - */ -void -netif_set_gw(struct netif *netif, ip_addr_t *gw) -{ - ip_addr_set(&(netif->gw), gw); - LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("netif: GW address of interface %c%c set to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", - netif->name[0], netif->name[1], - ip4_addr1_16(&netif->gw), - ip4_addr2_16(&netif->gw), - ip4_addr3_16(&netif->gw), - ip4_addr4_16(&netif->gw))); -} - -/** - * Change the netmask of a network interface - * - * @param netif the network interface to change - * @param netmask the new netmask - * - * @note call netif_set_addr() if you also want to change ip address and - * default gateway - */ -void -netif_set_netmask(struct netif *netif, ip_addr_t *netmask) -{ - snmp_delete_iprteidx_tree(0, netif); - /* set new netmask to netif */ - ip_addr_set(&(netif->netmask), netmask); - snmp_insert_iprteidx_tree(0, netif); - LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("netif: netmask of interface %c%c set to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", - netif->name[0], netif->name[1], - ip4_addr1_16(&netif->netmask), - ip4_addr2_16(&netif->netmask), - ip4_addr3_16(&netif->netmask), - ip4_addr4_16(&netif->netmask))); -} - -/** - * Set a network interface as the default network interface - * (used to output all packets for which no specific route is found) - * - * @param netif the default network interface - */ -void -netif_set_default(struct netif *netif) -{ - if (netif == NULL) { - /* remove default route */ - snmp_delete_iprteidx_tree(1, netif); - } else { - /* install default route */ - snmp_insert_iprteidx_tree(1, netif); - } - netif_default = netif; - LWIP_DEBUGF(NETIF_DEBUG, ("netif: setting default interface %c%c\n", - netif ? netif->name[0] : '\'', netif ? netif->name[1] : '\'')); -} - -/** - * Bring an interface up, available for processing - * traffic. - * - * @note: Enabling DHCP on a down interface will make it come - * up once configured. - * - * @see dhcp_start() - */ -void netif_set_up(struct netif *netif) -{ - if (!(netif->flags & NETIF_FLAG_UP)) { - netif->flags |= NETIF_FLAG_UP; - -#if LWIP_SNMP - snmp_get_sysuptime(&netif->ts); -#endif /* LWIP_SNMP */ - - NETIF_STATUS_CALLBACK(netif); - - if (netif->flags & NETIF_FLAG_LINK_UP) { -#if LWIP_ARP - /* For Ethernet network interfaces, we would like to send a "gratuitous ARP" */ - if (netif->flags & (NETIF_FLAG_ETHARP)) { - etharp_gratuitous(netif); - } -#endif /* LWIP_ARP */ - -#if LWIP_IGMP - /* resend IGMP memberships */ - if (netif->flags & NETIF_FLAG_IGMP) { - igmp_report_groups( netif); - } -#endif /* LWIP_IGMP */ - } - } -} - -/** - * Bring an interface down, disabling any traffic processing. - * - * @note: Enabling DHCP on a down interface will make it come - * up once configured. - * - * @see dhcp_start() - */ -void netif_set_down(struct netif *netif) -{ - if (netif->flags & NETIF_FLAG_UP) { - netif->flags &= ~NETIF_FLAG_UP; -#if LWIP_SNMP - snmp_get_sysuptime(&netif->ts); -#endif - - NETIF_STATUS_CALLBACK(netif); - } -} - -#if LWIP_NETIF_STATUS_CALLBACK -/** - * Set callback to be called when interface is brought up/down - */ -void netif_set_status_callback(struct netif *netif, netif_status_callback_fn status_callback) -{ - if (netif) { - netif->status_callback = status_callback; - } -} -#endif /* LWIP_NETIF_STATUS_CALLBACK */ - -/** - * Called by a driver when its link goes up - */ -void netif_set_link_up(struct netif *netif ) -{ - if (!(netif->flags & NETIF_FLAG_LINK_UP)) { - netif->flags |= NETIF_FLAG_LINK_UP; - -#if LWIP_DHCP - if (netif->dhcp) { - dhcp_network_changed(netif); - } -#endif /* LWIP_DHCP */ - -#if LWIP_AUTOIP - if (netif->autoip) { - autoip_network_changed(netif); - } -#endif /* LWIP_AUTOIP */ - - if (netif->flags & NETIF_FLAG_UP) { -#if LWIP_ARP - /* For Ethernet network interfaces, we would like to send a "gratuitous ARP" */ - if (netif->flags & NETIF_FLAG_ETHARP) { - etharp_gratuitous(netif); - } -#endif /* LWIP_ARP */ - -#if LWIP_IGMP - /* resend IGMP memberships */ - if (netif->flags & NETIF_FLAG_IGMP) { - igmp_report_groups( netif); - } -#endif /* LWIP_IGMP */ - } - NETIF_LINK_CALLBACK(netif); - } -} - -/** - * Called by a driver when its link goes down - */ -void netif_set_link_down(struct netif *netif ) -{ - if (netif->flags & NETIF_FLAG_LINK_UP) { - netif->flags &= ~NETIF_FLAG_LINK_UP; - NETIF_LINK_CALLBACK(netif); - } -} - -#if LWIP_NETIF_LINK_CALLBACK -/** - * Set callback to be called when link is brought up/down - */ -void netif_set_link_callback(struct netif *netif, netif_status_callback_fn link_callback) -{ - if (netif) { - netif->link_callback = link_callback; - } -} -#endif /* LWIP_NETIF_LINK_CALLBACK */ - -#if ENABLE_LOOPBACK -/** - * Send an IP packet to be received on the same netif (loopif-like). - * The pbuf is simply copied and handed back to netif->input. - * In multithreaded mode, this is done directly since netif->input must put - * the packet on a queue. - * In callback mode, the packet is put on an internal queue and is fed to - * netif->input by netif_poll(). - * - * @param netif the lwip network interface structure - * @param p the (IP) packet to 'send' - * @param ipaddr the ip address to send the packet to (not used) - * @return ERR_OK if the packet has been sent - * ERR_MEM if the pbuf used to copy the packet couldn't be allocated - */ -err_t -netif_loop_output(struct netif *netif, struct pbuf *p, - ip_addr_t *ipaddr) -{ - struct pbuf *r; - err_t err; - struct pbuf *last; -#if LWIP_LOOPBACK_MAX_PBUFS - u8_t clen = 0; -#endif /* LWIP_LOOPBACK_MAX_PBUFS */ - /* If we have a loopif, SNMP counters are adjusted for it, - * if not they are adjusted for 'netif'. */ -#if LWIP_SNMP -#if LWIP_HAVE_LOOPIF - struct netif *stats_if = &loop_netif; -#else /* LWIP_HAVE_LOOPIF */ - struct netif *stats_if = netif; -#endif /* LWIP_HAVE_LOOPIF */ -#endif /* LWIP_SNMP */ - SYS_ARCH_DECL_PROTECT(lev); - LWIP_UNUSED_ARG(ipaddr); - - /* Allocate a new pbuf */ - r = pbuf_alloc(PBUF_LINK, p->tot_len, PBUF_RAM); - if (r == NULL) { - LINK_STATS_INC(link.memerr); - LINK_STATS_INC(link.drop); - snmp_inc_ifoutdiscards(stats_if); - return ERR_MEM; - } -#if LWIP_LOOPBACK_MAX_PBUFS - clen = pbuf_clen(r); - /* check for overflow or too many pbuf on queue */ - if(((netif->loop_cnt_current + clen) < netif->loop_cnt_current) || - ((netif->loop_cnt_current + clen) > LWIP_LOOPBACK_MAX_PBUFS)) { - pbuf_free(r); - LINK_STATS_INC(link.memerr); - LINK_STATS_INC(link.drop); - snmp_inc_ifoutdiscards(stats_if); - return ERR_MEM; - } - netif->loop_cnt_current += clen; -#endif /* LWIP_LOOPBACK_MAX_PBUFS */ - - /* Copy the whole pbuf queue p into the single pbuf r */ - if ((err = pbuf_copy(r, p)) != ERR_OK) { - pbuf_free(r); - LINK_STATS_INC(link.memerr); - LINK_STATS_INC(link.drop); - snmp_inc_ifoutdiscards(stats_if); - return err; - } - - /* Put the packet on a linked list which gets emptied through calling - netif_poll(). */ - - /* let last point to the last pbuf in chain r */ - for (last = r; last->next != NULL; last = last->next); - - SYS_ARCH_PROTECT(lev); - if(netif->loop_first != NULL) { - LWIP_ASSERT("if first != NULL, last must also be != NULL", netif->loop_last != NULL); - netif->loop_last->next = r; - netif->loop_last = last; - } else { - netif->loop_first = r; - netif->loop_last = last; - } - SYS_ARCH_UNPROTECT(lev); - - LINK_STATS_INC(link.xmit); - snmp_add_ifoutoctets(stats_if, p->tot_len); - snmp_inc_ifoutucastpkts(stats_if); - -#if LWIP_NETIF_LOOPBACK_MULTITHREADING - /* For multithreading environment, schedule a call to netif_poll */ - tcpip_callback((tcpip_callback_fn)netif_poll, netif); -#endif /* LWIP_NETIF_LOOPBACK_MULTITHREADING */ - - return ERR_OK; -} - -/** - * Call netif_poll() in the main loop of your application. This is to prevent - * reentering non-reentrant functions like tcp_input(). Packets passed to - * netif_loop_output() are put on a list that is passed to netif->input() by - * netif_poll(). - */ -void -netif_poll(struct netif *netif) -{ - struct pbuf *in; - /* If we have a loopif, SNMP counters are adjusted for it, - * if not they are adjusted for 'netif'. */ -#if LWIP_SNMP -#if LWIP_HAVE_LOOPIF - struct netif *stats_if = &loop_netif; -#else /* LWIP_HAVE_LOOPIF */ - struct netif *stats_if = netif; -#endif /* LWIP_HAVE_LOOPIF */ -#endif /* LWIP_SNMP */ - SYS_ARCH_DECL_PROTECT(lev); - - do { - /* Get a packet from the list. With SYS_LIGHTWEIGHT_PROT=1, this is protected */ - SYS_ARCH_PROTECT(lev); - in = netif->loop_first; - if (in != NULL) { - struct pbuf *in_end = in; -#if LWIP_LOOPBACK_MAX_PBUFS - u8_t clen = pbuf_clen(in); - /* adjust the number of pbufs on queue */ - LWIP_ASSERT("netif->loop_cnt_current underflow", - ((netif->loop_cnt_current - clen) < netif->loop_cnt_current)); - netif->loop_cnt_current -= clen; -#endif /* LWIP_LOOPBACK_MAX_PBUFS */ - while (in_end->len != in_end->tot_len) { - LWIP_ASSERT("bogus pbuf: len != tot_len but next == NULL!", in_end->next != NULL); - in_end = in_end->next; - } - /* 'in_end' now points to the last pbuf from 'in' */ - if (in_end == netif->loop_last) { - /* this was the last pbuf in the list */ - netif->loop_first = netif->loop_last = NULL; - } else { - /* pop the pbuf off the list */ - netif->loop_first = in_end->next; - LWIP_ASSERT("should not be null since first != last!", netif->loop_first != NULL); - } - /* De-queue the pbuf from its successors on the 'loop_' list. */ - in_end->next = NULL; - } - SYS_ARCH_UNPROTECT(lev); - - if (in != NULL) { - LINK_STATS_INC(link.recv); - snmp_add_ifinoctets(stats_if, in->tot_len); - snmp_inc_ifinucastpkts(stats_if); - /* loopback packets are always IP packets! */ - if (ip_input(in, netif) != ERR_OK) { - pbuf_free(in); - } - /* Don't reference the packet any more! */ - in = NULL; - } - /* go on while there is a packet on the list */ - } while (netif->loop_first != NULL); -} - -#if !LWIP_NETIF_LOOPBACK_MULTITHREADING -/** - * Calls netif_poll() for every netif on the netif_list. - */ -void -netif_poll_all(void) -{ - struct netif *netif = netif_list; - /* loop through netifs */ - while (netif != NULL) { - netif_poll(netif); - /* proceed to next network interface */ - netif = netif->next; - } -} -#endif /* !LWIP_NETIF_LOOPBACK_MULTITHREADING */ -#endif /* ENABLE_LOOPBACK */ diff --git a/features/net/FEATURE_IPV4/lwip-interface/lwip/core/snmp/lwip_asn1_dec.c b/features/net/FEATURE_IPV4/lwip-interface/lwip/core/snmp/lwip_asn1_dec.c deleted file mode 100644 index 1d5658207a..0000000000 --- a/features/net/FEATURE_IPV4/lwip-interface/lwip/core/snmp/lwip_asn1_dec.c +++ /dev/null @@ -1,657 +0,0 @@ -/** - * @file - * Abstract Syntax Notation One (ISO 8824, 8825) decoding - * - * @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 - */ - -#include "lwip/opt.h" - -#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/snmp_asn1.h" - -/** - * Retrieves type field from incoming pbuf chain. - * - * @param p points to a pbuf holding an ASN1 coded type field - * @param ofs points to the offset within the pbuf chain of the ASN1 coded type field - * @param type return ASN1 type - * @return ERR_OK if successfull, ERR_ARG if we can't (or won't) decode - */ -err_t -snmp_asn1_dec_type(struct pbuf *p, u16_t ofs, u8_t *type) -{ - u16_t plen, base; - u8_t *msg_ptr; - - plen = 0; - while (p != NULL) - { - base = plen; - plen += p->len; - if (ofs < plen) - { - msg_ptr = (u8_t*)p->payload; - msg_ptr += ofs - base; - *type = *msg_ptr; - return ERR_OK; - } - p = p->next; - } - /* p == NULL, ofs >= plen */ - return ERR_ARG; -} - -/** - * Decodes length field from incoming pbuf chain into host length. - * - * @param p points to a pbuf holding an ASN1 coded length - * @param ofs points to the offset within the pbuf chain of the ASN1 coded length - * @param octets_used returns number of octets used by the length code - * @param length return host order length, upto 64k - * @return ERR_OK if successfull, ERR_ARG if we can't (or won't) decode - */ -err_t -snmp_asn1_dec_length(struct pbuf *p, u16_t ofs, u8_t *octets_used, u16_t *length) -{ - u16_t plen, base; - u8_t *msg_ptr; - - plen = 0; - while (p != NULL) - { - base = plen; - plen += p->len; - if (ofs < plen) - { - msg_ptr = (u8_t*)p->payload; - msg_ptr += ofs - base; - - if (*msg_ptr < 0x80) - { - /* primitive definite length format */ - *octets_used = 1; - *length = *msg_ptr; - return ERR_OK; - } - else if (*msg_ptr == 0x80) - { - /* constructed indefinite length format, termination with two zero octets */ - u8_t zeros; - u8_t i; - - *length = 0; - zeros = 0; - while (zeros != 2) - { - i = 2; - while (i > 0) - { - i--; - (*length) += 1; - ofs += 1; - if (ofs >= plen) - { - /* next octet in next pbuf */ - p = p->next; - if (p == NULL) { return ERR_ARG; } - msg_ptr = (u8_t*)p->payload; - plen += p->len; - } - else - { - /* next octet in same pbuf */ - msg_ptr++; - } - if (*msg_ptr == 0) - { - zeros++; - if (zeros == 2) - { - /* stop while (i > 0) */ - i = 0; - } - } - else - { - zeros = 0; - } - } - } - *octets_used = 1; - return ERR_OK; - } - else if (*msg_ptr == 0x81) - { - /* constructed definite length format, one octet */ - ofs += 1; - if (ofs >= plen) - { - /* next octet in next pbuf */ - p = p->next; - if (p == NULL) { return ERR_ARG; } - msg_ptr = (u8_t*)p->payload; - } - else - { - /* next octet in same pbuf */ - msg_ptr++; - } - *length = *msg_ptr; - *octets_used = 2; - return ERR_OK; - } - else if (*msg_ptr == 0x82) - { - u8_t i; - - /* constructed definite length format, two octets */ - i = 2; - while (i > 0) - { - i--; - ofs += 1; - if (ofs >= plen) - { - /* next octet in next pbuf */ - p = p->next; - if (p == NULL) { return ERR_ARG; } - msg_ptr = (u8_t*)p->payload; - plen += p->len; - } - else - { - /* next octet in same pbuf */ - msg_ptr++; - } - if (i == 0) - { - /* least significant length octet */ - *length |= *msg_ptr; - } - else - { - /* most significant length octet */ - *length = (*msg_ptr) << 8; - } - } - *octets_used = 3; - return ERR_OK; - } - else - { - /* constructed definite length format 3..127 octets, this is too big (>64k) */ - /** @todo: do we need to accept inefficient codings with many leading zero's? */ - *octets_used = 1 + ((*msg_ptr) & 0x7f); - return ERR_ARG; - } - } - p = p->next; - } - - /* p == NULL, ofs >= plen */ - return ERR_ARG; -} - -/** - * Decodes positive integer (counter, gauge, timeticks) into u32_t. - * - * @param p points to a pbuf holding an ASN1 coded integer - * @param ofs points to the offset within the pbuf chain of the ASN1 coded integer - * @param len length of the coded integer field - * @param value return host order integer - * @return ERR_OK if successfull, 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 pbuf *p, u16_t ofs, u16_t len, u32_t *value) -{ - u16_t plen, base; - u8_t *msg_ptr; - - plen = 0; - while (p != NULL) - { - base = plen; - plen += p->len; - if (ofs < plen) - { - msg_ptr = (u8_t*)p->payload; - msg_ptr += ofs - base; - if ((len > 0) && (len < 6)) - { - /* start from zero */ - *value = 0; - if (*msg_ptr & 0x80) - { - /* negative, expecting zero sign bit! */ - return ERR_ARG; - } - else - { - /* positive */ - if ((len > 1) && (*msg_ptr == 0)) - { - /* skip leading "sign byte" octet 0x00 */ - len--; - ofs += 1; - if (ofs >= plen) - { - /* next octet in next pbuf */ - p = p->next; - if (p == NULL) { return ERR_ARG; } - msg_ptr = (u8_t*)p->payload; - plen += p->len; - } - else - { - /* next octet in same pbuf */ - msg_ptr++; - } - } - } - /* OR octets with value */ - while (len > 1) - { - len--; - *value |= *msg_ptr; - *value <<= 8; - ofs += 1; - if (ofs >= plen) - { - /* next octet in next pbuf */ - p = p->next; - if (p == NULL) { return ERR_ARG; } - msg_ptr = (u8_t*)p->payload; - plen += p->len; - } - else - { - /* next octet in same pbuf */ - msg_ptr++; - } - } - *value |= *msg_ptr; - return ERR_OK; - } - else - { - return ERR_ARG; - } - } - p = p->next; - } - /* p == NULL, ofs >= plen */ - return ERR_ARG; -} - -/** - * Decodes integer into s32_t. - * - * @param p points to a pbuf holding an ASN1 coded integer - * @param ofs points to the offset within the pbuf chain of the ASN1 coded integer - * @param len length of the coded integer field - * @param value return host order integer - * @return ERR_OK if successfull, ERR_ARG if we can't (or won't) decode - * - * @note ASN coded integers are _always_ signed! - */ -err_t -snmp_asn1_dec_s32t(struct pbuf *p, u16_t ofs, u16_t len, s32_t *value) -{ - u16_t plen, base; - u8_t *msg_ptr; -#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; - - plen = 0; - while (p != NULL) - { - base = plen; - plen += p->len; - if (ofs < plen) - { - msg_ptr = (u8_t*)p->payload; - msg_ptr += ofs - base; - if ((len > 0) && (len < 5)) - { - if (*msg_ptr & 0x80) - { - /* negative, start from -1 */ - *value = -1; - sign = 1; - } - else - { - /* positive, start from 0 */ - *value = 0; - sign = 0; - } - /* OR/AND octets with value */ - while (len > 1) - { - len--; - if (sign) - { - *lsb_ptr &= *msg_ptr; - *value <<= 8; - *lsb_ptr |= 255; - } - else - { - *lsb_ptr |= *msg_ptr; - *value <<= 8; - } - ofs += 1; - if (ofs >= plen) - { - /* next octet in next pbuf */ - p = p->next; - if (p == NULL) { return ERR_ARG; } - msg_ptr = (u8_t*)p->payload; - plen += p->len; - } - else - { - /* next octet in same pbuf */ - msg_ptr++; - } - } - if (sign) - { - *lsb_ptr &= *msg_ptr; - } - else - { - *lsb_ptr |= *msg_ptr; - } - return ERR_OK; - } - else - { - return ERR_ARG; - } - } - p = p->next; - } - /* p == NULL, ofs >= plen */ - return ERR_ARG; -} - -/** - * Decodes object identifier from incoming message into array of s32_t. - * - * @param p points to a pbuf holding an ASN1 coded object identifier - * @param ofs points to the offset within the pbuf chain of the ASN1 coded object identifier - * @param len length of the coded object identifier - * @param oid return object identifier struct - * @return ERR_OK if successfull, ERR_ARG if we can't (or won't) decode - */ -err_t -snmp_asn1_dec_oid(struct pbuf *p, u16_t ofs, u16_t len, struct snmp_obj_id *oid) -{ - u16_t plen, base; - u8_t *msg_ptr; - s32_t *oid_ptr; - - plen = 0; - while (p != NULL) - { - base = plen; - plen += p->len; - if (ofs < plen) - { - msg_ptr = (u8_t*)p->payload; - msg_ptr += ofs - base; - - oid->len = 0; - oid_ptr = &oid->id[0]; - if (len > 0) - { - /* first compressed octet */ - if (*msg_ptr == 0x2B) - { - /* (most) common case 1.3 (iso.org) */ - *oid_ptr = 1; - oid_ptr++; - *oid_ptr = 3; - oid_ptr++; - } - else if (*msg_ptr < 40) - { - *oid_ptr = 0; - oid_ptr++; - *oid_ptr = *msg_ptr; - oid_ptr++; - } - else if (*msg_ptr < 80) - { - *oid_ptr = 1; - oid_ptr++; - *oid_ptr = (*msg_ptr) - 40; - oid_ptr++; - } - else - { - *oid_ptr = 2; - oid_ptr++; - *oid_ptr = (*msg_ptr) - 80; - oid_ptr++; - } - oid->len = 2; - } - else - { - /* accepting zero length identifiers e.g. for - getnext operation. uncommon but valid */ - return ERR_OK; - } - len--; - if (len > 0) - { - ofs += 1; - if (ofs >= plen) - { - /* next octet in next pbuf */ - p = p->next; - if (p == NULL) { return ERR_ARG; } - msg_ptr = (u8_t*)p->payload; - plen += p->len; - } - else - { - /* next octet in same pbuf */ - msg_ptr++; - } - } - while ((len > 0) && (oid->len < LWIP_SNMP_OBJ_ID_LEN)) - { - /* sub-identifier uses multiple octets */ - if (*msg_ptr & 0x80) - { - s32_t sub_id = 0; - - while ((*msg_ptr & 0x80) && (len > 1)) - { - len--; - sub_id = (sub_id << 7) + (*msg_ptr & ~0x80); - ofs += 1; - if (ofs >= plen) - { - /* next octet in next pbuf */ - p = p->next; - if (p == NULL) { return ERR_ARG; } - msg_ptr = (u8_t*)p->payload; - plen += p->len; - } - else - { - /* next octet in same pbuf */ - msg_ptr++; - } - } - if (!(*msg_ptr & 0x80) && (len > 0)) - { - /* last octet sub-identifier */ - len--; - sub_id = (sub_id << 7) + *msg_ptr; - *oid_ptr = sub_id; - } - } - else - { - /* !(*msg_ptr & 0x80) sub-identifier uses single octet */ - len--; - *oid_ptr = *msg_ptr; - } - if (len > 0) - { - /* remaining oid bytes available ... */ - ofs += 1; - if (ofs >= plen) - { - /* next octet in next pbuf */ - p = p->next; - if (p == NULL) { return ERR_ARG; } - msg_ptr = (u8_t*)p->payload; - plen += p->len; - } - else - { - /* next octet in same pbuf */ - msg_ptr++; - } - } - oid_ptr++; - oid->len++; - } - if (len == 0) - { - /* len == 0, end of oid */ - return ERR_OK; - } - else - { - /* len > 0, oid->len == LWIP_SNMP_OBJ_ID_LEN or malformed encoding */ - return ERR_ARG; - } - - } - p = p->next; - } - /* p == NULL, ofs >= plen */ - return ERR_ARG; -} - -/** - * Decodes (copies) raw data (ip-addresses, octet strings, opaque encoding) - * from incoming message into array. - * - * @param p points to a pbuf holding an ASN1 coded raw data - * @param ofs points to the offset within the pbuf chain of the ASN1 coded raw data - * @param len length of the coded raw data (zero is valid, e.g. empty string!) - * @param raw_len length of the raw return value - * @param raw return raw bytes - * @return ERR_OK if successfull, ERR_ARG if we can't (or won't) decode - */ -err_t -snmp_asn1_dec_raw(struct pbuf *p, u16_t ofs, u16_t len, u16_t raw_len, u8_t *raw) -{ - u16_t plen, base; - u8_t *msg_ptr; - - if (len > 0) - { - plen = 0; - while (p != NULL) - { - base = plen; - plen += p->len; - if (ofs < plen) - { - msg_ptr = (u8_t*)p->payload; - msg_ptr += ofs - base; - if (raw_len >= len) - { - while (len > 1) - { - /* copy len - 1 octets */ - len--; - *raw = *msg_ptr; - raw++; - ofs += 1; - if (ofs >= plen) - { - /* next octet in next pbuf */ - p = p->next; - if (p == NULL) { return ERR_ARG; } - msg_ptr = (u8_t*)p->payload; - plen += p->len; - } - else - { - /* next octet in same pbuf */ - msg_ptr++; - } - } - /* copy last octet */ - *raw = *msg_ptr; - return ERR_OK; - } - else - { - /* raw_len < len, not enough dst space */ - return ERR_ARG; - } - } - p = p->next; - } - /* p == NULL, ofs >= plen */ - return ERR_ARG; - } - else - { - /* len == 0, empty string */ - return ERR_OK; - } -} - -#endif /* LWIP_SNMP */ diff --git a/features/net/FEATURE_IPV4/lwip-interface/lwip/core/snmp/lwip_asn1_enc.c b/features/net/FEATURE_IPV4/lwip-interface/lwip/core/snmp/lwip_asn1_enc.c deleted file mode 100644 index 64dfc5f6ea..0000000000 --- a/features/net/FEATURE_IPV4/lwip-interface/lwip/core/snmp/lwip_asn1_enc.c +++ /dev/null @@ -1,611 +0,0 @@ -/** - * @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 - */ - -#include "lwip/opt.h" - -#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/snmp_asn1.h" - -/** - * Returns octet count for length. - * - * @param 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 - * @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 s32_t. - * - * @param value - * @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 ident_len object identifier array length - * @param ident points to object identifier array - * @param octets_needed points to the return value - */ -void -snmp_asn1_enc_oid_cnt(u8_t ident_len, s32_t *ident, u16_t *octets_needed) -{ - s32_t sub_id; - u8_t cnt; - - cnt = 0; - if (ident_len > 1) - { - /* compressed prefix in one octet */ - cnt++; - ident_len -= 2; - ident += 2; - } - while(ident_len > 0) - { - ident_len--; - sub_id = *ident; - - sub_id >>= 7; - cnt++; - while(sub_id > 0) - { - sub_id >>= 7; - cnt++; - } - ident++; - } - *octets_needed = cnt; -} - -/** - * Encodes ASN type field into a pbuf chained ASN1 msg. - * - * @param p points to output pbuf to encode value into - * @param ofs points to the offset within the pbuf chain - * @param type input ASN1 type - * @return ERR_OK if successfull, ERR_ARG if we can't (or won't) encode - */ -err_t -snmp_asn1_enc_type(struct pbuf *p, u16_t ofs, u8_t type) -{ - u16_t plen, base; - u8_t *msg_ptr; - - plen = 0; - while (p != NULL) - { - base = plen; - plen += p->len; - if (ofs < plen) - { - msg_ptr = (u8_t*)p->payload; - msg_ptr += ofs - base; - *msg_ptr = type; - return ERR_OK; - } - p = p->next; - } - /* p == NULL, ofs >= plen */ - return ERR_ARG; -} - -/** - * Encodes host order length field into a pbuf chained ASN1 msg. - * - * @param p points to output pbuf to encode length into - * @param ofs points to the offset within the pbuf chain - * @param length is the host order length to be encoded - * @return ERR_OK if successfull, ERR_ARG if we can't (or won't) encode - */ -err_t -snmp_asn1_enc_length(struct pbuf *p, u16_t ofs, u16_t length) -{ - u16_t plen, base; - u8_t *msg_ptr; - - plen = 0; - while (p != NULL) - { - base = plen; - plen += p->len; - if (ofs < plen) - { - msg_ptr = (u8_t*)p->payload; - msg_ptr += ofs - base; - - if (length < 0x80) - { - *msg_ptr = (u8_t)length; - return ERR_OK; - } - else if (length < 0x100) - { - *msg_ptr = 0x81; - ofs += 1; - if (ofs >= plen) - { - /* next octet in next pbuf */ - p = p->next; - if (p == NULL) { return ERR_ARG; } - msg_ptr = (u8_t*)p->payload; - } - else - { - /* next octet in same pbuf */ - msg_ptr++; - } - *msg_ptr = (u8_t)length; - return ERR_OK; - } - else - { - u8_t i; - - /* length >= 0x100 && length <= 0xFFFF */ - *msg_ptr = 0x82; - i = 2; - while (i > 0) - { - i--; - ofs += 1; - if (ofs >= plen) - { - /* next octet in next pbuf */ - p = p->next; - if (p == NULL) { return ERR_ARG; } - msg_ptr = (u8_t*)p->payload; - plen += p->len; - } - else - { - /* next octet in same pbuf */ - msg_ptr++; - } - if (i == 0) - { - /* least significant length octet */ - *msg_ptr = (u8_t)length; - } - else - { - /* most significant length octet */ - *msg_ptr = (u8_t)(length >> 8); - } - } - return ERR_OK; - } - } - p = p->next; - } - /* p == NULL, ofs >= plen */ - return ERR_ARG; -} - -/** - * Encodes u32_t (counter, gauge, timeticks) into a pbuf chained ASN1 msg. - * - * @param p points to output pbuf to encode value into - * @param ofs points to the offset within the pbuf chain - * @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 successfull, ERR_ARG if we can't (or won't) encode - * - * @see snmp_asn1_enc_u32t_cnt() - */ -err_t -snmp_asn1_enc_u32t(struct pbuf *p, u16_t ofs, u16_t octets_needed, u32_t value) -{ - u16_t plen, base; - u8_t *msg_ptr; - - plen = 0; - while (p != NULL) - { - base = plen; - plen += p->len; - if (ofs < plen) - { - msg_ptr = (u8_t*)p->payload; - msg_ptr += ofs - base; - - if (octets_needed == 5) - { - /* not enough bits in 'value' add leading 0x00 */ - octets_needed--; - *msg_ptr = 0x00; - ofs += 1; - if (ofs >= plen) - { - /* next octet in next pbuf */ - p = p->next; - if (p == NULL) { return ERR_ARG; } - msg_ptr = (u8_t*)p->payload; - plen += p->len; - } - else - { - /* next octet in same pbuf */ - msg_ptr++; - } - } - while (octets_needed > 1) - { - octets_needed--; - *msg_ptr = (u8_t)(value >> (octets_needed << 3)); - ofs += 1; - if (ofs >= plen) - { - /* next octet in next pbuf */ - p = p->next; - if (p == NULL) { return ERR_ARG; } - msg_ptr = (u8_t*)p->payload; - plen += p->len; - } - else - { - /* next octet in same pbuf */ - msg_ptr++; - } - } - /* (only) one least significant octet */ - *msg_ptr = (u8_t)value; - return ERR_OK; - } - p = p->next; - } - /* p == NULL, ofs >= plen */ - return ERR_ARG; -} - -/** - * Encodes s32_t integer into a pbuf chained ASN1 msg. - * - * @param p points to output pbuf to encode value into - * @param ofs points to the offset within the pbuf chain - * @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 successfull, ERR_ARG if we can't (or won't) encode - * - * @see snmp_asn1_enc_s32t_cnt() - */ -err_t -snmp_asn1_enc_s32t(struct pbuf *p, u16_t ofs, u16_t octets_needed, s32_t value) -{ - u16_t plen, base; - u8_t *msg_ptr; - - plen = 0; - while (p != NULL) - { - base = plen; - plen += p->len; - if (ofs < plen) - { - msg_ptr = (u8_t*)p->payload; - msg_ptr += ofs - base; - - while (octets_needed > 1) - { - octets_needed--; - *msg_ptr = (u8_t)(value >> (octets_needed << 3)); - ofs += 1; - if (ofs >= plen) - { - /* next octet in next pbuf */ - p = p->next; - if (p == NULL) { return ERR_ARG; } - msg_ptr = (u8_t*)p->payload; - plen += p->len; - } - else - { - /* next octet in same pbuf */ - msg_ptr++; - } - } - /* (only) one least significant octet */ - *msg_ptr = (u8_t)value; - return ERR_OK; - } - p = p->next; - } - /* p == NULL, ofs >= plen */ - return ERR_ARG; -} - -/** - * Encodes object identifier into a pbuf chained ASN1 msg. - * - * @param p points to output pbuf to encode oid into - * @param ofs points to the offset within the pbuf chain - * @param ident_len object identifier array length - * @param ident points to object identifier array - * @return ERR_OK if successfull, ERR_ARG if we can't (or won't) encode - */ -err_t -snmp_asn1_enc_oid(struct pbuf *p, u16_t ofs, u8_t ident_len, s32_t *ident) -{ - u16_t plen, base; - u8_t *msg_ptr; - - plen = 0; - while (p != NULL) - { - base = plen; - plen += p->len; - if (ofs < plen) - { - msg_ptr = (u8_t*)p->payload; - msg_ptr += ofs - base; - - if (ident_len > 1) - { - if ((ident[0] == 1) && (ident[1] == 3)) - { - /* compressed (most common) prefix .iso.org */ - *msg_ptr = 0x2b; - } - else - { - /* calculate prefix */ - *msg_ptr = (u8_t)((ident[0] * 40) + ident[1]); - } - ofs += 1; - if (ofs >= plen) - { - /* next octet in next pbuf */ - p = p->next; - if (p == NULL) { return ERR_ARG; } - msg_ptr = (u8_t*)p->payload; - plen += p->len; - } - else - { - /* next octet in same pbuf */ - msg_ptr++; - } - ident_len -= 2; - ident += 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 (ident_len > 0) - { - s32_t sub_id; - u8_t shift, tail; - - ident_len--; - sub_id = *ident; - tail = 0; - shift = 28; - while(shift > 0) - { - u8_t code; - - code = (u8_t)(sub_id >> shift); - if ((code != 0) || (tail != 0)) - { - tail = 1; - *msg_ptr = code | 0x80; - ofs += 1; - if (ofs >= plen) - { - /* next octet in next pbuf */ - p = p->next; - if (p == NULL) { return ERR_ARG; } - msg_ptr = (u8_t*)p->payload; - plen += p->len; - } - else - { - /* next octet in same pbuf */ - msg_ptr++; - } - } - shift -= 7; - } - *msg_ptr = (u8_t)sub_id & 0x7F; - if (ident_len > 0) - { - ofs += 1; - if (ofs >= plen) - { - /* next octet in next pbuf */ - p = p->next; - if (p == NULL) { return ERR_ARG; } - msg_ptr = (u8_t*)p->payload; - plen += p->len; - } - else - { - /* next octet in same pbuf */ - msg_ptr++; - } - } - /* proceed to next sub-identifier */ - ident++; - } - return ERR_OK; - } - p = p->next; - } - /* p == NULL, ofs >= plen */ - return ERR_ARG; -} - -/** - * Encodes raw data (octet string, opaque) into a pbuf chained ASN1 msg. - * - * @param p points to output pbuf to encode raw data into - * @param ofs points to the offset within the pbuf chain - * @param raw_len raw data length - * @param raw points raw data - * @return ERR_OK if successfull, ERR_ARG if we can't (or won't) encode - */ -err_t -snmp_asn1_enc_raw(struct pbuf *p, u16_t ofs, u16_t raw_len, u8_t *raw) -{ - u16_t plen, base; - u8_t *msg_ptr; - - plen = 0; - while (p != NULL) - { - base = plen; - plen += p->len; - if (ofs < plen) - { - msg_ptr = (u8_t*)p->payload; - msg_ptr += ofs - base; - - while (raw_len > 1) - { - /* copy raw_len - 1 octets */ - raw_len--; - *msg_ptr = *raw; - raw++; - ofs += 1; - if (ofs >= plen) - { - /* next octet in next pbuf */ - p = p->next; - if (p == NULL) { return ERR_ARG; } - msg_ptr = (u8_t*)p->payload; - plen += p->len; - } - else - { - /* next octet in same pbuf */ - msg_ptr++; - } - } - if (raw_len > 0) - { - /* copy last or single octet */ - *msg_ptr = *raw; - } - return ERR_OK; - } - p = p->next; - } - /* p == NULL, ofs >= plen */ - return ERR_ARG; -} - -#endif /* LWIP_SNMP */ diff --git a/features/net/FEATURE_IPV4/lwip-interface/lwip/core/snmp/lwip_mib2.c b/features/net/FEATURE_IPV4/lwip-interface/lwip/core/snmp/lwip_mib2.c deleted file mode 100644 index 29decd306f..0000000000 --- a/features/net/FEATURE_IPV4/lwip-interface/lwip/core/snmp/lwip_mib2.c +++ /dev/null @@ -1,4146 +0,0 @@ -/** - * @file - * Management Information Base II (RFC1213) objects and functions. - * - * @note the object identifiers for this MIB-2 and private MIB tree - * must be kept in sorted ascending order. This to ensure correct getnext operation. - */ - -/* - * 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 - */ - -#include "lwip/opt.h" - -#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/snmp.h" -#include "lwip/netif.h" -#include "lwip/ip.h" -#include "lwip/ip_frag.h" -#include "lwip/mem.h" -#include "lwip/tcp_impl.h" -#include "lwip/udp.h" -#include "lwip/snmp_asn1.h" -#include "lwip/snmp_structs.h" -#include "lwip/sys.h" -#include "netif/etharp.h" - -/** - * 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 (contact Christiaan Simons)! - * @note don't change this define, use snmp_set_sysobjid() - * - * 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_ENTERPRISE_ID 26381 -#define SNMP_SYSOBJID_LEN 7 -#define SNMP_SYSOBJID {1, 3, 6, 1, 4, 1, SNMP_ENTERPRISE_ID} - -#ifndef SNMP_SYSSERVICES -#define SNMP_SYSSERVICES ((1 << 6) | (1 << 3) | ((IP_FORWARD) << 2)) -#endif - -#ifndef SNMP_GET_SYSUPTIME -#define SNMP_GET_SYSUPTIME(sysuptime) -#endif - -static void system_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od); -static void system_get_value(struct obj_def *od, u16_t len, void *value); -static u8_t system_set_test(struct obj_def *od, u16_t len, void *value); -static void system_set_value(struct obj_def *od, u16_t len, void *value); -static void interfaces_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od); -static void interfaces_get_value(struct obj_def *od, u16_t len, void *value); -static void ifentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od); -static void ifentry_get_value(struct obj_def *od, u16_t len, void *value); -#if !SNMP_SAFE_REQUESTS -static u8_t ifentry_set_test (struct obj_def *od, u16_t len, void *value); -static void ifentry_set_value (struct obj_def *od, u16_t len, void *value); -#endif /* SNMP_SAFE_REQUESTS */ -static void atentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od); -static void atentry_get_value(struct obj_def *od, u16_t len, void *value); -static void ip_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od); -static void ip_get_value(struct obj_def *od, u16_t len, void *value); -static u8_t ip_set_test(struct obj_def *od, u16_t len, void *value); -static void ip_addrentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od); -static void ip_addrentry_get_value(struct obj_def *od, u16_t len, void *value); -static void ip_rteentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od); -static void ip_rteentry_get_value(struct obj_def *od, u16_t len, void *value); -static void ip_ntomentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od); -static void ip_ntomentry_get_value(struct obj_def *od, u16_t len, void *value); -static void icmp_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od); -static void icmp_get_value(struct obj_def *od, u16_t len, void *value); -#if LWIP_TCP -static void tcp_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od); -static void tcp_get_value(struct obj_def *od, u16_t len, void *value); -#ifdef THIS_SEEMS_UNUSED -static void tcpconnentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od); -static void tcpconnentry_get_value(struct obj_def *od, u16_t len, void *value); -#endif -#endif -static void udp_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od); -static void udp_get_value(struct obj_def *od, u16_t len, void *value); -static void udpentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od); -static void udpentry_get_value(struct obj_def *od, u16_t len, void *value); -static void snmp_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od); -static void snmp_get_value(struct obj_def *od, u16_t len, void *value); -static u8_t snmp_set_test(struct obj_def *od, u16_t len, void *value); -static void snmp_set_value(struct obj_def *od, u16_t len, void *value); - - -/* snmp .1.3.6.1.2.1.11 */ -const mib_scalar_node snmp_scalar = { - &snmp_get_object_def, - &snmp_get_value, - &snmp_set_test, - &snmp_set_value, - MIB_NODE_SC, - 0 -}; -const s32_t snmp_ids[28] = { - 1, 2, 3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14, 15, 16, - 17, 18, 19, 20, 21, 22, 24, 25, 26, 27, 28, 29, 30 -}; -struct mib_node* const snmp_nodes[28] = { - (struct mib_node*)&snmp_scalar, (struct mib_node*)&snmp_scalar, - (struct mib_node*)&snmp_scalar, (struct mib_node*)&snmp_scalar, - (struct mib_node*)&snmp_scalar, (struct mib_node*)&snmp_scalar, - (struct mib_node*)&snmp_scalar, (struct mib_node*)&snmp_scalar, - (struct mib_node*)&snmp_scalar, (struct mib_node*)&snmp_scalar, - (struct mib_node*)&snmp_scalar, (struct mib_node*)&snmp_scalar, - (struct mib_node*)&snmp_scalar, (struct mib_node*)&snmp_scalar, - (struct mib_node*)&snmp_scalar, (struct mib_node*)&snmp_scalar, - (struct mib_node*)&snmp_scalar, (struct mib_node*)&snmp_scalar, - (struct mib_node*)&snmp_scalar, (struct mib_node*)&snmp_scalar, - (struct mib_node*)&snmp_scalar, (struct mib_node*)&snmp_scalar, - (struct mib_node*)&snmp_scalar, (struct mib_node*)&snmp_scalar, - (struct mib_node*)&snmp_scalar, (struct mib_node*)&snmp_scalar, - (struct mib_node*)&snmp_scalar, (struct mib_node*)&snmp_scalar -}; -const struct mib_array_node snmp = { - &noleafs_get_object_def, - &noleafs_get_value, - &noleafs_set_test, - &noleafs_set_value, - MIB_NODE_AR, - 28, - snmp_ids, - snmp_nodes -}; - -/* 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) */ - -/* udp .1.3.6.1.2.1.7 */ -/** index root node for udpTable */ -struct mib_list_rootnode udp_root = { - &noleafs_get_object_def, - &noleafs_get_value, - &noleafs_set_test, - &noleafs_set_value, - MIB_NODE_LR, - 0, - NULL, - NULL, - 0 -}; -const s32_t udpentry_ids[2] = { 1, 2 }; -struct mib_node* const udpentry_nodes[2] = { - (struct mib_node*)&udp_root, (struct mib_node*)&udp_root, -}; -const struct mib_array_node udpentry = { - &noleafs_get_object_def, - &noleafs_get_value, - &noleafs_set_test, - &noleafs_set_value, - MIB_NODE_AR, - 2, - udpentry_ids, - udpentry_nodes -}; - -s32_t udptable_id = 1; -struct mib_node* udptable_node = (struct mib_node*)&udpentry; -struct mib_ram_array_node udptable = { - &noleafs_get_object_def, - &noleafs_get_value, - &noleafs_set_test, - &noleafs_set_value, - MIB_NODE_RA, - 0, - &udptable_id, - &udptable_node -}; - -const mib_scalar_node udp_scalar = { - &udp_get_object_def, - &udp_get_value, - &noleafs_set_test, - &noleafs_set_value, - MIB_NODE_SC, - 0 -}; -const s32_t udp_ids[5] = { 1, 2, 3, 4, 5 }; -struct mib_node* const udp_nodes[5] = { - (struct mib_node*)&udp_scalar, (struct mib_node*)&udp_scalar, - (struct mib_node*)&udp_scalar, (struct mib_node*)&udp_scalar, - (struct mib_node*)&udptable -}; -const struct mib_array_node udp = { - &noleafs_get_object_def, - &noleafs_get_value, - &noleafs_set_test, - &noleafs_set_value, - MIB_NODE_AR, - 5, - udp_ids, - udp_nodes -}; - -/* tcp .1.3.6.1.2.1.6 */ -#if LWIP_TCP -/* only if the TCP protocol is available may implement this group */ -/** index root node for tcpConnTable */ -struct mib_list_rootnode tcpconntree_root = { - &noleafs_get_object_def, - &noleafs_get_value, - &noleafs_set_test, - &noleafs_set_value, - MIB_NODE_LR, - 0, - NULL, - NULL, - 0 -}; -const s32_t tcpconnentry_ids[5] = { 1, 2, 3, 4, 5 }; -struct mib_node* const tcpconnentry_nodes[5] = { - (struct mib_node*)&tcpconntree_root, (struct mib_node*)&tcpconntree_root, - (struct mib_node*)&tcpconntree_root, (struct mib_node*)&tcpconntree_root, - (struct mib_node*)&tcpconntree_root -}; -const struct mib_array_node tcpconnentry = { - &noleafs_get_object_def, - &noleafs_get_value, - &noleafs_set_test, - &noleafs_set_value, - MIB_NODE_AR, - 5, - tcpconnentry_ids, - tcpconnentry_nodes -}; - -s32_t tcpconntable_id = 1; -struct mib_node* tcpconntable_node = (struct mib_node*)&tcpconnentry; -struct mib_ram_array_node tcpconntable = { - &noleafs_get_object_def, - &noleafs_get_value, - &noleafs_set_test, - &noleafs_set_value, - MIB_NODE_RA, -/** @todo update maxlength when inserting / deleting from table - 0 when table is empty, 1 when more than one entry */ - 0, - &tcpconntable_id, - &tcpconntable_node -}; - -const mib_scalar_node tcp_scalar = { - &tcp_get_object_def, - &tcp_get_value, - &noleafs_set_test, - &noleafs_set_value, - MIB_NODE_SC, - 0 -}; -const s32_t tcp_ids[15] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }; -struct mib_node* const tcp_nodes[15] = { - (struct mib_node*)&tcp_scalar, (struct mib_node*)&tcp_scalar, - (struct mib_node*)&tcp_scalar, (struct mib_node*)&tcp_scalar, - (struct mib_node*)&tcp_scalar, (struct mib_node*)&tcp_scalar, - (struct mib_node*)&tcp_scalar, (struct mib_node*)&tcp_scalar, - (struct mib_node*)&tcp_scalar, (struct mib_node*)&tcp_scalar, - (struct mib_node*)&tcp_scalar, (struct mib_node*)&tcp_scalar, - (struct mib_node*)&tcpconntable, (struct mib_node*)&tcp_scalar, - (struct mib_node*)&tcp_scalar -}; -const struct mib_array_node tcp = { - &noleafs_get_object_def, - &noleafs_get_value, - &noleafs_set_test, - &noleafs_set_value, - MIB_NODE_AR, - 15, - tcp_ids, - tcp_nodes -}; -#endif - -/* icmp .1.3.6.1.2.1.5 */ -const mib_scalar_node icmp_scalar = { - &icmp_get_object_def, - &icmp_get_value, - &noleafs_set_test, - &noleafs_set_value, - MIB_NODE_SC, - 0 -}; -const s32_t icmp_ids[26] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26 }; -struct mib_node* const icmp_nodes[26] = { - (struct mib_node*)&icmp_scalar, (struct mib_node*)&icmp_scalar, - (struct mib_node*)&icmp_scalar, (struct mib_node*)&icmp_scalar, - (struct mib_node*)&icmp_scalar, (struct mib_node*)&icmp_scalar, - (struct mib_node*)&icmp_scalar, (struct mib_node*)&icmp_scalar, - (struct mib_node*)&icmp_scalar, (struct mib_node*)&icmp_scalar, - (struct mib_node*)&icmp_scalar, (struct mib_node*)&icmp_scalar, - (struct mib_node*)&icmp_scalar, (struct mib_node*)&icmp_scalar, - (struct mib_node*)&icmp_scalar, (struct mib_node*)&icmp_scalar, - (struct mib_node*)&icmp_scalar, (struct mib_node*)&icmp_scalar, - (struct mib_node*)&icmp_scalar, (struct mib_node*)&icmp_scalar, - (struct mib_node*)&icmp_scalar, (struct mib_node*)&icmp_scalar, - (struct mib_node*)&icmp_scalar, (struct mib_node*)&icmp_scalar, - (struct mib_node*)&icmp_scalar, (struct mib_node*)&icmp_scalar -}; -const struct mib_array_node icmp = { - &noleafs_get_object_def, - &noleafs_get_value, - &noleafs_set_test, - &noleafs_set_value, - MIB_NODE_AR, - 26, - icmp_ids, - icmp_nodes -}; - -/** index root node for ipNetToMediaTable */ -struct mib_list_rootnode ipntomtree_root = { - &noleafs_get_object_def, - &noleafs_get_value, - &noleafs_set_test, - &noleafs_set_value, - MIB_NODE_LR, - 0, - NULL, - NULL, - 0 -}; -const s32_t ipntomentry_ids[4] = { 1, 2, 3, 4 }; -struct mib_node* const ipntomentry_nodes[4] = { - (struct mib_node*)&ipntomtree_root, (struct mib_node*)&ipntomtree_root, - (struct mib_node*)&ipntomtree_root, (struct mib_node*)&ipntomtree_root -}; -const struct mib_array_node ipntomentry = { - &noleafs_get_object_def, - &noleafs_get_value, - &noleafs_set_test, - &noleafs_set_value, - MIB_NODE_AR, - 4, - ipntomentry_ids, - ipntomentry_nodes -}; - -s32_t ipntomtable_id = 1; -struct mib_node* ipntomtable_node = (struct mib_node*)&ipntomentry; -struct mib_ram_array_node ipntomtable = { - &noleafs_get_object_def, - &noleafs_get_value, - &noleafs_set_test, - &noleafs_set_value, - MIB_NODE_RA, - 0, - &ipntomtable_id, - &ipntomtable_node -}; - -/** index root node for ipRouteTable */ -struct mib_list_rootnode iprtetree_root = { - &noleafs_get_object_def, - &noleafs_get_value, - &noleafs_set_test, - &noleafs_set_value, - MIB_NODE_LR, - 0, - NULL, - NULL, - 0 -}; -const s32_t iprteentry_ids[13] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 }; -struct mib_node* const iprteentry_nodes[13] = { - (struct mib_node*)&iprtetree_root, (struct mib_node*)&iprtetree_root, - (struct mib_node*)&iprtetree_root, (struct mib_node*)&iprtetree_root, - (struct mib_node*)&iprtetree_root, (struct mib_node*)&iprtetree_root, - (struct mib_node*)&iprtetree_root, (struct mib_node*)&iprtetree_root, - (struct mib_node*)&iprtetree_root, (struct mib_node*)&iprtetree_root, - (struct mib_node*)&iprtetree_root, (struct mib_node*)&iprtetree_root, - (struct mib_node*)&iprtetree_root -}; -const struct mib_array_node iprteentry = { - &noleafs_get_object_def, - &noleafs_get_value, - &noleafs_set_test, - &noleafs_set_value, - MIB_NODE_AR, - 13, - iprteentry_ids, - iprteentry_nodes -}; - -s32_t iprtetable_id = 1; -struct mib_node* iprtetable_node = (struct mib_node*)&iprteentry; -struct mib_ram_array_node iprtetable = { - &noleafs_get_object_def, - &noleafs_get_value, - &noleafs_set_test, - &noleafs_set_value, - MIB_NODE_RA, - 0, - &iprtetable_id, - &iprtetable_node -}; - -/** index root node for ipAddrTable */ -struct mib_list_rootnode ipaddrtree_root = { - &noleafs_get_object_def, - &noleafs_get_value, - &noleafs_set_test, - &noleafs_set_value, - MIB_NODE_LR, - 0, - NULL, - NULL, - 0 -}; -const s32_t ipaddrentry_ids[5] = { 1, 2, 3, 4, 5 }; -struct mib_node* const ipaddrentry_nodes[5] = { - (struct mib_node*)&ipaddrtree_root, - (struct mib_node*)&ipaddrtree_root, - (struct mib_node*)&ipaddrtree_root, - (struct mib_node*)&ipaddrtree_root, - (struct mib_node*)&ipaddrtree_root -}; -const struct mib_array_node ipaddrentry = { - &noleafs_get_object_def, - &noleafs_get_value, - &noleafs_set_test, - &noleafs_set_value, - MIB_NODE_AR, - 5, - ipaddrentry_ids, - ipaddrentry_nodes -}; - -s32_t ipaddrtable_id = 1; -struct mib_node* ipaddrtable_node = (struct mib_node*)&ipaddrentry; -struct mib_ram_array_node ipaddrtable = { - &noleafs_get_object_def, - &noleafs_get_value, - &noleafs_set_test, - &noleafs_set_value, - MIB_NODE_RA, - 0, - &ipaddrtable_id, - &ipaddrtable_node -}; - -/* ip .1.3.6.1.2.1.4 */ -const mib_scalar_node ip_scalar = { - &ip_get_object_def, - &ip_get_value, - &ip_set_test, - &noleafs_set_value, - MIB_NODE_SC, - 0 -}; -const s32_t ip_ids[23] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23 }; -struct mib_node* const ip_nodes[23] = { - (struct mib_node*)&ip_scalar, (struct mib_node*)&ip_scalar, - (struct mib_node*)&ip_scalar, (struct mib_node*)&ip_scalar, - (struct mib_node*)&ip_scalar, (struct mib_node*)&ip_scalar, - (struct mib_node*)&ip_scalar, (struct mib_node*)&ip_scalar, - (struct mib_node*)&ip_scalar, (struct mib_node*)&ip_scalar, - (struct mib_node*)&ip_scalar, (struct mib_node*)&ip_scalar, - (struct mib_node*)&ip_scalar, (struct mib_node*)&ip_scalar, - (struct mib_node*)&ip_scalar, (struct mib_node*)&ip_scalar, - (struct mib_node*)&ip_scalar, (struct mib_node*)&ip_scalar, - (struct mib_node*)&ip_scalar, (struct mib_node*)&ipaddrtable, - (struct mib_node*)&iprtetable, (struct mib_node*)&ipntomtable, - (struct mib_node*)&ip_scalar -}; -const struct mib_array_node mib2_ip = { - &noleafs_get_object_def, - &noleafs_get_value, - &noleafs_set_test, - &noleafs_set_value, - MIB_NODE_AR, - 23, - ip_ids, - ip_nodes -}; - -/** index root node for atTable */ -struct mib_list_rootnode arptree_root = { - &noleafs_get_object_def, - &noleafs_get_value, - &noleafs_set_test, - &noleafs_set_value, - MIB_NODE_LR, - 0, - NULL, - NULL, - 0 -}; -const s32_t atentry_ids[3] = { 1, 2, 3 }; -struct mib_node* const atentry_nodes[3] = { - (struct mib_node*)&arptree_root, - (struct mib_node*)&arptree_root, - (struct mib_node*)&arptree_root -}; -const struct mib_array_node atentry = { - &noleafs_get_object_def, - &noleafs_get_value, - &noleafs_set_test, - &noleafs_set_value, - MIB_NODE_AR, - 3, - atentry_ids, - atentry_nodes -}; - -const s32_t attable_id = 1; -struct mib_node* const attable_node = (struct mib_node*)&atentry; -const struct mib_array_node attable = { - &noleafs_get_object_def, - &noleafs_get_value, - &noleafs_set_test, - &noleafs_set_value, - MIB_NODE_AR, - 1, - &attable_id, - &attable_node -}; - -/* at .1.3.6.1.2.1.3 */ -s32_t at_id = 1; -struct mib_node* mib2_at_node = (struct mib_node*)&attable; -struct mib_ram_array_node at = { - &noleafs_get_object_def, - &noleafs_get_value, - &noleafs_set_test, - &noleafs_set_value, - MIB_NODE_RA, - 0, - &at_id, - &mib2_at_node -}; - -/** index root node for ifTable */ -struct mib_list_rootnode iflist_root = { - &ifentry_get_object_def, - &ifentry_get_value, -#if SNMP_SAFE_REQUESTS - &noleafs_set_test, - &noleafs_set_value, -#else /* SNMP_SAFE_REQUESTS */ - &ifentry_set_test, - &ifentry_set_value, -#endif /* SNMP_SAFE_REQUESTS */ - MIB_NODE_LR, - 0, - NULL, - NULL, - 0 -}; -const s32_t ifentry_ids[22] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22 }; -struct mib_node* const ifentry_nodes[22] = { - (struct mib_node*)&iflist_root, (struct mib_node*)&iflist_root, - (struct mib_node*)&iflist_root, (struct mib_node*)&iflist_root, - (struct mib_node*)&iflist_root, (struct mib_node*)&iflist_root, - (struct mib_node*)&iflist_root, (struct mib_node*)&iflist_root, - (struct mib_node*)&iflist_root, (struct mib_node*)&iflist_root, - (struct mib_node*)&iflist_root, (struct mib_node*)&iflist_root, - (struct mib_node*)&iflist_root, (struct mib_node*)&iflist_root, - (struct mib_node*)&iflist_root, (struct mib_node*)&iflist_root, - (struct mib_node*)&iflist_root, (struct mib_node*)&iflist_root, - (struct mib_node*)&iflist_root, (struct mib_node*)&iflist_root, - (struct mib_node*)&iflist_root, (struct mib_node*)&iflist_root -}; -const struct mib_array_node ifentry = { - &noleafs_get_object_def, - &noleafs_get_value, - &noleafs_set_test, - &noleafs_set_value, - MIB_NODE_AR, - 22, - ifentry_ids, - ifentry_nodes -}; - -s32_t iftable_id = 1; -struct mib_node* iftable_node = (struct mib_node*)&ifentry; -struct mib_ram_array_node iftable = { - &noleafs_get_object_def, - &noleafs_get_value, - &noleafs_set_test, - &noleafs_set_value, - MIB_NODE_RA, - 0, - &iftable_id, - &iftable_node -}; - -/* interfaces .1.3.6.1.2.1.2 */ -const mib_scalar_node interfaces_scalar = { - &interfaces_get_object_def, - &interfaces_get_value, - &noleafs_set_test, - &noleafs_set_value, - MIB_NODE_SC, - 0 -}; -const s32_t interfaces_ids[2] = { 1, 2 }; -struct mib_node* const interfaces_nodes[2] = { - (struct mib_node*)&interfaces_scalar, (struct mib_node*)&iftable -}; -const struct mib_array_node interfaces = { - &noleafs_get_object_def, - &noleafs_get_value, - &noleafs_set_test, - &noleafs_set_value, - MIB_NODE_AR, - 2, - interfaces_ids, - interfaces_nodes -}; - - -/* 0 1 2 3 4 5 6 */ -/* system .1.3.6.1.2.1.1 */ -const mib_scalar_node sys_tem_scalar = { - &system_get_object_def, - &system_get_value, - &system_set_test, - &system_set_value, - MIB_NODE_SC, - 0 -}; -const s32_t sys_tem_ids[7] = { 1, 2, 3, 4, 5, 6, 7 }; -struct mib_node* const sys_tem_nodes[7] = { - (struct mib_node*)&sys_tem_scalar, (struct mib_node*)&sys_tem_scalar, - (struct mib_node*)&sys_tem_scalar, (struct mib_node*)&sys_tem_scalar, - (struct mib_node*)&sys_tem_scalar, (struct mib_node*)&sys_tem_scalar, - (struct mib_node*)&sys_tem_scalar -}; -/* work around name issue with 'sys_tem', some compiler(s?) seem to reserve 'system' */ -const struct mib_array_node sys_tem = { - &noleafs_get_object_def, - &noleafs_get_value, - &noleafs_set_test, - &noleafs_set_value, - MIB_NODE_AR, - 7, - sys_tem_ids, - sys_tem_nodes -}; - -/* mib-2 .1.3.6.1.2.1 */ -#if LWIP_TCP -#define MIB2_GROUPS 8 -#else -#define MIB2_GROUPS 7 -#endif -const s32_t mib2_ids[MIB2_GROUPS] = -{ - 1, - 2, - 3, - 4, - 5, -#if LWIP_TCP - 6, -#endif - 7, - 11 -}; -struct mib_node* const mib2_nodes[MIB2_GROUPS] = { - (struct mib_node*)&sys_tem, - (struct mib_node*)&interfaces, - (struct mib_node*)&at, - (struct mib_node*)&mib2_ip, - (struct mib_node*)&icmp, -#if LWIP_TCP - (struct mib_node*)&tcp, -#endif - (struct mib_node*)&udp, - (struct mib_node*)&snmp -}; - -const struct mib_array_node mib2 = { - &noleafs_get_object_def, - &noleafs_get_value, - &noleafs_set_test, - &noleafs_set_value, - MIB_NODE_AR, - MIB2_GROUPS, - mib2_ids, - mib2_nodes -}; - -/* mgmt .1.3.6.1.2 */ -const s32_t mgmt_ids[1] = { 1 }; -struct mib_node* const mgmt_nodes[1] = { (struct mib_node*)&mib2 }; -const struct mib_array_node mgmt = { - &noleafs_get_object_def, - &noleafs_get_value, - &noleafs_set_test, - &noleafs_set_value, - MIB_NODE_AR, - 1, - mgmt_ids, - mgmt_nodes -}; - -/* internet .1.3.6.1 */ -#if SNMP_PRIVATE_MIB -/* When using a private MIB, you have to create a file 'private_mib.h' that contains - * a 'struct mib_array_node mib_private' which contains your MIB. */ -s32_t internet_ids[2] = { 2, 4 }; -struct mib_node* const internet_nodes[2] = { (struct mib_node*)&mgmt, (struct mib_node*)&mib_private }; -const struct mib_array_node internet = { - &noleafs_get_object_def, - &noleafs_get_value, - &noleafs_set_test, - &noleafs_set_value, - MIB_NODE_AR, - 2, - internet_ids, - internet_nodes -}; -#else -const s32_t internet_ids[1] = { 2 }; -struct mib_node* const internet_nodes[1] = { (struct mib_node*)&mgmt }; -const struct mib_array_node internet = { - &noleafs_get_object_def, - &noleafs_get_value, - &noleafs_set_test, - &noleafs_set_value, - MIB_NODE_AR, - 1, - internet_ids, - internet_nodes -}; -#endif - -/** mib-2.system.sysObjectID */ -static struct snmp_obj_id sysobjid = {SNMP_SYSOBJID_LEN, SNMP_SYSOBJID}; -/** enterprise ID for generic TRAPs, .iso.org.dod.internet.mgmt.mib-2.snmp */ -static struct snmp_obj_id snmpgrp_id = {7,{1,3,6,1,2,1,11}}; -/** mib-2.system.sysServices */ -static const s32_t sysservices = SNMP_SYSSERVICES; - -/** mib-2.system.sysDescr */ -static const u8_t sysdescr_len_default = 4; -static const u8_t sysdescr_default[] = "lwIP"; -static u8_t* sysdescr_len_ptr = (u8_t*)&sysdescr_len_default; -static u8_t* sysdescr_ptr = (u8_t*)&sysdescr_default[0]; -/** mib-2.system.sysContact */ -static const u8_t syscontact_len_default = 0; -static const u8_t syscontact_default[] = ""; -static u8_t* syscontact_len_ptr = (u8_t*)&syscontact_len_default; -static u8_t* syscontact_ptr = (u8_t*)&syscontact_default[0]; -/** mib-2.system.sysName */ -static const u8_t sysname_len_default = 8; -static const u8_t sysname_default[] = "FQDN-unk"; -static u8_t* sysname_len_ptr = (u8_t*)&sysname_len_default; -static u8_t* sysname_ptr = (u8_t*)&sysname_default[0]; -/** mib-2.system.sysLocation */ -static const u8_t syslocation_len_default = 0; -static const u8_t syslocation_default[] = ""; -static u8_t* syslocation_len_ptr = (u8_t*)&syslocation_len_default; -static u8_t* syslocation_ptr = (u8_t*)&syslocation_default[0]; -/** mib-2.snmp.snmpEnableAuthenTraps */ -static const u8_t snmpenableauthentraps_default = 2; /* disabled */ -static u8_t* snmpenableauthentraps_ptr = (u8_t*)&snmpenableauthentraps_default; - -/** mib-2.interfaces.ifTable.ifEntry.ifSpecific (zeroDotZero) */ -static const struct snmp_obj_id ifspecific = {2, {0, 0}}; -/** mib-2.ip.ipRouteTable.ipRouteEntry.ipRouteInfo (zeroDotZero) */ -static const struct snmp_obj_id iprouteinfo = {2, {0, 0}}; - - - -/* mib-2.system counter(s) */ -static u32_t sysuptime = 0; - -/* mib-2.ip counter(s) */ -static u32_t ipinreceives = 0, - ipinhdrerrors = 0, - ipinaddrerrors = 0, - ipforwdatagrams = 0, - ipinunknownprotos = 0, - ipindiscards = 0, - ipindelivers = 0, - ipoutrequests = 0, - ipoutdiscards = 0, - ipoutnoroutes = 0, - ipreasmreqds = 0, - ipreasmoks = 0, - ipreasmfails = 0, - ipfragoks = 0, - ipfragfails = 0, - ipfragcreates = 0, - iproutingdiscards = 0; -/* mib-2.icmp counter(s) */ -static u32_t icmpinmsgs = 0, - icmpinerrors = 0, - icmpindestunreachs = 0, - icmpintimeexcds = 0, - icmpinparmprobs = 0, - icmpinsrcquenchs = 0, - icmpinredirects = 0, - icmpinechos = 0, - icmpinechoreps = 0, - icmpintimestamps = 0, - icmpintimestampreps = 0, - icmpinaddrmasks = 0, - icmpinaddrmaskreps = 0, - icmpoutmsgs = 0, - icmpouterrors = 0, - icmpoutdestunreachs = 0, - icmpouttimeexcds = 0, - icmpoutparmprobs = 0, - icmpoutsrcquenchs = 0, - icmpoutredirects = 0, - icmpoutechos = 0, - icmpoutechoreps = 0, - icmpouttimestamps = 0, - icmpouttimestampreps = 0, - icmpoutaddrmasks = 0, - icmpoutaddrmaskreps = 0; -/* mib-2.tcp counter(s) */ -static u32_t tcpactiveopens = 0, - tcppassiveopens = 0, - tcpattemptfails = 0, - tcpestabresets = 0, - tcpinsegs = 0, - tcpoutsegs = 0, - tcpretranssegs = 0, - tcpinerrs = 0, - tcpoutrsts = 0; -/* mib-2.udp counter(s) */ -static u32_t udpindatagrams = 0, - udpnoports = 0, - udpinerrors = 0, - udpoutdatagrams = 0; -/* mib-2.snmp counter(s) */ -static u32_t snmpinpkts = 0, - snmpoutpkts = 0, - snmpinbadversions = 0, - snmpinbadcommunitynames = 0, - snmpinbadcommunityuses = 0, - snmpinasnparseerrs = 0, - snmpintoobigs = 0, - snmpinnosuchnames = 0, - snmpinbadvalues = 0, - snmpinreadonlys = 0, - snmpingenerrs = 0, - snmpintotalreqvars = 0, - snmpintotalsetvars = 0, - snmpingetrequests = 0, - snmpingetnexts = 0, - snmpinsetrequests = 0, - snmpingetresponses = 0, - snmpintraps = 0, - snmpouttoobigs = 0, - snmpoutnosuchnames = 0, - snmpoutbadvalues = 0, - snmpoutgenerrs = 0, - snmpoutgetrequests = 0, - snmpoutgetnexts = 0, - snmpoutsetrequests = 0, - snmpoutgetresponses = 0, - snmpouttraps = 0; - - - -/* prototypes of the following functions are in lwip/src/include/lwip/snmp.h */ -/** - * Copy octet string. - * - * @param dst points to destination - * @param src points to source - * @param n number of octets to copy. - */ -static void ocstrncpy(u8_t *dst, u8_t *src, u16_t n) -{ - u16_t i = n; - while (i > 0) { - i--; - *dst++ = *src++; - } -} - -/** - * Copy object identifier (s32_t) array. - * - * @param dst points to destination - * @param src points to source - * @param n number of sub identifiers to copy. - */ -void objectidncpy(s32_t *dst, s32_t *src, u8_t n) -{ - u8_t i = n; - while(i > 0) { - i--; - *dst++ = *src++; - } -} - -/** - * Initializes sysDescr pointers. - * - * @param str if non-NULL then copy str pointer - * @param len points to string length, excluding zero terminator - */ -void snmp_set_sysdesr(u8_t *str, u8_t *len) -{ - if (str != NULL) - { - sysdescr_ptr = str; - sysdescr_len_ptr = len; - } -} - -void snmp_get_sysobjid_ptr(struct snmp_obj_id **oid) -{ - *oid = &sysobjid; -} - -/** - * Initializes sysObjectID value. - * - * @param oid points to stuct snmp_obj_id to copy - */ -void snmp_set_sysobjid(struct snmp_obj_id *oid) -{ - sysobjid = *oid; -} - -/** - * Must be called at regular 10 msec interval from a timer interrupt - * or signal handler depending on your runtime environment. - */ -void snmp_inc_sysuptime(void) -{ - sysuptime++; -} - -void snmp_add_sysuptime(u32_t value) -{ - sysuptime+=value; -} - -void snmp_get_sysuptime(u32_t *value) -{ - SNMP_GET_SYSUPTIME(sysuptime); - *value = sysuptime; -} - -/** - * Initializes sysContact pointers, - * e.g. ptrs to non-volatile memory external to lwIP. - * - * @param ocstr if non-NULL then copy str pointer - * @param ocstrlen points to string length, excluding zero terminator - */ -void snmp_set_syscontact(u8_t *ocstr, u8_t *ocstrlen) -{ - if (ocstr != NULL) - { - syscontact_ptr = ocstr; - syscontact_len_ptr = ocstrlen; - } -} - -/** - * Initializes sysName pointers, - * e.g. ptrs to non-volatile memory external to lwIP. - * - * @param ocstr if non-NULL then copy str pointer - * @param ocstrlen points to string length, excluding zero terminator - */ -void snmp_set_sysname(u8_t *ocstr, u8_t *ocstrlen) -{ - if (ocstr != NULL) - { - sysname_ptr = ocstr; - sysname_len_ptr = ocstrlen; - } -} - -/** - * Initializes sysLocation pointers, - * e.g. ptrs to non-volatile memory external to lwIP. - * - * @param ocstr if non-NULL then copy str pointer - * @param ocstrlen points to string length, excluding zero terminator - */ -void snmp_set_syslocation(u8_t *ocstr, u8_t *ocstrlen) -{ - if (ocstr != NULL) - { - syslocation_ptr = ocstr; - syslocation_len_ptr = ocstrlen; - } -} - - -void snmp_add_ifinoctets(struct netif *ni, u32_t value) -{ - ni->ifinoctets += value; -} - -void snmp_inc_ifinucastpkts(struct netif *ni) -{ - (ni->ifinucastpkts)++; -} - -void snmp_inc_ifinnucastpkts(struct netif *ni) -{ - (ni->ifinnucastpkts)++; -} - -void snmp_inc_ifindiscards(struct netif *ni) -{ - (ni->ifindiscards)++; -} - -void snmp_add_ifoutoctets(struct netif *ni, u32_t value) -{ - ni->ifoutoctets += value; -} - -void snmp_inc_ifoutucastpkts(struct netif *ni) -{ - (ni->ifoutucastpkts)++; -} - -void snmp_inc_ifoutnucastpkts(struct netif *ni) -{ - (ni->ifoutnucastpkts)++; -} - -void snmp_inc_ifoutdiscards(struct netif *ni) -{ - (ni->ifoutdiscards)++; -} - -void snmp_inc_iflist(void) -{ - struct mib_list_node *if_node = NULL; - - snmp_mib_node_insert(&iflist_root, iflist_root.count + 1, &if_node); - /* enable getnext traversal on filled table */ - iftable.maxlength = 1; -} - -void snmp_dec_iflist(void) -{ - snmp_mib_node_delete(&iflist_root, iflist_root.tail); - /* disable getnext traversal on empty table */ - if(iflist_root.count == 0) iftable.maxlength = 0; -} - -/** - * Inserts ARP table indexes (.xIfIndex.xNetAddress) - * into arp table index trees (both atTable and ipNetToMediaTable). - */ -void snmp_insert_arpidx_tree(struct netif *ni, ip_addr_t *ip) -{ - struct mib_list_rootnode *at_rn; - struct mib_list_node *at_node; - s32_t arpidx[5]; - u8_t level, tree; - - LWIP_ASSERT("ni != NULL", ni != NULL); - snmp_netiftoifindex(ni, &arpidx[0]); - snmp_iptooid(ip, &arpidx[1]); - - for (tree = 0; tree < 2; tree++) - { - if (tree == 0) - { - at_rn = &arptree_root; - } - else - { - at_rn = &ipntomtree_root; - } - for (level = 0; level < 5; level++) - { - at_node = NULL; - snmp_mib_node_insert(at_rn, arpidx[level], &at_node); - if ((level != 4) && (at_node != NULL)) - { - if (at_node->nptr == NULL) - { - at_rn = snmp_mib_lrn_alloc(); - at_node->nptr = (struct mib_node*)at_rn; - if (at_rn != NULL) - { - if (level == 3) - { - if (tree == 0) - { - at_rn->get_object_def = atentry_get_object_def; - at_rn->get_value = atentry_get_value; - } - else - { - at_rn->get_object_def = ip_ntomentry_get_object_def; - at_rn->get_value = ip_ntomentry_get_value; - } - at_rn->set_test = noleafs_set_test; - at_rn->set_value = noleafs_set_value; - } - } - else - { - /* at_rn == NULL, malloc failure */ - LWIP_DEBUGF(SNMP_MIB_DEBUG,("snmp_insert_arpidx_tree() insert failed, mem full")); - break; - } - } - else - { - at_rn = (struct mib_list_rootnode*)at_node->nptr; - } - } - } - } - /* enable getnext traversal on filled tables */ - at.maxlength = 1; - ipntomtable.maxlength = 1; -} - -/** - * Removes ARP table indexes (.xIfIndex.xNetAddress) - * from arp table index trees. - */ -void snmp_delete_arpidx_tree(struct netif *ni, ip_addr_t *ip) -{ - struct mib_list_rootnode *at_rn, *next, *del_rn[5]; - struct mib_list_node *at_n, *del_n[5]; - s32_t arpidx[5]; - u8_t fc, tree, level, del_cnt; - - snmp_netiftoifindex(ni, &arpidx[0]); - snmp_iptooid(ip, &arpidx[1]); - - for (tree = 0; tree < 2; tree++) - { - /* mark nodes for deletion */ - if (tree == 0) - { - at_rn = &arptree_root; - } - else - { - at_rn = &ipntomtree_root; - } - level = 0; - del_cnt = 0; - while ((level < 5) && (at_rn != NULL)) - { - fc = snmp_mib_node_find(at_rn, arpidx[level], &at_n); - if (fc == 0) - { - /* arpidx[level] does not exist */ - del_cnt = 0; - at_rn = NULL; - } - else if (fc == 1) - { - del_rn[del_cnt] = at_rn; - del_n[del_cnt] = at_n; - del_cnt++; - at_rn = (struct mib_list_rootnode*)(at_n->nptr); - } - else if (fc == 2) - { - /* reset delete (2 or more childs) */ - del_cnt = 0; - at_rn = (struct mib_list_rootnode*)(at_n->nptr); - } - level++; - } - /* delete marked index nodes */ - while (del_cnt > 0) - { - del_cnt--; - - at_rn = del_rn[del_cnt]; - at_n = del_n[del_cnt]; - - next = snmp_mib_node_delete(at_rn, at_n); - if (next != NULL) - { - LWIP_ASSERT("next_count == 0",next->count == 0); - snmp_mib_lrn_free(next); - } - } - } - /* disable getnext traversal on empty tables */ - if(arptree_root.count == 0) at.maxlength = 0; - if(ipntomtree_root.count == 0) ipntomtable.maxlength = 0; -} - -void snmp_inc_ipinreceives(void) -{ - ipinreceives++; -} - -void snmp_inc_ipinhdrerrors(void) -{ - ipinhdrerrors++; -} - -void snmp_inc_ipinaddrerrors(void) -{ - ipinaddrerrors++; -} - -void snmp_inc_ipforwdatagrams(void) -{ - ipforwdatagrams++; -} - -void snmp_inc_ipinunknownprotos(void) -{ - ipinunknownprotos++; -} - -void snmp_inc_ipindiscards(void) -{ - ipindiscards++; -} - -void snmp_inc_ipindelivers(void) -{ - ipindelivers++; -} - -void snmp_inc_ipoutrequests(void) -{ - ipoutrequests++; -} - -void snmp_inc_ipoutdiscards(void) -{ - ipoutdiscards++; -} - -void snmp_inc_ipoutnoroutes(void) -{ - ipoutnoroutes++; -} - -void snmp_inc_ipreasmreqds(void) -{ - ipreasmreqds++; -} - -void snmp_inc_ipreasmoks(void) -{ - ipreasmoks++; -} - -void snmp_inc_ipreasmfails(void) -{ - ipreasmfails++; -} - -void snmp_inc_ipfragoks(void) -{ - ipfragoks++; -} - -void snmp_inc_ipfragfails(void) -{ - ipfragfails++; -} - -void snmp_inc_ipfragcreates(void) -{ - ipfragcreates++; -} - -void snmp_inc_iproutingdiscards(void) -{ - iproutingdiscards++; -} - -/** - * Inserts ipAddrTable indexes (.ipAdEntAddr) - * into index tree. - */ -void snmp_insert_ipaddridx_tree(struct netif *ni) -{ - struct mib_list_rootnode *ipa_rn; - struct mib_list_node *ipa_node; - s32_t ipaddridx[4]; - u8_t level; - - LWIP_ASSERT("ni != NULL", ni != NULL); - snmp_iptooid(&ni->ip_addr, &ipaddridx[0]); - - level = 0; - ipa_rn = &ipaddrtree_root; - while (level < 4) - { - ipa_node = NULL; - snmp_mib_node_insert(ipa_rn, ipaddridx[level], &ipa_node); - if ((level != 3) && (ipa_node != NULL)) - { - if (ipa_node->nptr == NULL) - { - ipa_rn = snmp_mib_lrn_alloc(); - ipa_node->nptr = (struct mib_node*)ipa_rn; - if (ipa_rn != NULL) - { - if (level == 2) - { - ipa_rn->get_object_def = ip_addrentry_get_object_def; - ipa_rn->get_value = ip_addrentry_get_value; - ipa_rn->set_test = noleafs_set_test; - ipa_rn->set_value = noleafs_set_value; - } - } - else - { - /* ipa_rn == NULL, malloc failure */ - LWIP_DEBUGF(SNMP_MIB_DEBUG,("snmp_insert_ipaddridx_tree() insert failed, mem full")); - break; - } - } - else - { - ipa_rn = (struct mib_list_rootnode*)ipa_node->nptr; - } - } - level++; - } - /* enable getnext traversal on filled table */ - ipaddrtable.maxlength = 1; -} - -/** - * Removes ipAddrTable indexes (.ipAdEntAddr) - * from index tree. - */ -void snmp_delete_ipaddridx_tree(struct netif *ni) -{ - struct mib_list_rootnode *ipa_rn, *next, *del_rn[4]; - struct mib_list_node *ipa_n, *del_n[4]; - s32_t ipaddridx[4]; - u8_t fc, level, del_cnt; - - LWIP_ASSERT("ni != NULL", ni != NULL); - snmp_iptooid(&ni->ip_addr, &ipaddridx[0]); - - /* mark nodes for deletion */ - level = 0; - del_cnt = 0; - ipa_rn = &ipaddrtree_root; - while ((level < 4) && (ipa_rn != NULL)) - { - fc = snmp_mib_node_find(ipa_rn, ipaddridx[level], &ipa_n); - if (fc == 0) - { - /* ipaddridx[level] does not exist */ - del_cnt = 0; - ipa_rn = NULL; - } - else if (fc == 1) - { - del_rn[del_cnt] = ipa_rn; - del_n[del_cnt] = ipa_n; - del_cnt++; - ipa_rn = (struct mib_list_rootnode*)(ipa_n->nptr); - } - else if (fc == 2) - { - /* reset delete (2 or more childs) */ - del_cnt = 0; - ipa_rn = (struct mib_list_rootnode*)(ipa_n->nptr); - } - level++; - } - /* delete marked index nodes */ - while (del_cnt > 0) - { - del_cnt--; - - ipa_rn = del_rn[del_cnt]; - ipa_n = del_n[del_cnt]; - - next = snmp_mib_node_delete(ipa_rn, ipa_n); - if (next != NULL) - { - LWIP_ASSERT("next_count == 0",next->count == 0); - snmp_mib_lrn_free(next); - } - } - /* disable getnext traversal on empty table */ - if (ipaddrtree_root.count == 0) ipaddrtable.maxlength = 0; -} - -/** - * Inserts ipRouteTable indexes (.ipRouteDest) - * into index tree. - * - * @param dflt non-zero for the default rte, zero for network rte - * @param ni points to network interface for this rte - * - * @todo record sysuptime for _this_ route when it is installed - * (needed for ipRouteAge) in the netif. - */ -void snmp_insert_iprteidx_tree(u8_t dflt, struct netif *ni) -{ - u8_t insert = 0; - ip_addr_t dst; - - if (dflt != 0) - { - /* the default route 0.0.0.0 */ - ip_addr_set_any(&dst); - insert = 1; - } - else - { - /* route to the network address */ - ip_addr_get_network(&dst, &ni->ip_addr, &ni->netmask); - /* exclude 0.0.0.0 network (reserved for default rte) */ - if (!ip_addr_isany(&dst)) { - insert = 1; - } - } - if (insert) - { - struct mib_list_rootnode *iprte_rn; - struct mib_list_node *iprte_node; - s32_t iprteidx[4]; - u8_t level; - - snmp_iptooid(&dst, &iprteidx[0]); - level = 0; - iprte_rn = &iprtetree_root; - while (level < 4) - { - iprte_node = NULL; - snmp_mib_node_insert(iprte_rn, iprteidx[level], &iprte_node); - if ((level != 3) && (iprte_node != NULL)) - { - if (iprte_node->nptr == NULL) - { - iprte_rn = snmp_mib_lrn_alloc(); - iprte_node->nptr = (struct mib_node*)iprte_rn; - if (iprte_rn != NULL) - { - if (level == 2) - { - iprte_rn->get_object_def = ip_rteentry_get_object_def; - iprte_rn->get_value = ip_rteentry_get_value; - iprte_rn->set_test = noleafs_set_test; - iprte_rn->set_value = noleafs_set_value; - } - } - else - { - /* iprte_rn == NULL, malloc failure */ - LWIP_DEBUGF(SNMP_MIB_DEBUG,("snmp_insert_iprteidx_tree() insert failed, mem full")); - break; - } - } - else - { - iprte_rn = (struct mib_list_rootnode*)iprte_node->nptr; - } - } - level++; - } - } - /* enable getnext traversal on filled table */ - iprtetable.maxlength = 1; -} - -/** - * Removes ipRouteTable indexes (.ipRouteDest) - * from index tree. - * - * @param dflt non-zero for the default rte, zero for network rte - * @param ni points to network interface for this rte or NULL - * for default route to be removed. - */ -void snmp_delete_iprteidx_tree(u8_t dflt, struct netif *ni) -{ - u8_t del = 0; - ip_addr_t dst; - - if (dflt != 0) - { - /* the default route 0.0.0.0 */ - ip_addr_set_any(&dst); - del = 1; - } - else - { - /* route to the network address */ - ip_addr_get_network(&dst, &ni->ip_addr, &ni->netmask); - /* exclude 0.0.0.0 network (reserved for default rte) */ - if (!ip_addr_isany(&dst)) { - del = 1; - } - } - if (del) - { - struct mib_list_rootnode *iprte_rn, *next, *del_rn[4]; - struct mib_list_node *iprte_n, *del_n[4]; - s32_t iprteidx[4]; - u8_t fc, level, del_cnt; - - snmp_iptooid(&dst, &iprteidx[0]); - /* mark nodes for deletion */ - level = 0; - del_cnt = 0; - iprte_rn = &iprtetree_root; - while ((level < 4) && (iprte_rn != NULL)) - { - fc = snmp_mib_node_find(iprte_rn, iprteidx[level], &iprte_n); - if (fc == 0) - { - /* iprteidx[level] does not exist */ - del_cnt = 0; - iprte_rn = NULL; - } - else if (fc == 1) - { - del_rn[del_cnt] = iprte_rn; - del_n[del_cnt] = iprte_n; - del_cnt++; - iprte_rn = (struct mib_list_rootnode*)(iprte_n->nptr); - } - else if (fc == 2) - { - /* reset delete (2 or more childs) */ - del_cnt = 0; - iprte_rn = (struct mib_list_rootnode*)(iprte_n->nptr); - } - level++; - } - /* delete marked index nodes */ - while (del_cnt > 0) - { - del_cnt--; - - iprte_rn = del_rn[del_cnt]; - iprte_n = del_n[del_cnt]; - - next = snmp_mib_node_delete(iprte_rn, iprte_n); - if (next != NULL) - { - LWIP_ASSERT("next_count == 0",next->count == 0); - snmp_mib_lrn_free(next); - } - } - } - /* disable getnext traversal on empty table */ - if (iprtetree_root.count == 0) iprtetable.maxlength = 0; -} - - -void snmp_inc_icmpinmsgs(void) -{ - icmpinmsgs++; -} - -void snmp_inc_icmpinerrors(void) -{ - icmpinerrors++; -} - -void snmp_inc_icmpindestunreachs(void) -{ - icmpindestunreachs++; -} - -void snmp_inc_icmpintimeexcds(void) -{ - icmpintimeexcds++; -} - -void snmp_inc_icmpinparmprobs(void) -{ - icmpinparmprobs++; -} - -void snmp_inc_icmpinsrcquenchs(void) -{ - icmpinsrcquenchs++; -} - -void snmp_inc_icmpinredirects(void) -{ - icmpinredirects++; -} - -void snmp_inc_icmpinechos(void) -{ - icmpinechos++; -} - -void snmp_inc_icmpinechoreps(void) -{ - icmpinechoreps++; -} - -void snmp_inc_icmpintimestamps(void) -{ - icmpintimestamps++; -} - -void snmp_inc_icmpintimestampreps(void) -{ - icmpintimestampreps++; -} - -void snmp_inc_icmpinaddrmasks(void) -{ - icmpinaddrmasks++; -} - -void snmp_inc_icmpinaddrmaskreps(void) -{ - icmpinaddrmaskreps++; -} - -void snmp_inc_icmpoutmsgs(void) -{ - icmpoutmsgs++; -} - -void snmp_inc_icmpouterrors(void) -{ - icmpouterrors++; -} - -void snmp_inc_icmpoutdestunreachs(void) -{ - icmpoutdestunreachs++; -} - -void snmp_inc_icmpouttimeexcds(void) -{ - icmpouttimeexcds++; -} - -void snmp_inc_icmpoutparmprobs(void) -{ - icmpoutparmprobs++; -} - -void snmp_inc_icmpoutsrcquenchs(void) -{ - icmpoutsrcquenchs++; -} - -void snmp_inc_icmpoutredirects(void) -{ - icmpoutredirects++; -} - -void snmp_inc_icmpoutechos(void) -{ - icmpoutechos++; -} - -void snmp_inc_icmpoutechoreps(void) -{ - icmpoutechoreps++; -} - -void snmp_inc_icmpouttimestamps(void) -{ - icmpouttimestamps++; -} - -void snmp_inc_icmpouttimestampreps(void) -{ - icmpouttimestampreps++; -} - -void snmp_inc_icmpoutaddrmasks(void) -{ - icmpoutaddrmasks++; -} - -void snmp_inc_icmpoutaddrmaskreps(void) -{ - icmpoutaddrmaskreps++; -} - -void snmp_inc_tcpactiveopens(void) -{ - tcpactiveopens++; -} - -void snmp_inc_tcppassiveopens(void) -{ - tcppassiveopens++; -} - -void snmp_inc_tcpattemptfails(void) -{ - tcpattemptfails++; -} - -void snmp_inc_tcpestabresets(void) -{ - tcpestabresets++; -} - -void snmp_inc_tcpinsegs(void) -{ - tcpinsegs++; -} - -void snmp_inc_tcpoutsegs(void) -{ - tcpoutsegs++; -} - -void snmp_inc_tcpretranssegs(void) -{ - tcpretranssegs++; -} - -void snmp_inc_tcpinerrs(void) -{ - tcpinerrs++; -} - -void snmp_inc_tcpoutrsts(void) -{ - tcpoutrsts++; -} - -void snmp_inc_udpindatagrams(void) -{ - udpindatagrams++; -} - -void snmp_inc_udpnoports(void) -{ - udpnoports++; -} - -void snmp_inc_udpinerrors(void) -{ - udpinerrors++; -} - -void snmp_inc_udpoutdatagrams(void) -{ - udpoutdatagrams++; -} - -/** - * Inserts udpTable indexes (.udpLocalAddress.udpLocalPort) - * into index tree. - */ -void snmp_insert_udpidx_tree(struct udp_pcb *pcb) -{ - struct mib_list_rootnode *udp_rn; - struct mib_list_node *udp_node; - s32_t udpidx[5]; - u8_t level; - - LWIP_ASSERT("pcb != NULL", pcb != NULL); - snmp_iptooid(&pcb->local_ip, &udpidx[0]); - udpidx[4] = pcb->local_port; - - udp_rn = &udp_root; - for (level = 0; level < 5; level++) - { - udp_node = NULL; - snmp_mib_node_insert(udp_rn, udpidx[level], &udp_node); - if ((level != 4) && (udp_node != NULL)) - { - if (udp_node->nptr == NULL) - { - udp_rn = snmp_mib_lrn_alloc(); - udp_node->nptr = (struct mib_node*)udp_rn; - if (udp_rn != NULL) - { - if (level == 3) - { - udp_rn->get_object_def = udpentry_get_object_def; - udp_rn->get_value = udpentry_get_value; - udp_rn->set_test = noleafs_set_test; - udp_rn->set_value = noleafs_set_value; - } - } - else - { - /* udp_rn == NULL, malloc failure */ - LWIP_DEBUGF(SNMP_MIB_DEBUG,("snmp_insert_udpidx_tree() insert failed, mem full")); - break; - } - } - else - { - udp_rn = (struct mib_list_rootnode*)udp_node->nptr; - } - } - } - udptable.maxlength = 1; -} - -/** - * Removes udpTable indexes (.udpLocalAddress.udpLocalPort) - * from index tree. - */ -void snmp_delete_udpidx_tree(struct udp_pcb *pcb) -{ - struct udp_pcb *npcb; - struct mib_list_rootnode *udp_rn, *next, *del_rn[5]; - struct mib_list_node *udp_n, *del_n[5]; - s32_t udpidx[5]; - u8_t bindings, fc, level, del_cnt; - - LWIP_ASSERT("pcb != NULL", pcb != NULL); - snmp_iptooid(&pcb->local_ip, &udpidx[0]); - udpidx[4] = pcb->local_port; - - /* count PCBs for a given binding - (e.g. when reusing ports or for temp output PCBs) */ - bindings = 0; - npcb = udp_pcbs; - while ((npcb != NULL)) - { - if (ip_addr_cmp(&npcb->local_ip, &pcb->local_ip) && - (npcb->local_port == udpidx[4])) - { - bindings++; - } - npcb = npcb->next; - } - if (bindings == 1) - { - /* selectively remove */ - /* mark nodes for deletion */ - level = 0; - del_cnt = 0; - udp_rn = &udp_root; - while ((level < 5) && (udp_rn != NULL)) - { - fc = snmp_mib_node_find(udp_rn, udpidx[level], &udp_n); - if (fc == 0) - { - /* udpidx[level] does not exist */ - del_cnt = 0; - udp_rn = NULL; - } - else if (fc == 1) - { - del_rn[del_cnt] = udp_rn; - del_n[del_cnt] = udp_n; - del_cnt++; - udp_rn = (struct mib_list_rootnode*)(udp_n->nptr); - } - else if (fc == 2) - { - /* reset delete (2 or more childs) */ - del_cnt = 0; - udp_rn = (struct mib_list_rootnode*)(udp_n->nptr); - } - level++; - } - /* delete marked index nodes */ - while (del_cnt > 0) - { - del_cnt--; - - udp_rn = del_rn[del_cnt]; - udp_n = del_n[del_cnt]; - - next = snmp_mib_node_delete(udp_rn, udp_n); - if (next != NULL) - { - LWIP_ASSERT("next_count == 0",next->count == 0); - snmp_mib_lrn_free(next); - } - } - } - /* disable getnext traversal on empty table */ - if (udp_root.count == 0) udptable.maxlength = 0; -} - - -void snmp_inc_snmpinpkts(void) -{ - snmpinpkts++; -} - -void snmp_inc_snmpoutpkts(void) -{ - snmpoutpkts++; -} - -void snmp_inc_snmpinbadversions(void) -{ - snmpinbadversions++; -} - -void snmp_inc_snmpinbadcommunitynames(void) -{ - snmpinbadcommunitynames++; -} - -void snmp_inc_snmpinbadcommunityuses(void) -{ - snmpinbadcommunityuses++; -} - -void snmp_inc_snmpinasnparseerrs(void) -{ - snmpinasnparseerrs++; -} - -void snmp_inc_snmpintoobigs(void) -{ - snmpintoobigs++; -} - -void snmp_inc_snmpinnosuchnames(void) -{ - snmpinnosuchnames++; -} - -void snmp_inc_snmpinbadvalues(void) -{ - snmpinbadvalues++; -} - -void snmp_inc_snmpinreadonlys(void) -{ - snmpinreadonlys++; -} - -void snmp_inc_snmpingenerrs(void) -{ - snmpingenerrs++; -} - -void snmp_add_snmpintotalreqvars(u8_t value) -{ - snmpintotalreqvars += value; -} - -void snmp_add_snmpintotalsetvars(u8_t value) -{ - snmpintotalsetvars += value; -} - -void snmp_inc_snmpingetrequests(void) -{ - snmpingetrequests++; -} - -void snmp_inc_snmpingetnexts(void) -{ - snmpingetnexts++; -} - -void snmp_inc_snmpinsetrequests(void) -{ - snmpinsetrequests++; -} - -void snmp_inc_snmpingetresponses(void) -{ - snmpingetresponses++; -} - -void snmp_inc_snmpintraps(void) -{ - snmpintraps++; -} - -void snmp_inc_snmpouttoobigs(void) -{ - snmpouttoobigs++; -} - -void snmp_inc_snmpoutnosuchnames(void) -{ - snmpoutnosuchnames++; -} - -void snmp_inc_snmpoutbadvalues(void) -{ - snmpoutbadvalues++; -} - -void snmp_inc_snmpoutgenerrs(void) -{ - snmpoutgenerrs++; -} - -void snmp_inc_snmpoutgetrequests(void) -{ - snmpoutgetrequests++; -} - -void snmp_inc_snmpoutgetnexts(void) -{ - snmpoutgetnexts++; -} - -void snmp_inc_snmpoutsetrequests(void) -{ - snmpoutsetrequests++; -} - -void snmp_inc_snmpoutgetresponses(void) -{ - snmpoutgetresponses++; -} - -void snmp_inc_snmpouttraps(void) -{ - snmpouttraps++; -} - -void snmp_get_snmpgrpid_ptr(struct snmp_obj_id **oid) -{ - *oid = &snmpgrp_id; -} - -void snmp_set_snmpenableauthentraps(u8_t *value) -{ - if (value != NULL) - { - snmpenableauthentraps_ptr = value; - } -} - -void snmp_get_snmpenableauthentraps(u8_t *value) -{ - *value = *snmpenableauthentraps_ptr; -} - -void -noleafs_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od) -{ - LWIP_UNUSED_ARG(ident_len); - LWIP_UNUSED_ARG(ident); - od->instance = MIB_OBJECT_NONE; -} - -void -noleafs_get_value(struct obj_def *od, u16_t len, void *value) -{ - LWIP_UNUSED_ARG(od); - LWIP_UNUSED_ARG(len); - LWIP_UNUSED_ARG(value); -} - -u8_t -noleafs_set_test(struct obj_def *od, u16_t len, void *value) -{ - LWIP_UNUSED_ARG(od); - LWIP_UNUSED_ARG(len); - LWIP_UNUSED_ARG(value); - /* can't set */ - return 0; -} - -void -noleafs_set_value(struct obj_def *od, u16_t len, void *value) -{ - LWIP_UNUSED_ARG(od); - LWIP_UNUSED_ARG(len); - LWIP_UNUSED_ARG(value); -} - - -/** - * Returns systems object definitions. - * - * @param ident_len the address length (2) - * @param ident points to objectname.0 (object id trailer) - * @param od points to object definition. - */ -static void -system_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od) -{ - u8_t id; - - /* return to object name, adding index depth (1) */ - ident_len += 1; - ident -= 1; - if (ident_len == 2) - { - od->id_inst_len = ident_len; - od->id_inst_ptr = ident; - - LWIP_ASSERT("invalid id", (ident[0] >= 0) && (ident[0] <= 0xff)); - id = (u8_t)ident[0]; - LWIP_DEBUGF(SNMP_MIB_DEBUG,("get_object_def system.%"U16_F".0\n",(u16_t)id)); - switch (id) - { - case 1: /* sysDescr */ - od->instance = MIB_OBJECT_SCALAR; - od->access = MIB_OBJECT_READ_ONLY; - od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR); - od->v_len = *sysdescr_len_ptr; - break; - case 2: /* sysObjectID */ - od->instance = MIB_OBJECT_SCALAR; - od->access = MIB_OBJECT_READ_ONLY; - od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OBJ_ID); - od->v_len = sysobjid.len * sizeof(s32_t); - break; - case 3: /* sysUpTime */ - od->instance = MIB_OBJECT_SCALAR; - od->access = MIB_OBJECT_READ_ONLY; - od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_TIMETICKS); - od->v_len = sizeof(u32_t); - break; - case 4: /* sysContact */ - od->instance = MIB_OBJECT_SCALAR; - od->access = MIB_OBJECT_READ_WRITE; - od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR); - od->v_len = *syscontact_len_ptr; - break; - case 5: /* sysName */ - od->instance = MIB_OBJECT_SCALAR; - od->access = MIB_OBJECT_READ_WRITE; - od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR); - od->v_len = *sysname_len_ptr; - break; - case 6: /* sysLocation */ - od->instance = MIB_OBJECT_SCALAR; - od->access = MIB_OBJECT_READ_WRITE; - od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR); - od->v_len = *syslocation_len_ptr; - break; - case 7: /* sysServices */ - od->instance = MIB_OBJECT_SCALAR; - od->access = MIB_OBJECT_READ_ONLY; - od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG); - od->v_len = sizeof(s32_t); - break; - default: - LWIP_DEBUGF(SNMP_MIB_DEBUG,("system_get_object_def: no such object\n")); - od->instance = MIB_OBJECT_NONE; - break; - }; - } - else - { - LWIP_DEBUGF(SNMP_MIB_DEBUG,("system_get_object_def: no scalar\n")); - od->instance = MIB_OBJECT_NONE; - } -} - -/** - * Returns system object value. - * - * @param ident_len the address length (2) - * @param ident points to objectname.0 (object id trailer) - * @param len return value space (in bytes) - * @param value points to (varbind) space to copy value into. - */ -static void -system_get_value(struct obj_def *od, u16_t len, void *value) -{ - u8_t id; - - LWIP_ASSERT("invalid id", (od->id_inst_ptr[0] >= 0) && (od->id_inst_ptr[0] <= 0xff)); - id = (u8_t)od->id_inst_ptr[0]; - switch (id) - { - case 1: /* sysDescr */ - ocstrncpy((u8_t*)value, sysdescr_ptr, len); - break; - case 2: /* sysObjectID */ - objectidncpy((s32_t*)value, (s32_t*)sysobjid.id, (u8_t)(len / sizeof(s32_t))); - break; - case 3: /* sysUpTime */ - { - snmp_get_sysuptime((u32_t*)value); - } - break; - case 4: /* sysContact */ - ocstrncpy((u8_t*)value, syscontact_ptr, len); - break; - case 5: /* sysName */ - ocstrncpy((u8_t*)value, sysname_ptr, len); - break; - case 6: /* sysLocation */ - ocstrncpy((u8_t*)value, syslocation_ptr, len); - break; - case 7: /* sysServices */ - { - s32_t *sint_ptr = (s32_t*)value; - *sint_ptr = sysservices; - } - break; - }; -} - -static u8_t -system_set_test(struct obj_def *od, u16_t len, void *value) -{ - u8_t id, set_ok; - - LWIP_UNUSED_ARG(value); - set_ok = 0; - LWIP_ASSERT("invalid id", (od->id_inst_ptr[0] >= 0) && (od->id_inst_ptr[0] <= 0xff)); - id = (u8_t)od->id_inst_ptr[0]; - switch (id) - { - case 4: /* sysContact */ - if ((syscontact_ptr != syscontact_default) && - (len <= 255)) - { - set_ok = 1; - } - break; - case 5: /* sysName */ - if ((sysname_ptr != sysname_default) && - (len <= 255)) - { - set_ok = 1; - } - break; - case 6: /* sysLocation */ - if ((syslocation_ptr != syslocation_default) && - (len <= 255)) - { - set_ok = 1; - } - break; - }; - return set_ok; -} - -static void -system_set_value(struct obj_def *od, u16_t len, void *value) -{ - u8_t id; - - LWIP_ASSERT("invalid len", len <= 0xff); - LWIP_ASSERT("invalid id", (od->id_inst_ptr[0] >= 0) && (od->id_inst_ptr[0] <= 0xff)); - id = (u8_t)od->id_inst_ptr[0]; - switch (id) - { - case 4: /* sysContact */ - ocstrncpy(syscontact_ptr, (u8_t*)value, len); - *syscontact_len_ptr = (u8_t)len; - break; - case 5: /* sysName */ - ocstrncpy(sysname_ptr, (u8_t*)value, len); - *sysname_len_ptr = (u8_t)len; - break; - case 6: /* sysLocation */ - ocstrncpy(syslocation_ptr, (u8_t*)value, len); - *syslocation_len_ptr = (u8_t)len; - break; - }; -} - -/** - * Returns interfaces.ifnumber object definition. - * - * @param ident_len the address length (2) - * @param ident points to objectname.index - * @param od points to object definition. - */ -static void -interfaces_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od) -{ - /* return to object name, adding index depth (1) */ - ident_len += 1; - ident -= 1; - if (ident_len == 2) - { - od->id_inst_len = ident_len; - od->id_inst_ptr = ident; - - od->instance = MIB_OBJECT_SCALAR; - od->access = MIB_OBJECT_READ_ONLY; - od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG); - od->v_len = sizeof(s32_t); - } - else - { - LWIP_DEBUGF(SNMP_MIB_DEBUG,("interfaces_get_object_def: no scalar\n")); - od->instance = MIB_OBJECT_NONE; - } -} - -/** - * Returns interfaces.ifnumber object value. - * - * @param ident_len the address length (2) - * @param ident points to objectname.0 (object id trailer) - * @param len return value space (in bytes) - * @param value points to (varbind) space to copy value into. - */ -static void -interfaces_get_value(struct obj_def *od, u16_t len, void *value) -{ - LWIP_UNUSED_ARG(len); - if (od->id_inst_ptr[0] == 1) - { - s32_t *sint_ptr = (s32_t*)value; - *sint_ptr = iflist_root.count; - } -} - -/** - * Returns ifentry object definitions. - * - * @param ident_len the address length (2) - * @param ident points to objectname.index - * @param od points to object definition. - */ -static void -ifentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od) -{ - u8_t id; - - /* return to object name, adding index depth (1) */ - ident_len += 1; - ident -= 1; - if (ident_len == 2) - { - od->id_inst_len = ident_len; - od->id_inst_ptr = ident; - - LWIP_ASSERT("invalid id", (ident[0] >= 0) && (ident[0] <= 0xff)); - id = (u8_t)ident[0]; - LWIP_DEBUGF(SNMP_MIB_DEBUG,("get_object_def ifentry.%"U16_F"\n",(u16_t)id)); - switch (id) - { - case 1: /* ifIndex */ - case 3: /* ifType */ - case 4: /* ifMtu */ - case 8: /* ifOperStatus */ - od->instance = MIB_OBJECT_TAB; - od->access = MIB_OBJECT_READ_ONLY; - od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG); - od->v_len = sizeof(s32_t); - break; - case 2: /* ifDescr */ - od->instance = MIB_OBJECT_TAB; - od->access = MIB_OBJECT_READ_ONLY; - od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR); - /** @todo this should be some sort of sizeof(struct netif.name) */ - od->v_len = 2; - break; - case 5: /* ifSpeed */ - case 21: /* ifOutQLen */ - od->instance = MIB_OBJECT_TAB; - od->access = MIB_OBJECT_READ_ONLY; - od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_GAUGE); - od->v_len = sizeof(u32_t); - break; - case 6: /* ifPhysAddress */ - { - struct netif *netif; - - snmp_ifindextonetif(ident[1], &netif); - od->instance = MIB_OBJECT_TAB; - od->access = MIB_OBJECT_READ_ONLY; - od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR); - od->v_len = netif->hwaddr_len; - } - break; - case 7: /* ifAdminStatus */ - od->instance = MIB_OBJECT_TAB; - od->access = MIB_OBJECT_READ_WRITE; - od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG); - od->v_len = sizeof(s32_t); - break; - case 9: /* ifLastChange */ - od->instance = MIB_OBJECT_TAB; - od->access = MIB_OBJECT_READ_ONLY; - od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_TIMETICKS); - od->v_len = sizeof(u32_t); - break; - case 10: /* ifInOctets */ - case 11: /* ifInUcastPkts */ - case 12: /* ifInNUcastPkts */ - case 13: /* ifInDiscarts */ - case 14: /* ifInErrors */ - case 15: /* ifInUnkownProtos */ - case 16: /* ifOutOctets */ - case 17: /* ifOutUcastPkts */ - case 18: /* ifOutNUcastPkts */ - case 19: /* ifOutDiscarts */ - case 20: /* ifOutErrors */ - od->instance = MIB_OBJECT_TAB; - od->access = MIB_OBJECT_READ_ONLY; - od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_COUNTER); - od->v_len = sizeof(u32_t); - break; - case 22: /* ifSpecific */ - /** @note returning zeroDotZero (0.0) no media specific MIB support */ - od->instance = MIB_OBJECT_TAB; - od->access = MIB_OBJECT_READ_ONLY; - od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OBJ_ID); - od->v_len = ifspecific.len * sizeof(s32_t); - break; - default: - LWIP_DEBUGF(SNMP_MIB_DEBUG,("ifentry_get_object_def: no such object\n")); - od->instance = MIB_OBJECT_NONE; - break; - }; - } - else - { - LWIP_DEBUGF(SNMP_MIB_DEBUG,("ifentry_get_object_def: no scalar\n")); - od->instance = MIB_OBJECT_NONE; - } -} - -/** - * Returns ifentry object value. - * - * @param ident_len the address length (2) - * @param ident points to objectname.0 (object id trailer) - * @param len return value space (in bytes) - * @param value points to (varbind) space to copy value into. - */ -static void -ifentry_get_value(struct obj_def *od, u16_t len, void *value) -{ - struct netif *netif; - u8_t id; - - snmp_ifindextonetif(od->id_inst_ptr[1], &netif); - LWIP_ASSERT("invalid id", (od->id_inst_ptr[0] >= 0) && (od->id_inst_ptr[0] <= 0xff)); - id = (u8_t)od->id_inst_ptr[0]; - switch (id) - { - case 1: /* ifIndex */ - { - s32_t *sint_ptr = (s32_t*)value; - *sint_ptr = od->id_inst_ptr[1]; - } - break; - case 2: /* ifDescr */ - ocstrncpy((u8_t*)value, (u8_t*)netif->name, len); - break; - case 3: /* ifType */ - { - s32_t *sint_ptr = (s32_t*)value; - *sint_ptr = netif->link_type; - } - break; - case 4: /* ifMtu */ - { - s32_t *sint_ptr = (s32_t*)value; - *sint_ptr = netif->mtu; - } - break; - case 5: /* ifSpeed */ - { - u32_t *uint_ptr = (u32_t*)value; - *uint_ptr = netif->link_speed; - } - break; - case 6: /* ifPhysAddress */ - ocstrncpy((u8_t*)value, netif->hwaddr, len); - break; - case 7: /* ifAdminStatus */ - { - s32_t *sint_ptr = (s32_t*)value; - if (netif_is_up(netif)) - { - if (netif_is_link_up(netif)) - { - *sint_ptr = 1; /* up */ - } - else - { - *sint_ptr = 7; /* lowerLayerDown */ - } - } - else - { - *sint_ptr = 2; /* down */ - } - } - break; - case 8: /* ifOperStatus */ - { - s32_t *sint_ptr = (s32_t*)value; - if (netif_is_up(netif)) - { - *sint_ptr = 1; - } - else - { - *sint_ptr = 2; - } - } - break; - case 9: /* ifLastChange */ - { - u32_t *uint_ptr = (u32_t*)value; - *uint_ptr = netif->ts; - } - break; - case 10: /* ifInOctets */ - { - u32_t *uint_ptr = (u32_t*)value; - *uint_ptr = netif->ifinoctets; - } - break; - case 11: /* ifInUcastPkts */ - { - u32_t *uint_ptr = (u32_t*)value; - *uint_ptr = netif->ifinucastpkts; - } - break; - case 12: /* ifInNUcastPkts */ - { - u32_t *uint_ptr = (u32_t*)value; - *uint_ptr = netif->ifinnucastpkts; - } - break; - case 13: /* ifInDiscarts */ - { - u32_t *uint_ptr = (u32_t*)value; - *uint_ptr = netif->ifindiscards; - } - break; - case 14: /* ifInErrors */ - case 15: /* ifInUnkownProtos */ - /** @todo add these counters! */ - { - u32_t *uint_ptr = (u32_t*)value; - *uint_ptr = 0; - } - break; - case 16: /* ifOutOctets */ - { - u32_t *uint_ptr = (u32_t*)value; - *uint_ptr = netif->ifoutoctets; - } - break; - case 17: /* ifOutUcastPkts */ - { - u32_t *uint_ptr = (u32_t*)value; - *uint_ptr = netif->ifoutucastpkts; - } - break; - case 18: /* ifOutNUcastPkts */ - { - u32_t *uint_ptr = (u32_t*)value; - *uint_ptr = netif->ifoutnucastpkts; - } - break; - case 19: /* ifOutDiscarts */ - { - u32_t *uint_ptr = (u32_t*)value; - *uint_ptr = netif->ifoutdiscards; - } - break; - case 20: /* ifOutErrors */ - /** @todo add this counter! */ - { - u32_t *uint_ptr = (u32_t*)value; - *uint_ptr = 0; - } - break; - case 21: /* ifOutQLen */ - /** @todo figure out if this must be 0 (no queue) or 1? */ - { - u32_t *uint_ptr = (u32_t*)value; - *uint_ptr = 0; - } - break; - case 22: /* ifSpecific */ - objectidncpy((s32_t*)value, (s32_t*)ifspecific.id, (u8_t)(len / sizeof(s32_t))); - break; - }; -} - -#if !SNMP_SAFE_REQUESTS -static u8_t -ifentry_set_test(struct obj_def *od, u16_t len, void *value) -{ - struct netif *netif; - u8_t id, set_ok; - LWIP_UNUSED_ARG(len); - - set_ok = 0; - snmp_ifindextonetif(od->id_inst_ptr[1], &netif); - id = (u8_t)od->id_inst_ptr[0]; - switch (id) - { - case 7: /* ifAdminStatus */ - { - s32_t *sint_ptr = (s32_t*)value; - if (*sint_ptr == 1 || *sint_ptr == 2) - set_ok = 1; - } - break; - } - return set_ok; -} - -static void -ifentry_set_value(struct obj_def *od, u16_t len, void *value) -{ - struct netif *netif; - u8_t id; - LWIP_UNUSED_ARG(len); - - snmp_ifindextonetif(od->id_inst_ptr[1], &netif); - id = (u8_t)od->id_inst_ptr[0]; - switch (id) - { - case 7: /* ifAdminStatus */ - { - s32_t *sint_ptr = (s32_t*)value; - if (*sint_ptr == 1) - { - netif_set_up(netif); - } - else if (*sint_ptr == 2) - { - netif_set_down(netif); - } - } - break; - } -} -#endif /* SNMP_SAFE_REQUESTS */ - -/** - * Returns atentry object definitions. - * - * @param ident_len the address length (6) - * @param ident points to objectname.atifindex.atnetaddress - * @param od points to object definition. - */ -static void -atentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od) -{ - /* return to object name, adding index depth (5) */ - ident_len += 5; - ident -= 5; - - if (ident_len == 6) - { - od->id_inst_len = ident_len; - od->id_inst_ptr = ident; - - switch (ident[0]) - { - case 1: /* atIfIndex */ - od->instance = MIB_OBJECT_TAB; - od->access = MIB_OBJECT_READ_WRITE; - od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG); - od->v_len = sizeof(s32_t); - break; - case 2: /* atPhysAddress */ - od->instance = MIB_OBJECT_TAB; - od->access = MIB_OBJECT_READ_WRITE; - od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR); - od->v_len = 6; /** @todo try to use netif::hwaddr_len */ - break; - case 3: /* atNetAddress */ - od->instance = MIB_OBJECT_TAB; - od->access = MIB_OBJECT_READ_WRITE; - od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_IPADDR); - od->v_len = 4; - break; - default: - LWIP_DEBUGF(SNMP_MIB_DEBUG,("atentry_get_object_def: no such object\n")); - od->instance = MIB_OBJECT_NONE; - break; - } - } - else - { - LWIP_DEBUGF(SNMP_MIB_DEBUG,("atentry_get_object_def: no scalar\n")); - od->instance = MIB_OBJECT_NONE; - } -} - -static void -atentry_get_value(struct obj_def *od, u16_t len, void *value) -{ -#if LWIP_ARP - u8_t id; - struct eth_addr* ethaddr_ret; - ip_addr_t* ipaddr_ret; -#endif /* LWIP_ARP */ - ip_addr_t ip; - struct netif *netif; - - LWIP_UNUSED_ARG(len); - LWIP_UNUSED_ARG(value);/* if !LWIP_ARP */ - - snmp_ifindextonetif(od->id_inst_ptr[1], &netif); - snmp_oidtoip(&od->id_inst_ptr[2], &ip); - -#if LWIP_ARP /** @todo implement a netif_find_addr */ - if (etharp_find_addr(netif, &ip, ðaddr_ret, &ipaddr_ret) > -1) - { - LWIP_ASSERT("invalid id", (od->id_inst_ptr[0] >= 0) && (od->id_inst_ptr[0] <= 0xff)); - id = (u8_t)od->id_inst_ptr[0]; - switch (id) - { - case 1: /* atIfIndex */ - { - s32_t *sint_ptr = (s32_t*)value; - *sint_ptr = od->id_inst_ptr[1]; - } - break; - case 2: /* atPhysAddress */ - { - struct eth_addr *dst = (struct eth_addr*)value; - - *dst = *ethaddr_ret; - } - break; - case 3: /* atNetAddress */ - { - ip_addr_t *dst = (ip_addr_t*)value; - - *dst = *ipaddr_ret; - } - break; - } - } -#endif /* LWIP_ARP */ -} - -static void -ip_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od) -{ - u8_t id; - - /* return to object name, adding index depth (1) */ - ident_len += 1; - ident -= 1; - if (ident_len == 2) - { - od->id_inst_len = ident_len; - od->id_inst_ptr = ident; - - LWIP_ASSERT("invalid id", (ident[0] >= 0) && (ident[0] <= 0xff)); - id = (u8_t)ident[0]; - LWIP_DEBUGF(SNMP_MIB_DEBUG,("get_object_def ip.%"U16_F".0\n",(u16_t)id)); - switch (id) - { - case 1: /* ipForwarding */ - case 2: /* ipDefaultTTL */ - od->instance = MIB_OBJECT_SCALAR; - od->access = MIB_OBJECT_READ_WRITE; - od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG); - od->v_len = sizeof(s32_t); - break; - case 3: /* ipInReceives */ - case 4: /* ipInHdrErrors */ - case 5: /* ipInAddrErrors */ - case 6: /* ipForwDatagrams */ - case 7: /* ipInUnknownProtos */ - case 8: /* ipInDiscards */ - case 9: /* ipInDelivers */ - case 10: /* ipOutRequests */ - case 11: /* ipOutDiscards */ - case 12: /* ipOutNoRoutes */ - case 14: /* ipReasmReqds */ - case 15: /* ipReasmOKs */ - case 16: /* ipReasmFails */ - case 17: /* ipFragOKs */ - case 18: /* ipFragFails */ - case 19: /* ipFragCreates */ - case 23: /* ipRoutingDiscards */ - od->instance = MIB_OBJECT_SCALAR; - od->access = MIB_OBJECT_READ_ONLY; - od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_COUNTER); - od->v_len = sizeof(u32_t); - break; - case 13: /* ipReasmTimeout */ - od->instance = MIB_OBJECT_SCALAR; - od->access = MIB_OBJECT_READ_ONLY; - od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG); - od->v_len = sizeof(s32_t); - break; - default: - LWIP_DEBUGF(SNMP_MIB_DEBUG,("ip_get_object_def: no such object\n")); - od->instance = MIB_OBJECT_NONE; - break; - }; - } - else - { - LWIP_DEBUGF(SNMP_MIB_DEBUG,("ip_get_object_def: no scalar\n")); - od->instance = MIB_OBJECT_NONE; - } -} - -static void -ip_get_value(struct obj_def *od, u16_t len, void *value) -{ - u8_t id; - - LWIP_UNUSED_ARG(len); - LWIP_ASSERT("invalid id", (od->id_inst_ptr[0] >= 0) && (od->id_inst_ptr[0] <= 0xff)); - id = (u8_t)od->id_inst_ptr[0]; - switch (id) - { - case 1: /* ipForwarding */ - { - s32_t *sint_ptr = (s32_t*)value; -#if IP_FORWARD - /* forwarding */ - *sint_ptr = 1; -#else - /* not-forwarding */ - *sint_ptr = 2; -#endif - } - break; - case 2: /* ipDefaultTTL */ - { - s32_t *sint_ptr = (s32_t*)value; - *sint_ptr = IP_DEFAULT_TTL; - } - break; - case 3: /* ipInReceives */ - { - u32_t *uint_ptr = (u32_t*)value; - *uint_ptr = ipinreceives; - } - break; - case 4: /* ipInHdrErrors */ - { - u32_t *uint_ptr = (u32_t*)value; - *uint_ptr = ipinhdrerrors; - } - break; - case 5: /* ipInAddrErrors */ - { - u32_t *uint_ptr = (u32_t*)value; - *uint_ptr = ipinaddrerrors; - } - break; - case 6: /* ipForwDatagrams */ - { - u32_t *uint_ptr = (u32_t*)value; - *uint_ptr = ipforwdatagrams; - } - break; - case 7: /* ipInUnknownProtos */ - { - u32_t *uint_ptr = (u32_t*)value; - *uint_ptr = ipinunknownprotos; - } - break; - case 8: /* ipInDiscards */ - { - u32_t *uint_ptr = (u32_t*)value; - *uint_ptr = ipindiscards; - } - break; - case 9: /* ipInDelivers */ - { - u32_t *uint_ptr = (u32_t*)value; - *uint_ptr = ipindelivers; - } - break; - case 10: /* ipOutRequests */ - { - u32_t *uint_ptr = (u32_t*)value; - *uint_ptr = ipoutrequests; - } - break; - case 11: /* ipOutDiscards */ - { - u32_t *uint_ptr = (u32_t*)value; - *uint_ptr = ipoutdiscards; - } - break; - case 12: /* ipOutNoRoutes */ - { - u32_t *uint_ptr = (u32_t*)value; - *uint_ptr = ipoutnoroutes; - } - break; - case 13: /* ipReasmTimeout */ - { - s32_t *sint_ptr = (s32_t*)value; -#if IP_REASSEMBLY - *sint_ptr = IP_REASS_MAXAGE; -#else - *sint_ptr = 0; -#endif - } - break; - case 14: /* ipReasmReqds */ - { - u32_t *uint_ptr = (u32_t*)value; - *uint_ptr = ipreasmreqds; - } - break; - case 15: /* ipReasmOKs */ - { - u32_t *uint_ptr = (u32_t*)value; - *uint_ptr = ipreasmoks; - } - break; - case 16: /* ipReasmFails */ - { - u32_t *uint_ptr = (u32_t*)value; - *uint_ptr = ipreasmfails; - } - break; - case 17: /* ipFragOKs */ - { - u32_t *uint_ptr = (u32_t*)value; - *uint_ptr = ipfragoks; - } - break; - case 18: /* ipFragFails */ - { - u32_t *uint_ptr = (u32_t*)value; - *uint_ptr = ipfragfails; - } - break; - case 19: /* ipFragCreates */ - { - u32_t *uint_ptr = (u32_t*)value; - *uint_ptr = ipfragcreates; - } - break; - case 23: /* ipRoutingDiscards */ - /** @todo can lwIP discard routes at all?? hardwire this to 0?? */ - { - u32_t *uint_ptr = (u32_t*)value; - *uint_ptr = iproutingdiscards; - } - break; - }; -} - -/** - * Test ip object value before setting. - * - * @param od is the object definition - * @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 u8_t -ip_set_test(struct obj_def *od, u16_t len, void *value) -{ - u8_t id, set_ok; - s32_t *sint_ptr = (s32_t*)value; - - LWIP_UNUSED_ARG(len); - set_ok = 0; - LWIP_ASSERT("invalid id", (od->id_inst_ptr[0] >= 0) && (od->id_inst_ptr[0] <= 0xff)); - id = (u8_t)od->id_inst_ptr[0]; - switch (id) - { - case 1: /* ipForwarding */ -#if IP_FORWARD - /* forwarding */ - if (*sint_ptr == 1) -#else - /* not-forwarding */ - if (*sint_ptr == 2) -#endif - { - set_ok = 1; - } - break; - case 2: /* ipDefaultTTL */ - if (*sint_ptr == IP_DEFAULT_TTL) - { - set_ok = 1; - } - break; - }; - return set_ok; -} - -static void -ip_addrentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od) -{ - /* return to object name, adding index depth (4) */ - ident_len += 4; - ident -= 4; - - if (ident_len == 5) - { - u8_t id; - - od->id_inst_len = ident_len; - od->id_inst_ptr = ident; - - LWIP_ASSERT("invalid id", (ident[0] >= 0) && (ident[0] <= 0xff)); - id = (u8_t)ident[0]; - switch (id) - { - case 1: /* ipAdEntAddr */ - case 3: /* ipAdEntNetMask */ - od->instance = MIB_OBJECT_TAB; - od->access = MIB_OBJECT_READ_ONLY; - od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_IPADDR); - od->v_len = 4; - break; - case 2: /* ipAdEntIfIndex */ - case 4: /* ipAdEntBcastAddr */ - case 5: /* ipAdEntReasmMaxSize */ - od->instance = MIB_OBJECT_TAB; - od->access = MIB_OBJECT_READ_ONLY; - od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG); - od->v_len = sizeof(s32_t); - break; - default: - LWIP_DEBUGF(SNMP_MIB_DEBUG,("ip_addrentry_get_object_def: no such object\n")); - od->instance = MIB_OBJECT_NONE; - break; - } - } - else - { - LWIP_DEBUGF(SNMP_MIB_DEBUG,("ip_addrentry_get_object_def: no scalar\n")); - od->instance = MIB_OBJECT_NONE; - } -} - -static void -ip_addrentry_get_value(struct obj_def *od, u16_t len, void *value) -{ - u8_t id; - u16_t ifidx; - ip_addr_t ip; - struct netif *netif = netif_list; - - LWIP_UNUSED_ARG(len); - snmp_oidtoip(&od->id_inst_ptr[1], &ip); - ifidx = 0; - while ((netif != NULL) && !ip_addr_cmp(&ip, &netif->ip_addr)) - { - netif = netif->next; - ifidx++; - } - - if (netif != NULL) - { - LWIP_ASSERT("invalid id", (od->id_inst_ptr[0] >= 0) && (od->id_inst_ptr[0] <= 0xff)); - id = (u8_t)od->id_inst_ptr[0]; - switch (id) - { - case 1: /* ipAdEntAddr */ - { - ip_addr_t *dst = (ip_addr_t*)value; - *dst = netif->ip_addr; - } - break; - case 2: /* ipAdEntIfIndex */ - { - s32_t *sint_ptr = (s32_t*)value; - *sint_ptr = ifidx + 1; - } - break; - case 3: /* ipAdEntNetMask */ - { - ip_addr_t *dst = (ip_addr_t*)value; - *dst = netif->netmask; - } - break; - case 4: /* ipAdEntBcastAddr */ - { - s32_t *sint_ptr = (s32_t*)value; - - /* lwIP oddity, there's no broadcast - address in the netif we can rely on */ - *sint_ptr = IPADDR_BROADCAST & 1; - } - break; - case 5: /* ipAdEntReasmMaxSize */ - { - s32_t *sint_ptr = (s32_t*)value; -#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... - */ - *sint_ptr = (IP_HLEN + ((IP_REASS_MAX_PBUFS/2) * - (PBUF_POOL_BUFSIZE - 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 */ - *sint_ptr = 0; -#endif - } - break; - } - } -} - -/** - * @note - * lwIP IP routing is currently using the network addresses in netif_list. - * if no suitable network IP is found in netif_list, the default_netif is used. - */ -static void -ip_rteentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od) -{ - u8_t id; - - /* return to object name, adding index depth (4) */ - ident_len += 4; - ident -= 4; - - if (ident_len == 5) - { - od->id_inst_len = ident_len; - od->id_inst_ptr = ident; - - LWIP_ASSERT("invalid id", (ident[0] >= 0) && (ident[0] <= 0xff)); - id = (u8_t)ident[0]; - switch (id) - { - case 1: /* ipRouteDest */ - case 7: /* ipRouteNextHop */ - case 11: /* ipRouteMask */ - od->instance = MIB_OBJECT_TAB; - od->access = MIB_OBJECT_READ_WRITE; - od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_IPADDR); - od->v_len = 4; - break; - case 2: /* ipRouteIfIndex */ - case 3: /* ipRouteMetric1 */ - case 4: /* ipRouteMetric2 */ - case 5: /* ipRouteMetric3 */ - case 6: /* ipRouteMetric4 */ - case 8: /* ipRouteType */ - case 10: /* ipRouteAge */ - case 12: /* ipRouteMetric5 */ - od->instance = MIB_OBJECT_TAB; - od->access = MIB_OBJECT_READ_WRITE; - od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG); - od->v_len = sizeof(s32_t); - break; - case 9: /* ipRouteProto */ - od->instance = MIB_OBJECT_TAB; - od->access = MIB_OBJECT_READ_ONLY; - od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG); - od->v_len = sizeof(s32_t); - break; - case 13: /* ipRouteInfo */ - /** @note returning zeroDotZero (0.0) no routing protocol specific MIB */ - od->instance = MIB_OBJECT_TAB; - od->access = MIB_OBJECT_READ_ONLY; - od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OBJ_ID); - od->v_len = iprouteinfo.len * sizeof(s32_t); - break; - default: - LWIP_DEBUGF(SNMP_MIB_DEBUG,("ip_rteentry_get_object_def: no such object\n")); - od->instance = MIB_OBJECT_NONE; - break; - } - } - else - { - LWIP_DEBUGF(SNMP_MIB_DEBUG,("ip_rteentry_get_object_def: no scalar\n")); - od->instance = MIB_OBJECT_NONE; - } -} - -static void -ip_rteentry_get_value(struct obj_def *od, u16_t len, void *value) -{ - struct netif *netif; - ip_addr_t dest; - s32_t *ident; - u8_t id; - - ident = od->id_inst_ptr; - snmp_oidtoip(&ident[1], &dest); - - if (ip_addr_isany(&dest)) - { - /* ip_route() uses default netif for default route */ - netif = netif_default; - } - else - { - /* not using ip_route(), need exact match! */ - netif = netif_list; - while ((netif != NULL) && - !ip_addr_netcmp(&dest, &(netif->ip_addr), &(netif->netmask)) ) - { - netif = netif->next; - } - } - if (netif != NULL) - { - LWIP_ASSERT("invalid id", (ident[0] >= 0) && (ident[0] <= 0xff)); - id = (u8_t)ident[0]; - switch (id) - { - case 1: /* ipRouteDest */ - { - ip_addr_t *dst = (ip_addr_t*)value; - - if (ip_addr_isany(&dest)) - { - /* default rte has 0.0.0.0 dest */ - ip_addr_set_zero(dst); - } - else - { - /* netifs have netaddress dest */ - ip_addr_get_network(dst, &netif->ip_addr, &netif->netmask); - } - } - break; - case 2: /* ipRouteIfIndex */ - { - s32_t *sint_ptr = (s32_t*)value; - - snmp_netiftoifindex(netif, sint_ptr); - } - break; - case 3: /* ipRouteMetric1 */ - { - s32_t *sint_ptr = (s32_t*)value; - - if (ip_addr_isany(&dest)) - { - /* default rte has metric 1 */ - *sint_ptr = 1; - } - else - { - /* other rtes have metric 0 */ - *sint_ptr = 0; - } - } - break; - case 4: /* ipRouteMetric2 */ - case 5: /* ipRouteMetric3 */ - case 6: /* ipRouteMetric4 */ - case 12: /* ipRouteMetric5 */ - { - s32_t *sint_ptr = (s32_t*)value; - /* not used */ - *sint_ptr = -1; - } - break; - case 7: /* ipRouteNextHop */ - { - ip_addr_t *dst = (ip_addr_t*)value; - - if (ip_addr_isany(&dest)) - { - /* default rte: gateway */ - *dst = netif->gw; - } - else - { - /* other rtes: netif ip_addr */ - *dst = netif->ip_addr; - } - } - break; - case 8: /* ipRouteType */ - { - s32_t *sint_ptr = (s32_t*)value; - - if (ip_addr_isany(&dest)) - { - /* default rte is indirect */ - *sint_ptr = 4; - } - else - { - /* other rtes are direct */ - *sint_ptr = 3; - } - } - break; - case 9: /* ipRouteProto */ - { - s32_t *sint_ptr = (s32_t*)value; - /* locally defined routes */ - *sint_ptr = 2; - } - break; - case 10: /* ipRouteAge */ - { - s32_t *sint_ptr = (s32_t*)value; - /** @todo (sysuptime - timestamp last change) / 100 - @see snmp_insert_iprteidx_tree() */ - *sint_ptr = 0; - } - break; - case 11: /* ipRouteMask */ - { - ip_addr_t *dst = (ip_addr_t*)value; - - if (ip_addr_isany(&dest)) - { - /* default rte use 0.0.0.0 mask */ - ip_addr_set_zero(dst); - } - else - { - /* other rtes use netmask */ - *dst = netif->netmask; - } - } - break; - case 13: /* ipRouteInfo */ - objectidncpy((s32_t*)value, (s32_t*)iprouteinfo.id, (u8_t)(len / sizeof(s32_t))); - break; - } - } -} - -static void -ip_ntomentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od) -{ - /* return to object name, adding index depth (5) */ - ident_len += 5; - ident -= 5; - - if (ident_len == 6) - { - u8_t id; - - od->id_inst_len = ident_len; - od->id_inst_ptr = ident; - - LWIP_ASSERT("invalid id", (ident[0] >= 0) && (ident[0] <= 0xff)); - id = (u8_t)ident[0]; - switch (id) - { - case 1: /* ipNetToMediaIfIndex */ - case 4: /* ipNetToMediaType */ - od->instance = MIB_OBJECT_TAB; - od->access = MIB_OBJECT_READ_WRITE; - od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG); - od->v_len = sizeof(s32_t); - break; - case 2: /* ipNetToMediaPhysAddress */ - od->instance = MIB_OBJECT_TAB; - od->access = MIB_OBJECT_READ_WRITE; - od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR); - od->v_len = 6; /** @todo try to use netif::hwaddr_len */ - break; - case 3: /* ipNetToMediaNetAddress */ - od->instance = MIB_OBJECT_TAB; - od->access = MIB_OBJECT_READ_WRITE; - od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_IPADDR); - od->v_len = 4; - break; - default: - LWIP_DEBUGF(SNMP_MIB_DEBUG,("ip_ntomentry_get_object_def: no such object\n")); - od->instance = MIB_OBJECT_NONE; - break; - } - } - else - { - LWIP_DEBUGF(SNMP_MIB_DEBUG,("ip_ntomentry_get_object_def: no scalar\n")); - od->instance = MIB_OBJECT_NONE; - } -} - -static void -ip_ntomentry_get_value(struct obj_def *od, u16_t len, void *value) -{ -#if LWIP_ARP - u8_t id; - struct eth_addr* ethaddr_ret; - ip_addr_t* ipaddr_ret; -#endif /* LWIP_ARP */ - ip_addr_t ip; - struct netif *netif; - - LWIP_UNUSED_ARG(len); - LWIP_UNUSED_ARG(value);/* if !LWIP_ARP */ - - snmp_ifindextonetif(od->id_inst_ptr[1], &netif); - snmp_oidtoip(&od->id_inst_ptr[2], &ip); - -#if LWIP_ARP /** @todo implement a netif_find_addr */ - if (etharp_find_addr(netif, &ip, ðaddr_ret, &ipaddr_ret) > -1) - { - LWIP_ASSERT("invalid id", (od->id_inst_ptr[0] >= 0) && (od->id_inst_ptr[0] <= 0xff)); - id = (u8_t)od->id_inst_ptr[0]; - switch (id) - { - case 1: /* ipNetToMediaIfIndex */ - { - s32_t *sint_ptr = (s32_t*)value; - *sint_ptr = od->id_inst_ptr[1]; - } - break; - case 2: /* ipNetToMediaPhysAddress */ - { - struct eth_addr *dst = (struct eth_addr*)value; - - *dst = *ethaddr_ret; - } - break; - case 3: /* ipNetToMediaNetAddress */ - { - ip_addr_t *dst = (ip_addr_t*)value; - - *dst = *ipaddr_ret; - } - break; - case 4: /* ipNetToMediaType */ - { - s32_t *sint_ptr = (s32_t*)value; - /* dynamic (?) */ - *sint_ptr = 3; - } - break; - } - } -#endif /* LWIP_ARP */ -} - -static void -icmp_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od) -{ - /* return to object name, adding index depth (1) */ - ident_len += 1; - ident -= 1; - if ((ident_len == 2) && - (ident[0] > 0) && (ident[0] < 27)) - { - od->id_inst_len = ident_len; - od->id_inst_ptr = ident; - - od->instance = MIB_OBJECT_SCALAR; - od->access = MIB_OBJECT_READ_ONLY; - od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_COUNTER); - od->v_len = sizeof(u32_t); - } - else - { - LWIP_DEBUGF(SNMP_MIB_DEBUG,("icmp_get_object_def: no scalar\n")); - od->instance = MIB_OBJECT_NONE; - } -} - -static void -icmp_get_value(struct obj_def *od, u16_t len, void *value) -{ - u32_t *uint_ptr = (u32_t*)value; - u8_t id; - - LWIP_UNUSED_ARG(len); - LWIP_ASSERT("invalid id", (od->id_inst_ptr[0] >= 0) && (od->id_inst_ptr[0] <= 0xff)); - id = (u8_t)od->id_inst_ptr[0]; - switch (id) - { - case 1: /* icmpInMsgs */ - *uint_ptr = icmpinmsgs; - break; - case 2: /* icmpInErrors */ - *uint_ptr = icmpinerrors; - break; - case 3: /* icmpInDestUnreachs */ - *uint_ptr = icmpindestunreachs; - break; - case 4: /* icmpInTimeExcds */ - *uint_ptr = icmpintimeexcds; - break; - case 5: /* icmpInParmProbs */ - *uint_ptr = icmpinparmprobs; - break; - case 6: /* icmpInSrcQuenchs */ - *uint_ptr = icmpinsrcquenchs; - break; - case 7: /* icmpInRedirects */ - *uint_ptr = icmpinredirects; - break; - case 8: /* icmpInEchos */ - *uint_ptr = icmpinechos; - break; - case 9: /* icmpInEchoReps */ - *uint_ptr = icmpinechoreps; - break; - case 10: /* icmpInTimestamps */ - *uint_ptr = icmpintimestamps; - break; - case 11: /* icmpInTimestampReps */ - *uint_ptr = icmpintimestampreps; - break; - case 12: /* icmpInAddrMasks */ - *uint_ptr = icmpinaddrmasks; - break; - case 13: /* icmpInAddrMaskReps */ - *uint_ptr = icmpinaddrmaskreps; - break; - case 14: /* icmpOutMsgs */ - *uint_ptr = icmpoutmsgs; - break; - case 15: /* icmpOutErrors */ - *uint_ptr = icmpouterrors; - break; - case 16: /* icmpOutDestUnreachs */ - *uint_ptr = icmpoutdestunreachs; - break; - case 17: /* icmpOutTimeExcds */ - *uint_ptr = icmpouttimeexcds; - break; - case 18: /* icmpOutParmProbs */ - *uint_ptr = icmpoutparmprobs; - break; - case 19: /* icmpOutSrcQuenchs */ - *uint_ptr = icmpoutsrcquenchs; - break; - case 20: /* icmpOutRedirects */ - *uint_ptr = icmpoutredirects; - break; - case 21: /* icmpOutEchos */ - *uint_ptr = icmpoutechos; - break; - case 22: /* icmpOutEchoReps */ - *uint_ptr = icmpoutechoreps; - break; - case 23: /* icmpOutTimestamps */ - *uint_ptr = icmpouttimestamps; - break; - case 24: /* icmpOutTimestampReps */ - *uint_ptr = icmpouttimestampreps; - break; - case 25: /* icmpOutAddrMasks */ - *uint_ptr = icmpoutaddrmasks; - break; - case 26: /* icmpOutAddrMaskReps */ - *uint_ptr = icmpoutaddrmaskreps; - break; - } -} - -#if LWIP_TCP -/** @todo tcp grp */ -static void -tcp_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od) -{ - u8_t id; - - /* return to object name, adding index depth (1) */ - ident_len += 1; - ident -= 1; - if (ident_len == 2) - { - od->id_inst_len = ident_len; - od->id_inst_ptr = ident; - - LWIP_ASSERT("invalid id", (ident[0] >= 0) && (ident[0] <= 0xff)); - id = (u8_t)ident[0]; - LWIP_DEBUGF(SNMP_MIB_DEBUG,("get_object_def tcp.%"U16_F".0\n",(u16_t)id)); - - switch (id) - { - case 1: /* tcpRtoAlgorithm */ - case 2: /* tcpRtoMin */ - case 3: /* tcpRtoMax */ - case 4: /* tcpMaxConn */ - od->instance = MIB_OBJECT_SCALAR; - od->access = MIB_OBJECT_READ_ONLY; - od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG); - od->v_len = sizeof(s32_t); - break; - case 5: /* tcpActiveOpens */ - case 6: /* tcpPassiveOpens */ - case 7: /* tcpAttemptFails */ - case 8: /* tcpEstabResets */ - case 10: /* tcpInSegs */ - case 11: /* tcpOutSegs */ - case 12: /* tcpRetransSegs */ - case 14: /* tcpInErrs */ - case 15: /* tcpOutRsts */ - od->instance = MIB_OBJECT_SCALAR; - od->access = MIB_OBJECT_READ_ONLY; - od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_COUNTER); - od->v_len = sizeof(u32_t); - break; - case 9: /* tcpCurrEstab */ - od->instance = MIB_OBJECT_TAB; - od->access = MIB_OBJECT_READ_ONLY; - od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_GAUGE); - od->v_len = sizeof(u32_t); - break; - default: - LWIP_DEBUGF(SNMP_MIB_DEBUG,("tcp_get_object_def: no such object\n")); - od->instance = MIB_OBJECT_NONE; - break; - }; - } - else - { - LWIP_DEBUGF(SNMP_MIB_DEBUG,("tcp_get_object_def: no scalar\n")); - od->instance = MIB_OBJECT_NONE; - } -} - -static void -tcp_get_value(struct obj_def *od, u16_t len, void *value) -{ - u32_t *uint_ptr = (u32_t*)value; - s32_t *sint_ptr = (s32_t*)value; - u8_t id; - - LWIP_UNUSED_ARG(len); - LWIP_ASSERT("invalid id", (od->id_inst_ptr[0] >= 0) && (od->id_inst_ptr[0] <= 0xff)); - id = (u8_t)od->id_inst_ptr[0]; - switch (id) - { - case 1: /* tcpRtoAlgorithm, vanj(4) */ - *sint_ptr = 4; - break; - case 2: /* tcpRtoMin */ - /* @todo not the actual value, a guess, - needs to be calculated */ - *sint_ptr = 1000; - break; - case 3: /* tcpRtoMax */ - /* @todo not the actual value, a guess, - needs to be calculated */ - *sint_ptr = 60000; - break; - case 4: /* tcpMaxConn */ - *sint_ptr = MEMP_NUM_TCP_PCB; - break; - case 5: /* tcpActiveOpens */ - *uint_ptr = tcpactiveopens; - break; - case 6: /* tcpPassiveOpens */ - *uint_ptr = tcppassiveopens; - break; - case 7: /* tcpAttemptFails */ - *uint_ptr = tcpattemptfails; - break; - case 8: /* tcpEstabResets */ - *uint_ptr = tcpestabresets; - break; - 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; - } - break; - case 10: /* tcpInSegs */ - *uint_ptr = tcpinsegs; - break; - case 11: /* tcpOutSegs */ - *uint_ptr = tcpoutsegs; - break; - case 12: /* tcpRetransSegs */ - *uint_ptr = tcpretranssegs; - break; - case 14: /* tcpInErrs */ - *uint_ptr = tcpinerrs; - break; - case 15: /* tcpOutRsts */ - *uint_ptr = tcpoutrsts; - break; - } -} -#ifdef THIS_SEEMS_UNUSED -static void -tcpconnentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od) -{ - /* return to object name, adding index depth (10) */ - ident_len += 10; - ident -= 10; - - if (ident_len == 11) - { - u8_t id; - - od->id_inst_len = ident_len; - od->id_inst_ptr = ident; - - id = ident[0]; - LWIP_DEBUGF(SNMP_MIB_DEBUG,("get_object_def tcp.%"U16_F".0\n",(u16_t)id)); - - switch (id) - { - case 1: /* tcpConnState */ - od->instance = MIB_OBJECT_TAB; - od->access = MIB_OBJECT_READ_WRITE; - od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG); - od->v_len = sizeof(s32_t); - break; - case 2: /* tcpConnLocalAddress */ - case 4: /* tcpConnRemAddress */ - od->instance = MIB_OBJECT_TAB; - od->access = MIB_OBJECT_READ_ONLY; - od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_IPADDR); - od->v_len = 4; - break; - case 3: /* tcpConnLocalPort */ - case 5: /* tcpConnRemPort */ - od->instance = MIB_OBJECT_TAB; - od->access = MIB_OBJECT_READ_ONLY; - od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG); - od->v_len = sizeof(s32_t); - break; - default: - LWIP_DEBUGF(SNMP_MIB_DEBUG,("tcpconnentry_get_object_def: no such object\n")); - od->instance = MIB_OBJECT_NONE; - break; - }; - } - else - { - LWIP_DEBUGF(SNMP_MIB_DEBUG,("tcpconnentry_get_object_def: no such object\n")); - od->instance = MIB_OBJECT_NONE; - } -} - -static void -tcpconnentry_get_value(struct obj_def *od, u16_t len, void *value) -{ - ip_addr_t lip, rip; - u16_t lport, rport; - s32_t *ident; - - ident = od->id_inst_ptr; - snmp_oidtoip(&ident[1], &lip); - lport = ident[5]; - snmp_oidtoip(&ident[6], &rip); - rport = ident[10]; - - /** @todo find matching PCB */ -} -#endif /* if 0 */ -#endif - -static void -udp_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od) -{ - /* return to object name, adding index depth (1) */ - ident_len += 1; - ident -= 1; - if ((ident_len == 2) && - (ident[0] > 0) && (ident[0] < 6)) - { - od->id_inst_len = ident_len; - od->id_inst_ptr = ident; - - od->instance = MIB_OBJECT_SCALAR; - od->access = MIB_OBJECT_READ_ONLY; - od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_COUNTER); - od->v_len = sizeof(u32_t); - } - else - { - LWIP_DEBUGF(SNMP_MIB_DEBUG,("udp_get_object_def: no scalar\n")); - od->instance = MIB_OBJECT_NONE; - } -} - -static void -udp_get_value(struct obj_def *od, u16_t len, void *value) -{ - u32_t *uint_ptr = (u32_t*)value; - u8_t id; - - LWIP_UNUSED_ARG(len); - LWIP_ASSERT("invalid id", (od->id_inst_ptr[0] >= 0) && (od->id_inst_ptr[0] <= 0xff)); - id = (u8_t)od->id_inst_ptr[0]; - switch (id) - { - case 1: /* udpInDatagrams */ - *uint_ptr = udpindatagrams; - break; - case 2: /* udpNoPorts */ - *uint_ptr = udpnoports; - break; - case 3: /* udpInErrors */ - *uint_ptr = udpinerrors; - break; - case 4: /* udpOutDatagrams */ - *uint_ptr = udpoutdatagrams; - break; - } -} - -static void -udpentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od) -{ - /* return to object name, adding index depth (5) */ - ident_len += 5; - ident -= 5; - - if (ident_len == 6) - { - od->id_inst_len = ident_len; - od->id_inst_ptr = ident; - - switch (ident[0]) - { - case 1: /* udpLocalAddress */ - od->instance = MIB_OBJECT_TAB; - od->access = MIB_OBJECT_READ_ONLY; - od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_IPADDR); - od->v_len = 4; - break; - case 2: /* udpLocalPort */ - od->instance = MIB_OBJECT_TAB; - od->access = MIB_OBJECT_READ_ONLY; - od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG); - od->v_len = sizeof(s32_t); - break; - default: - LWIP_DEBUGF(SNMP_MIB_DEBUG,("udpentry_get_object_def: no such object\n")); - od->instance = MIB_OBJECT_NONE; - break; - } - } - else - { - LWIP_DEBUGF(SNMP_MIB_DEBUG,("udpentry_get_object_def: no scalar\n")); - od->instance = MIB_OBJECT_NONE; - } -} - -static void -udpentry_get_value(struct obj_def *od, u16_t len, void *value) -{ - u8_t id; - struct udp_pcb *pcb; - ip_addr_t ip; - u16_t port; - - LWIP_UNUSED_ARG(len); - snmp_oidtoip(&od->id_inst_ptr[1], &ip); - LWIP_ASSERT("invalid port", (od->id_inst_ptr[5] >= 0) && (od->id_inst_ptr[5] <= 0xffff)); - port = (u16_t)od->id_inst_ptr[5]; - - pcb = udp_pcbs; - while ((pcb != NULL) && - !(ip_addr_cmp(&pcb->local_ip, &ip) && - (pcb->local_port == port))) - { - pcb = pcb->next; - } - - if (pcb != NULL) - { - LWIP_ASSERT("invalid id", (od->id_inst_ptr[0] >= 0) && (od->id_inst_ptr[0] <= 0xff)); - id = (u8_t)od->id_inst_ptr[0]; - switch (id) - { - case 1: /* udpLocalAddress */ - { - ip_addr_t *dst = (ip_addr_t*)value; - *dst = pcb->local_ip; - } - break; - case 2: /* udpLocalPort */ - { - s32_t *sint_ptr = (s32_t*)value; - *sint_ptr = pcb->local_port; - } - break; - } - } -} - -static void -snmp_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od) -{ - /* return to object name, adding index depth (1) */ - ident_len += 1; - ident -= 1; - if (ident_len == 2) - { - u8_t id; - - od->id_inst_len = ident_len; - od->id_inst_ptr = ident; - - LWIP_ASSERT("invalid id", (ident[0] >= 0) && (ident[0] <= 0xff)); - id = (u8_t)ident[0]; - switch (id) - { - case 1: /* snmpInPkts */ - case 2: /* snmpOutPkts */ - case 3: /* snmpInBadVersions */ - case 4: /* snmpInBadCommunityNames */ - case 5: /* snmpInBadCommunityUses */ - case 6: /* snmpInASNParseErrs */ - case 8: /* snmpInTooBigs */ - case 9: /* snmpInNoSuchNames */ - case 10: /* snmpInBadValues */ - case 11: /* snmpInReadOnlys */ - case 12: /* snmpInGenErrs */ - case 13: /* snmpInTotalReqVars */ - case 14: /* snmpInTotalSetVars */ - case 15: /* snmpInGetRequests */ - case 16: /* snmpInGetNexts */ - case 17: /* snmpInSetRequests */ - case 18: /* snmpInGetResponses */ - case 19: /* snmpInTraps */ - case 20: /* snmpOutTooBigs */ - case 21: /* snmpOutNoSuchNames */ - case 22: /* snmpOutBadValues */ - case 24: /* snmpOutGenErrs */ - case 25: /* snmpOutGetRequests */ - case 26: /* snmpOutGetNexts */ - case 27: /* snmpOutSetRequests */ - case 28: /* snmpOutGetResponses */ - case 29: /* snmpOutTraps */ - od->instance = MIB_OBJECT_SCALAR; - od->access = MIB_OBJECT_READ_ONLY; - od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_COUNTER); - od->v_len = sizeof(u32_t); - break; - case 30: /* snmpEnableAuthenTraps */ - od->instance = MIB_OBJECT_SCALAR; - od->access = MIB_OBJECT_READ_WRITE; - od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG); - od->v_len = sizeof(s32_t); - break; - default: - LWIP_DEBUGF(SNMP_MIB_DEBUG,("snmp_get_object_def: no such object\n")); - od->instance = MIB_OBJECT_NONE; - break; - }; - } - else - { - LWIP_DEBUGF(SNMP_MIB_DEBUG,("snmp_get_object_def: no scalar\n")); - od->instance = MIB_OBJECT_NONE; - } -} - -static void -snmp_get_value(struct obj_def *od, u16_t len, void *value) -{ - u32_t *uint_ptr = (u32_t*)value; - u8_t id; - - LWIP_UNUSED_ARG(len); - LWIP_ASSERT("invalid id", (od->id_inst_ptr[0] >= 0) && (od->id_inst_ptr[0] <= 0xff)); - id = (u8_t)od->id_inst_ptr[0]; - switch (id) - { - case 1: /* snmpInPkts */ - *uint_ptr = snmpinpkts; - break; - case 2: /* snmpOutPkts */ - *uint_ptr = snmpoutpkts; - break; - case 3: /* snmpInBadVersions */ - *uint_ptr = snmpinbadversions; - break; - case 4: /* snmpInBadCommunityNames */ - *uint_ptr = snmpinbadcommunitynames; - break; - case 5: /* snmpInBadCommunityUses */ - *uint_ptr = snmpinbadcommunityuses; - break; - case 6: /* snmpInASNParseErrs */ - *uint_ptr = snmpinasnparseerrs; - break; - case 8: /* snmpInTooBigs */ - *uint_ptr = snmpintoobigs; - break; - case 9: /* snmpInNoSuchNames */ - *uint_ptr = snmpinnosuchnames; - break; - case 10: /* snmpInBadValues */ - *uint_ptr = snmpinbadvalues; - break; - case 11: /* snmpInReadOnlys */ - *uint_ptr = snmpinreadonlys; - break; - case 12: /* snmpInGenErrs */ - *uint_ptr = snmpingenerrs; - break; - case 13: /* snmpInTotalReqVars */ - *uint_ptr = snmpintotalreqvars; - break; - case 14: /* snmpInTotalSetVars */ - *uint_ptr = snmpintotalsetvars; - break; - case 15: /* snmpInGetRequests */ - *uint_ptr = snmpingetrequests; - break; - case 16: /* snmpInGetNexts */ - *uint_ptr = snmpingetnexts; - break; - case 17: /* snmpInSetRequests */ - *uint_ptr = snmpinsetrequests; - break; - case 18: /* snmpInGetResponses */ - *uint_ptr = snmpingetresponses; - break; - case 19: /* snmpInTraps */ - *uint_ptr = snmpintraps; - break; - case 20: /* snmpOutTooBigs */ - *uint_ptr = snmpouttoobigs; - break; - case 21: /* snmpOutNoSuchNames */ - *uint_ptr = snmpoutnosuchnames; - break; - case 22: /* snmpOutBadValues */ - *uint_ptr = snmpoutbadvalues; - break; - case 24: /* snmpOutGenErrs */ - *uint_ptr = snmpoutgenerrs; - break; - case 25: /* snmpOutGetRequests */ - *uint_ptr = snmpoutgetrequests; - break; - case 26: /* snmpOutGetNexts */ - *uint_ptr = snmpoutgetnexts; - break; - case 27: /* snmpOutSetRequests */ - *uint_ptr = snmpoutsetrequests; - break; - case 28: /* snmpOutGetResponses */ - *uint_ptr = snmpoutgetresponses; - break; - case 29: /* snmpOutTraps */ - *uint_ptr = snmpouttraps; - break; - case 30: /* snmpEnableAuthenTraps */ - *uint_ptr = *snmpenableauthentraps_ptr; - break; - }; -} - -/** - * Test snmp object value before setting. - * - * @param od is the object definition - * @param len return value space (in bytes) - * @param value points to (varbind) space to copy value from. - */ -static u8_t -snmp_set_test(struct obj_def *od, u16_t len, void *value) -{ - u8_t id, set_ok; - - LWIP_UNUSED_ARG(len); - set_ok = 0; - LWIP_ASSERT("invalid id", (od->id_inst_ptr[0] >= 0) && (od->id_inst_ptr[0] <= 0xff)); - id = (u8_t)od->id_inst_ptr[0]; - if (id == 30) - { - /* snmpEnableAuthenTraps */ - s32_t *sint_ptr = (s32_t*)value; - - if (snmpenableauthentraps_ptr != &snmpenableauthentraps_default) - { - /* we should have writable non-volatile mem here */ - if ((*sint_ptr == 1) || (*sint_ptr == 2)) - { - set_ok = 1; - } - } - else - { - /* const or hardwired value */ - if (*sint_ptr == snmpenableauthentraps_default) - { - set_ok = 1; - } - } - } - return set_ok; -} - -static void -snmp_set_value(struct obj_def *od, u16_t len, void *value) -{ - u8_t id; - - LWIP_UNUSED_ARG(len); - LWIP_ASSERT("invalid id", (od->id_inst_ptr[0] >= 0) && (od->id_inst_ptr[0] <= 0xff)); - id = (u8_t)od->id_inst_ptr[0]; - if (id == 30) - { - /* snmpEnableAuthenTraps */ - /* @todo @fixme: which kind of pointer is 'value'? s32_t or u8_t??? */ - u8_t *ptr = (u8_t*)value; - *snmpenableauthentraps_ptr = *ptr; - } -} - -#endif /* LWIP_SNMP */ diff --git a/features/net/FEATURE_IPV4/lwip-interface/lwip/core/snmp/lwip_mib_structs.c b/features/net/FEATURE_IPV4/lwip-interface/lwip/core/snmp/lwip_mib_structs.c deleted file mode 100644 index 2f185cb436..0000000000 --- a/features/net/FEATURE_IPV4/lwip-interface/lwip/core/snmp/lwip_mib_structs.c +++ /dev/null @@ -1,1174 +0,0 @@ -/** - * @file - * MIB tree access/construction 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: Christiaan Simons - */ - -#include "lwip/opt.h" - -#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/snmp_structs.h" -#include "lwip/memp.h" -#include "lwip/netif.h" - -/** .iso.org.dod.internet address prefix, @see snmp_iso_*() */ -const s32_t prefix[4] = {1, 3, 6, 1}; - -#define NODE_STACK_SIZE (LWIP_SNMP_OBJ_ID_LEN) -/** node stack entry (old news?) */ -struct nse -{ - /** right child */ - struct mib_node* r_ptr; - /** right child identifier */ - s32_t r_id; - /** right child next level */ - u8_t r_nl; -}; -static u8_t node_stack_cnt; -static struct nse node_stack[NODE_STACK_SIZE]; - -/** - * Pushes nse struct onto stack. - */ -static void -push_node(struct nse* node) -{ - LWIP_ASSERT("node_stack_cnt < NODE_STACK_SIZE",node_stack_cnt < NODE_STACK_SIZE); - LWIP_DEBUGF(SNMP_MIB_DEBUG,("push_node() node=%p id=%"S32_F"\n",(void*)(node->r_ptr),node->r_id)); - if (node_stack_cnt < NODE_STACK_SIZE) - { - node_stack[node_stack_cnt] = *node; - node_stack_cnt++; - } -} - -/** - * Pops nse struct from stack. - */ -static void -pop_node(struct nse* node) -{ - if (node_stack_cnt > 0) - { - node_stack_cnt--; - *node = node_stack[node_stack_cnt]; - } - LWIP_DEBUGF(SNMP_MIB_DEBUG,("pop_node() node=%p id=%"S32_F"\n",(void *)(node->r_ptr),node->r_id)); -} - -/** - * Conversion from ifIndex to lwIP netif - * @param ifindex is a s32_t object sub-identifier - * @param netif points to returned netif struct pointer - */ -void -snmp_ifindextonetif(s32_t ifindex, struct netif **netif) -{ - struct netif *nif = netif_list; - s32_t i, ifidx; - - ifidx = ifindex - 1; - i = 0; - while ((nif != NULL) && (i < ifidx)) - { - nif = nif->next; - i++; - } - *netif = nif; -} - -/** - * Conversion from lwIP netif to ifIndex - * @param netif points to a netif struct - * @param ifidx points to s32_t object sub-identifier - */ -void -snmp_netiftoifindex(struct netif *netif, s32_t *ifidx) -{ - struct netif *nif = netif_list; - u16_t i; - - i = 0; - while ((nif != NULL) && (nif != netif)) - { - nif = nif->next; - i++; - } - *ifidx = i+1; -} - -/** - * Conversion from oid to lwIP ip_addr - * @param ident points to s32_t ident[4] input - * @param ip points to output struct - */ -void -snmp_oidtoip(s32_t *ident, ip_addr_t *ip) -{ - IP4_ADDR(ip, ident[0], ident[1], ident[2], ident[3]); -} - -/** - * Conversion from lwIP ip_addr to oid - * @param ip points to input struct - * @param ident points to s32_t ident[4] output - */ -void -snmp_iptooid(ip_addr_t *ip, s32_t *ident) -{ - ident[0] = ip4_addr1(ip); - ident[1] = ip4_addr2(ip); - ident[2] = ip4_addr3(ip); - ident[3] = ip4_addr4(ip); -} - -struct mib_list_node * -snmp_mib_ln_alloc(s32_t id) -{ - struct mib_list_node *ln; - - ln = (struct mib_list_node *)memp_malloc(MEMP_SNMP_NODE); - if (ln != NULL) - { - ln->prev = NULL; - ln->next = NULL; - ln->objid = id; - ln->nptr = NULL; - } - return ln; -} - -void -snmp_mib_ln_free(struct mib_list_node *ln) -{ - memp_free(MEMP_SNMP_NODE, ln); -} - -struct mib_list_rootnode * -snmp_mib_lrn_alloc(void) -{ - struct mib_list_rootnode *lrn; - - lrn = (struct mib_list_rootnode*)memp_malloc(MEMP_SNMP_ROOTNODE); - if (lrn != NULL) - { - lrn->get_object_def = noleafs_get_object_def; - lrn->get_value = noleafs_get_value; - lrn->set_test = noleafs_set_test; - lrn->set_value = noleafs_set_value; - lrn->node_type = MIB_NODE_LR; - lrn->maxlength = 0; - lrn->head = NULL; - lrn->tail = NULL; - lrn->count = 0; - } - return lrn; -} - -void -snmp_mib_lrn_free(struct mib_list_rootnode *lrn) -{ - memp_free(MEMP_SNMP_ROOTNODE, lrn); -} - -/** - * Inserts node in idx list in a sorted - * (ascending order) fashion and - * allocates the node if needed. - * - * @param rn points to the root node - * @param objid is the object sub identifier - * @param insn points to a pointer to the inserted node - * used for constructing the tree. - * @return -1 if failed, 1 if inserted, 2 if present. - */ -s8_t -snmp_mib_node_insert(struct mib_list_rootnode *rn, s32_t objid, struct mib_list_node **insn) -{ - struct mib_list_node *nn; - s8_t insert; - - LWIP_ASSERT("rn != NULL",rn != NULL); - - /* -1 = malloc failure, 0 = not inserted, 1 = inserted, 2 = was present */ - insert = 0; - if (rn->head == NULL) - { - /* empty list, add first node */ - LWIP_DEBUGF(SNMP_MIB_DEBUG,("alloc empty list objid==%"S32_F"\n",objid)); - nn = snmp_mib_ln_alloc(objid); - if (nn != NULL) - { - rn->head = nn; - rn->tail = nn; - *insn = nn; - insert = 1; - } - else - { - insert = -1; - } - } - else - { - struct mib_list_node *n; - /* at least one node is present */ - n = rn->head; - while ((n != NULL) && (insert == 0)) - { - if (n->objid == objid) - { - /* node is already there */ - LWIP_DEBUGF(SNMP_MIB_DEBUG,("node already there objid==%"S32_F"\n",objid)); - *insn = n; - insert = 2; - } - else if (n->objid < objid) - { - if (n->next == NULL) - { - /* alloc and insert at the tail */ - LWIP_DEBUGF(SNMP_MIB_DEBUG,("alloc ins tail objid==%"S32_F"\n",objid)); - nn = snmp_mib_ln_alloc(objid); - if (nn != NULL) - { - nn->next = NULL; - nn->prev = n; - n->next = nn; - rn->tail = nn; - *insn = nn; - insert = 1; - } - else - { - /* insertion failure */ - insert = -1; - } - } - else - { - /* there's more to explore: traverse list */ - LWIP_DEBUGF(SNMP_MIB_DEBUG,("traverse list\n")); - n = n->next; - } - } - else - { - /* n->objid > objid */ - /* alloc and insert between n->prev and n */ - LWIP_DEBUGF(SNMP_MIB_DEBUG,("alloc ins n->prev, objid==%"S32_F", n\n",objid)); - nn = snmp_mib_ln_alloc(objid); - if (nn != NULL) - { - if (n->prev == NULL) - { - /* insert at the head */ - nn->next = n; - nn->prev = NULL; - rn->head = nn; - n->prev = nn; - } - else - { - /* insert in the middle */ - nn->next = n; - nn->prev = n->prev; - n->prev->next = nn; - n->prev = nn; - } - *insn = nn; - insert = 1; - } - else - { - /* insertion failure */ - insert = -1; - } - } - } - } - if (insert == 1) - { - rn->count += 1; - } - LWIP_ASSERT("insert != 0",insert != 0); - return insert; -} - -/** - * Finds node in idx list and returns deletion mark. - * - * @param rn points to the root node - * @param objid is the object sub identifier - * @param fn returns pointer to found node - * @return 0 if not found, 1 if deletable, - * 2 can't delete (2 or more children), 3 not a list_node - */ -s8_t -snmp_mib_node_find(struct mib_list_rootnode *rn, s32_t objid, struct mib_list_node **fn) -{ - s8_t fc; - struct mib_list_node *n; - - LWIP_ASSERT("rn != NULL",rn != NULL); - n = rn->head; - while ((n != NULL) && (n->objid != objid)) - { - n = n->next; - } - if (n == NULL) - { - fc = 0; - } - else if (n->nptr == NULL) - { - /* leaf, can delete node */ - fc = 1; - } - else - { - struct mib_list_rootnode *r; - - if (n->nptr->node_type == MIB_NODE_LR) - { - r = (struct mib_list_rootnode *)n->nptr; - if (r->count > 1) - { - /* can't delete node */ - fc = 2; - } - else - { - /* count <= 1, can delete node */ - fc = 1; - } - } - else - { - /* other node type */ - fc = 3; - } - } - *fn = n; - return fc; -} - -/** - * Removes node from idx list - * if it has a single child left. - * - * @param rn points to the root node - * @param n points to the node to delete - * @return the nptr to be freed by caller - */ -struct mib_list_rootnode * -snmp_mib_node_delete(struct mib_list_rootnode *rn, struct mib_list_node *n) -{ - struct mib_list_rootnode *next; - - LWIP_ASSERT("rn != NULL",rn != NULL); - LWIP_ASSERT("n != NULL",n != NULL); - - /* caller must remove this sub-tree */ - next = (struct mib_list_rootnode*)(n->nptr); - rn->count -= 1; - - if (n == rn->head) - { - rn->head = n->next; - if (n->next != NULL) - { - /* not last node, new list begin */ - n->next->prev = NULL; - } - } - else if (n == rn->tail) - { - rn->tail = n->prev; - if (n->prev != NULL) - { - /* not last node, new list end */ - n->prev->next = NULL; - } - } - else - { - /* node must be in the middle */ - n->prev->next = n->next; - n->next->prev = n->prev; - } - LWIP_DEBUGF(SNMP_MIB_DEBUG,("free list objid==%"S32_F"\n",n->objid)); - snmp_mib_ln_free(n); - if (rn->count == 0) - { - rn->head = NULL; - rn->tail = NULL; - } - return next; -} - - - -/** - * Searches tree for the supplied (scalar?) object identifier. - * - * @param node points to the root of the tree ('.internet') - * @param ident_len the length of the supplied object identifier - * @param ident points to the array of sub identifiers - * @param np points to the found object instance (return) - * @return pointer to the requested parent (!) node if success, NULL otherwise - */ -struct mib_node * -snmp_search_tree(struct mib_node *node, u8_t ident_len, s32_t *ident, struct snmp_name_ptr *np) -{ - u8_t node_type, ext_level; - - ext_level = 0; - LWIP_DEBUGF(SNMP_MIB_DEBUG,("node==%p *ident==%"S32_F"\n",(void*)node,*ident)); - while (node != NULL) - { - node_type = node->node_type; - if ((node_type == MIB_NODE_AR) || (node_type == MIB_NODE_RA)) - { - struct mib_array_node *an; - u16_t i; - - if (ident_len > 0) - { - /* array node (internal ROM or RAM, fixed length) */ - an = (struct mib_array_node *)node; - i = 0; - while ((i < an->maxlength) && (an->objid[i] != *ident)) - { - i++; - } - if (i < an->maxlength) - { - /* found it, if available proceed to child, otherwise inspect leaf */ - LWIP_DEBUGF(SNMP_MIB_DEBUG,("an->objid[%"U16_F"]==%"S32_F" *ident==%"S32_F"\n",i,an->objid[i],*ident)); - if (an->nptr[i] == NULL) - { - /* a scalar leaf OR table, - inspect remaining instance number / table index */ - np->ident_len = ident_len; - np->ident = ident; - return (struct mib_node*)an; - } - else - { - /* follow next child pointer */ - ident++; - ident_len--; - node = an->nptr[i]; - } - } - else - { - /* search failed, identifier mismatch (nosuchname) */ - LWIP_DEBUGF(SNMP_MIB_DEBUG,("an search failed *ident==%"S32_F"\n",*ident)); - return NULL; - } - } - else - { - /* search failed, short object identifier (nosuchname) */ - LWIP_DEBUGF(SNMP_MIB_DEBUG,("an search failed, short object identifier\n")); - return NULL; - } - } - else if(node_type == MIB_NODE_LR) - { - struct mib_list_rootnode *lrn; - struct mib_list_node *ln; - - if (ident_len > 0) - { - /* list root node (internal 'RAM', variable length) */ - lrn = (struct mib_list_rootnode *)node; - ln = lrn->head; - /* iterate over list, head to tail */ - while ((ln != NULL) && (ln->objid != *ident)) - { - ln = ln->next; - } - if (ln != NULL) - { - /* found it, proceed to child */; - LWIP_DEBUGF(SNMP_MIB_DEBUG,("ln->objid==%"S32_F" *ident==%"S32_F"\n",ln->objid,*ident)); - if (ln->nptr == NULL) - { - np->ident_len = ident_len; - np->ident = ident; - return (struct mib_node*)lrn; - } - else - { - /* follow next child pointer */ - ident_len--; - ident++; - node = ln->nptr; - } - } - else - { - /* search failed */ - LWIP_DEBUGF(SNMP_MIB_DEBUG,("ln search failed *ident==%"S32_F"\n",*ident)); - return NULL; - } - } - else - { - /* search failed, short object identifier (nosuchname) */ - LWIP_DEBUGF(SNMP_MIB_DEBUG,("ln search failed, short object identifier\n")); - return NULL; - } - } - else if(node_type == MIB_NODE_EX) - { - struct mib_external_node *en; - u16_t i, len; - - if (ident_len > 0) - { - /* external node (addressing and access via functions) */ - en = (struct mib_external_node *)node; - - i = 0; - len = en->level_length(en->addr_inf,ext_level); - while ((i < len) && (en->ident_cmp(en->addr_inf,ext_level,i,*ident) != 0)) - { - i++; - } - if (i < len) - { - s32_t debug_id; - - en->get_objid(en->addr_inf,ext_level,i,&debug_id); - LWIP_DEBUGF(SNMP_MIB_DEBUG,("en->objid==%"S32_F" *ident==%"S32_F"\n",debug_id,*ident)); - if ((ext_level + 1) == en->tree_levels) - { - np->ident_len = ident_len; - np->ident = ident; - return (struct mib_node*)en; - } - else - { - /* found it, proceed to child */ - ident_len--; - ident++; - ext_level++; - } - } - else - { - /* search failed */ - LWIP_DEBUGF(SNMP_MIB_DEBUG,("en search failed *ident==%"S32_F"\n",*ident)); - return NULL; - } - } - else - { - /* search failed, short object identifier (nosuchname) */ - LWIP_DEBUGF(SNMP_MIB_DEBUG,("en search failed, short object identifier\n")); - return NULL; - } - } - else if (node_type == MIB_NODE_SC) - { - mib_scalar_node *sn; - - sn = (mib_scalar_node *)node; - if ((ident_len == 1) && (*ident == 0)) - { - np->ident_len = ident_len; - np->ident = ident; - return (struct mib_node*)sn; - } - else - { - /* search failed, short object identifier (nosuchname) */ - LWIP_DEBUGF(SNMP_MIB_DEBUG,("search failed, invalid object identifier length\n")); - return NULL; - } - } - else - { - /* unknown node_type */ - LWIP_DEBUGF(SNMP_MIB_DEBUG,("search failed node_type %"U16_F" unkown\n",(u16_t)node_type)); - return NULL; - } - } - /* done, found nothing */ - LWIP_DEBUGF(SNMP_MIB_DEBUG,("search failed node==%p\n",(void*)node)); - return NULL; -} - -/** - * Test table for presence of at least one table entry. - */ -static u8_t -empty_table(struct mib_node *node) -{ - u8_t node_type; - u8_t empty = 0; - - if (node != NULL) - { - node_type = node->node_type; - if (node_type == MIB_NODE_LR) - { - struct mib_list_rootnode *lrn; - lrn = (struct mib_list_rootnode *)node; - if ((lrn->count == 0) || (lrn->head == NULL)) - { - empty = 1; - } - } - else if ((node_type == MIB_NODE_AR) || (node_type == MIB_NODE_RA)) - { - struct mib_array_node *an; - an = (struct mib_array_node *)node; - if ((an->maxlength == 0) || (an->nptr == NULL)) - { - empty = 1; - } - } - else if (node_type == MIB_NODE_EX) - { - struct mib_external_node *en; - en = (struct mib_external_node *)node; - if (en->tree_levels == 0) - { - empty = 1; - } - } - } - return empty; -} - -/** - * Tree expansion. - */ -struct mib_node * -snmp_expand_tree(struct mib_node *node, u8_t ident_len, s32_t *ident, struct snmp_obj_id *oidret) -{ - u8_t node_type, ext_level, climb_tree; - - ext_level = 0; - /* reset node stack */ - node_stack_cnt = 0; - while (node != NULL) - { - climb_tree = 0; - node_type = node->node_type; - if ((node_type == MIB_NODE_AR) || (node_type == MIB_NODE_RA)) - { - struct mib_array_node *an; - u16_t i; - - /* array node (internal ROM or RAM, fixed length) */ - an = (struct mib_array_node *)node; - if (ident_len > 0) - { - i = 0; - while ((i < an->maxlength) && (an->objid[i] < *ident)) - { - i++; - } - if (i < an->maxlength) - { - LWIP_DEBUGF(SNMP_MIB_DEBUG,("an->objid[%"U16_F"]==%"S32_F" *ident==%"S32_F"\n",i,an->objid[i],*ident)); - /* add identifier to oidret */ - oidret->id[oidret->len] = an->objid[i]; - (oidret->len)++; - - if (an->nptr[i] == NULL) - { - LWIP_DEBUGF(SNMP_MIB_DEBUG,("leaf node\n")); - /* leaf node (e.g. in a fixed size table) */ - if (an->objid[i] > *ident) - { - return (struct mib_node*)an; - } - else if ((i + 1) < an->maxlength) - { - /* an->objid[i] == *ident */ - (oidret->len)--; - oidret->id[oidret->len] = an->objid[i + 1]; - (oidret->len)++; - return (struct mib_node*)an; - } - else - { - /* (i + 1) == an->maxlength */ - (oidret->len)--; - climb_tree = 1; - } - } - else - { - u8_t j; - struct nse cur_node; - - LWIP_DEBUGF(SNMP_MIB_DEBUG,("non-leaf node\n")); - /* non-leaf, store right child ptr and id */ - LWIP_ASSERT("i < 0xff", i < 0xff); - j = (u8_t)i + 1; - while ((j < an->maxlength) && (empty_table(an->nptr[j]))) - { - j++; - } - if (j < an->maxlength) - { - cur_node.r_ptr = an->nptr[j]; - cur_node.r_id = an->objid[j]; - cur_node.r_nl = 0; - } - else - { - cur_node.r_ptr = NULL; - } - push_node(&cur_node); - if (an->objid[i] == *ident) - { - ident_len--; - ident++; - } - else - { - /* an->objid[i] < *ident */ - ident_len = 0; - } - /* follow next child pointer */ - node = an->nptr[i]; - } - } - else - { - /* i == an->maxlength */ - climb_tree = 1; - } - } - else - { - u8_t j; - /* ident_len == 0, complete with leftmost '.thing' */ - j = 0; - while ((j < an->maxlength) && empty_table(an->nptr[j])) - { - j++; - } - if (j < an->maxlength) - { - LWIP_DEBUGF(SNMP_MIB_DEBUG,("left an->objid[j]==%"S32_F"\n",an->objid[j])); - oidret->id[oidret->len] = an->objid[j]; - (oidret->len)++; - if (an->nptr[j] == NULL) - { - /* leaf node */ - return (struct mib_node*)an; - } - else - { - /* no leaf, continue */ - node = an->nptr[j]; - } - } - else - { - /* j == an->maxlength */ - climb_tree = 1; - } - } - } - else if(node_type == MIB_NODE_LR) - { - struct mib_list_rootnode *lrn; - struct mib_list_node *ln; - - /* list root node (internal 'RAM', variable length) */ - lrn = (struct mib_list_rootnode *)node; - if (ident_len > 0) - { - ln = lrn->head; - /* iterate over list, head to tail */ - while ((ln != NULL) && (ln->objid < *ident)) - { - ln = ln->next; - } - if (ln != NULL) - { - LWIP_DEBUGF(SNMP_MIB_DEBUG,("ln->objid==%"S32_F" *ident==%"S32_F"\n",ln->objid,*ident)); - oidret->id[oidret->len] = ln->objid; - (oidret->len)++; - if (ln->nptr == NULL) - { - /* leaf node */ - if (ln->objid > *ident) - { - return (struct mib_node*)lrn; - } - else if (ln->next != NULL) - { - /* ln->objid == *ident */ - (oidret->len)--; - oidret->id[oidret->len] = ln->next->objid; - (oidret->len)++; - return (struct mib_node*)lrn; - } - else - { - /* ln->next == NULL */ - (oidret->len)--; - climb_tree = 1; - } - } - else - { - struct mib_list_node *jn; - struct nse cur_node; - - /* non-leaf, store right child ptr and id */ - jn = ln->next; - while ((jn != NULL) && empty_table(jn->nptr)) - { - jn = jn->next; - } - if (jn != NULL) - { - cur_node.r_ptr = jn->nptr; - cur_node.r_id = jn->objid; - cur_node.r_nl = 0; - } - else - { - cur_node.r_ptr = NULL; - } - push_node(&cur_node); - if (ln->objid == *ident) - { - ident_len--; - ident++; - } - else - { - /* ln->objid < *ident */ - ident_len = 0; - } - /* follow next child pointer */ - node = ln->nptr; - } - - } - else - { - /* ln == NULL */ - climb_tree = 1; - } - } - else - { - struct mib_list_node *jn; - /* ident_len == 0, complete with leftmost '.thing' */ - jn = lrn->head; - while ((jn != NULL) && empty_table(jn->nptr)) - { - jn = jn->next; - } - if (jn != NULL) - { - LWIP_DEBUGF(SNMP_MIB_DEBUG,("left jn->objid==%"S32_F"\n",jn->objid)); - oidret->id[oidret->len] = jn->objid; - (oidret->len)++; - if (jn->nptr == NULL) - { - /* leaf node */ - LWIP_DEBUGF(SNMP_MIB_DEBUG,("jn->nptr == NULL\n")); - return (struct mib_node*)lrn; - } - else - { - /* no leaf, continue */ - node = jn->nptr; - } - } - else - { - /* jn == NULL */ - climb_tree = 1; - } - } - } - else if(node_type == MIB_NODE_EX) - { - struct mib_external_node *en; - s32_t ex_id; - - /* external node (addressing and access via functions) */ - en = (struct mib_external_node *)node; - if (ident_len > 0) - { - u16_t i, len; - - i = 0; - len = en->level_length(en->addr_inf,ext_level); - while ((i < len) && (en->ident_cmp(en->addr_inf,ext_level,i,*ident) < 0)) - { - i++; - } - if (i < len) - { - /* add identifier to oidret */ - en->get_objid(en->addr_inf,ext_level,i,&ex_id); - LWIP_DEBUGF(SNMP_MIB_DEBUG,("en->objid[%"U16_F"]==%"S32_F" *ident==%"S32_F"\n",i,ex_id,*ident)); - oidret->id[oidret->len] = ex_id; - (oidret->len)++; - - if ((ext_level + 1) == en->tree_levels) - { - LWIP_DEBUGF(SNMP_MIB_DEBUG,("leaf node\n")); - /* leaf node */ - if (ex_id > *ident) - { - return (struct mib_node*)en; - } - else if ((i + 1) < len) - { - /* ex_id == *ident */ - en->get_objid(en->addr_inf,ext_level,i + 1,&ex_id); - (oidret->len)--; - oidret->id[oidret->len] = ex_id; - (oidret->len)++; - return (struct mib_node*)en; - } - else - { - /* (i + 1) == len */ - (oidret->len)--; - climb_tree = 1; - } - } - else - { - u8_t j; - struct nse cur_node; - - LWIP_DEBUGF(SNMP_MIB_DEBUG,("non-leaf node\n")); - /* non-leaf, store right child ptr and id */ - LWIP_ASSERT("i < 0xff", i < 0xff); - j = (u8_t)i + 1; - if (j < len) - { - /* right node is the current external node */ - cur_node.r_ptr = node; - en->get_objid(en->addr_inf,ext_level,j,&cur_node.r_id); - cur_node.r_nl = ext_level + 1; - } - else - { - cur_node.r_ptr = NULL; - } - push_node(&cur_node); - if (en->ident_cmp(en->addr_inf,ext_level,i,*ident) == 0) - { - ident_len--; - ident++; - } - else - { - /* external id < *ident */ - ident_len = 0; - } - /* proceed to child */ - ext_level++; - } - } - else - { - /* i == len (en->level_len()) */ - climb_tree = 1; - } - } - else - { - /* ident_len == 0, complete with leftmost '.thing' */ - en->get_objid(en->addr_inf,ext_level,0,&ex_id); - LWIP_DEBUGF(SNMP_MIB_DEBUG,("left en->objid==%"S32_F"\n",ex_id)); - oidret->id[oidret->len] = ex_id; - (oidret->len)++; - if ((ext_level + 1) == en->tree_levels) - { - /* leaf node */ - LWIP_DEBUGF(SNMP_MIB_DEBUG,("(ext_level + 1) == en->tree_levels\n")); - return (struct mib_node*)en; - } - else - { - /* no leaf, proceed to child */ - ext_level++; - } - } - } - else if(node_type == MIB_NODE_SC) - { - mib_scalar_node *sn; - - /* scalar node */ - sn = (mib_scalar_node *)node; - if (ident_len > 0) - { - /* at .0 */ - climb_tree = 1; - } - else - { - /* ident_len == 0, complete object identifier */ - oidret->id[oidret->len] = 0; - (oidret->len)++; - /* leaf node */ - LWIP_DEBUGF(SNMP_MIB_DEBUG,("completed scalar leaf\n")); - return (struct mib_node*)sn; - } - } - else - { - /* unknown/unhandled node_type */ - LWIP_DEBUGF(SNMP_MIB_DEBUG,("expand failed node_type %"U16_F" unkown\n",(u16_t)node_type)); - return NULL; - } - - if (climb_tree) - { - struct nse child; - - /* find right child ptr */ - child.r_ptr = NULL; - child.r_id = 0; - child.r_nl = 0; - while ((node_stack_cnt > 0) && (child.r_ptr == NULL)) - { - pop_node(&child); - /* trim returned oid */ - (oidret->len)--; - } - if (child.r_ptr != NULL) - { - /* incoming ident is useless beyond this point */ - ident_len = 0; - oidret->id[oidret->len] = child.r_id; - oidret->len++; - node = child.r_ptr; - ext_level = child.r_nl; - } - else - { - /* tree ends here ... */ - LWIP_DEBUGF(SNMP_MIB_DEBUG,("expand failed, tree ends here\n")); - return NULL; - } - } - } - /* done, found nothing */ - LWIP_DEBUGF(SNMP_MIB_DEBUG,("expand failed node==%p\n",(void*)node)); - return NULL; -} - -/** - * Test object identifier for the iso.org.dod.internet prefix. - * - * @param ident_len the length of the supplied object identifier - * @param ident points to the array of sub identifiers - * @return 1 if it matches, 0 otherwise - */ -u8_t -snmp_iso_prefix_tst(u8_t ident_len, s32_t *ident) -{ - if ((ident_len > 3) && - (ident[0] == 1) && (ident[1] == 3) && - (ident[2] == 6) && (ident[3] == 1)) - { - return 1; - } - else - { - return 0; - } -} - -/** - * Expands object identifier to the iso.org.dod.internet - * prefix for use in getnext operation. - * - * @param ident_len the length of the supplied object identifier - * @param ident points to the array of sub identifiers - * @param oidret points to returned expanded object identifier - * @return 1 if it matches, 0 otherwise - * - * @note ident_len 0 is allowed, expanding to the first known object id!! - */ -u8_t -snmp_iso_prefix_expand(u8_t ident_len, s32_t *ident, struct snmp_obj_id *oidret) -{ - const s32_t *prefix_ptr; - s32_t *ret_ptr; - u8_t i; - - i = 0; - prefix_ptr = &prefix[0]; - ret_ptr = &oidret->id[0]; - ident_len = ((ident_len < 4)?ident_len:4); - while ((i < ident_len) && ((*ident) <= (*prefix_ptr))) - { - *ret_ptr++ = *prefix_ptr++; - ident++; - i++; - } - if (i == ident_len) - { - /* match, complete missing bits */ - while (i < 4) - { - *ret_ptr++ = *prefix_ptr++; - i++; - } - oidret->len = i; - return 1; - } - else - { - /* i != ident_len */ - return 0; - } -} - -#endif /* LWIP_SNMP */ diff --git a/features/net/FEATURE_IPV4/lwip-interface/lwip/core/snmp/lwip_msg_in.c b/features/net/FEATURE_IPV4/lwip-interface/lwip/core/snmp/lwip_msg_in.c deleted file mode 100644 index 2dfb55b253..0000000000 --- a/features/net/FEATURE_IPV4/lwip-interface/lwip/core/snmp/lwip_msg_in.c +++ /dev/null @@ -1,1437 +0,0 @@ -/** - * @file - * SNMP input message processing (RFC1157). - */ - -/* - * 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 - */ - -#include "lwip/opt.h" - -#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/snmp.h" -#include "lwip/snmp_asn1.h" -#include "lwip/snmp_msg.h" -#include "lwip/snmp_structs.h" -#include "lwip/ip_addr.h" -#include "lwip/memp.h" -#include "lwip/udp.h" -#include "lwip/stats.h" - -#include - -/* public (non-static) constants */ -/** SNMP v1 == 0 */ -const s32_t snmp_version = 0; -/** default SNMP community string */ -const char snmp_publiccommunity[7] = "public"; - -/* statically allocated buffers for SNMP_CONCURRENT_REQUESTS */ -struct snmp_msg_pstat msg_input_list[SNMP_CONCURRENT_REQUESTS]; -/* UDP Protocol Control Block */ -struct udp_pcb *snmp1_pcb; - -static void snmp_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, ip_addr_t *addr, u16_t port); -static err_t snmp_pdu_header_check(struct pbuf *p, u16_t ofs, u16_t pdu_len, u16_t *ofs_ret, struct snmp_msg_pstat *m_stat); -static err_t snmp_pdu_dec_varbindlist(struct pbuf *p, u16_t ofs, u16_t *ofs_ret, struct snmp_msg_pstat *m_stat); - - -/** - * Starts SNMP Agent. - * Allocates UDP pcb and binds it to IP_ADDR_ANY port 161. - */ -void -snmp_init(void) -{ - struct snmp_msg_pstat *msg_ps; - u8_t i; - - snmp1_pcb = udp_new(); - if (snmp1_pcb != NULL) - { - udp_recv(snmp1_pcb, snmp_recv, (void *)SNMP_IN_PORT); - udp_bind(snmp1_pcb, IP_ADDR_ANY, SNMP_IN_PORT); - } - msg_ps = &msg_input_list[0]; - for (i=0; istate = SNMP_MSG_EMPTY; - msg_ps->error_index = 0; - msg_ps->error_status = SNMP_ES_NOERROR; - msg_ps++; - } - trap_msg.pcb = snmp1_pcb; - -#ifdef SNMP_PRIVATE_MIB_INIT - /* If defined, rhis must be a function-like define to initialize the - * private MIB after the stack has been initialized. - * The private MIB can also be initialized in tcpip_callback (or after - * the stack is initialized), this define is only for convenience. */ - SNMP_PRIVATE_MIB_INIT(); -#endif /* SNMP_PRIVATE_MIB_INIT */ - - /* The coldstart trap will only be output - if our outgoing interface is up & configured */ - snmp_coldstart_trap(); -} - -static void -snmp_error_response(struct snmp_msg_pstat *msg_ps, u8_t error) -{ - snmp_varbind_list_free(&msg_ps->outvb); - msg_ps->outvb = msg_ps->invb; - msg_ps->invb.head = NULL; - msg_ps->invb.tail = NULL; - msg_ps->invb.count = 0; - msg_ps->error_status = error; - msg_ps->error_index = 1 + msg_ps->vb_idx; - snmp_send_response(msg_ps); - snmp_varbind_list_free(&msg_ps->outvb); - msg_ps->state = SNMP_MSG_EMPTY; -} - -static void -snmp_ok_response(struct snmp_msg_pstat *msg_ps) -{ - err_t err_ret; - - err_ret = snmp_send_response(msg_ps); - if (err_ret == ERR_MEM) - { - /* serious memory problem, can't return tooBig */ - } - else - { - LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_msg_event = %"S32_F"\n",msg_ps->error_status)); - } - /* free varbinds (if available) */ - snmp_varbind_list_free(&msg_ps->invb); - snmp_varbind_list_free(&msg_ps->outvb); - msg_ps->state = SNMP_MSG_EMPTY; -} - -/** - * Service an internal or external event for SNMP GET. - * - * @param request_id identifies requests from 0 to (SNMP_CONCURRENT_REQUESTS-1) - * @param msg_ps points to the assosicated message process state - */ -static void -snmp_msg_get_event(u8_t request_id, struct snmp_msg_pstat *msg_ps) -{ - LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_msg_get_event: msg_ps->state==%"U16_F"\n",(u16_t)msg_ps->state)); - - if (msg_ps->state == SNMP_MSG_EXTERNAL_GET_OBJDEF) - { - struct mib_external_node *en; - struct snmp_name_ptr np; - - /* get_object_def() answer*/ - en = msg_ps->ext_mib_node; - np = msg_ps->ext_name_ptr; - - /* translate answer into a known lifeform */ - en->get_object_def_a(request_id, np.ident_len, np.ident, &msg_ps->ext_object_def); - if ((msg_ps->ext_object_def.instance != MIB_OBJECT_NONE) && - (msg_ps->ext_object_def.access & MIB_ACCESS_READ)) - { - msg_ps->state = SNMP_MSG_EXTERNAL_GET_VALUE; - en->get_value_q(request_id, &msg_ps->ext_object_def); - } - else - { - en->get_object_def_pc(request_id, np.ident_len, np.ident); - /* search failed, object id points to unknown object (nosuchname) */ - snmp_error_response(msg_ps,SNMP_ES_NOSUCHNAME); - } - } - else if (msg_ps->state == SNMP_MSG_EXTERNAL_GET_VALUE) - { - struct mib_external_node *en; - struct snmp_varbind *vb; - - /* get_value() answer */ - en = msg_ps->ext_mib_node; - - /* allocate output varbind */ - vb = (struct snmp_varbind *)memp_malloc(MEMP_SNMP_VARBIND); - LWIP_ASSERT("vb != NULL",vb != NULL); - if (vb != NULL) - { - vb->next = NULL; - vb->prev = NULL; - - /* move name from invb to outvb */ - vb->ident = msg_ps->vb_ptr->ident; - vb->ident_len = msg_ps->vb_ptr->ident_len; - /* ensure this memory is refereced once only */ - msg_ps->vb_ptr->ident = NULL; - msg_ps->vb_ptr->ident_len = 0; - - vb->value_type = msg_ps->ext_object_def.asn_type; - LWIP_ASSERT("invalid length", msg_ps->ext_object_def.v_len <= 0xff); - vb->value_len = (u8_t)msg_ps->ext_object_def.v_len; - if (vb->value_len > 0) - { - LWIP_ASSERT("SNMP_MAX_OCTET_STRING_LEN is configured too low", vb->value_len <= SNMP_MAX_VALUE_SIZE); - vb->value = memp_malloc(MEMP_SNMP_VALUE); - LWIP_ASSERT("vb->value != NULL",vb->value != NULL); - if (vb->value != NULL) - { - en->get_value_a(request_id, &msg_ps->ext_object_def, vb->value_len, vb->value); - snmp_varbind_tail_add(&msg_ps->outvb, vb); - /* search again (if vb_idx < msg_ps->invb.count) */ - msg_ps->state = SNMP_MSG_SEARCH_OBJ; - msg_ps->vb_idx += 1; - } - else - { - en->get_value_pc(request_id, &msg_ps->ext_object_def); - LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_msg_event: no variable space\n")); - msg_ps->vb_ptr->ident = vb->ident; - msg_ps->vb_ptr->ident_len = vb->ident_len; - memp_free(MEMP_SNMP_VARBIND, vb); - snmp_error_response(msg_ps,SNMP_ES_TOOBIG); - } - } - else - { - /* vb->value_len == 0, empty value (e.g. empty string) */ - en->get_value_a(request_id, &msg_ps->ext_object_def, 0, NULL); - vb->value = NULL; - snmp_varbind_tail_add(&msg_ps->outvb, vb); - /* search again (if vb_idx < msg_ps->invb.count) */ - msg_ps->state = SNMP_MSG_SEARCH_OBJ; - msg_ps->vb_idx += 1; - } - } - else - { - en->get_value_pc(request_id, &msg_ps->ext_object_def); - LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_msg_event: no outvb space\n")); - snmp_error_response(msg_ps,SNMP_ES_TOOBIG); - } - } - - while ((msg_ps->state == SNMP_MSG_SEARCH_OBJ) && - (msg_ps->vb_idx < msg_ps->invb.count)) - { - struct mib_node *mn; - struct snmp_name_ptr np; - - if (msg_ps->vb_idx == 0) - { - msg_ps->vb_ptr = msg_ps->invb.head; - } - else - { - msg_ps->vb_ptr = msg_ps->vb_ptr->next; - } - /** test object identifier for .iso.org.dod.internet prefix */ - if (snmp_iso_prefix_tst(msg_ps->vb_ptr->ident_len, msg_ps->vb_ptr->ident)) - { - mn = snmp_search_tree((struct mib_node*)&internet, msg_ps->vb_ptr->ident_len - 4, - msg_ps->vb_ptr->ident + 4, &np); - if (mn != NULL) - { - if (mn->node_type == MIB_NODE_EX) - { - /* external object */ - struct mib_external_node *en = (struct mib_external_node*)mn; - - msg_ps->state = SNMP_MSG_EXTERNAL_GET_OBJDEF; - /* save en && args in msg_ps!! */ - msg_ps->ext_mib_node = en; - msg_ps->ext_name_ptr = np; - - en->get_object_def_q(en->addr_inf, request_id, np.ident_len, np.ident); - } - else - { - /* internal object */ - struct obj_def object_def; - - msg_ps->state = SNMP_MSG_INTERNAL_GET_OBJDEF; - mn->get_object_def(np.ident_len, np.ident, &object_def); - if ((object_def.instance != MIB_OBJECT_NONE) && - (object_def.access & MIB_ACCESS_READ)) - { - mn = mn; - } - else - { - /* search failed, object id points to unknown object (nosuchname) */ - mn = NULL; - } - if (mn != NULL) - { - struct snmp_varbind *vb; - - msg_ps->state = SNMP_MSG_INTERNAL_GET_VALUE; - /* allocate output varbind */ - vb = (struct snmp_varbind *)memp_malloc(MEMP_SNMP_VARBIND); - LWIP_ASSERT("vb != NULL",vb != NULL); - if (vb != NULL) - { - vb->next = NULL; - vb->prev = NULL; - - /* move name from invb to outvb */ - vb->ident = msg_ps->vb_ptr->ident; - vb->ident_len = msg_ps->vb_ptr->ident_len; - /* ensure this memory is refereced once only */ - msg_ps->vb_ptr->ident = NULL; - msg_ps->vb_ptr->ident_len = 0; - - vb->value_type = object_def.asn_type; - LWIP_ASSERT("invalid length", object_def.v_len <= 0xff); - vb->value_len = (u8_t)object_def.v_len; - if (vb->value_len > 0) - { - LWIP_ASSERT("SNMP_MAX_OCTET_STRING_LEN is configured too low", - vb->value_len <= SNMP_MAX_VALUE_SIZE); - vb->value = memp_malloc(MEMP_SNMP_VALUE); - LWIP_ASSERT("vb->value != NULL",vb->value != NULL); - if (vb->value != NULL) - { - mn->get_value(&object_def, vb->value_len, vb->value); - snmp_varbind_tail_add(&msg_ps->outvb, vb); - msg_ps->state = SNMP_MSG_SEARCH_OBJ; - msg_ps->vb_idx += 1; - } - else - { - LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_msg_event: couldn't allocate variable space\n")); - msg_ps->vb_ptr->ident = vb->ident; - msg_ps->vb_ptr->ident_len = vb->ident_len; - memp_free(MEMP_SNMP_VARBIND, vb); - snmp_error_response(msg_ps,SNMP_ES_TOOBIG); - } - } - else - { - /* vb->value_len == 0, empty value (e.g. empty string) */ - vb->value = NULL; - snmp_varbind_tail_add(&msg_ps->outvb, vb); - msg_ps->state = SNMP_MSG_SEARCH_OBJ; - msg_ps->vb_idx += 1; - } - } - else - { - LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_msg_event: couldn't allocate outvb space\n")); - snmp_error_response(msg_ps,SNMP_ES_TOOBIG); - } - } - } - } - } - else - { - mn = NULL; - } - if (mn == NULL) - { - /* mn == NULL, noSuchName */ - snmp_error_response(msg_ps,SNMP_ES_NOSUCHNAME); - } - } - if ((msg_ps->state == SNMP_MSG_SEARCH_OBJ) && - (msg_ps->vb_idx == msg_ps->invb.count)) - { - snmp_ok_response(msg_ps); - } -} - -/** - * Service an internal or external event for SNMP GETNEXT. - * - * @param request_id identifies requests from 0 to (SNMP_CONCURRENT_REQUESTS-1) - * @param msg_ps points to the assosicated message process state - */ -static void -snmp_msg_getnext_event(u8_t request_id, struct snmp_msg_pstat *msg_ps) -{ - LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_msg_getnext_event: msg_ps->state==%"U16_F"\n",(u16_t)msg_ps->state)); - - if (msg_ps->state == SNMP_MSG_EXTERNAL_GET_OBJDEF) - { - struct mib_external_node *en; - - /* get_object_def() answer*/ - en = msg_ps->ext_mib_node; - - /* translate answer into a known lifeform */ - en->get_object_def_a(request_id, 1, &msg_ps->ext_oid.id[msg_ps->ext_oid.len - 1], &msg_ps->ext_object_def); - if (msg_ps->ext_object_def.instance != MIB_OBJECT_NONE) - { - msg_ps->state = SNMP_MSG_EXTERNAL_GET_VALUE; - en->get_value_q(request_id, &msg_ps->ext_object_def); - } - else - { - en->get_object_def_pc(request_id, 1, &msg_ps->ext_oid.id[msg_ps->ext_oid.len - 1]); - /* search failed, object id points to unknown object (nosuchname) */ - snmp_error_response(msg_ps,SNMP_ES_NOSUCHNAME); - } - } - else if (msg_ps->state == SNMP_MSG_EXTERNAL_GET_VALUE) - { - struct mib_external_node *en; - struct snmp_varbind *vb; - - /* get_value() answer */ - en = msg_ps->ext_mib_node; - - LWIP_ASSERT("invalid length", msg_ps->ext_object_def.v_len <= 0xff); - vb = snmp_varbind_alloc(&msg_ps->ext_oid, - msg_ps->ext_object_def.asn_type, - (u8_t)msg_ps->ext_object_def.v_len); - if (vb != NULL) - { - en->get_value_a(request_id, &msg_ps->ext_object_def, vb->value_len, vb->value); - snmp_varbind_tail_add(&msg_ps->outvb, vb); - msg_ps->state = SNMP_MSG_SEARCH_OBJ; - msg_ps->vb_idx += 1; - } - else - { - en->get_value_pc(request_id, &msg_ps->ext_object_def); - LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_msg_getnext_event: couldn't allocate outvb space\n")); - snmp_error_response(msg_ps,SNMP_ES_TOOBIG); - } - } - - while ((msg_ps->state == SNMP_MSG_SEARCH_OBJ) && - (msg_ps->vb_idx < msg_ps->invb.count)) - { - struct mib_node *mn; - struct snmp_obj_id oid; - - if (msg_ps->vb_idx == 0) - { - msg_ps->vb_ptr = msg_ps->invb.head; - } - else - { - msg_ps->vb_ptr = msg_ps->vb_ptr->next; - } - if (snmp_iso_prefix_expand(msg_ps->vb_ptr->ident_len, msg_ps->vb_ptr->ident, &oid)) - { - if (msg_ps->vb_ptr->ident_len > 3) - { - /* can offset ident_len and ident */ - mn = snmp_expand_tree((struct mib_node*)&internet, - msg_ps->vb_ptr->ident_len - 4, - msg_ps->vb_ptr->ident + 4, &oid); - } - else - { - /* can't offset ident_len -4, ident + 4 */ - mn = snmp_expand_tree((struct mib_node*)&internet, 0, NULL, &oid); - } - } - else - { - mn = NULL; - } - if (mn != NULL) - { - if (mn->node_type == MIB_NODE_EX) - { - /* external object */ - struct mib_external_node *en = (struct mib_external_node*)mn; - - msg_ps->state = SNMP_MSG_EXTERNAL_GET_OBJDEF; - /* save en && args in msg_ps!! */ - msg_ps->ext_mib_node = en; - msg_ps->ext_oid = oid; - - en->get_object_def_q(en->addr_inf, request_id, 1, &oid.id[oid.len - 1]); - } - else - { - /* internal object */ - struct obj_def object_def; - struct snmp_varbind *vb; - - msg_ps->state = SNMP_MSG_INTERNAL_GET_OBJDEF; - mn->get_object_def(1, &oid.id[oid.len - 1], &object_def); - - LWIP_ASSERT("invalid length", object_def.v_len <= 0xff); - vb = snmp_varbind_alloc(&oid, object_def.asn_type, (u8_t)object_def.v_len); - if (vb != NULL) - { - msg_ps->state = SNMP_MSG_INTERNAL_GET_VALUE; - mn->get_value(&object_def, object_def.v_len, vb->value); - snmp_varbind_tail_add(&msg_ps->outvb, vb); - msg_ps->state = SNMP_MSG_SEARCH_OBJ; - msg_ps->vb_idx += 1; - } - else - { - LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_recv couldn't allocate outvb space\n")); - snmp_error_response(msg_ps,SNMP_ES_TOOBIG); - } - } - } - if (mn == NULL) - { - /* mn == NULL, noSuchName */ - snmp_error_response(msg_ps,SNMP_ES_NOSUCHNAME); - } - } - if ((msg_ps->state == SNMP_MSG_SEARCH_OBJ) && - (msg_ps->vb_idx == msg_ps->invb.count)) - { - snmp_ok_response(msg_ps); - } -} - -/** - * Service an internal or external event for SNMP SET. - * - * @param request_id identifies requests from 0 to (SNMP_CONCURRENT_REQUESTS-1) - * @param msg_ps points to the assosicated message process state - */ -static void -snmp_msg_set_event(u8_t request_id, struct snmp_msg_pstat *msg_ps) -{ - LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_msg_set_event: msg_ps->state==%"U16_F"\n",(u16_t)msg_ps->state)); - - if (msg_ps->state == SNMP_MSG_EXTERNAL_GET_OBJDEF) - { - struct mib_external_node *en; - struct snmp_name_ptr np; - - /* get_object_def() answer*/ - en = msg_ps->ext_mib_node; - np = msg_ps->ext_name_ptr; - - /* translate answer into a known lifeform */ - en->get_object_def_a(request_id, np.ident_len, np.ident, &msg_ps->ext_object_def); - if (msg_ps->ext_object_def.instance != MIB_OBJECT_NONE) - { - msg_ps->state = SNMP_MSG_EXTERNAL_SET_TEST; - en->set_test_q(request_id, &msg_ps->ext_object_def); - } - else - { - en->get_object_def_pc(request_id, np.ident_len, np.ident); - /* search failed, object id points to unknown object (nosuchname) */ - snmp_error_response(msg_ps,SNMP_ES_NOSUCHNAME); - } - } - else if (msg_ps->state == SNMP_MSG_EXTERNAL_SET_TEST) - { - struct mib_external_node *en; - - /* set_test() answer*/ - en = msg_ps->ext_mib_node; - - if (msg_ps->ext_object_def.access & MIB_ACCESS_WRITE) - { - if ((msg_ps->ext_object_def.asn_type == msg_ps->vb_ptr->value_type) && - (en->set_test_a(request_id,&msg_ps->ext_object_def, - msg_ps->vb_ptr->value_len,msg_ps->vb_ptr->value) != 0)) - { - msg_ps->state = SNMP_MSG_SEARCH_OBJ; - msg_ps->vb_idx += 1; - } - else - { - en->set_test_pc(request_id,&msg_ps->ext_object_def); - /* bad value */ - snmp_error_response(msg_ps,SNMP_ES_BADVALUE); - } - } - else - { - en->set_test_pc(request_id,&msg_ps->ext_object_def); - /* object not available for set */ - snmp_error_response(msg_ps,SNMP_ES_NOSUCHNAME); - } - } - else if (msg_ps->state == SNMP_MSG_EXTERNAL_GET_OBJDEF_S) - { - struct mib_external_node *en; - struct snmp_name_ptr np; - - /* get_object_def() answer*/ - en = msg_ps->ext_mib_node; - np = msg_ps->ext_name_ptr; - - /* translate answer into a known lifeform */ - en->get_object_def_a(request_id, np.ident_len, np.ident, &msg_ps->ext_object_def); - if (msg_ps->ext_object_def.instance != MIB_OBJECT_NONE) - { - msg_ps->state = SNMP_MSG_EXTERNAL_SET_VALUE; - en->set_value_q(request_id, &msg_ps->ext_object_def, - msg_ps->vb_ptr->value_len,msg_ps->vb_ptr->value); - } - else - { - en->get_object_def_pc(request_id, np.ident_len, np.ident); - /* set_value failed, object has disappeared for some odd reason?? */ - snmp_error_response(msg_ps,SNMP_ES_GENERROR); - } - } - else if (msg_ps->state == SNMP_MSG_EXTERNAL_SET_VALUE) - { - struct mib_external_node *en; - - /** set_value_a() */ - en = msg_ps->ext_mib_node; - en->set_value_a(request_id, &msg_ps->ext_object_def, - msg_ps->vb_ptr->value_len, msg_ps->vb_ptr->value); - - /** @todo use set_value_pc() if toobig */ - msg_ps->state = SNMP_MSG_INTERNAL_SET_VALUE; - msg_ps->vb_idx += 1; - } - - /* test all values before setting */ - while ((msg_ps->state == SNMP_MSG_SEARCH_OBJ) && - (msg_ps->vb_idx < msg_ps->invb.count)) - { - struct mib_node *mn; - struct snmp_name_ptr np; - - if (msg_ps->vb_idx == 0) - { - msg_ps->vb_ptr = msg_ps->invb.head; - } - else - { - msg_ps->vb_ptr = msg_ps->vb_ptr->next; - } - /** test object identifier for .iso.org.dod.internet prefix */ - if (snmp_iso_prefix_tst(msg_ps->vb_ptr->ident_len, msg_ps->vb_ptr->ident)) - { - mn = snmp_search_tree((struct mib_node*)&internet, msg_ps->vb_ptr->ident_len - 4, - msg_ps->vb_ptr->ident + 4, &np); - if (mn != NULL) - { - if (mn->node_type == MIB_NODE_EX) - { - /* external object */ - struct mib_external_node *en = (struct mib_external_node*)mn; - - msg_ps->state = SNMP_MSG_EXTERNAL_GET_OBJDEF; - /* save en && args in msg_ps!! */ - msg_ps->ext_mib_node = en; - msg_ps->ext_name_ptr = np; - - en->get_object_def_q(en->addr_inf, request_id, np.ident_len, np.ident); - } - else - { - /* internal object */ - struct obj_def object_def; - - msg_ps->state = SNMP_MSG_INTERNAL_GET_OBJDEF; - mn->get_object_def(np.ident_len, np.ident, &object_def); - if (object_def.instance != MIB_OBJECT_NONE) - { - mn = mn; - } - else - { - /* search failed, object id points to unknown object (nosuchname) */ - mn = NULL; - } - if (mn != NULL) - { - msg_ps->state = SNMP_MSG_INTERNAL_SET_TEST; - - if (object_def.access & MIB_ACCESS_WRITE) - { - if ((object_def.asn_type == msg_ps->vb_ptr->value_type) && - (mn->set_test(&object_def,msg_ps->vb_ptr->value_len,msg_ps->vb_ptr->value) != 0)) - { - msg_ps->state = SNMP_MSG_SEARCH_OBJ; - msg_ps->vb_idx += 1; - } - else - { - /* bad value */ - snmp_error_response(msg_ps,SNMP_ES_BADVALUE); - } - } - else - { - /* object not available for set */ - snmp_error_response(msg_ps,SNMP_ES_NOSUCHNAME); - } - } - } - } - } - else - { - mn = NULL; - } - if (mn == NULL) - { - /* mn == NULL, noSuchName */ - snmp_error_response(msg_ps,SNMP_ES_NOSUCHNAME); - } - } - - if ((msg_ps->state == SNMP_MSG_SEARCH_OBJ) && - (msg_ps->vb_idx == msg_ps->invb.count)) - { - msg_ps->vb_idx = 0; - msg_ps->state = SNMP_MSG_INTERNAL_SET_VALUE; - } - - /* set all values "atomically" (be as "atomic" as possible) */ - while ((msg_ps->state == SNMP_MSG_INTERNAL_SET_VALUE) && - (msg_ps->vb_idx < msg_ps->invb.count)) - { - struct mib_node *mn; - struct snmp_name_ptr np; - - if (msg_ps->vb_idx == 0) - { - msg_ps->vb_ptr = msg_ps->invb.head; - } - else - { - msg_ps->vb_ptr = msg_ps->vb_ptr->next; - } - /* skip iso prefix test, was done previously while settesting() */ - mn = snmp_search_tree((struct mib_node*)&internet, msg_ps->vb_ptr->ident_len - 4, - msg_ps->vb_ptr->ident + 4, &np); - /* check if object is still available - (e.g. external hot-plug thingy present?) */ - if (mn != NULL) - { - if (mn->node_type == MIB_NODE_EX) - { - /* external object */ - struct mib_external_node *en = (struct mib_external_node*)mn; - - msg_ps->state = SNMP_MSG_EXTERNAL_GET_OBJDEF_S; - /* save en && args in msg_ps!! */ - msg_ps->ext_mib_node = en; - msg_ps->ext_name_ptr = np; - - en->get_object_def_q(en->addr_inf, request_id, np.ident_len, np.ident); - } - else - { - /* internal object */ - struct obj_def object_def; - - msg_ps->state = SNMP_MSG_INTERNAL_GET_OBJDEF_S; - mn->get_object_def(np.ident_len, np.ident, &object_def); - msg_ps->state = SNMP_MSG_INTERNAL_SET_VALUE; - mn->set_value(&object_def,msg_ps->vb_ptr->value_len,msg_ps->vb_ptr->value); - msg_ps->vb_idx += 1; - } - } - } - if ((msg_ps->state == SNMP_MSG_INTERNAL_SET_VALUE) && - (msg_ps->vb_idx == msg_ps->invb.count)) - { - /* simply echo the input if we can set it - @todo do we need to return the actual value? - e.g. if value is silently modified or behaves sticky? */ - msg_ps->outvb = msg_ps->invb; - msg_ps->invb.head = NULL; - msg_ps->invb.tail = NULL; - msg_ps->invb.count = 0; - snmp_ok_response(msg_ps); - } -} - - -/** - * Handle one internal or external event. - * Called for one async event. (recv external/private answer) - * - * @param request_id identifies requests from 0 to (SNMP_CONCURRENT_REQUESTS-1) - */ -void -snmp_msg_event(u8_t request_id) -{ - struct snmp_msg_pstat *msg_ps; - - if (request_id < SNMP_CONCURRENT_REQUESTS) - { - msg_ps = &msg_input_list[request_id]; - if (msg_ps->rt == SNMP_ASN1_PDU_GET_NEXT_REQ) - { - snmp_msg_getnext_event(request_id, msg_ps); - } - else if (msg_ps->rt == SNMP_ASN1_PDU_GET_REQ) - { - snmp_msg_get_event(request_id, msg_ps); - } - else if(msg_ps->rt == SNMP_ASN1_PDU_SET_REQ) - { - snmp_msg_set_event(request_id, msg_ps); - } - } -} - - -/* lwIP UDP receive callback function */ -static void -snmp_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, ip_addr_t *addr, u16_t port) -{ - struct snmp_msg_pstat *msg_ps; - u8_t req_idx; - err_t err_ret; - u16_t payload_len = p->tot_len; - u16_t payload_ofs = 0; - u16_t varbind_ofs = 0; - - /* suppress unused argument warning */ - LWIP_UNUSED_ARG(arg); - - /* traverse input message process list, look for SNMP_MSG_EMPTY */ - msg_ps = &msg_input_list[0]; - req_idx = 0; - while ((req_idx < SNMP_CONCURRENT_REQUESTS) && (msg_ps->state != SNMP_MSG_EMPTY)) - { - req_idx++; - msg_ps++; - } - if (req_idx == SNMP_CONCURRENT_REQUESTS) - { - /* exceeding number of concurrent requests */ - pbuf_free(p); - return; - } - - /* accepting request */ - snmp_inc_snmpinpkts(); - /* record used 'protocol control block' */ - msg_ps->pcb = pcb; - /* source address (network order) */ - msg_ps->sip = *addr; - /* source port (host order (lwIP oddity)) */ - msg_ps->sp = port; - - /* check total length, version, community, pdu type */ - err_ret = snmp_pdu_header_check(p, payload_ofs, payload_len, &varbind_ofs, msg_ps); - /* Only accept requests and requests without error (be robust) */ - /* Reject response and trap headers or error requests as input! */ - if ((err_ret != ERR_OK) || - ((msg_ps->rt != SNMP_ASN1_PDU_GET_REQ) && - (msg_ps->rt != SNMP_ASN1_PDU_GET_NEXT_REQ) && - (msg_ps->rt != SNMP_ASN1_PDU_SET_REQ)) || - ((msg_ps->error_status != SNMP_ES_NOERROR) || - (msg_ps->error_index != 0)) ) - { - /* header check failed drop request silently, do not return error! */ - pbuf_free(p); - LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_pdu_header_check() failed\n")); - return; - } - LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_recv ok, community %s\n", msg_ps->community)); - - /* Builds a list of variable bindings. Copy the varbinds from the pbuf - chain to glue them when these are divided over two or more pbuf's. */ - err_ret = snmp_pdu_dec_varbindlist(p, varbind_ofs, &varbind_ofs, msg_ps); - /* we've decoded the incoming message, release input msg now */ - pbuf_free(p); - if ((err_ret != ERR_OK) || (msg_ps->invb.count == 0)) - { - /* varbind-list decode failed, or varbind list empty. - drop request silently, do not return error! - (errors are only returned for a specific varbind failure) */ - LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_pdu_dec_varbindlist() failed\n")); - return; - } - - msg_ps->error_status = SNMP_ES_NOERROR; - msg_ps->error_index = 0; - /* find object for each variable binding */ - msg_ps->state = SNMP_MSG_SEARCH_OBJ; - /* first variable binding from list to inspect */ - msg_ps->vb_idx = 0; - - LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_recv varbind cnt=%"U16_F"\n",(u16_t)msg_ps->invb.count)); - - /* handle input event and as much objects as possible in one go */ - snmp_msg_event(req_idx); -} - -/** - * Checks and decodes incoming SNMP message header, logs header errors. - * - * @param p points to pbuf chain of SNMP message (UDP payload) - * @param ofs points to first octet of SNMP message - * @param pdu_len the length of the UDP payload - * @param ofs_ret returns the ofset of the variable bindings - * @param m_stat points to the current message request state return - * @return - * - ERR_OK SNMP header is sane and accepted - * - ERR_ARG SNMP header is either malformed or rejected - */ -static err_t -snmp_pdu_header_check(struct pbuf *p, u16_t ofs, u16_t pdu_len, u16_t *ofs_ret, struct snmp_msg_pstat *m_stat) -{ - err_t derr; - u16_t len, ofs_base; - u8_t len_octets; - u8_t type; - s32_t version; - - ofs_base = ofs; - snmp_asn1_dec_type(p, ofs, &type); - derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &len); - if ((derr != ERR_OK) || - (pdu_len != (1 + len_octets + len)) || - (type != (SNMP_ASN1_UNIV | SNMP_ASN1_CONSTR | SNMP_ASN1_SEQ))) - { - snmp_inc_snmpinasnparseerrs(); - return ERR_ARG; - } - ofs += (1 + len_octets); - snmp_asn1_dec_type(p, ofs, &type); - derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &len); - if ((derr != ERR_OK) || (type != (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG))) - { - /* can't decode or no integer (version) */ - snmp_inc_snmpinasnparseerrs(); - return ERR_ARG; - } - derr = snmp_asn1_dec_s32t(p, ofs + 1 + len_octets, len, &version); - if (derr != ERR_OK) - { - /* can't decode */ - snmp_inc_snmpinasnparseerrs(); - return ERR_ARG; - } - if (version != 0) - { - /* not version 1 */ - snmp_inc_snmpinbadversions(); - return ERR_ARG; - } - ofs += (1 + len_octets + len); - snmp_asn1_dec_type(p, ofs, &type); - derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &len); - if ((derr != ERR_OK) || (type != (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR))) - { - /* can't decode or no octet string (community) */ - snmp_inc_snmpinasnparseerrs(); - return ERR_ARG; - } - derr = snmp_asn1_dec_raw(p, ofs + 1 + len_octets, len, SNMP_COMMUNITY_STR_LEN, m_stat->community); - if (derr != ERR_OK) - { - snmp_inc_snmpinasnparseerrs(); - return ERR_ARG; - } - /* add zero terminator */ - len = ((len < (SNMP_COMMUNITY_STR_LEN))?(len):(SNMP_COMMUNITY_STR_LEN)); - m_stat->community[len] = 0; - m_stat->com_strlen = (u8_t)len; - if (strncmp(snmp_publiccommunity, (const char*)m_stat->community, SNMP_COMMUNITY_STR_LEN) != 0) - { - /** @todo: move this if we need to check more names */ - snmp_inc_snmpinbadcommunitynames(); - snmp_authfail_trap(); - return ERR_ARG; - } - ofs += (1 + len_octets + len); - snmp_asn1_dec_type(p, ofs, &type); - derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &len); - if (derr != ERR_OK) - { - snmp_inc_snmpinasnparseerrs(); - return ERR_ARG; - } - switch(type) - { - case (SNMP_ASN1_CONTXT | SNMP_ASN1_CONSTR | SNMP_ASN1_PDU_GET_REQ): - /* GetRequest PDU */ - snmp_inc_snmpingetrequests(); - derr = ERR_OK; - break; - case (SNMP_ASN1_CONTXT | SNMP_ASN1_CONSTR | SNMP_ASN1_PDU_GET_NEXT_REQ): - /* GetNextRequest PDU */ - snmp_inc_snmpingetnexts(); - derr = ERR_OK; - break; - case (SNMP_ASN1_CONTXT | SNMP_ASN1_CONSTR | SNMP_ASN1_PDU_GET_RESP): - /* GetResponse PDU */ - snmp_inc_snmpingetresponses(); - derr = ERR_ARG; - break; - case (SNMP_ASN1_CONTXT | SNMP_ASN1_CONSTR | SNMP_ASN1_PDU_SET_REQ): - /* SetRequest PDU */ - snmp_inc_snmpinsetrequests(); - derr = ERR_OK; - break; - case (SNMP_ASN1_CONTXT | SNMP_ASN1_CONSTR | SNMP_ASN1_PDU_TRAP): - /* Trap PDU */ - snmp_inc_snmpintraps(); - derr = ERR_ARG; - break; - default: - snmp_inc_snmpinasnparseerrs(); - derr = ERR_ARG; - break; - } - if (derr != ERR_OK) - { - /* unsupported input PDU for this agent (no parse error) */ - return ERR_ARG; - } - m_stat->rt = type & 0x1F; - ofs += (1 + len_octets); - if (len != (pdu_len - (ofs - ofs_base))) - { - /* decoded PDU length does not equal actual payload length */ - snmp_inc_snmpinasnparseerrs(); - return ERR_ARG; - } - snmp_asn1_dec_type(p, ofs, &type); - derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &len); - if ((derr != ERR_OK) || (type != (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG))) - { - /* can't decode or no integer (request ID) */ - snmp_inc_snmpinasnparseerrs(); - return ERR_ARG; - } - derr = snmp_asn1_dec_s32t(p, ofs + 1 + len_octets, len, &m_stat->rid); - if (derr != ERR_OK) - { - /* can't decode */ - snmp_inc_snmpinasnparseerrs(); - return ERR_ARG; - } - ofs += (1 + len_octets + len); - snmp_asn1_dec_type(p, ofs, &type); - derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &len); - if ((derr != ERR_OK) || (type != (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG))) - { - /* can't decode or no integer (error-status) */ - snmp_inc_snmpinasnparseerrs(); - return ERR_ARG; - } - /* must be noError (0) for incoming requests. - log errors for mib-2 completeness and for debug purposes */ - derr = snmp_asn1_dec_s32t(p, ofs + 1 + len_octets, len, &m_stat->error_status); - if (derr != ERR_OK) - { - /* can't decode */ - snmp_inc_snmpinasnparseerrs(); - return ERR_ARG; - } - switch (m_stat->error_status) - { - case SNMP_ES_TOOBIG: - snmp_inc_snmpintoobigs(); - break; - case SNMP_ES_NOSUCHNAME: - snmp_inc_snmpinnosuchnames(); - break; - case SNMP_ES_BADVALUE: - snmp_inc_snmpinbadvalues(); - break; - case SNMP_ES_READONLY: - snmp_inc_snmpinreadonlys(); - break; - case SNMP_ES_GENERROR: - snmp_inc_snmpingenerrs(); - break; - } - ofs += (1 + len_octets + len); - snmp_asn1_dec_type(p, ofs, &type); - derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &len); - if ((derr != ERR_OK) || (type != (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG))) - { - /* can't decode or no integer (error-index) */ - snmp_inc_snmpinasnparseerrs(); - return ERR_ARG; - } - /* must be 0 for incoming requests. - decode anyway to catch bad integers (and dirty tricks) */ - derr = snmp_asn1_dec_s32t(p, ofs + 1 + len_octets, len, &m_stat->error_index); - if (derr != ERR_OK) - { - /* can't decode */ - snmp_inc_snmpinasnparseerrs(); - return ERR_ARG; - } - ofs += (1 + len_octets + len); - *ofs_ret = ofs; - return ERR_OK; -} - -static err_t -snmp_pdu_dec_varbindlist(struct pbuf *p, u16_t ofs, u16_t *ofs_ret, struct snmp_msg_pstat *m_stat) -{ - err_t derr; - u16_t len, vb_len; - u8_t len_octets; - u8_t type; - - /* variable binding list */ - snmp_asn1_dec_type(p, ofs, &type); - derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &vb_len); - if ((derr != ERR_OK) || - (type != (SNMP_ASN1_UNIV | SNMP_ASN1_CONSTR | SNMP_ASN1_SEQ))) - { - snmp_inc_snmpinasnparseerrs(); - return ERR_ARG; - } - ofs += (1 + len_octets); - - /* start with empty list */ - m_stat->invb.count = 0; - m_stat->invb.head = NULL; - m_stat->invb.tail = NULL; - - while (vb_len > 0) - { - struct snmp_obj_id oid, oid_value; - struct snmp_varbind *vb; - - snmp_asn1_dec_type(p, ofs, &type); - derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &len); - if ((derr != ERR_OK) || - (type != (SNMP_ASN1_UNIV | SNMP_ASN1_CONSTR | SNMP_ASN1_SEQ)) || - (len == 0) || (len > vb_len)) - { - snmp_inc_snmpinasnparseerrs(); - /* free varbinds (if available) */ - snmp_varbind_list_free(&m_stat->invb); - return ERR_ARG; - } - ofs += (1 + len_octets); - vb_len -= (1 + len_octets); - - snmp_asn1_dec_type(p, ofs, &type); - derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &len); - if ((derr != ERR_OK) || (type != (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OBJ_ID))) - { - /* can't decode object name length */ - snmp_inc_snmpinasnparseerrs(); - /* free varbinds (if available) */ - snmp_varbind_list_free(&m_stat->invb); - return ERR_ARG; - } - derr = snmp_asn1_dec_oid(p, ofs + 1 + len_octets, len, &oid); - if (derr != ERR_OK) - { - /* can't decode object name */ - snmp_inc_snmpinasnparseerrs(); - /* free varbinds (if available) */ - snmp_varbind_list_free(&m_stat->invb); - return ERR_ARG; - } - ofs += (1 + len_octets + len); - vb_len -= (1 + len_octets + len); - - snmp_asn1_dec_type(p, ofs, &type); - derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &len); - if (derr != ERR_OK) - { - /* can't decode object value length */ - snmp_inc_snmpinasnparseerrs(); - /* free varbinds (if available) */ - snmp_varbind_list_free(&m_stat->invb); - return ERR_ARG; - } - - switch (type) - { - case (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG): - vb = snmp_varbind_alloc(&oid, type, sizeof(s32_t)); - if (vb != NULL) - { - s32_t *vptr = (s32_t*)vb->value; - - derr = snmp_asn1_dec_s32t(p, ofs + 1 + len_octets, len, vptr); - snmp_varbind_tail_add(&m_stat->invb, vb); - } - else - { - derr = ERR_ARG; - } - break; - case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_COUNTER): - case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_GAUGE): - case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_TIMETICKS): - vb = snmp_varbind_alloc(&oid, type, sizeof(u32_t)); - if (vb != NULL) - { - u32_t *vptr = (u32_t*)vb->value; - - derr = snmp_asn1_dec_u32t(p, ofs + 1 + len_octets, len, vptr); - snmp_varbind_tail_add(&m_stat->invb, vb); - } - else - { - derr = ERR_ARG; - } - break; - case (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR): - case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_OPAQUE): - LWIP_ASSERT("invalid length", len <= 0xff); - vb = snmp_varbind_alloc(&oid, type, (u8_t)len); - if (vb != NULL) - { - derr = snmp_asn1_dec_raw(p, ofs + 1 + len_octets, len, vb->value_len, (u8_t*)vb->value); - snmp_varbind_tail_add(&m_stat->invb, vb); - } - else - { - derr = ERR_ARG; - } - break; - case (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_NUL): - vb = snmp_varbind_alloc(&oid, type, 0); - if (vb != NULL) - { - snmp_varbind_tail_add(&m_stat->invb, vb); - derr = ERR_OK; - } - else - { - derr = ERR_ARG; - } - break; - case (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OBJ_ID): - derr = snmp_asn1_dec_oid(p, ofs + 1 + len_octets, len, &oid_value); - if (derr == ERR_OK) - { - vb = snmp_varbind_alloc(&oid, type, oid_value.len * sizeof(s32_t)); - if (vb != NULL) - { - u8_t i = oid_value.len; - s32_t *vptr = (s32_t*)vb->value; - - while(i > 0) - { - i--; - vptr[i] = oid_value.id[i]; - } - snmp_varbind_tail_add(&m_stat->invb, vb); - derr = ERR_OK; - } - else - { - derr = ERR_ARG; - } - } - break; - case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_IPADDR): - if (len == 4) - { - /* must be exactly 4 octets! */ - vb = snmp_varbind_alloc(&oid, type, 4); - if (vb != NULL) - { - derr = snmp_asn1_dec_raw(p, ofs + 1 + len_octets, len, vb->value_len, (u8_t*)vb->value); - snmp_varbind_tail_add(&m_stat->invb, vb); - } - else - { - derr = ERR_ARG; - } - } - else - { - derr = ERR_ARG; - } - break; - default: - derr = ERR_ARG; - break; - } - if (derr != ERR_OK) - { - snmp_inc_snmpinasnparseerrs(); - /* free varbinds (if available) */ - snmp_varbind_list_free(&m_stat->invb); - return ERR_ARG; - } - ofs += (1 + len_octets + len); - vb_len -= (1 + len_octets + len); - } - - if (m_stat->rt == SNMP_ASN1_PDU_SET_REQ) - { - snmp_add_snmpintotalsetvars(m_stat->invb.count); - } - else - { - snmp_add_snmpintotalreqvars(m_stat->invb.count); - } - - *ofs_ret = ofs; - return ERR_OK; -} - -struct snmp_varbind* -snmp_varbind_alloc(struct snmp_obj_id *oid, u8_t type, u8_t len) -{ - struct snmp_varbind *vb; - - vb = (struct snmp_varbind *)memp_malloc(MEMP_SNMP_VARBIND); - LWIP_ASSERT("vb != NULL",vb != NULL); - if (vb != NULL) - { - u8_t i; - - vb->next = NULL; - vb->prev = NULL; - i = oid->len; - vb->ident_len = i; - if (i > 0) - { - LWIP_ASSERT("SNMP_MAX_TREE_DEPTH is configured too low", i <= SNMP_MAX_TREE_DEPTH); - /* allocate array of s32_t for our object identifier */ - vb->ident = (s32_t*)memp_malloc(MEMP_SNMP_VALUE); - LWIP_ASSERT("vb->ident != NULL",vb->ident != NULL); - if (vb->ident == NULL) - { - memp_free(MEMP_SNMP_VARBIND, vb); - return NULL; - } - while(i > 0) - { - i--; - vb->ident[i] = oid->id[i]; - } - } - else - { - /* i == 0, pass zero length object identifier */ - vb->ident = NULL; - } - vb->value_type = type; - vb->value_len = len; - if (len > 0) - { - LWIP_ASSERT("SNMP_MAX_OCTET_STRING_LEN is configured too low", vb->value_len <= SNMP_MAX_VALUE_SIZE); - /* allocate raw bytes for our object value */ - vb->value = memp_malloc(MEMP_SNMP_VALUE); - LWIP_ASSERT("vb->value != NULL",vb->value != NULL); - if (vb->value == NULL) - { - if (vb->ident != NULL) - { - memp_free(MEMP_SNMP_VALUE, vb->ident); - } - memp_free(MEMP_SNMP_VARBIND, vb); - return NULL; - } - } - else - { - /* ASN1_NUL type, or zero length ASN1_OC_STR */ - vb->value = NULL; - } - } - return vb; -} - -void -snmp_varbind_free(struct snmp_varbind *vb) -{ - if (vb->value != NULL ) - { - memp_free(MEMP_SNMP_VALUE, vb->value); - } - if (vb->ident != NULL ) - { - memp_free(MEMP_SNMP_VALUE, vb->ident); - } - memp_free(MEMP_SNMP_VARBIND, vb); -} - -void -snmp_varbind_list_free(struct snmp_varbind_root *root) -{ - struct snmp_varbind *vb, *prev; - - vb = root->tail; - while ( vb != NULL ) - { - prev = vb->prev; - snmp_varbind_free(vb); - vb = prev; - } - root->count = 0; - root->head = NULL; - root->tail = NULL; -} - -void -snmp_varbind_tail_add(struct snmp_varbind_root *root, struct snmp_varbind *vb) -{ - if (root->count == 0) - { - /* add first varbind to list */ - root->head = vb; - root->tail = vb; - } - else - { - /* add nth varbind to list tail */ - root->tail->next = vb; - vb->prev = root->tail; - root->tail = vb; - } - root->count += 1; -} - -struct snmp_varbind* -snmp_varbind_tail_remove(struct snmp_varbind_root *root) -{ - struct snmp_varbind* vb; - - if (root->count > 0) - { - /* remove tail varbind */ - vb = root->tail; - root->tail = vb->prev; - vb->prev->next = NULL; - root->count -= 1; - } - else - { - /* nothing to remove */ - vb = NULL; - } - return vb; -} - -#endif /* LWIP_SNMP */ diff --git a/features/net/FEATURE_IPV4/lwip-interface/lwip/core/snmp/lwip_msg_out.c b/features/net/FEATURE_IPV4/lwip-interface/lwip/core/snmp/lwip_msg_out.c deleted file mode 100644 index 4778bee6f4..0000000000 --- a/features/net/FEATURE_IPV4/lwip-interface/lwip/core/snmp/lwip_msg_out.c +++ /dev/null @@ -1,681 +0,0 @@ -/** - * @file - * SNMP output message processing (RFC1157). - * - * Output responses and traps are build in two passes: - * - * Pass 0: iterate over the output message backwards to determine encoding lengths - * Pass 1: the actual forward encoding of internal form into ASN1 - * - * The single-pass encoding method described by Comer & Stevens - * requires extra buffer space and copying for reversal of the packet. - * The buffer requirement can be prohibitively large for big payloads - * (>= 484) therefore we use the two encoding passes. - */ - -/* - * 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 - */ - -#include "lwip/opt.h" - -#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/udp.h" -#include "lwip/netif.h" -#include "lwip/snmp.h" -#include "lwip/snmp_asn1.h" -#include "lwip/snmp_msg.h" - -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; -}; -struct snmp_trap_dst trap_dst[SNMP_TRAP_DESTINATIONS]; - -/** TRAP message structure */ -struct snmp_msg_trap trap_msg; - -static u16_t snmp_resp_header_sum(struct snmp_msg_pstat *m_stat, u16_t vb_len); -static u16_t snmp_trap_header_sum(struct snmp_msg_trap *m_trap, u16_t vb_len); -static u16_t snmp_varbind_list_sum(struct snmp_varbind_root *root); - -static u16_t snmp_resp_header_enc(struct snmp_msg_pstat *m_stat, struct pbuf *p); -static u16_t snmp_trap_header_enc(struct snmp_msg_trap *m_trap, struct pbuf *p); -static u16_t snmp_varbind_list_enc(struct snmp_varbind_root *root, struct pbuf *p, u16_t ofs); - -/** - * 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; - } -} - -/** - * 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, ip_addr_t *dst) -{ - if (dst_idx < SNMP_TRAP_DESTINATIONS) - { - ip_addr_set(&trap_dst[dst_idx].dip, dst); - } -} - -/** - * Sends a 'getresponse' message to the request originator. - * - * @param m_stat points to the current message request state source - * @return ERR_OK when success, ERR_MEM if we're out of memory - * - * @note the caller is responsible for filling in outvb in the m_stat - * and provide error-status and index (except for tooBig errors) ... - */ -err_t -snmp_send_response(struct snmp_msg_pstat *m_stat) -{ - struct snmp_varbind_root emptyvb = {NULL, NULL, 0, 0, 0}; - struct pbuf *p; - u16_t tot_len; - err_t err; - - /* pass 0, calculate length fields */ - tot_len = snmp_varbind_list_sum(&m_stat->outvb); - tot_len = snmp_resp_header_sum(m_stat, tot_len); - - /* try allocating pbuf(s) for complete response */ - p = pbuf_alloc(PBUF_TRANSPORT, tot_len, PBUF_POOL); - if (p == NULL) - { - LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_snd_response() tooBig\n")); - - /* can't construct reply, return error-status tooBig */ - m_stat->error_status = SNMP_ES_TOOBIG; - m_stat->error_index = 0; - /* pass 0, recalculate lengths, for empty varbind-list */ - tot_len = snmp_varbind_list_sum(&emptyvb); - tot_len = snmp_resp_header_sum(m_stat, tot_len); - /* retry allocation once for header and empty varbind-list */ - p = pbuf_alloc(PBUF_TRANSPORT, tot_len, PBUF_POOL); - } - if (p != NULL) - { - /* first pbuf alloc try or retry alloc success */ - u16_t ofs; - - LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_snd_response() p != NULL\n")); - - /* pass 1, size error, encode packet ino the pbuf(s) */ - ofs = snmp_resp_header_enc(m_stat, p); - if (m_stat->error_status == SNMP_ES_TOOBIG) - { - snmp_varbind_list_enc(&emptyvb, p, ofs); - } - else - { - snmp_varbind_list_enc(&m_stat->outvb, p, ofs); - } - - switch (m_stat->error_status) - { - case SNMP_ES_TOOBIG: - snmp_inc_snmpouttoobigs(); - break; - case SNMP_ES_NOSUCHNAME: - snmp_inc_snmpoutnosuchnames(); - break; - case SNMP_ES_BADVALUE: - snmp_inc_snmpoutbadvalues(); - break; - case SNMP_ES_GENERROR: - snmp_inc_snmpoutgenerrs(); - break; - } - snmp_inc_snmpoutgetresponses(); - snmp_inc_snmpoutpkts(); - - /** @todo do we need separate rx and tx pcbs for threaded case? */ - /** connect to the originating source */ - udp_connect(m_stat->pcb, &m_stat->sip, m_stat->sp); - err = udp_send(m_stat->pcb, p); - if (err == ERR_MEM) - { - /** @todo release some memory, retry and return tooBig? tooMuchHassle? */ - err = ERR_MEM; - } - else - { - err = ERR_OK; - } - /** disassociate remote address and port with this pcb */ - udp_disconnect(m_stat->pcb); - - pbuf_free(p); - LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_snd_response() done\n")); - return err; - } - else - { - /* first pbuf alloc try or retry alloc failed - very low on memory, couldn't return tooBig */ - return ERR_MEM; - } -} - - -/** - * Sends an generic or enterprise specific trap message. - * - * @param generic_trap is the trap code - * @param eoid points to enterprise object identifier - * @param specific_trap used for enterprise traps when generic_trap == 6 - * @return ERR_OK when success, ERR_MEM if we're out of memory - * - * @note the caller is responsible for filling in outvb in the trap_msg - * @note the use of the enterpise 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(s8_t generic_trap, struct snmp_obj_id *eoid, s32_t specific_trap) -{ - struct snmp_trap_dst *td; - struct netif *dst_if; - ip_addr_t dst_ip; - struct pbuf *p; - u16_t i,tot_len; - - for (i=0, td = &trap_dst[0]; ienable != 0) && !ip_addr_isany(&td->dip)) - { - /* network order trap destination */ - ip_addr_copy(trap_msg.dip, td->dip); - /* lookup current source address for this dst */ - dst_if = ip_route(&td->dip); - ip_addr_copy(dst_ip, dst_if->ip_addr); - /* @todo: what about IPv6? */ - trap_msg.sip_raw[0] = ip4_addr1(&dst_ip); - trap_msg.sip_raw[1] = ip4_addr2(&dst_ip); - trap_msg.sip_raw[2] = ip4_addr3(&dst_ip); - trap_msg.sip_raw[3] = ip4_addr4(&dst_ip); - trap_msg.gen_trap = generic_trap; - trap_msg.spc_trap = specific_trap; - if (generic_trap == SNMP_GENTRAP_ENTERPRISESPC) - { - /* enterprise-Specific trap */ - trap_msg.enterprise = eoid; - } - else - { - /* generic (MIB-II) trap */ - snmp_get_snmpgrpid_ptr(&trap_msg.enterprise); - } - snmp_get_sysuptime(&trap_msg.ts); - - /* pass 0, calculate length fields */ - tot_len = snmp_varbind_list_sum(&trap_msg.outvb); - tot_len = snmp_trap_header_sum(&trap_msg, tot_len); - - /* allocate pbuf(s) */ - p = pbuf_alloc(PBUF_TRANSPORT, tot_len, PBUF_POOL); - if (p != NULL) - { - u16_t ofs; - - /* pass 1, encode packet ino the pbuf(s) */ - ofs = snmp_trap_header_enc(&trap_msg, p); - snmp_varbind_list_enc(&trap_msg.outvb, p, ofs); - - snmp_inc_snmpouttraps(); - snmp_inc_snmpoutpkts(); - - /** send to the TRAP destination */ - udp_sendto(trap_msg.pcb, p, &trap_msg.dip, SNMP_TRAP_PORT); - - pbuf_free(p); - } - else - { - return ERR_MEM; - } - } - } - return ERR_OK; -} - -void -snmp_coldstart_trap(void) -{ - trap_msg.outvb.head = NULL; - trap_msg.outvb.tail = NULL; - trap_msg.outvb.count = 0; - snmp_send_trap(SNMP_GENTRAP_COLDSTART, NULL, 0); -} - -void -snmp_authfail_trap(void) -{ - u8_t enable; - snmp_get_snmpenableauthentraps(&enable); - if (enable == 1) - { - trap_msg.outvb.head = NULL; - trap_msg.outvb.tail = NULL; - trap_msg.outvb.count = 0; - snmp_send_trap(SNMP_GENTRAP_AUTHFAIL, NULL, 0); - } -} - -/** - * Sums response header field lengths from tail to head and - * returns resp_header_lengths for second encoding pass. - * - * @param vb_len varbind-list length - * @param rhl points to returned header lengths - * @return the required lenght for encoding the response header - */ -static u16_t -snmp_resp_header_sum(struct snmp_msg_pstat *m_stat, u16_t vb_len) -{ - u16_t tot_len; - struct snmp_resp_header_lengths *rhl; - - rhl = &m_stat->rhl; - tot_len = vb_len; - snmp_asn1_enc_s32t_cnt(m_stat->error_index, &rhl->erridxlen); - snmp_asn1_enc_length_cnt(rhl->erridxlen, &rhl->erridxlenlen); - tot_len += 1 + rhl->erridxlenlen + rhl->erridxlen; - - snmp_asn1_enc_s32t_cnt(m_stat->error_status, &rhl->errstatlen); - snmp_asn1_enc_length_cnt(rhl->errstatlen, &rhl->errstatlenlen); - tot_len += 1 + rhl->errstatlenlen + rhl->errstatlen; - - snmp_asn1_enc_s32t_cnt(m_stat->rid, &rhl->ridlen); - snmp_asn1_enc_length_cnt(rhl->ridlen, &rhl->ridlenlen); - tot_len += 1 + rhl->ridlenlen + rhl->ridlen; - - rhl->pdulen = tot_len; - snmp_asn1_enc_length_cnt(rhl->pdulen, &rhl->pdulenlen); - tot_len += 1 + rhl->pdulenlen; - - rhl->comlen = m_stat->com_strlen; - snmp_asn1_enc_length_cnt(rhl->comlen, &rhl->comlenlen); - tot_len += 1 + rhl->comlenlen + rhl->comlen; - - snmp_asn1_enc_s32t_cnt(snmp_version, &rhl->verlen); - snmp_asn1_enc_length_cnt(rhl->verlen, &rhl->verlenlen); - tot_len += 1 + rhl->verlen + rhl->verlenlen; - - rhl->seqlen = tot_len; - snmp_asn1_enc_length_cnt(rhl->seqlen, &rhl->seqlenlen); - tot_len += 1 + rhl->seqlenlen; - - return tot_len; -} - -/** - * Sums trap header field lengths from tail to head and - * returns trap_header_lengths for second encoding pass. - * - * @param vb_len varbind-list length - * @param thl points to returned header lengths - * @return the required lenght for encoding the trap header - */ -static u16_t -snmp_trap_header_sum(struct snmp_msg_trap *m_trap, u16_t vb_len) -{ - u16_t tot_len; - struct snmp_trap_header_lengths *thl; - - thl = &m_trap->thl; - tot_len = vb_len; - - snmp_asn1_enc_u32t_cnt(m_trap->ts, &thl->tslen); - snmp_asn1_enc_length_cnt(thl->tslen, &thl->tslenlen); - tot_len += 1 + thl->tslen + thl->tslenlen; - - snmp_asn1_enc_s32t_cnt(m_trap->spc_trap, &thl->strplen); - snmp_asn1_enc_length_cnt(thl->strplen, &thl->strplenlen); - tot_len += 1 + thl->strplen + thl->strplenlen; - - snmp_asn1_enc_s32t_cnt(m_trap->gen_trap, &thl->gtrplen); - snmp_asn1_enc_length_cnt(thl->gtrplen, &thl->gtrplenlen); - tot_len += 1 + thl->gtrplen + thl->gtrplenlen; - - thl->aaddrlen = 4; - snmp_asn1_enc_length_cnt(thl->aaddrlen, &thl->aaddrlenlen); - tot_len += 1 + thl->aaddrlen + thl->aaddrlenlen; - - snmp_asn1_enc_oid_cnt(m_trap->enterprise->len, &m_trap->enterprise->id[0], &thl->eidlen); - snmp_asn1_enc_length_cnt(thl->eidlen, &thl->eidlenlen); - tot_len += 1 + thl->eidlen + thl->eidlenlen; - - thl->pdulen = tot_len; - snmp_asn1_enc_length_cnt(thl->pdulen, &thl->pdulenlen); - tot_len += 1 + thl->pdulenlen; - - thl->comlen = sizeof(snmp_publiccommunity) - 1; - snmp_asn1_enc_length_cnt(thl->comlen, &thl->comlenlen); - tot_len += 1 + thl->comlenlen + thl->comlen; - - snmp_asn1_enc_s32t_cnt(snmp_version, &thl->verlen); - snmp_asn1_enc_length_cnt(thl->verlen, &thl->verlenlen); - tot_len += 1 + thl->verlen + thl->verlenlen; - - thl->seqlen = tot_len; - snmp_asn1_enc_length_cnt(thl->seqlen, &thl->seqlenlen); - tot_len += 1 + thl->seqlenlen; - - return tot_len; -} - -/** - * Sums varbind lengths from tail to head and - * annotates lengths in varbind for second encoding pass. - * - * @param root points to the root of the variable binding list - * @return the required lenght for encoding the variable bindings - */ -static u16_t -snmp_varbind_list_sum(struct snmp_varbind_root *root) -{ - struct snmp_varbind *vb; - u32_t *uint_ptr; - s32_t *sint_ptr; - u16_t tot_len; - - tot_len = 0; - vb = root->tail; - while ( vb != NULL ) - { - /* encoded value lenght depends on type */ - switch (vb->value_type) - { - case (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG): - sint_ptr = (s32_t*)vb->value; - snmp_asn1_enc_s32t_cnt(*sint_ptr, &vb->vlen); - break; - case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_COUNTER): - case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_GAUGE): - case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_TIMETICKS): - uint_ptr = (u32_t*)vb->value; - snmp_asn1_enc_u32t_cnt(*uint_ptr, &vb->vlen); - break; - case (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR): - case (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_NUL): - case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_IPADDR): - case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_OPAQUE): - vb->vlen = vb->value_len; - break; - case (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OBJ_ID): - sint_ptr = (s32_t*)vb->value; - snmp_asn1_enc_oid_cnt(vb->value_len / sizeof(s32_t), sint_ptr, &vb->vlen); - break; - default: - /* unsupported type */ - vb->vlen = 0; - break; - }; - /* encoding length of value length field */ - snmp_asn1_enc_length_cnt(vb->vlen, &vb->vlenlen); - snmp_asn1_enc_oid_cnt(vb->ident_len, vb->ident, &vb->olen); - snmp_asn1_enc_length_cnt(vb->olen, &vb->olenlen); - - vb->seqlen = 1 + vb->vlenlen + vb->vlen; - vb->seqlen += 1 + vb->olenlen + vb->olen; - snmp_asn1_enc_length_cnt(vb->seqlen, &vb->seqlenlen); - - /* varbind seq */ - tot_len += 1 + vb->seqlenlen + vb->seqlen; - - vb = vb->prev; - } - - /* varbind-list seq */ - root->seqlen = tot_len; - snmp_asn1_enc_length_cnt(root->seqlen, &root->seqlenlen); - tot_len += 1 + root->seqlenlen; - - return tot_len; -} - -/** - * Encodes response header from head to tail. - */ -static u16_t -snmp_resp_header_enc(struct snmp_msg_pstat *m_stat, struct pbuf *p) -{ - u16_t ofs; - - ofs = 0; - snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_CONSTR | SNMP_ASN1_SEQ)); - ofs += 1; - snmp_asn1_enc_length(p, ofs, m_stat->rhl.seqlen); - ofs += m_stat->rhl.seqlenlen; - - snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG)); - ofs += 1; - snmp_asn1_enc_length(p, ofs, m_stat->rhl.verlen); - ofs += m_stat->rhl.verlenlen; - snmp_asn1_enc_s32t(p, ofs, m_stat->rhl.verlen, snmp_version); - ofs += m_stat->rhl.verlen; - - snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR)); - ofs += 1; - snmp_asn1_enc_length(p, ofs, m_stat->rhl.comlen); - ofs += m_stat->rhl.comlenlen; - snmp_asn1_enc_raw(p, ofs, m_stat->rhl.comlen, m_stat->community); - ofs += m_stat->rhl.comlen; - - snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_CONTXT | SNMP_ASN1_CONSTR | SNMP_ASN1_PDU_GET_RESP)); - ofs += 1; - snmp_asn1_enc_length(p, ofs, m_stat->rhl.pdulen); - ofs += m_stat->rhl.pdulenlen; - - snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG)); - ofs += 1; - snmp_asn1_enc_length(p, ofs, m_stat->rhl.ridlen); - ofs += m_stat->rhl.ridlenlen; - snmp_asn1_enc_s32t(p, ofs, m_stat->rhl.ridlen, m_stat->rid); - ofs += m_stat->rhl.ridlen; - - snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG)); - ofs += 1; - snmp_asn1_enc_length(p, ofs, m_stat->rhl.errstatlen); - ofs += m_stat->rhl.errstatlenlen; - snmp_asn1_enc_s32t(p, ofs, m_stat->rhl.errstatlen, m_stat->error_status); - ofs += m_stat->rhl.errstatlen; - - snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG)); - ofs += 1; - snmp_asn1_enc_length(p, ofs, m_stat->rhl.erridxlen); - ofs += m_stat->rhl.erridxlenlen; - snmp_asn1_enc_s32t(p, ofs, m_stat->rhl.erridxlen, m_stat->error_index); - ofs += m_stat->rhl.erridxlen; - - return ofs; -} - -/** - * Encodes trap header from head to tail. - */ -static u16_t -snmp_trap_header_enc(struct snmp_msg_trap *m_trap, struct pbuf *p) -{ - u16_t ofs; - - ofs = 0; - snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_CONSTR | SNMP_ASN1_SEQ)); - ofs += 1; - snmp_asn1_enc_length(p, ofs, m_trap->thl.seqlen); - ofs += m_trap->thl.seqlenlen; - - snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG)); - ofs += 1; - snmp_asn1_enc_length(p, ofs, m_trap->thl.verlen); - ofs += m_trap->thl.verlenlen; - snmp_asn1_enc_s32t(p, ofs, m_trap->thl.verlen, snmp_version); - ofs += m_trap->thl.verlen; - - snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR)); - ofs += 1; - snmp_asn1_enc_length(p, ofs, m_trap->thl.comlen); - ofs += m_trap->thl.comlenlen; - snmp_asn1_enc_raw(p, ofs, m_trap->thl.comlen, (u8_t *)&snmp_publiccommunity[0]); - ofs += m_trap->thl.comlen; - - snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_CONTXT | SNMP_ASN1_CONSTR | SNMP_ASN1_PDU_TRAP)); - ofs += 1; - snmp_asn1_enc_length(p, ofs, m_trap->thl.pdulen); - ofs += m_trap->thl.pdulenlen; - - snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OBJ_ID)); - ofs += 1; - snmp_asn1_enc_length(p, ofs, m_trap->thl.eidlen); - ofs += m_trap->thl.eidlenlen; - snmp_asn1_enc_oid(p, ofs, m_trap->enterprise->len, &m_trap->enterprise->id[0]); - ofs += m_trap->thl.eidlen; - - snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_IPADDR)); - ofs += 1; - snmp_asn1_enc_length(p, ofs, m_trap->thl.aaddrlen); - ofs += m_trap->thl.aaddrlenlen; - snmp_asn1_enc_raw(p, ofs, m_trap->thl.aaddrlen, &m_trap->sip_raw[0]); - ofs += m_trap->thl.aaddrlen; - - snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG)); - ofs += 1; - snmp_asn1_enc_length(p, ofs, m_trap->thl.gtrplen); - ofs += m_trap->thl.gtrplenlen; - snmp_asn1_enc_u32t(p, ofs, m_trap->thl.gtrplen, m_trap->gen_trap); - ofs += m_trap->thl.gtrplen; - - snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG)); - ofs += 1; - snmp_asn1_enc_length(p, ofs, m_trap->thl.strplen); - ofs += m_trap->thl.strplenlen; - snmp_asn1_enc_u32t(p, ofs, m_trap->thl.strplen, m_trap->spc_trap); - ofs += m_trap->thl.strplen; - - snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_TIMETICKS)); - ofs += 1; - snmp_asn1_enc_length(p, ofs, m_trap->thl.tslen); - ofs += m_trap->thl.tslenlen; - snmp_asn1_enc_u32t(p, ofs, m_trap->thl.tslen, m_trap->ts); - ofs += m_trap->thl.tslen; - - return ofs; -} - -/** - * Encodes varbind list from head to tail. - */ -static u16_t -snmp_varbind_list_enc(struct snmp_varbind_root *root, struct pbuf *p, u16_t ofs) -{ - struct snmp_varbind *vb; - s32_t *sint_ptr; - u32_t *uint_ptr; - u8_t *raw_ptr; - - snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_CONSTR | SNMP_ASN1_SEQ)); - ofs += 1; - snmp_asn1_enc_length(p, ofs, root->seqlen); - ofs += root->seqlenlen; - - vb = root->head; - while ( vb != NULL ) - { - snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_CONSTR | SNMP_ASN1_SEQ)); - ofs += 1; - snmp_asn1_enc_length(p, ofs, vb->seqlen); - ofs += vb->seqlenlen; - - snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OBJ_ID)); - ofs += 1; - snmp_asn1_enc_length(p, ofs, vb->olen); - ofs += vb->olenlen; - snmp_asn1_enc_oid(p, ofs, vb->ident_len, &vb->ident[0]); - ofs += vb->olen; - - snmp_asn1_enc_type(p, ofs, vb->value_type); - ofs += 1; - snmp_asn1_enc_length(p, ofs, vb->vlen); - ofs += vb->vlenlen; - - switch (vb->value_type) - { - case (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG): - sint_ptr = (s32_t*)vb->value; - snmp_asn1_enc_s32t(p, ofs, vb->vlen, *sint_ptr); - break; - case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_COUNTER): - case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_GAUGE): - case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_TIMETICKS): - uint_ptr = (u32_t*)vb->value; - snmp_asn1_enc_u32t(p, ofs, vb->vlen, *uint_ptr); - break; - case (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR): - case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_IPADDR): - case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_OPAQUE): - raw_ptr = (u8_t*)vb->value; - snmp_asn1_enc_raw(p, ofs, vb->vlen, raw_ptr); - break; - case (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_NUL): - break; - case (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OBJ_ID): - sint_ptr = (s32_t*)vb->value; - snmp_asn1_enc_oid(p, ofs, vb->value_len / sizeof(s32_t), sint_ptr); - break; - default: - /* unsupported type */ - break; - }; - ofs += vb->vlen; - vb = vb->next; - } - return ofs; -} - -#endif /* LWIP_SNMP */ diff --git a/features/net/FEATURE_IPV4/lwip-interface/lwip/doc/FILES b/features/net/FEATURE_IPV4/lwip-interface/lwip/doc/FILES new file mode 100644 index 0000000000..05d356f4f9 --- /dev/null +++ b/features/net/FEATURE_IPV4/lwip-interface/lwip/doc/FILES @@ -0,0 +1,6 @@ +savannah.txt - How to obtain the current development source code. +contrib.txt - How to contribute to lwIP as a developer. +rawapi.txt - The documentation for the core API of lwIP. + Also provides an overview about the other APIs and multithreading. +snmp_agent.txt - The documentation for the lwIP SNMP agent. +sys_arch.txt - The documentation for a system abstraction layer of lwIP. diff --git a/features/net/FEATURE_IPV4/lwip-interface/lwip/doc/contrib.txt b/features/net/FEATURE_IPV4/lwip-interface/lwip/doc/contrib.txt new file mode 100644 index 0000000000..fa11dfecdd --- /dev/null +++ b/features/net/FEATURE_IPV4/lwip-interface/lwip/doc/contrib.txt @@ -0,0 +1,58 @@ +1 Introduction + +This document describes some guidelines for people participating +in lwIP development. + +2 How to contribute to lwIP + +Here is a short list of suggestions to anybody working with lwIP and +trying to contribute bug reports, fixes, enhancements, platform ports etc. +First of all as you may already know lwIP is a volunteer project so feedback +to fixes or questions might often come late. Hopefully the bug and patch tracking +features of Savannah help us not lose users' input. + +2.1 Source code style: + +1. do not use tabs. +2. indentation is two spaces per level (i.e. per tab). +3. end debug messages with a trailing newline (\n). +4. one space between keyword and opening bracket. +5. no space between function and opening bracket. +6. one space and no newline before opening curly braces of a block. +7. closing curly brace on a single line. +8. spaces surrounding assignment and comparisons. +9. don't initialize static and/or global variables to zero, the compiler takes care of that. +10. use current source code style as further reference. + +2.2 Source code documentation style: + +1. JavaDoc compliant and Doxygen compatible. +2. Function documentation above functions in .c files, not .h files. + (This forces you to synchronize documentation and implementation.) +3. Use current documentation style as further reference. + +2.3 Bug reports and patches: + +1. Make sure you are reporting bugs or send patches against the latest + sources. (From the latest release and/or the current Git sources.) +2. If you think you found a bug make sure it's not already filed in the + bugtracker at Savannah. +3. If you have a fix put the patch on Savannah. If it is a patch that affects + both core and arch specific stuff please separate them so that the core can + be applied separately while leaving the other patch 'open'. The prefered way + is to NOT touch archs you can't test and let maintainers take care of them. + This is a good way to see if they are used at all - the same goes for unix + netifs except tapif. +4. Do not file a bug and post a fix to it to the patch area. Either a bug report + or a patch will be enough. + If you correct an existing bug then attach the patch to the bug rather than creating a new entry in the patch area. +5. Patches should be specific to a single change or to related changes. Do not mix bugfixes with spelling and other + trivial fixes unless the bugfix is trivial too. Do not reorganize code and rename identifiers in the same patch you + change behaviour if not necessary. A patch is easier to read and understand if it's to the point and short than + if it's not to the point and long :) so the chances for it to be applied are greater. + +2.4 Platform porters: + +1. If you have ported lwIP to a platform (an OS, a uC/processor or a combination of these) and + you think it could benefit others[1] you might want discuss this on the mailing list. You + can also ask for Git access to submit and maintain your port in the contrib Git module. diff --git a/features/net/FEATURE_IPV4/lwip-interface/lwip/doc/doxygen/generate.bat b/features/net/FEATURE_IPV4/lwip-interface/lwip/doc/doxygen/generate.bat new file mode 100644 index 0000000000..99afb124be --- /dev/null +++ b/features/net/FEATURE_IPV4/lwip-interface/lwip/doc/doxygen/generate.bat @@ -0,0 +1 @@ +doxygen lwip.Doxyfile diff --git a/features/net/FEATURE_IPV4/lwip-interface/lwip/doc/doxygen/generate.sh b/features/net/FEATURE_IPV4/lwip-interface/lwip/doc/doxygen/generate.sh new file mode 100755 index 0000000000..99afb124be --- /dev/null +++ b/features/net/FEATURE_IPV4/lwip-interface/lwip/doc/doxygen/generate.sh @@ -0,0 +1 @@ +doxygen lwip.Doxyfile diff --git a/features/net/FEATURE_IPV4/lwip-interface/lwip/doc/doxygen/lwip.Doxyfile b/features/net/FEATURE_IPV4/lwip-interface/lwip/doc/doxygen/lwip.Doxyfile new file mode 100644 index 0000000000..f9d5fc17b0 --- /dev/null +++ b/features/net/FEATURE_IPV4/lwip-interface/lwip/doc/doxygen/lwip.Doxyfile @@ -0,0 +1,2502 @@ +# Doxyfile 1.8.11 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project. +# +# All text after a double hash (##) is considered a comment and is placed in +# front of the TAG it is preceding. +# +# All text after a single hash (#) is considered a comment and will be ignored. +# The format is: +# TAG = value [value, ...] +# For lists, items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (\" \"). + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the config file +# that follow. The default is UTF-8 which is also the encoding used for all text +# before the first occurrence of this tag. Doxygen uses libiconv (or the iconv +# built into libc) for the transcoding. See http://www.gnu.org/software/libiconv +# for the list of possible encodings. +# The default value is: UTF-8. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by +# double-quotes, unless you are using Doxywizard) that should identify the +# project for which the documentation is generated. This name is used in the +# title of most generated pages and in a few other places. +# The default value is: My Project. + +PROJECT_NAME = "lwIP 2.0.0" + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. This +# could be handy for archiving the generated documentation or if some version +# control system is used. + +PROJECT_NUMBER = "lwIP 2.0.0" + +# Using the PROJECT_BRIEF tag one can provide an optional one line description +# for a project that appears at the top of each page and should give viewer a +# quick idea about the purpose of the project. Keep the description short. + +PROJECT_BRIEF = Lightweight IP stack + +# With the PROJECT_LOGO tag one can specify a logo or an icon that is included +# in the documentation. The maximum height of the logo should not exceed 55 +# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy +# the logo to the output directory. + +PROJECT_LOGO = + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path +# into which the generated documentation will be written. If a relative path is +# entered, it will be relative to the location where doxygen was started. If +# left blank the current directory will be used. + +OUTPUT_DIRECTORY = output + +# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub- +# directories (in 2 levels) under the output directory of each output format and +# will distribute the generated files over these directories. Enabling this +# option can be useful when feeding doxygen a huge amount of source files, where +# putting all generated files in the same directory would otherwise causes +# performance problems for the file system. +# The default value is: NO. + +CREATE_SUBDIRS = NO + +# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII +# characters to appear in the names of generated files. If set to NO, non-ASCII +# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode +# U+3044. +# The default value is: NO. + +ALLOW_UNICODE_NAMES = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese, +# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States), +# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian, +# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages), +# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian, +# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian, +# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish, +# Ukrainian and Vietnamese. +# The default value is: English. + +OUTPUT_LANGUAGE = English + +# If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member +# descriptions after the members that are listed in the file and class +# documentation (similar to Javadoc). Set to NO to disable this. +# The default value is: YES. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES, doxygen will prepend the brief +# description of a member or function before the detailed description +# +# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. +# The default value is: YES. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator that is +# used to form the text in various listings. Each string in this list, if found +# as the leading text of the brief description, will be stripped from the text +# and the result, after processing the whole list, is used as the annotated +# text. Otherwise, the brief description is used as-is. If left blank, the +# following values are used ($name is automatically replaced with the name of +# the entity):The $name class, The $name widget, The $name file, is, provides, +# specifies, contains, represents, a, an and the. + +ABBREVIATE_BRIEF = "The $name class " \ + "The $name widget " \ + "The $name file " \ + is \ + provides \ + specifies \ + contains \ + represents \ + a \ + an \ + the + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# doxygen will generate a detailed section even if there is only a brief +# description. +# The default value is: NO. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. +# The default value is: NO. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path +# before files name in the file list and in the header files. If set to NO the +# shortest path that makes the file name unique will be used +# The default value is: YES. + +FULL_PATH_NAMES = YES + +# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path. +# Stripping is only done if one of the specified strings matches the left-hand +# part of the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the path to +# strip. +# +# Note that you can specify absolute paths here, but also relative paths, which +# will be relative from the directory where doxygen is started. +# This tag requires that the tag FULL_PATH_NAMES is set to YES. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the +# path mentioned in the documentation of a class, which tells the reader which +# header file to include in order to use a class. If left blank only the name of +# the header file containing the class definition is used. Otherwise one should +# specify the list of include paths that are normally passed to the compiler +# using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but +# less readable) file names. This can be useful is your file systems doesn't +# support long names like on DOS, Mac, or CD-ROM. +# The default value is: NO. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the +# first line (until the first dot) of a Javadoc-style comment as the brief +# description. If set to NO, the Javadoc-style will behave just like regular Qt- +# style comments (thus requiring an explicit @brief command for a brief +# description.) +# The default value is: NO. + +JAVADOC_AUTOBRIEF = NO + +# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first +# line (until the first dot) of a Qt-style comment as the brief description. If +# set to NO, the Qt-style will behave just like regular Qt-style comments (thus +# requiring an explicit \brief command for a brief description.) +# The default value is: NO. + +QT_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a +# multi-line C++ special comment block (i.e. a block of //! or /// comments) as +# a brief description. This used to be the default behavior. The new default is +# to treat a multi-line C++ comment block as a detailed description. Set this +# tag to YES if you prefer the old behavior instead. +# +# Note that setting this tag to YES also means that rational rose comments are +# not recognized any more. +# The default value is: NO. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the +# documentation from any documented member that it re-implements. +# The default value is: YES. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES then doxygen will produce a new +# page for each member. If set to NO, the documentation of a member will be part +# of the file/class/namespace that contains it. +# The default value is: NO. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen +# uses this value to replace tabs by spaces in code fragments. +# Minimum value: 1, maximum value: 16, default value: 4. + +TAB_SIZE = 8 + +# This tag can be used to specify a number of aliases that act as commands in +# the documentation. An alias has the form: +# name=value +# For example adding +# "sideeffect=@par Side Effects:\n" +# will allow you to put the command \sideeffect (or @sideeffect) in the +# documentation, which will result in a user-defined paragraph with heading +# "Side Effects:". You can put \n's in the value part of an alias to insert +# newlines. + +ALIASES = + +# This tag can be used to specify a number of word-keyword mappings (TCL only). +# A mapping has the form "name=value". For example adding "class=itcl::class" +# will allow you to use the command class in the itcl::class meaning. + +TCL_SUBST = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources +# only. Doxygen will then generate output that is more tailored for C. For +# instance, some of the names that are used will be different. The list of all +# members will be omitted, etc. +# The default value is: NO. + +OPTIMIZE_OUTPUT_FOR_C = YES + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or +# Python sources only. Doxygen will then generate output that is more tailored +# for that language. For instance, namespaces will be presented as packages, +# qualified scopes will look different, etc. +# The default value is: NO. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran +# sources. Doxygen will then generate output that is tailored for Fortran. +# The default value is: NO. + +OPTIMIZE_FOR_FORTRAN = NO + +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL +# sources. Doxygen will then generate output that is tailored for VHDL. +# The default value is: NO. + +OPTIMIZE_OUTPUT_VHDL = NO + +# Doxygen selects the parser to use depending on the extension of the files it +# parses. With this tag you can assign which parser to use for a given +# extension. Doxygen has a built-in mapping, but you can override or extend it +# using this tag. The format is ext=language, where ext is a file extension, and +# language is one of the parsers supported by doxygen: IDL, Java, Javascript, +# C#, C, C++, D, PHP, Objective-C, Python, Fortran (fixed format Fortran: +# FortranFixed, free formatted Fortran: FortranFree, unknown formatted Fortran: +# Fortran. In the later case the parser tries to guess whether the code is fixed +# or free formatted code, this is the default for Fortran type files), VHDL. For +# instance to make doxygen treat .inc files as Fortran files (default is PHP), +# and .f files as C (default is Fortran), use: inc=Fortran f=C. +# +# Note: For files without extension you can use no_extension as a placeholder. +# +# Note that for custom extensions you also need to set FILE_PATTERNS otherwise +# the files are not read by doxygen. + +EXTENSION_MAPPING = + +# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments +# according to the Markdown format, which allows for more readable +# documentation. See http://daringfireball.net/projects/markdown/ for details. +# The output of markdown processing is further processed by doxygen, so you can +# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in +# case of backward compatibilities issues. +# The default value is: YES. + +MARKDOWN_SUPPORT = YES + +# When enabled doxygen tries to link words that correspond to documented +# classes, or namespaces to their corresponding documentation. Such a link can +# be prevented in individual cases by putting a % sign in front of the word or +# globally by setting AUTOLINK_SUPPORT to NO. +# The default value is: YES. + +AUTOLINK_SUPPORT = YES + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should set this +# tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); +# versus func(std::string) {}). This also make the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. +# The default value is: NO. + +BUILTIN_STL_SUPPORT = NO + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. +# The default value is: NO. + +CPP_CLI_SUPPORT = NO + +# Set the SIP_SUPPORT tag to YES if your project consists of sip (see: +# http://www.riverbankcomputing.co.uk/software/sip/intro) sources only. Doxygen +# will parse them like normal C++ but will assume all classes use public instead +# of private inheritance when no explicit protection keyword is present. +# The default value is: NO. + +SIP_SUPPORT = NO + +# For Microsoft's IDL there are propget and propput attributes to indicate +# getter and setter methods for a property. Setting this option to YES will make +# doxygen to replace the get and set methods by a property in the documentation. +# This will only work if the methods are indeed getting or setting a simple +# type. If this is not the case, or you want to show the methods anyway, you +# should set this option to NO. +# The default value is: YES. + +IDL_PROPERTY_SUPPORT = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. +# The default value is: NO. + +DISTRIBUTE_GROUP_DOC = NO + +# If one adds a struct or class to a group and this option is enabled, then also +# any nested class or struct is added to the same group. By default this option +# is disabled and one has to add nested compounds explicitly via \ingroup. +# The default value is: NO. + +GROUP_NESTED_COMPOUNDS = NO + +# Set the SUBGROUPING tag to YES to allow class member groups of the same type +# (for instance a group of public functions) to be put as a subgroup of that +# type (e.g. under the Public Functions section). Set it to NO to prevent +# subgrouping. Alternatively, this can be done per class using the +# \nosubgrouping command. +# The default value is: YES. + +SUBGROUPING = YES + +# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions +# are shown inside the group in which they are included (e.g. using \ingroup) +# instead of on a separate page (for HTML and Man pages) or section (for LaTeX +# and RTF). +# +# Note that this feature does not work in combination with +# SEPARATE_MEMBER_PAGES. +# The default value is: NO. + +INLINE_GROUPED_CLASSES = NO + +# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions +# with only public data fields or simple typedef fields will be shown inline in +# the documentation of the scope in which they are defined (i.e. file, +# namespace, or group documentation), provided this scope is documented. If set +# to NO, structs, classes, and unions are shown on a separate page (for HTML and +# Man pages) or section (for LaTeX and RTF). +# The default value is: NO. + +INLINE_SIMPLE_STRUCTS = NO + +# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or +# enum is documented as struct, union, or enum with the name of the typedef. So +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct +# with name TypeT. When disabled the typedef will appear as a member of a file, +# namespace, or class. And the struct will be named TypeS. This can typically be +# useful for C code in case the coding convention dictates that all compound +# types are typedef'ed and only the typedef is referenced, never the tag name. +# The default value is: NO. + +TYPEDEF_HIDES_STRUCT = NO + +# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This +# cache is used to resolve symbols given their name and scope. Since this can be +# an expensive process and often the same symbol appears multiple times in the +# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small +# doxygen will become slower. If the cache is too large, memory is wasted. The +# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range +# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536 +# symbols. At the end of a run doxygen will report the cache usage and suggest +# the optimal cache size from a speed point of view. +# Minimum value: 0, maximum value: 9, default value: 0. + +LOOKUP_CACHE_SIZE = 0 + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in +# documentation are documented, even if no documentation was available. Private +# class members and static file members will be hidden unless the +# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES. +# Note: This will also disable the warnings about undocumented members that are +# normally produced when WARNINGS is set to YES. +# The default value is: NO. + +EXTRACT_ALL = NO + +# If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will +# be included in the documentation. +# The default value is: NO. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal +# scope will be included in the documentation. +# The default value is: NO. + +EXTRACT_PACKAGE = NO + +# If the EXTRACT_STATIC tag is set to YES, all static members of a file will be +# included in the documentation. +# The default value is: NO. + +EXTRACT_STATIC = NO + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined +# locally in source files will be included in the documentation. If set to NO, +# only classes defined in header files are included. Does not have any effect +# for Java sources. +# The default value is: YES. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. If set to YES, local methods, +# which are defined in the implementation section but not in the interface are +# included in the documentation. If set to NO, only methods in the interface are +# included. +# The default value is: NO. + +EXTRACT_LOCAL_METHODS = NO + +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base name of +# the file that contains the anonymous namespace. By default anonymous namespace +# are hidden. +# The default value is: NO. + +EXTRACT_ANON_NSPACES = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all +# undocumented members inside documented classes or files. If set to NO these +# members will be included in the various overviews, but no documentation +# section is generated. This option has no effect if EXTRACT_ALL is enabled. +# The default value is: NO. + +HIDE_UNDOC_MEMBERS = YES + +# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. If set +# to NO, these classes will be included in the various overviews. This option +# has no effect if EXTRACT_ALL is enabled. +# The default value is: NO. + +HIDE_UNDOC_CLASSES = YES + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend +# (class|struct|union) declarations. If set to NO, these declarations will be +# included in the documentation. +# The default value is: NO. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any +# documentation blocks found inside the body of a function. If set to NO, these +# blocks will be appended to the function's detailed documentation block. +# The default value is: NO. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation that is typed after a +# \internal command is included. If the tag is set to NO then the documentation +# will be excluded. Set it to YES to include the internal documentation. +# The default value is: NO. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file +# names in lower-case letters. If set to YES, upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. +# The default value is: system dependent. + +CASE_SENSE_NAMES = NO + +# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with +# their full class and namespace scopes in the documentation. If set to YES, the +# scope will be hidden. +# The default value is: NO. + +HIDE_SCOPE_NAMES = NO + +# If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will +# append additional text to a page's title, such as Class Reference. If set to +# YES the compound reference will be hidden. +# The default value is: NO. + +HIDE_COMPOUND_REFERENCE= NO + +# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of +# the files that are included by a file in the documentation of that file. +# The default value is: YES. + +SHOW_INCLUDE_FILES = YES + +# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each +# grouped member an include statement to the documentation, telling the reader +# which file to include in order to use the member. +# The default value is: NO. + +SHOW_GROUPED_MEMB_INC = NO + +# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include +# files with double quotes in the documentation rather than with sharp brackets. +# The default value is: NO. + +FORCE_LOCAL_INCLUDES = NO + +# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the +# documentation for inline members. +# The default value is: YES. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the +# (detailed) documentation of file and class members alphabetically by member +# name. If set to NO, the members will appear in declaration order. +# The default value is: YES. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief +# descriptions of file, namespace and class members alphabetically by member +# name. If set to NO, the members will appear in declaration order. Note that +# this will also influence the order of the classes in the class list. +# The default value is: NO. + +SORT_BRIEF_DOCS = NO + +# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the +# (brief and detailed) documentation of class members so that constructors and +# destructors are listed first. If set to NO the constructors will appear in the +# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS. +# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief +# member documentation. +# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting +# detailed member documentation. +# The default value is: NO. + +SORT_MEMBERS_CTORS_1ST = NO + +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy +# of group names into alphabetical order. If set to NO the group names will +# appear in their defined order. +# The default value is: NO. + +SORT_GROUP_NAMES = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by +# fully-qualified names, including namespaces. If set to NO, the class list will +# be sorted only by class name, not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the alphabetical +# list. +# The default value is: NO. + +SORT_BY_SCOPE_NAME = NO + +# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper +# type resolution of all parameters of a function it will reject a match between +# the prototype and the implementation of a member function even if there is +# only one candidate or it is obvious which candidate to choose by doing a +# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still +# accept a match between prototype and implementation in such cases. +# The default value is: NO. + +STRICT_PROTO_MATCHING = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo +# list. This list is created by putting \todo commands in the documentation. +# The default value is: YES. + +GENERATE_TODOLIST = NO + +# The GENERATE_TESTLIST tag can be used to enable (YES) or disable (NO) the test +# list. This list is created by putting \test commands in the documentation. +# The default value is: YES. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or disable (NO) the bug +# list. This list is created by putting \bug commands in the documentation. +# The default value is: YES. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or disable (NO) +# the deprecated list. This list is created by putting \deprecated commands in +# the documentation. +# The default value is: YES. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional documentation +# sections, marked by \if ... \endif and \cond +# ... \endcond blocks. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the +# initial value of a variable or macro / define can have for it to appear in the +# documentation. If the initializer consists of more lines than specified here +# it will be hidden. Use a value of 0 to hide initializers completely. The +# appearance of the value of individual variables and macros / defines can be +# controlled using \showinitializer or \hideinitializer command in the +# documentation regardless of this setting. +# Minimum value: 0, maximum value: 10000, default value: 30. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at +# the bottom of the documentation of classes and structs. If set to YES, the +# list will mention the files that were used to generate the documentation. +# The default value is: YES. + +SHOW_USED_FILES = YES + +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This +# will remove the Files entry from the Quick Index and from the Folder Tree View +# (if specified). +# The default value is: YES. + +SHOW_FILES = YES + +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces +# page. This will remove the Namespaces entry from the Quick Index and from the +# Folder Tree View (if specified). +# The default value is: YES. + +SHOW_NAMESPACES = YES + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command command input-file, where command is the value of the +# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided +# by doxygen. Whatever the program writes to standard output is used as the file +# version. For an example see the documentation. + +FILE_VERSION_FILTER = + +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed +# by doxygen. The layout file controls the global structure of the generated +# output files in an output format independent way. To create the layout file +# that represents doxygen's defaults, run doxygen with the -l option. You can +# optionally specify a file name after the option, if omitted DoxygenLayout.xml +# will be used as the name of the layout file. +# +# Note that if you run doxygen from a directory containing a file called +# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE +# tag is left empty. + +LAYOUT_FILE = + +# The CITE_BIB_FILES tag can be used to specify one or more bib files containing +# the reference definitions. This must be a list of .bib files. The .bib +# extension is automatically appended if omitted. This requires the bibtex tool +# to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info. +# For LaTeX the style of the bibliography can be controlled using +# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the +# search path. See also \cite for info how to create references. + +CITE_BIB_FILES = + +#--------------------------------------------------------------------------- +# Configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated to +# standard output by doxygen. If QUIET is set to YES this implies that the +# messages are off. +# The default value is: NO. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated to standard error (stderr) by doxygen. If WARNINGS is set to YES +# this implies that the warnings are on. +# +# Tip: Turn warnings on while writing the documentation. +# The default value is: YES. + +WARNINGS = YES + +# If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate +# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag +# will automatically be disabled. +# The default value is: YES. + +WARN_IF_UNDOCUMENTED = YES + +# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some parameters +# in a documented function, or documenting parameters that don't exist or using +# markup commands wrongly. +# The default value is: YES. + +WARN_IF_DOC_ERROR = YES + +# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that +# are documented, but have no documentation for their parameters or return +# value. If set to NO, doxygen will only warn about wrong or incomplete +# parameter documentation, but not about the absence of documentation. +# The default value is: NO. + +WARN_NO_PARAMDOC = NO + +# If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when +# a warning is encountered. +# The default value is: NO. + +WARN_AS_ERROR = NO + +# The WARN_FORMAT tag determines the format of the warning messages that doxygen +# can produce. The string should contain the $file, $line, and $text tags, which +# will be replaced by the file and line number from which the warning originated +# and the warning text. Optionally the format may contain $version, which will +# be replaced by the version of the file (if it could be obtained via +# FILE_VERSION_FILTER) +# The default value is: $file:$line: $text. + +WARN_FORMAT = "$file:$line: $text " + +# The WARN_LOGFILE tag can be used to specify a file to which warning and error +# messages should be written. If left blank the output is written to standard +# error (stderr). + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# Configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag is used to specify the files and/or directories that contain +# documented source files. You may enter file names like myfile.cpp or +# directories like /usr/src/myproject. Separate the files or directories with +# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING +# Note: If this tag is empty the current directory is searched. + +INPUT = ../../src main_page.h + +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses +# libiconv (or the iconv built into libc) for the transcoding. See the libiconv +# documentation (see: http://www.gnu.org/software/libiconv) for the list of +# possible encodings. +# The default value is: UTF-8. + +INPUT_ENCODING = UTF-8 + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and +# *.h) to filter out the source-files in the directories. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# read by doxygen. +# +# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp, +# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, +# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, +# *.m, *.markdown, *.md, *.mm, *.dox, *.py, *.pyw, *.f90, *.f, *.for, *.tcl, +# *.vhd, *.vhdl, *.ucf, *.qsf, *.as and *.js. + +FILE_PATTERNS = *.c \ + *.cc \ + *.cxx \ + *.cpp \ + *.c++ \ + *.java \ + *.ii \ + *.ixx \ + *.ipp \ + *.i++ \ + *.inl \ + *.h \ + *.hh \ + *.hxx \ + *.hpp \ + *.h++ \ + *.idl \ + *.odl \ + *.inc \ + *.m \ + *.mm \ + *.dox + +# The RECURSIVE tag can be used to specify whether or not subdirectories should +# be searched for input files as well. +# The default value is: NO. + +RECURSIVE = YES + +# The EXCLUDE tag can be used to specify files and/or directories that should be +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. +# +# Note that relative paths are relative to the directory from which doxygen is +# run. + +EXCLUDE = ../../src/include/netif/ppp/polarssl + +# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or +# directories that are symbolic links (a Unix file system feature) are excluded +# from the input. +# The default value is: NO. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. +# +# Note that the wildcards are matched against the file with absolute path, so to +# exclude all test directories for example use the pattern */test/* + +EXCLUDE_PATTERNS = + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, +# AClass::ANamespace, ANamespace::*Test +# +# Note that the wildcards are matched against the file with absolute path, so to +# exclude all test directories use the pattern */test/* + +EXCLUDE_SYMBOLS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or directories +# that contain example code fragments that are included (see the \include +# command). + +EXAMPLE_PATH = ../ ../../ + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and +# *.h) to filter out the source-files in the directories. If left blank all +# files are included. + +EXAMPLE_PATTERNS = * + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude commands +# irrespective of the value of the RECURSIVE tag. +# The default value is: NO. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or directories +# that contain images that are to be included in the documentation (see the +# \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command: +# +# +# +# where is the value of the INPUT_FILTER tag, and is the +# name of an input file. Doxygen will then use the output that the filter +# program writes to standard output. If FILTER_PATTERNS is specified, this tag +# will be ignored. +# +# Note that the filter must not add or remove lines; it is applied before the +# code is scanned, but not when the output code is generated. If lines are added +# or removed, the anchors will not be placed correctly. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# properly processed by doxygen. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: pattern=filter +# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how +# filters are used. If the FILTER_PATTERNS tag is empty or if none of the +# patterns match the file name, INPUT_FILTER is applied. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# properly processed by doxygen. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will also be used to filter the input files that are used for +# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES). +# The default value is: NO. + +FILTER_SOURCE_FILES = NO + +# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file +# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and +# it is also possible to disable source filtering for a specific pattern using +# *.ext= (so without naming a filter). +# This tag requires that the tag FILTER_SOURCE_FILES is set to YES. + +FILTER_SOURCE_PATTERNS = + +# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that +# is part of the input, its contents will be placed on the main page +# (index.html). This can be useful if you have a project on for instance GitHub +# and want to reuse the introduction page also for the doxygen output. + +USE_MDFILE_AS_MAINPAGE = main_page.h + +#--------------------------------------------------------------------------- +# Configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will be +# generated. Documented entities will be cross-referenced with these sources. +# +# Note: To get rid of all source code in the generated output, make sure that +# also VERBATIM_HEADERS is set to NO. +# The default value is: NO. + +SOURCE_BROWSER = NO + +# Setting the INLINE_SOURCES tag to YES will include the body of functions, +# classes and enums directly into the documentation. +# The default value is: NO. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any +# special comment blocks from generated source code fragments. Normal C, C++ and +# Fortran comments will always remain visible. +# The default value is: YES. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES then for each documented +# function all documented functions referencing it will be listed. +# The default value is: NO. + +REFERENCED_BY_RELATION = NO + +# If the REFERENCES_RELATION tag is set to YES then for each documented function +# all documented entities called/used by that function will be listed. +# The default value is: NO. + +REFERENCES_RELATION = NO + +# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set +# to YES then the hyperlinks from functions in REFERENCES_RELATION and +# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will +# link to the documentation. +# The default value is: YES. + +REFERENCES_LINK_SOURCE = YES + +# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the +# source code will show a tooltip with additional information such as prototype, +# brief description and links to the definition and documentation. Since this +# will make the HTML file larger and loading of large files a bit slower, you +# can opt to disable this feature. +# The default value is: YES. +# This tag requires that the tag SOURCE_BROWSER is set to YES. + +SOURCE_TOOLTIPS = YES + +# If the USE_HTAGS tag is set to YES then the references to source code will +# point to the HTML generated by the htags(1) tool instead of doxygen built-in +# source browser. The htags tool is part of GNU's global source tagging system +# (see http://www.gnu.org/software/global/global.html). You will need version +# 4.8.6 or higher. +# +# To use it do the following: +# - Install the latest version of global +# - Enable SOURCE_BROWSER and USE_HTAGS in the config file +# - Make sure the INPUT points to the root of the source tree +# - Run doxygen as normal +# +# Doxygen will invoke htags (and that will in turn invoke gtags), so these +# tools must be available from the command line (i.e. in the search path). +# +# The result: instead of the source browser generated by doxygen, the links to +# source code will now point to the output of htags. +# The default value is: NO. +# This tag requires that the tag SOURCE_BROWSER is set to YES. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a +# verbatim copy of the header file for each class for which an include is +# specified. Set to NO to disable this. +# See also: Section \class. +# The default value is: YES. + +VERBATIM_HEADERS = NO + +# If the CLANG_ASSISTED_PARSING tag is set to YES then doxygen will use the +# clang parser (see: http://clang.llvm.org/) for more accurate parsing at the +# cost of reduced performance. This can be particularly helpful with template +# rich C++ code for which doxygen's built-in parser lacks the necessary type +# information. +# Note: The availability of this option depends on whether or not doxygen was +# generated with the -Duse-libclang=ON option for CMake. +# The default value is: NO. + +CLANG_ASSISTED_PARSING = NO + +# If clang assisted parsing is enabled you can provide the compiler with command +# line options that you would normally use when invoking the compiler. Note that +# the include paths will already be set by doxygen for the files and directories +# specified with INPUT and INCLUDE_PATH. +# This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES. + +CLANG_OPTIONS = + +#--------------------------------------------------------------------------- +# Configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all +# compounds will be generated. Enable this if the project contains a lot of +# classes, structs, unions or interfaces. +# The default value is: YES. + +ALPHABETICAL_INDEX = NO + +# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in +# which the alphabetical index list will be split. +# Minimum value: 1, maximum value: 20, default value: 5. +# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all classes will +# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag +# can be used to specify a prefix (or a list of prefixes) that should be ignored +# while generating the index headers. +# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output +# The default value is: YES. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a +# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of +# it. +# The default directory is: html. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each +# generated HTML page (for example: .htm, .php, .asp). +# The default value is: .html. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a user-defined HTML header file for +# each generated HTML page. If the tag is left blank doxygen will generate a +# standard header. +# +# To get valid HTML the header file that includes any scripts and style sheets +# that doxygen needs, which is dependent on the configuration options used (e.g. +# the setting GENERATE_TREEVIEW). It is highly recommended to start with a +# default header using +# doxygen -w html new_header.html new_footer.html new_stylesheet.css +# YourConfigFile +# and then modify the file new_header.html. See also section "Doxygen usage" +# for information on how to generate the default header that doxygen normally +# uses. +# Note: The header is subject to change so you typically have to regenerate the +# default header when upgrading to a newer version of doxygen. For a description +# of the possible markers and block names see the documentation. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each +# generated HTML page. If the tag is left blank doxygen will generate a standard +# footer. See HTML_HEADER for more information on how to generate a default +# footer and what special commands can be used inside the footer. See also +# section "Doxygen usage" for information on how to generate the default footer +# that doxygen normally uses. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style +# sheet that is used by each HTML page. It can be used to fine-tune the look of +# the HTML output. If left blank doxygen will generate a default style sheet. +# See also section "Doxygen usage" for information on how to generate the style +# sheet that doxygen normally uses. +# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as +# it is more robust and this tag (HTML_STYLESHEET) will in the future become +# obsolete. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_STYLESHEET = + +# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined +# cascading style sheets that are included after the standard style sheets +# created by doxygen. Using this option one can overrule certain style aspects. +# This is preferred over using HTML_STYLESHEET since it does not replace the +# standard style sheet and is therefore more robust against future updates. +# Doxygen will copy the style sheet files to the output directory. +# Note: The order of the extra style sheet files is of importance (e.g. the last +# style sheet in the list overrules the setting of the previous ones in the +# list). For an example see the documentation. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_EXTRA_STYLESHEET = + +# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or +# other source files which should be copied to the HTML output directory. Note +# that these files will be copied to the base HTML output directory. Use the +# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these +# files. In the HTML_STYLESHEET file, use the file name only. Also note that the +# files will be copied as-is; there are no commands or markers available. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_EXTRA_FILES = + +# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen +# will adjust the colors in the style sheet and background images according to +# this color. Hue is specified as an angle on a colorwheel, see +# http://en.wikipedia.org/wiki/Hue for more information. For instance the value +# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300 +# purple, and 360 is red again. +# Minimum value: 0, maximum value: 359, default value: 220. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_HUE = 220 + +# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors +# in the HTML output. For a value of 0 the output will use grayscales only. A +# value of 255 will produce the most vivid colors. +# Minimum value: 0, maximum value: 255, default value: 100. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_SAT = 100 + +# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the +# luminance component of the colors in the HTML output. Values below 100 +# gradually make the output lighter, whereas values above 100 make the output +# darker. The value divided by 100 is the actual gamma applied, so 80 represents +# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not +# change the gamma. +# Minimum value: 40, maximum value: 240, default value: 80. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_GAMMA = 80 + +# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML +# page will contain the date and time when the page was generated. Setting this +# to YES can help to show when doxygen was last run and thus if the +# documentation is up to date. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_TIMESTAMP = NO + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_DYNAMIC_SECTIONS = NO + +# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries +# shown in the various tree structured indices initially; the user can expand +# and collapse entries dynamically later on. Doxygen will expand the tree to +# such a level that at most the specified number of entries are visible (unless +# a fully collapsed tree already exceeds this amount). So setting the number of +# entries 1 will produce a full collapsed tree by default. 0 is a special value +# representing an infinite number of entries and will result in a full expanded +# tree by default. +# Minimum value: 0, maximum value: 9999, default value: 100. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_INDEX_NUM_ENTRIES = 100 + +# If the GENERATE_DOCSET tag is set to YES, additional index files will be +# generated that can be used as input for Apple's Xcode 3 integrated development +# environment (see: http://developer.apple.com/tools/xcode/), introduced with +# OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a +# Makefile in the HTML output directory. Running make will produce the docset in +# that directory and running make install will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at +# startup. See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html +# for more information. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_DOCSET = NO + +# This tag determines the name of the docset feed. A documentation feed provides +# an umbrella under which multiple documentation sets from a single provider +# (such as a company or product suite) can be grouped. +# The default value is: Doxygen generated docs. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_FEEDNAME = "Doxygen generated docs" + +# This tag specifies a string that should uniquely identify the documentation +# set bundle. This should be a reverse domain-name style string, e.g. +# com.mycompany.MyDocSet. Doxygen will append .docset to the name. +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_BUNDLE_ID = org.doxygen.Project + +# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify +# the documentation publisher. This should be a reverse domain-name style +# string, e.g. com.mycompany.MyDocSet.documentation. +# The default value is: org.doxygen.Publisher. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_PUBLISHER_ID = org.doxygen.Publisher + +# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher. +# The default value is: Publisher. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_PUBLISHER_NAME = Publisher + +# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three +# additional HTML index files: index.hhp, index.hhc, and index.hhk. The +# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop +# (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on +# Windows. +# +# The HTML Help Workshop contains a compiler that can convert all HTML output +# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML +# files are now used as the Windows 98 help format, and will replace the old +# Windows help format (.hlp) on all Windows platforms in the future. Compressed +# HTML files also contain an index, a table of contents, and you can search for +# words in the documentation. The HTML workshop also contains a viewer for +# compressed HTML files. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_HTMLHELP = NO + +# The CHM_FILE tag can be used to specify the file name of the resulting .chm +# file. You can add a path in front of the file if the result should not be +# written to the html output directory. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +CHM_FILE = lwip.chm + +# The HHC_LOCATION tag can be used to specify the location (absolute path +# including file name) of the HTML help compiler (hhc.exe). If non-empty, +# doxygen will try to run the HTML help compiler on the generated index.hhp. +# The file has to be specified with full path. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +HHC_LOCATION = + +# The GENERATE_CHI flag controls if a separate .chi index file is generated +# (YES) or that it should be included in the master .chm file (NO). +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +GENERATE_CHI = NO + +# The CHM_INDEX_ENCODING is used to encode HtmlHelp index (hhk), content (hhc) +# and project file content. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +CHM_INDEX_ENCODING = + +# The BINARY_TOC flag controls whether a binary table of contents is generated +# (YES) or a normal table of contents (NO) in the .chm file. Furthermore it +# enables the Previous and Next buttons. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members to +# the table of contents of the HTML help documentation and to the tree view. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +TOC_EXPAND = NO + +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and +# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that +# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help +# (.qch) of the generated HTML documentation. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_QHP = NO + +# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify +# the file name of the resulting .qch file. The path specified is relative to +# the HTML output folder. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QCH_FILE = + +# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help +# Project output. For more information please see Qt Help Project / Namespace +# (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#namespace). +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_NAMESPACE = org.doxygen.Project + +# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt +# Help Project output. For more information please see Qt Help Project / Virtual +# Folders (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#virtual- +# folders). +# The default value is: doc. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_VIRTUAL_FOLDER = doc + +# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom +# filter to add. For more information please see Qt Help Project / Custom +# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom- +# filters). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_CUST_FILTER_NAME = + +# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the +# custom filter to add. For more information please see Qt Help Project / Custom +# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom- +# filters). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_CUST_FILTER_ATTRS = + +# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this +# project's filter section matches. Qt Help Project / Filter Attributes (see: +# http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_SECT_FILTER_ATTRS = + +# The QHG_LOCATION tag can be used to specify the location of Qt's +# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the +# generated .qhp file. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHG_LOCATION = + +# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be +# generated, together with the HTML files, they form an Eclipse help plugin. To +# install this plugin and make it available under the help contents menu in +# Eclipse, the contents of the directory containing the HTML and XML files needs +# to be copied into the plugins directory of eclipse. The name of the directory +# within the plugins directory should be the same as the ECLIPSE_DOC_ID value. +# After copying Eclipse needs to be restarted before the help appears. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_ECLIPSEHELP = NO + +# A unique identifier for the Eclipse help plugin. When installing the plugin +# the directory name containing the HTML and XML files should also have this +# name. Each documentation set should have its own identifier. +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES. + +ECLIPSE_DOC_ID = org.doxygen.Project + +# If you want full control over the layout of the generated HTML pages it might +# be necessary to disable the index and replace it with your own. The +# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top +# of each HTML page. A value of NO enables the index and the value YES disables +# it. Since the tabs in the index contain the same information as the navigation +# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +DISABLE_INDEX = NO + +# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index +# structure should be generated to display hierarchical information. If the tag +# value is set to YES, a side panel will be generated containing a tree-like +# index structure (just like the one that is generated for HTML Help). For this +# to work a browser that supports JavaScript, DHTML, CSS and frames is required +# (i.e. any modern browser). Windows users are probably better off using the +# HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can +# further fine-tune the look of the index. As an example, the default style +# sheet generated by doxygen has an example that shows how to put an image at +# the root of the tree instead of the PROJECT_NAME. Since the tree basically has +# the same information as the tab index, you could consider setting +# DISABLE_INDEX to YES when enabling this option. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_TREEVIEW = YES + +# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that +# doxygen will group on one line in the generated HTML documentation. +# +# Note that a value of 0 will completely suppress the enum values from appearing +# in the overview section. +# Minimum value: 0, maximum value: 20, default value: 4. +# This tag requires that the tag GENERATE_HTML is set to YES. + +ENUM_VALUES_PER_LINE = 4 + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used +# to set the initial width (in pixels) of the frame in which the tree is shown. +# Minimum value: 0, maximum value: 1500, default value: 250. +# This tag requires that the tag GENERATE_HTML is set to YES. + +TREEVIEW_WIDTH = 250 + +# If the EXT_LINKS_IN_WINDOW option is set to YES, doxygen will open links to +# external symbols imported via tag files in a separate window. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +EXT_LINKS_IN_WINDOW = NO + +# Use this tag to change the font size of LaTeX formulas included as images in +# the HTML documentation. When you change the font size after a successful +# doxygen run you need to manually remove any form_*.png images from the HTML +# output directory to force them to be regenerated. +# Minimum value: 8, maximum value: 50, default value: 10. +# This tag requires that the tag GENERATE_HTML is set to YES. + +FORMULA_FONTSIZE = 10 + +# Use the FORMULA_TRANPARENT tag to determine whether or not the images +# generated for formulas are transparent PNGs. Transparent PNGs are not +# supported properly for IE 6.0, but are supported on all modern browsers. +# +# Note that when changing this option you need to delete any form_*.png files in +# the HTML output directory before the changes have effect. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +FORMULA_TRANSPARENT = YES + +# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see +# http://www.mathjax.org) which uses client side Javascript for the rendering +# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX +# installed or if you want to formulas look prettier in the HTML output. When +# enabled you may also need to install MathJax separately and configure the path +# to it using the MATHJAX_RELPATH option. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +USE_MATHJAX = NO + +# When MathJax is enabled you can set the default output format to be used for +# the MathJax output. See the MathJax site (see: +# http://docs.mathjax.org/en/latest/output.html) for more details. +# Possible values are: HTML-CSS (which is slower, but has the best +# compatibility), NativeMML (i.e. MathML) and SVG. +# The default value is: HTML-CSS. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_FORMAT = HTML-CSS + +# When MathJax is enabled you need to specify the location relative to the HTML +# output directory using the MATHJAX_RELPATH option. The destination directory +# should contain the MathJax.js script. For instance, if the mathjax directory +# is located at the same level as the HTML output directory, then +# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax +# Content Delivery Network so you can quickly see the result without installing +# MathJax. However, it is strongly recommended to install a local copy of +# MathJax from http://www.mathjax.org before deployment. +# The default value is: http://cdn.mathjax.org/mathjax/latest. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest + +# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax +# extension names that should be enabled during MathJax rendering. For example +# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_EXTENSIONS = + +# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces +# of code that will be used on startup of the MathJax code. See the MathJax site +# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an +# example see the documentation. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_CODEFILE = + +# When the SEARCHENGINE tag is enabled doxygen will generate a search box for +# the HTML output. The underlying search engine uses javascript and DHTML and +# should work on any modern browser. Note that when using HTML help +# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET) +# there is already a search function so this one should typically be disabled. +# For large projects the javascript based search engine can be slow, then +# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to +# search using the keyboard; to jump to the search box use + S +# (what the is depends on the OS and browser, but it is typically +# , /