net: Process received ICMPv4 messages

Call ICMPv4 handler when receiving ICMP v4 packet.
Currently only echo-request msg is handled.

Change-Id: Ib59c65b38f13c484f1842485118dad32fb6a6f36
Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
This commit is contained in:
Jukka Rissanen 2016-05-19 16:19:59 +03:00
commit b6a7648569
7 changed files with 155 additions and 7 deletions

View file

@ -44,6 +44,7 @@ extern "C" {
/** Protocol numbers from IANA */ /** Protocol numbers from IANA */
enum ip_protocol { enum ip_protocol {
IPPROTO_ICMP = 1,
IPPROTO_TCP = 6, IPPROTO_TCP = 6,
IPPROTO_UDP = 17, IPPROTO_UDP = 17,
IPPROTO_ICMPV6 = 58, IPPROTO_ICMPV6 = 58,

View file

@ -141,13 +141,6 @@ config NETWORK_IP_STACK_DEBUG_ICMPV6
help help
Enables ICMPv6 code part to output debug messages Enables ICMPv6 code part to output debug messages
config NETWORK_IP_STACK_DEBUG_ICMPV6
bool "Debug ICMPv6"
depends on NET_IPV6
default n
help
Enables ICMPv6 code part to output debug messages
config NETWORK_IP_STACK_DEBUG_ICMPV4 config NETWORK_IP_STACK_DEBUG_ICMPV4
bool "Debug ICMPv4" bool "Debug ICMPv4"
depends on NET_IPV4 depends on NET_IPV4

View file

@ -6,3 +6,4 @@ obj-y = net_core.o \
utils.o utils.o
obj-$(CONFIG_NET_IPV6) += icmpv6.o obj-$(CONFIG_NET_IPV6) += icmpv6.o
obj-$(CONFIG_NET_IPV4) += icmpv4.o

87
net/yaip/icmpv4.c Normal file
View file

@ -0,0 +1,87 @@
/** @file
* @brief ICMPv4 related functions
*/
/*
* Copyright (c) 2016 Intel Corporation
*
* 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.
*/
#ifdef CONFIG_NETWORK_IP_STACK_DEBUG_ICMPV4
#define SYS_LOG_DOMAIN "net/icmpv4"
#define NET_DEBUG 1
#endif
#include <errno.h>
#include <misc/slist.h>
#include <net/net_core.h>
#include <net/nbuf.h>
#include <net/net_if.h>
#include <net/net_stats.h>
#include "net_private.h"
#include "icmpv4.h"
static inline enum net_verdict handle_echo_request(struct net_buf *buf)
{
/* Note that we send the same data buffers back and just swap
* the addresses etc.
*/
struct in_addr addr;
#if NET_DEBUG > 0
char out[sizeof("xxx.xxx.xxx.xxx")];
snprintf(out, sizeof(out),
net_sprint_ipv4_addr(&NET_IPV4_BUF(buf)->dst));
NET_DBG("Received Echo Request from %s to %s",
net_sprint_ipv4_addr(&NET_IPV4_BUF(buf)->src), out);
#endif /* NET_DEBUG > 0 */
net_ipaddr_copy(&addr, &NET_IPV4_BUF(buf)->src);
net_ipaddr_copy(&NET_IPV4_BUF(buf)->src,
&NET_IPV4_BUF(buf)->dst);
net_ipaddr_copy(&NET_IPV4_BUF(buf)->dst, &addr);
NET_ICMP_BUF(buf)->type = NET_ICMPV4_ECHO_REPLY;
NET_ICMP_BUF(buf)->code = 0;
NET_ICMP_BUF(buf)->chksum = 0;
NET_ICMP_BUF(buf)->chksum = ~net_calc_chksum_icmpv4(buf);
#if NET_DEBUG > 0
snprintf(out, sizeof(out),
net_sprint_ipv4_addr(&NET_IPV4_BUF(buf)->dst));
NET_DBG("Sending Echo Reply from %s to %s",
net_sprint_ipv4_addr(&NET_IPV4_BUF(buf)->src), out);
#endif /* NET_DEBUG > 0 */
if (net_send_data(buf) < 0) {
NET_STATS(++net_stats.icmp.drop);
return NET_DROP;
}
NET_STATS(++net_stats.icmp.sent);
return NET_OK;
}
enum net_verdict net_icmpv4_input(struct net_buf *buf, uint16_t len,
uint8_t type, uint8_t code)
{
switch (type) {
case NET_ICMPV4_ECHO_REQUEST:
return handle_echo_request(buf);
}
return NET_DROP;
}

37
net/yaip/icmpv4.h Normal file
View file

@ -0,0 +1,37 @@
/** @file
@brief ICMPv4 handler
This is not to be included by the application.
*/
/*
* Copyright (c) 2016 Intel Corporation
*
* 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.
*/
#ifndef __ICMPV4_H
#define __ICMPV4_H
#include <stdint.h>
#include <net/net_ip.h>
#include <net/nbuf.h>
#define NET_ICMPV4_ECHO_REQUEST 8
#define NET_ICMPV4_ECHO_REPLY 0
enum net_verdict net_icmpv4_input(struct net_buf *buf, uint16_t len,
uint8_t type, uint8_t code);
#endif /* __ICMPV4_H */

View file

@ -45,6 +45,10 @@
#include "icmpv6.h" #include "icmpv6.h"
#endif #endif
#if defined(CONFIG_NET_IPV4)
#include "icmpv4.h"
#endif
/* Stack for the rx fiber. /* Stack for the rx fiber.
*/ */
#if !defined(CONFIG_NET_RX_STACK_SIZE) #if !defined(CONFIG_NET_RX_STACK_SIZE)
@ -205,6 +209,20 @@ drop:
} }
#endif /* CONFIG_NET_IPV6 */ #endif /* CONFIG_NET_IPV6 */
#if defined(CONFIG_NET_IPV4)
static inline enum net_verdict process_icmpv4_pkt(struct net_buf *buf,
struct net_ipv4_hdr *ipv4)
{
struct net_icmp_hdr *hdr = NET_ICMP_BUF(buf);
uint16_t len = (ipv4->len[0] << 8) + ipv4->len[1];
NET_DBG("ICMPv4 packet received length %d type %d code %d",
len, hdr->type, hdr->code);
return net_icmpv4_input(buf, len, hdr->type, hdr->code);
}
#endif /* CONFIG_NET_IPV4 */
#if defined(CONFIG_NET_IPV4) #if defined(CONFIG_NET_IPV4)
static inline enum net_verdict process_ipv4_pkt(struct net_buf *buf) static inline enum net_verdict process_ipv4_pkt(struct net_buf *buf)
{ {
@ -238,6 +256,12 @@ static inline enum net_verdict process_ipv4_pkt(struct net_buf *buf)
goto drop; goto drop;
} }
switch (hdr->proto) {
case IPPROTO_ICMP:
net_nbuf_ip_hdr_len(buf) = sizeof(struct net_ipv4_hdr);
return process_icmpv4_pkt(buf, hdr);
}
drop: drop:
return NET_DROP; return NET_DROP;
} }

View file

@ -38,6 +38,11 @@ static inline uint16_t net_calc_chksum_icmpv6(struct net_buf *buf)
return net_calc_chksum(buf, IPPROTO_ICMPV6); return net_calc_chksum(buf, IPPROTO_ICMPV6);
} }
static inline uint16_t net_calc_chksum_icmpv4(struct net_buf *buf)
{
return net_calc_chksum(buf, IPPROTO_ICMP);
}
#if NET_DEBUG > 0 #if NET_DEBUG > 0
static inline char *net_sprint_ll_addr(uint8_t *ll, uint8_t ll_len) static inline char *net_sprint_ll_addr(uint8_t *ll, uint8_t ll_len)
{ {