This is the mail archive of the
ecos-discuss@sources.redhat.com
mailing list for the eCos project.
Re: RedBoot: __eth_install_handler?
- To: ecos-discuss at sources dot redhat dot com
- Subject: Re: [ECOS] RedBoot: __eth_install_handler?
- From: Grant Edwards <grante at visi dot com>
- Date: Mon, 22 Jan 2001 16:56:03 -0600
- References: <20010122135829.A24681@visi.com>
Attached is a patch that impliments __eth_install_handler()
functionality. It's currently hard-wired to allow up to 4
handlers. The normal IP/ARP/RARP handlers are still handled
seperately.
--
Grant Edwards
grante@visi.com
Index: src/net/enet.c
===================================================================
RCS file: /cvs/ecos/ecos/packages/redboot/current/src/net/enet.c,v
retrieving revision 1.3
diff -U5 -r1.3 enet.c
--- enet.c 2000/10/31 20:53:15 1.3
+++ enet.c 2001/01/22 22:45:54
@@ -57,10 +57,26 @@
#endif
static int num_received = 0;
static int num_transmitted = 0;
#endif
+
+/*
+ * data structures used to register ethernet proto handlers
+ */
+
+typedef struct {
+int eth_type;
+pkt_handler_t handler;
+} eth_handler_table_entry;
+
+/* the size of this array should perhaps be configurable via cdl */
+
+static eth_handler_table_entry handler_table[4];
+
+
+
/*
* Non-blocking poll of ethernet link. Process packets until no more
* are available.
*/
void
@@ -113,12 +129,27 @@
__rarp_handler(pkt);
break;
#endif
default:
- __pktbuf_free(pkt);
+ {
+ int i;
+ pkt_handler_t handler = NULL;
+
+ pkt->eth_hdr = ð_hdr;
+
+ for (i=0; i< (sizeof handler_table)/(sizeof handler_table[0]); ++i)
+ if (handler_table[i].eth_type == ntohs(eth_hdr.type)) {
+ handler = handler_table[i].handler;
+ break;
+ }
+ if (handler)
+ handler(pkt);
+ else
+ __pktbuf_free(pkt);
break;
+ }
}
} else {
__pktbuf_free(pkt);
break;
}
@@ -142,10 +173,44 @@
eth_drv_write((char *)ð_hdr, (char *)pkt->buf, pkt->pkt_bytes);
#if ENET_STATS
++num_transmitted;
#endif
+}
+
+
+
+
+/*
+ * Install handlers for ethernet packets.
+ * Returns old handler.
+ */
+pkt_handler_t
+__eth_install_handler(int eth_type, pkt_handler_t handler)
+{
+ int i;
+ int found = -1;
+ int empty = -1;
+ pkt_handler_t ret = NULL;
+
+ for (i=0; i<(sizeof handler_table)/(sizeof handler_table[0]); ++i)
+ if (handler_table[i].eth_type == eth_type)
+ found = i;
+ else if (handler_table[i].handler == NULL && empty < 0)
+ empty = i;
+
+ if (found >= 0) {
+ ret = handler_table[found].handler;
+ handler_table[found].handler = handler;
+ } else if (empty >= 0) {
+ handler_table[empty].handler = handler;
+ handler_table[empty].eth_type = eth_type;
+ } else {
+ // out of space in table!!
+ }
+
+ return ret;
}
#ifdef __LITTLE_ENDIAN__
Index: include/net/net.h
===================================================================
RCS file: /cvs/ecos/ecos/packages/redboot/current/include/net/net.h,v
retrieving revision 1.3
diff -U5 -r1.3 net.h
--- net.h 2000/12/08 03:30:08 1.3
+++ net.h 2001/01/22 22:45:55
@@ -258,13 +258,11 @@
} icmp_header_t;
typedef struct _pktbuf {
struct _pktbuf *next;
-#if 0
eth_header_t *eth_hdr; /* pointer to ethernet header */
-#endif
union {
ip_header_t *__iphdr; /* pointer to IP header */
arp_header_t *__arphdr; /* pointer to ARP header */
} u1;
#define ip_hdr u1.__iphdr