diff mbox

[2/2] example: echo: reply to icmp echo request

Message ID 1466073070-20148-2-git-send-email-matias.elo@nokia.com
State New
Headers show

Commit Message

Elo, Matias (Nokia - FI/Espoo) June 16, 2016, 10:31 a.m. UTC
When the application is run in responder mode it will also
reply to standard ICMP echo packets sent by for example the
ping utility.

Signed-off-by: Matias Elo <matias.elo@nokia.com>
---
 example/echo/odp_echo.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 51 insertions(+), 1 deletion(-)

Comments

Maxim Uvarov June 16, 2016, 11:13 a.m. UTC | #1
you introducing new app, I think it's better to merge this patch to 
first one.

Maxim.

On 06/16/16 13:31, Matias Elo wrote:
> When the application is run in responder mode it will also
> reply to standard ICMP echo packets sent by for example the
> ping utility.
>
> Signed-off-by: Matias Elo <matias.elo@nokia.com>
> ---
>   example/echo/odp_echo.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++-
>   1 file changed, 51 insertions(+), 1 deletion(-)
>
> diff --git a/example/echo/odp_echo.c b/example/echo/odp_echo.c
> index cc966e1..ff56f30 100644
> --- a/example/echo/odp_echo.c
> +++ b/example/echo/odp_echo.c
> @@ -12,6 +12,7 @@
>   #include <odp/helper/linux.h>
>   #include <odp/helper/eth.h>
>   #include <odp/helper/ip.h>
> +#include <odp/helper/icmp.h>
>   
>   #define POOL_NUM_PKT 256
>   #define POOL_SEG_LEN 1856
> @@ -178,6 +179,31 @@ static echo_hdr_t *echo_hdr(odp_packet_t pkt)
>   }
>   
>   /**
> + * ICMPv4 echo header start pointer
> + *
> + * @param pkt  Packet handle
> + *
> + * @return  ICMP echo header start pointer
> + * @retval  NULL packet does not contain a valid ICMP echo header
> + */
> +static odph_icmphdr_t *icmp_echo_hdr(odp_packet_t pkt)
> +{
> +	odph_icmphdr_t *icmp;
> +
> +	if (!odp_packet_has_ipv4(pkt))
> +		return NULL;
> +
> +	if (!odp_packet_has_icmp(pkt))
> +		return NULL;
> +
> +	icmp = odp_packet_l4_ptr(pkt, NULL);
> +	if (icmp->type != ICMP_ECHO)
> +		return NULL;
> +
> +	return icmp;
> +}
> +
> +/**
>    * Echo packet responder thread
>    */
>   static int run_responder(void *arg ODP_UNUSED)
> @@ -197,9 +223,13 @@ static int run_responder(void *arg ODP_UNUSED)
>   
>   		if (odp_unlikely(pkts <= 0))
>   			continue;
> +
>   		for (i = 0; i < pkts; i++) {
>   			odp_packet_t pkt = pkt_tbl[i];
>   			odph_ethhdr_t *eth;
> +			odph_icmphdr_t *icmp;
> +			echo_hdr_t *echo;
> +			int icmp_len;
>   
>   			if (odp_unlikely(!odp_packet_has_eth(pkt))) {
>   				odp_packet_free(pkt);
> @@ -207,11 +237,31 @@ static int run_responder(void *arg ODP_UNUSED)
>   			}
>   			eth = odp_packet_l2_ptr(pkt, NULL);
>   
> -			if (echo_hdr(pkt) == NULL) {
> +			icmp = icmp_echo_hdr(pkt);
> +			echo = echo_hdr(pkt);
> +			if (echo == NULL && icmp == NULL) {
>   				odp_packet_free(pkt);
>   				continue;
>   			}
>   
> +			/* Format ICMP echo reply */
> +			if (icmp) {
> +				odph_ipv4hdr_t *ip;
> +				odp_u32be_t tmp_addr;
> +
> +				ip = odp_packet_l3_ptr(pkt, NULL);
> +				tmp_addr = ip->src_addr;
> +				ip->src_addr = ip->dst_addr;
> +				ip->dst_addr = tmp_addr;
> +
> +				icmp_len = odp_packet_len(pkt) -
> +					ODPH_ETHHDR_LEN - ODPH_IPV4HDR_LEN;
> +
> +				icmp->type = ICMP_ECHOREPLY;
> +				icmp->chksum = 0;
> +				icmp->chksum = odph_chksum(icmp, icmp_len);
> +			}
> +
>   			/* Swap MAC addresses */
>   			eth->dst = eth->src;
>   			eth->src = global.src;
diff mbox

Patch

diff --git a/example/echo/odp_echo.c b/example/echo/odp_echo.c
index cc966e1..ff56f30 100644
--- a/example/echo/odp_echo.c
+++ b/example/echo/odp_echo.c
@@ -12,6 +12,7 @@ 
 #include <odp/helper/linux.h>
 #include <odp/helper/eth.h>
 #include <odp/helper/ip.h>
+#include <odp/helper/icmp.h>
 
 #define POOL_NUM_PKT 256
 #define POOL_SEG_LEN 1856
@@ -178,6 +179,31 @@  static echo_hdr_t *echo_hdr(odp_packet_t pkt)
 }
 
 /**
+ * ICMPv4 echo header start pointer
+ *
+ * @param pkt  Packet handle
+ *
+ * @return  ICMP echo header start pointer
+ * @retval  NULL packet does not contain a valid ICMP echo header
+ */
+static odph_icmphdr_t *icmp_echo_hdr(odp_packet_t pkt)
+{
+	odph_icmphdr_t *icmp;
+
+	if (!odp_packet_has_ipv4(pkt))
+		return NULL;
+
+	if (!odp_packet_has_icmp(pkt))
+		return NULL;
+
+	icmp = odp_packet_l4_ptr(pkt, NULL);
+	if (icmp->type != ICMP_ECHO)
+		return NULL;
+
+	return icmp;
+}
+
+/**
  * Echo packet responder thread
  */
 static int run_responder(void *arg ODP_UNUSED)
@@ -197,9 +223,13 @@  static int run_responder(void *arg ODP_UNUSED)
 
 		if (odp_unlikely(pkts <= 0))
 			continue;
+
 		for (i = 0; i < pkts; i++) {
 			odp_packet_t pkt = pkt_tbl[i];
 			odph_ethhdr_t *eth;
+			odph_icmphdr_t *icmp;
+			echo_hdr_t *echo;
+			int icmp_len;
 
 			if (odp_unlikely(!odp_packet_has_eth(pkt))) {
 				odp_packet_free(pkt);
@@ -207,11 +237,31 @@  static int run_responder(void *arg ODP_UNUSED)
 			}
 			eth = odp_packet_l2_ptr(pkt, NULL);
 
-			if (echo_hdr(pkt) == NULL) {
+			icmp = icmp_echo_hdr(pkt);
+			echo = echo_hdr(pkt);
+			if (echo == NULL && icmp == NULL) {
 				odp_packet_free(pkt);
 				continue;
 			}
 
+			/* Format ICMP echo reply */
+			if (icmp) {
+				odph_ipv4hdr_t *ip;
+				odp_u32be_t tmp_addr;
+
+				ip = odp_packet_l3_ptr(pkt, NULL);
+				tmp_addr = ip->src_addr;
+				ip->src_addr = ip->dst_addr;
+				ip->dst_addr = tmp_addr;
+
+				icmp_len = odp_packet_len(pkt) -
+					ODPH_ETHHDR_LEN - ODPH_IPV4HDR_LEN;
+
+				icmp->type = ICMP_ECHOREPLY;
+				icmp->chksum = 0;
+				icmp->chksum = odph_chksum(icmp, icmp_len);
+			}
+
 			/* Swap MAC addresses */
 			eth->dst = eth->src;
 			eth->src = global.src;