This is the mail archive of the ecos-discuss@sources.redhat.com mailing list for the eCos project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Patch redboot icmp, ping, tcp, suggestion


In icmp.c it was impossible to intercept
ICMP Echo Requests. Changed the handler
registration to allow intercept.
In ping.c any ICMP segment was considered
to be an ICMP Echo Reply in the handler
registered. Changed it to count only
ICMP Echo Reply.
Added the possibility to send an RST flag
in TCP in order to abort a connection.


2002-06-06  Hendrik Ruijter  <Hendrik.Ruijter@axis.com>

	* include/net/net.h: Add __tcp_abort prototype.

	* src/net/icmp.c: The default handler can be replaced by a
	user defined handler which handles all ICMP segments.

	* src/net/ping.c
	(handle_icmp): Only ICMP Echo Reply segments must be counted and
	ICMP Echo Requests are handled in the user defined handler.

	* src/net/tcp.c
	(do_abort, __tcp_abort): Send an RST flag in order to abort a
	connection. May use a delay to send the flag.

Brgrds,
Hendrik Ruijter


Index: src/net/icmp.c
===================================================================
RCS file: /n/cvsroot/os/ecos/packages/redboot/current/src/net/icmp.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -u -r1.1.1.1 -r1.2
--- src/net/icmp.c	12 Dec 2001 11:56:46 -0000	1.1.1.1
+++ src/net/icmp.c	31 May 2002 14:42:01 -0000	1.2
@@ -48,54 +48,70 @@
 /*
  * Handle ICMP packets.
  */
+static void default_icmp_handler(pktbuf_t *pkt, ip_route_t *dest);
 
-static icmp_handler_t icmp_handler;
+static icmp_handler_t icmp_handler = default_icmp_handler;
 
 /*
- * Install a handler for incoming icmp packets.
- * Returns zero if successful, -1 if socket is already used.
+ * Install a user defined user_handler for incoming icmp packets.
+ * Returns zero if successful, -1 if the user_handler is already used.
  */
 int
-__icmp_install_listener(icmp_handler_t handler)
+__icmp_install_listener(icmp_handler_t user_handler)
 {
-    if (icmp_handler) {
+    if (icmp_handler == user_handler) {
         return -1;
     }
-    icmp_handler = handler;
+    icmp_handler = user_handler;
     return 0;
 }
 
 
 /*
- * Remove the handler
+ * Replace a user defined handler by the default handler.
  */
 void
 __icmp_remove_listener(void)
 {
-    icmp_handler = (icmp_handler_t)NULL;
+  if (icmp_handler != default_icmp_handler) {
+      icmp_handler = default_icmp_handler;
+  }
 }
 
+/*
+ * ICMP entry point with an IP packet pkt and the destination dest a reply
+ * should be sent to.
+ */
 void
-__icmp_handler(pktbuf_t *pkt, ip_route_t *r)
+__icmp_handler(pktbuf_t *pkt, ip_route_t *dest)
+{
+    (*icmp_handler)(pkt, dest);
+
+    BSPLOG(bsp_log("icmp: dest[%s] type[%d] seq[%d]\n",
+		   inet_ntoa(pkt->ip_hdr->destination),
+		   pkt->icmp_hdr->type,
+		   pkt->icmp_hdr->seqnum));
+    __pktbuf_free(pkt);
+}
+
+
+/*
+ * The default ICMP handler only handles ICMP incoming echo request and
+ * outgoing echo reply.
+ */
+static void
+default_icmp_handler(pktbuf_t *pkt, ip_route_t *dest)
 {
     word cksum;
 
-    if (pkt->icmp_hdr->type == ICMP_TYPE_ECHOREQUEST &&
-	pkt->icmp_hdr->code == 0 &&
-	__sum((word *)pkt->icmp_hdr, pkt->pkt_bytes, 0) == 0) {
+    if (pkt->icmp_hdr->type == ICMP_TYPE_ECHOREQUEST
+	&& pkt->icmp_hdr->code == 0
+	&& __sum((word *)pkt->icmp_hdr, pkt->pkt_bytes, 0) == 0) {
 
 	pkt->icmp_hdr->type = ICMP_TYPE_ECHOREPLY;
 	pkt->icmp_hdr->checksum = 0;
         cksum = __sum((word *)pkt->icmp_hdr, pkt->pkt_bytes, 0);
 	pkt->icmp_hdr->checksum = htons(cksum);
-	
-	BSPLOG(bsp_log("icmp: seq<%d>\n", pkt->icmp_hdr->seqnum));
-
-	__ip_send(pkt, IP_PROTO_ICMP, r);
-    } else if (icmp_handler) {
-        (*icmp_handler)(pkt, r);
+        __ip_send(pkt, IP_PROTO_ICMP, dest);
     }
-    __pktbuf_free(pkt);
 }
-
-
Index: src/net/ping.c
===================================================================
RCS file: /n/cvsroot/os/ecos/packages/redboot/current/src/net/ping.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -u -r1.1.1.1 -r1.2
--- src/net/ping.c	12 Dec 2001 11:56:46 -0000	1.1.1.1
+++ src/net/ping.c	31 May 2002 14:47:18 -0000	1.2
@@ -67,8 +67,19 @@
     icmp_header_t *icmp;
 
     icmp = pkt->icmp_hdr;
-    memcpy(&hold_hdr, icmp, sizeof(*icmp));
-    icmp_received = true;
+    if (icmp->type == ICMP_TYPE_ECHOREQUEST
+	&& icmp->code == 0
+	&& __sum((word *)icmp, pkt->pkt_bytes, 0) == 0) {
+
+	icmp->type = ICMP_TYPE_ECHOREPLY;
+	icmp->checksum = 0;
+        cksum = __sum((word *)icmp, pkt->pkt_bytes, 0);
+	icmp->checksum = htons(cksum);
+        __ip_send(pkt, IP_PROTO_ICMP, src_route);
+    } else if (icmp->type == ICMP_TYPE_ECHOREPLY) {
+        memcpy(&hold_hdr, icmp, sizeof(*icmp));
+        icmp_received = true;
+    }
 }
 
 static void
Index: src/net/tcp.c
===================================================================
RCS file: /n/cvsroot/os/ecos/packages/redboot/current/src/net/tcp.c,v
retrieving revision 1.1.1.2
retrieving revision 1.4
diff -u -r1.1.1.2 -r1.4
--- src/net/tcp.c	5 Apr 2002 11:57:36 -0000	1.1.1.2
+++ src/net/tcp.c	5 Jun 2002 14:15:26 -0000	1.4
@@ -55,6 +55,8 @@
 #define SEQ_GT(a,b) ((int)((a)-(b)) > 0)
 #define SEQ_GE(a,b) ((int)((a)-(b)) >= 0)
 
+/* Set a timer which will send an RST and abort a connection. */
+static timer_t abort_timer;
 
 static void do_retrans(void *p);
 static void do_close(void *p);
@@ -627,6 +619,25 @@
 }
 
 
+/*
+ * Close the tcp connection.
+ */
+static void
+do_abort(void *s)
+{
+    BSPLOG(bsp_log("do_abort: send RST\n"));
+    tcp_send((tcp_socket_t *)s, TCP_FLAG_ACK | TCP_FLAG_RST, 0);
+    __timer_cancel(&abort_timer);
+    ((tcp_socket_t *)s)->state = _CLOSED;
+    free_rxlist((tcp_socket_t *)s);
+    unlink_socket((tcp_socket_t *)s);
+}
+
+void
+__tcp_abort(tcp_socket_t *s, unsigned long delay)
+{
+  __timer_set(&abort_timer, delay, do_abort, s);
+}
 
 /*
  * Close the tcp connection.
Index: include/net/net.h
===================================================================
RCS file: /n/cvsroot/os/ecos/packages/redboot/current/include/net/net.h,v
retrieving revision 1.1.1.2
retrieving revision 1.2
diff -u -r1.1.1.2 -r1.2
--- include/net/net.h	5 Apr 2002 11:57:36 -0000	1.1.1.2
+++ include/net/net.h	5 Jun 2002 14:15:19 -0000	1.2
@@ -514,6 +514,10 @@
  */
 extern void __tcp_drain(tcp_socket_t *s);
 
+/*
+ * Abort connection.
+ */
+extern void __tcp_abort(tcp_socket_t *s, unsigned long delay);
 
 /*
  * Initiate connection close.

-- 
Before posting, please read the FAQ: http://sources.redhat.com/fom/ecos
and search the list archive: http://sources.redhat.com/ml/ecos-discuss

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]