openblt

a hobby OS from the late 90s
git clone http://frotz.net/git/openblt.git
Log | Files | Refs | LICENSE

eth.c (5495B)


      1 /* $Id: //depot/blt/srv/network/protocol/eth/eth.c#1 $
      2 **
      3 ** Copyright 1999 Sidney Cammeresi
      4 ** All rights reserved.
      5 **
      6 ** Redistribution and use in source and binary forms, with or without
      7 ** modification, are permitted provided that the following conditions
      8 ** are met:
      9 ** 1. Redistributions of source code must retain the above copyright
     10 **    notice, this list of conditions, and the following disclaimer.
     11 ** 2. Redistributions in binary form must reproduce the above copyright
     12 **    notice, this list of conditions, and the following disclaimer in the
     13 **    documentation and/or other materials provided with the distribution.
     14 ** 3. The name of the author may not be used to endorse or promote products
     15 **    derived from this software without specific prior written permission.
     16 **
     17 ** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     18 ** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     19 e* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     20 ** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     21 ** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     22 ** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     23 ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     24 ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     25 ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     26 ** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27 */
     28 
     29 #include <stdio.h>
     30 #include <stdlib.h>
     31 #include <dlfcn.h>
     32 #include <blt/qsem.h>
     33 #include <blt/network/eth.h>
     34 #include <blt/network/mbuf.h>
     35 #include <blt/network/module.h>
     36 
     37 eth_drv_t *drvlist = NULL;
     38 eth_dev_t *devlist = NULL;
     39 eth_prot_t *protlist = NULL;
     40 
     41 static qsem_t *eth_input_lock_sem, *eth_input_length_sem;
     42 static qsem_t *eth_output_lock_sem, *eth_output_length_sem;
     43 static struct mbuf *eth_input_queue = NULL, *eth_output_queue = NULL;
     44 static void eth_input_thread (void);
     45 static void eth_output_thread (void);
     46 
     47 int _init (void)
     48 {
     49 	eth_input_lock_sem = qsem_create (1);
     50 	eth_input_length_sem = qsem_create (0);
     51 	thr_create (eth_input_thread, 0, "network:eth:input");
     52 	eth_output_lock_sem = qsem_create (1);
     53 	eth_output_length_sem = qsem_create (0);
     54 	thr_create (eth_output_thread, 0, "network:eth:output");
     55 	return 1;
     56 }
     57 
     58 void _fini (void)
     59 {
     60 }
     61 
     62 void register_eth_driver (eth_drv_t *drv)
     63 {
     64 	drv->next = drvlist;
     65 	drvlist = drv;
     66 }
     67 
     68 void unregister_eth_driver (eth_drv_t *drv)
     69 {
     70 }
     71 
     72 void register_eth_device (eth_dev_t *dev)
     73 {
     74 	dev->next = devlist;
     75 	devlist = dev;
     76 }
     77 
     78 void unregister_eth_device (eth_dev_t *dev)
     79 {
     80 }
     81 
     82 void register_eth_protocol (eth_prot_t *prot)
     83 {
     84 	prot->next = protlist;
     85 	protlist = prot;
     86 }
     87 
     88 void unregister_eth_protocol (eth_prot_t *prot)
     89 {
     90 }
     91 
     92 void eth_input (struct mbuf *mbuf)
     93 {
     94 	struct mbuf *m;
     95 
     96 	qsem_acquire (eth_input_lock_sem);
     97 	if (eth_input_queue == NULL)
     98 	{
     99 		eth_input_queue = mbuf;
    100 		mbuf->m_nextpkt = NULL;
    101 	}
    102 	else
    103 	{
    104 		m = eth_input_queue;
    105 		while (m->m_nextpkt != NULL)
    106 			m = m->m_nextpkt;
    107 		m->m_nextpkt = mbuf;
    108 	}
    109 	qsem_release (eth_input_lock_sem);
    110 	qsem_release (eth_input_length_sem);
    111 }
    112 
    113 static void eth_input_thread (void)
    114 {
    115 	struct mbuf *mbuf, *mbuf_header;
    116 	eth_prot_t *prot;
    117 	ether_header *header;
    118 
    119 	for (;;)
    120 	{
    121 		qsem_acquire (eth_input_length_sem);
    122 		qsem_acquire (eth_input_lock_sem);
    123 		mbuf_header = eth_input_queue;
    124 		eth_input_queue = eth_input_queue->m_nextpkt;
    125 		qsem_release (eth_input_lock_sem);
    126 
    127 		mbuf = mbuf_header->m_next;
    128 		header = (ether_header *) mbuf->m_data;
    129 #if 0
    130 		printf ("eth_input_thread prot: %x src: %X:%X:%X:%X:%X:%X  dst: "
    131 			"%X:%X:%X:%X:%X:%X\n", header->frame_type, header->src[0],
    132 			header->src[1], header->src[2], header->src[3], header->src[4],
    133 			header->src[5], header->dst[0], header->dst[1], header->dst[2],
    134 			header->dst[3], header->dst[4], header->dst[5]);
    135 #endif
    136 		prot = protlist;
    137 		while (prot != NULL)
    138 			if (prot->num == header->frame_type)
    139 			{
    140 				prot->input (mbuf_header);
    141 				break;
    142 			}
    143 			else
    144 				prot = prot->next;
    145 	}
    146 }
    147 
    148 void eth_output (struct mbuf *mbuf)
    149 {
    150 	struct mbuf *m;
    151 
    152 	qsem_acquire (eth_output_lock_sem);
    153 	if (eth_output_queue == NULL)
    154 	{
    155 		eth_output_queue = mbuf;
    156 		mbuf->m_nextpkt = NULL;
    157 	}
    158 	else
    159 	{
    160 		m = eth_output_queue;
    161 		while (m->m_nextpkt != NULL)
    162 			m = m->m_nextpkt;
    163 		m->m_nextpkt = mbuf;
    164 	}
    165 	qsem_release (eth_output_lock_sem);
    166 	qsem_release (eth_output_length_sem);
    167 }
    168 
    169 static void eth_output_thread (void)
    170 {
    171 	struct mbuf *mbuf;
    172 
    173 	for (;;)
    174 	{
    175 		qsem_acquire (eth_output_length_sem);
    176 		qsem_acquire (eth_output_lock_sem);
    177 		mbuf = eth_output_queue;
    178 		eth_output_queue = eth_input_queue->m_nextpkt;
    179 		qsem_release (eth_output_lock_sem);
    180 		printf ("eth_output_thread\n");
    181 	}
    182 }
    183 
    184 void eth_config (eth_dev_t *dev, const char *prot, int state, const char *data)
    185 {
    186 	char *devname;
    187 	int len;
    188 	int (*config_up)(const char *, void (*)(struct mbuf *), const char *);
    189 	module_t *mod;
    190 
    191 	mod = modlist;
    192 	while (mod != NULL)
    193 		if (!strcmp (mod->name, prot))
    194 		{
    195 			printf ("network: %s%d: interface %s, ", dev->dev_driver->name,
    196 				dev->dev_num, state ? "up" : "down");
    197 			devname = malloc (len = 16);
    198 			snprintf (devname, len, "%s%d", dev->dev_driver->name,
    199 				dev->dev_num);
    200 			config_up = dlsym (mod->handle, "ipv4_config_up"); /* XXX */
    201 			if (config_up != NULL)
    202 				(*config_up) (devname, eth_output, data);
    203 			return;
    204 		}
    205 		else
    206 			mod = mod->next;
    207 	printf ("network: %s%d: unknown protocol %s\n", dev->dev_driver->name,
    208 		dev->dev_num, prot);
    209 }
    210