This is the mail archive of the
ecos-discuss@sources.redhat.com
mailing list for the eCos project.
Patch redboot icmp, ping, tcp, suggestion
- From: Hendrik Ruijter <hendrik dot ruijter at axis dot com>
- To: ecos-discuss at sources dot redhat dot com
- Date: Thu, 06 Jun 2002 16:18:29 +0200
- Subject: [ECOS] Patch redboot icmp, ping, tcp, suggestion
- Organization: Axis Communications AB
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