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]

Re: RedBoot: __eth_install_handler?



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 = &eth_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 *)&eth_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

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