net/icpmv4: Add dynamically registered ICMPv4 handlers
As it is done for ICMPv6. This will prove to be useful for implementing an echo reply handler in a ping for instance. Change-Id: I969a1da60f2a4ea59eee5c9983eb6e340923e2ef Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
This commit is contained in:
parent
1d361b0507
commit
19af4eee4f
3 changed files with 63 additions and 20 deletions
|
@ -24,6 +24,8 @@
|
|||
|
||||
#define BUF_WAIT_TIME K_SECONDS(1)
|
||||
|
||||
static sys_slist_t handlers;
|
||||
|
||||
static inline enum net_verdict handle_echo_request(struct net_buf *buf)
|
||||
{
|
||||
/* Note that we send the same data buffers back and just swap
|
||||
|
@ -161,24 +163,6 @@ int net_icmpv4_send_echo_request(struct net_if *iface,
|
|||
return -EIO;
|
||||
}
|
||||
|
||||
enum net_verdict net_icmpv4_input(struct net_buf *buf, uint16_t len,
|
||||
uint8_t type, uint8_t code)
|
||||
{
|
||||
ARG_UNUSED(code);
|
||||
ARG_UNUSED(len);
|
||||
|
||||
net_stats_update_icmp_recv();
|
||||
|
||||
switch (type) {
|
||||
case NET_ICMPV4_ECHO_REQUEST:
|
||||
return handle_echo_request(buf);
|
||||
}
|
||||
|
||||
net_stats_update_icmp_drop();
|
||||
|
||||
return NET_DROP;
|
||||
}
|
||||
|
||||
int net_icmpv4_send_error(struct net_buf *orig, uint8_t type, uint8_t code)
|
||||
{
|
||||
struct net_buf *buf, *frag;
|
||||
|
@ -283,3 +267,44 @@ drop_no_buf:
|
|||
|
||||
return err;
|
||||
}
|
||||
|
||||
void net_icmpv4_register_handler(struct net_icmpv4_handler *handler)
|
||||
{
|
||||
sys_slist_prepend(&handlers, &handler->node);
|
||||
}
|
||||
|
||||
void net_icmpv4_unregister_handler(struct net_icmpv4_handler *handler)
|
||||
{
|
||||
sys_slist_find_and_remove(&handlers, &handler->node);
|
||||
}
|
||||
|
||||
enum net_verdict net_icmpv4_input(struct net_buf *buf, uint16_t len,
|
||||
uint8_t type, uint8_t code)
|
||||
{
|
||||
struct net_icmpv4_handler *cb;
|
||||
|
||||
ARG_UNUSED(len);
|
||||
|
||||
net_stats_update_icmp_recv();
|
||||
|
||||
SYS_SLIST_FOR_EACH_CONTAINER(&handlers, cb, node) {
|
||||
if (cb->type == type && (cb->code == code || cb->code == 0)) {
|
||||
return cb->handler(buf);
|
||||
}
|
||||
}
|
||||
|
||||
net_stats_update_icmp_drop();
|
||||
|
||||
return NET_DROP;
|
||||
}
|
||||
|
||||
static struct net_icmpv4_handler echo_request_handler = {
|
||||
.type = NET_ICMPV4_ECHO_REQUEST,
|
||||
.code = 0,
|
||||
.handler = handle_echo_request,
|
||||
};
|
||||
|
||||
void net_icmpv4_init(void)
|
||||
{
|
||||
net_icmpv4_register_handler(&echo_request_handler);
|
||||
}
|
||||
|
|
|
@ -34,6 +34,15 @@ struct net_icmpv4_echo_req {
|
|||
((struct net_icmpv4_echo_req *)(net_nbuf_icmp_data(buf) + \
|
||||
sizeof(struct net_icmp_hdr)))
|
||||
|
||||
typedef enum net_verdict (*icmpv4_callback_handler_t)(struct net_buf *buf);
|
||||
|
||||
struct net_icmpv4_handler {
|
||||
sys_snode_t node;
|
||||
uint8_t type;
|
||||
uint8_t code;
|
||||
icmpv4_callback_handler_t handler;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Send ICMPv4 error message.
|
||||
* @param buf Network buffer that this error is related to.
|
||||
|
@ -60,7 +69,17 @@ int net_icmpv4_send_echo_request(struct net_if *iface,
|
|||
uint16_t identifier,
|
||||
uint16_t sequence);
|
||||
|
||||
void net_icmpv4_register_handler(struct net_icmpv4_handler *handler);
|
||||
|
||||
void net_icmpv4_unregister_handler(struct net_icmpv4_handler *handler);
|
||||
|
||||
enum net_verdict net_icmpv4_input(struct net_buf *buf, uint16_t len,
|
||||
uint8_t type, uint8_t code);
|
||||
|
||||
#if defined(CONFIG_NET_IPV4)
|
||||
void net_icmpv4_init(void);
|
||||
#else
|
||||
#define net_icmpv4_init(...)
|
||||
#endif
|
||||
|
||||
#endif /* __ICMPV4_H */
|
||||
|
|
|
@ -35,9 +35,7 @@
|
|||
#include "icmpv6.h"
|
||||
#include "ipv6.h"
|
||||
|
||||
#if defined(CONFIG_NET_IPV4)
|
||||
#include "icmpv4.h"
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_NET_DHCPV4)
|
||||
#include "dhcpv4.h"
|
||||
|
@ -757,6 +755,7 @@ int net_recv_data(struct net_if *iface, struct net_buf *buf)
|
|||
|
||||
static inline void l3_init(void)
|
||||
{
|
||||
net_icmpv4_init();
|
||||
net_icmpv6_init();
|
||||
net_ipv6_init();
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue