mirror of
https://git.savannah.nongnu.org/git/lwip.git
synced 2025-08-06 22:44:38 +08:00
pcapif: add option PCAPIF_RX_READONLY to simulate readonly RX
This uses VirtualAlloc/VirtualProtect on windows to simulate RX buffers that are readonly to lwIP (see task #14807). Signed-off-by: Simon Goldschmidt <goldsimon@gmx.de>
This commit is contained in:
parent
ea9726056c
commit
04cf6bbe66
@ -113,6 +113,8 @@
|
|||||||
|
|
||||||
/** If 1, use PBUF_REF for RX (for testing purposes mainly).
|
/** If 1, use PBUF_REF for RX (for testing purposes mainly).
|
||||||
* For this, LWIP_SUPPORT_CUSTOM_PBUF must be enabled.
|
* For this, LWIP_SUPPORT_CUSTOM_PBUF must be enabled.
|
||||||
|
* Also, PBUF_POOL_BUFSIZE must be set high enough to ensure all rx packets
|
||||||
|
* fit into a single pbuf.
|
||||||
*/
|
*/
|
||||||
#ifndef PCAPIF_RX_REF
|
#ifndef PCAPIF_RX_REF
|
||||||
#define PCAPIF_RX_REF 0
|
#define PCAPIF_RX_REF 0
|
||||||
@ -127,6 +129,13 @@
|
|||||||
#define PCAPIF_GET_STATE_PTR(netif) ((netif)->state)
|
#define PCAPIF_GET_STATE_PTR(netif) ((netif)->state)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/** Define this to 1 to allocate readonly pbufs for RX (needs PCAPIF_RX_REF,
|
||||||
|
* only implemented for windows, for now)
|
||||||
|
*/
|
||||||
|
#ifndef PCAPIF_RX_READONLY
|
||||||
|
#define PCAPIF_RX_READONLY 0
|
||||||
|
#endif
|
||||||
|
|
||||||
#if PCAPIF_HANDLE_LINKSTATE
|
#if PCAPIF_HANDLE_LINKSTATE
|
||||||
#include "pcapif_helper.h"
|
#include "pcapif_helper.h"
|
||||||
|
|
||||||
@ -320,7 +329,11 @@ pcaipf_is_tx_packet(struct netif *netif, const void *packet, int packet_len)
|
|||||||
struct pcapif_pbuf_custom
|
struct pcapif_pbuf_custom
|
||||||
{
|
{
|
||||||
struct pbuf_custom pc;
|
struct pbuf_custom pc;
|
||||||
|
#if PCAPIF_RX_READONLY
|
||||||
|
void *ro_mem;
|
||||||
|
#else
|
||||||
struct pbuf* p;
|
struct pbuf* p;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
#endif /* PCAPIF_RX_REF */
|
#endif /* PCAPIF_RX_REF */
|
||||||
|
|
||||||
@ -961,9 +974,15 @@ pcapif_rx_pbuf_free_custom(struct pbuf *p)
|
|||||||
struct pcapif_pbuf_custom* ppc;
|
struct pcapif_pbuf_custom* ppc;
|
||||||
LWIP_ASSERT("NULL pointer", p != NULL);
|
LWIP_ASSERT("NULL pointer", p != NULL);
|
||||||
ppc = (struct pcapif_pbuf_custom*)p;
|
ppc = (struct pcapif_pbuf_custom*)p;
|
||||||
|
#if PCAPIF_RX_READONLY
|
||||||
|
LWIP_ASSERT("NULL pointer", ppc->ro_mem != NULL);
|
||||||
|
pcapifh_free_readonly_mem(ppc->ro_mem);
|
||||||
|
ppc->ro_mem = NULL;
|
||||||
|
#else
|
||||||
LWIP_ASSERT("NULL pointer", ppc->p != NULL);
|
LWIP_ASSERT("NULL pointer", ppc->p != NULL);
|
||||||
pbuf_free(ppc->p);
|
pbuf_free(ppc->p);
|
||||||
ppc->p = NULL;
|
ppc->p = NULL;
|
||||||
|
#endif
|
||||||
mem_free(p);
|
mem_free(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -972,6 +991,8 @@ pcapif_rx_ref(struct pbuf* p)
|
|||||||
{
|
{
|
||||||
struct pcapif_pbuf_custom* ppc;
|
struct pcapif_pbuf_custom* ppc;
|
||||||
struct pbuf* q;
|
struct pbuf* q;
|
||||||
|
u16_t len;
|
||||||
|
void *payload_mem;
|
||||||
|
|
||||||
LWIP_ASSERT("NULL pointer", p != NULL);
|
LWIP_ASSERT("NULL pointer", p != NULL);
|
||||||
LWIP_ASSERT("chained pbuf not supported here", p->next == NULL);
|
LWIP_ASSERT("chained pbuf not supported here", p->next == NULL);
|
||||||
@ -979,9 +1000,18 @@ pcapif_rx_ref(struct pbuf* p)
|
|||||||
ppc = (struct pcapif_pbuf_custom*)mem_malloc(sizeof(struct pcapif_pbuf_custom));
|
ppc = (struct pcapif_pbuf_custom*)mem_malloc(sizeof(struct pcapif_pbuf_custom));
|
||||||
LWIP_ASSERT("out of memory for RX", ppc != NULL);
|
LWIP_ASSERT("out of memory for RX", ppc != NULL);
|
||||||
ppc->pc.custom_free_function = pcapif_rx_pbuf_free_custom;
|
ppc->pc.custom_free_function = pcapif_rx_pbuf_free_custom;
|
||||||
|
len = p->tot_len;
|
||||||
|
#if PCAPIF_RX_READONLY
|
||||||
|
payload_mem = pcapifh_alloc_readonly_copy(p->payload, len);
|
||||||
|
LWIP_ASSERT("out of readonly memory for RX", payload_mem != NULL);
|
||||||
|
pbuf_free(p);
|
||||||
|
ppc->ro_mem = payload_mem;
|
||||||
|
#else
|
||||||
ppc->p = p;
|
ppc->p = p;
|
||||||
|
payload_mem = p->payload;
|
||||||
|
#endif
|
||||||
|
|
||||||
q = pbuf_alloced_custom(PBUF_RAW, p->tot_len, PBUF_REF, &ppc->pc, p->payload, p->tot_len);
|
q = pbuf_alloced_custom(PBUF_RAW, len, PBUF_REF, &ppc->pc, payload_mem, len);
|
||||||
LWIP_ASSERT("pbuf_alloced_custom returned NULL", q != NULL);
|
LWIP_ASSERT("pbuf_alloced_custom returned NULL", q != NULL);
|
||||||
return q;
|
return q;
|
||||||
}
|
}
|
||||||
|
@ -78,6 +78,43 @@ void pcapifh_linkstate_close(struct pcapifh_linkstate* state)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Helper function for PCAPIF_RX_READONLY for windows: copy the date to a new
|
||||||
|
* page which is set to READONLY after copying.
|
||||||
|
* This is a helper to simulate hardware that receives to memory that cannot be
|
||||||
|
* written by the CPU.
|
||||||
|
*/
|
||||||
|
void *
|
||||||
|
pcapifh_alloc_readonly_copy(void *data, size_t len)
|
||||||
|
{
|
||||||
|
DWORD oldProtect;
|
||||||
|
void *ret;
|
||||||
|
if (len > 4096) {
|
||||||
|
lwip_win32_platform_diag("pcapifh_alloc_readonly_copy: invalid len: %d\n", len);
|
||||||
|
while(1);
|
||||||
|
}
|
||||||
|
ret = VirtualAlloc(NULL, 4096, MEM_COMMIT, PAGE_READWRITE);
|
||||||
|
if (ret == NULL) {
|
||||||
|
lwip_win32_platform_diag("VirtualAlloc failed: %d\n", GetLastError());
|
||||||
|
while(1);
|
||||||
|
}
|
||||||
|
memcpy(ret, data, len);
|
||||||
|
if (!VirtualProtect(ret, len, PAGE_READONLY, &oldProtect)) {
|
||||||
|
lwip_win32_platform_diag("VirtualProtect failed: %d\n", GetLastError());
|
||||||
|
while(1);
|
||||||
|
}
|
||||||
|
printf("pcapifh_alloc_readonly_copy(%d): 0x%08x\n", len, ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
pcapifh_free_readonly_mem(void *data)
|
||||||
|
{
|
||||||
|
if (!VirtualFree(data, 0, MEM_RELEASE)) {
|
||||||
|
lwip_win32_platform_diag("VirtualFree(0x%08x) failed: %d\n", data, GetLastError());
|
||||||
|
while(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#else /* WIN32 */
|
#else /* WIN32 */
|
||||||
|
|
||||||
/* @todo: add linux/unix implementation? */
|
/* @todo: add linux/unix implementation? */
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
#ifndef LWIP_PCAPIF_HELPER_H
|
#ifndef LWIP_PCAPIF_HELPER_H
|
||||||
#define LWIP_PCAPIF_HELPER_H
|
#define LWIP_PCAPIF_HELPER_H
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
@ -17,6 +19,8 @@ struct pcapifh_linkstate* pcapifh_linkstate_init(char *adapter_name);
|
|||||||
enum pcapifh_link_event pcapifh_linkstate_get(struct pcapifh_linkstate* state);
|
enum pcapifh_link_event pcapifh_linkstate_get(struct pcapifh_linkstate* state);
|
||||||
void pcapifh_linkstate_close(struct pcapifh_linkstate* state);
|
void pcapifh_linkstate_close(struct pcapifh_linkstate* state);
|
||||||
|
|
||||||
|
void *pcapifh_alloc_readonly_copy(void *data, size_t len);
|
||||||
|
void pcapifh_free_readonly_mem(void *data);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user